IL_REMOVE(g_conveyed, this);
this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
if(this.swampslug)
- delete(this.swampslug);
- this.in_swamp = false;
+ IL_REMOVE(g_swamped, this);
+ this.swampslug = NULL;
+ this.swamp_interval = 0;
+ IL_EACH(g_counters, it.realowner == this,
+ {
+ delete(it);
+ });
STAT(HUD, this) = HUD_NORMAL;
this.event_damage = PlayerDamage;
modifications = substring(modifications, 2, strlen(modifications) - 2);
string versionmessage = GetClientVersionMessage(this);
- string s = strcat(versionmessage, "^8\n^8\nmatch type is ^1", gamemode_name, "^8\n");
+ string s = strcat(versionmessage, "^8\n^8\nhost is ^9", autocvar_hostname, "^8\n");
+
+ s = strcat(s, "^8\nmatch type is ^1", gamemode_name, "^8\n");
if(modifications != "")
s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
if (this.chatbubbleentity) delete(this.chatbubbleentity);
if (this.killindicator) delete(this.killindicator);
+ IL_EACH(g_counters, it.realowner == this,
+ {
+ delete(it);
+ });
+
WaypointSprite_PlayerGone(this);
bot_relinkplayerlist();
void respawn(entity this)
{
- if(this.alpha >= 0 && autocvar_g_respawn_ghosts)
+ bool damagedbycontents_prev = this.damagedbycontents;
+ if(this.alpha >= 0)
{
- this.solid = SOLID_NOT;
- this.takedamage = DAMAGE_NO;
- set_movetype(this, MOVETYPE_FLY);
- this.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed;
- this.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
- this.effects |= CSQCMODEL_EF_RESPAWNGHOST;
- Send_Effect(EFFECT_RESPAWN_GHOST, this.origin, '0 0 0', 1);
- if(autocvar_g_respawn_ghosts_maxtime)
- SUB_SetFade (this, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5);
+ if(autocvar_g_respawn_ghosts)
+ {
+ this.solid = SOLID_NOT;
+ this.takedamage = DAMAGE_NO;
+ this.damagedbycontents = false;
+ set_movetype(this, MOVETYPE_FLY);
+ this.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed;
+ this.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
+ this.effects |= CSQCMODEL_EF_RESPAWNGHOST;
+ this.alpha = min(this.alpha, autocvar_g_respawn_ghosts_alpha);
+ Send_Effect(EFFECT_RESPAWN_GHOST, this.origin, '0 0 0', 1);
+ if(autocvar_g_respawn_ghosts_time > 0)
+ SUB_SetFade(this, time + autocvar_g_respawn_ghosts_time, autocvar_g_respawn_ghosts_fadetime);
+ }
+ else
+ SUB_SetFade (this, time, 1); // fade out the corpse immediately
}
CopyBody(this, 1);
+ this.damagedbycontents = damagedbycontents_prev;
this.effects |= EF_NODRAW; // prevent another CopyBody
PutClientInServer(this);
void player_powerups(entity this)
{
- // add a way to see what the items were BEFORE all of these checks for the mutator hook
- int items_prev = this.items;
-
if((this.items & IT_USING_JETPACK) && !IS_DEAD(this) && !game_stopped)
this.modelflags |= MF_ROCKET;
else
this.effects &= ~(EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST);
+ if (IS_DEAD(this))
+ {
+ if (this.items & (ITEM_Strength.m_itemid | ITEM_Shield.m_itemid | IT_SUPERWEAPON))
+ {
+ sound(this, CH_INFO, SND_POWEROFF, VOL_BASE, ATTEN_NORM);
+ stopsound(this, CH_TRIGGER_SINGLE); // get rid of the pickup sound
+ this.items &= ~ITEM_Strength.m_itemid;
+ this.items &= ~ITEM_Shield.m_itemid;
+ this.items -= (this.items & IT_SUPERWEAPON);
+ }
+ }
+
if((this.alpha < 0 || IS_DEAD(this)) && !this.vehicle) // don't apply the flags if the player is gibbed
return;
+ // add a way to see what the items were BEFORE all of these checks for the mutator hook
+ int items_prev = this.items;
+
Fire_ApplyDamage(this);
Fire_ApplyEffect(this);
int GetPlayerLimit()
{
+ if(g_duel)
+ return 2; // TODO: this workaround is needed since the mutator hook from duel can't be activated before the gametype is loaded (e.g. switching modes via gametype vote screen)
int player_limit = autocvar_g_maxplayers;
MUTATOR_CALLHOOK(GetPlayerLimit, player_limit);
player_limit = M_ARGV(0, int);
return true;
}
-.int items_added;
.string shootfromfixedorigin;
.bool dualwielding_prev;
bool PlayerThink(entity this)
// LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers
//if(frametime)
{
- this.items &= ~this.items_added;
-
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
.entity weaponentity = weaponentities[slot];
W_Vortex_Charge(this, weaponentity, frametime);
W_WeaponFrame(this, weaponentity);
}
-
- this.items_added = 0;
- if ((this.items & ITEM_Jetpack.m_itemid) && ((this.items & ITEM_JetpackRegen.m_itemid) || GetResource(this, RES_FUEL) >= 0.01))
- this.items_added |= IT_FUEL;
-
- this.items |= this.items_added;
}
if (frametime)
}
if (this.flags & FL_JUMPRELEASED) {
- if (PHYS_INPUT_BUTTON_JUMP(this) && joinAllowed(this)) {
+ if (PHYS_INPUT_BUTTON_JUMP(this) && (joinAllowed(this) || time < CS(this).jointime + MIN_SPEC_TIME)) {
this.flags &= ~FL_JUMPRELEASED;
this.flags |= FL_SPAWNING;
} else if(PHYS_INPUT_BUTTON_ATCK(this) && !CS(this).version_mismatch || this.would_spectate) {
this.flags &= ~FL_SPAWNING;
if(joinAllowed(this))
Join(this);
+ else if(time < CS(this).jointime + MIN_SPEC_TIME)
+ CS(this).autojoin_checked = -1;
return;
}
}
}
if (this.flags & FL_JUMPRELEASED) {
- if (PHYS_INPUT_BUTTON_JUMP(this) && joinAllowed(this)) {
+ if (PHYS_INPUT_BUTTON_JUMP(this) && (joinAllowed(this) || time < CS(this).jointime + MIN_SPEC_TIME)) {
this.flags &= ~FL_JUMPRELEASED;
this.flags |= FL_SPAWNING;
} else if(PHYS_INPUT_BUTTON_ATCK(this) || CS(this).impulse == 10 || CS(this).impulse == 15 || CS(this).impulse == 18 || (CS(this).impulse >= 200 && CS(this).impulse <= 209)) {
if(this.flags & FL_SPAWNING)
{
this.flags &= ~FL_SPAWNING;
- Join(this);
+ if(joinAllowed(this))
+ Join(this);
+ else if(time < CS(this).jointime + MIN_SPEC_TIME)
+ CS(this).autojoin_checked = -1;
return;
}
}
IntermissionThink(this);
return;
}
- else if (IS_REAL_CLIENT(this) && !CS(this).autojoin_checked && time >= CS(this).jointime + MIN_SPEC_TIME)
+ else if (IS_REAL_CLIENT(this) && CS(this).autojoin_checked <= 0 && time >= CS(this).jointime + MIN_SPEC_TIME)
{
- CS(this).autojoin_checked = true;
+ bool early_join_requested = (CS(this).autojoin_checked < 0);
+ CS(this).autojoin_checked = 1;
// don't do this in ClientConnect
// many things can go wrong if a client is spawned as player on connection
- if (MUTATOR_CALLHOOK(AutoJoinOnConnection, this)
+ if (early_join_requested || MUTATOR_CALLHOOK(AutoJoinOnConnection, this)
|| (!(autocvar_sv_spectate || autocvar_g_campaign || (Player_GetForcedTeamIndex(this) == TEAM_FORCE_SPECTATOR))
&& (!teamplay || autocvar_g_balance_teams)))
{
campaign_bots_may_start = true;
- Join(this);
+ if(joinAllowed(this))
+ Join(this);
return;
}
}
wep_zoomed += thiswep.wr_zoom(thiswep, this);
}
SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
- }
+ }
if (CS(this).teamkill_soundtime && time > CS(this).teamkill_soundtime)
{
store.ping_movementloss = this.ping_movementloss;
store.v_angle = this.v_angle;
- store.movement = (typing) ? '0 0 0' : this.movement;
+ store.movement = this.movement;
}
NET_HANDLE(fpsreport, bool)