X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fgamemode_freezetag.qc;h=d6285cdafd112509b99e8c9ffcacd6b0430e3abe;hp=c1cb5b85145ae42db57d844c1264552f60fb6a17;hb=a08620064dbe59abd194f302768d65934b87b6df;hpb=410ff5f6cc4f7d5d8282ba9d93fe6a65d1c74489 diff --git a/qcsrc/server/mutators/gamemode_freezetag.qc b/qcsrc/server/mutators/gamemode_freezetag.qc index c1cb5b8514..d6285cdafd 100644 --- a/qcsrc/server/mutators/gamemode_freezetag.qc +++ b/qcsrc/server/mutators/gamemode_freezetag.qc @@ -1,67 +1,68 @@ .float freezetag_frozen_time; .float freezetag_frozen_timeout; -.float freezetag_revive_progress; -#define ICE_MAX_ALPHA 1 -#define ICE_MIN_ALPHA 0.1 +const float ICE_MAX_ALPHA = 1; +const float ICE_MIN_ALPHA = 0.1; float freezetag_teams; +const float SP_FREEZETAG_REVIVALS = 4; +void freezetag_ScoreRules(float teams) +{ + ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true); // SFL_SORT_PRIO_PRIMARY + ScoreInfo_SetLabel_PlayerScore(SP_FREEZETAG_REVIVALS, "revivals", 0); + ScoreRules_basics_end(); +} + void freezetag_count_alive_players() { entity e; total_players = redalive = bluealive = yellowalive = pinkalive = 0; - FOR_EACH_PLAYER(e) { - if(e.team == NUM_TEAM_1 && e.health >= 1) - { - ++total_players; - if (e.frozen != 1) ++redalive; - } - else if(e.team == NUM_TEAM_2 && e.health >= 1) - { - ++total_players; - if (e.frozen != 1) ++bluealive; - } - else if(e.team == NUM_TEAM_3 && e.health >= 1) - { - ++total_players; - if (e.frozen != 1) ++yellowalive; - } - else if(e.team == NUM_TEAM_4 && e.health >= 1) + FOR_EACH_PLAYER(e) + { + switch(e.team) { - ++total_players; - if (e.frozen != 1) ++pinkalive; + case NUM_TEAM_1: ++total_players; if(e.health >= 1 && e.frozen != 1) ++redalive; break; + case NUM_TEAM_2: ++total_players; if(e.health >= 1 && e.frozen != 1) ++bluealive; break; + case NUM_TEAM_3: ++total_players; if(e.health >= 1 && e.frozen != 1) ++yellowalive; break; + case NUM_TEAM_4: ++total_players; if(e.health >= 1 && e.frozen != 1) ++pinkalive; break; } } - FOR_EACH_REALCLIENT(e) { + FOR_EACH_REALCLIENT(e) + { e.redalive_stat = redalive; e.bluealive_stat = bluealive; e.yellowalive_stat = yellowalive; e.pinkalive_stat = pinkalive; } + + eliminatedPlayers.SendFlags |= 1; } #define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0)) #define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams) -float prev_total_players; float freezetag_CheckTeams() { + static float prev_missing_teams_mask; if(FREEZETAG_ALIVE_TEAMS_OK()) { - if(prev_total_players > 0) + if(prev_missing_teams_mask > 0) Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); - prev_total_players = -1; + prev_missing_teams_mask = -1; return 1; } - if(prev_total_players != total_players) + if(total_players == 0) + { + if(prev_missing_teams_mask > 0) + Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); + prev_missing_teams_mask = -1; + return 0; + } + float missing_teams_mask = (!redalive) + (!bluealive) * 2; + if(freezetag_teams >= 3) missing_teams_mask += (!yellowalive) * 4; + if(freezetag_teams >= 4) missing_teams_mask += (!pinkalive) * 8; + if(prev_missing_teams_mask != missing_teams_mask) { - float p1 = 0, p2 = 0, p3 = 0, p4 = 0; - if(!redalive) p1 = NUM_TEAM_1; - if(!bluealive) p2 = NUM_TEAM_2; - if(freezetag_teams >= 3) - if(!yellowalive) p3 = NUM_TEAM_3; - if(freezetag_teams >= 4) - if(!pinkalive) p4 = NUM_TEAM_4; - Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, p1, p2, p3, p4); - prev_total_players = total_players; + Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask); + prev_missing_teams_mask = missing_teams_mask; } return 0; } @@ -99,7 +100,10 @@ float freezetag_CheckWinner() Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER); Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER); FOR_EACH_PLAYER(e) + { e.freezetag_frozen_timeout = 0; + nades_Clear(e); + } round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit); return 1; } @@ -122,11 +126,42 @@ float freezetag_CheckWinner() } FOR_EACH_PLAYER(e) + { e.freezetag_frozen_timeout = 0; + nades_Clear(e); + } round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit); return 1; } +entity freezetag_LastPlayerForTeam() +{ + entity pl, last_pl = world; + FOR_EACH_PLAYER(pl) + { + if(pl.health >= 1) + if(!pl.frozen) + if(pl != self) + if(pl.team == self.team) + if(!last_pl) + last_pl = pl; + else + return world; + } + return last_pl; +} + +void freezetag_LastPlayerForTeam_Notify() +{ + if(round_handler_IsActive()) + if(round_handler_IsRoundStarted()) + { + entity pl = freezetag_LastPlayerForTeam(); + if(pl) + Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE); + } +} + void freezetag_Add_Score(entity attacker) { if(attacker == self) @@ -149,9 +184,12 @@ void freezetag_Freeze(entity attacker) { if(self.frozen) return; - - Freeze(self, 0, 1, TRUE); - + + if(autocvar_g_freezetag_frozen_maxtime > 0) + self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime; + + Freeze(self, 0, 1, true); + freezetag_count_alive_players(); freezetag_Add_Score(attacker); @@ -161,10 +199,18 @@ void freezetag_Unfreeze(entity attacker) { self.freezetag_frozen_time = 0; self.freezetag_frozen_timeout = 0; - + Unfreeze(self); } +float freezetag_isEliminated(entity e) +{ + if(IS_PLAYER(e) && (e.frozen == 1 || e.deadflag != DEAD_NO)) + return true; + return false; +} + + // ================ // Bot player logic // ================ @@ -276,6 +322,8 @@ void havocbot_role_ft_freeing() MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer) { self.health = 0; // neccessary to update correctly alive stats + if(!self.frozen) + freezetag_LastPlayerForTeam_Notify(); freezetag_Unfreeze(world); freezetag_count_alive_players(); return 1; @@ -302,9 +350,11 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies) { freezetag_Add_Score(frag_attacker); freezetag_count_alive_players(); + freezetag_LastPlayerForTeam_Notify(); } else freezetag_Unfreeze(world); // remove ice + self.health = 0; // Unfreeze resets health self.freezetag_frozen_timeout = -2; // freeze on respawn return 1; } @@ -313,6 +363,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies) return 1; freezetag_Freeze(frag_attacker); + freezetag_LastPlayerForTeam_Notify(); if(frag_attacker == frag_target || frag_attacker == world) { @@ -359,8 +410,7 @@ MUTATOR_HOOKFUNCTION(freezetag_reset_map_players) { FOR_EACH_PLAYER(self) { - if (self.frozen) - freezetag_Unfreeze(world); + self.killcount = 0; self.freezetag_frozen_timeout = -1; PutClientInServer(); self.freezetag_frozen_timeout = 0; @@ -395,8 +445,9 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink) entity o; o = world; - if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout) - self.iceblock.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time); + //if(self.frozen) + //if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout) + //self.iceblock.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time); if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout) n = -1; @@ -404,29 +455,25 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink) { vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size; n = 0; - FOR_EACH_PLAYER(other) if(self != other) + FOR_EACH_PLAYER(other) + if(self != other) + if(other.frozen == 0) + if(other.deadflag == DEAD_NO) + if(SAME_TEAM(other, self)) + if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax)) { - if(other.frozen == 0) - { - if(SAME_TEAM(other, self)) - { - if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax)) - { - if(!o) - o = other; - if(self.frozen == 1) - other.reviving = TRUE; - ++n; - } - } - } + if(!o) + o = other; + if(self.frozen == 1) + other.reviving = true; + ++n; } } if(n && self.frozen == 1) // OK, there is at least one teammate reviving us { self.revive_progress = bound(0, self.revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1); - self.health = max(1, self.revive_progress * autocvar_g_balance_health_start); + self.health = max(1, self.revive_progress * ((warmup_stage) ? warmup_start_health : start_health)); if(self.revive_progress >= 1) { @@ -447,6 +494,8 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink) { PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1); PlayerScore_Add(other, SP_SCORE, +1); + + nades_GiveBonus(other,autocvar_g_nades_bonus_score_low); } } @@ -460,14 +509,14 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink) if(other.reviving) { other.revive_progress = self.revive_progress; - other.reviving = FALSE; + other.reviving = false; } } } else if(!n && self.frozen == 1) // only if no teammate is nearby will we reset { self.revive_progress = bound(0, self.revive_progress - frametime * autocvar_g_freezetag_revive_clearspeed, 1); - self.health = max(1, self.revive_progress * autocvar_g_balance_health_start); + self.health = max(1, self.revive_progress * ((warmup_stage) ? warmup_start_health : start_health)); } else if(!n && !self.frozen) { @@ -477,30 +526,9 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink) return 1; } -MUTATOR_HOOKFUNCTION(freezetag_PlayerDamage_Calculate) -{ - if(frag_target.frozen == 1 && frag_deathtype != DEATH_HURTTRIGGER) - { - if(autocvar_g_freezetag_revive_falldamage > 0) - if(frag_deathtype == DEATH_FALL) - if(frag_damage >= autocvar_g_freezetag_revive_falldamage) - { - freezetag_Unfreeze(frag_target); - frag_target.health = autocvar_g_freezetag_revive_falldamage_health; - pointparticles(particleeffectnum("iceorglass"), frag_target.origin, '0 0 0', 3); - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, frag_target.netname); - Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_REVIVE_FALL); - } - - frag_damage = 0; - frag_force = frag_force * autocvar_g_freezetag_frozen_force; - } - return 1; -} - MUTATOR_HOOKFUNCTION(freezetag_BotRoles) { - if not(self.deadflag) + if (!self.deadflag) { if (random() < 0.5) self.havocbot_role = havocbot_role_ft_freeing; @@ -508,23 +536,22 @@ MUTATOR_HOOKFUNCTION(freezetag_BotRoles) self.havocbot_role = havocbot_role_ft_offense; } - return TRUE; + return true; } MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount) { - freezetag_teams = autocvar_g_freezetag_teams_override; - if(freezetag_teams < 2) - freezetag_teams = autocvar_g_freezetag_teams; - freezetag_teams = bound(2, freezetag_teams, 4); ret_float = freezetag_teams; return 0; } void freezetag_Initialize() { - precache_model("models/ice/ice.md3"); - ScoreRules_freezetag(); + freezetag_teams = autocvar_g_freezetag_teams_override; + if(freezetag_teams < 2) + freezetag_teams = autocvar_g_freezetag_teams; + freezetag_teams = bound(2, freezetag_teams, 4); + freezetag_ScoreRules(freezetag_teams); round_handler_Spawn(freezetag_CheckTeams, freezetag_CheckWinner, func_null); round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit); @@ -533,6 +560,8 @@ void freezetag_Initialize() addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat); addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat); addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat); + + EliminatedPlayers_Init(freezetag_isEliminated); } MUTATOR_DEFINITION(gamemode_freezetag) @@ -544,8 +573,7 @@ MUTATOR_DEFINITION(gamemode_freezetag) MUTATOR_HOOK(reset_map_players, freezetag_reset_map_players, CBC_ORDER_ANY); MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST); MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST); - MUTATOR_HOOK(PlayerDamage_Calculate, freezetag_PlayerDamage_Calculate, CBC_ORDER_ANY); - MUTATOR_HOOK(HavocBot_ChooseRule, freezetag_BotRoles, CBC_ORDER_ANY); + MUTATOR_HOOK(HavocBot_ChooseRole, freezetag_BotRoles, CBC_ORDER_ANY); MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE); MUTATOR_ONADD