X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fgamemodes%2Fgamemode%2Fsurvival%2Fsv_survival.qc;h=6414686e0bcc67638503f6aaeda15ecb9e67754b;hb=refs%2Fheads%2FMario%2Fsurvival;hp=f29c6b72a57c14a6bc46fcb97e5f873e03952793;hpb=d84bc9c6f444d8fcd8a28712230a677664628b27;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc b/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc index f29c6b72a..6414686e0 100644 --- a/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc +++ b/qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc @@ -1,24 +1,11 @@ #include "sv_survival.qh" float autocvar_g_survival_hunter_count = 0.25; -float autocvar_g_survival_round_timelimit = 180; +float autocvar_g_survival_round_timelimit = 120; float autocvar_g_survival_warmup = 10; bool autocvar_g_survival_punish_teamkill = true; bool autocvar_g_survival_reward_survival = true; -void surv_FakeTimeLimit(entity e, float t) -{ - if(!IS_REAL_CLIENT(e)) - return; - msg_entity = e; - WriteByte(MSG_ONE, 3); // svc_updatestat - WriteByte(MSG_ONE, 236); // STAT_TIMELIMIT - if(t < 0) - WriteCoord(MSG_ONE, autocvar_timelimit); - else - WriteCoord(MSG_ONE, (t + 1) / 60); -} - void nades_Clear(entity player); void Surv_UpdateScores(bool timed_out) @@ -30,8 +17,16 @@ void Surv_UpdateScores(bool timed_out) if(it.survival_validkills) GameRules_scoring_add(it, SCORE, it.survival_validkills); it.survival_validkills = 0; - if(autocvar_g_survival_reward_survival && timed_out && IS_PLAYER(it) && !IS_DEAD(it) && it.survival_status == SURV_STATUS_PREY) - GameRules_scoring_add(it, SCORE, 1); // reward survivors who make it to the end of the round time limit + // player survived the round + if(IS_PLAYER(it) && !IS_DEAD(it)) + { + if(autocvar_g_survival_reward_survival && timed_out && it.survival_status == SURV_STATUS_PREY) + GameRules_scoring_add(it, SCORE, 1); // reward survivors who make it to the end of the round time limit + if(it.survival_status == SURV_STATUS_PREY) + GameRules_scoring_add(it, SURV_SURVIVALS, 1); + else if(it.survival_status == SURV_STATUS_HUNTER) + GameRules_scoring_add(it, SURV_HUNTS, 1); + } }); } @@ -46,7 +41,6 @@ float Surv_CheckWinner() { if(IS_PLAYER(it)) nades_Clear(it); - surv_FakeTimeLimit(it, -1); }); Surv_UpdateScores(true); @@ -96,7 +90,6 @@ float Surv_CheckWinner() { if(IS_PLAYER(it)) nades_Clear(it); - surv_FakeTimeLimit(it, -1); }); return 1; @@ -133,8 +126,6 @@ void Surv_RoundStart() Send_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CENTER_SURVIVAL_SURVIVOR); else if(it.survival_status == SURV_STATUS_HUNTER) Send_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CENTER_SURVIVAL_HUNTER); - - surv_FakeTimeLimit(it, round_handler_GetEndTime()); }); } @@ -172,15 +163,20 @@ bool Surv_CheckPlayers() bool surv_isEliminated(entity e) { - if(e.caplayer == 1 && (IS_DEAD(e) || e.frags == FRAGS_PLAYER_OUT_OF_GAME)) + if(INGAME_JOINED(e) && (IS_DEAD(e) || e.frags == FRAGS_PLAYER_OUT_OF_GAME)) return true; - if(e.caplayer == 0.5) + if(INGAME_JOINING(e)) return true; return false; } void surv_Initialize() // run at the start of a match, initiates game mode { + GameRules_scoring(0, SFL_SORT_PRIO_PRIMARY, 0, { + field(SP_SURV_SURVIVALS, "survivals", 0); + field(SP_SURV_HUNTS, "hunts", SFL_SORT_PRIO_SECONDARY); + }); + allowed_to_spawn = true; round_handler_Spawn(Surv_CheckPlayers, Surv_CheckWinner, Surv_RoundStart); round_handler_Init(5, autocvar_g_survival_warmup, autocvar_g_survival_round_timelimit); @@ -207,7 +203,23 @@ MUTATOR_HOOKFUNCTION(surv, ClientObituary) GiveFrags(frag_attacker, frag_target, ((autocvar_g_survival_punish_teamkill) ? -1 : -2), frag_deathtype, wep_ent.weaponentity_fld); } - M_ARGV(5, bool) = true; // anonymous attacker + if(frag_attacker.survival_status == SURV_STATUS_HUNTER) + M_ARGV(5, bool) = true; // anonymous attacker +} + +MUTATOR_HOOKFUNCTION(surv, PlayerPreThink) +{ + entity player = M_ARGV(0, entity); + + if(IS_PLAYER(player) || INGAME_JOINED(player)) + { + // update the scoreboard colour display to out the real killer at the end of the round + // running this every frame to avoid cheats + int plcolor = SURV_COLOR_PREY; + if(player.survival_status == SURV_STATUS_HUNTER && game_stopped) + plcolor = SURV_COLOR_HUNTER; + setcolor(player, plcolor); + } } MUTATOR_HOOKFUNCTION(surv, PlayerSpawn) @@ -216,7 +228,7 @@ MUTATOR_HOOKFUNCTION(surv, PlayerSpawn) player.survival_status = 0; player.survival_validkills = 0; - player.caplayer = 1; + INGAME_STATUS_SET(player, INGAME_STATUS_JOINED); if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; } @@ -228,7 +240,7 @@ MUTATOR_HOOKFUNCTION(surv, ForbidSpawn) // spectators / observers that weren't playing can join; they are // immediately forced to observe in the PutClientInServer hook // this way they are put in a team and can play in the next round - if (!allowed_to_spawn && player.caplayer) + if (!allowed_to_spawn && INGAME(player)) return true; return false; } @@ -240,9 +252,9 @@ MUTATOR_HOOKFUNCTION(surv, PutClientInServer) if (!allowed_to_spawn && IS_PLAYER(player)) // this is true even when player is trying to join { TRANSMUTE(Observer, player); - if (CS(player).jointime != time && !player.caplayer) // not when connecting + if (CS(player).jointime != time && !INGAME(player)) // not when connecting { - player.caplayer = 0.5; + INGAME_STATUS_SET(player, INGAME_STATUS_JOINING); Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE); } } @@ -253,13 +265,10 @@ MUTATOR_HOOKFUNCTION(surv, reset_map_players) FOREACH_CLIENT(true, { CS(it).killcount = 0; it.survival_status = 0; - surv_FakeTimeLimit(it, -1); // restore original timelimit - if (!it.caplayer && IS_BOT_CLIENT(it)) - it.caplayer = 1; - if (it.caplayer) + if (INGAME(it) || IS_BOT_CLIENT(it)) { TRANSMUTE(Player, it); - it.caplayer = 1; + INGAME_STATUS_SET(it, INGAME_STATUS_JOINED); PutClientInServer(it); } }); @@ -294,7 +303,7 @@ void surv_LastPlayerForTeam_Notify(entity this) { entity pl = surv_LastPlayerForTeam(this); if (pl) - Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE); + Send_Notification(NOTIF_ONE_ONLY, pl, MSG_CENTER, CENTER_ALONE); } } @@ -316,7 +325,7 @@ MUTATOR_HOOKFUNCTION(surv, PlayerDies) { eliminatedPlayers.SendFlags |= 1; if (IS_BOT_CLIENT(frag_target)) - bot_clear(frag_target); + bot_clearqueue(frag_target); } // killed an ally! punishment is death @@ -338,20 +347,22 @@ MUTATOR_HOOKFUNCTION(surv, ClientDisconnect) MUTATOR_HOOKFUNCTION(surv, MakePlayerObserver) { entity player = M_ARGV(0, entity); + bool is_forced = M_ARGV(1, bool); + if (is_forced && INGAME(player)) + INGAME_STATUS_CLEAR(player); if (IS_PLAYER(player) && !IS_DEAD(player)) surv_LastPlayerForTeam_Notify(player); if (player.killindicator_teamchange == -2) // player wants to spectate - player.caplayer = 0; - if (player.caplayer) + INGAME_STATUS_CLEAR(player); + if (INGAME(player)) player.frags = FRAGS_PLAYER_OUT_OF_GAME; if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; - if (!player.caplayer) + if (!INGAME(player)) { player.survival_validkills = 0; player.survival_status = 0; - surv_FakeTimeLimit(player, -1); // restore original timelimit return false; // allow team reset } return true; // prevent team reset @@ -388,7 +399,7 @@ MUTATOR_HOOKFUNCTION(surv, CalculateRespawnTime) MUTATOR_HOOKFUNCTION(surv, Bot_FixCount, CBC_ORDER_EXCLUSIVE) { FOREACH_CLIENT(IS_REAL_CLIENT(it), { - if (IS_PLAYER(it) || it.caplayer == 1) + if (IS_PLAYER(it) || INGAME_JOINED(it)) ++M_ARGV(0, int); ++M_ARGV(1, int); }); @@ -399,7 +410,7 @@ MUTATOR_HOOKFUNCTION(surv, ClientCommand_Spectate) { entity player = M_ARGV(0, entity); - if (player.caplayer) + if (INGAME(player)) { // they're going to spec, we can do other checks if (autocvar_sv_spectate && (IS_SPEC(player) || IS_OBSERVER(player))) @@ -410,13 +421,6 @@ MUTATOR_HOOKFUNCTION(surv, ClientCommand_Spectate) return MUT_SPECCMD_CONTINUE; } -MUTATOR_HOOKFUNCTION(surv, GetPlayerStatus) -{ - entity player = M_ARGV(0, entity); - - return player.caplayer == 1; -} - MUTATOR_HOOKFUNCTION(surv, BotShouldAttack) { entity bot = M_ARGV(0, entity);