Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
items.qh File Reference
Include dependency graph for items.qh:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define autocvar_g_weapon_stay   cvar("g_weapon_stay")
#define ITEM_DAMAGE_NEEDKILL(dt)
#define ITEM_TOUCH_NEEDKILL()
#define POSTGIVE_BIT(e, f, b, snd_incr, snd_decr)
#define POSTGIVE_RES_ROT(e, f, t, rotfield, rottime, regenfield, regentime, snd_incr, snd_decr)
#define POSTGIVE_RESOURCE(e, f, t, snd_incr, snd_decr)
#define POSTGIVE_STATUSEFFECT(e, f, snd_incr, snd_decr)
#define POSTGIVE_VALUE(e, f, t, snd_incr, snd_decr)
#define POSTGIVE_VALUE_ROT(e, f, t, rotfield, rottime, regenfield, regentime, snd_incr, snd_decr)
#define POSTGIVE_WEAPON(e, b, snd_incr, snd_decr)
#define PREGIVE(e, f)
#define PREGIVE_RESOURCE(e, f)
#define PREGIVE_STATUSEFFECT(e, f)
#define PREGIVE_WEAPONS(e)

Functions

float ammo_pickupevalfunc (entity player, entity item)
float generic_pickupevalfunc (entity player, entity item)
bool GiveBuff (entity e, Buff thebuff, int op, int val)
float GiveItems (entity e, float beginarg, float endarg)
void GiveRandomWeapons (entity receiver, int num_weapons, string weapon_names, entity ammo_entity)
 Give several random weapons and ammo to the entity.
void GiveRot (entity e, float v0, float v1,.float rotfield, float rottime,.float regenfield, float regentime)
void GiveSound (entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr)
float GiveWeapon (entity e, float wpn, float op, float val)
float healtharmor_pickupevalfunc (entity player, entity item)
void Item_CopyFields (entity this, entity to)
void Item_FindTeam (entity this)
bool Item_GiveAmmoTo (entity item, entity player, Resource res_type, float ammomax)
bool Item_GiveTo (entity item, entity player)
void Item_Reset (entity this)
void Item_Respawn (entity this)
void Item_RespawnCountdown (entity this)
void Item_ScheduleInitialRespawn (entity e)
void Item_ScheduleRespawn (entity e)
void Item_ScheduleRespawnIn (entity e, float t)
void Item_Show (entity e, int mode)
void Item_Touch (entity this, entity toucher)
bool ItemSend (entity this, entity to, int sf)
void ItemUpdate (entity this)
void RemoveItem (entity this)
void setItemGroup (entity this)
void setItemGroupCount ()
void StartItem (entity this)
 STATIC_INIT (g_items)
void UpdateItemAfterTeleport (entity this)
float weapon_pickupevalfunc (entity player, entity item)

Variables

float autocvar_g_balance_superweapons_time
bool autocvar_g_fullbrightitems
float autocvar_g_items_dropped_lifetime
float autocvar_g_items_maxdist
bool autocvar_g_nodepthtestitems
int autocvar_g_pickup_items
float autocvar_sv_simple_items
int count
IntrusiveList g_items
bool is_item
int item_group
int item_group_count
int item_group_last
entity item_model_ent
string item_pickupsound
entity item_pickupsound_ent
const float ITEM_RESPAWN_TICKS = 10
float item_respawncounter
float item_spawnshieldtime
entity itemdef
float max_armorvalue
bool noalign
float pickup_anyway
float respawntime
float respawntimejitter
float respawntimestart
float scheduledrespawntime
float superweapons_finished

Macro Definition Documentation

◆ autocvar_g_weapon_stay

#define autocvar_g_weapon_stay   cvar("g_weapon_stay")

Definition at line 13 of file items.qh.

◆ ITEM_DAMAGE_NEEDKILL

#define ITEM_DAMAGE_NEEDKILL ( dt)
Value:
(((dt) == DEATH_HURTTRIGGER.m_id) || ((dt) == DEATH_SLIME.m_id) || ((dt) == DEATH_LAVA.m_id) || ((dt) == DEATH_SWAMP.m_id))

Definition at line 122 of file items.qh.

Referenced by ctf_FlagDamage(), Item_Damage(), ka_DamageEvent(), kh_Key_Damage(), Monster_Damage(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), nade_damage(), and physical_item_damage().

◆ ITEM_TOUCH_NEEDKILL

#define ITEM_TOUCH_NEEDKILL ( )
Value:
float Q3SURFACEFLAG_SKY
float trace_dphitcontents
float DPCONTENTS_NODROP
float trace_dpstartcontents
float trace_dphitq3surfaceflags

Definition at line 121 of file items.qh.

Referenced by buff_Touch(), Item_Touch(), kh_Key_Touch(), nade_touch(), and physical_item_touch().

◆ POSTGIVE_BIT

#define POSTGIVE_BIT ( e,
f,
b,
snd_incr,
snd_decr )
Value:
GiveSound((e), save_##f & (b), (e).f & (b), 0, snd_incr, snd_decr)
void GiveSound(entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr)
Definition items.qc:1378

Definition at line 109 of file items.qh.

Referenced by GiveItems().

◆ POSTGIVE_RES_ROT

#define POSTGIVE_RES_ROT ( e,
f,
t,
rotfield,
rottime,
regenfield,
regentime,
snd_incr,
snd_decr )
Value:
GiveRot((e),save_##f,GetResource((e),(f)),rotfield,rottime,regenfield,regentime);GiveSound((e),save_##f,GetResource((e),(f)),t,snd_incr,snd_decr)
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
void GiveRot(entity e, float v0, float v1,.float rotfield, float rottime,.float regenfield, float regentime)
Definition items.qc:1394

Definition at line 112 of file items.qh.

Referenced by GiveItems().

◆ POSTGIVE_RESOURCE

#define POSTGIVE_RESOURCE ( e,
f,
t,
snd_incr,
snd_decr )
Value:
GiveSound((e), save_##f, GetResource((e), (f)), t, snd_incr, snd_decr)

Definition at line 111 of file items.qh.

Referenced by GiveItems().

◆ POSTGIVE_STATUSEFFECT

#define POSTGIVE_STATUSEFFECT ( e,
f,
snd_incr,
snd_decr )
Value:
GiveSound((e), save_##f, StatusEffects_active(f, (e)), 0, snd_incr, snd_decr)
bool StatusEffects_active(StatusEffect this, entity actor)

Definition at line 110 of file items.qh.

Referenced by GiveItems().

◆ POSTGIVE_VALUE

#define POSTGIVE_VALUE ( e,
f,
t,
snd_incr,
snd_decr )
Value:
GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)

Definition at line 113 of file items.qh.

◆ POSTGIVE_VALUE_ROT

#define POSTGIVE_VALUE_ROT ( e,
f,
t,
rotfield,
rottime,
regenfield,
regentime,
snd_incr,
snd_decr )
Value:
GiveRot((e), save_##f, (e).f, rotfield, rottime, regenfield, regentime); GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)

Definition at line 114 of file items.qh.

◆ POSTGIVE_WEAPON

#define POSTGIVE_WEAPON ( e,
b,
snd_incr,
snd_decr )
Value:
GiveSound((e), !!(save_weapons & WepSet_FromWeapon(b)), !!(STAT(WEAPONS, e) & WepSet_FromWeapon(b)), 0, snd_incr, snd_decr)
#define STAT(...)
Definition stats.qh:94
#define WepSet_FromWeapon(it)
Definition all.qh:48

Definition at line 108 of file items.qh.

Referenced by GiveItems().

◆ PREGIVE

#define PREGIVE ( e,
f )
Value:
float save_##f; save_##f = (e).f

Definition at line 105 of file items.qh.

Referenced by GiveItems().

◆ PREGIVE_RESOURCE

#define PREGIVE_RESOURCE ( e,
f )
Value:
float save_##f = GetResource((e), (f))

Definition at line 107 of file items.qh.

Referenced by GiveItems().

◆ PREGIVE_STATUSEFFECT

#define PREGIVE_STATUSEFFECT ( e,
f )
Value:
bool save_##f = StatusEffects_active(f, (e))

Definition at line 106 of file items.qh.

Referenced by GiveItems().

◆ PREGIVE_WEAPONS

#define PREGIVE_WEAPONS ( e)
Value:
WepSet save_weapons; save_weapons = STAT(WEAPONS, e)
vector WepSet
Definition weapon.qh:13

Definition at line 104 of file items.qh.

Referenced by GiveItems().

Function Documentation

◆ ammo_pickupevalfunc()

float ammo_pickupevalfunc ( entity player,
entity item )

Definition at line 920 of file items.qc.

921{
922 entity item_resource = NULL; // pointer to the resource that may be associated with the given item
923 entity wpn = NULL;
924 float c = 0;
925 float rating = 0;
926
927 // detect needed ammo
928 if(item.itemdef.instanceOfWeaponPickup)
929 {
930 entity res = item.itemdef.m_weapon.ammo_type;
931 entity ammo = (res != RES_NONE) ? GetAmmoItem(res) : NULL;
932 if(!ammo)
933 return 0;
934 if(res != RES_NONE && GetResource(item, res))
935 item_resource = res;
936
937 wpn = item;
938 rating = ammo.m_botvalue;
939 }
940 else
941 {
942 FOREACH(Weapons, it != WEP_Null, {
943 if(!(STAT(WEAPONS, player) & (it.m_wepset)))
944 continue;
945 if(it.ammo_type == RES_NONE)
946 continue;
947
948 if(GetResource(item, it.ammo_type))
949 {
950 item_resource = it.ammo_type;
951 break;
952 }
953 });
954 rating = item.bot_pickupbasevalue;
955 }
956
957 float noammorating = 0.5;
958
959 if(item_resource && (GetResource(player, item_resource) < GetResourceLimit(player, item_resource)))
960 c = GetResource(item, item_resource) / max(noammorating, GetResource(player, item_resource));
961
962 rating *= min(c, 2);
963 if(wpn)
964 rating += wpn.bot_pickupbasevalue * 0.1;
965 return rating;
966}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
Weapons
Definition guide.qh:113
#define FOREACH(list, cond, body)
Definition iter.qh:19
float min(float f,...)
float max(float f,...)
#define NULL
Definition post.qh:14
float GetResourceLimit(entity e, Resource res_type)
Returns the maximum amount of the given resource.
float ammo
Definition sv_turrets.qh:43
entity GetAmmoItem(Resource ammotype)
Definition all.qc:175

References ammo, entity(), FOREACH, GetAmmoItem(), GetResource(), GetResourceLimit(), max(), min(), NULL, STAT, and Weapons.

Referenced by Ammo::float(), FuelRegen::float(), Jetpack::float(), and weapon_pickupevalfunc().

◆ generic_pickupevalfunc()

float generic_pickupevalfunc ( entity player,
entity item )

Definition at line 896 of file items.qc.

896{return item.bot_pickupbasevalue;}

References entity().

Referenced by buff_Init().

◆ GiveBuff()

bool GiveBuff ( entity e,
Buff thebuff,
int op,
int val )

Definition at line 1342 of file items.qc.

1343{
1344 bool had_buff = StatusEffects_active(thebuff, e);
1345 float new_buff_time = ((had_buff) ? StatusEffects_gettime(thebuff, e) : time);
1346 switch (op)
1347 {
1348 case OP_SET:
1349 new_buff_time = time + val;
1350 break;
1351 case OP_MIN:
1352 new_buff_time = max(new_buff_time, time + val);
1353 break;
1354 case OP_MAX:
1355 new_buff_time = min(new_buff_time, time + val);
1356 break;
1357 case OP_PLUS:
1358 new_buff_time += val;
1359 break;
1360 case OP_MINUS:
1361 new_buff_time -= val;
1362 break;
1363 }
1364 if(new_buff_time <= time)
1365 {
1366 if(had_buff) // only trigger removal mechanics if there is an effect to remove!
1368 }
1369 else
1370 {
1371 buff_RemoveAll(e, STATUSEFFECT_REMOVE_CLEAR); // clear old buffs on the player first!
1372 StatusEffects_apply(thebuff, e, new_buff_time, 0);
1373 }
1374 bool have_buff = StatusEffects_active(thebuff, e);
1375 return (had_buff != have_buff);
1376}
@ OP_MIN
Definition bits.qh:79
@ OP_PLUS
Definition bits.qh:81
@ OP_MAX
Definition bits.qh:80
@ OP_SET
Definition bits.qh:78
@ OP_MINUS
Definition bits.qh:82
float time
@ STATUSEFFECT_REMOVE_CLEAR
Effect is being forcibly removed without calling any additional mechanics.
Definition all.qh:30
@ STATUSEFFECT_REMOVE_NORMAL
Effect is being removed by a function, calls regular removal mechanics.
Definition all.qh:28
void StatusEffects_remove(StatusEffect this, entity actor, int removal_type)
float StatusEffects_gettime(StatusEffect this, entity actor)
void StatusEffects_apply(StatusEffect this, entity actor, float eff_time, int eff_flags)
void buff_RemoveAll(entity actor, int removal_type)
Definition sv_buffs.qc:285

References buff_RemoveAll(), entity(), max(), min(), OP_MAX, OP_MIN, OP_MINUS, OP_PLUS, OP_SET, STATUSEFFECT_REMOVE_CLEAR, STATUSEFFECT_REMOVE_NORMAL, StatusEffects_active(), StatusEffects_apply(), StatusEffects_gettime(), StatusEffects_remove(), and time.

◆ GiveItems()

float GiveItems ( entity e,
float beginarg,
float endarg )

Definition at line 1451 of file items.qc.

1452{
1453 float got, i, val, op;
1454 string cmd;
1455
1456 val = 999;
1457 op = OP_SET;
1458
1459 got = 0;
1460
1461 int _switchweapon = 0;
1462
1463 bool use_cts_autoswitch = (g_cts && (CS_CVAR(e).cvar_cl_autoswitch_cts != -1));
1464 if(CS_CVAR(e).cvar_cl_autoswitch && !use_cts_autoswitch)
1465 {
1466 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
1467 {
1468 .entity weaponentity = weaponentities[slot];
1469 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1470 if(e.(weaponentity).m_switchweapon == w_getbestweapon(e, weaponentity))
1471 _switchweapon |= BIT(slot);
1472 }
1473 }
1474
1475 PREGIVE(e, items);
1476 PREGIVE_WEAPONS(e);
1477 PREGIVE_STATUSEFFECT(e, STATUSEFFECT_Strength);
1478 PREGIVE_STATUSEFFECT(e, STATUSEFFECT_Shield);
1479 PREGIVE_STATUSEFFECT(e, STATUSEFFECT_Speed);
1480 PREGIVE_STATUSEFFECT(e, STATUSEFFECT_Invisibility);
1481 //PREGIVE_STATUSEFFECT(e, STATUSEFFECT_Superweapon);
1482 PREGIVE_RESOURCE(e, RES_BULLETS);
1483 PREGIVE_RESOURCE(e, RES_CELLS);
1484 PREGIVE_RESOURCE(e, RES_SHELLS);
1485 PREGIVE_RESOURCE(e, RES_ROCKETS);
1486 PREGIVE_RESOURCE(e, RES_FUEL);
1488 PREGIVE_RESOURCE(e, RES_HEALTH);
1489
1490 Weapon last_wep = WEP_Null;
1491 for(i = beginarg; i < endarg; ++i)
1492 {
1493 cmd = argv(i);
1494
1495 if(cmd == "0" || stof(cmd))
1496 {
1497 val = stof(cmd);
1498 continue;
1499 }
1500 switch(cmd)
1501 {
1502 case "no":
1503 op = OP_MAX;
1504 val = 0;
1505 continue;
1506 case "max":
1507 op = OP_MAX;
1508 continue;
1509 case "min":
1510 op = OP_MIN;
1511 continue;
1512 case "plus":
1513 op = OP_PLUS;
1514 continue;
1515 case "minus":
1516 op = OP_MINUS;
1517 continue;
1518 case "ALL":
1519 got += GiveBit(e, items, ITEM_FuelRegen.m_itemid, op, val);
1520 FOREACH(StatusEffects, it.instanceOfPowerupStatusEffect, got += GiveStatusEffect(e, it, op, val));
1522 case "all":
1523 got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
1524 got += GiveResourceValue(e, RES_HEALTH, op, val);
1525 got += GiveResourceValue(e, RES_ARMOR, op, val);
1526 case "allweapons":
1527 FOREACH(Weapons, it != WEP_Null && !(it.spawnflags & (WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN)),
1528 got += GiveWeapon(e, it.m_id, op, val));
1529 //case "allbuffs": // all buffs makes a player god, do not want!
1530 //FOREACH(StatusEffects, it.instanceOfBuff, got += GiveBuff(e, it, op, val));
1531 case "allammo":
1532 got += GiveResourceValue(e, RES_CELLS, op, val);
1533 got += GiveResourceValue(e, RES_SHELLS, op, val);
1534 got += GiveResourceValue(e, RES_BULLETS, op, val);
1535 got += GiveResourceValue(e, RES_ROCKETS, op, val);
1536 got += GiveResourceValue(e, RES_FUEL, op, val);
1537 break;
1538 case "unlimited_ammo":
1539 // this is from a time when unlimited superweapons were handled together with ammo in some parts of the code
1541 break;
1542 case "unlimited_weapon_ammo":
1543 got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
1544 break;
1545 case "unlimited_superweapons":
1546 got += GiveBit(e, items, IT_UNLIMITED_SUPERWEAPONS, op, val);
1547 break;
1548 case "jetpack":
1549 got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
1550 break;
1551 case "fuel_regen":
1552 got += GiveBit(e, items, ITEM_FuelRegen.m_itemid, op, val);
1553 break;
1554 case "strength":
1555 got += GiveStatusEffect(e, STATUSEFFECT_Strength, op, val);
1556 break;
1557 case "invincible":
1558 case "shield":
1559 got += GiveStatusEffect(e, STATUSEFFECT_Shield, op, val);
1560 break;
1561 case "speed":
1562 got += GiveStatusEffect(e, STATUSEFFECT_Speed, op, val);
1563 break;
1564 case "invisibility":
1565 got += GiveStatusEffect(e, STATUSEFFECT_Invisibility, op, val);
1566 break;
1567 case "superweapons":
1568 got += GiveStatusEffect(e, STATUSEFFECT_Superweapon, op, val);
1569 break;
1570 case "cells":
1571 got += GiveResourceValue(e, RES_CELLS, op, val);
1572 break;
1573 case "shells":
1574 got += GiveResourceValue(e, RES_SHELLS, op, val);
1575 break;
1576 case "nails":
1577 case "bullets":
1578 got += GiveResourceValue(e, RES_BULLETS, op, val);
1579 break;
1580 case "rockets":
1581 got += GiveResourceValue(e, RES_ROCKETS, op, val);
1582 break;
1583 case "health":
1584 got += GiveResourceValue(e, RES_HEALTH, op, val);
1585 break;
1586 case "armor":
1587 got += GiveResourceValue(e, RES_ARMOR, op, val);
1588 break;
1589 case "fuel":
1590 got += GiveResourceValue(e, RES_FUEL, op, val);
1591 break;
1592 default:
1593 FOREACH(StatusEffects, it.instanceOfBuff && buff_Available(it) && Buff_CompatName(cmd) == it.netname,
1594 {
1595 got += GiveBuff(e, it, op, val);
1596 break;
1597 });
1598 FOREACH(Weapons, it != WEP_Null && (cmd == it.netname || cmd == it.m_deprecated_netname), {
1599 got += GiveWeapon(e, it.m_id, op, val);
1600 if(use_cts_autoswitch && CS_CVAR(e).cvar_cl_autoswitch_cts == 1)
1601 if(val > 0 && (op == OP_SET || op == OP_PLUS || op == OP_MIN)) // switch to any given weapons, even if we already had it
1602 last_wep = it; // (... non-CTS autoswitching can switch to a weapon we already have, so CTS autoswitch should be the same)
1603 break;
1604 });
1605 break;
1606 }
1607 val = 999;
1608 op = OP_SET;
1609 }
1610
1611 POSTGIVE_BIT(e, items, ITEM_FuelRegen.m_itemid, SND_ITEMPICKUP, SND_Null);
1612 POSTGIVE_BIT(e, items, IT_UNLIMITED_SUPERWEAPONS, SND_POWERUP, SND_POWEROFF);
1613 POSTGIVE_BIT(e, items, IT_UNLIMITED_AMMO, SND_POWERUP, SND_POWEROFF);
1614 POSTGIVE_BIT(e, items, ITEM_Jetpack.m_itemid, SND_ITEMPICKUP, SND_Null);
1615 FOREACH(Weapons, it != WEP_Null, {
1616 POSTGIVE_WEAPON(e, it, SND_WEAPONPICKUP, SND_Null);
1617 if(!(save_weapons & (it.m_wepset)))
1618 if(STAT(WEAPONS, e) & (it.m_wepset))
1619 it.wr_init(it);
1620 });
1621 POSTGIVE_STATUSEFFECT(e, STATUSEFFECT_Strength, SND_POWERUP, SND_POWEROFF);
1622 POSTGIVE_STATUSEFFECT(e, STATUSEFFECT_Shield, SND_POWERUP, SND_POWEROFF);
1623 POSTGIVE_STATUSEFFECT(e, STATUSEFFECT_Speed, SND_POWERUP, SND_POWEROFF);
1624 POSTGIVE_STATUSEFFECT(e, STATUSEFFECT_Invisibility, SND_POWERUP, SND_POWEROFF);
1625 POSTGIVE_RESOURCE(e, RES_BULLETS, 0, SND_ITEMPICKUP, SND_Null);
1626 POSTGIVE_RESOURCE(e, RES_CELLS, 0, SND_ITEMPICKUP, SND_Null);
1627 POSTGIVE_RESOURCE(e, RES_SHELLS, 0, SND_ITEMPICKUP, SND_Null);
1628 POSTGIVE_RESOURCE(e, RES_ROCKETS, 0, SND_ITEMPICKUP, SND_Null);
1632
1633 if(!StatusEffects_active(STATUSEFFECT_Superweapon, e))
1634 {
1635 // also give default superweapon time if player had no superweapons and just got one
1636 if(g_weaponarena_type == WEPARENA_OFF && !(save_weapons & WEPSET_SUPERWEAPONS) && (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
1637 StatusEffects_apply(STATUSEFFECT_Superweapon, e, time + autocvar_g_balance_superweapons_time, 0);
1638 }
1639
1640 if(e.statuseffects)
1642
1643 if(use_cts_autoswitch)
1644 {
1645 // CTS handling: never switch (0), always switch (1)
1646 if(last_wep != WEP_Null)
1647 if(CS_CVAR(e).cvar_cl_autoswitch_cts == 1)
1648 {
1649 // crude hack to enforce switching weapons
1650 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
1651 {
1652 .entity weaponentity = weaponentities[slot];
1653 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1654 if(client_hasweapon(e, last_wep, weaponentity, true, false)) // ammo check
1655 W_SwitchWeapon_Force(e, last_wep, weaponentity);
1656 }
1657 }
1658 }
1659 else
1660 {
1661 // non-CTS handling: weaponpriority-based autoswitch
1662 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
1663 {
1664 .entity weaponentity = weaponentities[slot];
1665 if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
1666 if(!(STAT(WEAPONS, e) & WepSet_FromWeapon(e.(weaponentity).m_switchweapon)))
1667 _switchweapon |= BIT(slot);
1668
1669 if(_switchweapon & BIT(slot))
1670 {
1671 Weapon best_wep = w_getbestweapon(e, weaponentity);
1672 if(e.(weaponentity).m_switchweapon != best_wep)
1673 W_SwitchWeapon_Force(e, best_wep, weaponentity);
1674 }
1675 }
1676 }
1677
1678 return got;
1679}
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
ERASEABLE bool GiveBit(entity e,.int fld, int bit, int op, int val)
Definition bits.qh:86
string Buff_CompatName(string buffname)
Definition buffs.qc:4
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:36
const int IT_UNLIMITED_AMMO
Definition item.qh:23
const int IT_UNLIMITED_SUPERWEAPONS
Definition item.qh:24
int items
Definition player.qh:226
#define g_cts
Definition cts.qh:36
void W_SwitchWeapon_Force(Player this, Weapon w,.entity weaponentity)
Definition selection.qc:237
RES_ARMOR
Definition ent_cs.qc:155
float stof(string val,...)
void cmd(string command,...)
string argv(float n)
bool client_hasweapon(entity this, Weapon wpn,.entity weaponentity, float andammo, bool complain)
Definition selection.qc:47
#define w_getbestweapon(ent, wepent)
Definition selection.qh:23
float pauserotfuel_finished
Definition client.qh:339
float pauseregen_finished
Definition client.qh:336
float pauserothealth_finished
Definition client.qh:337
float pauserotarmor_finished
Definition client.qh:338
bool GiveStatusEffect(entity e, StatusEffect this, int op, float val)
Definition items.qc:1418
float GiveWeapon(entity e, float wpn, float op, float val)
Definition items.qc:1311
bool GiveResourceValue(entity e, Resource res_type, int op, int val)
Definition items.qc:1401
float autocvar_g_balance_superweapons_time
Definition items.qh:7
#define POSTGIVE_WEAPON(e, b, snd_incr, snd_decr)
Definition items.qh:108
#define PREGIVE_WEAPONS(e)
Definition items.qh:104
#define POSTGIVE_RESOURCE(e, f, t, snd_incr, snd_decr)
Definition items.qh:111
#define PREGIVE(e, f)
Definition items.qh:105
#define PREGIVE_STATUSEFFECT(e, f)
Definition items.qh:106
#define PREGIVE_RESOURCE(e, f)
Definition items.qh:107
#define POSTGIVE_STATUSEFFECT(e, f, snd_incr, snd_decr)
Definition items.qh:110
#define POSTGIVE_RES_ROT(e, f, t, rotfield, rottime, regenfield, regentime, snd_incr, snd_decr)
Definition items.qh:112
#define POSTGIVE_BIT(e, f, b, snd_incr, snd_decr)
Definition items.qh:109
#define CS_CVAR(this)
Definition state.qh:51
void StatusEffects_update(entity e)
float buff_Available(entity buff)
Definition sv_buffs.qc:256
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
WepSet WEPSET_SUPERWEAPONS
Definition all.qh:347
@ WEPARENA_OFF
Definition weapon.qh:272
const int MAX_WEAPONSLOTS
Definition weapon.qh:15
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:16
const int WEP_FLAG_MUTATORBLOCKED
hides from impulse 99 etc. (mutators are allowed to clear this flag)
Definition weapon.qh:255
const int WEP_FLAG_HIDDEN
hides from menu
Definition weapon.qh:252
int g_weaponarena_type
Definition world.qh:77

References argv(), autocvar_g_balance_pause_armor_rot, autocvar_g_balance_pause_fuel_regen, autocvar_g_balance_pause_fuel_rot, autocvar_g_balance_pause_health_regen, autocvar_g_balance_pause_health_rot, autocvar_g_balance_superweapons_time, BIT, buff_Available(), Buff_CompatName(), client_hasweapon(), cmd(), CS_CVAR, entity(), FOREACH, g_cts, g_weaponarena_type, GiveBit(), GiveResourceValue(), GiveStatusEffect(), GiveWeapon(), IT_UNLIMITED_AMMO, IT_UNLIMITED_SUPERWEAPONS, items, MAX_WEAPONSLOTS, OP_MAX, OP_MIN, OP_MINUS, OP_PLUS, OP_SET, pauseregen_finished, pauserotarmor_finished, pauserotfuel_finished, pauserothealth_finished, POSTGIVE_BIT, POSTGIVE_RES_ROT, POSTGIVE_RESOURCE, POSTGIVE_STATUSEFFECT, POSTGIVE_WEAPON, PREGIVE, PREGIVE_RESOURCE, PREGIVE_STATUSEFFECT, PREGIVE_WEAPONS, RES_ARMOR, STAT, StatusEffects_active(), StatusEffects_apply(), StatusEffects_update(), stof(), time, w_getbestweapon, W_SwitchWeapon_Force(), weaponentities, Weapons, WEP_FLAG_HIDDEN, WEP_FLAG_MUTATORBLOCKED, WEPARENA_OFF, WepSet_FromWeapon, and WEPSET_SUPERWEAPONS.

Referenced by CheatCommand(), and target_items_use().

◆ GiveRandomWeapons()

void GiveRandomWeapons ( entity receiver,
int num_weapons,
string weapon_names,
entity ammo_entity )

Give several random weapons and ammo to the entity.

Parameters
[in,out]receiverEntity to give weapons to.
[in]num_weaponsNumber of weapons to give.
[in]weapon_namesNames of weapons to give separated by spaces.
[in]ammoEntity containing the ammo amount for each possible weapon.
Returns
No return.

Definition at line 441 of file items.qc.

443{
444 if (num_weapons == 0)
445 {
446 return;
447 }
448 int num_potential_weapons = tokenize_console(weapon_names);
449 for (int give_attempt = 0; give_attempt < num_weapons; ++give_attempt)
450 {
452 for (int weapon_index = 0; weapon_index < num_potential_weapons;
453 ++weapon_index)
454 {
455 string weapon = argv(weapon_index);
456 FOREACH(Weapons, it != WEP_Null,
457 {
458 // Finding a weapon which player doesn't have.
459 if (!(STAT(WEAPONS, receiver) & it.m_wepset) && (it.netname == weapon))
460 {
461 RandomSelection_AddEnt(it, 1, 1);
462 break;
463 }
464 });
465 }
467 {
468 return;
469 }
470 STAT(WEAPONS, receiver) |= RandomSelection_chosen_ent.m_wepset;
471 if (RandomSelection_chosen_ent.ammo_type == RES_NONE)
472 {
473 continue;
474 }
475 if (GetResource(receiver,
476 RandomSelection_chosen_ent.ammo_type) != 0)
477 {
478 continue;
479 }
480 GiveResource(receiver, RandomSelection_chosen_ent.ammo_type,
481 GetResource(ammo_entity,
482 RandomSelection_chosen_ent.ammo_type));
483 }
484}
#define tokenize_console
float weapon
Definition progsdefs.qc:139
ERASEABLE void RandomSelection_Init()
Definition random.qc:4
#define RandomSelection_AddEnt(e, weight, priority)
Definition random.qh:14
entity RandomSelection_chosen_ent
Definition random.qh:5
void GiveResource(entity receiver, Resource res_type, float amount)
Gives an entity some resource.

References argv(), entity(), FOREACH, GetResource(), GiveResource(), NULL, RandomSelection_AddEnt, RandomSelection_chosen_ent, RandomSelection_Init(), STAT, tokenize_console, weapon, and Weapons.

Referenced by PutPlayerInServer().

◆ GiveRot()

void GiveRot ( entity e,
float v0,
float v1,
.float rotfield,
float rottime,
.float regenfield,
float regentime )

Definition at line 1394 of file items.qc.

1395{
1396 if(v0 < v1)
1397 e.(rotfield) = max(e.(rotfield), time + rottime);
1398 else if(v0 > v1)
1399 e.(regenfield) = max(e.(regenfield), time + regentime);
1400}

References entity(), max(), and time.

◆ GiveSound()

void GiveSound ( entity e,
float v0,
float v1,
float t,
Sound snd_incr,
Sound snd_decr )

Definition at line 1378 of file items.qc.

1379{
1380 if(v1 == v0)
1381 return;
1382 if(v1 <= v0 - t)
1383 {
1384 if(snd_decr != NULL)
1385 sound(e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM);
1386 }
1387 else if(v0 >= v0 + t)
1388 {
1389 if(snd_incr != NULL)
1390 sound(e, ((snd_incr == SND_POWERUP) ? CH_TRIGGER_SINGLE : CH_TRIGGER), snd_incr, VOL_BASE, ATTEN_NORM);
1391 }
1392}
const int CH_TRIGGER
Definition sound.qh:12
const int CH_TRIGGER_SINGLE
Definition sound.qh:13
const float VOL_BASE
Definition sound.qh:36
const float ATTEN_NORM
Definition sound.qh:30
#define sound(e, c, s, v, a)
Definition sound.qh:52

References ATTEN_NORM, CH_TRIGGER, CH_TRIGGER_SINGLE, entity(), NULL, sound, and VOL_BASE.

◆ GiveWeapon()

float GiveWeapon ( entity e,
float wpn,
float op,
float val )

Definition at line 1311 of file items.qc.

1312{
1313 WepSet v0, v1;
1315 v0 = (STAT(WEAPONS, e) & s);
1316 switch(op)
1317 {
1318 case OP_SET:
1319 if(val > 0)
1320 STAT(WEAPONS, e) |= s;
1321 else
1322 STAT(WEAPONS, e) &= ~s;
1323 break;
1324 case OP_MIN:
1325 case OP_PLUS:
1326 if(val > 0)
1327 STAT(WEAPONS, e) |= s;
1328 break;
1329 case OP_MAX:
1330 if(val <= 0)
1331 STAT(WEAPONS, e) &= ~s;
1332 break;
1333 case OP_MINUS:
1334 if(val > 0)
1335 STAT(WEAPONS, e) &= ~s;
1336 break;
1337 }
1338 v1 = (STAT(WEAPONS, e) & s);
1339 return (v0 != v1);
1340}
#define REGISTRY_GET(id, i)
Definition registry.qh:62

References entity(), OP_MAX, OP_MIN, OP_MINUS, OP_PLUS, OP_SET, REGISTRY_GET, STAT, Weapons, and WepSet_FromWeapon.

Referenced by GiveItems().

◆ healtharmor_pickupevalfunc()

float healtharmor_pickupevalfunc ( entity player,
entity item )

Definition at line 968 of file items.qc.

969{
970 float c = 0;
971 float rating = item.bot_pickupbasevalue;
972
973 float itemarmor = GetResource(item, RES_ARMOR);
974 float itemhealth = GetResource(item, RES_HEALTH);
975
976 if (item.item_group)
977 {
978 itemarmor *= min(4, item.item_group_count);
979 itemhealth *= min(4, item.item_group_count);
980 }
981
982 if (itemarmor && (GetResource(player, RES_ARMOR) < item.max_armorvalue))
983 c = itemarmor / max(1, GetResource(player, RES_ARMOR) * 2/3 + GetResource(player, RES_HEALTH) * 1/3);
984
985 if (itemhealth && (GetResource(player, RES_HEALTH) < item.max_health))
986 c = itemhealth / max(1, GetResource(player, RES_HEALTH));
987
988 rating *= min(2, c);
989 return rating;
990}

References entity(), GetResource(), max(), min(), and RES_ARMOR.

Referenced by Armor::float(), and Health::float().

◆ Item_CopyFields()

void Item_CopyFields ( entity this,
entity to )

Definition at line 853 of file items.qc.

854{
855 setorigin(to, this.origin);
856 to.spawnflags = this.spawnflags;
857 to.noalign = ITEM_SHOULD_KEEP_POSITION(this);
858 to.cnt = this.cnt;
859 to.team = this.team;
860 to.spawnfunc_checked = true;
861 // TODO: copy respawn times? this may not be desirable in some cases
862 //to.respawntime = this.respawntime;
863 //to.respawntimejitter = this.respawntimejitter;
864
865 // misc_follow compat
866 if (this.move_movetype == MOVETYPE_FOLLOW)
867 to.move_movetype = this.move_movetype;
868 if (this.tag_entity)
869 {
870 gettaginfo(this.tag_entity, this.tag_index); // resolve .tag_index back to its name (awkward)
871 setattachment(to, this.tag_entity, gettaginfo_name);
872 }
873}
float cnt
Definition powerups.qc:24
int team
Definition main.qh:188
int spawnflags
Definition ammo.qh:15
string gettaginfo_name
vector origin
entity tag_entity
int tag_index
#define ITEM_SHOULD_KEEP_POSITION(item)
Returns whether item should keep its position or be dropped to the ground.
Definition spawning.qh:50
const int MOVETYPE_FOLLOW
Definition movetypes.qh:145
float move_movetype
Definition movetypes.qh:80
#define gettaginfo
Definition post.qh:32

References cnt, entity(), gettaginfo, gettaginfo_name, ITEM_SHOULD_KEEP_POSITION, move_movetype, MOVETYPE_FOLLOW, origin, spawnflags, tag_entity, tag_index, and team.

Referenced by instagib_replace_item_with(), lms_replace_with_extralife(), MUTATOR_HOOKFUNCTION(), RandomItems_ReplaceMapItem(), and weapon_defaultspawnfunc().

◆ Item_FindTeam()

void Item_FindTeam ( entity this)

Definition at line 815 of file items.qc.

816{
817 if(!(this.effects & EF_NOGUNBOB)) // marker for item team search
818 return;
819
820 LOG_TRACE("Initializing item team ", ftos(this.team));
822 IL_EACH(g_items, it.team == this.team,
823 {
824 if(it.itemdef) // is a registered item
825 RandomSelection_AddEnt(it, it.cnt, 0);
826 });
827
829 if (!e)
830 return;
831
832 IL_EACH(g_items, it.team == this.team,
833 {
834 if(it.itemdef) // is a registered item
835 {
836 if(it != e)
837 {
838 Item_Show(it, -1); // make it non-spawned
839 if (it.waypointsprite_attached)
840 WaypointSprite_Kill(it.waypointsprite_attached);
841 it.nextthink = 0; // disable any scheduled powerup spawn
842 }
843 else
844 Item_Reset(it);
845
846 // leave 'this' marked so Item_FindTeam() works when called again via this.reset
847 if(it != this)
848 it.effects &= ~EF_NOGUNBOB;
849 }
850 });
851}
float effects
float EF_NOGUNBOB
#define IL_EACH(this, cond, body)
#define LOG_TRACE(...)
Definition log.qh:74
string ftos(float f)
IntrusiveList g_items
Definition items.qh:118

References EF_NOGUNBOB, effects, entity(), ftos(), g_items, IL_EACH, LOG_TRACE, RandomSelection_chosen_ent, RandomSelection_Init(), and team.

Referenced by StartItem().

◆ Item_GiveAmmoTo()

bool Item_GiveAmmoTo ( entity item,
entity player,
Resource res_type,
float ammomax )

Definition at line 486 of file items.qc.

487{
488 float amount = GetResource(item, res_type);
489 if (amount == 0)
490 {
491 return false;
492 }
493 float player_amount = GetResource(player, res_type);
494 if (item.spawnshieldtime)
495 {
496 if ((player_amount >= ammomax) && (item.pickup_anyway <= 0))
497 return false;
498 }
499 else if (g_weapon_stay == 2)
500 {
501 ammomax = min(amount, ammomax);
502 if(player_amount >= ammomax)
503 return false;
504 }
505 else
506 return false;
507 if (amount < 0)
508 TakeResourceWithLimit(player, res_type, -amount, ammomax);
509 else
510 GiveResourceWithLimit(player, res_type, amount, ammomax);
511 return true;
512}
void TakeResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Takes an entity some resource but not less than a limit.
void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Gives an entity some resource but not more than a limit.
float g_weapon_stay
Definition world.qh:108

References entity(), g_weapon_stay, GetResource(), GiveResourceWithLimit(), min(), and TakeResourceWithLimit().

Referenced by Item_GiveTo().

◆ Item_GiveTo()

bool Item_GiveTo ( entity item,
entity player )

Definition at line 523 of file items.qc.

524{
525 // if nothing happens to player, just return without taking the item
526 int _switchweapon = 0;
527 // in case the player has cl_autoswitch enabled do the following:
528 // if the player is using their best weapon before items are given, they
529 // probably want to switch to an even better weapon after items are given
530
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)
533 {
534 for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
535 {
536 .entity weaponentity = weaponentities[slot];
537 if (player.(weaponentity).m_weapon != WEP_Null || slot == 0)
538 {
539 if (player.(weaponentity).m_switchweapon == w_getbestweapon(player, weaponentity))
540 _switchweapon |= BIT(slot);
541
542 if (!(STAT(WEAPONS, player) & WepSet_FromWeapon(player.(weaponentity).m_switchweapon)))
543 _switchweapon |= BIT(slot);
544 }
545 }
546 }
547 bool pickedup = false;
548 pickedup |= Item_GiveAmmoTo(item, player, RES_HEALTH, item.max_health);
549 pickedup |= Item_GiveAmmoTo(item, player, RES_ARMOR, item.max_armorvalue);
550 pickedup |= Item_GiveAmmoTo(item, player, RES_SHELLS, autocvar_g_pickup_shells_max);
551 pickedup |= Item_GiveAmmoTo(item, player, RES_BULLETS, autocvar_g_pickup_nails_max);
552 pickedup |= Item_GiveAmmoTo(item, player, RES_ROCKETS, autocvar_g_pickup_rockets_max);
553 pickedup |= Item_GiveAmmoTo(item, player, RES_CELLS, autocvar_g_pickup_cells_max);
554 pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, autocvar_g_pickup_fuel_max);
555 if (item.itemdef.instanceOfWeaponPickup)
556 {
557 WepSet w, wp;
558 w = STAT(WEAPONS, item);
559 wp = w & ~STAT(WEAPONS, player);
560
561 if (wp || (item.spawnshieldtime && item.pickup_anyway > 0))
562 {
563 pickedup = true;
564 FOREACH(Weapons, it != WEP_Null, {
565 if(w & (it.m_wepset))
566 Item_NotifyWeapon(player, it);
567
568 if(wp & (it.m_wepset))
569 {
570 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
571 {
572 .entity weaponentity = weaponentities[slot];
573 if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
574 W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
575 }
576 W_GiveWeapon(player, it.m_id);
577 }
578 });
579 }
580 }
581
582 if (item.itemdef.instanceOfPowerup)
583 {
584 if ((item.itemdef == ITEM_FuelRegen) && !(player.items & IT_FUEL_REGEN))
585 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_FUELREGEN_GOT);
586 else if ((item.itemdef == ITEM_Jetpack) && !(player.items & IT_JETPACK))
587 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_JETPACK_GOT);
588 }
589
590 int its = item.items & ~(player.items) & IT_PICKUPMASK;
591 if (its)
592 {
593 pickedup = true;
594 player.items |= its;
595 // TODO: we probably want to show a message in the console, but not this one!
596 //Send_Notification(NOTIF_ONE, player, MSG_INFO, INFO_ITEM_WEAPON_GOT, item.netname);
597 }
598
599 if (item.strength_finished)
600 {
601 pickedup = true;
602 float t = max(time, StatusEffects_gettime(STATUSEFFECT_Strength, player));
604 t += item.strength_finished;
605 else
606 t = max(t, time + item.strength_finished);
607 StatusEffects_apply(STATUSEFFECT_Strength, player, t, 0);
608 }
609 if (item.invincible_finished)
610 {
611 pickedup = true;
612 float t = max(time, StatusEffects_gettime(STATUSEFFECT_Shield, player));
614 t += item.invincible_finished;
615 else
616 t = max(t, time + item.invincible_finished);
617 StatusEffects_apply(STATUSEFFECT_Shield, player, t, 0);
618 }
619 if (item.speed_finished)
620 {
621 pickedup = true;
622 float t = max(time, StatusEffects_gettime(STATUSEFFECT_Speed, player));
624 t += item.speed_finished;
625 else
626 t = max(t, time + item.speed_finished);
627 StatusEffects_apply(STATUSEFFECT_Speed, player, t, 0);
628 }
629 if (item.invisibility_finished)
630 {
631 pickedup = true;
632 float t = max(time, StatusEffects_gettime(STATUSEFFECT_Invisibility, player));
634 t += item.invisibility_finished;
635 else
636 t = max(t, time + item.invisibility_finished);
637 StatusEffects_apply(STATUSEFFECT_Invisibility, player, t, 0);
638 }
639 if (item.superweapons_finished)
640 {
641 pickedup = true;
642 float t = max(time, StatusEffects_gettime(STATUSEFFECT_Superweapon, player));
643 StatusEffects_apply(STATUSEFFECT_Superweapon, player, t + item.superweapons_finished, 0);
644 }
645
646 // always eat teamed entities
647 if(item.team)
648 pickedup = true;
649
650 if (!pickedup)
651 return false;
652
653 if(use_cts_autoswitch)
654 {
655 // CTS handling: never switch (0), always switch (1)
656 if(CS_CVAR(player).cvar_cl_autoswitch_cts == 1)
657 {
658 // crude hack to enforce switching weapons
659 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
660 {
661 .entity weaponentity = weaponentities[slot];
662 Weapon w = REGISTRY_GET(Weapons, item.weapon);
663 if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
664 if(client_hasweapon(player, w, weaponentity, true, false)) // ammo check
665 W_SwitchWeapon_Force(player, w, weaponentity);
666 }
667 }
668 }
669 else if(_switchweapon)
670 {
671 // non-CTS handling: weaponpriority-based autoswitch
672 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
673 {
674 .entity weaponentity = weaponentities[slot];
675 if(_switchweapon & BIT(slot))
676 {
677 Weapon best_wep = w_getbestweapon(player, weaponentity);
678 if(player.(weaponentity).m_switchweapon != best_wep)
679 W_SwitchWeapon_Force(player, best_wep, weaponentity);
680 }
681 }
682 }
683
684 return true;
685}
int autocvar_g_pickup_rockets_max
Definition ammo.qh:118
int autocvar_g_pickup_fuel_max
Definition ammo.qh:190
int autocvar_g_pickup_shells_max
Definition ammo.qh:46
int autocvar_g_pickup_cells_max
Definition ammo.qh:154
int autocvar_g_pickup_nails_max
Definition ammo.qh:82
const int IT_JETPACK
Definition item.qh:26
const int IT_PICKUPMASK
Definition item.qh:46
const int IT_FUEL_REGEN
Definition item.qh:28
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1500
void Item_NotifyWeapon(entity player, entity wep)
Definition items.qc:514
bool Item_GiveAmmoTo(entity item, entity player, Resource res_type, float ammomax)
Definition items.qc:486
void W_GiveWeapon(entity e, int wep)
Definition common.qc:33
bool autocvar_g_powerups_stack
void W_DropEvent(.void(Weapon, entity actor,.entity) event, entity player, int weapon_type, entity weapon_item,.entity weaponentity)

References autocvar_g_pickup_cells_max, autocvar_g_pickup_fuel_max, autocvar_g_pickup_nails_max, autocvar_g_pickup_rockets_max, autocvar_g_pickup_shells_max, autocvar_g_powerups_stack, BIT, client_hasweapon(), CS_CVAR, entity(), FOREACH, g_cts, IT_FUEL_REGEN, IT_JETPACK, IT_PICKUPMASK, Item_GiveAmmoTo(), Item_NotifyWeapon(), max(), MAX_WEAPONSLOTS, REGISTRY_GET, RES_ARMOR, Send_Notification(), STAT, StatusEffects_apply(), StatusEffects_gettime(), time, W_DropEvent(), w_getbestweapon, W_GiveWeapon(), W_SwitchWeapon_Force(), weaponentities, Weapons, and WepSet_FromWeapon.

Referenced by Pickup::giveTo(), and WeaponPickup::giveTo().

◆ Item_Reset()

void Item_Reset ( entity this)

Definition at line 784 of file items.qc.

785{
786 if (this.targetname != "" && !(this.spawnflags & 16)) // q3compat and/or target_give
787 if (this.move_movetype != MOVETYPE_FOLLOW && !this.tag_entity) // misc_follow compat
788 {
789 Item_Show(this, -1);
792 this.nextthink = 0;
793 return;
794 }
795
796 Item_Show(this, !this.state);
797
798 if (ITEM_IS_LOOT(this))
799 {
800 return;
801 }
802 setthink(this, Item_Think);
803 this.nextthink = time;
804 this.active = ACTIVE_ACTIVE;
806 {
808 }
809 if (this.itemdef.instanceOfPowerup || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially!
810 {
812 }
813}
float nextthink
int state
int active
Definition defs.qh:34
const int ACTIVE_ACTIVE
Definition defs.qh:37
#define ITEM_IS_LOOT(item)
Returns whether the item is loot.
Definition spawning.qh:37
#define setthink(e, f)
void Item_ScheduleInitialRespawn(entity e)
Definition items.qc:406
void Item_Think(entity this)
Definition items.qc:193
void Item_Show(entity e, int mode)
Definition items.qc:131
entity itemdef
Definition items.qh:83
string targetname
Definition triggers.qh:56
void WaypointSprite_Kill(entity wp)
entity waypointsprite_attached

References active, ACTIVE_ACTIVE, entity(), ITEM_IS_LOOT, Item_ScheduleInitialRespawn(), Item_Show(), Item_Think(), itemdef, move_movetype, MOVETYPE_FOLLOW, nextthink, setthink, spawnflags, STAT, state, tag_entity, targetname, time, waypointsprite_attached, WaypointSprite_Kill(), and WEPSET_SUPERWEAPONS.

Referenced by StartItem().

◆ Item_Respawn()

void Item_Respawn ( entity this)

Definition at line 242 of file items.qc.

243{
244 Item_Show(this, 1);
245 sound(this, CH_TRIGGER, this.itemdef.m_respawnsound, VOL_BASE, ATTEN_NORM); // play respawn sound
246
247 if (Item_ItemsTime_Allow(this.itemdef) || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
248 {
249 float t = Item_ItemsTime_UpdateTime(this, 0);
250 Item_ItemsTime_SetTime(this, t);
252 }
253
254 setthink(this, Item_Think);
255 this.nextthink = time;
256}
float Item_ItemsTime_UpdateTime(entity e, float t)
Definition itemstime.qc:129
void Item_ItemsTime_SetTimesForAllPlayers()
Definition itemstime.qc:122
void Item_ItemsTime_SetTime(entity e, float t)
Definition itemstime.qc:107
bool Item_ItemsTime_Allow(GameItem it)
Definition itemstime.qc:66

References ATTEN_NORM, CH_TRIGGER, entity(), Item_ItemsTime_Allow(), Item_ItemsTime_SetTime(), Item_ItemsTime_SetTimesForAllPlayers(), Item_ItemsTime_UpdateTime(), Item_Show(), Item_Think(), itemdef, nextthink, setthink, sound, STAT, time, VOL_BASE, and WEPSET_SUPERWEAPONS.

Referenced by Item_RespawnCountdown(), Item_RespawnThink(), and item_use().

◆ Item_RespawnCountdown()

void Item_RespawnCountdown ( entity this)

Definition at line 258 of file items.qc.

259{
261 {
264 Item_Respawn(this);
265 }
266 else
267 {
268 this.nextthink = time + 1;
269 ++this.item_respawncounter;
270 if(this.item_respawncounter == 1)
271 {
272 do {
273 {
274 entity wi = REGISTRY_GET(Weapons, this.weapon);
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;
278 break;
279 }
280 }
281 {
282 entity ii = this.itemdef;
283 if (ii != NULL) {
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;
286 break;
287 }
288 }
289 } while (0);
290 bool mutator_returnvalue = MUTATOR_CALLHOOK(Item_RespawnCountdown, this);
292 {
293 GameItem def = this.itemdef;
294 if (Item_ItemsTime_SpectatorOnly(def) && !mutator_returnvalue)
297 }
298 }
299
301 {
303 if(this.waypointsprite_attached.waypointsprite_visible_for_player(this.waypointsprite_attached, it, it))
304 {
305 msg_entity = it;
306 soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM, 0); // play respawn sound
307 }
308 });
309
311 //WaypointSprite_UpdateHealth(this.waypointsprite_attached, this.item_respawncounter);
312 }
313 }
314}
#define MUTATOR_CALLHOOK(name,...)
Definition base.qh:186
float MSG_ONE
Definition menudefs.qc:56
entity msg_entity
Definition progsdefs.qc:63
bool Item_ItemsTime_SpectatorOnly(GameItem it)
Definition itemstime.qc:58
void Item_RespawnCountdown(entity this)
Definition items.qc:258
void Item_Respawn(entity this)
Definition items.qc:242
float item_respawncounter
Definition items.qh:35
const float ITEM_RESPAWN_TICKS
Definition items.qh:19
void soundto(int _dest, entity e, int chan, string samp, float vol, float _atten, float _pitch)
Definition all.qc:74
#define SND(id)
Definition all.qh:35
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
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)
const int SPRITERULE_SPECTATOR

References ATTEN_NORM, CH_TRIGGER, entity(), FOREACH_CLIENT, IS_REAL_CLIENT, Item_ItemsTime_SpectatorOnly(), Item_Respawn(), ITEM_RESPAWN_TICKS, Item_RespawnCountdown(), item_respawncounter, itemdef, msg_entity, MSG_ONE, MUTATOR_CALLHOOK, nextthink, NULL, REGISTRY_GET, SND, soundto(), SPRITERULE_SPECTATOR, time, VOL_BASE, waypointsprite_attached, WaypointSprite_Kill(), WaypointSprite_Ping(), WaypointSprite_Spawn(), WaypointSprite_UpdateBuildFinished(), WaypointSprite_UpdateRule(), weapon, and Weapons.

Referenced by Item_RespawnCountdown(), Item_ScheduleRespawnIn(), MUTATOR_HOOKABLE(), and MUTATOR_HOOKFUNCTION().

◆ Item_ScheduleInitialRespawn()

void Item_ScheduleInitialRespawn ( entity e)

Definition at line 406 of file items.qc.

407{
408 Item_Show(e, 0);
409
410 float spawn_in;
411 if (autocvar_g_pickup_respawntime_initial_random == 0)
412 {
413 // range: respawntime .. respawntime + respawntimejitter
414 spawn_in = e.respawntime + random() * e.respawntimejitter;
415 }
416 else
417 {
418 float rnd;
419 if (autocvar_g_pickup_respawntime_initial_random == 1)
420 {
421 static float shared_random = 0;
422 // NOTE this code works only if items are scheduled at the same time (normal case)
423 // NOTE2 random() can't return exactly 1 so this check always work as intended
424 if (!shared_random || floor(time) > shared_random)
425 shared_random = floor(time) + random();
426 rnd = shared_random - floor(time);
427 }
428 else
429 rnd = random();
430
431 // range:
432 // if respawntime >= ITEM_RESPAWN_TICKS: ITEM_RESPAWN_TICKS .. respawntime + respawntimejitter
433 // else: 0 .. ITEM_RESPAWN_TICKS
434 // this is to prevent powerups spawning unexpectedly without waypoints
435 spawn_in = ITEM_RESPAWN_TICKS + rnd * (e.respawntime + e.respawntimejitter - ITEM_RESPAWN_TICKS);
436 }
437
438 Item_ScheduleRespawnIn(e, max(0, game_starttime - time) + ((e.respawntimestart) ? e.respawntimestart : spawn_in));
439}
float game_starttime
Definition stats.qh:82
float random(void)
float floor(float f)
void Item_ScheduleRespawnIn(entity e, float t)
Definition items.qc:326

References entity(), floor(), game_starttime, ITEM_RESPAWN_TICKS, Item_ScheduleRespawnIn(), Item_Show(), max(), random(), and time.

Referenced by Item_Reset().

◆ Item_ScheduleRespawn()

void Item_ScheduleRespawn ( entity e)

Definition at line 386 of file items.qc.

387{
388 if(e.respawntime > 0)
389 {
390 Item_Show(e, 0);
391
392 float adjusted_respawntime = adjust_respawntime(e.respawntime);
393 //LOG_INFOF("item %s will respawn in %f", e.classname, adjusted_respawntime);
394
395 // range: adjusted_respawntime - respawntimejitter .. adjusted_respawntime + respawntimejitter
396 float respawn_in = adjusted_respawntime + crandom() * e.respawntimejitter;
397 Item_ScheduleRespawnIn(e, respawn_in);
398 }
399 else // if respawntime is -1, this item does not respawn
400 Item_Show(e, -1);
401}
#define crandom()
Returns a random number between -1.0 and 1.0.
Definition random.qh:32
float adjust_respawntime(float normal_respawntime)
Adjust respawn time according to the number of players.
Definition items.qc:358

References adjust_respawntime(), crandom, entity(), Item_ScheduleRespawnIn(), and Item_Show().

Referenced by Item_ScheduleRespawnIn(), MUTATOR_HOOKABLE(), MUTATOR_HOOKFUNCTION(), and MUTATOR_HOOKFUNCTION().

◆ Item_ScheduleRespawnIn()

void Item_ScheduleRespawnIn ( entity e,
float t )

Definition at line 326 of file items.qc.

327{
328 // if the respawn time is longer than 10 seconds, show a waypoint, otherwise, just respawn normally
329 bool set_itemstime = Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS);
330 if ((set_itemstime || MUTATOR_CALLHOOK(Item_ScheduleRespawn, e, t)) && (t - ITEM_RESPAWN_TICKS) > 0)
331 {
333 e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS);
334 e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
335 e.item_respawncounter = 0;
336 }
337 else
338 {
340 e.nextthink = time;
341 e.scheduledrespawntime = time + t;
342 e.wait = time + t;
343 }
344
345 if (set_itemstime)
346 {
347 t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime);
350 }
351}
void Item_ScheduleRespawn(entity e)
Definition items.qc:386
void Item_RespawnThink(entity this)
Definition items.qc:316

References entity(), Item_ItemsTime_Allow(), Item_ItemsTime_SetTime(), Item_ItemsTime_SetTimesForAllPlayers(), Item_ItemsTime_UpdateTime(), ITEM_RESPAWN_TICKS, Item_RespawnCountdown(), Item_RespawnThink(), Item_ScheduleRespawn(), max(), MUTATOR_CALLHOOK, setthink, STAT, time, and WEPSET_SUPERWEAPONS.

Referenced by Item_ScheduleInitialRespawn(), and Item_ScheduleRespawn().

◆ Item_Show()

void Item_Show ( entity e,
int mode )

Definition at line 131 of file items.qc.

132{
134 e.ItemStatus &= ~ITS_STAYWEP;
135 entity def = e.itemdef;
136 if (mode > 0)
137 {
138 // make the item look normal, and be touchable
139 e.model = e.mdl;
140 e.solid = SOLID_TRIGGER;
141 e.spawnshieldtime = 1;
142 e.ItemStatus |= ITS_AVAILABLE;
143 }
144 else if (mode < 0)
145 {
146 // hide the item completely
147 e.model = string_null;
148 e.solid = SOLID_NOT;
149 e.spawnshieldtime = 1;
150 e.ItemStatus &= ~ITS_AVAILABLE;
151 }
152 else
153 {
154 bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.m_wepset & WEPSET_SUPERWEAPONS) : false // no weapon-stay on superweapons
155 || e.team // weapon stay isn't supported for teamed weapons
156 ;
157 if(def.instanceOfWeaponPickup && !nostay && g_weapon_stay)
158 {
159 // make the item translucent and not touchable
160 e.model = e.mdl;
161 e.solid = SOLID_TRIGGER; // can STILL be picked up!
162 e.effects |= EF_STARDUST;
163 e.spawnshieldtime = 0; // field indicates whether picking it up may give you anything other than the weapon
164 e.ItemStatus |= (ITS_AVAILABLE | ITS_STAYWEP);
165 }
166 else
167 {
168 e.solid = SOLID_NOT;
169 e.spawnshieldtime = 1;
170 e.ItemStatus &= ~ITS_AVAILABLE;
171 }
172 }
173
174 if (def.m_glow)
175 e.ItemStatus |= ITS_GLOW;
176
178 e.effects |= EF_NODEPTHTEST;
179
181 e.ItemStatus |= ITS_ALLOWFB;
182 else
183 e.ItemStatus &= ~ITS_ALLOWFB;
184
186 e.ItemStatus |= ITS_ALLOWSI;
187
188 // relink entity (because solid may have changed)
189 setorigin(e, e.origin);
190 e.SendFlags |= ISF_STATUS;
191}
const int ITS_STAYWEP
Definition item.qh:62
const int ITS_ALLOWSI
Definition item.qh:67
const int ITS_ALLOWFB
Definition item.qh:66
const int ITS_GLOW
Definition item.qh:68
const int ITS_AVAILABLE
Definition item.qh:65
const int ISF_STATUS
Definition item.qh:52
const float EF_STARDUST
const float SOLID_TRIGGER
const float EF_ADDITIVE
const float EF_FULLBRIGHT
const float SOLID_NOT
const float EF_NODEPTHTEST
#define false
Definition csprogsdefs.qh:6
string string_null
Definition nil.qh:9
float autocvar_sv_simple_items
Definition items.qh:15
bool autocvar_g_fullbrightitems
Definition items.qh:8
bool autocvar_g_nodepthtestitems
Definition items.qh:12

References autocvar_g_fullbrightitems, autocvar_g_nodepthtestitems, autocvar_sv_simple_items, EF_ADDITIVE, EF_FULLBRIGHT, EF_NODEPTHTEST, EF_STARDUST, entity(), g_weapon_stay, ISF_STATUS, ITS_ALLOWFB, ITS_ALLOWSI, ITS_AVAILABLE, ITS_GLOW, ITS_STAYWEP, SOLID_NOT, SOLID_TRIGGER, string_null, and WEPSET_SUPERWEAPONS.

Referenced by Item_Reset(), Item_Respawn(), Item_ScheduleInitialRespawn(), Item_ScheduleRespawn(), item_setactive(), and Item_Touch().

◆ Item_Touch()

void Item_Touch ( entity this,
entity toucher )

Definition at line 687 of file items.qc.

688{
689 // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
690 if (ITEM_IS_LOOT(this))
691 {
693 {
694 this.SendFlags |= ISF_REMOVEFX;
695 RemoveItem(this);
696 return;
697 }
698 }
699
700 if(!(toucher.flags & FL_PICKUPITEMS)
701 || IS_DEAD(toucher)
702 || (this.solid != SOLID_TRIGGER)
703 || (this.owner == toucher)
704 || (time < this.item_spawnshieldtime)
705 ) { return; }
706
707 switch (MUTATOR_CALLHOOK(ItemTouch, this, toucher))
708 {
709 case MUT_ITEMTOUCH_RETURN: { return; }
710 case MUT_ITEMTOUCH_PICKUP: { toucher = M_ARGV(1, entity); goto pickup; }
711 }
712
713 toucher = M_ARGV(1, entity);
714
715 if (ITEM_IS_EXPIRING(this))
716 {
719 this.speed_finished = max(0, this.speed_finished - time);
722 }
723 bool gave = ITEM_HANDLE(Pickup, this.itemdef, this, toucher);
724 if (!gave)
725 {
726 if (ITEM_IS_EXPIRING(this))
727 {
728 // undo what we did above
729 this.strength_finished += time;
731 this.speed_finished += time;
734 }
735 return;
736 }
737
738LABEL(pickup)
739
740 if(this.target != "" && this.target != "###item###") // q3compat
742
743 GameItem def = this.itemdef;
744 int ch = ((def.instanceOfPowerup && def.m_itemid != IT_RESOURCE) ? CH_TRIGGER_SINGLE : CH_TRIGGER);
746
747 MUTATOR_CALLHOOK(ItemTouched, this, toucher);
748 if (wasfreed(this))
749 {
750 return;
751 }
752
753 if (ITEM_IS_LOOT(this))
754 {
755 this.SendFlags |= ISF_REMOVEFX;
756 RemoveItem(this);
757 return;
758 }
759 if (!this.spawnshieldtime)
760 {
761 return;
762 }
763 entity e;
764 if (this.team)
765 {
767 IL_EACH(g_items, it.team == this.team,
768 {
769 if (it.itemdef) // is a registered item
770 {
771 Item_Show(it, -1);
772 it.scheduledrespawntime = 0;
773 RandomSelection_AddEnt(it, it.cnt, 0);
774 }
775 });
777 Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway)
778 }
779 else
780 e = this;
782}
#define M_ARGV(idx, type)
Definition base.qh:153
entity owner
Definition main.qh:87
float strength_finished
Definition item.qh:93
const int IT_RESOURCE
Definition item.qh:30
float invincible_finished
Definition item.qh:94
const int ISF_REMOVEFX
Definition item.qh:49
#define ITEM_HANDLE(signal,...)
Definition item.qh:126
#define IS_DEAD(s)
Definition player.qh:244
#define LABEL(id)
Definition compiler.qh:34
const int FL_PICKUPITEMS
Definition constants.qh:80
float solid
float spawnshieldtime
Definition damage.qh:61
float invisibility_finished
#define ITEM_IS_EXPIRING(item)
Returns whether the item is expiring (i.e.
Definition spawning.qh:56
void SUB_UseTargets(entity this, entity actor, entity trigger)
Definition triggers.qc:353
int SendFlags
Definition net.qh:159
float speed_finished
Definition speed.qh:17
entity entity toucher
Definition self.qh:76
void RemoveItem(entity this)
Definition items.qc:876
#define ITEM_TOUCH_NEEDKILL()
Definition items.qh:121
float superweapons_finished
Definition items.qh:39
float item_spawnshieldtime
Definition items.qh:42
string item_pickupsound
Definition items.qh:22
@ MUT_ITEMTOUCH_PICKUP
Definition events.qh:800
@ MUT_ITEMTOUCH_RETURN
Definition events.qh:799
#define _sound(e, c, s, v, a)
Definition sound.qh:43
string target
Definition triggers.qh:55

References _sound, ATTEN_NORM, CH_TRIGGER, CH_TRIGGER_SINGLE, entity(), FL_PICKUPITEMS, g_items, IL_EACH, invincible_finished, invisibility_finished, IS_DEAD, ISF_REMOVEFX, IT_RESOURCE, ITEM_HANDLE, ITEM_IS_EXPIRING, ITEM_IS_LOOT, item_pickupsound, Item_Show(), item_spawnshieldtime, ITEM_TOUCH_NEEDKILL, itemdef, LABEL, M_ARGV, max(), MUT_ITEMTOUCH_PICKUP, MUT_ITEMTOUCH_RETURN, MUTATOR_CALLHOOK, NULL, owner, RandomSelection_chosen_ent, RandomSelection_Init(), RemoveItem(), SendFlags, solid, SOLID_TRIGGER, spawnshieldtime, speed_finished, strength_finished, SUB_UseTargets(), superweapons_finished, target, team, time, toucher, and VOL_BASE.

Referenced by StartItem().

◆ ItemSend()

bool ItemSend ( entity this,
entity to,
int sf )

Definition at line 32 of file items.qc.

33{
34 if(this.gravity)
35 sf |= ISF_DROP;
36 else
37 sf &= ~ISF_DROP;
38
39 // if this item is being spawned (in CSQC's perspective)
40 // reuse ISF_SIZE and ISF_SIZE2 to also tell CSQC its bbox size
41 if(sf & ISF_SIZE)
42 {
43 if(this.maxs == ITEM_S_MAXS) // Small
44 {
45 sf |= ISF_SIZE;
46 sf &= ~ISF_SIZE2;
47 }
48 else if(this.maxs == ITEM_L_MAXS) // Large
49 {
50 sf &= ~ISF_SIZE;
51 sf |= ISF_SIZE2;
52 }
53 else // Default
54 sf |= ISF_SIZE | ISF_SIZE2;
55 }
56
57 WriteHeader(MSG_ENTITY, ENT_CLIENT_ITEM);
59
60 //WriteByte(MSG_ENTITY, this.cnt);
61 if(sf & ISF_LOCATION)
62 {
63 WriteVector(MSG_ENTITY, this.origin);
64 }
65
66 if(sf & ISF_ANGLES)
67 {
68 WriteAngleVector(MSG_ENTITY, this.angles);
69 }
70
71 if(sf & ISF_STATUS)
73
74 if(sf & (ISF_SIZE | ISF_SIZE2)) // always true when it's spawned (in CSQC's perspective)
75 {
76 WriteShort(MSG_ENTITY, bound(0, this.fade_end, 32767));
77
78 if(this.mdl == "")
79 LOG_TRACE("^1WARNING!^7 this.mdl is unset for item ", this.classname, "expect a crash just about now");
80
82 WriteByte(MSG_ENTITY, bound(0, this.skin, 255));
83 }
84
85 if(sf & ISF_COLORMAP)
86 {
88 WriteByte(MSG_ENTITY, this.glowmod.x * 255.0);
89 WriteByte(MSG_ENTITY, this.glowmod.y * 255.0);
90 WriteByte(MSG_ENTITY, this.glowmod.z * 255.0);
91 }
92
93 if(sf & ISF_DROP)
94 {
95 WriteVector(MSG_ENTITY, this.velocity);
96 }
97
98 return true;
99}
float gravity
Definition items.qh:17
float fade_end
Definition item.qh:87
const int ISF_COLORMAP
Definition item.qh:53
string mdl
Definition item.qh:89
const int ISF_SIZE2
Definition item.qh:51
const vector ITEM_S_MAXS
Definition item.qh:81
int ItemStatus
Definition item.qh:61
const vector ITEM_L_MAXS
Definition item.qh:84
const int ISF_ANGLES
Definition item.qh:55
const int ISF_SIZE
Definition item.qh:56
const int ISF_LOCATION
Definition item.qh:50
const int ISF_DROP
Definition item.qh:54
string classname
vector velocity
vector maxs
float colormap
vector glowmod
WriteString(chan, ent.netname)
ent angles
Definition ent_cs.qc:146
WriteByte(chan, ent.angles.y/DEC_FACTOR)
skin
Definition ent_cs.qc:168
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
float bound(float min, float value, float max)
void WriteShort(float data, float dest, float desto)

References angles, bound(), classname, colormap, entity(), fade_end, glowmod, gravity, ISF_ANGLES, ISF_COLORMAP, ISF_DROP, ISF_LOCATION, ISF_SIZE, ISF_SIZE2, ISF_STATUS, ITEM_L_MAXS, ITEM_S_MAXS, ItemStatus, LOG_TRACE, maxs, mdl, MSG_ENTITY, origin, skin, velocity, WriteByte(), WriteHeader, WriteShort(), and WriteString().

Referenced by StartItem(), UpdateCSQCProjectile(), and UpdateItemAfterTeleport().

◆ ItemUpdate()

void ItemUpdate ( entity this)

Definition at line 101 of file items.qc.

102{
103 this.oldorigin = this.origin;
104 this.SendFlags |= ISF_LOCATION;
105}
vector oldorigin

References entity(), ISF_LOCATION, oldorigin, origin, and SendFlags.

Referenced by Item_RespawnThink(), Item_Think(), UpdateCSQCProjectile(), and UpdateItemAfterTeleport().

◆ RemoveItem()

void RemoveItem ( entity this)

Definition at line 876 of file items.qc.

877{
878 if(wasfreed(this) || !this) { return; }
881
882 if (this.SendFlags & ISF_REMOVEFX)
883 {
884 // delay removal until ISF_REMOVEFX has been sent
885 setthink(this, RemoveItem);
886 this.nextthink = time + 2 * autocvar_sys_ticrate; // micro optimisation: next frame will be too soon
887 this.solid = SOLID_NOT; // untouchable
888 }
889 else
890 delete(this);
891}
float autocvar_sys_ticrate
Definition main.qh:17

References autocvar_sys_ticrate, entity(), ISF_REMOVEFX, nextthink, RemoveItem(), SendFlags, setthink, solid, SOLID_NOT, time, waypointsprite_attached, and WaypointSprite_Kill().

Referenced by Item_Damage(), Item_Think(), Item_Touch(), RemoveItem(), and StartItem().

◆ setItemGroup()

void setItemGroup ( entity this)

Definition at line 1272 of file items.qc.

1273{
1274 if (!IS_SMALL(this.itemdef) || ITEM_IS_LOOT(this))
1275 return;
1276
1278 for (entity head = WarpZone_SearchInRadius(this.origin, 120, MOVE_NOTHING, setItemGroup_cond); head; head = head.chain)
1279 {
1280 if (!this.item_group)
1281 {
1282 if (!head.item_group)
1283 head.item_group = ++item_group_last;
1284 this.item_group = head.item_group;
1285 }
1286 else // spawning item is already part of a item_group X
1287 {
1288 if (!head.item_group)
1289 head.item_group = this.item_group;
1290 else if (head.item_group != this.item_group) // found an item near the spawning item that is part of a different item_group Y
1291 {
1292 int grY = head.item_group;
1293 // move all items of item_group Y to item_group X
1294 IL_EACH(g_items, IS_SMALL(it.itemdef) && it.item_group == grY, it.item_group = this.item_group);
1295 }
1296 }
1297 }
1298}
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.
Definition common.qc:684
noref entity WarpZone_SearchInRadius_otherent
Free to use in the callback.
Definition common.qh:71
#define MOVE_NOTHING
Definition common.qh:35
bool setItemGroup_cond(entity e)
Definition items.qc:1268
#define IS_SMALL(def)
Definition items.qc:1266
int item_group_last
Definition items.qh:93
int item_group
Definition items.qh:94

References entity(), g_items, IL_EACH, IS_SMALL, item_group, item_group_last, ITEM_IS_LOOT, itemdef, MOVE_NOTHING, origin, setItemGroup_cond(), WarpZone_SearchInRadius(), and WarpZone_SearchInRadius_otherent.

Referenced by StartItem().

◆ setItemGroupCount()

void setItemGroupCount ( )

Definition at line 1300 of file items.qc.

1301{
1302 for (int k = 1; k <= item_group_last; ++k)
1303 {
1304 int count = 0;
1305 IL_EACH(g_items, it.item_group == k, { ++count; });
1306 if (count)
1307 IL_EACH(g_items, it.item_group == k, { it.item_group_count = count; });
1308 }
1309}
float count
Definition powerups.qc:22

References count, g_items, IL_EACH, and item_group_last.

Referenced by bot_spawn().

◆ StartItem()

void StartItem ( entity this)

Definition at line 1018 of file items.qc.

1019{
1020 entity def = this.itemdef;
1021 if (def.instanceOfWeapon)
1022 {
1023 weapon_defaultspawnfunc(this, def);
1024 if (wasfreed(this))
1025 return;
1026 def = this.itemdef;
1027 }
1028 else
1029 {
1030 if (def.m_spawnfunc_hookreplace)
1031 def = this.itemdef = def.m_spawnfunc_hookreplace(def, this);
1032 if (def.m_canonical_spawnfunc != "")
1033 this.classname = def.m_canonical_spawnfunc;
1034 }
1035
1036 // some mutators check for resources set by m_iteminit in FilterItem
1037 if(def.m_iteminit)
1038 def.m_iteminit(def, this);
1039
1040 // also checked by some mutators in FilterItem
1041 this.items = def.m_itemid;
1042 this.weapon = def.instanceOfWeaponPickup ? def.m_weapon.m_id : 0;
1043 if(this.weapon)
1044 STAT(WEAPONS, this) = WepSet_FromWeapon(REGISTRY_GET(Weapons, this.weapon));
1045 this.flags = FL_ITEM | def.m_itemflags;
1046
1047 // FilterItem may change any field of a specific instance of an item, but
1048 // it must not change any itemdef field (would cause mutators to break other mutators),
1049 // and must not convert items into different ones (StartItem could be refactored to support that).
1050 if(MUTATOR_CALLHOOK(FilterItem, this))
1051 {
1052 delete(this);
1053 return;
1054 }
1055
1056 if (!this.item_model_ent)
1057 this.item_model_ent = def.m_model;
1058
1059 if (!this.item_pickupsound_ent)
1060 this.item_pickupsound_ent = def.m_sound;
1061 if (!this.item_pickupsound && this.item_pickupsound_ent)
1063 if (this.item_pickupsound == "")
1064 LOG_WARNF("No pickup sound set for a %s", this.classname);
1065
1066 if(!this.pickup_anyway && def.m_pickupanyway)
1067 this.pickup_anyway = def.m_pickupanyway;
1068
1069 // bones_was_here TODO: implement sv_cullentities_dist and replace g_items_maxdist with it
1070 if(!this.fade_end)
1072
1073 // bones_was_here TODO: can we do this after we're sure the entity won't be deleted?
1074 IL_PUSH(g_items, this);
1075
1076 this.mdl = this.model ? this.model : strzone(this.item_model_ent.model_str());
1077 setmodel(this, MDL_Null); // precision set below
1078 // set item size before we spawn a waypoint or droptofloor or MoveOutOfSolid
1079 setsize (this, this.pos1 = def.m_mins, this.pos2 = def.m_maxs);
1080
1081 if (ITEM_IS_LOOT(this))
1082 {
1083 this.reset = RemoveItem;
1084
1086 this.gravity = 1;
1087
1088 setthink(this, Item_Think);
1091
1092 this.owner = NULL; // anyone can pick this up, including the player who threw it
1093 this.item_spawnshieldtime = time + 0.5; // but not straight away
1094
1095 this.takedamage = DAMAGE_YES;
1096 this.event_damage = Item_Damage;
1097 // enable this to have thrown items burn in lava
1098 //this.damagedbycontents = true;
1099 //IL_PUSH(g_damagedbycontents, this);
1100
1101 if (ITEM_IS_EXPIRING(this))
1102 {
1103 // if item is worthless after a timer, have it expire then
1105 }
1106
1107 // most loot items have a bigger horizontal size than a player
1108 nudgeoutofsolid_OrFallback(this);
1109
1110 // don't drop if in a NODROP zone (such as lava)
1111 traceline(this.origin, this.origin, MOVE_NORMAL, this);
1113 {
1114 delete(this);
1115 return;
1116 }
1117 }
1118 else // it's a level item
1119 {
1120 // must be done after def.m_iteminit() as that may set ITEM_FLAG_MUTATORBLOCKED
1121 if(!have_pickup_item(this))
1122 {
1123 delete(this);
1124 return;
1125 }
1126
1127 // must be done before Item_Reset() and after MUTATORBLOCKED check (blocked items may be uninitialised)
1128 if(!this.respawntime)
1129 {
1130 if (def.m_respawntime)
1131 this.respawntime = def.m_respawntime;
1132 else
1133 LOG_WARNF("Default respawntime for a %s is unavailable from its itemdef", this.classname);
1134 }
1135
1136 this.reset = Item_Reset;
1137
1138 if(this.angles != '0 0 0')
1139 this.SendFlags |= ISF_ANGLES;
1140
1141 if(q3compat)
1142 {
1143 if (!this.team)
1144 {
1145 string t = GetField_fullspawndata(this, "team", false);
1146 // bones_was_here: this hack is cheaper than changing to a .string strcmp()
1147 if(t) this.team = crc16(false, t);
1148 }
1149
1150 // In Q3 the origin is in the middle of the bbox ("radius" 15), in Xon it's at the bottom
1151 // so we need to offset vertically (only for items placed by the mapper).
1152 this.origin.z += -15 - this.mins.z;
1153 setorigin(this, this.origin);
1154 }
1155
1156 if(this.spawnflags & 1)
1157 this.noalign = 1;
1158 if (this.noalign > 0 && this.move_movetype != MOVETYPE_FOLLOW) // misc_follow compat
1160 else
1161 {
1162 if (!this.noalign)
1163 {
1164 DropToFloor_QC(this);
1165 if (wasfreed(this))
1166 return;
1167 }
1168
1169 if (this.move_movetype != MOVETYPE_FOLLOW) // misc_follow compat
1171
1173 }
1174
1175 if (this.targetname != "")
1176 this.use = item_use;
1177
1178 this.setactive = item_setactive;
1179 this.active = ACTIVE_ACTIVE;
1180
1181 if(autocvar_spawn_debug >= 2)
1182 {
1183 for (entity head = WarpZone_FindRadius(this.origin, 3); head; head = head.chain)
1184 if (head.is_item) // why not flags & fl_item?
1185 {
1186 LOG_TRACE("XXX Found duplicated item: ", def.m_name, vtos(this.origin));
1187 LOG_TRACE(" vs ", head.netname, vtos(head.origin));
1188 error("Mapper sucks.");
1189 }
1190 this.is_item = true;
1191 }
1192
1193 // DO NOT DELETE AFTER THIS POINT //
1195
1196 if ( def.instanceOfPowerup
1197 || def.instanceOfWeaponPickup
1198 || (def.instanceOfHealth && def != ITEM_HealthSmall)
1199 || (def.instanceOfArmor && def != ITEM_ArmorSmall)
1200 || (def.m_itemid & (IT_KEY1 | IT_KEY2))
1201 )
1202 {
1203 if(!this.target || this.target == "")
1204 this.target = "###item###"; // for finding the nearest item using findnearest
1205 }
1206
1207 Item_ItemsTime_SetTime(this, 0);
1208
1209 this.glowmod = def.m_color;
1210 }
1211
1212 this.bot_pickup = true;
1213 this.bot_pickupevalfunc = def.m_pickupevalfunc;
1214 this.bot_pickupbasevalue = def.m_botvalue;
1215 this.netname = def.m_name;
1216 settouch(this, Item_Touch);
1217 //this.effects |= EF_LOWPRECISION;
1218
1219 // support skinned models for powerups
1220 if(!this.skin)
1221 this.skin = def.m_skin;
1222
1223 if (!(this.spawnflags & 1024)) {
1224 if(def.instanceOfPowerup)
1225 this.ItemStatus |= ITS_ANIMATE1;
1226
1227 if(GetResource(this, RES_ARMOR) || GetResource(this, RES_HEALTH))
1228 this.ItemStatus |= ITS_ANIMATE2;
1229 }
1230
1231 if(def.instanceOfWeaponPickup)
1232 {
1233 if (!ITEM_IS_LOOT(this)) // if dropped, colormap is already set up nicely
1234 this.colormap = 1024; // color shirt=0 pants=0 grey
1235 if (!(this.spawnflags & 1024))
1236 this.ItemStatus |= ITS_ANIMATE1;
1237 this.SendFlags |= ISF_COLORMAP;
1238 }
1239
1240 this.state = 0;
1241 if(this.team)
1242 {
1243 if(!this.cnt)
1244 this.cnt = 1; // item probability weight
1245
1246 this.effects |= EF_NOGUNBOB; // marker for item team search
1248 this.reset = Item_FindTeam;
1249 }
1250 else
1251 Item_Reset(this);
1252
1253 Net_LinkEntity(this, !(def.instanceOfPowerup || def.instanceOfHealth || def.instanceOfArmor), 0, ItemSend);
1254
1255 // call this hook after everything else has been done
1256 MUTATOR_CALLHOOK(Item_Spawn, this);
1257
1258 // we should be sure this item will spawn before loading its assets
1259 // CSQC handles model precaching: it may not use this model (eg simple items) and may not have connected yet
1260 //precache_model(this.mdl);
1262
1263 setItemGroup(this);
1264}
void waypoint_spawnforitem(entity e)
float bot_pickup
Definition api.qh:43
float bot_pickupbasevalue
Definition bot.qh:68
string netname
Definition powerups.qc:20
float wait
Definition items.qc:17
const float IT_UPDATE_INTERVAL
Definition item.qh:76
const int ITS_ANIMATE1
Definition item.qh:63
const int ITS_ANIMATE2
Definition item.qh:64
void InitializeEntity(entity e, void(entity this) func, int order)
Definition world.qc:2198
#define setmodel(this, m)
Definition model.qh:26
vector weaponsInMap
all the weapons actually spawned in the map, does not include filtered items
Definition stats.qh:53
const int INITPRIO_SETLOCATION
Definition constants.qh:91
const int FL_ITEM
Definition constants.qh:69
float flags
const float MOVE_NORMAL
vector mins
#define use
model
Definition ent_cs.qc:164
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:167
#define WarpZone_FindRadius(org, radius)
Modified findradius aware of warpzones.
Definition common.qh:73
#define LOG_WARNF(...)
Definition log.qh:59
string precache_sound(string sample)
string vtos(vector v)
string strzone(string s)
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:133
const int MOVETYPE_TOSS
Definition movetypes.qh:139
#define error
Definition pre.qh:6
q3compat
Definition quake3.qc:59
#define settouch(e, f)
Definition self.qh:77
int autocvar_spawn_debug
Definition client.qh:51
bool ItemSend(entity this, entity to, int sf)
Definition items.qc:32
void Item_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition items.qc:992
void setItemGroup(entity this)
Definition items.qc:1272
void item_use(entity this, entity actor, entity trigger)
Definition items.qc:998
void Item_FindTeam(entity this)
Definition items.qc:815
bool have_pickup_item(entity this)
Definition items.qc:113
void Item_Reset(entity this)
Definition items.qc:784
void item_setactive(entity this, int act)
Definition items.qc:1006
void Item_Touch(entity this, entity toucher)
Definition items.qc:687
entity item_pickupsound_ent
Definition items.qh:23
entity item_model_ent
Definition items.qh:24
bool noalign
Definition items.qh:37
float pickup_anyway
Definition items.qh:27
float autocvar_g_items_maxdist
Definition items.qh:9
bool is_item
Definition items.qh:82
float respawntime
Definition items.qh:31
float autocvar_g_items_dropped_lifetime
Definition items.qh:10
string GetField_fullspawndata(entity e, string fieldname, bool vfspath)
Retrieves the value of a map entity field from fullspawndata.
Definition main.qc:451
#define Sound_fixpath(this)
Definition sound.qh:141
const int DAMAGE_YES
Definition subs.qh:80
vector pos1
Definition subs.qh:50
float takedamage
Definition subs.qh:78
#define IT_KEY1
Definition sys-pre.qh:20
#define IT_KEY2
Definition sys-pre.qh:21
void weapon_defaultspawnfunc(entity this, Weapon wpn)
Definition spawning.qc:29
void DropToFloor_QC(entity this)
Definition world.qc:2272

References active, ACTIVE_ACTIVE, angles, autocvar_g_items_dropped_lifetime, autocvar_g_items_maxdist, autocvar_spawn_debug, bot_pickup, bot_pickupbasevalue, classname, cnt, colormap, DAMAGE_YES, DPCONTENTS_NODROP, DropToFloor_QC(), EF_NOGUNBOB, effects, entity(), error, fade_end, FL_ITEM, flags, g_items, GetField_fullspawndata(), GetResource(), glowmod, gravity, have_pickup_item(), IL_PUSH(), InitializeEntity(), INITPRIO_SETLOCATION, invincible_finished, is_item, ISF_ANGLES, ISF_COLORMAP, IT_KEY1, IT_KEY2, IT_UPDATE_INTERVAL, Item_Damage(), Item_FindTeam(), ITEM_IS_EXPIRING, ITEM_IS_LOOT, Item_ItemsTime_SetTime(), item_model_ent, item_pickupsound, item_pickupsound_ent, Item_Reset(), item_setactive(), item_spawnshieldtime, Item_Think(), Item_Touch(), item_use(), itemdef, items, ItemSend(), ItemStatus, ITS_ANIMATE1, ITS_ANIMATE2, LOG_TRACE, LOG_WARNF, max(), mdl, mins, model, move_movetype, MOVE_NORMAL, MOVETYPE_FOLLOW, MOVETYPE_NONE, MOVETYPE_TOSS, MUTATOR_CALLHOOK, Net_LinkEntity(), netname, nextthink, noalign, NULL, origin, owner, pickup_anyway, pos1, precache_sound(), q3compat, REGISTRY_GET, RemoveItem(), RES_ARMOR, respawntime, SendFlags, set_movetype(), setItemGroup(), setmodel, setthink, settouch, skin, Sound_fixpath, spawnflags, STAT, state, strength_finished, strzone(), superweapons_finished, takedamage, target, targetname, team, time, trace_dpstartcontents, use, vtos(), wait, WarpZone_FindRadius, waypoint_spawnforitem(), weapon, weapon_defaultspawnfunc(), Weapons, weaponsInMap, and WepSet_FromWeapon.

Referenced by instagib_replace_item_with(), Item_Initialise(), lms_replace_with_extralife(), and W_ThrowNewWeapon().

◆ STATIC_INIT()

STATIC_INIT ( g_items )

Definition at line 119 of file items.qh.

119{ g_items = IL_NEW(); }
#define IL_NEW()

References g_items, and IL_NEW.

◆ UpdateItemAfterTeleport()

void UpdateItemAfterTeleport ( entity this)

Definition at line 107 of file items.qc.

108{
109 if(getSendEntity(this) == ItemSend)
110 ItemUpdate(this);
111}
#define getSendEntity(e)
void ItemUpdate(entity this)
Definition items.qc:101

References entity(), getSendEntity, ItemSend(), and ItemUpdate().

Referenced by TeleportPlayer(), and WarpZone_PostTeleportPlayer_Callback().

◆ weapon_pickupevalfunc()

float weapon_pickupevalfunc ( entity player,
entity item )

Definition at line 898 of file items.qc.

899{
900 // See if I have it already
901 if(STAT(WEAPONS, player) & STAT(WEAPONS, item))
902 {
903 // If I can pick it up
904 if(!item.spawnshieldtime)
905 return 0;
906 return ammo_pickupevalfunc(player, item);
907 }
908
909 // reduce weapon value if bot already got a good arsenal
910 float c = 1;
911 int weapons_value = 0;
912 FOREACH(Weapons, it != WEP_Null && (STAT(WEAPONS, player) & it.m_wepset), {
913 weapons_value += it.bot_pickupbasevalue;
914 });
915 c -= bound(0, weapons_value / 20000, 1) * 0.5;
916
917 return item.bot_pickupbasevalue * c;
918}
float ammo_pickupevalfunc(entity player, entity item)
Definition items.qc:920

References ammo_pickupevalfunc(), bound(), entity(), FOREACH, STAT, and Weapons.

Variable Documentation

◆ autocvar_g_balance_superweapons_time

float autocvar_g_balance_superweapons_time

◆ autocvar_g_fullbrightitems

bool autocvar_g_fullbrightitems

Definition at line 8 of file items.qh.

Referenced by Item_Show().

◆ autocvar_g_items_dropped_lifetime

float autocvar_g_items_dropped_lifetime

Definition at line 10 of file items.qh.

Referenced by powerups_DropItem(), and StartItem().

◆ autocvar_g_items_maxdist

float autocvar_g_items_maxdist

Definition at line 9 of file items.qh.

Referenced by StartItem().

◆ autocvar_g_nodepthtestitems

bool autocvar_g_nodepthtestitems

Definition at line 12 of file items.qh.

Referenced by Item_Show().

◆ autocvar_g_pickup_items

◆ autocvar_sv_simple_items

float autocvar_sv_simple_items

Definition at line 15 of file items.qh.

Referenced by Item_Show().

◆ count

int count

Definition at line 28 of file items.qh.

◆ g_items

◆ is_item

bool is_item

Definition at line 82 of file items.qh.

Referenced by StartItem().

◆ item_group

int item_group

Definition at line 94 of file items.qh.

Referenced by havocbot_movetogoal(), and setItemGroup().

◆ item_group_count

int item_group_count

Definition at line 95 of file items.qh.

◆ item_group_last

int item_group_last

Definition at line 93 of file items.qh.

Referenced by setItemGroup(), and setItemGroupCount().

◆ item_model_ent

entity item_model_ent

Definition at line 24 of file items.qh.

Referenced by StartItem().

◆ item_pickupsound

string item_pickupsound

Definition at line 22 of file items.qh.

Referenced by Item_Touch(), and StartItem().

◆ item_pickupsound_ent

entity item_pickupsound_ent

Definition at line 23 of file items.qh.

Referenced by StartItem().

◆ ITEM_RESPAWN_TICKS

const float ITEM_RESPAWN_TICKS = 10

◆ item_respawncounter

float item_respawncounter

Definition at line 35 of file items.qh.

Referenced by Item_RespawnCountdown().

◆ item_spawnshieldtime

float item_spawnshieldtime

Definition at line 42 of file items.qh.

Referenced by Item_Touch(), and StartItem().

◆ itemdef

◆ max_armorvalue

float max_armorvalue

Definition at line 26 of file items.qh.

Referenced by PlayerDamage(), and PlayerFrame().

◆ noalign

bool noalign

Definition at line 37 of file items.qh.

Referenced by buff_Init(), ctf_FlagThink(), Monster_Spawn(), spawn_item_key(), spawner_use(), and StartItem().

◆ pickup_anyway

float pickup_anyway

Definition at line 27 of file items.qh.

Referenced by StartItem(), and weapon_defaultspawnfunc().

◆ respawntime

◆ respawntimejitter

float respawntimejitter

Definition at line 32 of file items.qh.

Referenced by func_breakable_destroy(), and weapon_defaultspawnfunc().

◆ respawntimestart

float respawntimestart

Definition at line 33 of file items.qh.

◆ scheduledrespawntime

float scheduledrespawntime

Definition at line 30 of file items.qh.

◆ superweapons_finished

float superweapons_finished

Definition at line 39 of file items.qh.

Referenced by Item_Touch(), spawnfunc(), StartItem(), and weapon_defaultspawnfunc().