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