*/
.float idlekick_lasttimeleft;
void PlayerPostThink (void)
-{
+{SELFPARAM();
if(sv_maxidle > 0 && frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
+ if(IS_REAL_CLIENT(self))
if(IS_PLAYER(self) || sv_maxidle_spectatorsareidle)
{
if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
"netname" Name of the team (for example Red, Blue, Green, Yellow, Life, Death, Offense, Defense, etc)...
"cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
void spawnfunc_tdm_team()
-{
+{SELFPARAM();
- if(!g_tdm) { remove(self); return; }
+ if(!g_tdm || !self.cnt) { remove(self); return; }
self.classname = "tdm_team";
self.team = self.cnt + 1;
.float campcheck_traveled_distance;
MUTATOR_HOOKFUNCTION(campcheck_PlayerDies)
-{
+{SELFPARAM();
- Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_CAMPCHECK);
+ Kill_Notification(NOTIF_ONE, self, MSG_CENTER_CPID, CPID_CAMPCHECK);
return false;
}
}
MUTATOR_HOOKFUNCTION(campcheck_PlayerThink)
-{
+{SELFPARAM();
+ if(!gameover)
+ if(!warmup_stage) // don't consider it camping during warmup?
+ if(time >= game_starttime)
if(IS_PLAYER(self))
+ if(IS_REAL_CLIENT(self)) // bots may camp, but that's no reason to constantly kill them
if(self.deadflag == DEAD_NO)
if(!self.frozen)
+ if(!self.BUTTON_CHAT)
if(autocvar_g_campcheck_interval)
{
vector dist;
if(self.weapon == WEP_DEVASTATOR.m_id || self.weapon == WEP_VORTEX.m_id)
{
- entity e = spawn(), oldself;
+ entity e = spawn();
setorigin(e, self.origin);
- oldself = self;
- self = e;
- self.noalign = oldself.noalign;
- self.cnt = oldself.cnt;
- self.team = oldself.team;
- spawnfunc_item_minst_cells();
- self = oldself;
++ e.noalign = self.noalign;
++ e.cnt = self.cnt;
++ e.team = self.team;
+ SELFCALL(e, spawnfunc_item_minst_cells());
+ SELFCALL_DONE();
return true;
}
.float stat_multijump;
.float stat_multijump_speed;
.float stat_multijump_add;
+ .float stat_multijump_maxspeed;
+ .float stat_multijump_dodging;
void multijump_UpdateStats()
-{
+{SELFPARAM();
self.stat_multijump = PHYS_MULTIJUMP;
self.stat_multijump_speed = PHYS_MULTIJUMP_SPEED;
self.stat_multijump_add = PHYS_MULTIJUMP_ADD;
}
}
- float PM_multijump_checkjump()
+ bool PM_multijump_checkjump()
-{
+{SELFPARAM();
if(!PHYS_MULTIJUMP) { return false; }
- if (!IS_JUMP_HELD(self) && !IS_ONGROUND(self)) // jump button pressed this frame and we are in midair
+ #ifdef SVQC
+ bool client_multijump = self.cvar_cl_multijump;
+ #elif defined(CSQC)
+ bool client_multijump = cvar("cl_multijump");
+
+ if(cvar("cl_multijump") > 1)
+ return false; // nope
+ #endif
+
+ if (!IS_JUMP_HELD(self) && !IS_ONGROUND(self) && client_multijump) // jump button pressed this frame and we are in midair
self.multijump_ready = true; // this is necessary to check that we released the jump button and pressed it again
else
self.multijump_ready = false;
}
void nade_prime()
-{
+{SELFPARAM();
+ if(autocvar_g_nades_bonus_only)
+ if(!self.bonus_nades)
+ return; // only allow bonus nades
+
if(self.nade)
remove(self.nade);
}
MUTATOR_HOOKFUNCTION(nt_FilterItem)
-{
+{SELFPARAM();
- if(nt_IsNewToy(self.weapon))
+ if(nt_IsNewToy(self.weapon) && autocvar_g_new_toys_use_pickupsound)
self.item_pickupsound = W_Sound("weaponpickup_new_toys");
return 0;
}
.float msnt_timer;
.vector msnt_deathloc;
+ .float cvar_cl_spawn_near_teammate;
+
MUTATOR_HOOKFUNCTION(msnt_Spawn_Score)
-{
+{SELFPARAM();
- if(autocvar_g_spawn_near_teammate_ignore_spawnpoint)
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate))
return 0;
entity p;
}
MUTATOR_HOOKFUNCTION(msnt_PlayerSpawn)
-{
+{SELFPARAM();
// Note: when entering this, fixangle is already set.
- if(autocvar_g_spawn_near_teammate_ignore_spawnpoint)
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate))
{
if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death)
self.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
}
}
+ void Item_PreDraw()
+ {
+ vector org;
+ float alph;
+ org = getpropertyvec(VF_ORIGIN);
+ if(!checkpvs(org, self)) // this makes sense as long as we don't support recursive warpzones
+ alph = 0;
+ else if(self.fade_start)
+ alph = bound(0, (self.fade_end - vlen(org - self.origin - 0.5 * (self.mins + self.maxs))) / (self.fade_end - self.fade_start), 1);
+ else
+ alph = 1;
+ //printf("%v <-> %v\n", view_origin, self.origin + 0.5 * (self.mins + self.maxs));
+ if(self.ItemStatus & ITS_AVAILABLE)
+ self.alpha = alph;
+ if(alph <= 0)
+ self.drawmask = 0;
+ else
+ self.drawmask = MASK_NORMAL;
+ }
+
void ItemRead(float _IsNew)
-{
+{SELFPARAM();
int sf = ReadByte();
if(sf & ISF_LOCATION)
#ifdef SVQC
bool ItemSend(entity to, int sf)
-{
+{SELFPARAM();
- if(self.gravity)
- sf |= ISF_DROP;
- else
- sf &= ~ISF_DROP;
+ if(self.gravity)
+ sf |= ISF_DROP;
+ else
+ sf &= ~ISF_DROP;
WriteByte(MSG_ENTITY, ENT_CLIENT_ITEM);
WriteByte(MSG_ENTITY, sf);
// Savage: used for item garbage-collection
// TODO: perhaps nice special effect?
void RemoveItem(void)
-{
+{SELFPARAM();
+ if(wasfreed(self) || !self) { return; }
Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
remove(self);
}