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 // 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 // cap super health
if(self.health > 100) { self.health = minmax(self.health, 50, 100);
self.health = 100;
} parm1 = self.items;
if(self.health < 50) { parm2 = self.health;
self.health = 50; parm3 = self.armorvalue;
} parm4 = (self.ammo_shells < 25 ? 25 : self.ammo_shells);
parm1 = self.items; parm5 = self.ammo_nails;
parm2 = self.health; parm6 = self.ammo_rockets;
parm3 = self.armorvalue; parm7 = self.ammo_cells;
if(self.ammo_shells < 25) { parm8 = self.weapon;
parm4 = 25; parm9 = self.armortype * 100;
} else {
parm4 = 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; parm10 = self.pronoun;
}; };
@ -66,16 +59,16 @@ void() DecodeLevelParms = {
} }
} }
self.items = parm1; self.items = parm1;
self.health = parm2; self.health = parm2;
self.armorvalue = parm3; self.armorvalue = parm3;
self.ammo_shells = parm4; self.ammo_shells = parm4;
self.ammo_nails = parm5; self.ammo_nails = parm5;
self.ammo_rockets = parm6; self.ammo_rockets = parm6;
self.ammo_cells = parm7; self.ammo_cells = parm7;
self.weapon = parm8; self.weapon = parm8;
self.armortype = parm9 * 0.01; self.armortype = parm9 * 0.01;
self.pronoun = parm10; self.pronoun = parm10;
}; };
/* /*
@ -231,14 +224,15 @@ void() execute_changelevel = {
other = find(world, classname, "player"); other = find(world, classname, "player");
while(other != world) { while(other != world) {
other.view_ofs = VEC_ORIGIN; other.view_ofs = VEC_ORIGIN;
other.angles = other.v_angle = pos.mangle; other.angles = other.v_angle = pos.mangle;
other.fixangle = TRUE; // turn this way immediately other.fixangle = TRUE; // turn this way immediately
other.nextthink = time + 0.5; other.nextthink = time + 0.5;
other.takedamage = DAMAGE_NO; other.takedamage = DAMAGE_NO;
other.solid = SOLID_NOT; other.solid = SOLID_NOT;
other.movetype = MOVETYPE_NONE; other.movetype = MOVETYPE_NONE;
other.modelindex = 0; other.modelindex = 0;
other.spectating = SPECTATING_INTERMISSION;
setorigin(other, pos.origin); setorigin(other, pos.origin);
other = find(other, classname, "player"); 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; float not_dead;
entity pl; entity pl;
self.spectating = (self.lives ? SPECTATING_SPECTATING : SPECTATING_DEAD);
self.health = self.max_health; self.health = self.max_health;
self.armortype = 0; self.armortype = 0;
self.armorvalue = 0; self.armorvalue = 0;
@ -455,7 +450,7 @@ void() PutClientInServer = {
} else { } else {
bprint(ftos(self.lives), " lives left\n"); bprint(ftos(self.lives), " lives left\n");
} }
} else { } else if(self.lives == 0) {
self.lives = sf_lives; self.lives = sf_lives;
dprint("lives reset to ", ftos(sf_lives), "\n"); dprint("lives reset to ", ftos(sf_lives), "\n");
} }
@ -465,22 +460,23 @@ void() PutClientInServer = {
spot = SelectSpawnPoint(); spot = SelectSpawnPoint();
self.classname = "player"; self.classname = "player";
self.health = 100; self.health = 100;
self.takedamage = DAMAGE_AIM; self.takedamage = DAMAGE_AIM;
self.solid = SOLID_SLIDEBOX; self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_WALK; self.movetype = MOVETYPE_WALK;
self.show_hostile = 0; self.show_hostile = 0;
self.max_health = 100; self.max_health = 100;
self.flags = FL_CLIENT; self.flags = FL_CLIENT;
self.air_finished = time + 12; self.air_finished = time + 12;
self.dmg = 2; // initial water damage self.dmg = 2; // initial water damage
self.super_damage_finished = 0; self.super_damage_finished = 0;
self.radsuit_finished = 0; self.radsuit_finished = 0;
self.invisible_finished = 0; self.invisible_finished = 0;
self.invincible_finished = 0; self.invincible_finished = 0;
self.effects = 0; self.effects = 0;
self.invincible_time = 0; self.invincible_time = 0;
self.spectating = SPECTATING_NOT;
DecodeLevelParms(); DecodeLevelParms();
@ -524,7 +520,7 @@ void() PutClientInServer = {
/* /*
============================================================================= =============================================================================
QUAKED FUNCTIONS QUAKED FUNCTIONS
============================================================================= =============================================================================
*/ */
@ -620,8 +616,7 @@ Exit deathmatch games upon conditions
============ ============
*/ */
void() CheckRules = { void() CheckRules = {
float timelimit; float timelimit, fraglimit;
float fraglimit;
if(gameover) { // someone else quit the game already if(gameover) { // someone else quit the game already
return; return;
@ -630,12 +625,8 @@ void() CheckRules = {
timelimit = cvar("timelimit") * 60; timelimit = cvar("timelimit") * 60;
fraglimit = cvar("fraglimit"); fraglimit = cvar("fraglimit");
if(timelimit && time >= timelimit) { if((timelimit && time >= timelimit) ||
NextLevel(); (fraglimit && self.frags >= fraglimit)) {
return;
}
if(fraglimit && self.frags >= fraglimit) {
NextLevel(); NextLevel();
return; return;
} }
@ -707,17 +698,12 @@ void() PlayerJump = {
return; return;
} }
if(!(self.flags & FL_ONGROUND)) { if(!(self.flags & FL_ONGROUND) || !(self.flags & FL_JUMPRELEASED)) {
return;
}
if(!(self.flags & FL_JUMPRELEASED)) {
return; // don't pogo stick return; // don't pogo stick
} }
self.flags = self.flags - (self.flags & FL_JUMPRELEASED); self.flags -= (self.flags & FL_JUMPRELEASED);
self.flags -= FL_ONGROUND; // don't stairwalk
self.flags = self.flags - FL_ONGROUND; // don't stairwalk
self.button2 = 0; self.button2 = 0;
// player jumping sound // player jumping sound
@ -732,11 +718,7 @@ WaterMove
============ ============
*/ */
void() WaterMove = { void() WaterMove = {
//dprint(ftos(self.waterlevel)); if(self.movetype == MOVETYPE_NOCLIP || self.health < 0) {
if(self.movetype == MOVETYPE_NOCLIP) {
return;
}
if(self.health < 0) {
return; return;
} }
@ -843,13 +825,12 @@ Called every frame before physics are run
================ ================
*/ */
void() PlayerPreThink = { void() PlayerPreThink = {
// otherwise a button could be missed between the think tics
if(intermission_running) { if(intermission_running) {
IntermissionThink(); // otherwise a button could be missed between IntermissionThink();
return; // the think tics return;
} } else if(self.spectating) {
return;
if(self.view_ofs == VEC_ORIGIN) {
return; // intermission, finale or spectating
} }
makevectors(self.v_angle); // is this still used makevectors(self.v_angle); // is this still used
@ -895,7 +876,7 @@ Check for turning off powerups
================ ================
*/ */
void() CheckPowerups = { void() CheckPowerups = {
if(self.health <= 0) { if(self.health <= 0 || self.spectating) {
return; return;
} }
@ -1020,16 +1001,18 @@ Called every frame after physics are run
================ ================
*/ */
void() PlayerPostThink = { void() PlayerPostThink = {
if(self.view_ofs == VEC_ORIGIN) { if(time >= self.attack_finished) {
return; // intermission, finale or spectating ImpulseCommands();
} }
if(self.deadflag) {
if(self.spectating || self.deadflag) {
return; return;
} }
// do weapon stuff // do weapon stuff
if(time >= self.attack_finished) {
W_WeaponFrame(); W_WeaponFrame();
}
// check to see if player landed and play landing sound // check to see if player landed and play landing sound
if(self.jump_flag < -300 && self.flags & FL_ONGROUND && self.health > 0) { 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 = { void() ClientDisconnect = {
// if the level end trigger has been activated, just return
// since they aren't *really* leaving
if(gameover) { if(gameover) {
return; return;
} }
// if the level end trigger has been activated, just return
// since they aren't *really* leaving
// let everyone else know // let everyone else know
bprint(self.netname, " left the game with ", ftos(self.frags), " frags\n"); 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 = { void() cheat = {
if((deathmatch || coop) && !sf_cheats) { if(((deathmatch || coop) && !sf_cheats) || self.spectating) {
return; return;
} }
@ -1114,13 +1100,13 @@ void() cheat = {
}; };
void() cheat_quad = { void() cheat_quad = {
if((deathmatch || coop) && !sf_cheats) { if(((deathmatch || coop) && !sf_cheats) || self.spectating) {
return; return;
} }
self.super_time = 1; self.super_time = 1;
self.super_damage_finished = time + 30; self.super_damage_finished = time + 30;
self.items = self.items | IT_QUAD; self.items = self.items | IT_QUAD;
}; };
string(float pro) pronoun_subject = { string(float pro) pronoun_subject = {
@ -1545,7 +1531,7 @@ Player entered the suicide command
============ ============
*/ */
void() ClientKill = { void() ClientKill = {
if(self.view_ofs != VEC_ORIGIN) { if(!self.spectating) {
reset_death_vel(); reset_death_vel();
self.frags--; // extra penalty self.frags--; // extra penalty
ClientObituary(self, self); ClientObituary(self, self);

View File

@ -485,22 +485,6 @@ enum {
WORLD_BASE, 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 { enum {
DOOR_START_OPEN = 1, DOOR_START_OPEN = 1,
DOOR_DONT_LINK = 4, DOOR_DONT_LINK = 4,
@ -574,6 +558,23 @@ enum {
SIGIL_4 = 8, 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 { enum {
SF_CHEATS = 1, SF_CHEATS = 1,
SF_LIVES_BEG = 1, SF_LIVES_BEG = 1,
@ -581,6 +582,14 @@ enum {
SF_LIVES_MSK = 14, SF_LIVES_MSK = 14,
SF_DIST_AMMO = 16, SF_DIST_AMMO = 16,
}; };
enum {
SPECTATING_NOT,
SPECTATING_DEAD,
SPECTATING_SPECTATING,
SPECTATING_INTERMISSION,
SPECTATING_FINALE,
};
#pragma noref 0 #pragma noref 0
// globals -------------------------------------------------------------------| // globals -------------------------------------------------------------------|
@ -753,6 +762,7 @@ float ext_con_set;
// super co-op additions // super co-op additions
.float pronoun; .float pronoun;
.float lives; .float lives;
.float spectating;
// functions -----------------------------------------------------------------| // functions -----------------------------------------------------------------|
@ -921,4 +931,6 @@ void() func_train_find;
void(vector p) boss_missile; void(vector p) boss_missile;
void() ImpulseCommands;
// EOF // EOF

View File

@ -116,15 +116,16 @@ void() finale_1 = {
pl = find(world, classname, "player"); pl = find(world, classname, "player");
while(pl != world) { while(pl != world) {
pl.view_ofs = VEC_ORIGIN; pl.view_ofs = VEC_ORIGIN;
pl.angles = other.v_angle = pos.mangle; pl.angles = other.v_angle = pos.mangle;
pl.fixangle = TRUE; // turn this way immediately pl.fixangle = TRUE; // turn this way immediately
pl.map = self.map; pl.map = self.map;
pl.nextthink = time + 0.5; pl.nextthink = time + 0.5;
pl.takedamage = DAMAGE_NO; pl.takedamage = DAMAGE_NO;
pl.solid = SOLID_NOT; pl.solid = SOLID_NOT;
pl.movetype = MOVETYPE_NONE; pl.movetype = MOVETYPE_NONE;
pl.modelindex = 0; pl.modelindex = 0;
pl.spectating = SPECTATING_FINALE;
setorigin(pl, pos.origin); setorigin(pl, pos.origin);
pl = find(pl, classname, "player"); 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 = { void() W_WeaponFrame = {
if(time < self.attack_finished) {
return;
}
ImpulseCommands();
// check for attack // check for attack
if(self.button0) { if(self.button0) {
SuperDamageSound(); SuperDamageSound();