78 LOG_TRACE(
"^1WARNING!^7 this.mdl is unset for item ", this.
classname,
"expect a crash just about now");
117 if(!this.
itemdef.instanceOfPowerup)
124 if(
STAT(WEAPONS,
this) || this.
itemdef.instanceOfAmmo)
140 e.spawnshieldtime = 1;
148 e.spawnshieldtime = 1;
153 bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.m_wepset &
WEPSET_SUPERWEAPONS) :
false
162 e.spawnshieldtime = 0;
168 e.spawnshieldtime = 1;
188 setorigin(e, e.origin);
212 if (this.
itemdef.instanceOfPowerup)
274 if (wi != WEP_Null) {
275 entity wp =
WaypointSprite_Spawn(WP_Weapon, 0, 0,
this,
'0 0 64',
NULL, 0,
this,
waypointsprite_attached,
true, RADARICON_Weapon);
276 wp.wp_extra = wi.m_id;
283 entity wp =
WaypointSprite_Spawn(WP_Item, 0, 0,
this,
'0 0 64',
NULL, 0,
this,
waypointsprite_attached,
true, RADARICON_Item);
284 wp.wp_extra = ii.m_id;
334 e.item_respawncounter = 0;
340 e.scheduledrespawntime =
time + t;
352AUTOCVAR(g_pickup_respawntime_scaling_reciprocal,
float, 0.0,
"multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to \\\"0\\\") can be used to achieve a constant number of items spawned *per player*");
353AUTOCVAR(g_pickup_respawntime_scaling_offset,
float, 0.0,
"multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right (NOTE: results are not intuitive and it is recommend to plot the respawn time and the number of items per player to see what's happening)");
354AUTOCVAR(g_pickup_respawntime_scaling_linear,
float, 1.0,
"multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly");
358 float r = autocvar_g_pickup_respawntime_scaling_reciprocal;
359 float o = autocvar_g_pickup_respawntime_scaling_offset;
360 float l = autocvar_g_pickup_respawntime_scaling_linear;
362 if (r == 0 && l == 1) {
363 return normal_respawntime;
379 return normal_respawntime * (r / (
players + o) + l);
381 return normal_respawntime;
387 if(e.respawntime > 0)
395 float respawn_in = adjusted_respawntime +
crandom() * e.respawntimejitter;
402AUTOCVAR(g_pickup_respawntime_initial_random,
int, 1,
403 "for items that don't start spawned; \\\"0\\\" = spawn after their normal respawntime, \\\"1\\\" = spawn after `random * respawntime` with the *same* random, \\\"2\\\" = same as 1 but each item has separate random");
410 if (autocvar_g_pickup_respawntime_initial_random == 0)
413 spawn_in = e.respawntime +
random() * e.respawntimejitter;
418 if (autocvar_g_pickup_respawntime_initial_random == 1)
420 static float shared_random = 0;
423 if (!shared_random ||
floor(
time) > shared_random)
443 if (num_weapons == 0)
448 for (
int give_attempt = 0; give_attempt < num_weapons; ++give_attempt)
451 for (
int weapon_index = 0; weapon_index < num_potential_weapons;
458 if (!(
STAT(WEAPONS, receiver) & it.m_wepset) && (it.netname ==
weapon))
492 float player_amount =
GetResource(player, res_type);
493 if (item.spawnshieldtime)
495 if ((player_amount >= ammomax) && (item.pickup_anyway <= 0))
500 ammomax =
min(amount, ammomax);
501 if(player_amount >= ammomax)
517 WriteHeader(MSG_ONE, TE_CSQC_WEAPONPICKUP);
518 WriteByte(MSG_ONE, wep);
525 int _switchweapon = 0;
530 bool use_cts_autoswitch = (
g_cts && item.itemdef.instanceOfWeaponPickup && (
CS_CVAR(player).cvar_cl_autoswitch_cts != -1));
531 if (
CS_CVAR(player).cvar_cl_autoswitch && !use_cts_autoswitch)
536 if (player.(weaponentity).m_weapon != WEP_Null || slot == 0)
538 if (player.(weaponentity).m_switchweapon ==
w_getbestweapon(player, weaponentity))
539 _switchweapon |=
BIT(slot);
542 _switchweapon |=
BIT(slot);
546 bool pickedup =
false;
547 pickedup |=
Item_GiveAmmoTo(item, player, RES_HEALTH, item.max_health);
554 if (item.itemdef.instanceOfWeaponPickup)
557 w =
STAT(WEAPONS, item);
558 wp = w &
~STAT(WEAPONS, player);
560 if (wp || (item.spawnshieldtime && item.pickup_anyway > 0))
564 if(w & (it.m_wepset))
567 if(wp & (it.m_wepset))
572 if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
573 W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
581 if (item.itemdef.instanceOfPowerup)
583 if ((item.itemdef == ITEM_FuelRegen) && !(player.items &
IT_FUEL_REGEN))
585 else if ((item.itemdef == ITEM_Jetpack) && !(player.items &
IT_JETPACK))
598 if (item.strength_finished)
603 t += item.strength_finished;
605 t =
max(t,
time + item.strength_finished);
608 if (item.invincible_finished)
613 t += item.invincible_finished;
615 t =
max(t,
time + item.invincible_finished);
618 if (item.speed_finished)
623 t += item.speed_finished;
625 t =
max(t,
time + item.speed_finished);
628 if (item.invisibility_finished)
633 t += item.invisibility_finished;
635 t =
max(t,
time + item.invisibility_finished);
638 if (item.superweapons_finished)
652 if(use_cts_autoswitch)
655 if(
CS_CVAR(player).cvar_cl_autoswitch_cts == 1)
662 if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
668 else if(_switchweapon)
674 if(_switchweapon &
BIT(slot))
677 if(player.(weaponentity).m_switchweapon != best_wep)
771 it.scheduledrespawntime = 0;
772 RandomSelection_AddEnt(it, it.cnt, 0);
823 RandomSelection_AddEnt(it, it.cnt, 0);
837 if (it.waypointsprite_attached)
838 WaypointSprite_Kill(it.waypointsprite_attached);
846 it.effects &= ~EF_NOGUNBOB;
853 setorigin(to, this.
origin);
858 to.spawnfunc_checked =
true;
867 if(wasfreed(
this) || !
this) {
return; }
890 if(
STAT(WEAPONS, player) &
STAT(WEAPONS, item))
893 if(!item.spawnshieldtime)
900 int weapons_value = 0;
902 weapons_value += it.bot_pickupbasevalue;
904 c -=
bound(0, weapons_value / 20000, 1) * 0.5;
906 return item.bot_pickupbasevalue * c;
917 if(item.itemdef.instanceOfWeaponPickup)
919 entity res = item.itemdef.m_weapon.ammo_type;
927 rating =
ammo.m_botvalue;
932 if(!(
STAT(WEAPONS, player) & (it.m_wepset)))
934 if(it.ammo_type == RES_NONE)
939 item_resource = it.ammo_type;
943 rating = item.bot_pickupbasevalue;
946 float noammorating = 0.5;
953 rating += wpn.bot_pickupbasevalue * 0.1;
960 float rating = item.bot_pickupbasevalue;
967 itemarmor *=
min(4, item.item_group_count);
968 itemhealth *=
min(4, item.item_group_count);
974 if (itemhealth && (
GetResource(player, RES_HEALTH) < item.max_health))
997 int old_status = this.
active;
1003 if(this.
active != old_status)
1009 if (def.m_spawnfunc_hookreplace)
1010 def = def.m_spawnfunc_hookreplace(def,
this);
1012 if (def.m_canonical_spawnfunc !=
"")
1013 this.
classname = def.m_canonical_spawnfunc;
1019 def.m_iteminit(def,
this);
1022 this.
items = def.m_itemid;
1023 this.
weapon = def.instanceOfWeaponPickup ? def.m_weapon.m_id : 0;
1060 setsize (
this, this.
pos1 = def.m_mins,
this.pos2 = def.m_maxs);
1089 nudgeoutofsolid_OrFallback(
this);
1111 if (def.m_respawntime)
1114 LOG_WARNF(
"Default respawntime for a %s is unavailable from its itemdef", this.
classname);
1119 if(this.
angles !=
'0 0 0')
1128 if(t) this.
team = crc16(
false, t);
1134 setorigin(
this, this.
origin);
1162 LOG_TRACE(
"XXX Found duplicated item: ", def.m_name, vtos(this.origin));
1163 LOG_TRACE(
" vs ", it.netname, vtos(it.origin));
1164 error(
"Mapper sucks.");
1171 if ( def.instanceOfPowerup
1172 || def.instanceOfWeaponPickup
1173 || (def.instanceOfHealth && def != ITEM_HealthSmall)
1174 || (def.instanceOfArmor && def != ITEM_ArmorSmall)
1179 this.
target =
"###item###";
1188 this.bot_pickupevalfunc = def.m_pickupevalfunc;
1196 this.
skin = def.m_skin;
1199 if(def.instanceOfPowerup)
1206 if(def.instanceOfWeaponPickup)
1228 Net_LinkEntity(
this, !(def.instanceOfPowerup || def.instanceOfHealth || def.instanceOfArmor), 0,
ItemSend);
1247#define IS_SMALL(def) ((def.instanceOfHealth && def == ITEM_HealthSmall) || (def.instanceOfArmor && def == ITEM_ArmorSmall))
1257 if(!this.item_group)
1261 it.item_group = group_count;
1264 this.item_group = it.item_group;
1269 it.item_group = this.item_group;
1270 else if(it.item_group != this.item_group)
1272 int grY = it.item_group;
1274 IL_EACH(g_items, IS_SMALL(it.itemdef),
1276 if(it.item_group == grY)
1277 it.item_group = this.item_group;
1299 v0 = (
STAT(WEAPONS, e) & s);
1304 STAT(WEAPONS, e) |= s;
1306 STAT(WEAPONS, e) &= ~s;
1311 STAT(WEAPONS, e) |= s;
1315 STAT(WEAPONS, e) &= ~s;
1319 STAT(WEAPONS, e) &= ~s;
1322 v1 = (
STAT(WEAPONS, e) & s);
1333 new_buff_time =
time + val;
1336 new_buff_time =
max(new_buff_time,
time + val);
1339 new_buff_time =
min(new_buff_time,
time + val);
1342 new_buff_time += val;
1345 new_buff_time -= val;
1348 if(new_buff_time <=
time)
1359 return (had_buff != have_buff);
1368 if(snd_decr !=
NULL)
1371 else if(v0 >= v0 + t)
1373 if(snd_incr !=
NULL)
1378void GiveRot(
entity e,
float v0,
float v1, .
float rotfield,
float rottime, .
float regenfield,
float regentime)
1381 e.(rotfield) =
max(e.(rotfield),
time + rottime);
1383 e.(regenfield) =
max(e.(regenfield),
time + regentime);
1392 case OP_SET: new_val = val;
break;
1393 case OP_MIN: new_val =
max(v0, val);
break;
1394 case OP_MAX: new_val =
min(v0, val);
break;
1395 case OP_PLUS: new_val = v0 + val;
break;
1396 case OP_MINUS: new_val = v0 - val;
break;
1397 default:
return false;
1409 new_eff_time =
time + val;
1412 new_eff_time =
max(new_eff_time,
time + val);
1415 new_eff_time =
min(new_eff_time,
time + val);
1418 new_eff_time += val;
1421 new_eff_time -= val;
1424 if(new_eff_time <=
time)
1432 return (had_eff != have_eff);
1437 float got, i, val, op;
1445 int _switchweapon = 0;
1447 bool use_cts_autoswitch = (
g_cts && (
CS_CVAR(e).cvar_cl_autoswitch_cts != -1));
1448 if(
CS_CVAR(e).cvar_cl_autoswitch && !use_cts_autoswitch)
1453 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1454 if(e.(weaponentity).m_switchweapon ==
w_getbestweapon(e, weaponentity))
1455 _switchweapon |=
BIT(slot);
1474 Weapon last_wep = WEP_Null;
1475 for(i = beginarg; i < endarg; ++i)
1503 got +=
GiveBit(e,
items, ITEM_FuelRegen.m_itemid, op, val);
1507 got +=
GiveBit(e,
items, ITEM_Jetpack.m_itemid, op, val);
1522 case "unlimited_ammo":
1526 case "unlimited_weapon_ammo":
1529 case "unlimited_superweapons":
1533 got +=
GiveBit(e,
items, ITEM_Jetpack.m_itemid, op, val);
1536 got +=
GiveBit(e,
items, ITEM_FuelRegen.m_itemid, op, val);
1548 case "invisibility":
1551 case "superweapons":
1579 got += GiveBuff(e, it, op, val);
1583 got += GiveWeapon(e, it.m_id, op, val);
1584 if(use_cts_autoswitch && CS_CVAR(e).cvar_cl_autoswitch_cts == 1)
1585 if(val > 0 && (op == OP_SET || op == OP_PLUS || op == OP_MIN))
1601 if(!(save_weapons & (it.m_wepset)))
1602 if(
STAT(WEAPONS, e) & (it.m_wepset))
1627 if(use_cts_autoswitch)
1630 if(last_wep != WEP_Null)
1631 if(
CS_CVAR(e).cvar_cl_autoswitch_cts == 1)
1637 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1649 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1651 _switchweapon |=
BIT(slot);
1653 if(_switchweapon &
BIT(slot))
1656 if(e.(weaponentity).m_switchweapon != best_wep)
void waypoint_spawnforitem(entity e)
#define MUTATOR_CALLHOOK(id,...)
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
ERASEABLE bool GiveBit(entity e,.int fld, int bit, int op, int val)
float bot_pickupbasevalue
string Buff_CompatName(string buffname)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Takes an entity some resource but not less than a limit.
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
int autocvar_g_pickup_rockets_max
int autocvar_g_pickup_fuel_max
int autocvar_g_pickup_shells_max
int autocvar_g_pickup_cells_max
int autocvar_g_pickup_nails_max
const float IT_UPDATE_INTERVAL
const int IT_UNLIMITED_AMMO
const int IT_UNLIMITED_SUPERWEAPONS
float invincible_finished
@ ITEM_FLAG_MUTATORBLOCKED
#define ITEM_HANDLE(signal,...)
const float IT_DESPAWNFX_TIME
#define setmodel(this, m)
vector weaponsInMap
all the weapons actually spawned in the map, does not include filtered items
const int INITPRIO_FINDTARGET
const float SOLID_TRIGGER
float trace_dpstartcontents
const float EF_FULLBRIGHT
const float EF_NODEPTHTEST
void W_SwitchWeapon_Force(Player this, Weapon w,.entity weaponentity)
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
float invisibility_finished
#define ITEM_IS_LOOT(item)
Returns whether the item is loot.
#define ITEM_IS_EXPIRING(item)
Returns whether the item is expiring (i.e.
#define ITEM_SHOULD_KEEP_POSITION(item)
Returns whether item should keep its position or be dropped to the ground.
#define FOREACH_ENTITY_RADIUS(org, dist, cond, body)
#define FOREACH(list, cond, body)
void SUB_UseTargets(entity this, entity actor, entity trigger)
#define WriteHeader(to, id)
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
void set_movetype(entity this, int mt)
@ STATUSEFFECT_REMOVE_CLEAR
Effect is being forcibly removed without calling any additional mechanics.
@ STATUSEFFECT_REMOVE_NORMAL
Effect is being removed by a function, calls regular removal mechanics.
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
ERASEABLE void RandomSelection_Init()
#define RandomSelection_AddEnt(e, weight, priority)
entity RandomSelection_chosen_ent
#define crandom()
Returns a random number between -1.0 and 1.0.
#define REGISTRY_GET(id, i)
bool client_hasweapon(entity this, Weapon wpn,.entity weaponentity, float andammo, bool complain)
#define w_getbestweapon(ent, wepent)
float pauserotfuel_finished
float pauseregen_finished
float pauserothealth_finished
float pauserotarmor_finished
float generic_pickupevalfunc(entity player, entity item)
bool Item_ItemsTime_SpectatorOnly(GameItem it)
float ammo_pickupevalfunc(entity player, entity item)
float Item_ItemsTime_UpdateTime(entity e, float t)
void Item_NotifyWeapon(entity player, int wep)
void GiveRot(entity e, float v0, float v1,.float rotfield, float rottime,.float regenfield, float regentime)
float adjust_respawntime(float normal_respawntime)
Adjust respawn time according to the number of players.
void Item_ScheduleRespawn(entity e)
void Item_ItemsTime_SetTimesForAllPlayers()
void Item_CopyFields(entity this, entity to)
bool GiveStatusEffect(entity e, StatusEffect this, int op, float val)
bool GiveBuff(entity e, Buff thebuff, int op, int val)
bool ItemSend(entity this, entity to, int sf)
void Item_RespawnThink(entity this)
bool Item_GiveAmmoTo(entity item, entity player, Resource res_type, float ammomax)
void Item_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void ItemUpdate(entity this)
void StartItem(entity this, entity def)
void Item_ScheduleInitialRespawn(entity e)
void Item_ScheduleRespawnIn(entity e, float t)
void UpdateItemAfterTeleport(entity this)
void RemoveItem(entity this)
float weapon_pickupevalfunc(entity player, entity item)
float GiveWeapon(entity e, float wpn, float op, float val)
void Item_Think(entity this)
void Item_RespawnCountdown(entity this)
void Item_Show(entity e, int mode)
void setItemGroup(entity this)
void item_use(entity this, entity actor, entity trigger)
void Item_ItemsTime_SetTime(entity e, float t)
void Item_FindTeam(entity this)
float GiveItems(entity e, float beginarg, float endarg)
bool have_pickup_item(entity this)
bool Item_ItemsTime_Allow(GameItem it)
void Item_Reset(entity this)
bool GiveResourceValue(entity e, Resource res_type, int op, int val)
float healtharmor_pickupevalfunc(entity player, entity item)
void item_setactive(entity this, int act)
void GiveSound(entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr)
void GiveRandomWeapons(entity receiver, int num_weapons, string weapon_names, entity ammo_entity)
Give several random weapons and ammo to the entity.
bool Item_GiveTo(entity item, entity player)
void Item_Respawn(entity this)
void Item_Touch(entity this, entity toucher)
float autocvar_g_balance_superweapons_time
entity item_pickupsound_ent
int autocvar_g_pickup_items
float item_respawncounter
#define ITEM_TOUCH_NEEDKILL()
#define ITEM_DAMAGE_NEEDKILL(dt)
#define POSTGIVE_WEAPON(e, b, snd_incr, snd_decr)
float autocvar_sv_simple_items
#define PREGIVE_WEAPONS(e)
#define POSTGIVE_RESOURCE(e, f, t, snd_incr, snd_decr)
bool autocvar_g_fullbrightitems
#define PREGIVE_STATUSEFFECT(e, f)
float superweapons_finished
const float ITEM_RESPAWN_TICKS
#define PREGIVE_RESOURCE(e, f)
float autocvar_g_items_maxdist
bool autocvar_g_nodepthtestitems
#define POSTGIVE_STATUSEFFECT(e, f, snd_incr, snd_decr)
float item_spawnshieldtime
#define POSTGIVE_RES_ROT(e, f, t, rotfield, rottime, regenfield, regentime, snd_incr, snd_decr)
#define POSTGIVE_BIT(e, f, b, snd_incr, snd_decr)
float autocvar_g_items_dropped_lifetime
string GetField_fullspawndata(entity e, string fieldname, bool vfspath)
Retrieves the value of a map entity field from fullspawndata.
float autocvar_sys_ticrate
void W_GiveWeapon(entity e, int wep)
const int CH_TRIGGER_SINGLE
#define Sound_fixpath(this)
#define _sound(e, c, s, v, a)
#define sound(e, c, s, v, a)
void soundto(int _dest, entity e, int chan, string samp, float vol, float _atten, float _pitch)
void StatusEffects_remove(StatusEffect this, entity actor, int removal_type)
float StatusEffects_gettime(StatusEffect this, entity actor)
bool StatusEffects_active(StatusEffect this, entity actor)
void StatusEffects_apply(StatusEffect this, entity actor, float eff_time, int eff_flags)
void StatusEffects_update(entity e)
float buff_Available(entity buff)
void buff_RemoveAll(entity actor, int removal_type)
void powerups_DropItem_Think(entity this)
bool autocvar_g_powerups_stack
void GiveResource(entity receiver, Resource res_type, float amount)
Gives an entity some resource.
float GetResourceLimit(entity e, Resource res_type)
Returns the maximum amount of the given resource.
void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Gives an entity some resource but not more than a limit.
float autocvar_g_balance_pause_fuel_regen
float autocvar_g_balance_pause_armor_rot
float autocvar_g_balance_pause_health_rot
float autocvar_g_balance_pause_health_regen
float autocvar_g_balance_pause_fuel_rot
void TeamBalance_Destroy(entity balance)
Destroy the team balance entity.
int TeamBalance_GetNumberOfPlayers(entity balance, int index)
Returns the number of players (both humans and bots) in a team.
void TeamBalance_GetTeamCounts(entity balance, entity ignore)
Counts the number of players and various other information about each team.
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings.
bool TeamBalance_IsTeamAllowed(entity balance, int index)
Returns whether the team change to the specified team is allowed.
const int NUM_TEAMS
Number of teams in the game.
#define IS_REAL_CLIENT(v)
#define FOREACH_CLIENT(cond, body)
void WaypointSprite_Kill(entity wp)
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)
void WaypointSprite_UpdateBuildFinished(entity e, float f)
void WaypointSprite_UpdateRule(entity e, float t, float r)
entity waypointsprite_attached
const int SPRITERULE_SPECTATOR
entity GetAmmoItem(Resource ammotype)
WepSet WEPSET_SUPERWEAPONS
#define WepSet_FromWeapon(it)
const int MAX_WEAPONSLOTS
entity weaponentities[MAX_WEAPONSLOTS]
const int WEP_FLAG_MUTATORBLOCKED
const int WEP_FLAG_HIDDEN
void W_DropEvent(.void(Weapon, entity actor,.entity) event, entity player, int weapon_type, entity weapon_item,.entity weaponentity)
void DropToFloor_QC_DelayedInit(entity this)
void InitializeEntity(entity e, void(entity this) func, int order)