41#ifdef KH_PLAYER_USE_ATTACHMENT
42const vector KH_PLAYER_ATTACHMENT_DIST_ROTATED =
'0 -4 0';
43const vector KH_PLAYER_ATTACHMENT_DIST =
'4 0 0';
44const vector KH_PLAYER_ATTACHMENT =
'0 0 0';
45const vector KH_PLAYER_ATTACHMENT_ANGLES =
'0 0 0';
46const string KH_PLAYER_ATTACHMENT_BONE =
"";
96 field(SP_KH_PUSHES,
"pushes", 0);
98 field(SP_KH_PICKUPS,
"pickups", 0);
99 field(SP_KH_KCKILLS,
"kckills", 0);
106 if(view.kh_next &&
IS_SPEC(player))
138 s |= (32 ** key.count) * f;
146 STAT(OBJECTIVE_STATUS, key.owner) |= (32 ** key.count) * 31;
172 else if(this.
cnt == 0)
193 if(key && key.owner && frags_owner)
199 s =
strcat(
":keyhunt:", what,
":",
ftos(player.playerid),
":",
ftos(frags_player));
209 s =
strcat(s, key.netname);
228#ifdef KH_PLAYER_USE_ATTACHMENT
229 entity first = key.owner.kh_next;
232 setattachment(key, key.owner, KH_PLAYER_ATTACHMENT_BONE);
235 setattachment(key.kh_next, key,
"");
236 setorigin(key, key.kh_next.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
237 setorigin(key.kh_next, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
238 key.kh_next.angles =
'0 0 0';
241 setorigin(key, KH_PLAYER_ATTACHMENT);
242 key.angles = KH_PLAYER_ATTACHMENT_ANGLES;
246 setattachment(key, key.kh_prev,
"");
248 setattachment(key.kh_next, key,
"");
249 setorigin(key, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
250 setorigin(first, first.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
251 key.angles =
'0 0 0';
254 setattachment(key, key.owner,
"");
256 key.angles_y -= key.owner.angles.y;
262 key.team = key.owner.team;
263 key.nextthink =
time;
264 key.damageforcescale = 0;
273#ifdef KH_PLAYER_USE_ATTACHMENT
274 entity first = key.owner.kh_next;
279 setattachment(key.kh_next, key.owner, KH_PLAYER_ATTACHMENT_BONE);
280 setorigin(key.kh_next, key.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
281 key.kh_next.angles = KH_PLAYER_ATTACHMENT_ANGLES;
287 setattachment(key.kh_next, key.kh_prev,
"");
288 setorigin(first, first.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
291 setattachment(key,
NULL,
"");
292 setorigin(key, key.owner.origin +
'0 0 1' * (
STAT(PL_MIN, key.owner).z - KH_KEY_MIN_z));
293 key.angles = key.owner.angles;
295 setorigin(key, key.owner.origin + key.origin.z *
'0 0 1');
296 setattachment(key,
NULL,
"");
297 key.angles_y += key.owner.angles.y;
303 nudgeoutofsolid_OrFallback(key);
310 key.previous_owner = key.owner;
311 key.kh_previous_owner_playerid = key.owner.playerid;
316 if(key.owner == player)
327 key.kh_next.kh_prev = key.kh_prev;
328 key.kh_prev.kh_next = key.kh_next;
332 if(key.owner.kh_next ==
NULL)
346 key.kh_next = player.kh_next;
347 key.kh_prev = player;
348 player.kh_next = key;
350 key.kh_next.kh_prev = key;
354 if(key.kh_next ==
NULL)
380 if(ownerteam != ownerteam0)
391 if (!k.owner)
continue;
393 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, { first = it; break; });
395 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, { third = it; break; });
406 if (!k.owner)
continue;
408 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, { first = it; break; });
410 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, { third = it; break; });
430 this.
team = attacker.team;
437 if(key.kh_dropperteam != player.team)
442 key.kh_dropperteam = 0;
492 if (o.kh_worldkeynext == key)
494 o.kh_worldkeynext = o.kh_worldkeynext.kh_worldkeynext;
497 o = o.kh_worldkeynext;
540 string keyowner =
"";
542 if(key.owner.kh_next == key)
545 keyowner =
strcat(keyowner,
", ");
546 keyowner = key.owner.netname;
554 vector firstorigin =
'0 0 0', lastorigin =
'0 0 0', midpoint =
'0 0 0';
559 midpoint += thisorigin;
566 Send_Effect(EFFECT_TR_NEXUIZPLASMA, lastorigin, thisorigin, 1);
568 lastorigin = thisorigin;
570 firstorigin = thisorigin;
576 Send_Effect(EFFECT_TR_NEXUIZPLASMA, lastorigin, firstorigin, 1);
579 te_customflash(midpoint, 1000, 1,
Team_ColorRGB(winner_team) * 0.5 +
'0.5 0.5 0.5');
590 if(lostkey.pusher.team != loser_team)
592 attacker = lostkey.pusher;
596 if(lostkey.previous_owner)
613 if(key.owner && key.team != loser_team)
616 if(lostkey.previous_owner)
620 if(lostkey.previous_owner.playerid == lostkey.kh_previous_owner_playerid)
626 if(key.owner && key.team != loser_team)
639 if(thisteam == loser_team)
650 f = DistributeEvenly_Get(1);
651 kh_Scores_Event(it, NULL,
"destroyed", f, 0);
666 te_tarexplosion(lostkey.origin);
678#ifndef KH_PLAYER_USE_ATTACHMENT
734 entity key =
new(item_kh_key);
738 key.nextthink =
time;
740 key.angles =
'0 360 0' *
random();
747 key.kh_dropperteam = 0;
754 switch(initial_owner.team)
757 key.netname =
"^1red key";
760 key.netname =
"^4blue key";
763 key.netname =
"^3yellow key";
766 key.netname =
"^6pink key";
769 key.netname =
"NETGIER key";
779 WaypointSprite_Spawn(WP_KeyDropped, 0, 0, key,
'0 0 1' *
KH_KEY_WP_ZSHIFT,
NULL, key.team, key,
waypointsprite_attachedforcarrier,
false, RADARICON_FLAG);
797 else if(teem != key.team)
809 entity player = key.owner;
811 key.kh_droptime =
time;
824 key.kh_dropperteam = key.team;
835 if(
time < player.pushltime)
836 mypusher = player.pusher;
839 while((key = player.kh_next))
848 key.pusher = mypusher;
851 key.kh_dropperteam = player.team;
859 int missing_teams = 0;
869 missing_teams |=
BIT(i);
871 return missing_teams;
876 static int prev_missing_teams_mask;
956 if(attacker.team == targ.team)
959 for(
entity k = targ.kh_next; k !=
NULL; k = k.kh_next)
987#ifdef KH_PLAYER_USE_CARRIEDMODEL
988 setmodel(tmp_ent, MDL_KH_KEY_CARRIED);
1022 entity key_wp = e.waypointsprite_attachedforcarrier;
1063 LOG_TRACE(
"changing role to freelancer");
1101 LOG_TRACE(
"changing role to freelancer");
1109 float key_owner_team;
1113 if(key_owner_team == this.
team)
1115 else if(key_owner_team == -1)
1143 LOG_TRACE(
"changing role to freelancer");
1151 float key_owner_team;
1156 if(key_owner_team == this.
team)
1158 else if(key_owner_team == -1)
1205 if(key_owner_team == this.
team)
1207 else if(key_owner_team == -1)
1299 float frag_score =
M_ARGV(2,
float);
1320 entity k = player.kh_next;
void navigation_goalrating_start(entity this)
void navigation_goalrating_timeout_set(entity this)
bool navigation_goalrating_timeout(entity this)
void navigation_dynamicgoal_init(entity this, bool initially_static)
void navigation_routerating(entity this, entity e, float f, float rangebias)
void navigation_dynamicgoal_set(entity this, entity dropper)
void navigation_goalrating_end(entity this)
float havocbot_role_timeout
void navigation_dynamicgoal_unset(entity this)
const int CBC_ORDER_FIRST
#define MUTATOR_HOOKFUNCTION(...)
const int CBC_ORDER_EXCLUSIVE
#define MUTATOR_RETURNVALUE
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define colormapPaletteColor(c, isPants)
#define setmodel(this, m)
#define PHYS_INPUT_BUTTON_CHAT(s)
const int SFL_LOWER_IS_BETTER
Lower scores are better (e.g.
const int SFL_SORT_PRIO_SECONDARY
Scoring priority (NOTE: PRIMARY is used for fraglimit) NOTE: SFL_SORT_PRIO_SECONDARY value must be lo...
const int SFL_SORT_PRIO_PRIMARY
const float SOLID_TRIGGER
float DPCONTENTS_PLAYERCLIP
float checkpvs(vector viewpos, entity viewee)
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
void GameLogEcho(string s)
bool autocvar_sv_eventlog
ERASEABLE void IL_REMOVE(IntrusiveList this, entity it)
Remove any element, anywhere in the list.
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
ERASEABLE bool IL_CONTAINS(IntrusiveList this, entity it)
#define FOREACH(list, cond, body)
void set_movetype(entity this, int mt)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
void Kill_Notification(NOTIF broadcast, entity client, MSG net_type, CPID net_cpid)
#define APP_TEAM_NUM(num, prefix)
#define new_pure(class)
purely logical entities (not linked to the area grid)
ERASEABLE void DistributeEvenly_Init(float amount, float totalweight)
ERASEABLE float DistributeEvenly_Get(float weight)
void PlayerUseKey(entity this)
#define IS_INDEPENDENT_PLAYER(e)
#define ITEM_TOUCH_NEEDKILL()
#define ITEM_DAMAGE_NEEDKILL(dt)
#define sound(e, c, s, v, a)
void play2all(string samp)
float float2int_decimal_fld
void kh_EnableTrackingDevice()
void havocbot_role_kh_offense(entity this)
void key_reset(entity this)
void kh_Key_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void kh_Key_Spawn(entity initial_owner, float _angle, float i)
int kh_Key_AllOwnedByWhichTeam()
bool kh_Key_waypointsprite_visible_for_player(entity this, entity player, entity view)
const float KH_KEY_ZSHIFT
void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)
int autocvar_g_balance_keyhunt_score_destroyed
void havocbot_role_kh_carrier(entity this)
void kh_ScoreRules(int teams)
void kh_LoserTeam(int loser_team, entity lostkey)
void kh_Key_DropOne(entity key)
float autocvar_g_balance_keyhunt_delay_collect
int autocvar_g_balance_keyhunt_score_collect
void kh_Key_Think(entity this)
float autocvar_g_balance_keyhunt_delay_tracking
int autocvar_g_keyhunt_teams_override
void kh_Controller_Think(entity this)
const float KH_KEY_BRIGHTNESS
int kh_previous_owner_playerid
float autocvar_g_balance_keyhunt_delay_return
void kh_Controller_SetThink(float t, kh_Think_t func)
void kh_Key_AssignTo(entity key, entity player)
float autocvar_g_balance_keyhunt_protecttime
float autocvar_g_balance_keyhunt_return_when_unreachable
void kh_Key_Detach(entity key)
float autocvar_g_balance_keyhunt_delay_damage_return
void nades_GiveBonus(entity player, float score)
float kh_interferemsg_time
const float KH_KEY_WP_ZSHIFT
void kh_Key_Remove(entity key)
const float KH_KEY_XYSPEED
vector autocvar_g_balance_keyhunt_noncarrier_force
void kh_Key_Collect(entity key, entity player)
bool kh_KeyCarrier_waypointsprite_visible_for_player(entity this, entity player, entity view)
float autocvar_g_balance_keyhunt_delay_round
void kh_Key_Touch(entity this, entity toucher)
var kh_Think_t kh_Controller_Thinkfunc
vector autocvar_g_balance_keyhunt_noncarrier_damage
vector autocvar_g_balance_keyhunt_carrier_damage
void havocbot_role_kh_freelancer(entity this)
vector kh_AttachedOrigin(entity e)
bool kh_waypointsprite_visible_for_bot(entity this, entity e)
void kh_Key_Attach(entity key)
float autocvar_g_balance_keyhunt_damageforcescale
float autocvar_g_balance_keyhunt_maxdist
float autocvar_g_balance_keyhunt_dropvelocity
void kh_Key_DropAll(entity player, float suicide)
vector autocvar_g_balance_keyhunt_carrier_force
void kh_WinnerTeam(int winner_team)
float kh_HandleFrags(entity attacker, entity targ, float f)
float autocvar_g_balance_keyhunt_throwvelocity
int autocvar_g_balance_keyhunt_score_capture
void havocbot_goalrating_kh(entity this, float ratingscale_team, float ratingscale_dropped, float ratingscale_enemy)
void havocbot_role_kh_defense(entity this)
int autocvar_g_balance_keyhunt_score_carrierfrag
int autocvar_g_balance_keyhunt_score_push
int autocvar_g_balance_keyhunt_score_destroyed_ownfactor
const float KH_KEY_XYDIST
#define FOR_EACH_KH_KEY(v)
int autocvar_g_nades_bonus_score_high
void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius)
#define GameRules_scoring_add_team_float2int(client, fld, value, float_field, score_factor)
#define GameRules_scoring_add(client, fld, value)
#define GameRules_scoring_add_team(client, fld, value)
#define GameRules_scoring(teams, spprio, stprio, fields)
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings.
vector Team_ColorRGB(int teamid)
vector W_CalculateProjectileVelocity(entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
#define FOREACH_CLIENT(cond, body)
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
void WaypointSprite_Kill(entity wp)
void WaypointSprite_UpdateSprites(entity e, entity _m1, entity _m2, entity _m3)
void WaypointSprite_Ping(entity e)
entity WaypointSprite_Spawn(entity spr, float _lifetime, float maxdistance, entity ref, vector ofs, entity showto, float t, entity own,.entity ownfield, float hideable, entity icon)
entity WaypointSprite_getviewentity(entity e)
entity WaypointSprite_AttachCarrier(entity spr, entity carrier, entity icon)
void WaypointSprite_DetachCarrier(entity carrier)
void WaypointSprite_UpdateRule(entity e, float t, float r)
entity waypointsprite_attachedforcarrier
const int SPRITERULE_TEAMPLAY