From c0f7b9b69d62436eebc89f124c445d93821dfd12 Mon Sep 17 00:00:00 2001 From: terencehill Date: Sun, 14 Nov 2021 10:59:27 +0100 Subject: [PATCH] LMS: update leader waypoints when a player disconnects or becomes spectator too --- qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc | 142 +++++++++--------- 1 file changed, 73 insertions(+), 69 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc index 95ecb8b8d..a4ad5cd52 100644 --- a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc +++ b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc @@ -128,6 +128,76 @@ int WinningCondition_LMS() return WINNING_NO; } +// runs on waypoints which are attached to leaders, updates once per frame +bool lms_waypointsprite_visible_for_player(entity this, entity player, entity view) +{ + if(view.lms_wp_time) + if(IS_SPEC(player)) + return false; // we don't want spectators of leaders to see the attached waypoint on the top of their screen + + float leader_time = autocvar_g_lms_leader_wp_time; + float leader_repeat_time = leader_time + autocvar_g_lms_leader_wp_time_repeat; + float wp_time = this.owner.lms_wp_time; + if (wp_time && (time - wp_time) % leader_repeat_time > leader_time) + return false; + + return true; +} + +void lms_UpdateWaypoints() +{ + int max_lives = 0; + int pl_cnt = 0; + FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { + int lives = GameRules_scoring_add(it, LMS_LIVES, 0); + if (lives > max_lives) + max_lives = lives; + pl_cnt++; + }); + + int second_max_lives = 0; + int pl_cnt_with_max_lives = 0; + FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { + int lives = GameRules_scoring_add(it, LMS_LIVES, 0); + if (lives == max_lives) + pl_cnt_with_max_lives++; + else if (lives > second_max_lives) + second_max_lives = lives; + }); + + int lives_diff = autocvar_g_lms_leader_wp_lives; + if (max_lives - second_max_lives >= lives_diff && pl_cnt_with_max_lives <= pl_cnt * autocvar_g_lms_leader_wp_max_relative) + FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { + int lives = GameRules_scoring_add(it, LMS_LIVES, 0); + if (lives == max_lives) + { + if (!it.waypointsprite_attachedforcarrier) + { + WaypointSprite_AttachCarrier(WP_LmsLeader, it, RADARICON_FLAGCARRIER); + it.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = lms_waypointsprite_visible_for_player; + WaypointSprite_UpdateRule(it.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT); + vector pl_color = colormapPaletteColor(it.clientcolors & 0x0F, false); + WaypointSprite_UpdateTeamRadar(it.waypointsprite_attachedforcarrier, RADARICON_FLAGCARRIER, pl_color); + WaypointSprite_Ping(it.waypointsprite_attachedforcarrier); + } + if (!it.lms_wp_time) + it.lms_wp_time = time; + } + else + { + if (it.waypointsprite_attachedforcarrier) + WaypointSprite_Kill(it.waypointsprite_attachedforcarrier); + it.lms_wp_time = 0; + } + }); + else + FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { + if (it.waypointsprite_attachedforcarrier) + WaypointSprite_Kill(it.waypointsprite_attachedforcarrier); + it.lms_wp_time = 0; + }); +} + // mutator hooks MUTATOR_HOOKFUNCTION(lms, reset_map_global) { @@ -157,6 +227,7 @@ MUTATOR_HOOKFUNCTION(lms, reset_map_players) TRANSMUTE(Player, it); PutClientInServer(it); + it.lms_wp_time = 0; if (it.waypointsprite_attachedforcarrier) WaypointSprite_Kill(it.waypointsprite_attachedforcarrier); }); @@ -293,6 +364,8 @@ void lms_RemovePlayer(entity player) player.frags = FRAGS_PLAYER_OUT_OF_GAME; TRANSMUTE(Observer, player); } + if (autocvar_g_lms_leader_wp_lives > 0) + lms_UpdateWaypoints(); } if (CS(player).killcount != FRAGS_SPECTATOR && player.lms_spectate_warning < 3) @@ -405,75 +478,6 @@ MUTATOR_HOOKFUNCTION(lms, Damage_Calculate) } } -bool lms_waypointsprite_visible_for_player(entity this, entity player, entity view) // runs on waypoints which are attached to ballcarriers, updates once per frame -{ - if(view.lms_wp_time) - if(IS_SPEC(player)) - return false; // we don't want spectators of leaders to see the attached waypoint on the top of their screen - - float leader_time = autocvar_g_lms_leader_wp_time; - float leader_repeat_time = leader_time + autocvar_g_lms_leader_wp_time_repeat; - float wp_time = this.owner.lms_wp_time; - if (wp_time && (time - wp_time) % leader_repeat_time > leader_time) - return false; - - return true; -} - -void lms_UpdateWaypoints() -{ - int max_lives = 0; - int pl_cnt = 0; - FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { - int lives = GameRules_scoring_add(it, LMS_LIVES, 0); - if (lives > max_lives) - max_lives = lives; - pl_cnt++; - }); - - int second_max_lives = 0; - int pl_cnt_with_max_lives = 0; - FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { - int lives = GameRules_scoring_add(it, LMS_LIVES, 0); - if (lives == max_lives) - pl_cnt_with_max_lives++; - else if (lives > second_max_lives) - second_max_lives = lives; - }); - - int lives_diff = autocvar_g_lms_leader_wp_lives; - if (max_lives - second_max_lives >= lives_diff && pl_cnt_with_max_lives <= pl_cnt * autocvar_g_lms_leader_wp_max_relative) - FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { - int lives = GameRules_scoring_add(it, LMS_LIVES, 0); - if (lives == max_lives) - { - if (!it.waypointsprite_attachedforcarrier) - { - WaypointSprite_AttachCarrier(WP_LmsLeader, it, RADARICON_FLAGCARRIER); - it.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = lms_waypointsprite_visible_for_player; - WaypointSprite_UpdateRule(it.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT); - vector pl_color = colormapPaletteColor(it.clientcolors & 0x0F, false); - WaypointSprite_UpdateTeamRadar(it.waypointsprite_attachedforcarrier, RADARICON_FLAGCARRIER, pl_color); - WaypointSprite_Ping(it.waypointsprite_attachedforcarrier); - } - if (!it.lms_wp_time) - it.lms_wp_time = time; - } - else - { - if (it.waypointsprite_attachedforcarrier) - WaypointSprite_Kill(it.waypointsprite_attachedforcarrier); - it.lms_wp_time = 0; - } - }); - else - FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { - if (it.waypointsprite_attachedforcarrier) - WaypointSprite_Kill(it.waypointsprite_attachedforcarrier); - it.lms_wp_time = 0; - }); -} - MUTATOR_HOOKFUNCTION(lms, PlayerDied) { if (!warmup_stage && autocvar_g_lms_leader_wp_lives > 0) -- 2.39.5