// 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))
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)))
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();
}
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
}
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;
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)
if(STAT(REVIVE_PROGRESS, player) >= 1)
{
- freezetag_Unfreeze(player);
+ Unfreeze(player);
freezetag_count_alive_players();
if(n == -1)
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))
});
// 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;
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)
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);
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);