]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/effects/qc/modeleffects.qc
Add Read/WriteAngleVector macros to simplify the networking of angles
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / effects / qc / modeleffects.qc
1 #include "modeleffects.qh"
2
3 REGISTER_NET_LINKED(ENT_CLIENT_MODELEFFECT)
4
5 #ifdef SVQC
6
7 .float scale2;
8
9 bool modeleffect_SendEntity(entity this, entity to, int sf)
10 {
11         float f;
12         WriteHeader(MSG_ENTITY, ENT_CLIENT_MODELEFFECT);
13
14         f = 0;
15         if(this.velocity != '0 0 0')
16                 f |= 1;
17         if(this.angles != '0 0 0')
18                 f |= 2;
19         if(this.avelocity != '0 0 0')
20                 f |= 4;
21
22         WriteByte(MSG_ENTITY, f);
23         WriteShort(MSG_ENTITY, this.modelindex);
24         WriteByte(MSG_ENTITY, this.skin);
25         WriteByte(MSG_ENTITY, this.frame);
26         WriteVector(MSG_ENTITY, this.origin);
27         if(f & 1)
28         {
29                 WriteVector(MSG_ENTITY, this.velocity);
30         }
31         if(f & 2)
32         {
33                 WriteAngleVector(MSG_ENTITY, this.angles);
34         }
35         if(f & 4)
36         {
37                 WriteAngleVector(MSG_ENTITY, this.avelocity);
38         }
39         WriteShort(MSG_ENTITY, this.scale * 256.0);
40         WriteShort(MSG_ENTITY, this.scale2 * 256.0);
41         WriteByte(MSG_ENTITY, this.teleport_time * 100.0);
42         WriteByte(MSG_ENTITY, this.fade_time * 100.0);
43         WriteByte(MSG_ENTITY, this.alpha * 255.0);
44
45         return true;
46 }
47
48 void modeleffect_spawn(string m, float s, float f, vector o, vector v, vector ang, vector angv, float s0, float s2, float a, float t1, float t2)
49 {
50         entity e = new(modeleffect);
51         _setmodel(e, m);
52         e.frame = f;
53         setorigin(e, o);
54         e.velocity = v;
55         e.angles = ang;
56         e.avelocity = angv;
57         e.alpha = a;
58         e.teleport_time = t1;
59         e.fade_time = t2;
60         e.skin = s;
61         if(s0 >= 0)
62                 e.scale = s0 / max6(-e.mins.x, -e.mins.y, -e.mins.z, e.maxs.x, e.maxs.y, e.maxs.z);
63         else
64                 e.scale = -s0;
65         if(s2 >= 0)
66                 e.scale2 = s2 / max6(-e.mins.x, -e.mins.y, -e.mins.z, e.maxs.x, e.maxs.y, e.maxs.z);
67         else
68                 e.scale2 = -s2;
69         float sz = max(e.scale, e.scale2);
70         setsize(e, e.mins * sz, e.maxs * sz);
71         Net_LinkEntity(e, false, 0.1, modeleffect_SendEntity);
72 }
73
74 #endif
75
76 #ifdef CSQC
77
78 entityclass(ModelEffect);
79 classfield(ModelEffect) .float frame1time;
80 classfield(ModelEffect) .float lifetime, fadetime;
81 classfield(ModelEffect) .float teleport_time;
82 classfield(ModelEffect) .float scale1, scale2;
83
84 .float cnt;
85 .float scale;
86 .float alpha;
87
88 void ModelEffect_Draw(entity this)
89 {
90         this.angles = this.angles + frametime * this.avelocity;
91         setorigin(this, this.origin + frametime * this.velocity);
92         this.scale = this.scale1 + (this.scale2 - this.scale1) * (time - this.teleport_time) / (this.lifetime + this.fadetime - this.teleport_time);
93         this.alpha = this.cnt * bound(0, 1 - (time - this.lifetime) / this.fadetime, 1);
94         if(this.alpha < ALPHA_MIN_VISIBLE)
95         {
96                 delete(this);
97                 return;
98         }
99         this.drawmask = MASK_NORMAL;
100         if(this.scale <= 0)
101         {
102                 this.drawmask = 0;
103                 return;
104         }
105 }
106
107 NET_HANDLE(ENT_CLIENT_MODELEFFECT, bool isnew)
108 {
109         make_pure(this);
110
111         int f = ReadByte();
112
113         entity e = new(modeleffect);
114         e.model = "from network";
115         e.modelindex = ReadShort();
116         e.skin = ReadByte();
117         e.frame = ReadByte();
118         e.frame1time = time;
119         e.origin = ReadVector();
120         setorigin(e, e.origin);
121         if(f & 1)
122         {
123                 e.velocity = ReadVector();
124         }
125         if(f & 2)
126         {
127                 e.angles = ReadAngleVector();
128         }
129         if(f & 4)
130         {
131                 e.avelocity = ReadAngleVector();
132         }
133         e.scale1 = ReadShort() / 256.0;
134         e.scale2 = ReadShort() / 256.0;
135         e.lifetime = time + ReadByte() * 0.01;
136         e.fadetime = ReadByte() * 0.01;
137         e.teleport_time = time;
138         e.cnt = ReadByte() / 255.0; // actually alpha
139
140         e.draw = ModelEffect_Draw;
141         if (isnew) IL_PUSH(g_drawables, e);
142
143         if (!isnew) delete(e); // yes, this IS stupid, but I don't need to duplicate all the read* stuff then
144         return true;
145 }
146 #endif