79 LOG_TRACE(
"^1WARNING!^7 this.mdl is unset for item ", this.
classname,
"expect a crash just about now");
118 if(!this.
itemdef.instanceOfPowerup)
125 if(
STAT(WEAPONS,
this) || this.
itemdef.instanceOfAmmo)
141 e.spawnshieldtime = 1;
149 e.spawnshieldtime = 1;
154 bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.m_wepset &
WEPSET_SUPERWEAPONS) :
false
163 e.spawnshieldtime = 0;
169 e.spawnshieldtime = 1;
189 setorigin(e, e.origin);
213 if (this.
itemdef.instanceOfPowerup)
275 if (wi != WEP_Null) {
276 entity wp =
WaypointSprite_Spawn(WP_Weapon, 0, 0,
this,
'0 0 64',
NULL, 0,
this,
waypointsprite_attached,
true, RADARICON_Weapon);
277 wp.wp_extra = wi.m_id;
284 entity wp =
WaypointSprite_Spawn(WP_Item, 0, 0,
this,
'0 0 64',
NULL, 0,
this,
waypointsprite_attached,
true, RADARICON_Item);
285 wp.wp_extra = ii.m_id;
335 e.item_respawncounter = 0;
341 e.scheduledrespawntime =
time + t;
353AUTOCVAR(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*");
354AUTOCVAR(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)");
355AUTOCVAR(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");
359 float r = autocvar_g_pickup_respawntime_scaling_reciprocal;
360 float o = autocvar_g_pickup_respawntime_scaling_offset;
361 float l = autocvar_g_pickup_respawntime_scaling_linear;
363 if (r == 0 && l == 1) {
364 return normal_respawntime;
380 return normal_respawntime * (r / (
players + o) + l);
382 return normal_respawntime;
388 if(e.respawntime > 0)
396 float respawn_in = adjusted_respawntime +
crandom() * e.respawntimejitter;
403AUTOCVAR(g_pickup_respawntime_initial_random,
int, 1,
404 "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");
411 if (autocvar_g_pickup_respawntime_initial_random == 0)
414 spawn_in = e.respawntime +
random() * e.respawntimejitter;
419 if (autocvar_g_pickup_respawntime_initial_random == 1)
421 static float shared_random = 0;
424 if (!shared_random ||
floor(
time) > shared_random)
444 if (num_weapons == 0)
449 for (
int give_attempt = 0; give_attempt < num_weapons; ++give_attempt)
452 for (
int weapon_index = 0; weapon_index < num_potential_weapons;
459 if (!(
STAT(WEAPONS, receiver) & it.m_wepset) && (it.netname ==
weapon))
493 float player_amount =
GetResource(player, res_type);
494 if (item.spawnshieldtime)
496 if ((player_amount >= ammomax) && (item.pickup_anyway <= 0))
501 ammomax =
min(amount, ammomax);
502 if(player_amount >= ammomax)
518 WriteHeader(MSG_ONE, TE_CSQC_WEAPONPICKUP);
519 WriteRegistered(Weapons, MSG_ONE, wep);
526 int _switchweapon = 0;
531 bool use_cts_autoswitch = (
g_cts && item.itemdef.instanceOfWeaponPickup && (
CS_CVAR(player).cvar_cl_autoswitch_cts != -1));
532 if (
CS_CVAR(player).cvar_cl_autoswitch && !use_cts_autoswitch)
537 if (player.(weaponentity).m_weapon != WEP_Null || slot == 0)
539 if (player.(weaponentity).m_switchweapon ==
w_getbestweapon(player, weaponentity))
540 _switchweapon |=
BIT(slot);
543 _switchweapon |=
BIT(slot);
547 bool pickedup =
false;
548 pickedup |=
Item_GiveAmmoTo(item, player, RES_HEALTH, item.max_health);
555 if (item.itemdef.instanceOfWeaponPickup)
558 w =
STAT(WEAPONS, item);
559 wp = w &
~STAT(WEAPONS, player);
561 if (wp || (item.spawnshieldtime && item.pickup_anyway > 0))
565 if(w & (it.m_wepset))
568 if(wp & (it.m_wepset))
573 if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
574 W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
582 if (item.itemdef.instanceOfPowerup)
584 if ((item.itemdef == ITEM_FuelRegen) && !(player.items &
IT_FUEL_REGEN))
586 else if ((item.itemdef == ITEM_Jetpack) && !(player.items &
IT_JETPACK))
599 if (item.strength_finished)
604 t += item.strength_finished;
606 t =
max(t,
time + item.strength_finished);
609 if (item.invincible_finished)
614 t += item.invincible_finished;
616 t =
max(t,
time + item.invincible_finished);
619 if (item.speed_finished)
624 t += item.speed_finished;
626 t =
max(t,
time + item.speed_finished);
629 if (item.invisibility_finished)
634 t += item.invisibility_finished;
636 t =
max(t,
time + item.invisibility_finished);
639 if (item.superweapons_finished)
653 if(use_cts_autoswitch)
656 if(
CS_CVAR(player).cvar_cl_autoswitch_cts == 1)
663 if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
669 else if(_switchweapon)
675 if(_switchweapon &
BIT(slot))
678 if(player.(weaponentity).m_switchweapon != best_wep)
772 it.scheduledrespawntime = 0;
773 RandomSelection_AddEnt(it, it.cnt, 0);
824 RandomSelection_AddEnt(it, it.cnt, 0);
838 if (it.waypointsprite_attached)
839 WaypointSprite_Kill(it.waypointsprite_attached);
847 it.effects &= ~EF_NOGUNBOB;
854 setorigin(to, this.
origin);
859 to.spawnfunc_checked =
true;
868 if(wasfreed(
this) || !
this) {
return; }
891 if(
STAT(WEAPONS, player) &
STAT(WEAPONS, item))
894 if(!item.spawnshieldtime)
901 int weapons_value = 0;
903 weapons_value += it.bot_pickupbasevalue;
905 c -=
bound(0, weapons_value / 20000, 1) * 0.5;
907 return item.bot_pickupbasevalue * c;
918 if(item.itemdef.instanceOfWeaponPickup)
920 entity res = item.itemdef.m_weapon.ammo_type;
928 rating =
ammo.m_botvalue;
933 if(!(
STAT(WEAPONS, player) & (it.m_wepset)))
935 if(it.ammo_type == RES_NONE)
940 item_resource = it.ammo_type;
944 rating = item.bot_pickupbasevalue;
947 float noammorating = 0.5;
954 rating += wpn.bot_pickupbasevalue * 0.1;
961 float rating = item.bot_pickupbasevalue;
968 itemarmor *=
min(4, item.item_group_count);
969 itemhealth *=
min(4, item.item_group_count);
975 if (itemhealth && (
GetResource(player, RES_HEALTH) < item.max_health))
998 int old_status = this.
active;
1004 if(this.
active != old_status)
1011 if (def.instanceOfWeapon)
1020 if (def.m_spawnfunc_hookreplace)
1021 def = this.
itemdef = def.m_spawnfunc_hookreplace(def,
this);
1022 if (def.m_canonical_spawnfunc !=
"")
1023 this.
classname = def.m_canonical_spawnfunc;
1028 def.m_iteminit(def,
this);
1031 this.
items = def.m_itemid;
1032 this.
weapon = def.instanceOfWeaponPickup ? def.m_weapon.m_id : 0;
1069 setsize (
this, this.
pos1 = def.m_mins,
this.pos2 = def.m_maxs);
1098 nudgeoutofsolid_OrFallback(
this);
1120 if (def.m_respawntime)
1123 LOG_WARNF(
"Default respawntime for a %s is unavailable from its itemdef", this.
classname);
1128 if(this.
angles !=
'0 0 0')
1137 if(t) this.
team = crc16(
false, t);
1143 setorigin(
this, this.
origin);
1175 error(
"Mapper sucks.");
1183 if ( def.instanceOfPowerup
1184 || def.instanceOfWeaponPickup
1185 || (def.instanceOfHealth && def != ITEM_HealthSmall)
1186 || (def.instanceOfArmor && def != ITEM_ArmorSmall)
1191 this.
target =
"###item###";
1200 this.bot_pickupevalfunc = def.m_pickupevalfunc;
1208 this.
skin = def.m_skin;
1211 if(def.instanceOfPowerup)
1218 if(def.instanceOfWeaponPickup)
1240 Net_LinkEntity(
this, !(def.instanceOfPowerup || def.instanceOfHealth || def.instanceOfArmor), 0,
ItemSend);
1253#define IS_SMALL(def) ((def.instanceOfHealth && def == ITEM_HealthSmall) || (def.instanceOfArmor && def == ITEM_ArmorSmall))
1270 if (!head.item_group)
1279 if (!head.item_group)
1281 else if (head.item_group !=
this.item_group)
1283 int grY = head.item_group;
1306 v0 = (
STAT(WEAPONS, e) & s);
1311 STAT(WEAPONS, e) |= s;
1313 STAT(WEAPONS, e) &= ~s;
1318 STAT(WEAPONS, e) |= s;
1322 STAT(WEAPONS, e) &= ~s;
1326 STAT(WEAPONS, e) &= ~s;
1329 v1 = (
STAT(WEAPONS, e) & s);
1340 new_buff_time =
time + val;
1343 new_buff_time =
max(new_buff_time,
time + val);
1346 new_buff_time =
min(new_buff_time,
time + val);
1349 new_buff_time += val;
1352 new_buff_time -= val;
1355 if(new_buff_time <=
time)
1366 return (had_buff != have_buff);
1375 if(snd_decr !=
NULL)
1378 else if(v0 >= v0 + t)
1380 if(snd_incr !=
NULL)
1385void GiveRot(
entity e,
float v0,
float v1, .
float rotfield,
float rottime, .
float regenfield,
float regentime)
1388 e.(rotfield) =
max(e.(rotfield),
time + rottime);
1390 e.(regenfield) =
max(e.(regenfield),
time + regentime);
1399 case OP_SET: new_val = val;
break;
1400 case OP_MIN: new_val =
max(v0, val);
break;
1401 case OP_MAX: new_val =
min(v0, val);
break;
1402 case OP_PLUS: new_val = v0 + val;
break;
1403 case OP_MINUS: new_val = v0 - val;
break;
1404 default:
return false;
1416 new_eff_time =
time + val;
1419 new_eff_time =
max(new_eff_time,
time + val);
1422 new_eff_time =
min(new_eff_time,
time + val);
1425 new_eff_time += val;
1428 new_eff_time -= val;
1431 if(new_eff_time <=
time)
1439 return (had_eff != have_eff);
1444 float got, i, val, op;
1452 int _switchweapon = 0;
1454 bool use_cts_autoswitch = (
g_cts && (
CS_CVAR(e).cvar_cl_autoswitch_cts != -1));
1455 if(
CS_CVAR(e).cvar_cl_autoswitch && !use_cts_autoswitch)
1460 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1461 if(e.(weaponentity).m_switchweapon ==
w_getbestweapon(e, weaponentity))
1462 _switchweapon |=
BIT(slot);
1481 Weapon last_wep = WEP_Null;
1482 for(i = beginarg; i < endarg; ++i)
1510 got +=
GiveBit(e,
items, ITEM_FuelRegen.m_itemid, op, val);
1514 got +=
GiveBit(e,
items, ITEM_Jetpack.m_itemid, op, val);
1529 case "unlimited_ammo":
1533 case "unlimited_weapon_ammo":
1536 case "unlimited_superweapons":
1540 got +=
GiveBit(e,
items, ITEM_Jetpack.m_itemid, op, val);
1543 got +=
GiveBit(e,
items, ITEM_FuelRegen.m_itemid, op, val);
1555 case "invisibility":
1558 case "superweapons":
1586 got += GiveBuff(e, it, op, val);
1590 got += GiveWeapon(e, it.m_id, op, val);
1591 if(use_cts_autoswitch && CS_CVAR(e).cvar_cl_autoswitch_cts == 1)
1592 if(val > 0 && (op == OP_SET || op == OP_PLUS || op == OP_MIN))
1608 if(!(save_weapons & (it.m_wepset)))
1609 if(
STAT(WEAPONS, e) & (it.m_wepset))
1634 if(use_cts_autoswitch)
1637 if(last_wep != WEP_Null)
1638 if(
CS_CVAR(e).cvar_cl_autoswitch_cts == 1)
1644 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1656 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1658 _switchweapon |=
BIT(slot);
1660 if(_switchweapon &
BIT(slot))
1663 if(e.(weaponentity).m_switchweapon != best_wep)
void waypoint_spawnforitem(entity e)
#define MUTATOR_CALLHOOK(name,...)
#define M_ARGV(idx, type)
#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.
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
void InitializeEntity(entity e, void(entity this) func, int order)
#define setmodel(this, m)
vector weaponsInMap
all the weapons actually spawned in the map, does not include filtered items
const int INITPRIO_SETLOCATION
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)
WriteString(chan, ent.netname)
WriteByte(chan, ent.angles.y/DEC_FACTOR)
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
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(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)
entity WarpZone_SearchInRadius(vector org, float rad, float nomonsters, WarpZone_FindRadius_cond_callback_t cb)
Modified findradius aware of warpzones, that only includes entities that meet the "cb" criteria.
#define WarpZone_FindRadius(org, radius)
Modified findradius aware of warpzones.
noref entity WarpZone_SearchInRadius_otherent
Free to use in the callback.
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)
#define AVAILABLE_TEAMS
Number of teams that exist currently.
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 StartItem(entity this)
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)
void Item_NotifyWeapon(entity player, entity wep)
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 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)
bool setItemGroup_cond(entity e)
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.
#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)
void weapon_defaultspawnfunc(entity this, Weapon wpn)
const int MAX_WEAPONSLOTS
entity weaponentities[MAX_WEAPONSLOTS]
const int WEP_FLAG_MUTATORBLOCKED
hides from impulse 99 etc. (mutators are allowed to clear this flag)
const int WEP_FLAG_HIDDEN
hides from menu
void W_DropEvent(.void(Weapon, entity actor,.entity) event, entity player, int weapon_type, entity weapon_item,.entity weaponentity)
void DropToFloor_QC(entity this)