]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/laser.qc
fix compile errors; make sky-hitting lasers extend to infinity
[divverent/nexuiz.git] / data / qcsrc / client / laser.qc
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;
6 .float itime1, itime2;
7 void InterpolateOrigin_Note()
8 {
9         float dt;
10
11         makevectors(self.angles);
12
13         self.iorigin1 = self.iorigin2;
14         self.iforward1 = self.iforward2;
15         self.iright1 = self.iright2;
16         self.ivelocity1 = self.ivelocity2;
17
18         self.iorigin2 = self.origin;
19         self.iforward2 = v_forward;
20         self.iright2 = v_right;
21         self.ivelocity2 = self.velocity;
22
23         dt = time - self.itime1;
24
25         if(vlen(self.iorigin2 - self.iorigin1) > 1000)
26         {
27                 self.iorigin1 = self.iorigin2;
28                 self.iforward1 = self.iforward2;
29                 self.iright1 = self.iright2;
30                 self.ivelocity1 = self.ivelocity2;
31         }
32         else if(vlen(self.ivelocity2 - self.ivelocity1) > 1000)
33         {
34                 self.iforward1 = self.iforward2;
35                 self.iright1 = self.iright2;
36                 self.ivelocity1 = self.ivelocity2;
37         }
38
39         if(dt < 0.2)
40         {
41                 self.itime1 = time;
42                 self.itime2 = time + getstatf(STAT_SYS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
43         }
44         else
45         {
46                 // don't lerp
47                 self.itime1 = self.itime2 = time;
48         }
49 }
50 void InterpolateOrigin_Do()
51 {
52         vector forward, right;
53         if(self.itime1 && self.itime2 && self.itime1 != self.itime2)
54         {
55                 float f;
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;
63         }
64 }
65 void InterpolateOrigin_Undo()
66 {
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;
71 }
72
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
77 .vector colormod;
78 .float state; // on-off
79 .float count; // flags for the laser
80 .vector velocity;
81 .float alpha;
82
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)
87
88 void Draw_Laser()
89 {
90         if(!self.state)
91                 return;
92         InterpolateOrigin_Do();
93         if(self.count & 0x80)
94         {
95                 traceline(self.origin, self.velocity, 0, self);
96         }
97         else
98         {
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;
103         }
104         if(self.alpha)
105         {
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
107         }
108         else
109         {
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
111         }
112         if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
113         {
114                 if(self.cnt >= 0)
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);
118         }
119 }
120
121 void Ent_Laser()
122 {
123         float f;
124         // 30 bytes, or 13 bytes for just moving
125         f = ReadByte();
126         self.count = (f & 0xC0);
127         InterpolateOrigin_Undo();
128         if(f & 1)
129         {
130                 self.origin_x = ReadCoord();
131                 self.origin_y = ReadCoord();
132                 self.origin_z = ReadCoord();
133         }
134         if(f & 8)
135         {
136                 self.colormod_x = ReadByte() / 255.0;
137                 self.colormod_y = ReadByte() / 255.0;
138                 self.colormod_z = ReadByte() / 255.0;
139                 if(f & 0x40)
140                         self.alpha = ReadByte() / 255.0;
141                 else
142                         self.alpha = 0;
143                 self.cnt = ReadShort() - 1; // effect number
144         }
145         if(f & 2)
146         {
147                 if(f & 0x80)
148                 {
149                         self.velocity_x = ReadCoord();
150                         self.velocity_y = ReadCoord();
151                         self.velocity_z = ReadCoord();
152                 }
153                 else
154                 {
155                         self.angles_x = ReadCoord();
156                         self.angles_y = ReadCoord();
157                 }
158         }
159         if(f & 4)
160                 self.state = ReadByte();
161         InterpolateOrigin_Note();
162         self.draw = Draw_Laser;
163 }