#include <common/monsters/sv_spawn.qh>
#include <common/monsters/sv_monsters.qh>
-REGISTER_MUTATOR(nades, autocvar_g_nades);
-
.float nade_time_primed;
.float nade_lifetime;
void nade_napalm_boom(entity this)
{
- entity fountain;
- int c;
- for (c = 0; c < autocvar_g_nades_napalm_ball_count; c++)
+ for (int c = 0; c < autocvar_g_nades_napalm_ball_count; c++)
nade_napalm_ball(this);
-
- fountain = spawn();
+ entity fountain = new(nade_napalm_fountain);
fountain.owner = this.owner;
fountain.realowner = this.realowner;
fountain.origin = this.origin;
void nade_ice_boom(entity this)
{
- entity fountain;
- fountain = spawn();
+ entity fountain = new(nade_ice_fountain);
fountain.owner = this.owner;
fountain.realowner = this.realowner;
fountain.origin = this.origin;
void nade_spawn_boom(entity this)
{
- entity spawnloc = spawn();
+ entity player = this.realowner;
+ entity spawnloc = new(nade_spawn_loc);
setorigin(spawnloc, this.origin);
- setsize(spawnloc, this.realowner.mins, this.realowner.maxs);
+ setsize(spawnloc, player.mins, player.maxs);
set_movetype(spawnloc, MOVETYPE_NONE);
spawnloc.solid = SOLID_NOT;
- spawnloc.drawonlytoclient = this.realowner;
+ spawnloc.drawonlytoclient = player;
spawnloc.effects = EF_STARDUST;
spawnloc.cnt = autocvar_g_nades_spawn_count;
- if(this.realowner.nade_spawnloc)
- {
- delete(this.realowner.nade_spawnloc);
- this.realowner.nade_spawnloc = NULL;
- }
+ if(player.nade_spawnloc)
+ delete(player.nade_spawnloc);
- this.realowner.nade_spawnloc = spawnloc;
+ player.nade_spawnloc = spawnloc;
}
void nades_orb_think(entity this)
// NOTE: this function merely places an orb
// you must add a custom touch function to the returned entity if desired
// also set .colormod if you wish to have it colorized
- entity orb = spawn(); // Net_LinkEntity sets the classname (TODO)
+ entity orb = new(nades_spawn_orb);
orb.owner = own;
orb.realowner = realown;
setorigin(orb, org);
entity _nade = e.nade;
e.nade = NULL;
- delete(e.fake_nade);
+ if(e.fake_nade)
+ delete(e.fake_nade);
e.fake_nade = NULL;
Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_NADES);
void nade_prime(entity this)
{
- if(autocvar_g_nades_bonus_only)
- if(!STAT(NADE_BONUS, this))
+ if(autocvar_g_nades_bonus_only && !STAT(NADE_BONUS, this))
return; // only allow bonus nades
+ // TODO: handle old nade if it exists?
if(this.nade)
delete(this.nade);
+ this.nade = NULL;
if(this.fake_nade)
delete(this.fake_nade);
+ this.fake_nade = NULL;
int ntype;
string pntype = this.pokenade_type;
}
else
{
- ntype = ((autocvar_g_nades_client_select) ? CS(this).cvar_cl_nade_type : autocvar_g_nades_nade_type);
- pntype = ((autocvar_g_nades_client_select) ? CS(this).cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type);
+ 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);
}
spawn_held_nade(this, this, autocvar_g_nades_nade_lifetime, ntype, pntype);
bool CanThrowNade(entity this)
{
- if(this.vehicle)
- return false;
-
- if(IS_DEAD(this))
- return false;
-
- if (!autocvar_g_nades)
- return false; // allow turning them off mid match
-
- if (weaponLocked(this))
- return false;
-
- if (!IS_PLAYER(this))
- return false;
-
- return true;
+ return !(this.vehicle || !autocvar_g_nades || IS_DEAD(this) || !IS_PLAYER(this) || weaponLocked(this));
}
.bool nade_altbutton;
}
ENDCLASS(NadeOffhand)
NadeOffhand OFFHAND_NADE;
-STATIC_INIT(OFFHAND_NADE) { OFFHAND_NADE = NEW(NadeOffhand); }
+REGISTER_MUTATOR(nades, autocvar_g_nades)
+{
+ MUTATOR_ONADD
+ {
+ OFFHAND_NADE = NEW(NadeOffhand);
+ }
+ return 0;
+}
MUTATOR_HOOKFUNCTION(nades, ForbidThrowCurrentWeapon, CBC_ORDER_LAST)
{
}
}
-#ifdef IS_REVIVING
- #undef IS_REVIVING
+#ifdef IN_REVIVING_RANGE
+ #undef IN_REVIVING_RANGE
#endif
// returns true if player is reviving it
-#define IS_REVIVING(player, it, revive_extra_size) \
- (it != player && !STAT(FROZEN, it) && !IS_DEAD(it) && SAME_TEAM(it, player) \
+#define IN_REVIVING_RANGE(player, it, revive_extra_size) \
+ (it != player && !IS_DEAD(it) && SAME_TEAM(it, player) \
&& boxesoverlap(player.absmin - revive_extra_size, player.absmax + revive_extra_size, it.absmin, it.absmax))
MUTATOR_HOOKFUNCTION(nades, PlayerPreThink)
if (!IS_PLAYER(player)) { return; }
- if (player.nade && (player.offhand != OFFHAND_NADE || (STAT(WEAPONS, player) & WEPSET(HOOK)))) OFFHAND_NADE.offhand_think(OFFHAND_NADE, player, player.nade_altbutton);
+ if (player.nade && (player.offhand != OFFHAND_NADE || (STAT(WEAPONS, player) & WEPSET(HOOK))))
+ OFFHAND_NADE.offhand_think(OFFHAND_NADE, player, player.nade_altbutton);
entity held_nade = player.nade;
if (held_nade)
if(autocvar_g_nades_bonus_client_select)
{
- STAT(NADE_BONUS_TYPE, player) = CS(player).cvar_cl_nade_type;
- player.pokenade_type = CS(player).cvar_cl_pokenade_type;
+ STAT(NADE_BONUS_TYPE, player) = CS_CVAR(player).cvar_cl_nade_type;
+ player.pokenade_type = CS_CVAR(player).cvar_cl_pokenade_type;
}
else
{
{
int n = 0;
- IntrusiveList reviving_players = NULL;
+ entity revivers_last = NULL;
+ entity revivers_first = NULL;
- if(player.freezetag_frozen_timeout > 0 && time >= player.freezetag_frozen_timeout)
- n = -1;
- else if (STAT(FROZEN, player) == FROZEN_TEMP_DYING)
+ if (STAT(FROZEN, player) == FROZEN_TEMP_DYING)
{
vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
n = 0;
- FOREACH_CLIENT(IS_PLAYER(it) && IS_REVIVING(player, it, revive_extra_size), {
- if (!reviving_players)
- reviving_players = IL_NEW();
- IL_PUSH(reviving_players, it);
+ FOREACH_CLIENT(IS_PLAYER(it) && IN_REVIVING_RANGE(player, it, revive_extra_size), {
+ if (STAT(FROZEN, it))
+ continue;
+ if (revivers_last)
+ revivers_last.chain = it;
+ revivers_last = it;
+ if (!revivers_first)
+ revivers_first = it;
++n;
});
+ if (revivers_last)
+ revivers_last.chain = NULL;
}
if (n > 0 && STAT(FROZEN, player) == FROZEN_TEMP_DYING) // OK, there is at least one teammate reviving us
{
Unfreeze(player, false);
- entity first = IL_FIRST(reviving_players);
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_REVIVED, first.netname);
- Send_Notification(NOTIF_ONE, first, MSG_CENTER, CENTER_FREEZETAG_REVIVE, player.netname);
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_REVIVED, revivers_first.netname);
+ Send_Notification(NOTIF_ONE, revivers_first, MSG_CENTER, CENTER_FREEZETAG_REVIVE, player.netname);
}
- IL_EACH(reviving_players, true, {
+ for(entity it = revivers_first; it; it = it.chain)
STAT(REVIVE_PROGRESS, it) = STAT(REVIVE_PROGRESS, player);
- });
}
- if (reviving_players)
- IL_DELETE(reviving_players);
}
}
player.nade_refire = time + autocvar_g_nades_nade_refire;
if(autocvar_g_nades_bonus_client_select)
- STAT(NADE_BONUS_TYPE, player) = CS(player).cvar_cl_nade_type;
+ STAT(NADE_BONUS_TYPE, player) = CS_CVAR(player).cvar_cl_nade_type;
STAT(NADE_TIMER, player) = 0;