1 .vector iorigin1, iorigin2;
\r
3 .vector trail_oldorigin;
\r
4 .float trail_oldtime;
\r
5 .float fade_time, fade_rate;
\r
13 self.move_velocity = self.move_avelocity = '0 0 0';
\r
14 self.move_movetype = MOVETYPE_NONE;
\r
18 .float count; // set if clientside projectile
\r
19 .float cnt; // sound index
\r
25 void Projectile_DrawTrail(vector to)
\r
29 from = self.trail_oldorigin;
\r
30 t0 = self.trail_oldtime;
\r
31 self.trail_oldorigin = to;
\r
32 self.trail_oldtime = time;
\r
34 if (self.traileffect)
\r
35 trailparticles(self, self.traileffect, from, to);
\r
38 void Projectile_Draw()
\r
47 f = self.move_flags;
\r
49 if(self.count & 0x80)
\r
51 //self.move_flags &~= FL_ONGROUND;
\r
52 Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
\r
53 if(!(self.move_flags & FL_ONGROUND))
\r
54 self.angles = vectoangles(self.velocity);
\r
58 InterpolateOrigin_Do();
\r
61 if(self.count & 0x80)
\r
63 drawn = (time >= self.spawntime - 0.02);
\r
64 t = max(time, self.spawntime);
\r
68 drawn = (self.iflags & IFLAG_VALID);
\r
72 if(!(f & FL_ONGROUND))
\r
78 case PROJECTILE_EXAMPLE:
\r
85 self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
\r
93 a = 1 - (time - self.fade_time) * self.fade_rate;
\r
97 trailorigin = self.origin;
\r
100 case PROJECTILE_EXAMPLE:
\r
101 trailorigin += v_right * 1 + v_forward * -10;
\r
107 Projectile_DrawTrail(trailorigin);
\r
110 self.trail_oldorigin = trailorigin;
\r
111 self.trail_oldtime = time;
\r
119 case PROJECTILE_EXAMPLE:
\r
120 R_AddDynamicLight(self.origin, 50 * a, '1 1 0');
\r
126 self.alpha = self.alphamod * a;
\r
127 self.renderflags = 0;
\r
132 void loopsound(entity e, float ch, string samp, float vol, float attn)
\r
137 sound(e, ch, samp, vol, attn);
\r
141 void Ent_RemoveProjectile()
\r
143 if(self.snd_looping)
\r
144 sound(self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM);
\r
146 if(self.count & 0x80)
\r
148 tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.05, MOVE_NORMAL, self);
\r
149 Projectile_DrawTrail(trace_endpos);
\r
153 void Ent_Projectile()
\r
157 // projectile properties:
\r
158 // kind (interpolated, or clientside)
\r
166 // soundindex (hardcoded list)
\r
169 // projectiles don't send angles, because they always follow the velocity
\r
172 self.count = (f & 0x80);
\r
173 self.iflags = (self.iflags & IFLAG_INTERNALMASK) | IFLAG_AUTOANGLES | IFLAG_ANGLES;
\r
174 self.solid = SOLID_TRIGGER;
\r
175 //self.effects = EF_NOMODELFLAGS;
\r
177 // this should make collisions with bmodels more exact, but it leads to
\r
178 // projectiles no longer being able to lie on a bmodel
\r
179 self.move_nomonsters = MOVE_WORLDONLY;
\r
181 self.move_flags |= FL_ONGROUND;
\r
183 self.move_flags &~= FL_ONGROUND;
\r
185 if(!self.move_time)
\r
187 // for some unknown reason, we don't need to care for
\r
188 // sv_gameplayfix_delayprojectiles here.
\r
189 self.move_time = time;
\r
190 self.spawntime = time;
\r
193 self.move_time = max(self.move_time, time);
\r
195 if(!(self.count & 0x80))
\r
196 InterpolateOrigin_Undo();
\r
200 self.origin_x = ReadCoord();
\r
201 self.origin_y = ReadCoord();
\r
202 self.origin_z = ReadCoord();
\r
203 if(self.count & 0x80)
\r
205 self.velocity_x = ReadCoord();
\r
206 self.velocity_y = ReadCoord();
\r
207 self.velocity_z = ReadCoord();
\r
208 self.gravity = ReadCoord();
\r
210 self.move_origin = self.origin;
\r
211 self.move_velocity = self.velocity;
\r
214 if(time == self.spawntime || (self.count & 0x80) || (f & 0x10))
\r
216 self.trail_oldorigin = self.origin;
\r
217 if(!(self.count & 0x80))
\r
218 InterpolateOrigin_Reset();
\r
223 self.fade_time = time + ReadByte() * ticrate;
\r
224 self.fade_rate = 1 / (ReadByte() * ticrate);
\r
228 self.fade_time = 0;
\r
229 self.fade_rate = 0;
\r
235 self.cnt = ReadByte();
\r
237 self.silent = (self.cnt & 0x80);
\r
238 self.cnt = (self.cnt & 0x7F);
\r
241 self.traileffect = 0;
\r
244 case PROJECTILE_EXAMPLE: setmodel(self, "models/example.mdl");self.traileffect = particleeffectnum("TR_EXAMPLE"); break;
\r
246 error("Received invalid CSQC projectile, can't work with this!");
\r
250 self.mins = '0 0 0';
\r
251 self.maxs = '0 0 0';
\r
252 self.colormod = '0 0 0';
\r
253 self.move_touch = SUB_Stop;
\r
254 self.move_movetype = MOVETYPE_TOSS;
\r
259 case PROJECTILE_EXAMPLE:
\r
260 loopsound(self, CHAN_PROJECTILE, "weapons/example.wav", VOL_BASE, ATTN_NORM);
\r
261 self.mins = '-3 -3 -3';
\r
262 self.maxs = '3 3 3';
\r
271 if(self.move_movetype == MOVETYPE_FLY)
\r
272 self.move_movetype = MOVETYPE_TOSS;
\r
273 if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
\r
274 self.move_movetype = MOVETYPE_BOUNCE;
\r
278 if(self.move_movetype == MOVETYPE_TOSS)
\r
279 self.move_movetype = MOVETYPE_FLY;
\r
280 if(self.move_movetype == MOVETYPE_BOUNCE)
\r
281 self.move_movetype = MOVETYPE_BOUNCEMISSILE;
\r
284 if(!(self.count & 0x80))
\r
285 InterpolateOrigin_Note();
\r
287 self.draw = Projectile_Draw;
\r
288 self.entremove = Ent_RemoveProjectile;
\r
291 void Projectile_Precache()
\r
293 precache_model("models/example.mdl");
\r
294 precache_sound("weapons/example.wav");
\r