float autocvar_g_balance_keyhunt_damageforcescale;
float autocvar_g_balance_keyhunt_delay_collect;
+float autocvar_g_balance_keyhunt_delay_damage_return;
float autocvar_g_balance_keyhunt_delay_return;
float autocvar_g_balance_keyhunt_delay_round;
float autocvar_g_balance_keyhunt_delay_tracking;
+float autocvar_g_balance_keyhunt_return_when_unreachable;
float autocvar_g_balance_keyhunt_dropvelocity;
float autocvar_g_balance_keyhunt_maxdist;
float autocvar_g_balance_keyhunt_protecttime;
f = key.team;
else
f = 30;
- s |= pow(32, key.count) * f;
+ s |= (32 ** key.count) * f;
}
FOREACH_CLIENT(true, LAMBDA(it.kh_state = s));
FOR_EACH_KH_KEY(key)
{
if(key.owner)
- key.owner.kh_state |= pow(32, key.count) * 31;
+ key.owner.kh_state |= (32 ** key.count) * 31;
}
//print(ftos((nextent(NULL)).kh_state), "\n");
}
void kh_WaitForPlayers();
void kh_Controller_Think(entity this) // called a lot
{
- if(intermission_running)
+ if(game_stopped)
return;
if(this.cnt > 0)
{
void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner) // update the score when a key is captured
{
string s;
- if(intermission_running)
+ if(game_stopped)
return;
if(frags_player)
key.angles_y -= key.owner.angles.y;
#endif
key.flags = 0;
- IL_REMOVE(g_items, key);
+ if(IL_CONTAINS(g_items, key))
+ IL_REMOVE(g_items, key);
key.solid = SOLID_NOT;
set_movetype(key, MOVETYPE_NONE);
key.team = key.owner.team;
key.damageforcescale = 0;
key.takedamage = DAMAGE_NO;
key.modelindex = kh_key_carried;
+ navigation_dynamicgoal_unset(key);
}
void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs several times times when all the keys are captured
}
// in any case:
setattachment(key, NULL, "");
- setorigin(key, key.owner.origin + '0 0 1' * (STAT(PL_MIN, NULL).z - KH_KEY_MIN_z));
+ setorigin(key, key.owner.origin + '0 0 1' * (STAT(PL_MIN, key.owner).z - KH_KEY_MIN_z));
key.angles = key.owner.angles;
#else
setorigin(key, key.owner.origin + key.origin.z * '0 0 1');
key.angles_y += key.owner.angles.y;
#endif
key.flags = FL_ITEM;
- IL_PUSH(g_items, key);
+ if(!IL_CONTAINS(g_items, key))
+ IL_PUSH(g_items, key);
key.solid = SOLID_TRIGGER;
set_movetype(key, MOVETYPE_TOSS);
key.pain_finished = time + autocvar_g_balance_keyhunt_delay_return;
key.takedamage = DAMAGE_YES;
// let key.team stay
key.modelindex = kh_key_dropped;
+ navigation_dynamicgoal_set(key);
key.kh_previous_owner = key.owner;
key.kh_previous_owner_playerid = key.owner.playerid;
}
return;
if(ITEM_DAMAGE_NEEDKILL(deathtype))
{
- // touching lava, or hurt trigger
- // what shall we do?
- // immediately return is bad
- // maybe start a shorter countdown?
+ this.pain_finished = bound(time, time + autocvar_g_balance_keyhunt_delay_damage_return, this.pain_finished);
+ return;
}
if(force == '0 0 0')
return;
void kh_Key_Touch(entity this, entity toucher) // runs many, many times when a key has been dropped and can be picked up
{
- if(intermission_running)
+ if(game_stopped)
return;
if(this.owner) // already carried
if(ITEM_TOUCH_NEEDKILL())
{
- // touching sky, or nodrop
- // what shall we do?
- // immediately return is bad
- // maybe start a shorter countdown?
+ this.pain_finished = bound(time, time + autocvar_g_balance_keyhunt_delay_damage_return, this.pain_finished);
+ return;
}
if (!IS_PLAYER(toucher))
first = false;
}
+ Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_KEYHUNT_CAPTURE), keyowner);
first = true;
}
int realteam = kh_Team_ByID(lostkey.count);
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(realteam, INFO_KEYHUNT_LOST), lostkey.kh_previous_owner.netname);
+ Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(loser_team, CENTER_ROUND_TEAM_LOSS));
+ if(attacker)
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(realteam, INFO_KEYHUNT_PUSHED), attacker.netname, lostkey.kh_previous_owner.netname);
+ else
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(realteam, INFO_KEYHUNT_DESTROYED), lostkey.kh_previous_owner.netname);
play2all(SND(KH_DESTROY));
te_tarexplosion(lostkey.origin);
void kh_Key_Think(entity this) // runs all the time
{
- if(intermission_running)
+ if(game_stopped)
return;
if(this.owner)
key.angles = '0 360 0' * random();
key.event_damage = kh_Key_Damage;
key.takedamage = DAMAGE_YES;
+ key.damagedbytriggers = autocvar_g_balance_keyhunt_return_when_unreachable;
+ key.damagedbycontents = autocvar_g_balance_keyhunt_return_when_unreachable;
key.modelindex = kh_key_dropped;
key.model = "key";
key.kh_dropperteam = 0;
setsize(key, KH_KEY_MIN, KH_KEY_MAX);
key.colormod = Team_ColorRGB(initial_owner.team) * KH_KEY_BRIGHTNESS;
key.reset = key_reset;
+ navigation_dynamicgoal_init(key, false);
switch(initial_owner.team)
{
++players;
));
if (!players)
- missing_teams |= pow(2, i);
+ missing_teams |= (2 ** i);
}
return missing_teams;
}
void kh_WaitForPlayers() // delay start of the round until enough players are present
{
+ static int prev_missing_teams_mask;
if(time < game_starttime)
{
+ if (prev_missing_teams_mask > 0)
+ Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_MISSING_TEAMS);
+ prev_missing_teams_mask = -1;
kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
return;
}
- static int prev_missing_teams_mask;
int missing_teams_mask = kh_GetMissingTeams();
if(!missing_teams_mask)
{
}
}
if(!head.owner)
- navigation_routerating(this, head, ratingscale_dropped * BOT_PICKUP_RATING_HIGH, 100000);
+ navigation_routerating(this, head, ratingscale_dropped * 10000, 100000);
else if(head.team == this.team)
- navigation_routerating(this, head.owner, ratingscale_team * BOT_PICKUP_RATING_HIGH, 100000);
+ navigation_routerating(this, head.owner, ratingscale_team * 10000, 100000);
else
- navigation_routerating(this, head.owner, ratingscale_enemy * BOT_PICKUP_RATING_HIGH, 100000);
+ navigation_routerating(this, head.owner, ratingscale_enemy * 10000, 100000);
}
havocbot_goalrating_items(this, 1, this.origin, 10000);
MUTATOR_HOOKFUNCTION(kh, reset_map_global)
{
- kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round + (game_starttime - time), kh_StartRound);
+ kh_WaitForPlayers(); // takes care of killing the "missing teams" message
}