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