54 static float prev_missing_teams_mask;
57 if(prev_missing_teams_mask > 0)
58 Kill_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CPID_MISSING_TEAMS);
59 prev_missing_teams_mask = -1;
64 if(prev_missing_teams_mask > 0)
65 Kill_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CPID_MISSING_TEAMS);
66 prev_missing_teams_mask = -1;
69 int missing_teams_mask = 0;
78 if(prev_missing_teams_mask != missing_teams_mask)
80 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
81 prev_missing_teams_mask = missing_teams_mask;
93 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CENTER_ROUND_OVER);
94 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_ROUND_OVER);
96 it.freezetag_frozen_timeout = 0;
97 it.freezetag_revive_time = 0;
111 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER,
APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
112 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
115 else if(winner_team == -1)
117 Send_Notification(NOTIF_ALL,
NULL, MSG_CENTER, CENTER_ROUND_TIED);
118 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_ROUND_TIED);
122 it.freezetag_frozen_timeout = 0;
123 it.freezetag_revive_time = 0;
154 Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE);
179 if(STAT(FROZEN, targ))
182 targ.freezetag_frozen_time =
time;
215 if(
vdist(it.origin - org, >, sradius))
221 &&
vlen2(it.origin - org) < best_dist2)
225 best_dist2 = vlen2(it.origin - org);
226 if (best_dist2 < 700 ** 2)
338 float frag_deathtype =
M_ARGV(3,
float);
346 frag_target.respawn_time =
time;
351 frag_target.respawn_time =
time + 1;
357 || frag_deathtype == DEATH_TEAMCHANGE.m_id || frag_deathtype == DEATH_AUTOTEAMCHANGE.m_id)
365 frag_target.freezetag_frozen_timeout = -2;
369 float t = frag_target.freezetag_frozen_timeout;
370 float t2 = frag_target.freezetag_frozen_time;
374 frag_target.freezetag_frozen_timeout = -t;
375 frag_target.freezetag_frozen_time = t2;
386 if(frag_attacker == frag_target || frag_attacker ==
NULL)
389 Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_SELF);
390 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_FREEZETAG_SELF, frag_target.netname);
394 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
404 if(player.freezetag_frozen_timeout == -1)
407 if(player.freezetag_frozen_timeout <= -2)
409 float t = player.freezetag_frozen_timeout;
410 float t2 = player.freezetag_frozen_time;
414 player.freezetag_frozen_timeout = -t;
415 player.freezetag_frozen_time = t2;
425 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_SPAWN_LATE);
435 CS(it).killcount = 0;
436 it.freezetag_revive_time = 0;
437 it.freezetag_frozen_timeout = -1;
439 it.freezetag_frozen_timeout = 0;
454 targ.freezetag_frozen_time = 0;
455 targ.freezetag_frozen_timeout = 0;
471 && frag_target.freezetag_frozen_timeout >
time)
476 t =
vlen(frag_force);
479 if (frag_target.freezetag_frozen_force + t > maxforce)
481 t =
max(0, maxforce - frag_target.freezetag_frozen_force);
482 frag_target.freezetag_frozen_force = maxforce;
485 frag_target.freezetag_frozen_force += t;
488 frag_target.freezetag_frozen_timeout -= t;
489 if (frag_target.freezetag_frozen_timeout <
time)
490 frag_target.freezetag_frozen_timeout =
time;
495 #ifdef IN_REVIVING_RANGE 496 #undef IN_REVIVING_RANGE 499 #define IN_REVIVING_RANGE(player, it, revive_extra_size) \ 500 (it != player && !IS_DEAD(it) && SAME_TEAM(it, player) \ 501 && boxesoverlap(player.absmin - revive_extra_size, player.absmax + revive_extra_size, it.absmin, it.absmax)) 517 player.freezetag_frozen_force = 0;
525 bool player_is_reviving =
false;
536 player_is_reviving =
true;
549 while (it.freezetag_revive_time > 1)
551 GameRules_scoring_add(it, SCORE, +1);
552 it.freezetag_revive_time -= 1;
556 revivers_last.chain = it;
563 revivers_last.chain =
NULL;
568 if (!n && player.freezetag_frozen_timeout > 0 &&
time >= player.freezetag_frozen_timeout)
571 float base_progress = 0;
586 if (STAT(REVIVE_PROGRESS, player) > base_progress)
589 base_progress = STAT(REVIVE_PROGRESS, player);
594 STAT(REVIVE_PROGRESS, player) = base_progress;
597 STAT(REVIVE_PROGRESS, player) =
bound(base_progress, STAT(REVIVE_PROGRESS, player) -
frametime * clearspeed * (1 - base_progress), 1);
599 else if (!STAT(FROZEN, player) && !player_is_reviving)
600 STAT(REVIVE_PROGRESS, player) = base_progress;
607 STAT(REVIVE_PROGRESS, player) =
bound(base_progress, STAT(REVIVE_PROGRESS, player) +
frametime *
max(1/60, spd), 1);
609 if(STAT(REVIVE_PROGRESS, player) >= 1)
611 float frozen_time =
time - player.freezetag_frozen_time;
621 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_AUTO_REVIVED, frozen_time);
622 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_FREEZETAG_AUTO_REVIVED, player.netname, frozen_time);
627 for(
entity it = revivers_first; it; it = it.chain)
635 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_REVIVED, revivers_first.netname);
636 Send_Notification(NOTIF_ONE, revivers_first, MSG_CENTER, CENTER_FREEZETAG_REVIVE, player.netname);
637 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_FREEZETAG_REVIVED, player.netname, revivers_first.netname);
640 string revivers =
"";
641 for(
entity it = revivers_first; it; it = it.chain)
642 revivers =
strcat(revivers,
ftos(it.playerid),
",");
648 for(
entity it = revivers_first; it; it = it.chain)
649 STAT(REVIVE_PROGRESS, it) = STAT(REVIVE_PROGRESS, player);
654 entity player_wp = player.waypointsprite_attached;
655 if (n > 0 || (n == 0 && STAT(REVIVE_PROGRESS, player) > 0.95))
657 WaypointSprite_UpdateSprites(player_wp, WP_Reviving, WP_Null, WP_Null);
658 WaypointSprite_UpdateTeamRadar(player_wp, RADARICON_WAYPOINT,
WP_REVIVING_COLOR);
662 WaypointSprite_UpdateSprites(player_wp, WP_Frozen, WP_Null, WP_Null);
663 WaypointSprite_UpdateTeamRadar(player_wp, RADARICON_WAYPOINT,
WP_FROZEN_COLOR);
666 WaypointSprite_UpdateMaxHealth(player_wp, 1);
667 WaypointSprite_UpdateHealth(player_wp, STAT(REVIVE_PROGRESS, player));
675 start_items &= ~(IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS);
676 if(!
cvar(
"g_use_ammunition"))
703 bot.havocbot_role_timeout =
time + 10 +
random() * 10;
725 int kill_count_to_attacker =
M_ARGV(3,
int);
726 int kill_count_to_target =
M_ARGV(4,
int);
731 Send_Notification(NOTIF_ONE, frag_attacker, MSG_CHOICE, CHOICE_FRAG_FREEZE, frag_target.netname, kill_count_to_attacker, (
IS_BOT_CLIENT(frag_target) ? -1 :
CS(frag_target).
ping));
732 Send_Notification(NOTIF_ONE, frag_target, MSG_CHOICE, CHOICE_FRAGGED_FREEZE, frag_attacker.netname, kill_count_to_target,
741 if (cmd_name ==
"shuffleteams")
761 field(SP_FREEZETAG_REVIVALS,
"revivals", 0);
const int NUM_TEAMS
Number of teams in the game.
float autocvar_g_ft_start_ammo_fuel
int Team_IndexToBit(int index)
Converts team index into bit value that is used in team bitmasks.
#define APP_TEAM_NUM(num, prefix)
#define round_handler_IsActive()
#define GameRules_scoring(teams, spprio, stprio, fields)
float havocbot_role_timeout
float autocvar_g_ft_start_ammo_cells
bool freezetag_CheckTeams()
void freezetag_Initialize()
void navigation_goalrating_start(entity this)
void(entity this) havocbot_role_ft_freeing
const int CBC_ORDER_EXCLUSIVE
void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius)
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
float warmup_start_ammo_shells
void navigation_goalrating_end(entity this)
int autocvar_g_freezetag_revive_auto_reducible
Header file that describes the resource system.
float autocvar_g_freezetag_revive_speed_t2s
float autocvar_g_ft_start_health
void round_handler_Spawn(bool() canRoundStart_func, bool() canRoundEnd_func, void() roundStart_func)
float autocvar_g_freezetag_revive_clearspeed
entity freezetag_LastPlayerForTeam(entity this)
float TeamScore_AddToTeam(int t, float scorefield, float score)
Adds a score to the given team.
float autocvar_g_ft_start_ammo_rockets
bool freezetag_isEliminated(entity e)
void EliminatedPlayers_Init(float(entity) isEliminated_func)
int Team_GetNumberOfAlivePlayers(entity team_ent)
Returns the number of alive players in a team.
ClientState CS(Client this)
void Freeze(entity targ, float revivespeed, int frozen_type, bool show_waypoint)
#define FOREACH_CLIENT(cond, body)
#define GameRules_scoring_add(client, fld, value)
float autocvar_g_freezetag_revive_time_to_score
float autocvar_g_ft_start_ammo_plasma
const int SFL_SORT_PRIO_PRIMARY
#define round_handler_IsRoundStarted()
float autocvar_g_ft_start_armor
void PlayerPreThink(entity this)
void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius)
float autocvar_g_freezetag_revive_auto_reducible_maxforce
entity Entity_GetTeam(entity this)
Returns the team entity of the given entity.
float warmup_start_ammo_plasma
void freezetag_Freeze(entity targ, entity attacker)
float autocvar_g_freezetag_revive_extra_size
void navigation_routerating(entity this, entity e, float f, float rangebias)
#define IS_REAL_CLIENT(v)
string autocvar_g_freezetag_weaponarena
const vector WP_REVIVING_COLOR
void freezetag_Add_Score(entity targ, entity attacker)
float autocvar_g_freezetag_warmup
bool Entity_HasValidTeam(entity this)
Returns whether the given entity belongs to a valid team.
void Unfreeze(entity targ, bool reset_health)
float autocvar_g_freezetag_frozen_maxtime
void nades_GiveBonus(entity player, float score)
int autocvar_g_freezetag_teams_override
float warmup_start_ammo_cells
float warmup_start_ammo_fuel
bool navigation_goalrating_timeout(entity this)
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
void havocbot_goalrating_ft_freeplayers(entity this, float ratingscale, vector org, float sradius)
void freezetag_count_alive_players()
float autocvar_g_freezetag_round_timelimit
float autocvar_g_freezetag_revive_speed
const int CBC_ORDER_FIRST
void Team_SetNumberOfAlivePlayers(entity team_ent, int number)
Sets the number of alive players in a team.
#define round_handler_GetEndTime()
void GameLogEcho(string s)
int Team_GetNumberOfAliveTeams()
Returns the number of alive teams.
entity Team_GetTeamFromIndex(int index)
Returns the global team entity at the given index.
void navigation_goalrating_timeout_set(entity this)
float warmup_start_armorvalue
int autocvar_g_freezetag_revive_auto_progress
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define ITEM_DAMAGE_NEEDKILL(dt)
bool shuffleteams_on_reset_map
#define IN_REVIVING_RANGE(player, it, revive_extra_size)
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
float warmup_start_ammo_rockets
float autocvar_g_ft_start_ammo_shells
bool autocvar_g_freezetag_revive_auto
void havocbot_goalrating_waypoints(entity this, float ratingscale, vector org, float sradius)
float autocvar_g_ft_start_ammo_nails
const vector WP_FROZEN_COLOR
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
void freezetag_LastPlayerForTeam_Notify(entity this)
float warmup_start_health
void ft_RemovePlayer(entity this)
float autocvar_g_freezetag_revive_auto_reducible_forcefactor
int Team_GetWinnerAliveTeam()
Returns the winner team.
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings...
void havocbot_role_ft_offense(entity this)
bool autocvar_sv_eventlog
void round_handler_Init(float the_delay, float the_count, float the_round_timelimit)
bool freezetag_CheckWinner()
MUTATOR_HOOKFUNCTION(ft, ClientDisconnect)
float autocvar_g_freezetag_revive_spawnshield
#define round_handler_CountdownRunning()
float warmup_start_ammo_nails
void havocbot_role_ft_freeing(entity this)