Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
net.qc
Go to the documentation of this file.
1#include "net.qh"
2
3#ifdef GAMEQC
4
5#include "nades.qh"
6
7#ifdef CSQC
8#include <client/view.qh>
9
10void orb_draw(entity this)
11{
12 float age = time - (this.ltime - this.lifetime);
13 float dt = time - this.update_time;
14 this.update_time = time;
15
16 if (dt > 0)
17 {
18 this.avelocity *= 24 ** (dt / this.lifetime); // speed up, frametime independent
19 this.angles += dt * this.avelocity;
20 }
21 if (age > 0)
22 {
23 this.scale = this.radius * (age >= this.animstate_endtime
24 ? 1
25 : (this.height * age * (age - this.animstate_endtime * 2))); // increases at decreasing pace up to .radius, as age -> .animstate_endtime
26 this.alpha = sqrt(1 - age / this.lifetime); // slowly fade out
27 }
28}
29
31{
32 static float orb_drawtime; // last drawn orb frame, to counter overlapping orbs
33 if (time <= orb_drawtime)
34 return;
35
36 if (boxesoverlap(view_origin - '1 1 1', view_origin + '1 1 1', this.absmin, this.absmax)) // nade orbs actually act as a cube
37 {
38 orb_drawtime = time; // prevent rendering more than one of these per frame!
39 float orb_alpha = this.alpha * 0.6;
41 }
42}
43
45{
46 orb.update_time = time; // used to calculate dt
47 orb.animstate_endtime = 0.25 * min(orb.lifetime, 1); // when the orb will stop expanding
48 orb.height = -4 * (2 * orb.animstate_endtime) ** -2; // amplitude used in scaling calculation
49
50 setmodel(orb, MDL_NADE_ORB);
51 orb.skin = 1;
52
53 float model_radius = orb.maxs.x;
54 vector size = '0.5 0.5 0.5' * orb.radius;
55 setsize(orb, -size, size);
56 orb.radius *= 0.6 / model_radius;
57
58 orb.draw = orb_draw;
59 orb.draw2d = orb_draw2d;
60 IL_PUSH(g_drawables, orb);
62 SetResourceExplicit(orb, RES_HEALTH, 255);
64 orb.solid = SOLID_NOT;
65 orb.drawmask = MASK_NORMAL;
66 orb.renderflags |= RF_ADDITIVE;
67 orb.scale = 0.01;
68 float spin_dir = 2*M_PI * random();
69 orb.avelocity = '6 0 0' * sin(spin_dir) + '0 0 6' * cos(spin_dir);
70
71 float age = time - (orb.ltime - orb.lifetime);
72 if (age > 0)
73 orb.avelocity *= 24 ** (age / orb.lifetime);
74}
75#endif // CSQC
76
77REGISTER_NET_LINKED(Nade_Orb)
78
79#ifdef CSQC
80NET_HANDLE(Nade_Orb, bool isNew)
81{
82 Net_Accept(Nade_Orb);
83
84 int sf = ReadByte();
85 this.colormod = ReadRegistered(Nades).m_color;
86 setorigin(this, ReadVector());
87 this.ltime = ReadFloat();
88 //this.ltime = time + ReadByte() / 10.0;
90 ? ReadFloat()
91 : (ReadByte() + 1) * 0.125;
93 ? ReadFloat()
94 : (ReadByte() + 1) * 5;
95
96 if (isNew)
97 orb_setup(this);
98 return true;
99}
100#elifdef SVQC
101bool orb_send(entity this, entity to, int sf)
102{
103 sf = 0;
104 float byte_lifetime = this.lifetime * 8 - 1; // range: 0.125..32 in increments of 0.125
105 if (byte_lifetime < 0 || byte_lifetime >= BIT(8) || byte_lifetime != floor(byte_lifetime))
107 float byte_radius = this.radius * 0.2 - 1; // range: 5..1280 in increments of 5
108 if (byte_radius < 0 || byte_radius >= BIT(8) || byte_radius != floor(byte_radius))
110
111 WriteHeader(MSG_ENTITY, Nade_Orb);
113 WriteRegistered(Nades, MSG_ENTITY, REGISTRY_GET(Nades, STAT(NADE_BONUS_TYPE, this)));
114 WriteVector(MSG_ENTITY, this.origin);
115 WriteFloat(MSG_ENTITY, this.ltime);
116 //WriteByte(MSG_ENTITY, (this.ltime - time) * 10.0 + 0.5); // round time delta to a 1/10th of a second
118 WriteFloat(MSG_ENTITY, this.lifetime);
119 else
120 WriteByte(MSG_ENTITY, rint(byte_lifetime));
122 WriteFloat(MSG_ENTITY, this.radius);
123 else
124 WriteByte(MSG_ENTITY, rint(byte_radius));
125
126 return true;
127}
128#endif
129
130REGISTER_NET_TEMP(Nade_Orb_Effect)
131
132#ifdef CSQC
133NET_HANDLE(Nade_Orb_Effect, bool isNew)
134{
135 entity player = CSQCModel_server2csqc(ReadByte() - 1);
136 int cnt_and_type = ReadByte();
137 if (player)
138 {
139 vector org = CENTER_OF_ENT(player);
140 vector vel = vec2(player.velocity);
141 particles_alphamin = particles_alphamax = (!player.alpha ? 1 : player.alpha); // scale by player alpha
142 boxparticles(particleeffectnum((cnt_and_type & 1) ? EFFECT_AMMO_REGEN : EFFECT_HEALING), player, org, org, vel, vel, cnt_and_type >> 1, PARTICLES_USEALPHA);
143 }
144 return true;
145}
146#elifdef SVQC
147void nade_Effect(entity player, entity eff, int eff_cnt)
148{
149 if (time < player.nade_special_time)
150 return;
151 player.nade_special_time = time + 1/16; // 0.0625; prevent spam
152
153 if (player.alpha >= 0 && eff_cnt)
154 {
155 WriteHeader(MSG_BROADCAST, Nade_Orb_Effect);
156 WriteByte(MSG_BROADCAST, etof(player));
157 WriteByte(MSG_BROADCAST, (min(eff_cnt, BITS(7)) << 1) | (eff == EFFECT_AMMO_REGEN)); // bit 0 is the effect type, remaining are the count (right-shifted by 1)
158 }
159}
160#endif
161
162#endif // GAMEQC
float animstate_endtime
Definition anim.qh:38
#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
float height
Definition bobbing.qc:3
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define drawfill(position, size, rgb, alpha, flag)
Definition draw.qh:36
float lifetime
Definition powerups.qc:23
vector colormod
Definition powerups.qc:21
float alpha
Definition items.qc:13
IntrusiveList g_drawables
Definition main.qh:91
vector view_origin
Definition main.qh:109
IntrusiveList g_drawables_2d
Definition main.qh:92
float radius
Definition impulse.qh:11
#define setmodel(this, m)
Definition model.qh:26
const int SF_NADEORB_LIFETIME_FLOAT
Definition net.qh:5
float update_time
Definition net.qh:11
float ltime
Definition net.qh:10
const int SF_NADEORB_RADIUS_FLOAT
Definition net.qh:6
#define CENTER_OF_ENT(ent)
Definition util.qh:10
const float RF_ADDITIVE
const float DRAWFLAG_ADDITIVE
vector avelocity
const float MASK_NORMAL
const float SOLID_NOT
float time
vector size
float particles_alphamax
vector absmax
vector origin
float PARTICLES_USEALPHA
float particles_alphamin
vector absmin
#define particleeffectnum(e)
Definition effect.qh:3
ent angles
Definition ent_cs.qc:146
WriteByte(chan, ent.angles.y/DEC_FACTOR)
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
entity CSQCModel_server2csqc(int i)
Definition cl_model.qc:314
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
noref float vid_conwidth
Definition draw.qh:7
noref float vid_conheight
Definition draw.qh:8
#define ReadFloat()
Definition net.qh:348
#define NET_HANDLE(id, param)
Definition net.qh:15
const int MSG_ENTITY
Definition net.qh:156
#define ReadVector()
Definition net.qh:349
#define ReadRegistered(r)
Definition net.qh:290
#define WriteHeader(to, id)
Definition net.qh:265
#define REGISTER_NET_LINKED(id)
Definition net.qh:91
int ReadByte()
#define WriteRegistered(r, to, it)
Definition net.qh:292
#define REGISTER_NET_TEMP(id)
Definition net.qh:31
#define STAT(...)
Definition stats.qh:94
#define M_PI
pi
Definition mathlib.qh:114
float cos(float f)
float random(void)
float sqrt(float f)
float sin(float f)
float min(float f,...)
float rint(float f)
float floor(float f)
float MSG_BROADCAST
Definition menudefs.qc:55
#define etof(e)
Definition misc.qh:25
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:133
void orb_setup(entity orb)
Definition net.qc:44
void orb_draw(entity this)
Definition net.qc:10
void orb_draw2d(entity this)
Definition net.qc:30
void nade_Effect(entity player, entity eff, int eff_cnt)
Network nade effect data to player.
Definition net.qc:147
bool orb_send(entity this, entity to, int sf)
Definition net.qc:101
float scale
Definition projectile.qc:14
#define REGISTRY_GET(id, i)
Definition registry.qh:62
vector
Definition self.qh:96
vector org
Definition self.qh:96
ERASEABLE float boxesoverlap(vector m1, vector m2, vector m3, vector m4)
Requires that m2>m1 in all coordinates, and that m4>m3.
Definition vector.qh:72
#define vec2(...)
Definition vector.qh:95
float autocvar_hud_colorflash_alpha
Definition view.qh:39