fix spectating edge cases
This commit is contained in:
parent
6933e8bf68
commit
d3372f846a
176
source/client.qc
176
source/client.qc
|
@ -22,28 +22,21 @@ void() SetChangeParms = {
|
|||
}
|
||||
|
||||
// remove items
|
||||
self.items &= ~(IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD);
|
||||
self.items &= ~(IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY |
|
||||
IT_SUIT | IT_QUAD);
|
||||
|
||||
// cap super health
|
||||
if(self.health > 100) {
|
||||
self.health = 100;
|
||||
}
|
||||
if(self.health < 50) {
|
||||
self.health = 50;
|
||||
}
|
||||
parm1 = self.items;
|
||||
parm2 = self.health;
|
||||
parm3 = self.armorvalue;
|
||||
if(self.ammo_shells < 25) {
|
||||
parm4 = 25;
|
||||
} else {
|
||||
parm4 = self.ammo_shells;
|
||||
}
|
||||
parm5 = self.ammo_nails;
|
||||
parm6 = self.ammo_rockets;
|
||||
parm7 = self.ammo_cells;
|
||||
parm8 = self.weapon;
|
||||
parm9 = self.armortype * 100;
|
||||
self.health = minmax(self.health, 50, 100);
|
||||
|
||||
parm1 = self.items;
|
||||
parm2 = self.health;
|
||||
parm3 = self.armorvalue;
|
||||
parm4 = (self.ammo_shells < 25 ? 25 : self.ammo_shells);
|
||||
parm5 = self.ammo_nails;
|
||||
parm6 = self.ammo_rockets;
|
||||
parm7 = self.ammo_cells;
|
||||
parm8 = self.weapon;
|
||||
parm9 = self.armortype * 100;
|
||||
parm10 = self.pronoun;
|
||||
};
|
||||
|
||||
|
@ -66,16 +59,16 @@ void() DecodeLevelParms = {
|
|||
}
|
||||
}
|
||||
|
||||
self.items = parm1;
|
||||
self.health = parm2;
|
||||
self.armorvalue = parm3;
|
||||
self.ammo_shells = parm4;
|
||||
self.ammo_nails = parm5;
|
||||
self.items = parm1;
|
||||
self.health = parm2;
|
||||
self.armorvalue = parm3;
|
||||
self.ammo_shells = parm4;
|
||||
self.ammo_nails = parm5;
|
||||
self.ammo_rockets = parm6;
|
||||
self.ammo_cells = parm7;
|
||||
self.weapon = parm8;
|
||||
self.armortype = parm9 * 0.01;
|
||||
self.pronoun = parm10;
|
||||
self.ammo_cells = parm7;
|
||||
self.weapon = parm8;
|
||||
self.armortype = parm9 * 0.01;
|
||||
self.pronoun = parm10;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -231,14 +224,15 @@ void() execute_changelevel = {
|
|||
|
||||
other = find(world, classname, "player");
|
||||
while(other != world) {
|
||||
other.view_ofs = VEC_ORIGIN;
|
||||
other.angles = other.v_angle = pos.mangle;
|
||||
other.fixangle = TRUE; // turn this way immediately
|
||||
other.nextthink = time + 0.5;
|
||||
other.view_ofs = VEC_ORIGIN;
|
||||
other.angles = other.v_angle = pos.mangle;
|
||||
other.fixangle = TRUE; // turn this way immediately
|
||||
other.nextthink = time + 0.5;
|
||||
other.takedamage = DAMAGE_NO;
|
||||
other.solid = SOLID_NOT;
|
||||
other.movetype = MOVETYPE_NONE;
|
||||
other.solid = SOLID_NOT;
|
||||
other.movetype = MOVETYPE_NONE;
|
||||
other.modelindex = 0;
|
||||
other.spectating = SPECTATING_INTERMISSION;
|
||||
setorigin(other, pos.origin);
|
||||
other = find(other, classname, "player");
|
||||
}
|
||||
|
@ -295,7 +289,7 @@ void() trigger_changelevel = {
|
|||
/*
|
||||
=============================================================================
|
||||
|
||||
PLAYER GAME EDGE FUNCTIONS
|
||||
PLAYER GAME EDGE FUNCTIONS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
@ -304,6 +298,7 @@ void() become_spectator = {
|
|||
float not_dead;
|
||||
entity pl;
|
||||
|
||||
self.spectating = (self.lives ? SPECTATING_SPECTATING : SPECTATING_DEAD);
|
||||
self.health = self.max_health;
|
||||
self.armortype = 0;
|
||||
self.armorvalue = 0;
|
||||
|
@ -455,7 +450,7 @@ void() PutClientInServer = {
|
|||
} else {
|
||||
bprint(ftos(self.lives), " lives left\n");
|
||||
}
|
||||
} else {
|
||||
} else if(self.lives == 0) {
|
||||
self.lives = sf_lives;
|
||||
dprint("lives reset to ", ftos(sf_lives), "\n");
|
||||
}
|
||||
|
@ -465,22 +460,23 @@ void() PutClientInServer = {
|
|||
|
||||
spot = SelectSpawnPoint();
|
||||
|
||||
self.classname = "player";
|
||||
self.health = 100;
|
||||
self.takedamage = DAMAGE_AIM;
|
||||
self.solid = SOLID_SLIDEBOX;
|
||||
self.movetype = MOVETYPE_WALK;
|
||||
self.show_hostile = 0;
|
||||
self.max_health = 100;
|
||||
self.flags = FL_CLIENT;
|
||||
self.air_finished = time + 12;
|
||||
self.dmg = 2; // initial water damage
|
||||
self.classname = "player";
|
||||
self.health = 100;
|
||||
self.takedamage = DAMAGE_AIM;
|
||||
self.solid = SOLID_SLIDEBOX;
|
||||
self.movetype = MOVETYPE_WALK;
|
||||
self.show_hostile = 0;
|
||||
self.max_health = 100;
|
||||
self.flags = FL_CLIENT;
|
||||
self.air_finished = time + 12;
|
||||
self.dmg = 2; // initial water damage
|
||||
self.super_damage_finished = 0;
|
||||
self.radsuit_finished = 0;
|
||||
self.invisible_finished = 0;
|
||||
self.invincible_finished = 0;
|
||||
self.effects = 0;
|
||||
self.invincible_time = 0;
|
||||
self.radsuit_finished = 0;
|
||||
self.invisible_finished = 0;
|
||||
self.invincible_finished = 0;
|
||||
self.effects = 0;
|
||||
self.invincible_time = 0;
|
||||
self.spectating = SPECTATING_NOT;
|
||||
|
||||
DecodeLevelParms();
|
||||
|
||||
|
@ -524,7 +520,7 @@ void() PutClientInServer = {
|
|||
/*
|
||||
=============================================================================
|
||||
|
||||
QUAKED FUNCTIONS
|
||||
QUAKED FUNCTIONS
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
@ -620,8 +616,7 @@ Exit deathmatch games upon conditions
|
|||
============
|
||||
*/
|
||||
void() CheckRules = {
|
||||
float timelimit;
|
||||
float fraglimit;
|
||||
float timelimit, fraglimit;
|
||||
|
||||
if(gameover) { // someone else quit the game already
|
||||
return;
|
||||
|
@ -630,12 +625,8 @@ void() CheckRules = {
|
|||
timelimit = cvar("timelimit") * 60;
|
||||
fraglimit = cvar("fraglimit");
|
||||
|
||||
if(timelimit && time >= timelimit) {
|
||||
NextLevel();
|
||||
return;
|
||||
}
|
||||
|
||||
if(fraglimit && self.frags >= fraglimit) {
|
||||
if((timelimit && time >= timelimit) ||
|
||||
(fraglimit && self.frags >= fraglimit)) {
|
||||
NextLevel();
|
||||
return;
|
||||
}
|
||||
|
@ -707,17 +698,12 @@ void() PlayerJump = {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!(self.flags & FL_ONGROUND)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(self.flags & FL_JUMPRELEASED)) {
|
||||
if(!(self.flags & FL_ONGROUND) || !(self.flags & FL_JUMPRELEASED)) {
|
||||
return; // don't pogo stick
|
||||
}
|
||||
|
||||
self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
|
||||
|
||||
self.flags = self.flags - FL_ONGROUND; // don't stairwalk
|
||||
self.flags -= (self.flags & FL_JUMPRELEASED);
|
||||
self.flags -= FL_ONGROUND; // don't stairwalk
|
||||
|
||||
self.button2 = 0;
|
||||
// player jumping sound
|
||||
|
@ -732,11 +718,7 @@ WaterMove
|
|||
============
|
||||
*/
|
||||
void() WaterMove = {
|
||||
//dprint(ftos(self.waterlevel));
|
||||
if(self.movetype == MOVETYPE_NOCLIP) {
|
||||
return;
|
||||
}
|
||||
if(self.health < 0) {
|
||||
if(self.movetype == MOVETYPE_NOCLIP || self.health < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -843,13 +825,12 @@ Called every frame before physics are run
|
|||
================
|
||||
*/
|
||||
void() PlayerPreThink = {
|
||||
// otherwise a button could be missed between the think tics
|
||||
if(intermission_running) {
|
||||
IntermissionThink(); // otherwise a button could be missed between
|
||||
return; // the think tics
|
||||
}
|
||||
|
||||
if(self.view_ofs == VEC_ORIGIN) {
|
||||
return; // intermission, finale or spectating
|
||||
IntermissionThink();
|
||||
return;
|
||||
} else if(self.spectating) {
|
||||
return;
|
||||
}
|
||||
|
||||
makevectors(self.v_angle); // is this still used
|
||||
|
@ -895,7 +876,7 @@ Check for turning off powerups
|
|||
================
|
||||
*/
|
||||
void() CheckPowerups = {
|
||||
if(self.health <= 0) {
|
||||
if(self.health <= 0 || self.spectating) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1020,16 +1001,18 @@ Called every frame after physics are run
|
|||
================
|
||||
*/
|
||||
void() PlayerPostThink = {
|
||||
if(self.view_ofs == VEC_ORIGIN) {
|
||||
return; // intermission, finale or spectating
|
||||
if(time >= self.attack_finished) {
|
||||
ImpulseCommands();
|
||||
}
|
||||
if(self.deadflag) {
|
||||
|
||||
if(self.spectating || self.deadflag) {
|
||||
return;
|
||||
}
|
||||
|
||||
// do weapon stuff
|
||||
|
||||
W_WeaponFrame();
|
||||
if(time >= self.attack_finished) {
|
||||
W_WeaponFrame();
|
||||
}
|
||||
|
||||
// check to see if player landed and play landing sound
|
||||
if(self.jump_flag < -300 && self.flags & FL_ONGROUND && self.health > 0) {
|
||||
|
@ -1076,20 +1059,23 @@ called when a player disconnects from a server
|
|||
============
|
||||
*/
|
||||
void() ClientDisconnect = {
|
||||
// if the level end trigger has been activated, just return
|
||||
// since they aren't *really* leaving
|
||||
if(gameover) {
|
||||
return;
|
||||
}
|
||||
// if the level end trigger has been activated, just return
|
||||
// since they aren't *really* leaving
|
||||
|
||||
// let everyone else know
|
||||
bprint(self.netname, " left the game with ", ftos(self.frags), " frags\n");
|
||||
sound(self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
|
||||
set_suicide_frame();
|
||||
|
||||
if(!self.spectating) {
|
||||
sound(self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
|
||||
set_suicide_frame();
|
||||
}
|
||||
};
|
||||
|
||||
void() cheat = {
|
||||
if((deathmatch || coop) && !sf_cheats) {
|
||||
if(((deathmatch || coop) && !sf_cheats) || self.spectating) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1114,13 +1100,13 @@ void() cheat = {
|
|||
};
|
||||
|
||||
void() cheat_quad = {
|
||||
if((deathmatch || coop) && !sf_cheats) {
|
||||
if(((deathmatch || coop) && !sf_cheats) || self.spectating) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.super_time = 1;
|
||||
self.super_time = 1;
|
||||
self.super_damage_finished = time + 30;
|
||||
self.items = self.items | IT_QUAD;
|
||||
self.items = self.items | IT_QUAD;
|
||||
};
|
||||
|
||||
string(float pro) pronoun_subject = {
|
||||
|
@ -1545,7 +1531,7 @@ Player entered the suicide command
|
|||
============
|
||||
*/
|
||||
void() ClientKill = {
|
||||
if(self.view_ofs != VEC_ORIGIN) {
|
||||
if(!self.spectating) {
|
||||
reset_death_vel();
|
||||
self.frags--; // extra penalty
|
||||
ClientObituary(self, self);
|
||||
|
|
|
@ -485,22 +485,6 @@ enum {
|
|||
WORLD_BASE,
|
||||
};
|
||||
|
||||
enum {
|
||||
PRO_NONE,
|
||||
|
||||
// alphabetically sorted, based on pronoun.is and what i've seen used
|
||||
PRO_FAE,
|
||||
PRO_HE,
|
||||
PRO_IT,
|
||||
PRO_SHE,
|
||||
PRO_THEY,
|
||||
PRO_XEY,
|
||||
PRO_ZE_H,
|
||||
PRO_ZE_Z,
|
||||
|
||||
PRO_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
DOOR_START_OPEN = 1,
|
||||
DOOR_DONT_LINK = 4,
|
||||
|
@ -574,6 +558,23 @@ enum {
|
|||
SIGIL_4 = 8,
|
||||
};
|
||||
|
||||
// super co-op additions
|
||||
enum {
|
||||
PRO_NONE,
|
||||
|
||||
// alphabetically sorted, based on pronoun.is and what i've seen used
|
||||
PRO_FAE,
|
||||
PRO_HE,
|
||||
PRO_IT,
|
||||
PRO_SHE,
|
||||
PRO_THEY,
|
||||
PRO_XEY,
|
||||
PRO_ZE_H,
|
||||
PRO_ZE_Z,
|
||||
|
||||
PRO_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
SF_CHEATS = 1,
|
||||
SF_LIVES_BEG = 1,
|
||||
|
@ -581,6 +582,14 @@ enum {
|
|||
SF_LIVES_MSK = 14,
|
||||
SF_DIST_AMMO = 16,
|
||||
};
|
||||
|
||||
enum {
|
||||
SPECTATING_NOT,
|
||||
SPECTATING_DEAD,
|
||||
SPECTATING_SPECTATING,
|
||||
SPECTATING_INTERMISSION,
|
||||
SPECTATING_FINALE,
|
||||
};
|
||||
#pragma noref 0
|
||||
|
||||
// globals -------------------------------------------------------------------|
|
||||
|
@ -753,6 +762,7 @@ float ext_con_set;
|
|||
// super co-op additions
|
||||
.float pronoun;
|
||||
.float lives;
|
||||
.float spectating;
|
||||
|
||||
// functions -----------------------------------------------------------------|
|
||||
|
||||
|
@ -921,4 +931,6 @@ void() func_train_find;
|
|||
|
||||
void(vector p) boss_missile;
|
||||
|
||||
void() ImpulseCommands;
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -116,15 +116,16 @@ void() finale_1 = {
|
|||
|
||||
pl = find(world, classname, "player");
|
||||
while(pl != world) {
|
||||
pl.view_ofs = VEC_ORIGIN;
|
||||
pl.angles = other.v_angle = pos.mangle;
|
||||
pl.fixangle = TRUE; // turn this way immediately
|
||||
pl.map = self.map;
|
||||
pl.nextthink = time + 0.5;
|
||||
pl.view_ofs = VEC_ORIGIN;
|
||||
pl.angles = other.v_angle = pos.mangle;
|
||||
pl.fixangle = TRUE; // turn this way immediately
|
||||
pl.map = self.map;
|
||||
pl.nextthink = time + 0.5;
|
||||
pl.takedamage = DAMAGE_NO;
|
||||
pl.solid = SOLID_NOT;
|
||||
pl.movetype = MOVETYPE_NONE;
|
||||
pl.solid = SOLID_NOT;
|
||||
pl.movetype = MOVETYPE_NONE;
|
||||
pl.modelindex = 0;
|
||||
pl.spectating = SPECTATING_FINALE;
|
||||
setorigin(pl, pos.origin);
|
||||
pl = find(pl, classname, "player");
|
||||
}
|
||||
|
|
|
@ -1051,12 +1051,6 @@ Called every frame so impulse events can be handled as well as possible
|
|||
============
|
||||
*/
|
||||
void() W_WeaponFrame = {
|
||||
if(time < self.attack_finished) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImpulseCommands();
|
||||
|
||||
// check for attack
|
||||
if(self.button0) {
|
||||
SuperDamageSound();
|
||||
|
|
Loading…
Reference in New Issue
Block a user