self.health = -666;
self.takedamage = DAMAGE_NO;
self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_FLY_WORLDONLY; //(self.cvar_cl_clippedspectating ? MOVETYPE_NOCLIP : MOVETYPE_FLY); // it's too early for this anyway, lets just set it in playerprethink
+ self.movetype = MOVETYPE_FLY_WORLDONLY; // user preference is controlled by playerprethink
self.flags = FL_CLIENT | FL_NOTARGET;
self.armorvalue = 666;
self.effects = 0;
self.pauseregen_finished = 0;
self.damageforcescale = 0;
self.death_time = 0;
+ self.respawn_time = 0;
self.alpha = 0;
self.scale = 0;
self.fade_time = 0;
self.pain_finished = 0;
self.strength_finished = 0;
self.invincible_finished = 0;
+ self.superweapons_finished = 0;
self.pushltime = 0;
self.think = SUB_Null;
self.nextthink = 0;
self.fixangle = TRUE;
self.crouch = FALSE;
- setorigin (self, spot.origin);
+ setorigin (self, (spot.origin + PL_VIEW_OFS)); // offset it so that the spectator spawns higher off the ground, looks better this way
self.prevorigin = self.origin;
self.items = 0;
self.weapons = 0;
=============
*/
//void() ctf_playerchanged;
+
void PutClientInServer (void)
{
if(clienttype(self) == CLIENTTYPE_BOT)
self.weapons = start_weapons;
}
+ if(self.weapons & WEPBIT_SUPERWEAPONS) // exception for minstagib, as minstanex is a superweapon
+ self.superweapons_finished = time + autocvar_g_balance_superweapons_time;
+ else
+ self.superweapons_finished = 0;
+
if(g_weaponarena_random)
{
if(g_weaponarena_random_with_laser)
}
self.items = start_items;
- self.jump_interval = time;
self.spawnshieldtime = time + autocvar_g_spawnshieldtime;
self.pauserotarmor_finished = time + autocvar_g_balance_pause_armor_rot_spawn;
}
self.damageforcescale = 2;
self.death_time = 0;
+ self.respawn_time = 0;
self.scale = 0;
self.fade_time = 0;
self.pain_frame = 0;
WriteByte(MSG_ENTITY, autocvar_g_balance_minelayer_limit); // minelayer max mines
WriteByte(MSG_ENTITY, autocvar_g_balance_hagar_secondary_load_max); // hagar max loadable rockets
WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
+ WriteByte(MSG_ENTITY, autocvar_g_balance_porto_secondary);
return TRUE;
}
CSQCMODEL_AUTOINIT();
self.model_randomizer = random();
+
+ if(clienttype(self) != CLIENTTYPE_REAL)
+ return;
+
+ sv_notice_join();
}
-
/*
=============
ClientDisconnect
else self.colormod = '1 1 1';
}*/
-.float oldcolormap;
void respawn(void)
{
if(self.alpha >= 0 && autocvar_g_respawn_ghosts)
self.movetype = MOVETYPE_FLY;
self.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed;
self.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
- self.effects |= EF_ADDITIVE;
- self.oldcolormap = self.colormap;
- self.colormap = 0; // this originally was 512, but raises a warning in the engine, so get rid of it
+ self.effects |= CSQCMODEL_EF_RESPAWNGHOST;
pointparticles(particleeffectnum("respawn_ghost"), self.origin, '0 0 0', 1);
if(autocvar_g_respawn_ghosts_maxtime)
SUB_SetFade (self, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5);
}
CopyBody(1);
+
self.effects |= EF_NODRAW; // prevent another CopyBody
- if(self.oldcolormap)
- {
- self.colormap = self.oldcolormap;
- self.oldcolormap = 0;
- }
PutClientInServer();
}
sprint(self, "^3Shield surrounds you\n");
}
}
+ if (self.items & IT_SUPERWEAPON)
+ {
+ //if(W_WeaponBit(self.weapon) & WEPBIT_SUPERWEAPONS)
+ // self.effects = self.effects | EF_RED;
+ if (!(self.weapons & WEPBIT_SUPERWEAPONS))
+ {
+ self.superweapons_finished = 0;
+ self.items = self.items - (self.items & IT_SUPERWEAPON);
+ sprint(self, "^3Superweapons have been lost\n");
+ }
+ else if (self.items & IT_UNLIMITED_SUPERWEAPONS)
+ {
+ // don't let them run out
+ }
+ else
+ {
+ play_countdown(self.superweapons_finished, "misc/poweroff.wav");
+ if (time > self.superweapons_finished)
+ {
+ self.items = self.items - (self.items & IT_SUPERWEAPON);
+ self.weapons &~= WEPBIT_SUPERWEAPONS;
+ sprint(self, "^3Superweapons have broken down\n");
+ }
+ }
+ }
+ else if(self.weapons & WEPBIT_SUPERWEAPONS)
+ {
+ if (time < self.superweapons_finished || (self.items & IT_UNLIMITED_SUPERWEAPONS))
+ {
+ self.items = self.items | IT_SUPERWEAPON;
+ sprint(self, "^3You now have a superweapon\n");
+ }
+ else
+ {
+ self.superweapons_finished = 0;
+ self.weapons &~= WEPBIT_SUPERWEAPONS; // just in case
+ }
+ }
+ else
+ {
+ self.superweapons_finished = 0;
+ }
+ }
+
+ if(autocvar_g_nodepthtestplayers)
+ self.effects = self.effects | EF_NODEPTHTEST;
- if(autocvar_g_nodepthtestplayers)
- self.effects = self.effects | EF_NODEPTHTEST;
-
- if(autocvar_g_fullbrightplayers)
- self.effects = self.effects | EF_FULLBRIGHT;
+ if(autocvar_g_fullbrightplayers)
+ self.effects = self.effects | EF_FULLBRIGHT;
- // midair gamemode: damage only while in the air
- // if in midair mode, being on ground grants temporary invulnerability
- // (this is so that multishot weapon don't clear the ground flag on the
- // first damage in the frame, leaving the player vulnerable to the
- // remaining hits in the same frame)
- if (self.flags & FL_ONGROUND)
- if (g_midair)
- self.spawnshieldtime = max(self.spawnshieldtime, time + autocvar_g_midair_shieldtime);
+ // midair gamemode: damage only while in the air
+ // if in midair mode, being on ground grants temporary invulnerability
+ // (this is so that multishot weapon don't clear the ground flag on the
+ // first damage in the frame, leaving the player vulnerable to the
+ // remaining hits in the same frame)
+ if (self.flags & FL_ONGROUND)
+ if (g_midair)
+ self.spawnshieldtime = max(self.spawnshieldtime, time + autocvar_g_midair_shieldtime);
- if (time >= game_starttime)
- if (time < self.spawnshieldtime)
- self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
- }
+ if (time >= game_starttime)
+ if (time < self.spawnshieldtime)
+ self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
MUTATOR_CALLHOOK(PlayerPowerups);
}
return;
else
{
- number = ceil(self.death_time - time);
+ number = ceil(self.respawn_time - time);
if(number <= 0)
return;
if(number <= self.respawn_countdown)
{
self.respawn_countdown = number - 1;
- if(ceil(self.death_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
+ if(ceil(self.respawn_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
AnnounceTo(self, strcat(ftos(number), ""));
}
}
.float prevent_join_msgtime;
void LeaveSpectatorMode()
{
- if(nJoinAllowed(1)) {
+ if(nJoinAllowed(self)) {
if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
self.classname = "player";
* it checks whether the number of currently playing players exceeds g_maxplayers.
* @return int number of free slots for players, 0 if none
*/
-float nJoinAllowed(float includeMe) {
+float nJoinAllowed(entity ignore) {
+ if(!ignore)
+ // this is called that way when checking if anyone may be able to join (to build qcstatus)
+ // so report 0 free slots if restricted
+ {
+ if(autocvar_g_forced_team_otherwise == "spectate")
+ return 0;
+ if(autocvar_g_forced_team_otherwise == "spectator")
+ return 0;
+ }
+
if(self.team_forced < 0)
- return FALSE; // forced spectators can never join
+ return 0; // forced spectators can never join
// TODO simplify this
entity e;
-
float totalClients;
FOR_EACH_CLIENT(e)
- totalClients += 1;
+ if(e != ignore)
+ totalClients += 1;
if (!autocvar_g_maxplayers)
- return maxclients - totalClients + includeMe;
+ return maxclients - totalClients;
float currentlyPlaying;
FOR_EACH_REALPLAYER(e)
currentlyPlaying += 1;
if(currentlyPlaying < autocvar_g_maxplayers)
- return min(maxclients - totalClients + includeMe, autocvar_g_maxplayers - currentlyPlaying);
+ return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying);
return 0;
}
float button_pressed, force_respawn;
if(self.personal && g_race_qualifying)
{
- if(time > self.death_time)
+ if(time > self.respawn_time)
{
- self.death_time = time + 1; // only retry once a second
+ self.respawn_time = time + 1; // only retry once a second
respawn();
self.impulse = 141;
}
}
else if (self.deadflag == DEAD_RESPAWNING)
{
- if(time > self.death_time)
+ if(time > self.respawn_time)
{
- self.death_time = time + 1; // only retry once a second
+ self.respawn_time = time + 1; // only retry once a second
respawn();
}
}