fix spectating edge cases

master
an 2019-09-20 11:38:29 -04:00
parent 6933e8bf68
commit d3372f846a
4 changed files with 117 additions and 124 deletions

View File

@ -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);

View File

@ -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

View File

@ -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");
}

View File

@ -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();