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 =
"";
95 field(SP_KH_PUSHES,
"pushes", 0);
97 field(SP_KH_PICKUPS,
"pickups", 0);
98 field(SP_KH_KCKILLS,
"kckills", 0);
105 if(view.kh_next &&
IS_SPEC(player))
137 s |= (32 ** key.count) * f;
145 STAT(OBJECTIVE_STATUS, key.owner) |= (32 ** key.count) * 31;
171 else if(this.
cnt == 0)
192 if(key && key.owner && frags_owner)
198 s =
strcat(
":keyhunt:", what,
":",
ftos(player.playerid),
":",
ftos(frags_player));
208 s =
strcat(s, key.netname);
227#ifdef KH_PLAYER_USE_ATTACHMENT
228 entity first = key.owner.kh_next;
231 setattachment(key, key.owner, KH_PLAYER_ATTACHMENT_BONE);
234 setattachment(key.kh_next, key,
"");
235 setorigin(key, key.kh_next.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
236 setorigin(key.kh_next, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
237 key.kh_next.angles =
'0 0 0';
240 setorigin(key, KH_PLAYER_ATTACHMENT);
241 key.angles = KH_PLAYER_ATTACHMENT_ANGLES;
245 setattachment(key, key.kh_prev,
"");
247 setattachment(key.kh_next, key,
"");
248 setorigin(key, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
249 setorigin(first, first.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
250 key.angles =
'0 0 0';
253 setattachment(key, key.owner,
"");
255 key.angles_y -= key.owner.angles.y;
261 key.team = key.owner.team;
262 key.nextthink =
time;
263 key.damageforcescale = 0;
272#ifdef KH_PLAYER_USE_ATTACHMENT
273 entity first = key.owner.kh_next;
278 setattachment(key.kh_next, key.owner, KH_PLAYER_ATTACHMENT_BONE);
279 setorigin(key.kh_next, key.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
280 key.kh_next.angles = KH_PLAYER_ATTACHMENT_ANGLES;
286 setattachment(key.kh_next, key.kh_prev,
"");
287 setorigin(first, first.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
290 setattachment(key,
NULL,
"");
291 setorigin(key, key.owner.origin +
'0 0 1' * (
STAT(PL_MIN, key.owner).z - KH_KEY_MIN_z));
292 key.angles = key.owner.angles;
294 setorigin(key, key.owner.origin + key.origin.z *
'0 0 1');
295 setattachment(key,
NULL,
"");
296 key.angles_y += key.owner.angles.y;
302 nudgeoutofsolid_OrFallback(key);
309 key.previous_owner = key.owner;
310 key.kh_previous_owner_playerid = key.owner.playerid;
315 if(key.owner == player)
326 key.kh_next.kh_prev = key.kh_prev;
327 key.kh_prev.kh_next = key.kh_next;
331 if(key.owner.kh_next ==
NULL)
345 key.kh_next = player.kh_next;
346 key.kh_prev = player;
347 player.kh_next = key;
349 key.kh_next.kh_prev = key;
353 if(key.kh_next ==
NULL)
379 if(ownerteam != ownerteam0)
390 if (!k.owner)
continue;
392 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, { first = it; break; });
394 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, { third = it; break; });
405 if (!k.owner)
continue;
407 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, { first = it; break; });
409 FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, { third = it; break; });
429 this.
team = attacker.team;
436 if(key.kh_dropperteam != player.team)
441 key.kh_dropperteam = 0;
491 if (o.kh_worldkeynext == key)
493 o.kh_worldkeynext = o.kh_worldkeynext.kh_worldkeynext;
496 o = o.kh_worldkeynext;
539 string keyowner =
"";
541 if(key.owner.kh_next == key)
544 keyowner =
strcat(keyowner,
", ");
545 keyowner = key.owner.netname;
553 vector firstorigin =
'0 0 0', lastorigin =
'0 0 0', midpoint =
'0 0 0';
558 midpoint += thisorigin;
565 Send_Effect(EFFECT_TR_NEXUIZPLASMA, lastorigin, thisorigin, 1);
567 lastorigin = thisorigin;
569 firstorigin = thisorigin;
575 Send_Effect(EFFECT_TR_NEXUIZPLASMA, lastorigin, firstorigin, 1);
578 te_customflash(midpoint, 1000, 1,
Team_ColorRGB(winner_team) * 0.5 +
'0.5 0.5 0.5');
589 if(lostkey.pusher.team != loser_team)
591 attacker = lostkey.pusher;
595 if(lostkey.previous_owner)
612 if(key.owner && key.team != loser_team)
615 if(lostkey.previous_owner)
619 if(lostkey.previous_owner.playerid == lostkey.kh_previous_owner_playerid)
625 if(key.owner && key.team != loser_team)
638 if(thisteam == loser_team)
649 f = DistributeEvenly_Get(1);
650 kh_Scores_Event(it, NULL,
"destroyed", f, 0);
665 te_tarexplosion(lostkey.origin);
677#ifndef KH_PLAYER_USE_ATTACHMENT
733 entity key =
new(item_kh_key);
737 key.nextthink =
time;
739 key.angles =
'0 360 0' *
random();
746 key.kh_dropperteam = 0;
753 switch(initial_owner.team)
756 key.netname =
"^1red key";
759 key.netname =
"^4blue key";
762 key.netname =
"^3yellow key";
765 key.netname =
"^6pink key";
768 key.netname =
"NETGIER key";
778 WaypointSprite_Spawn(WP_KeyDropped, 0, 0, key,
'0 0 1' *
KH_KEY_WP_ZSHIFT,
NULL, key.team, key,
waypointsprite_attachedforcarrier,
false, RADARICON_FLAG);
796 else if(teem != key.team)
808 entity player = key.owner;
810 key.kh_droptime =
time;
823 key.kh_dropperteam = key.team;
834 if(
time < player.pushltime)
835 mypusher = player.pusher;
838 while((key = player.kh_next))
847 key.pusher = mypusher;
850 key.kh_dropperteam = player.team;
858 int missing_teams = 0;
868 missing_teams |=
BIT(i);
870 return missing_teams;
875 static int prev_missing_teams_mask;
955 if(attacker.team == targ.team)
958 for(
entity k = targ.kh_next; k !=
NULL; k = k.kh_next)
978 kh_teams =
cvar(
"g_keyhunt_teams");
986#ifdef KH_PLAYER_USE_CARRIEDMODEL
987 setmodel(tmp_ent, MDL_KH_KEY_CARRIED);
1021 entity key_wp = e.waypointsprite_attachedforcarrier;
1062 LOG_TRACE(
"changing role to freelancer");
1100 LOG_TRACE(
"changing role to freelancer");
1108 float key_owner_team;
1112 if(key_owner_team == this.
team)
1114 else if(key_owner_team == -1)
1142 LOG_TRACE(
"changing role to freelancer");
1150 float key_owner_team;
1155 if(key_owner_team == this.
team)
1157 else if(key_owner_team == -1)
1204 if(key_owner_team == this.
team)
1206 else if(key_owner_team == -1)
1298 float frag_score =
M_ARGV(2,
float);
1313 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(...)
#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)
#define AVAILABLE_TEAMS
Number of teams that exist currently.
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)
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