1 // FIXME make this generic code, to be used for other entities too?
2 .vector iorigin1, iorigin2;
3 .vector ivelocity1, ivelocity2;
4 .vector iforward1, iforward2;
5 .vector iright1, iright2;
7 void InterpolateOrigin_Note()
11 makevectors(self.angles);
13 self.iorigin1 = self.iorigin2;
14 self.iforward1 = self.iforward2;
15 self.iright1 = self.iright2;
16 self.ivelocity1 = self.ivelocity2;
18 self.iorigin2 = self.origin;
19 self.iforward2 = v_forward;
20 self.iright2 = v_right;
21 self.ivelocity2 = self.velocity;
23 dt = time - self.itime1;
25 if(vlen(self.iorigin2 - self.iorigin1) > 1000)
27 self.iorigin1 = self.iorigin2;
28 self.iforward1 = self.iforward2;
29 self.iright1 = self.iright2;
30 self.ivelocity1 = self.ivelocity2;
32 else if(vlen(self.ivelocity2 - self.ivelocity1) > 1000)
34 self.iforward1 = self.iforward2;
35 self.iright1 = self.iright2;
36 self.ivelocity1 = self.ivelocity2;
42 self.itime2 = time + getstatf(STAT_SYS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
47 self.itime1 = self.itime2 = time;
50 void InterpolateOrigin_Do()
52 vector forward, right;
53 if(self.itime1 && self.itime2 && self.itime1 != self.itime2)
56 f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1);
57 self.origin = (1 - f) * self.iorigin1 + f * self.iorigin2;
58 forward = (1 - f) * self.iforward1 + f * self.iforward2;
59 right = (1 - f) * self.iright1 + f * self.iright2;
60 self.angles = vectoangles(forward, right);
61 self.angles_x = -self.angles_x;
62 self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2;
65 void InterpolateOrigin_Undo()
67 self.origin = self.iorigin2;
68 self.angles = vectoangles(self.iforward2, self.iright2);
69 self.angles_x = -self.angles_x;
70 self.velocity = self.ivelocity2;
73 // a laser goes from origin in direction angles
74 // it has color 'colormod'
75 // and stops when something is in the way
76 .float cnt; // end effect
78 .float state; // on-off
79 .float count; // flags for the laser
83 // TODO move these into a heade file
84 float trace_dphitq3surfaceflags;
85 float Q3SURFACEFLAG_SKY = 4; // sky surface (also has NOIMPACT and NOMARKS set)
86 float Q3SURFACEFLAG_NOIMPACT = 16; // projectiles should remove themselves on impact (this is set on sky)
92 InterpolateOrigin_Do();
95 traceline(self.origin, self.velocity, 0, self);
99 makevectors(self.angles);
100 traceline(self.origin, self.origin + v_forward * 32768, 0, self);
101 if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
102 trace_endpos = self.origin + v_forward * 1048576;
106 Draw_CylindricLine(self.origin, trace_endpos, 2, "particles/laserbeam", 0, time * 3, self.colormod, self.alpha, DRAWFLAG_NORMAL); // TODO make a texture to make the laser look smoother
110 Draw_CylindricLine(self.origin, trace_endpos, 2, "particles/laserbeam", 0, time * 3, self.colormod, 0.5, DRAWFLAG_ADDITIVE); // TODO make a texture to make the laser look smoother
112 if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
115 pointparticles(self.cnt, trace_endpos, trace_plane_normal, drawframetime * 1000);
116 if(self.colormod != '0 0 0')
117 R_AddDynamicLight(trace_endpos + trace_plane_normal * 1, 50, self.colormod * 5);
124 // 30 bytes, or 13 bytes for just moving
126 self.count = (f & 0xC0);
127 InterpolateOrigin_Undo();
130 self.origin_x = ReadCoord();
131 self.origin_y = ReadCoord();
132 self.origin_z = ReadCoord();
136 self.colormod_x = ReadByte() / 255.0;
137 self.colormod_y = ReadByte() / 255.0;
138 self.colormod_z = ReadByte() / 255.0;
140 self.alpha = ReadByte() / 255.0;
143 self.cnt = ReadShort() - 1; // effect number
149 self.velocity_x = ReadCoord();
150 self.velocity_y = ReadCoord();
151 self.velocity_z = ReadCoord();
155 self.angles_x = ReadCoord();
156 self.angles_y = ReadCoord();
160 self.state = ReadByte();
161 InterpolateOrigin_Note();
162 self.draw = Draw_Laser;