{
FOREACH_CLIENT(true, {
if (it.frags == FRAGS_PLAYER_OUT_OF_GAME)
- {
- // players who forfeited (rank >= 256) become spectators
- if (it.lms_spectate_warning == 2)
- it.frags = FRAGS_SPECTATOR;
- else
- it.frags = FRAGS_PLAYER;
- }
+ it.frags = FRAGS_PLAYER;
CS(it).killcount = 0;
INGAME_STATUS_CLEAR(it);
- it.lms_spectate_warning = 0;
+ it.lms_spectate = false;
GameRules_scoring_add(it, LMS_RANK, -GameRules_scoring_add(it, LMS_RANK, 0));
GameRules_scoring_add(it, LMS_LIVES, -GameRules_scoring_add(it, LMS_LIVES, 0));
}
if (warmup_stage || time <= game_starttime)
{
- if(player.lms_spectate_warning)
- {
- player.lms_spectate_warning = 0;
- GameRules_scoring_add(player, LMS_RANK, -GameRules_scoring_add(player, LMS_RANK, 0));
- int lives = GameRules_scoring_add(player, LMS_LIVES, 0);
- if(lives <= 0)
- GameRules_scoring_add(player, LMS_LIVES, LMS_NewPlayerLives());
- }
+ player.lms_spectate = false;
+ GameRules_scoring_add(player, LMS_RANK, -GameRules_scoring_add(player, LMS_RANK, 0));
+ int lives = GameRules_scoring_add(player, LMS_LIVES, 0);
+ if(lives <= 0)
+ GameRules_scoring_add(player, LMS_LIVES, LMS_NewPlayerLives());
}
else
{
}
}
+int last_forfeiter_lives;
+float last_forfeiter_health;
+float last_forfeiter_armorvalue;
MUTATOR_HOOKFUNCTION(lms, PlayerSpawn)
{
entity player = M_ARGV(0, entity);
int pl_lives = GameRules_scoring_add(player, LMS_LIVES, 0);
float min_health = start_health;
float min_armorvalue = start_armorvalue;
+ if (last_forfeiter_lives == pl_lives)
+ {
+ min_health = last_forfeiter_health;
+ min_armorvalue = last_forfeiter_armorvalue;
+ }
FOREACH_CLIENT(it != player && IS_PLAYER(it) && !IS_DEAD(it) && GameRules_scoring_add(it, LMS_LIVES, 0) == pl_lives, {
if (GetResource(it, RES_HEALTH) < min_health)
min_health = GetResource(it, RES_HEALTH);
float player_rank = GameRules_scoring_add(player, LMS_RANK, 0);
if (!player_rank)
{
- if (player.lms_spectate_warning < 2)
+ if (!player.lms_spectate)
{
player.frags = FRAGS_PLAYER_OUT_OF_GAME;
int pl_cnt = 0;
}
else if (INGAME(player))
{
- int min_forfeiter_rank = 665; // different from 666
FOREACH_CLIENT(it != player, {
- // update rank of other players that were eliminated
+ // update rank of other players
if (it.frags == FRAGS_PLAYER_OUT_OF_GAME)
+ GameRules_scoring_add(it, LMS_RANK, -1);
+ });
+ int rank = GameRules_scoring_add(player, LMS_RANK, 0);
+ GameRules_scoring_add(player, LMS_RANK, -rank);
+ if(!warmup_stage)
+ {
+ int pl_lives = GameRules_scoring_add(player, LMS_LIVES, 0);
+ if (!last_forfeiter_lives || pl_lives < last_forfeiter_lives)
{
- float it_rank = GameRules_scoring_add(it, LMS_RANK, 0);
- if (it_rank > player_rank && it_rank <= 256)
- GameRules_scoring_add(it, LMS_RANK, -1);
- if (it_rank > 256 && it_rank <= min_forfeiter_rank)
- min_forfeiter_rank = it_rank - 1;
+ last_forfeiter_lives = pl_lives;
+ last_forfeiter_health = GetResource(player, RES_HEALTH);
+ last_forfeiter_armorvalue = GetResource(player, RES_ARMOR);
}
- else if (it.frags != FRAGS_SPECTATOR)
+ else if (pl_lives == last_forfeiter_lives)
{
- float tl = GameRules_scoring_add(it, LMS_LIVES, 0);
- if(tl < lms_lowest_lives)
- lms_lowest_lives = tl;
+ // these values actually can belong to a different forfeiter
+ last_forfeiter_health = min(last_forfeiter_health, GetResource(player, RES_HEALTH));
+ last_forfeiter_armorvalue = min(last_forfeiter_armorvalue, GetResource(player, RES_ARMOR));
}
- });
- GameRules_scoring_add(player, LMS_RANK, min_forfeiter_rank);
- if(!warmup_stage)
- GameRules_scoring_add(player, LMS_LIVES, -GameRules_scoring_add(player, LMS_LIVES, 0));
- player.frags = FRAGS_PLAYER_OUT_OF_GAME;
+ GameRules_scoring_add(player, LMS_LIVES, -pl_lives);
+ }
+ player.frags = FRAGS_SPECTATOR;
TRANSMUTE(Observer, player);
+ INGAME_STATUS_CLEAR(player);
+ player.lms_spectate = false;
+ CS(player).killcount = FRAGS_SPECTATOR;
}
if (autocvar_g_lms_leader_lives_diff > 0)
lms_UpdateLeaders();
}
- if (CS(player).killcount != FRAGS_SPECTATOR && player.lms_spectate_warning < 3)
+ if (CS(player).killcount != FRAGS_SPECTATOR)
{
- if (GameRules_scoring_add(player, LMS_RANK, 0) > 0 && player.lms_spectate_warning < 2)
+ if (GameRules_scoring_add(player, LMS_RANK, 0) > 0)
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_LMS_NOLIVES, player.netname);
- else
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_LMS_FORFEIT, player.netname);
}
}
{
entity player = M_ARGV(0, entity);
- // no further message other than the disconnect message
- player.lms_spectate_warning = 3;
+ player.lms_spectate = true;
lms_RemovePlayer(player);
INGAME_STATUS_CLEAR(player);
}
else
{
- if (is_forced)
- player.lms_spectate_warning = 2;
+ if (is_forced || player.killindicator_teamchange == -2) // player is forced or wants to spectate
+ player.lms_spectate = true;
if (!GameRules_scoring_add(player, LMS_RANK, 0))
lms_RemovePlayer(player);
}
MUTATOR_HOOKFUNCTION(lms, Bot_FixCount, CBC_ORDER_EXCLUSIVE)
{
FOREACH_CLIENT(IS_REAL_CLIENT(it), {
- if (INGAME(it) && it.lms_spectate_warning < 2)
+ if (INGAME(it))
++M_ARGV(0, int); // activerealplayers
++M_ARGV(1, int); // realplayers
});
MUTATOR_HOOKFUNCTION(lms, ClientCommand_Spectate)
{
entity player = M_ARGV(0, entity);
-
- if(warmup_stage || time < game_starttime || player.lms_spectate_warning)
- {
- // for the forfeit message...
- player.lms_spectate_warning = 2;
- }
- else
- {
- if(player.frags != FRAGS_SPECTATOR && player.frags != FRAGS_PLAYER_OUT_OF_GAME)
- {
- player.lms_spectate_warning = 1;
- sprint(player, "^1WARNING:^7 you can't rejoin this match after spectating. Use the same command again to spectate anyway.\n");
- Send_Notification(NOTIF_ONE_ONLY, player, MSG_CENTER, CENTER_LMS_SPECWARN);
- }
- return MUT_SPECCMD_RETURN;
- }
- return MUT_SPECCMD_CONTINUE;
+ if(player.frags != FRAGS_SPECTATOR && player.frags != FRAGS_PLAYER_OUT_OF_GAME)
+ return MUT_SPECCMD_CONTINUE;
+ // ranked players (out of game) can no longer become real spectators
+ return MUT_SPECCMD_RETURN;
}
MUTATOR_HOOKFUNCTION(lms, CheckRules_World)
MULTITEAM_INFO(KEYHUNT_DESTROYED, N_CONSOLE, 1, 0, "s1", "", "", _("^BG%s^BG destroyed the ^TC^TT Key"), "", KEY)
MULTITEAM_INFO(KEYHUNT_PICKUP, N_CONSOLE, 1, 0, "s1", "", "", _("^BG%s^BG picked up the ^TC^TT Key"), "", KEY)
- MSG_INFO_NOTIF(LMS_FORFEIT, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 forfeited"), "")
MSG_INFO_NOTIF(LMS_NOLIVES, N_CONSOLE, 1, 0, "s1", "", "", _("^BG%s^F3 has no more lives left"), "")
MSG_INFO_NOTIF(MONSTERS_DISABLED, N_CONSOLE, 0, 0, "", "", "", _("^BGMonsters are currently disabled"), "")
MULTITEAM_CENTER(KEYHUNT_START, N_ENABLE, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "", KEY)
MSG_CENTER_NOTIF(LMS_NOLIVES, N_ENABLE, 0, 0, "", CPID_LMS, "0 0", _("^BGYou have no lives left, you must wait until the next match"), "")
- MSG_CENTER_NOTIF(LMS_SPECWARN, N_ENABLE, 0, 0, "", CPID_LMS, "0 0", _("^F4WARNING:^BG you can't rejoin this match after spectating.\nUse the same command again to spectate anyway."), "")
+ // TODO update notifications.cfg
MSG_CENTER_NOTIF(LMS_VISIBLE_LEADER, N_ENABLE, 0, 0, "", CPID_LMS, "0 0", _("^BGEnemies can now see you on radar!"), "")
MSG_CENTER_NOTIF(LMS_VISIBLE_OTHER, N_ENABLE, 0, 0, "", CPID_LMS, "0 0", _("^BGLeaders can now be seen by enemies on radar!"), "")