Xonotic
casings.qc
Go to the documentation of this file.
1 #include "casings.qh"
2 
3 #include <common/replicate.qh>
4 #include <common/util.qh>
5 
6 #ifdef CSQC
8 #include "rubble.qh"
9 #endif
10 
11 REGISTER_NET_TEMP(casings)
12 
13 REPLICATE(cvar_cl_casings, bool, "cl_casings");
14 REPLICATE(cvar_r_drawviewmodel, int, "r_drawviewmodel");
15 
16 #ifdef SVQC
17 void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner, .entity weaponentity)
18 {
19  vector org = casingowner.(weaponentity).spawnorigin;
20  org = casingowner.origin + casingowner.view_ofs + org.x * v_forward - org.y * v_right + org.z * v_up;
21 
22  FOREACH_CLIENT(true, {
23  if (!(CS_CVAR(it).cvar_cl_casings))
24  continue;
25  if (it == casingowner && !(CS_CVAR(it).cvar_r_drawviewmodel))
26  continue;
27 
28  msg_entity = it;
29  if (!sound_allowed(MSG_ONE, it))
30  casingtype |= 0x80; // silent
31 
32  WriteHeader(MSG_ONE, casings);
33  WriteByte(MSG_ONE, casingtype);
34  WriteVector(MSG_ONE, org);
35  WriteShort(MSG_ONE, compressShortVector(vel)); // actually compressed velocity
36  WriteByte(MSG_ONE, ang.x * 256 / 360);
37  WriteByte(MSG_ONE, ang.y * 256 / 360);
38  WriteByte(MSG_ONE, ang.z * 256 / 360);
39  });
40 }
41 #endif
42 
43 #ifdef CSQC
44 entityclass(Casing);
45 classfield(Casing) .float alpha;
46 classfield(Casing) .bool silent;
47 classfield(Casing) .int state;
48 classfield(Casing) .float cnt;
49 
50 void Casing_Delete(entity this)
51 {
52  delete(this);
53 }
54 
55 void Casing_Draw(entity this)
56 {
57  if (IS_ONGROUND(this))
58  {
59  this.angles_x = 0;
60  this.angles_z = 0;
61  //UNSET_ONGROUND(this);
62  }
63 
64  this.renderflags = 0;
65  this.alpha = bound(0, this.cnt - time, 1);
66 
67  if (this.alpha < ALPHA_MIN_VISIBLE)
68  {
69  Casing_Delete(this);
70  this.drawmask = 0;
71  return;
72  }
73 
74  Movetype_Physics_MatchTicrate(this, autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
75  //if (wasfreed(this))
76  // return; // deleted by touch function
77 }
78 
79 SOUND(BRASS1, W_Sound("brass1"));
80 SOUND(BRASS2, W_Sound("brass2"));
81 SOUND(BRASS3, W_Sound("brass3"));
82 Sound SND_BRASS_RANDOM() {
83  return REGISTRY_GET(Sounds, SND_BRASS1.m_id + floor(prandom() * 3));
84 }
85 SOUND(CASINGS1, W_Sound("casings1"));
86 SOUND(CASINGS2, W_Sound("casings2"));
87 SOUND(CASINGS3, W_Sound("casings3"));
88 Sound SND_CASINGS_RANDOM() {
89  return REGISTRY_GET(Sounds, SND_CASINGS1.m_id + floor(prandom() * 3));
90 }
91 
92 void Casing_Touch(entity this, entity toucher)
93 {
95  {
96  Casing_Delete(this);
97  return;
98  }
99 
100  if (!this.silent)
101  if (!trace_ent || trace_ent.solid == SOLID_BSP)
102  {
103  if(vdist(this.velocity, >, 50))
104  {
105  if (time >= this.nextthink)
106  {
107  Sound s;
108  switch (this.state)
109  {
110  case 1:
111  s = SND_CASINGS_RANDOM();
112  break;
113  default:
114  s = SND_BRASS_RANDOM();
115  break;
116  }
117 
118  sound (this, CH_SHOTS, s, VOL_BASE, ATTEN_LARGE);
119  }
120  }
121  }
122 
123  this.nextthink = time + 0.2;
124 }
125 
126 void Casing_Damage(entity this, float thisdmg, int hittype, vector org, vector thisforce)
127 {
128  if (thisforce.z < 0)
129  thisforce.z = 0;
130  this.velocity = this.velocity + thisforce + '0 0 100';
131  UNSET_ONGROUND(this);
132 }
133 
134 NET_HANDLE(casings, bool isNew)
135 {
136  int _state = ReadByte();
137  vector org = ReadVector();
138  vector vel = decompressShortVector(ReadShort());
139  vector ang;
140  ang_x = ReadByte() * 360 / 256;
141  ang_y = ReadByte() * 360 / 256;
142  ang_z = ReadByte() * 360 / 256;
143  return = true;
144 
145  Casing casing = ListNewChildRubble(CasingsNGibs, new(casing));
146  casing.silent = (_state & 0x80);
147  casing.state = (_state & 0x7F);
148  casing.origin = org;
149  setorigin(casing, casing.origin);
150  casing.velocity = vel;
151  casing.angles = ang;
152  casing.drawmask = MASK_NORMAL;
153 
154  casing.draw = Casing_Draw;
155  if (isNew) IL_PUSH(g_drawables, casing);
156  casing.velocity = casing.velocity + 2 * prandomvec();
157  casing.avelocity = '0 250 0' + 100 * prandomvec();
158  set_movetype(casing, MOVETYPE_BOUNCE);
159  casing.bouncefactor = 0.25;
160  settouch(casing, Casing_Touch);
161  casing.move_time = time;
162  casing.event_damage = Casing_Damage;
163  casing.solid = SOLID_TRIGGER;
164 
165  switch (casing.state)
166  {
167  case 1:
168  setmodel(casing, MDL_CASING_SHELL);
169  casing.cnt = time + autocvar_cl_casings_shell_time;
170  break;
171  default:
172  setmodel(casing, MDL_CASING_BULLET);
173  casing.cnt = time + autocvar_cl_casings_bronze_time;
174  break;
175  }
176 
177  setsize(casing, '0 0 -1', '0 0 -1');
178 
179  LimitedChildrenRubble(CasingsNGibs, "casing", autocvar_cl_casings_maxcount, Casing_Delete, NULL);
180 }
181 
182 #endif
float state
Definition: subs.qh:32
const float ALPHA_MIN_VISIBLE
Definition: main.qh:128
float alpha
Definition: items.qc:14
float compressShortVector(vector vec)
Definition: util.qc:406
const float ATTEN_LARGE
Definition: sound.qh:31
float trace_dphitq3surfaceflags
entity() spawn
#define REGISTRY_GET(id, i)
Definition: registry.qh:43
float prandom()
Definition: random.qc:100
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
#define IS_ONGROUND(s)
Definition: movetypes.qh:16
REPLICATE(cvar_cl_casings, bool, "cl_casings")
#define CS_CVAR(this)
Definition: state.qh:51
#define classfield(name)
Definition: oo.qh:52
#define NET_HANDLE(id, param)
Definition: net.qh:12
string W_Sound(string w_snd)
Definition: all.qc:281
float MOVETYPE_BOUNCE
Definition: progsdefs.qc:256
#define UNSET_ONGROUND(s)
Definition: movetypes.qh:18
float renderflags
Definition: main.qh:95
entity trace_ent
Definition: csprogsdefs.qc:40
#define setmodel(this, m)
Definition: model.qh:26
entity msg_entity
Definition: progsdefs.qc:63
float cnt
Definition: powerups.qc:24
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)
Definition: movetypes.qc:869
vector v_up
Definition: csprogsdefs.qc:31
#define NULL
Definition: post.qh:17
const float VOL_BASE
Definition: sound.qh:36
Definition: sound.qh:119
float Q3SURFACEFLAG_NOIMPACT
const float MASK_NORMAL
Definition: csprogsdefs.qc:164
float drawmask
Definition: csprogsdefs.qc:95
float nextthink
Definition: csprogsdefs.qc:121
const int CH_SHOTS
Definition: sound.qh:14
vector decompressShortVector(int data)
Definition: util.qc:372
vector(float skel, float bonenum) _skel_get_boneabs_hidden
const float SOLID_BSP
Definition: csprogsdefs.qc:248
vector prandomvec()
Definition: random.qc:113
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
const float SOLID_TRIGGER
Definition: csprogsdefs.qc:245
vector v_right
Definition: csprogsdefs.qc:31
setorigin(ent, v)
#define REGISTER_NET_TEMP(id)
Definition: net.qh:33
#define sound(e, c, s, v, a)
Definition: sound.qh:52
#define SOUND(name, path)
Definition: all.qh:30
#define entityclass(...)
Definition: oo.qh:47
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
IntrusiveList g_drawables
Definition: main.qh:77
void set_movetype(entity this, int mt)
vector v_forward
Definition: csprogsdefs.qc:31