ATTRIB(AmmoNade, m_color, vector, '0.66 0.33 0');
ATTRIB(AmmoNade, m_name, string, _("Ammo grenade"));
ATTRIB(AmmoNade, m_icon, string, "nade_ammo");
+ ATTRIB(AmmoNade, netname, string, "ammo");
+ ATTRIB(AmmoNade, impulse, int, 10);
ENDCLASS(AmmoNade)
ATTRIB(DarknessNade, m_color, vector, '0.23 0 0.23');
ATTRIB(DarknessNade, m_name, string, _("Darkness grenade"));
ATTRIB(DarknessNade, m_icon, string, "nade_darkness");
+ ATTRIB(DarknessNade, netname, string, "darkness");
+ ATTRIB(DarknessNade, impulse, int, 11);
ENDCLASS(DarknessNade)
ATTRIB(EntrapNade, m_color, vector, '0.15 0.85 0');
ATTRIB(EntrapNade, m_name, string, _("Entrap grenade"));
ATTRIB(EntrapNade, m_icon, string, "nade_entrap");
+ ATTRIB(EntrapNade, netname, string, "entrap");
+ ATTRIB(EntrapNade, impulse, int, 8);
ENDCLASS(EntrapNade)
ATTRIB(HealNade, m_color, vector, '1 0 0');
ATTRIB(HealNade, m_name, string, _("Heal grenade"));
ATTRIB(HealNade, m_icon, string, "nade_heal");
+ ATTRIB(HealNade, netname, string, "heal");
+ ATTRIB(HealNade, impulse, int, 6);
ENDCLASS(HealNade)
ATTRIB(IceNade, m_color, vector, '0 0.5 2');
ATTRIB(IceNade, m_name, string, _("Ice grenade"));
ATTRIB(IceNade, m_icon, string, "nade_ice");
+ ATTRIB(IceNade, netname, string, "ice");
+ ATTRIB(IceNade, impulse, int, 3);
ENDCLASS(IceNade)
ATTRIB(MonsterNade, m_color, vector, '0.25 0.75 0');
ATTRIB(MonsterNade, m_name, string, _("Monster grenade"));
ATTRIB(MonsterNade, m_icon, string, "nade_monster");
+ ATTRIB(MonsterNade, netname, string, "pokenade"); // TODO: "monster"? nade needs renaming!
+ ATTRIB(MonsterNade, impulse, int, 7);
ENDCLASS(MonsterNade)
ATTRIB(NapalmNade, m_color, vector, '2 0.5 0');
ATTRIB(NapalmNade, m_name, string, _("Napalm grenade"));
ATTRIB(NapalmNade, m_icon, string, "nade_napalm");
+ ATTRIB(NapalmNade, netname, string, "napalm");
+ ATTRIB(NapalmNade, impulse, int, 2);
ENDCLASS(NapalmNade)
ATTRIB(NormalNade, m_color, vector, '1 1 1');
ATTRIB(NormalNade, m_name, string, _("Grenade"));
ATTRIB(NormalNade, m_icon, string, "nade_normal");
+ ATTRIB(NormalNade, impulse, int, 1);
+ ATTRIB(NormalNade, netname, string, "normal");
ENDCLASS(NormalNade)
ATTRIB(SpawnNade, m_color, vector, '1 0.9 0');
ATTRIB(SpawnNade, m_name, string, _("Spawn grenade"));
ATTRIB(SpawnNade, m_icon, string, "nade_spawn");
+ ATTRIB(SpawnNade, netname, string, "spawn");
+ ATTRIB(SpawnNade, impulse, int, 5);
ENDCLASS(SpawnNade)
ATTRIB(TranslocateNade, m_color, vector, '1 0 1');
ATTRIB(TranslocateNade, m_name, string, _("Translocate grenade"));
ATTRIB(TranslocateNade, m_icon, string, "nade_translocate");
+ ATTRIB(TranslocateNade, netname, string, "translocate");
+ ATTRIB(TranslocateNade, impulse, int, 4);
ENDCLASS(TranslocateNade)
ATTRIB(VeilNade, m_name, string, _("Veil grenade"));
ATTRIB(VeilNade, m_icon, string, "nade_veil");
ATTRIB(VeilNade, m_alpha, float, 0.45);
+ ATTRIB(VeilNade, netname, string, "veil");
+ ATTRIB(VeilNade, impulse, int, 9);
ENDCLASS(VeilNade)
#ifdef GAMEQC
-REPLICATE(cvar_cl_nade_type, int, "cl_nade_type");
+REPLICATE(cvar_cl_nade_type, string, "cl_nade_type");
REPLICATE(cvar_cl_pokenade_type, string, "cl_pokenade_type");
entity Nade_TrailEffect(int proj, int nade_team)
ATTRIB(Nade, m_name, string, _("Grenade"));
ATTRIB(Nade, m_icon, string, "nade_normal");
ATTRIB(Nade, m_alpha, float, 1);
+ ATTRIB(Nade, netname, string, "random");
+ ATTRIB(Nade, impulse, int, 0); // legacy number for selection, do not add to new nade types
ATTRIBARRAY(Nade, m_projectile, int, 2);
ATTRIBARRAY(Nade, m_trail, entity, 2);
METHOD(Nade, display, void(entity this, void(string name, string icon) returns)) {
.float orb_radius;
#ifdef GAMEQC
-REPLICATE_INIT(int, cvar_cl_nade_type);
+REPLICATE_INIT(string, cvar_cl_nade_type);
REPLICATE_INIT(string, cvar_cl_pokenade_type);
#endif
delete(this);
}
-void spawn_held_nade(entity player, entity nowner, float ntime, int ntype, string pntype);
+void spawn_held_nade(entity player, entity nowner, float ntime, string ntype, string pntype);
void nade_pickup(entity this, entity thenade)
{
- spawn_held_nade(this, thenade.realowner, autocvar_g_nades_pickup_time, STAT(NADE_BONUS_TYPE, thenade), thenade.pokenade_type);
+ spawn_held_nade(this, thenade.realowner, autocvar_g_nades_pickup_time, REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, thenade)).netname, thenade.pokenade_type);
// set refire so player can't even
this.nade_refire = time + autocvar_g_nades_nade_refire;
return true;
}
-void spawn_held_nade(entity player, entity nowner, float ntime, int ntype, string pntype)
+Nade Nades_FromString(string ntype)
+{
+ FOREACH(Nades, it != NADE_TYPE_Null && (it.netname == ntype || ftos(it.impulse) == ntype),
+ {
+ return it;
+ });
+ return NADE_TYPE_Null;
+}
+
+Nade Nades_GetType(string ntype)
+{
+ Nade def = Nades_FromString(ntype);
+ if(ntype == "random" || ntype == "0")
+ {
+ int rnade = floor(random() * (REGISTRY_COUNT(Nades) - 1)) + 1;
+ def = REGISTRY_GET(Nades, rnade);
+ }
+
+ return (def == NADE_TYPE_Null) ? NADE_TYPE_NORMAL : def;
+}
+
+void spawn_held_nade(entity player, entity nowner, float ntime, string ntype, string pntype)
{
entity n = new(nade), fn = new(fake_nade);
- n.pokenade_type = pntype;
+ Nade def = Nades_GetType(ntype);
- if(ntype == 0) // random nade
- ntype = floor(random() * (REGISTRY_COUNT(Nades) - 1)) + 1;
- Nade def = REGISTRY_GET(Nades, ntype);
- if(def == NADE_TYPE_Null)
- def = NADE_TYPE_NORMAL;
+ n.pokenade_type = pntype;
STAT(NADE_BONUS_TYPE, n) = def.m_id;
delete(this.fake_nade);
this.fake_nade = NULL;
- int ntype;
+ Nade ntype;
string pntype = this.pokenade_type;
if(StatusEffects_active(STATUSEFFECT_Strength, this) && autocvar_g_nades_bonus_onstrength)
- ntype = STAT(NADE_BONUS_TYPE, this);
+ ntype = REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this));
else if (STAT(NADE_BONUS, this) >= 1)
{
- ntype = STAT(NADE_BONUS_TYPE, this);
+ ntype = REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this));
pntype = this.pokenade_type;
STAT(NADE_BONUS, this) -= 1;
}
else
{
- ntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_nade_type : autocvar_g_nades_nade_type);
- pntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type);
+ ntype = Nades_FromString(((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_nade_type : autocvar_g_nades_nade_type));
+ pntype = ((autocvar_g_nades_client_select) ? CS_CVAR(this).cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type);
}
- spawn_held_nade(this, this, autocvar_g_nades_nade_lifetime, ntype, pntype);
+ spawn_held_nade(this, this, autocvar_g_nades_nade_lifetime, ntype.netname, pntype);
}
bool CanThrowNade(entity this)
STAT(NADE_TIMER, player) = 0;
}
-int nades_CheckTypes(entity player, int cl_ntype)
+int nades_CheckTypes(entity player, Nade cl_ntype)
{
// TODO check what happens without this patch
#define CL_NADE_TYPE_CHECK(nade_ent, nade_cvar) \
- case nade_ent.m_id: if (nade_cvar) return cl_ntype
+ case nade_ent: if (nade_cvar) return cl_ntype.m_id
switch (cl_ntype)
{
- case 0: return 0; // random nade
+ case NADE_TYPE_Null: return 0; // random nade
CL_NADE_TYPE_CHECK(NADE_TYPE_NAPALM, autocvar_g_nades_napalm);
CL_NADE_TYPE_CHECK(NADE_TYPE_ICE, autocvar_g_nades_ice);
CL_NADE_TYPE_CHECK(NADE_TYPE_TRANSLOCATE, autocvar_g_nades_translocate);
if(autocvar_g_nades_bonus_client_select)
{
- STAT(NADE_BONUS_TYPE, player) = nades_CheckTypes(player, CS_CVAR(player).cvar_cl_nade_type);
+ STAT(NADE_BONUS_TYPE, player) = nades_CheckTypes(player, Nades_FromString(CS_CVAR(player).cvar_cl_nade_type));
player.pokenade_type = CS_CVAR(player).cvar_cl_pokenade_type;
}
else
{
- STAT(NADE_BONUS_TYPE, player) = autocvar_g_nades_bonus_type;
+ STAT(NADE_BONUS_TYPE, player) = Nades_FromString(autocvar_g_nades_bonus_type).m_id;
player.pokenade_type = autocvar_g_nades_pokenade_monster_type;
}
player.nade_refire += autocvar_g_nades_nade_refire;
if(autocvar_g_nades_bonus_client_select)
- STAT(NADE_BONUS_TYPE, player) = CS_CVAR(player).cvar_cl_nade_type;
+ STAT(NADE_BONUS_TYPE, player) = Nades_FromString(CS_CVAR(player).cvar_cl_nade_type).m_id;
STAT(NADE_TIMER, player) = 0;
float autocvar_g_nades_nade_radius;
float autocvar_g_nades_nade_force;
int autocvar_g_nades_nade_newton_style;
-int autocvar_g_nades_nade_type;
+string autocvar_g_nades_nade_type;
bool autocvar_g_nades_client_select;
bool autocvar_g_nades_bonus;
-int autocvar_g_nades_bonus_type;
+string autocvar_g_nades_bonus_type;
bool autocvar_g_nades_bonus_client_select;
bool autocvar_g_nades_bonus_onstrength;
bool autocvar_g_nades_bonus_only;
.float nade_special_time;
.string pokenade_type;
.entity nade_damage_target;
-.int cvar_cl_nade_type;
+.string cvar_cl_nade_type;
.string cvar_cl_pokenade_type;
.float toss_time;
.float nade_show_particles;
ATTRIB(Client, cvar_cl_voice_directional_taunt_attenuation, float, this.cvar_cl_voice_directional_taunt_attenuation);
ATTRIB(Client, cvar_cl_physics, string, this.cvar_cl_physics);
ATTRIB(Client, cvar_cl_buffs_autoreplace, bool, this.cvar_cl_buffs_autoreplace);
- ATTRIB(Client, cvar_cl_nade_type, int, this.cvar_cl_nade_type);
+ ATTRIB(Client, cvar_cl_nade_type, string, this.cvar_cl_nade_type);
ATTRIB(Client, cvar_cl_pokenade_type, string, this.cvar_cl_pokenade_type);
ATTRIB(Client, cvar_cl_spawn_near_teammate, bool, this.cvar_cl_spawn_near_teammate);
ATTRIB(Client, cvar_cl_gunalign, int, this.cvar_cl_gunalign);