From 8d8a46d2598a4f6966956d18b2d15e891ef5dcd6 Mon Sep 17 00:00:00 2001 From: Alison Watson Date: Sat, 21 Sep 2019 01:26:24 -0400 Subject: [PATCH] add sc_challenge for interruptable level transitions --- default_sc.cfg | 12 ++++++ source/client.qc | 105 ++++++++++++++++++++++++++++++++++++----------- source/defs.qc | 27 ++++++++---- source/items.qc | 2 +- source/world.qc | 14 ++++--- todo | 2 +- 6 files changed, 121 insertions(+), 41 deletions(-) diff --git a/default_sc.cfg b/default_sc.cfg index 92165f9..c97603a 100644 --- a/default_sc.cfg +++ b/default_sc.cfg @@ -9,12 +9,24 @@ alias pronoun_ze_hir "impulse 27" alias pronoun_ze_zir "impulse 28" alias spectate "impulse 13" +alias reject_challenge "impulse 14" set sc_cheats 0 set sc_lives 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 "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 diff --git a/source/client.qc b/source/client.qc index 47589bb..0190140 100644 --- a/source/client.qc +++ b/source/client.qc @@ -371,22 +371,7 @@ void() execute_changelevel = { write_byte(MSG_ALL, SVC_INTERMISSION); }; -void() changelevel_touch = { - 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"); - } - +void() changelevel_finish = { nextmap = self.map; sub_use_targets(); @@ -404,6 +389,75 @@ void() changelevel_touch = { 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 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; player_respawned = FALSE; - if(sf_lives) { + if(sc_lives) { if(respawned) { self.lives--; print_all(self.netname, " has "); @@ -580,8 +634,8 @@ void() PutClientInServer = { print_all(ftos(self.lives), " lives left\n"); } } else if(self.lives == 0) { - self.lives = sf_lives; - print_dbg("lives reset to ", ftos(sf_lives), "\n"); + self.lives = sc_lives; + print_dbg("lives reset to ", ftos(sc_lives), "\n"); } } else { self.lives = 1; @@ -1200,7 +1254,7 @@ void() ClientDisconnect = { }; void() cheat = { - if(((deathmatch || coop) && !sf_cheats) || self.spectating) { + if(((deathmatch || coop) && !sc_cheats) || self.spectating) { return; } @@ -1225,7 +1279,7 @@ void() cheat = { }; void() cheat_quad = { - if(((deathmatch || coop) && !sf_cheats) || self.spectating) { + if(((deathmatch || coop) && !sc_cheats) || self.spectating) { return; } @@ -1278,11 +1332,12 @@ void() impulse_commands = { change_pronoun(self.impulse - 20); } else { switch(self.impulse) { - case 9: cheat(); break; - case 10: wep_cycle_weapon(); break; - case 11: cheat_quad(); break; + case 9: cheat(); break; + case 10: wep_cycle_weapon(); break; + case 11: cheat_quad(); break; case 12: wep_cycle_weapon_reverse(); break; - case 13: spectate(); break; + case 13: spectate(); break; + case 14: set_challenge_reject(); break; } } diff --git a/source/defs.qc b/source/defs.qc index 88ec671..5f3f73b 100644 --- a/source/defs.qc +++ b/source/defs.qc @@ -591,11 +591,12 @@ enum { }; enum { - SF_CHEATS = 1, - SF_LIVES_BEG = 1, - SF_LIVES_END = 3, - SF_LIVES_MSK = 14, - SF_DIST_AMMO = 16, + SC_CHEATS = 1, + SC_LIVES_BEG = 1, + SC_LIVES_END = 3, + SC_LIVES_MSK = 14, + SC_DIST_AMMO = 16, + SC_CHALLENGE = 32, }; enum { @@ -605,6 +606,12 @@ enum { SPECTATING_INTERMISSION, SPECTATING_FINALE, }; + +enum { + CHALLENGE_NONE, + CHALLENGE_ACTIVE, + CHALLENGE_REJECTED, +}; #pragma noref 0 // globals -------------------------------------------------------------------| @@ -651,13 +658,17 @@ entity sight_entity; float sight_entity_time; // super co-op additions -float sf_cheats; -float sf_lives; -float sf_dist_ammo; +float sc_cheats; +float sc_lives; +float sc_dist_ammo; +float sc_challenge; float player_respawned; float all_players_are_dead; +float changelevel_challenge; +string challenge_rejecter; + float ext_con_set; float ext_strings; diff --git a/source/items.qc b/source/items.qc index db83033..8a5a481 100644 --- a/source/items.qc +++ b/source/items.qc @@ -569,7 +569,7 @@ AMMO void(.float ammo, float max) distribute_ammo = { entity pl, stemp; - if(sf_dist_ammo) { + if(sc_dist_ammo) { pl = find(world, classname, "player"); while(pl != world) { pl.ammo += self.aflag; diff --git a/source/world.qc b/source/world.qc index 4798e33..52bf738 100644 --- a/source/world.qc +++ b/source/world.qc @@ -192,14 +192,16 @@ void() StartFrame = { framecount = framecount + 1; if(ext_con_set) { - sf_cheats = cvar("sc_cheats"); - sf_lives = cvar("sc_lives"); - sf_dist_ammo = cvar("sc_dist_ammo"); + sc_cheats = cvar("sc_cheats"); + sc_lives = cvar("sc_lives"); + sc_dist_ammo = cvar("sc_dist_ammo"); + sc_challenge = cvar("sc_challenge"); } else { temp1flag = cvar("temp1"); - sf_cheats = (temp1flag & SF_CHEATS) != 0; - sf_lives = bit_shift_right(temp1flag & SF_LIVES_MSK, SF_LIVES_BEG); - sf_dist_ammo = (temp1flag & SF_DIST_AMMO) != 0; + sc_cheats = (temp1flag & SC_CHEATS) != 0; + sc_lives = bit_shift_right(temp1flag & SC_LIVES_MSK, SC_LIVES_BEG); + sc_dist_ammo = (temp1flag & SC_DIST_AMMO) != 0; + sc_challenge = (temp1flag & SC_CHALLENGE) != 0; } if(all_players_are_dead) { diff --git a/todo b/todo index e09129e..6504e10 100644 --- a/todo +++ b/todo @@ -14,7 +14,6 @@ useful features: configurable enemy stats indicators for where other players are -users can cancel map ends (" initiated travel to ") extraneous features: @@ -37,3 +36,4 @@ lives counting no friendly fire rename all functions to be lower_underscore restart map after 10 seconds when everyone is dead +users can cancel map ends (" initiated travel to ")