Xonotic
items.qc
Go to the documentation of this file.
1 #include "items.qh"
2 
3 #include <client/main.qh>
4 #include <common/items/_mod.qh>
6 #include <common/weapons/_all.qh>
9 #include <lib/warpzone/common.qh>
10 
12 .vector item_glowmod;
13 .bool item_simple; // probably not really needed, but better safe than sorry
14 .float alpha;
15 .bool pushable;
17 {
18  bool veh_hud = (hud && autocvar_cl_ghost_items_vehicle);
19 
20  if(!veh_hud && (this.ItemStatus & ITS_AVAILABLE))
21  {
22  this.alpha = 1;
23  this.colormod = '1 1 1';
24  this.glowmod = this.item_glowmod;
25  }
26  else
27  {
30  }
31 
32  if((!veh_hud) && (this.ItemStatus & ITS_STAYWEP))
33  {
36  }
37 
38  this.drawmask = ((this.alpha <= 0) ? 0 : MASK_NORMAL);
39 }
40 
41 void ItemDraw(entity this)
42 {
43  if(this.gravity)
44  {
45  Movetype_Physics_MatchServer(this, false);
46  if(IS_ONGROUND(this))
47  { // For some reason avelocity gets set to '0 0 0' here ...
48  this.oldorigin = this.origin;
49  this.gravity = 0;
50 
52  { // ... so reset it if animations are requested.
53  if(this.ItemStatus & ITS_ANIMATE1)
54  this.avelocity = '0 180 0';
55 
56  if(this.ItemStatus & ITS_ANIMATE2)
57  this.avelocity = '0 -90 0';
58  }
59 
60  // delay is for blocking item's position for a while;
61  // it's a workaround for dropped weapons that receive the position
62  // another time right after they spawn overriding animation position
63  this.onground_time = time + 0.5;
64  }
65  }
66  else if (autocvar_cl_animate_items && !this.item_simple) // no bobbing applied to simple items, for consistency's sake (no visual difference between ammo and weapons)
67  {
68  if(this.ItemStatus & ITS_ANIMATE1)
69  {
70  this.angles += this.avelocity * frametime;
71  float fade_in = bound(0, time - this.onground_time, 1);
72  setorigin(this, this.oldorigin + fade_in * ('0 0 10' + '0 0 8' * sin((time - this.onground_time) * 2)));
73  }
74 
75  if(this.ItemStatus & ITS_ANIMATE2)
76  {
77  this.angles += this.avelocity * frametime;
78  float fade_in = bound(0, time - this.onground_time, 1);
79  setorigin(this, this.oldorigin + fade_in * ('0 0 8' + '0 0 4' * sin((time - this.onground_time) * 3)));
80  }
81  }
82 
83  Item_SetAlpha(this);
84 }
85 
86 void Item_PreDraw(entity this)
87 {
89  {
90  setpredraw(this, func_null); // no need to keep running this
91  return;
92  }
93  float alph;
94  vector org = getpropertyvec(VF_ORIGIN);
95  //if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones
96  //alph = 0; // this shouldn't be needed, since items behind walls are culled anyway
97  if(this.fade_start)
98  {
99  if(vdist(org - this.origin, >, this.fade_end))
100  alph = 0; // save on some processing
101  else if(vdist(org - this.origin, <, this.fade_start))
102  alph = 1; // more processing saved
103  else
104  alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
105  }
106  else
107  alph = 1;
108  //printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
109  if(!hud && (this.ItemStatus & ITS_AVAILABLE))
110  this.alpha = alph;
111  if(alph <= 0)
112  this.drawmask = 0;
113  //else
114  //this.drawmask = MASK_NORMAL; // reset by the setalpha function
115 }
116 
117 void ItemRemove(entity this)
118 {
119  strfree(this.mdl);
120 }
121 
124 {
126 }
128 {
130 }
131 
132 NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
133 {
134  int sf = ReadByte();
135 
136  if(sf & ISF_LOCATION)
137  {
138  vector org = ReadVector();
139  setorigin(this, org);
140  this.oldorigin = org;
141  }
142 
143  if(sf & ISF_ANGLES)
144  {
145  this.angles = ReadAngleVector();
146  }
147 
148  if(sf & ISF_SIZE)
149  {
150  setsize(this, '-16 -16 0', '16 16 48');
151  }
152 
153  if(sf & ISF_STATUS) // need to read/write status first so model can handle simple, fb etc.
154  {
155  this.ItemStatus = ReadByte();
156 
157  Item_SetAlpha(this);
158 
159  if(this.ItemStatus & ITS_ALLOWFB)
160  this.effects |= EF_FULLBRIGHT;
161  else
162  this.effects &= ~EF_FULLBRIGHT;
163 
164  if(this.ItemStatus & ITS_GLOW)
165  {
166  if(this.ItemStatus & ITS_AVAILABLE)
167  this.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
168  else
169  this.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT);
170  }
171  }
172 
173  if(sf & ISF_MODEL)
174  {
175  this.drawmask = MASK_NORMAL;
177  if (isnew) IL_PUSH(g_drawables, this);
178  this.draw = ItemDraw;
179  this.solid = SOLID_TRIGGER;
180  //this.flags |= FL_ITEM;
181 
182  this.fade_end = ReadShort();
183  this.fade_start = ReadShort();
185  setpredraw(this, Item_PreDraw);
186 
187  strfree(this.mdl);
188 
189  string _fn = ReadString();
190  this.item_simple = false; // reset it!
191 
192  if(autocvar_cl_simple_items && (this.ItemStatus & ITS_ALLOWSI))
193  {
194  string _fn2 = substring(_fn, 0 , strlen(_fn) -4);
195  this.item_simple = true;
196 
197  #define extensions(x) \
198  x(md3) \
199  x(dpm) \
200  x(iqm) \
201  x(mdl) \
202 
203  #define tryext(ext) { \
204  string s = strcat(_fn2, autocvar_cl_simpleitems_postfix, "." #ext); \
205  string cached = HM_gets(ENT_CLIENT_ITEM_simple, s); \
206  if (cached == "") { \
207  HM_sets(ENT_CLIENT_ITEM_simple, s, cached = fexists(s) ? "1" : "0"); \
208  } \
209  if (cached != "0") { \
210  strcpy(this.mdl, s); \
211  break; \
212  } \
213  }
214  do {
216  this.item_simple = false;
217  LOG_TRACEF("Simple item requested for %s but no model exists for it", _fn);
218  } while (0);
219  #undef tryext
220  #undef extensions
221  }
222 
223  if(!this.item_simple)
224  strcpy(this.mdl, _fn);
225 
226  if(this.mdl == "")
227  LOG_WARNF("this.mdl is unset for item %s", this.classname);
228 
229  precache_model(this.mdl);
230  _setmodel(this, this.mdl);
231 
232  this.skin = ReadByte();
233 
234  setsize(this, '-16 -16 0', '16 16 48');
235  }
236 
237  if(sf & ISF_COLORMAP)
238  {
239  this.colormap = ReadShort();
240  this.item_glowmod_x = ReadByte() / 255.0;
241  this.item_glowmod_y = ReadByte() / 255.0;
242  this.item_glowmod_z = ReadByte() / 255.0;
243  }
244 
245  if(sf & ISF_DROP)
246  {
247  this.gravity = 1;
248  this.pushable = true;
249  //this.angles = '0 0 0';
251  this.velocity = ReadVector();
252  setorigin(this, this.oldorigin);
253 
254  if(!this.move_time)
255  {
256  this.move_time = time;
257  this.spawntime = time;
258  }
259  else
260  this.move_time = max(this.move_time, time);
261  }
262 
264  {
265  if(this.ItemStatus & ITS_ANIMATE1)
266  this.avelocity = '0 180 0';
267 
268  if(this.ItemStatus & ITS_ANIMATE2)
269  this.avelocity = '0 -90 0';
270  }
271 
272  this.entremove = ItemRemove;
273 
274  return true;
275 }
float autocvar_cl_ghost_items
Definition: items.qh:9
#define HM_NEW(this)
Definition: map.qh:29
vector autocvar_cl_ghost_items_color
Definition: items.qh:10
float autocvar_cl_animate_items
Definition: items.qh:8
float colormap
Definition: csprogsdefs.qc:131
float alpha
Definition: items.qc:14
skin
Definition: ent_cs.qc:143
vector colormod
Definition: powerups.qc:21
SHUTDOWN(ENT_CLIENT_ITEM_simple)
Definition: items.qc:127
#define ReadString
bool pushable
Definition: items.qc:15
float MOVETYPE_TOSS
Definition: progsdefs.qc:252
float autocvar_cl_simple_items
Definition: items.qh:13
vector oldorigin
Definition: csprogsdefs.qc:102
void Item_PreDraw(entity this)
Definition: items.qc:86
entity() spawn
float fade_start
Definition: models.qh:23
#define IS_ONGROUND(s)
Definition: movetypes.qh:16
vector maxs
Definition: csprogsdefs.qc:113
#define setpredraw(e, f)
Definition: self.qh:84
origin
Definition: ent_cs.qc:114
string classname
Definition: csprogsdefs.qc:107
void Item_SetAlpha(entity this)
Definition: items.qc:16
vector avelocity
Definition: csprogsdefs.qc:105
float warpzone_warpzones_exist
Definition: common.qh:9
float effects
Definition: csprogsdefs.qc:111
vector item_glowmod
Definition: items.qc:12
const float EF_ADDITIVE
Definition: csprogsdefs.qc:300
#define tryext(ext)
#define strcpy(this, s)
Definition: string.qh:49
#define LOG_WARNF(...)
Definition: log.qh:67
const float EF_FULLBRIGHT
Definition: csprogsdefs.qc:303
vector mins
Definition: csprogsdefs.qc:113
bool autocvar_cl_ghost_items_vehicle
Definition: items.qc:11
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define extensions(x)
void Movetype_Physics_MatchServer(entity this, bool sloppy)
Definition: movetypes.qc:851
void ItemRemove(entity this)
Definition: items.qc:117
vector autocvar_cl_weapon_stay_color
Definition: items.qh:11
float frametime
Definition: csprogsdefs.qc:17
#define LOG_TRACEF(...)
Definition: log.qh:82
const float MASK_NORMAL
Definition: csprogsdefs.qc:164
float drawmask
Definition: csprogsdefs.qc:95
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float gravity
Definition: items.qh:16
float onground_time
Definition: items.qh:5
float move_time
Definition: movetypes.qh:77
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
void ItemDraw(entity this)
Definition: items.qc:41
float autocvar_cl_weapon_stay_alpha
Definition: items.qh:12
const float SOLID_TRIGGER
Definition: csprogsdefs.qc:245
bool item_simple
Definition: items.qc:13
setorigin(ent, v)
HashMap ENT_CLIENT_ITEM_simple
Definition: items.qc:122
#define strfree(this)
Definition: string.qh:56
vector angles
Definition: csprogsdefs.qc:104
vector glowmod
float spawntime
Definition: items.qh:15
#define HM_DELETE(this)
Definition: map.qh:88
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
STATIC_INIT(ENT_CLIENT_ITEM_simple)
Definition: items.qc:123
float fade_end
Definition: models.qh:23
bool autocvar_cl_items_nofade
Definition: items.qh:7
int HashMap
Definition: map.qh:22
IntrusiveList g_drawables
Definition: main.qh:77
void set_movetype(entity this, int mt)
var void func_null()
const float VF_ORIGIN
Definition: csprogsdefs.qc:182
float solid
Definition: csprogsdefs.qc:99
int hud
Definition: main.qh:142
NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
Definition: items.qc:132