Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
all.qc
Go to the documentation of this file.
1#include "all.qh"
2
3REGISTER_NET_TEMP(net_effect)
4const int SF_EFF_VELOCITY = BIT(0);
5const int SF_EFF_COLOR_MIN = BIT(1);
6const int SF_EFF_COLOR_MAX = BIT(2);
7const int SF_EFF_ALPHA_MIN = BIT(3);
8const int SF_EFF_ALPHA_MAX = BIT(4);
9const int SF_EFF_FADE = BIT(5);
10
11#ifdef CSQC
12NET_HANDLE(net_effect, bool isNew)
13{
14 int sf = ReadByte();
15 entity eff = ReadRegistered(Effects);
16
17 vector vel, org = ReadVector();
18
19 if (sf & SF_EFF_VELOCITY)
20 vel = ReadVector();
21 else
22 vel = '0 0 0';
23
24 int eff_flags = 0;
25 if (sf & SF_EFF_COLOR_MIN)
26 {
30 eff_flags |= PARTICLES_USECOLOR;
31 if (!(sf & SF_EFF_COLOR_MAX))
33 }
34 if (sf & SF_EFF_COLOR_MAX)
35 {
39 eff_flags |= PARTICLES_USECOLOR;
40 if (!(sf & SF_EFF_COLOR_MIN))
42 }
43
44 if (sf & SF_EFF_ALPHA_MIN)
45 {
47 eff_flags |= PARTICLES_USEALPHA;
48 if (!(sf & SF_EFF_ALPHA_MAX))
50 }
51 if (sf & SF_EFF_ALPHA_MAX)
52 {
54 eff_flags |= PARTICLES_USEALPHA;
55 if (!(sf & SF_EFF_ALPHA_MIN))
57 }
58 if (sf & SF_EFF_FADE)
59 {
61 eff_flags |= PARTICLES_USEFADE;
62 }
63
64 int eff_cnt = ReadByte();
65 if (eff.eent_eff_trail)
67 else
68 boxparticles(particleeffectnum(eff), NULL, org, org, vel, vel, eff_cnt, eff_flags);
69 return true;
70}
71#endif // CSQC
72
73#ifdef SVQC
74void Send_Effect_Core(entity eff, vector eff_loc, vector eff_vel, int eff_cnt, vector eff_col_min, vector eff_col_max, float eff_alpha_min, float eff_alpha_max, float eff_alpha_fade, entity ignore)
75{
76 if (!eff
77 || (!eff.eent_eff_trail && !eff_cnt)) // effect has no count
78 return;
79
80 int sf = 0;
81 if (eff_vel != '0 0 0')
82 sf |= SF_EFF_VELOCITY;
83
84 // if only one of min or max is set, that color is used for both
85 if (eff_col_min != '0 0 0')
86 {
87 sf |= SF_EFF_COLOR_MIN;
88 eff_col_min.x = rint(bound(0, 16 * eff_col_min.x, BITS(8)));
89 eff_col_min.y = rint(bound(0, 16 * eff_col_min.y, BITS(8)));
90 eff_col_min.z = rint(bound(0, 16 * eff_col_min.z, BITS(8)));
91 }
92 if (eff_col_max != '0 0 0'
93 && eff_col_min != eff_col_max) // optimization: only send one color if the min and max match
94 {
95 sf |= SF_EFF_COLOR_MAX;
96 eff_col_max.x = rint(bound(0, 16 * eff_col_max.x, BITS(8)));
97 eff_col_max.y = rint(bound(0, 16 * eff_col_max.y, BITS(8)));
98 eff_col_max.z = rint(bound(0, 16 * eff_col_max.z, BITS(8)));
99 }
100
101 if (eff_alpha_min >= 0)
102 {
103 sf |= SF_EFF_ALPHA_MIN;
104 eff_alpha_min = rint(bound(0, eff_alpha_min, 1) * BITS(8));
105 }
106 if (eff_alpha_max >= 0
107 && eff_alpha_min != eff_alpha_max) // optimization: only send one alpha if the min and max match
108 {
109 sf |= SF_EFF_ALPHA_MAX;
110 eff_alpha_max = rint(bound(0, eff_alpha_max, 1) * BITS(8));
111 }
112 if (eff_alpha_fade >= 0)
113 {
114 sf |= SF_EFF_FADE;
115 eff_alpha_fade = rint(bound(0, eff_alpha_fade, 1) * BITS(8));
116 }
117
118 // now network to every client
119 FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != ignore && !(IS_SPEC(it) && it.enemy && it.enemy == ignore),
120 {
121 msg_entity = it;
122 WriteHeader(MSG_ONE, net_effect);
123 WriteByte(MSG_ONE, sf);
124 WriteRegistered(Effects, MSG_ONE, eff);
125 WriteVector(MSG_ONE, eff_loc);
126
127 // attempt to save a tiny bit more bandwidth by not sending velocity if it isn't set
128 if (sf & SF_EFF_VELOCITY)
129 WriteVector(MSG_ONE, eff_vel);
130
131 if (sf & SF_EFF_COLOR_MIN)
132 {
133 WriteByte(MSG_ONE, eff_col_min.x);
134 WriteByte(MSG_ONE, eff_col_min.y);
135 WriteByte(MSG_ONE, eff_col_min.z);
136 }
137 if (sf & SF_EFF_COLOR_MAX)
138 {
139 WriteByte(MSG_ONE, eff_col_max.x);
140 WriteByte(MSG_ONE, eff_col_max.y);
141 WriteByte(MSG_ONE, eff_col_max.z);
142 }
143
144 if (sf & SF_EFF_ALPHA_MIN)
145 WriteByte(MSG_ONE, eff_alpha_min);
146 if (sf & SF_EFF_ALPHA_MAX)
147 WriteByte(MSG_ONE, eff_alpha_max);
148 if (sf & SF_EFF_FADE)
149 WriteByte(MSG_ONE, eff_alpha_fade);
150
151 WriteByte(MSG_ONE, eff_cnt);
152 });
153}
154
155void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
156{
157 Send_Effect_Core(eff, eff_loc, eff_vel, eff_cnt, '0 0 0', '0 0 0', -1, -1, -1, NULL);
158}
159
160void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt)
161{
162 // problem with this is, we might not have all the available effects for it
163 FOREACH(Effects, it.eent_eff_name == eff_name,
164 {
165 Send_Effect(it, eff_loc, eff_vel, eff_cnt);
166 return;
167 });
168 // revert to engine handling TODO: send the effect name and draw it on the client side? not as light on networking, but resolves the use of server side effects
169 __pointparticles(_particleeffectnum(eff_name), eff_loc, eff_vel, eff_cnt);
170}
171#endif
172
173#if ENABLE_EFFECTINFO
174 #include "effectinfo.qc"
175#endif
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
#define BITS(n)
Definition bits.qh:9
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
vector particles_colormin
float particles_alphamax
vector particles_colormax
float PARTICLES_USEALPHA
float particles_alphamin
float PARTICLES_USECOLOR
float particles_fade
float PARTICLES_USEFADE
#define particleeffectnum(e)
Definition effect.qh:3
void Send_Effect_Core(entity eff, vector eff_loc, vector eff_vel, int eff_cnt, vector eff_col_min, vector eff_col_max, float eff_alpha_min, float eff_alpha_max, float eff_alpha_fade, entity ignore)
Definition all.qc:74
void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:160
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:155
const int SF_EFF_FADE
Definition all.qc:9
const int SF_EFF_ALPHA_MIN
Definition all.qc:7
const int SF_EFF_COLOR_MIN
Definition all.qc:5
const int SF_EFF_VELOCITY
Definition all.qc:4
const int SF_EFF_COLOR_MAX
Definition all.qc:6
const int SF_EFF_ALPHA_MAX
Definition all.qc:8
WriteByte(chan, ent.angles.y/DEC_FACTOR)
#define FOREACH(list, cond, body)
Definition iter.qh:19
#define NET_HANDLE(id, param)
Definition net.qh:15
#define ReadVector()
Definition net.qh:349
#define ReadRegistered(r)
Definition net.qh:290
int ReadByte()
#define REGISTER_NET_TEMP(id)
Definition net.qh:31
void WarpZone_TrailParticles_WithMultiplier(entity own, float eff, vector org, vector end, float f, int boxflags)
Definition common.qc:466
float MSG_ONE
Definition menudefs.qc:56
float bound(float min, float value, float max)
float rint(float f)
#define NULL
Definition post.qh:14
vector
Definition self.qh:96
vector org
Definition self.qh:96
if(frag_attacker.flagcarried)
Definition sv_ctf.qc:2319
#define IS_SPEC(v)
Definition utils.qh:10
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52