add sc_challenge for interruptable level transitions

master
an 2019-09-21 01:26:24 -04:00
parent 4095eb7d59
commit 8d8a46d259
6 changed files with 121 additions and 41 deletions

View File

@ -9,12 +9,24 @@ alias pronoun_ze_hir "impulse 27"
alias pronoun_ze_zir "impulse 28" alias pronoun_ze_zir "impulse 28"
alias spectate "impulse 13" alias spectate "impulse 13"
alias reject_challenge "impulse 14"
set sc_cheats 0 set sc_cheats 0
set sc_lives 0 set sc_lives 0
set sc_dist_ammo 0 set sc_dist_ammo 0
set sc_challenge 0
bind p "reject_challenge"
echo "To change your pronouns in-game use one of the pronoun_ commands." echo "To change your pronouns in-game use one of the pronoun_ commands."
echo "You can get a list by typing 'pronoun_' and pressing tab." echo "You can get a list by typing 'pronoun_' and pressing tab."
echo
echo "If the server supports it, you can also put (possessive) after your"
echo "name, and it will be automatically detected. Example:"
echo "_cl_name Marrub (their)"
echo
echo "To reject travel to another level while sc_challenge is set, you"
echo "may type 'reject_challenge' into the console, which by default is"
echo "bound to 'p'."
// EOF // EOF

View File

@ -371,22 +371,7 @@ void() execute_changelevel = {
write_byte(MSG_ALL, SVC_INTERMISSION); write_byte(MSG_ALL, SVC_INTERMISSION);
}; };
void() changelevel_touch = { void() changelevel_finish = {
entity pos;
if(other.classname != "player") {
return;
}
if(cvar("noexit") == 1 || (cvar("noexit") == 2 && mapname != "start")) {
ent_damage(other, self, self, 50000);
return;
}
if(coop || deathmatch) {
print_all(other.netname, " exited the level\n");
}
nextmap = self.map; nextmap = self.map;
sub_use_targets(); sub_use_targets();
@ -404,6 +389,75 @@ void() changelevel_touch = {
self.nextthink = time + 0.1; self.nextthink = time + 0.1;
}; };
void() set_challenge_reject = {
if(changelevel_challenge == CHALLENGE_ACTIVE) {
changelevel_challenge = CHALLENGE_REJECTED;
challenge_rejecter = self.netname;
}
};
void() changelevel_think = {
entity pl;
if(changelevel_challenge == CHALLENGE_REJECTED) {
pl = find(world, classname, "player");
while(pl != world) {
print_center(pl, "The travel was canceled by\n", challenge_rejecter);
pl = find(pl, classname, "player");
}
changelevel_challenge = CHALLENGE_NONE;
self.netname = string_null;
self.aflag = 0;
return;
}
if(self.aflag == 0) {
changelevel_finish();
return;
}
pl = find(world, classname, "player");
while(pl != world) {
print_center(pl,
self.netname,
"\ninitiated travel to\n",
self.map, "\n\n",
ftos(self.aflag), " seconds to travel");
pl = find(pl, classname, "player");
}
sound(self, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NONE);
self.aflag--;
self.nextthink = time + 1;
};
void() changelevel_touch = {
entity pos;
if(other.classname != "player" || changelevel_challenge) {
return;
}
if(cvar("noexit") == 1 || (cvar("noexit") == 2 && mapname != "start")) {
ent_damage(other, self, self, 50000);
return;
}
if(sc_challenge) {
changelevel_challenge = CHALLENGE_ACTIVE;
self.netname = other.netname;
self.aflag = 10;
self.think = changelevel_think;
self.nextthink = time + 0.1;
} else {
if(coop || deathmatch) {
print_all(other.netname, " exited the level\n");
}
changelevel_finish();
}
};
/*QUAKED trigger_changelevel(0.5 0.5 0.5) ? NO_INTERMISSION /*QUAKED trigger_changelevel(0.5 0.5 0.5) ? NO_INTERMISSION
When the player touches this, they get sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats. When the player touches this, they get sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats.
*/ */
@ -566,7 +620,7 @@ void() PutClientInServer = {
respawned = player_respawned; respawned = player_respawned;
player_respawned = FALSE; player_respawned = FALSE;
if(sf_lives) { if(sc_lives) {
if(respawned) { if(respawned) {
self.lives--; self.lives--;
print_all(self.netname, " has "); print_all(self.netname, " has ");
@ -580,8 +634,8 @@ void() PutClientInServer = {
print_all(ftos(self.lives), " lives left\n"); print_all(ftos(self.lives), " lives left\n");
} }
} else if(self.lives == 0) { } else if(self.lives == 0) {
self.lives = sf_lives; self.lives = sc_lives;
print_dbg("lives reset to ", ftos(sf_lives), "\n"); print_dbg("lives reset to ", ftos(sc_lives), "\n");
} }
} else { } else {
self.lives = 1; self.lives = 1;
@ -1200,7 +1254,7 @@ void() ClientDisconnect = {
}; };
void() cheat = { void() cheat = {
if(((deathmatch || coop) && !sf_cheats) || self.spectating) { if(((deathmatch || coop) && !sc_cheats) || self.spectating) {
return; return;
} }
@ -1225,7 +1279,7 @@ void() cheat = {
}; };
void() cheat_quad = { void() cheat_quad = {
if(((deathmatch || coop) && !sf_cheats) || self.spectating) { if(((deathmatch || coop) && !sc_cheats) || self.spectating) {
return; return;
} }
@ -1278,11 +1332,12 @@ void() impulse_commands = {
change_pronoun(self.impulse - 20); change_pronoun(self.impulse - 20);
} else { } else {
switch(self.impulse) { switch(self.impulse) {
case 9: cheat(); break; case 9: cheat(); break;
case 10: wep_cycle_weapon(); break; case 10: wep_cycle_weapon(); break;
case 11: cheat_quad(); break; case 11: cheat_quad(); break;
case 12: wep_cycle_weapon_reverse(); break; case 12: wep_cycle_weapon_reverse(); break;
case 13: spectate(); break; case 13: spectate(); break;
case 14: set_challenge_reject(); break;
} }
} }

View File

@ -591,11 +591,12 @@ enum {
}; };
enum { enum {
SF_CHEATS = 1, SC_CHEATS = 1,
SF_LIVES_BEG = 1, SC_LIVES_BEG = 1,
SF_LIVES_END = 3, SC_LIVES_END = 3,
SF_LIVES_MSK = 14, SC_LIVES_MSK = 14,
SF_DIST_AMMO = 16, SC_DIST_AMMO = 16,
SC_CHALLENGE = 32,
}; };
enum { enum {
@ -605,6 +606,12 @@ enum {
SPECTATING_INTERMISSION, SPECTATING_INTERMISSION,
SPECTATING_FINALE, SPECTATING_FINALE,
}; };
enum {
CHALLENGE_NONE,
CHALLENGE_ACTIVE,
CHALLENGE_REJECTED,
};
#pragma noref 0 #pragma noref 0
// globals -------------------------------------------------------------------| // globals -------------------------------------------------------------------|
@ -651,13 +658,17 @@ entity sight_entity;
float sight_entity_time; float sight_entity_time;
// super co-op additions // super co-op additions
float sf_cheats; float sc_cheats;
float sf_lives; float sc_lives;
float sf_dist_ammo; float sc_dist_ammo;
float sc_challenge;
float player_respawned; float player_respawned;
float all_players_are_dead; float all_players_are_dead;
float changelevel_challenge;
string challenge_rejecter;
float ext_con_set; float ext_con_set;
float ext_strings; float ext_strings;

View File

@ -569,7 +569,7 @@ AMMO
void(.float ammo, float max) distribute_ammo = { void(.float ammo, float max) distribute_ammo = {
entity pl, stemp; entity pl, stemp;
if(sf_dist_ammo) { if(sc_dist_ammo) {
pl = find(world, classname, "player"); pl = find(world, classname, "player");
while(pl != world) { while(pl != world) {
pl.ammo += self.aflag; pl.ammo += self.aflag;

View File

@ -192,14 +192,16 @@ void() StartFrame = {
framecount = framecount + 1; framecount = framecount + 1;
if(ext_con_set) { if(ext_con_set) {
sf_cheats = cvar("sc_cheats"); sc_cheats = cvar("sc_cheats");
sf_lives = cvar("sc_lives"); sc_lives = cvar("sc_lives");
sf_dist_ammo = cvar("sc_dist_ammo"); sc_dist_ammo = cvar("sc_dist_ammo");
sc_challenge = cvar("sc_challenge");
} else { } else {
temp1flag = cvar("temp1"); temp1flag = cvar("temp1");
sf_cheats = (temp1flag & SF_CHEATS) != 0; sc_cheats = (temp1flag & SC_CHEATS) != 0;
sf_lives = bit_shift_right(temp1flag & SF_LIVES_MSK, SF_LIVES_BEG); sc_lives = bit_shift_right(temp1flag & SC_LIVES_MSK, SC_LIVES_BEG);
sf_dist_ammo = (temp1flag & SF_DIST_AMMO) != 0; sc_dist_ammo = (temp1flag & SC_DIST_AMMO) != 0;
sc_challenge = (temp1flag & SC_CHALLENGE) != 0;
} }
if(all_players_are_dead) { if(all_players_are_dead) {

2
todo
View File

@ -14,7 +14,6 @@ useful features:
configurable enemy stats configurable enemy stats
indicators for where other players are indicators for where other players are
users can cancel map ends ("<name> initiated travel to <mapname>")
extraneous features: extraneous features:
@ -37,3 +36,4 @@ lives counting
no friendly fire no friendly fire
rename all functions to be lower_underscore rename all functions to be lower_underscore
restart map after 10 seconds when everyone is dead restart map after 10 seconds when everyone is dead
users can cancel map ends ("<name> initiated travel to <mapname>")