#include "bot/bot.qh"
#include "bot/waypoints.qh"
- #include "mutators/mutators_include.qh"
+ #include "mutators/all.qh"
#include "weapons/common.qh"
#include "weapons/selection.qh"
#include "weapons/weaponsystem.qh"
#include "../common/constants.qh"
- #include "../common/deathtypes.qh"
+ #include "../common/deathtypes/all.qh"
#include "../common/notifications.qh"
#include "../common/triggers/subs.qh"
#include "../common/util.qh"
if(sf & ISF_SIZE)
{
- WriteByte(MSG_ENTITY, ((self.flags & FL_POWERUP) || self.health || self.armorvalue));
+ Pickup p = this.itemdef;
+ WriteByte(MSG_ENTITY, p.instanceOfPowerup || p.instanceOfHealth || p.instanceOfArmor);
}
if(sf & ISF_STATUS)
item.SendFlags |= ISF_LOCATION;
}
-float have_pickup_item(void)
-{SELFPARAM();
- if(self.flags & FL_POWERUP)
+bool have_pickup_item(entity this)
+{
+ if(this.itemdef.instanceOfPowerup)
{
if(autocvar_g_powerups > 0)
return true;
if(autocvar_g_pickup_items == 0)
return false;
if(g_weaponarena)
- if(self.weapons || (self.items & IT_AMMO)) // no item or ammo pickups in weaponarena
+ if(this.weapons || (this.items & IT_AMMO)) // no item or ammo pickups in weaponarena
return false;
}
return true;
e.spawnshieldtime = 1;
e.ItemStatus &= ~ITS_AVAILABLE;
}
- else if((e.flags & FL_WEAPON) && !(e.flags & FL_NO_WEAPON_STAY) && g_weapon_stay)
+ else {
+ entity def = e.itemdef;
+ bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.weapons & WEPSET_SUPERWEAPONS) : false // no weapon-stay on superweapons
+ || e.team // weapon stay isn't supported for teamed weapons
+ ;
+ if(def.instanceOfWeaponPickup && !nostay && g_weapon_stay)
{
// make the item translucent and not touchable
e.model = e.mdl;
e.glowmod = e.colormod;
e.spawnshieldtime = 1;
e.ItemStatus &= ~ITS_AVAILABLE;
- }
+ }}
if (e.items & ITEM_Strength.m_itemid || e.items & ITEM_Shield.m_itemid)
e.ItemStatus |= ITS_POWERUP;
WaypointSprite_Ping(self.waypointsprite_attached);
//WaypointSprite_UpdateHealth(self.waypointsprite_attached, self.count);
}
- else
- sound(self, CH_TRIGGER, SND_ITEMRESPAWNCOUNTDOWN, VOL_BASE, ATTEN_NORM); // play respawn sound
}
}
if (item.spawnshieldtime)
{
- if ((player.(ammotype) < ammomax) || item.pickup_anyway)
+ if ((player.(ammotype) < ammomax) || item.pickup_anyway > 0)
{
player.(ammotype) = bound(player.(ammotype), ammomax, player.(ammotype) + item.(ammotype));
goto YEAH;
pickedup |= Item_GiveAmmoTo(item, player, health, item.max_health, ITEM_MODE_HEALTH);
pickedup |= Item_GiveAmmoTo(item, player, armorvalue, item.max_armorvalue, ITEM_MODE_ARMOR);
- if (item.flags & FL_WEAPON)
+ if (item.itemdef.instanceOfWeaponPickup)
{
WepSet it;
it = item.weapons;
it &= ~player.weapons;
- if (it || (item.spawnshieldtime && item.pickup_anyway))
+ if (it || (item.spawnshieldtime && item.pickup_anyway > 0))
{
pickedup = true;
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
return 0;
// crude hack to enforce switching weapons
- if(g_cts && (item.flags & FL_WEAPON))
+ if(g_cts && item.itemdef.instanceOfWeaponPickup)
{
W_SwitchWeapon_Force(player, item.weapon);
return 1;
return 1;
}
-void Item_Touch (void)
-{SELFPARAM();
- entity e, head;
+void Item_Touch()
+{
+ SELFPARAM();
// remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
- if(self.classname == "droppedweapon")
+ if (this.classname == "droppedweapon")
{
if (ITEM_TOUCH_NEEDKILL())
{
- remove(self);
+ remove(this);
return;
}
}
if(!(other.flags & FL_PICKUPITEMS)
|| other.frozen
|| other.deadflag
- || (self.solid != SOLID_TRIGGER)
- || (self.owner == other)
- || (time < self.item_spawnshieldtime)
- ) { return;}
+ || (this.solid != SOLID_TRIGGER)
+ || (this.owner == other)
+ || (time < this.item_spawnshieldtime)
+ ) { return; }
- switch(MUTATOR_CALLHOOK(ItemTouch, self, other))
+ switch (MUTATOR_CALLHOOK(ItemTouch, this, other))
{
case MUT_ITEMTOUCH_RETURN: { return; }
case MUT_ITEMTOUCH_PICKUP: { goto pickup; }
}
- if (self.classname == "droppedweapon")
+ if (this.classname == "droppedweapon")
{
- self.strength_finished = max(0, self.strength_finished - time);
- self.invincible_finished = max(0, self.invincible_finished - time);
- self.superweapons_finished = max(0, self.superweapons_finished - time);
+ this.strength_finished = max(0, this.strength_finished - time);
+ this.invincible_finished = max(0, this.invincible_finished - time);
+ this.superweapons_finished = max(0, this.superweapons_finished - time);
}
- entity it = self.itemdef;
- bool gave = (it && it.instanceOfPickup) ? ITEM_HANDLE(Pickup, it, self, other) : Item_GiveTo(self, other);
+ entity it = this.itemdef;
+ bool gave = ITEM_HANDLE(Pickup, it, this, other);
if (!gave)
{
- if (self.classname == "droppedweapon")
+ if (this.classname == "droppedweapon")
{
// undo what we did above
- self.strength_finished += time;
- self.invincible_finished += time;
- self.superweapons_finished += time;
+ this.strength_finished += time;
+ this.invincible_finished += time;
+ this.superweapons_finished += time;
}
return;
}
other.last_pickup = time;
- Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
- _sound (other, CH_TRIGGER, (self.item_pickupsound ? self.item_pickupsound : self.item_pickupsound_ent.sound_str()), VOL_BASE, ATTEN_NORM);
+ Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
+ _sound (other, CH_TRIGGER, (this.item_pickupsound ? this.item_pickupsound : this.item_pickupsound_ent.sound_str()), VOL_BASE, ATTEN_NORM);
- if (self.classname == "droppedweapon")
- remove (self);
- else if (self.spawnshieldtime)
+ if (this.classname == "droppedweapon")
+ remove (this);
+ else if (this.spawnshieldtime)
{
- if(self.team)
+ entity e;
+ if(this.team)
{
RandomSelection_Init();
- for(head = world; (head = findfloat(head, team, self.team)); )
+ for(entity head = world; (head = findfloat(head, team, this.team)); )
{
if(head.flags & FL_ITEM)
if(head.classname != "item_flag_team" && head.classname != "item_key_team")
}
else
- e = self;
+ e = this;
Item_ScheduleRespawn(e);
}
}
if (this.waypointsprite_attached)
WaypointSprite_Kill(this.waypointsprite_attached);
- if ((this.flags & FL_POWERUP) || (this.weapons & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially!
+ if (this.itemdef.instanceOfPowerup || (this.weapons & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially!
Item_ScheduleInitialRespawn(this);
}
}
RemoveItem();
}
-void _StartItem(entity this, string itemmodel, string pickupsound, float defaultrespawntime, float defaultrespawntimejitter, string itemname, float itemid, float weaponid, float itemflags, float(entity player, entity item) pickupevalfunc, float pickupbasevalue)
+void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter)
{
- startitem_failed = false;
-
- if(this.model == "")
- this.model = itemmodel;
+ string itemname = def.m_name;
+ Model itemmodel = def.m_model;
+ Sound pickupsound = def.m_sound;
+ float(entity player, entity item) pickupevalfunc = def.m_pickupevalfunc;
+ float pickupbasevalue = def.m_botvalue;
+ int itemflags = def.m_itemflags;
- if(this.model == "")
- {
- error(strcat("^1Tried to spawn ", itemname, " with no model!\n"));
- return;
- }
+ startitem_failed = false;
- if(this.item_pickupsound == "")
- this.item_pickupsound = pickupsound;
+ this.item_model_ent = itemmodel;
+ this.item_pickupsound_ent = pickupsound;
if(!this.respawntime) // both need to be set
{
this.respawntimejitter = defaultrespawntimejitter;
}
+ int itemid = def.m_itemid;
this.items = itemid;
+ int weaponid = def.instanceOfWeaponPickup ? def.m_weapon.m_id : 0;
this.weapon = weaponid;
if(!this.fade_end)
this.event_damage = Item_Damage;
if(this.strength_finished || this.invincible_finished || this.superweapons_finished)
- /*
- if(this.items == 0)
- if(!(this.weapons & ~WEPSET_SUPERWEAPONS)) // only superweapons
- if(this.ammo_nails == 0)
- if(this.ammo_cells == 0)
- if(this.ammo_rockets == 0)
- if(this.ammo_shells == 0)
- if(this.ammo_fuel == 0)
- if(this.health == 0)
- if(this.armorvalue == 0)
- */
{
// if item is worthless after a timer, have it expire then
this.nextthink = max(this.strength_finished, this.invincible_finished, this.superweapons_finished);
}
else
{
- if(!have_pickup_item())
+ if(!have_pickup_item(this))
{
startitem_failed = true;
remove (this);
// it's a level item
if(this.spawnflags & 1)
this.noalign = 1;
- if (this.noalign)
+ if (this.noalign > 0)
this.movetype = MOVETYPE_NONE;
else
this.movetype = MOVETYPE_TOSS;
// do item filtering according to game mode and other things
- if (!this.noalign)
+ if (this.noalign <= 0)
{
// first nudge it off the floor a little bit to avoid math errors
setorigin(this, this.origin + '0 0 1');
// set item size before we spawn a spawnfunc_waypoint
- if((itemflags & FL_POWERUP) || this.health || this.armorvalue)
- setsize (this, '-16 -16 0', '16 16 48');
- else
- setsize (this, '-16 -16 0', '16 16 32');
+ setsize(this, def.m_mins, def.m_maxs);
this.SendFlags |= ISF_SIZE;
// note droptofloor returns false if stuck/or would fall too far
- WITH(entity, self, this, droptofloor());
+ if (!this.noalign)
+ WITH(entity, self, this, droptofloor());
waypoint_spawnforitem(this);
}
precache_model(this.model);
precache_sound(this.item_pickupsound);
- if ((itemflags & (FL_POWERUP | FL_WEAPON)) || (itemid & (IT_HEALTH | IT_ARMOR | IT_KEY1 | IT_KEY2)))
- this.target = "###item###"; // for finding the nearest item using find()
+ if ( def.instanceOfPowerup
+ || def.instanceOfWeaponPickup
+ || (def.instanceOfHealth && def != ITEM_HealthSmall)
+ || (def.instanceOfArmor && def != ITEM_ArmorSmall)
+ || (itemid & (IT_KEY1 | IT_KEY2))
+ ) this.target = "###item###"; // for finding the nearest item using find()
Item_ItemsTime_SetTime(this, 0);
}
this.bot_pickup = true;
this.bot_pickupevalfunc = pickupevalfunc;
this.bot_pickupbasevalue = pickupbasevalue;
- this.mdl = this.model;
+ this.mdl = this.model ? this.model : strzone(this.item_model_ent.model_str());
this.netname = itemname;
this.touch = Item_Touch;
setmodel(this, MDL_Null); // precision set below
//this.effects |= EF_LOWPRECISION;
- if((itemflags & FL_POWERUP) || this.health || this.armorvalue)
- {
- this.pos1 = '-16 -16 0';
- this.pos2 = '16 16 48';
- }
- else
- {
- this.pos1 = '-16 -16 0';
- this.pos2 = '16 16 32';
- }
- setsize (this, this.pos1, this.pos2);
+ setsize (this, this.pos1 = def.m_mins, this.pos2 = def.m_maxs);
this.SendFlags |= ISF_SIZE;
- if(itemflags & FL_POWERUP)
- this.ItemStatus |= ITS_ANIMATE1;
-
- if(this.armorvalue || this.health)
- this.ItemStatus |= ITS_ANIMATE2;
+ if (!(this.spawnflags & 1024)) {
+ if(def.instanceOfPowerup)
+ this.ItemStatus |= ITS_ANIMATE1;
+
+ if(this.armorvalue || this.health)
+ this.ItemStatus |= ITS_ANIMATE2;
+ }
- if(itemflags & FL_WEAPON)
+ if(def.instanceOfWeaponPickup)
{
if (this.classname != "droppedweapon") // if dropped, colormap is already set up nicely
this.colormap = 1024; // color shirt=0 pants=0 grey
else
this.gravity = 1;
-
- this.ItemStatus |= ITS_ANIMATE1;
+ if (!(this.spawnflags & 1024))
+ this.ItemStatus |= ITS_ANIMATE1;
this.ItemStatus |= ISF_COLORMAP;
}
else
Item_Reset(this);
- Net_LinkEntity(this, !((itemflags & FL_POWERUP) || this.health || this.armorvalue), 0, ItemSend);
+ Net_LinkEntity(this, !(def.instanceOfPowerup || def.instanceOfHealth || def.instanceOfArmor), 0, ItemSend);
// call this hook after everything else has been done
if (MUTATOR_CALLHOOK(Item_Spawn, this))
}
}
-void StartItem(entity this, entity a)
+void StartItem(entity this, GameItem def)
{
- this.itemdef = a;
_StartItem(
this,
- strzone(a.m_model.model_str()), // itemmodel
- a.m_sound, // pickupsound
- a.m_respawntime(), // defaultrespawntime
- a.m_respawntimejitter(), // defaultrespawntimejitter
- a.m_name, // itemname
- a.m_itemid, // itemid
- 0, // weaponid
- a.m_itemflags, // itemflags
- a.m_pickupevalfunc, // pickupevalfunc
- a.m_botvalue // pickupbasevalue
+ this.itemdef = def,
+ def.m_respawntime(), // defaultrespawntime
+ def.m_respawntimejitter() // defaultrespawntimejitter
);
}