Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
casings.qc File Reference
#include "casings.qh"
#include <common/replicate.qh>
#include <common/util.qh>
#include <common/physics/movetypes/movetypes.qh>
#include "rubble.qh"
Include dependency graph for casings.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void Casing_Damage (entity this, float thisdmg, int hittype, vector org, vector thisforce)
void Casing_Delete (entity this)
void Casing_Draw (entity this)
void Casing_Touch (entity this, entity toucher)
 classfield (Casing) .float alpha
 entityclass (Casing)
 NET_HANDLE (casings, bool isNew)
 REPLICATE (cvar_cl_casings, bool, "cl_casings")
 REPLICATE (cvar_r_drawviewmodel, int, "r_drawviewmodel")
Sound SND_BRASS_RANDOM ()
Sound SND_CASINGS_RANDOM ()
 SOUND (BRASS1, W_Sound("brass1"))
 SOUND (BRASS2, W_Sound("brass2"))
 SOUND (BRASS3, W_Sound("brass3"))
 SOUND (CASINGS1, W_Sound("casings1"))
 SOUND (CASINGS2, W_Sound("casings2"))
 SOUND (CASINGS3, W_Sound("casings3"))
void SpawnCasing (vector vel, vector ang, int casingtype, entity casingowner,.entity weaponentity)

Function Documentation

◆ Casing_Damage()

void Casing_Damage ( entity this,
float thisdmg,
int hittype,
vector org,
vector thisforce )

Definition at line 147 of file casings.qc.

148{
149 if (thisforce.z < 0)
150 thisforce.z = 0;
151 this.velocity = this.velocity + thisforce + '0 0 100';
152 UNSET_ONGROUND(this);
153}
vector velocity
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18

References entity(), org, UNSET_ONGROUND, vector, and velocity.

Referenced by NET_HANDLE().

◆ Casing_Delete()

void Casing_Delete ( entity this)

Definition at line 61 of file casings.qc.

62{
63 delete(this);
64}

References entity().

Referenced by NET_HANDLE().

◆ Casing_Draw()

void Casing_Draw ( entity this)

Definition at line 66 of file casings.qc.

67{
68 if (IS_ONGROUND(this))
69 {
70 this.angles_x = 0;
71 this.angles_z = 0;
72 //UNSET_ONGROUND(this);
73 }
74
75 this.renderflags = 0;
76 this.alpha = bound(0, this.cnt - time, 1);
77
78 if (this.alpha < ALPHA_MIN_VISIBLE)
79 {
80 delete(this);
81 this.drawmask = 0;
82 return;
83 }
84
85 trace_startsolid = 0; // due to cl_casings_ticrate, traces are not always performed
87 //if (wasfreed(this))
88 // return; // deleted by touch function
89
90 // prevent glitchy casings when the gun model is poking into a wall
91 // doing this here is cheaper than doing it on the server as the client performs the trace anyway
93 {
94 delete(this);
95 this.drawmask = 0;
96 return;
97 }
98}
bool autocvar_cl_casings_sloppy
Definition casings.qh:7
float autocvar_cl_casings_ticrate
Definition casings.qh:8
float cnt
Definition powerups.qc:24
float alpha
Definition items.qc:13
float renderflags
Definition main.qh:111
const float ALPHA_MIN_VISIBLE
Definition main.qh:158
float drawmask
float time
float trace_startsolid
float bound(float min, float value, float max)
void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)
Definition movetypes.qc:835
#define IS_ONGROUND(s)
Definition movetypes.qh:16

References alpha, ALPHA_MIN_VISIBLE, autocvar_cl_casings_sloppy, autocvar_cl_casings_ticrate, bound(), cnt, drawmask, entity(), IS_ONGROUND, Movetype_Physics_MatchTicrate(), renderflags, time, and trace_startsolid.

Referenced by NET_HANDLE().

◆ Casing_Touch()

void Casing_Touch ( entity this,
entity toucher )

Definition at line 113 of file casings.qc.

114{
116 {
117 delete(this);
118 return;
119 }
120
121 if (!this.silent)
122 if (!trace_ent || trace_ent.solid == SOLID_BSP)
123 {
124 if(vdist(this.velocity, >, 50))
125 {
126 if (time >= this.nextthink)
127 {
128 Sound s;
129 switch (this.state)
130 {
131 case 1:
132 s = SND_CASINGS_RANDOM();
133 break;
134 default:
135 s = SND_BRASS_RANDOM();
136 break;
137 }
138
139 sound (this, CH_SHOTS, s, VOL_BASE, ATTEN_LARGE);
140 }
141 }
142 }
143
144 this.nextthink = time + 0.2;
145}
Sound SND_CASINGS_RANDOM()
Definition casings.qc:109
Sound SND_BRASS_RANDOM()
Definition casings.qc:103
entity trace_ent
float nextthink
float trace_dphitq3surfaceflags
float Q3SURFACEFLAG_NOIMPACT
const float SOLID_BSP
int state
bool silent
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
#define sound(e, c, s, v, a)
Definition sound.qh:52
const float ATTEN_LARGE
Definition sound.qh:31
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8

References ATTEN_LARGE, CH_SHOTS, entity(), nextthink, Q3SURFACEFLAG_NOIMPACT, silent, SND_BRASS_RANDOM(), SND_CASINGS_RANDOM(), SOLID_BSP, sound, state, time, toucher, trace_dphitq3surfaceflags, trace_ent, vdist, velocity, and VOL_BASE.

Referenced by NET_HANDLE().

◆ classfield()

classfield ( Casing )

References alpha, cnt, silent, and state.

◆ entityclass()

entityclass ( Casing )

◆ NET_HANDLE()

NET_HANDLE ( casings ,
bool isNew )

Definition at line 155 of file casings.qc.

156{
157 Casing casing = ListNewChildRubble(CasingsNGibs, new(casing));
158
159 casing.state = ReadByte();
160 casing.origin = ReadVector();
161 casing.velocity = decompressShortVector(ReadShort());
162 casing.angles_x = ReadByte() * 360 / 256;
163 casing.angles_y = ReadByte() * 360 / 256;
164
165 return = true;
166
167 casing.silent = casing.state & 0x80;
168 if ((casing.state & 0x40) && !autocvar_chase_active)
169 casing.origin += autocvar_cl_gunoffset.x * v_forward
172 casing.state &= 0x3F; // the 2 most significant bits are reserved for the silent and casingowner bitflags
173
174 setorigin(casing, casing.origin);
175 casing.drawmask = MASK_NORMAL;
176 casing.draw = Casing_Draw;
177 if (isNew) IL_PUSH(g_drawables, casing);
178 casing.velocity += 2 * prandomvec();
179 casing.avelocity = '0 10 0' + 100 * prandomvec();
181 settouch(casing, Casing_Touch);
182 casing.move_time = time;
183 casing.event_damage = Casing_Damage;
184 casing.solid = SOLID_TRIGGER;
185
186 switch (casing.state)
187 {
188 case 1:
189 setmodel(casing, MDL_CASING_SHELL);
190 casing.bouncefactor = 0.25;
192 break;
193 default:
194 setmodel(casing, MDL_CASING_BULLET);
195 casing.bouncefactor = 0.5;
197 break;
198 }
199
201}
void Casing_Draw(entity this)
Definition casings.qc:66
void Casing_Touch(entity this, entity toucher)
Definition casings.qc:113
void Casing_Delete(entity this)
Definition casings.qc:61
void Casing_Damage(entity this, float thisdmg, int hittype, vector org, vector thisforce)
Definition casings.qc:147
int autocvar_cl_casings_maxcount
Definition casings.qh:5
float autocvar_cl_casings_shell_time
Definition casings.qh:6
float autocvar_cl_casings_bronze_time
Definition casings.qh:4
IntrusiveList g_drawables
Definition main.qh:91
#define setmodel(this, m)
Definition model.qh:26
vector decompressShortVector(int data)
Definition util.qc:486
vector v_up
const float SOLID_TRIGGER
const float MASK_NORMAL
vector v_right
vector v_forward
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define ReadVector()
Definition net.qh:367
int ReadByte()
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_BOUNCE
Definition movetypes.qh:139
#define NULL
Definition post.qh:14
vector prandomvec()
Definition random.qc:121
void LimitedChildrenRubble(IntrusiveList list, string cname, int limit, void(entity) deleteproc, entity parent)
Definition rubble.qc:5
entity ListNewChildRubble(IntrusiveList list, entity child)
Definition rubble.qc:46
IntrusiveList CasingsNGibs
Definition rubble.qh:8
#define settouch(e, f)
Definition self.qh:73
int autocvar_chase_active
Definition view.qh:17
vector autocvar_cl_gunoffset
Definition view.qh:98

References autocvar_chase_active, autocvar_cl_casings_bronze_time, autocvar_cl_casings_maxcount, autocvar_cl_casings_shell_time, autocvar_cl_gunoffset, Casing_Damage(), Casing_Delete(), Casing_Draw(), Casing_Touch(), CasingsNGibs, decompressShortVector(), g_drawables, IL_PUSH(), LimitedChildrenRubble(), ListNewChildRubble(), MASK_NORMAL, MOVETYPE_BOUNCE, NULL, prandomvec(), ReadByte(), ReadVector, set_movetype(), setmodel, settouch, SOLID_TRIGGER, time, v_forward, v_right, and v_up.

◆ REPLICATE() [1/2]

REPLICATE ( cvar_cl_casings ,
bool ,
"cl_casings"  )

References REPLICATE.

◆ REPLICATE() [2/2]

REPLICATE ( cvar_r_drawviewmodel ,
int ,
"r_drawviewmodel"  )

References REPLICATE.

◆ SND_BRASS_RANDOM()

Sound SND_BRASS_RANDOM ( )

Definition at line 103 of file casings.qc.

103 {
104 return REGISTRY_GET(Sounds, SND_BRASS1.m_id + floor(prandom() * 3));
105}
float floor(float f)
float prandom()
Predictable random number generator (not seeded yet)
Definition random.qc:108
#define REGISTRY_GET(id, i)
Definition registry.qh:43

References floor(), prandom(), and REGISTRY_GET.

Referenced by Casing_Touch().

◆ SND_CASINGS_RANDOM()

Sound SND_CASINGS_RANDOM ( )

Definition at line 109 of file casings.qc.

109 {
110 return REGISTRY_GET(Sounds, SND_CASINGS1.m_id + floor(prandom() * 3));
111}

References floor(), prandom(), and REGISTRY_GET.

Referenced by Casing_Touch().

◆ SOUND() [1/6]

SOUND ( BRASS1 ,
W_Sound("brass1")  )

◆ SOUND() [2/6]

SOUND ( BRASS2 ,
W_Sound("brass2")  )

◆ SOUND() [3/6]

SOUND ( BRASS3 ,
W_Sound("brass3")  )

◆ SOUND() [4/6]

SOUND ( CASINGS1 ,
W_Sound("casings1")  )

◆ SOUND() [5/6]

SOUND ( CASINGS2 ,
W_Sound("casings2")  )

◆ SOUND() [6/6]

SOUND ( CASINGS3 ,
W_Sound("casings3")  )

◆ SpawnCasing()

void SpawnCasing ( vector vel,
vector ang,
int casingtype,
entity casingowner,
.entity weaponentity )

Definition at line 17 of file casings.qc.

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
26 casingtype &= 0x3F; // reset any bitflags that were set for the previous client
27
28 if (it == casingowner || (IS_SPEC(it) && it.enemy == casingowner))
29 {
30 if (!(CS_CVAR(it).cvar_r_drawviewmodel))
31 continue;
32
33 casingtype |= 0x40; // client will apply autocvar_cl_gunoffset in first person
34 }
35 else if (1 & ~checkpvs(it.origin + it.view_ofs, casingowner)) // 1 or 3 means visible
36 continue;
37
38 msg_entity = it; // sound_allowed checks this
39 if (!sound_allowed(MSG_ONE, it))
40 casingtype |= 0x80; // silent
41
42 WriteHeader(MSG_ONE, casings);
43 WriteByte(MSG_ONE, casingtype);
44 WriteVector(MSG_ONE, org);
45 WriteShort(MSG_ONE, compressShortVector(vel)); // actually compressed velocity
46 WriteByte(MSG_ONE, ang.x * 256 / 360);
47 WriteByte(MSG_ONE, ang.y * 256 / 360);
48 // weapons only have pitch and yaw, so no need to send ang.z
49 });
50}
float compressShortVector(vector vec)
Definition util.qc:521
float checkpvs(vector viewpos, entity viewee)
#define WriteHeader(to, id)
Definition net.qh:221
float MSG_ONE
Definition menudefs.qc:56
void WriteShort(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
entity msg_entity
Definition progsdefs.qc:63
vector
Definition self.qh:92
vector org
Definition self.qh:92
vector vector ang
Definition self.qh:92
bool sound_allowed(int to, entity e)
Definition all.qc:9
#define CS_CVAR(this)
Definition state.qh:51
#define IS_SPEC(v)
Definition utils.qh:10
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:50
vector spawnorigin
Definition all.qh:391

References ang, checkpvs(), compressShortVector(), CS_CVAR, entity(), FOREACH_CLIENT, IS_SPEC, msg_entity, MSG_ONE, org, sound_allowed(), spawnorigin, v_forward, v_right, v_up, vector, WriteByte(), WriteHeader, and WriteShort().

Referenced by W_MachineGun_Attack(), W_MachineGun_Attack_Auto(), W_MachineGun_Attack_Burst(), W_OverkillHeavyMachineGun_Attack_Auto(), W_OverkillMachineGun_Attack_Auto(), W_Rifle_FireBullet(), and W_Shotgun_Attack().