.float anim_start_time; // reusing for bob waveform synchronisation
.vector angles_held; // reusing for (re)storing original angles
.float wait, delay, pointtime; // reusing for despawn effects
+.vector m_mins, m_maxs; // reusing for storing standard bbox (same purpose as in SVQC itemdef)
HashMap ENT_CLIENT_ITEM_simple;
STATIC_INIT(ENT_CLIENT_ITEM_simple)
LOG_WARNF("this.model is unset for item %s", this.classname);
precache_model(this.model);
_setmodel(this, this.model);
- setsize(this, '-16 -16 0', '16 16 48');
- // bones_was_here TODO: network proper box size for sv_legacy_bbox_expand 0
+ setsize(this, this.m_mins, this.m_maxs);
}
void ItemDraw(entity this)
{
- bool wantsimple = autocvar_cl_simple_items && this.ItemStatus & ITS_ALLOWSI;
+ bool wantsimple = autocvar_cl_simple_items && (this.ItemStatus & ITS_ALLOWSI);
if(wantsimple != this.item_simple && this.item_simple != -1)
ItemSetModel(this, wantsimple);
// no bobbing applied to simple items, for consistency's sake (no visual difference between ammo and weapons)
- bool animate = autocvar_cl_items_animate & 1 && this.item_simple <= 0 && (this.ItemStatus & ITS_ANIMATE1 || this.ItemStatus & ITS_ANIMATE2);
+ bool animate = (autocvar_cl_items_animate & 1) && this.item_simple <= 0 && ((this.ItemStatus & ITS_ANIMATE1) || (this.ItemStatus & ITS_ANIMATE2));
// rotation must be set before running physics
if(!animate)
if (bobheight != this.origin_z - this.oldorigin_z)
{
this.origin_z = this.oldorigin_z + bobheight;
- this.mins_z = 0 - bobheight; // don't want the absmin and absmax to bob
- this.maxs_z = 48 - bobheight;
- // bones_was_here TODO: network proper box size for sv_legacy_bbox_expand 0
+ this.mins_z = this.m_mins.z - bobheight; // don't want the absmin and absmax to bob
+ this.maxs_z = this.m_maxs.z - bobheight;
}
// set alpha based on distance
if(autocvar_cl_items_animate & 2)
this.alpha *= (this.wait - time) / IT_DESPAWNFX_TIME;
- if(autocvar_cl_items_animate & 4 && time >= this.pointtime)
+ if((autocvar_cl_items_animate & 4) && time >= this.pointtime)
{
pointparticles(EFFECT_ITEM_DESPAWN, this.origin + '0 0 16', '0 0 0', 1);
if (this.delay > 0.0625)
this.angles = this.angles_held = ReadAngleVector();
}
- if(sf & ISF_SIZE)
- {
- setsize(this, '-16 -16 0', '16 16 48');
- }
-
if(sf & ISF_STATUS) // need to read/write status first so model can handle simple, fb etc.
{
+ int prevItemStatus = this.ItemStatus;
this.ItemStatus = ReadByte();
if(this.ItemStatus & ITS_ALLOWFB)
else
this.effects &= ~EF_FULLBRIGHT;
- if(this.ItemStatus & ITS_GLOW)
+ if(this.ItemStatus & ITS_AVAILABLE)
{
- if(this.ItemStatus & ITS_AVAILABLE)
+ if(this.solid != SOLID_TRIGGER)
+ {
+ this.solid = SOLID_TRIGGER;
+ setorigin(this, this.origin); // link it to the area grid
+ }
+
+ if(this.ItemStatus & ITS_GLOW)
this.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
- else
+ if(!(prevItemStatus & ITS_AVAILABLE) && this.alpha && !isnew)
+ pointparticles(EFFECT_ITEM_RESPAWN, (this.absmin + this.absmax) * 0.5, '0 0 0', 1);
+ }
+ else
+ {
+ if(this.solid != SOLID_NOT)
+ {
+ this.solid = SOLID_NOT;
+ setorigin(this, this.origin); // optimisation: unlink it from the area grid
+ }
+
+ if(this.ItemStatus & ITS_GLOW)
this.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT);
+ if((prevItemStatus & ITS_AVAILABLE) && this.alpha)
+ pointparticles(EFFECT_ITEM_PICKUP, (this.absmin + this.absmax) * 0.5, '0 0 0', 1);
}
}
- if(sf & ISF_MODEL)
+ if(sf & ISF_SIZE || sf & ISF_SIZE2) // always true when it's spawned (in CSQC's perspective)
{
- if (isnew) IL_PUSH(g_drawables, this);
- this.draw = ItemDraw;
- this.solid = SOLID_TRIGGER;
- //this.flags |= FL_ITEM;
+ if(isnew)
+ {
+ IL_PUSH(g_drawables, this);
+ this.draw = ItemDraw;
+ this.flags |= FL_ITEM;
+ this.entremove = ItemRemove;
+ }
+
+ if(sf & ISF_SIZE && !(sf & ISF_SIZE2)) // Small
+ {
+ this.m_mins = ITEM_S_MINS;
+ this.m_maxs = ITEM_S_MAXS;
+ }
+ else if(!(sf & ISF_SIZE) && sf & ISF_SIZE2) // Large
+ {
+ this.m_mins = ITEM_D_MINS;
+ this.m_maxs = ITEM_L_MAXS;
+ }
+ else // Default
+ {
+ this.m_mins = ITEM_D_MINS;
+ this.m_maxs = ITEM_D_MAXS;
+ }
this.fade_end = ReadShort();
{
this.gravity = 1;
this.pushable = true;
- //this.angles = '0 0 0';
set_movetype(this, MOVETYPE_TOSS);
this.velocity = ReadVector();
}
+ else if (this.gravity) // caution: kludge FIXME (with sv_legacy_bbox_expand)
+ {
+ // workaround for prediction errors caused by bbox discrepancy between SVQC and CSQC
+ this.gravity = 0; // don't do this kludge again
+ this.pushable = false; // no fun allowed
+ set_movetype(this, MOVETYPE_NONE); // disable physics
+ this.velocity = '0 0 0'; // disable it more
+ SET_ONGROUND(this); // extra overkill
+ }
- this.entremove = ItemRemove;
+ if(sf & ISF_REMOVEFX && !(sf & ISF_SIZE) && !(sf & ISF_SIZE2)) // TODO !isnew isn't reliable for this... are we double sending initialisations?
+ {
+ // no longer available to pick up, about to be removed
+ if (this.drawmask) // this.alpha > 0
+ pointparticles(EFFECT_ITEM_PICKUP, (this.absmin + this.absmax) * 0.5, '0 0 0', 1);
+ // removing now causes CSQC_Ent_Remove() to spam
+ this.drawmask = 0;
+ IL_REMOVE(g_drawables, this);
+ this.solid = SOLID_NOT;
+ }
return true;
}