#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"
#include "../lib/warpzone/util_server.qh"
#endif
+REGISTER_NET_LINKED(ENT_CLIENT_ITEM)
+
#ifdef CSQC
void ItemDraw(entity self)
{
self.drawmask = MASK_NORMAL;
}
-void ItemRead(float _IsNew)
-{SELFPARAM();
+NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
+{
int sf = ReadByte();
if(sf & ISF_LOCATION)
if(self.ItemStatus & ITS_ANIMATE2)
self.move_avelocity = '0 -90 0';
}
+ return true;
}
#endif
else
sf &= ~ISF_DROP;
- WriteByte(MSG_ENTITY, ENT_CLIENT_ITEM);
+ WriteHeader(MSG_ENTITY, ENT_CLIENT_ITEM);
WriteByte(MSG_ENTITY, sf);
//WriteByte(MSG_ENTITY, self.cnt);
e.spawnshieldtime = 1;
e.ItemStatus &= ~ITS_AVAILABLE;
}
- else if(e.itemdef.instanceOfWeaponPickup && !(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;
void Item_ItemsTime_SetTime(entity e, float t);
void Item_ItemsTime_SetTimesForAllPlayers();
-void Item_Respawn (void)
+void Item_Respawn ()
{SELFPARAM();
Item_Show(self, 1);
// this is ugly...
Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
}
-void Item_RespawnCountdown (void)
+void Item_RespawnCountdown ()
{SELFPARAM();
if(self.count >= ITEM_RESPAWN_TICKS)
{
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;
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 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 : Sound_fixpath(this.item_pickupsound_ent)), 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);
}
}
// Savage: used for item garbage-collection
// TODO: perhaps nice special effect?
-void RemoveItem(void)
+void RemoveItem()
{SELFPARAM();
if(wasfreed(self) || !self) { return; }
Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
RemoveItem();
}
-void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter, float itemflags)
+void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter)
{
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;
startitem_failed = false;
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);
// 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');
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);
}
this.SendFlags |= ISF_SIZE;
- if(def.instanceOfPowerup)
- 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(def.instanceOfWeaponPickup)
{
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;
}
this,
this.itemdef = def,
def.m_respawntime(), // defaultrespawntime
- def.m_respawntimejitter(), // defaultrespawntimejitter
- def.m_itemflags // itemflags
+ def.m_respawntimejitter() // defaultrespawntimejitter
);
}
return (v0 != v1);
}
-float GiveBit(entity e, .float fld, float bit, float op, float val)
-{
- float v0, v1;
- v0 = (e.(fld) & bit);
- switch(op)
- {
- case OP_SET:
- if(val > 0)
- e.(fld) |= bit;
- else
- e.(fld) &= ~bit;
- break;
- case OP_MIN:
- case OP_PLUS:
- if(val > 0)
- e.(fld) |= bit;
- break;
- case OP_MAX:
- if(val <= 0)
- e.(fld) &= ~bit;
- break;
- case OP_MINUS:
- if(val > 0)
- e.(fld) &= ~bit;
- break;
- }
- v1 = (e.(fld) & bit);
- return (v0 != v1);
-}
-
-float GiveValue(entity e, .float fld, float op, float val)
-{
- float v0, v1;
- v0 = e.(fld);
- switch(op)
- {
- case OP_SET:
- e.(fld) = val;
- break;
- case OP_MIN:
- e.(fld) = max(e.(fld), val); // min 100 cells = at least 100 cells
- break;
- case OP_MAX:
- e.(fld) = min(e.(fld), val);
- break;
- case OP_PLUS:
- e.(fld) += val;
- break;
- case OP_MINUS:
- e.(fld) -= val;
- break;
- }
- v1 = e.(fld);
- return (v0 != v1);
-}
-
void GiveSound(entity e, float v0, float v1, float t, string snd_incr, string snd_decr)
{
if(v1 == v0)