From 3ab7e099570eaf057574e08759f38966da07f94c Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 25 Jun 2018 16:17:33 +1000 Subject: [PATCH] Add mutator hooks for freezing/unfreezing, make use of them to fix a revive bug in freezetag --- .../gamemodes/gamemode/freezetag/freezetag.qc | 26 ++++++++++--------- qcsrc/server/g_damage.qc | 10 ++++--- qcsrc/server/g_damage.qh | 2 +- qcsrc/server/mutators/events.qh | 18 +++++++++++++ 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/freezetag/freezetag.qc b/qcsrc/common/gamemodes/gamemode/freezetag/freezetag.qc index 1cdd4d1f8..9c5083209 100644 --- a/qcsrc/common/gamemodes/gamemode/freezetag/freezetag.qc +++ b/qcsrc/common/gamemodes/gamemode/freezetag/freezetag.qc @@ -182,6 +182,7 @@ void freezetag_Add_Score(entity targ, entity attacker) // else nothing - got frozen by the game type rules themselves } +// to be called when the player is frozen by freezetag (on death, spectator join etc), gives the score void freezetag_Freeze(entity targ, entity attacker) { if(STAT(FROZEN, targ)) @@ -197,14 +198,6 @@ void freezetag_Freeze(entity targ, entity attacker) freezetag_Add_Score(targ, attacker); } -void freezetag_Unfreeze(entity this) -{ - this.freezetag_frozen_time = 0; - this.freezetag_frozen_timeout = 0; - - Unfreeze(this); -} - float freezetag_isEliminated(entity e) { if(IS_PLAYER(e) && (STAT(FROZEN, e) == 1 || IS_DEAD(e))) @@ -313,7 +306,7 @@ void ft_RemovePlayer(entity this) SetResourceAmountExplicit(this, RESOURCE_HEALTH, 0); // neccessary to update correctly alive stats if(!STAT(FROZEN, this)) freezetag_LastPlayerForTeam_Notify(this); - freezetag_Unfreeze(this); + Unfreeze(this); freezetag_count_alive_players(); } @@ -342,7 +335,7 @@ MUTATOR_HOOKFUNCTION(ft, PlayerDies) if(round_handler_CountdownRunning()) { if(STAT(FROZEN, frag_target)) - freezetag_Unfreeze(frag_target); + Unfreeze(frag_target); freezetag_count_alive_players(); return true; // let the player die so that he can respawn whenever he wants } @@ -360,7 +353,7 @@ MUTATOR_HOOKFUNCTION(ft, PlayerDies) freezetag_LastPlayerForTeam_Notify(frag_target); } else - freezetag_Unfreeze(frag_target); // remove ice + Unfreeze(frag_target); // remove ice SetResourceAmountExplicit(frag_target, RESOURCE_HEALTH, 0); // Unfreeze resets health frag_target.freezetag_frozen_timeout = -2; // freeze on respawn return true; @@ -429,6 +422,15 @@ MUTATOR_HOOKFUNCTION(ft, GiveFragsForKill, CBC_ORDER_FIRST) return true; } +MUTATOR_HOOKFUNCTION(ft, Unfreeze) +{ + entity targ = M_ARGV(0, entity); + targ.freezetag_frozen_time = 0; + targ.freezetag_frozen_timeout = 0; + + freezetag_count_alive_players(); +} + MUTATOR_HOOKFUNCTION(ft, PlayerPreThink, CBC_ORDER_FIRST) { if(game_stopped) @@ -474,7 +476,7 @@ MUTATOR_HOOKFUNCTION(ft, PlayerPreThink, CBC_ORDER_FIRST) if(STAT(REVIVE_PROGRESS, player) >= 1) { - freezetag_Unfreeze(player); + Unfreeze(player); freezetag_count_alive_players(); if(n == -1) diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index cc0c71be5..4881fac2d 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -477,9 +477,9 @@ void Ice_Think(entity this) this.nextthink = time; } -void Freeze (entity targ, float revivespeed, float frozen_type, float show_waypoint) +void Freeze(entity targ, float revivespeed, int frozen_type, bool show_waypoint) { - if(!IS_PLAYER(targ) && !IS_MONSTER(targ)) // only specified entities can be freezed + if(!IS_PLAYER(targ) && !IS_MONSTER(targ)) // TODO: only specified entities can be freezed return; if(STAT(FROZEN, targ)) @@ -524,11 +524,11 @@ void Freeze (entity targ, float revivespeed, float frozen_type, float show_waypo }); // add waypoint - if(show_waypoint) + if(Freeze(targ, revivespeed, frozen_type) || show_waypoint) WaypointSprite_Spawn(WP_Frozen, 0, 0, targ, '0 0 64', NULL, targ.team, targ, waypointsprite_attached, true, RADARICON_WAYPOINT); } -void Unfreeze (entity targ) +void Unfreeze(entity targ) { if(!STAT(FROZEN, targ)) return; @@ -562,6 +562,8 @@ void Unfreeze (entity targ) if(targ.iceblock) delete(targ.iceblock); targ.iceblock = NULL; + + MUTATOR_CALLHOOK(Unfreeze, targ); } void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) diff --git a/qcsrc/server/g_damage.qh b/qcsrc/server/g_damage.qh index 88fbf1344..0af110c9e 100644 --- a/qcsrc/server/g_damage.qh +++ b/qcsrc/server/g_damage.qh @@ -83,7 +83,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .en void Ice_Think(entity this); -void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint); +void Freeze(entity targ, float freeze_time, int frozen_type, bool show_waypoint); void Unfreeze (entity targ); diff --git a/qcsrc/server/mutators/events.qh b/qcsrc/server/mutators/events.qh index de21a5903..a4cf9df8e 100644 --- a/qcsrc/server/mutators/events.qh +++ b/qcsrc/server/mutators/events.qh @@ -1174,3 +1174,21 @@ enum { MUT_VOTEPARSE_INVALID, // return -1 (vote parsed but counted as invalid, no action or vote) MUT_VOTEPARSE_UNACCEPTABLE // return 0 (vote parameter counted as unacceptable, warns caller) }; + +/** + * Called when freezing an entity (monster or player), return true to force showing a waypoint + */ +#define EV_Freeze(i, o) \ + /** targ */ i(entity, MUTATOR_ARGV_0_entity) \ + /** revive speed */ i(float, MUTATOR_ARGV_1_float) \ + /** frozen type */ i(int, MUTATOR_ARGV_2_int) \ + /**/ +MUTATOR_HOOKABLE(Freeze, EV_Freeze); + +/** + * Called when an entity (monster or player) is defrosted + */ +#define EV_Unfreeze(i, o) \ + /** targ */ i(entity, MUTATOR_ARGV_0_entity) \ + /**/ +MUTATOR_HOOKABLE(Unfreeze, EV_Unfreeze); -- 2.39.2