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