VERY experimental change to handle electro lg beam in csqc
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hook.qc
1 .vector HookStart;
2 .vector HookEnd;
3 .float HookKillTime;
4 .vector LGBeamStart;
5 .vector LGBeamEnd;
6 .float LGBeamKillTime;
7 .float LGBeamSound;
8 .float LGBeamSilent;
9
10 void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float alpha, float drawflag)
11 {
12         // I want to draw a quad...
13         // from and to are MIDPOINTS.
14         
15         vector axis, thickdir, A, B, C, D;
16         float length_tex;
17
18         axis = normalize(to - from);
19         length_tex = aspect * vlen(to - from) / thickness;
20
21         // direction is perpendicular to the view normal, and perpendicular to the axis
22         thickdir = normalize(cross(axis, view_origin - from));
23
24 /*
25         print("from ", vtos(from), "\n");
26         print("to ", vtos(to), "\n");
27         print("org ", vtos(view_origin), "\n");
28         print("dir ", vtos(thickdir), "\n");
29 */
30
31         A = from - thickdir * (thickness / 2);
32         B = from + thickdir * (thickness / 2);
33         C = to + thickdir * (thickness / 2);
34         D = to - thickdir * (thickness / 2);
35
36         R_BeginPolygon(texture, drawflag);
37         R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, alpha);
38         R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, alpha);
39         R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
40         R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
41         R_EndPolygon();
42 }
43
44 string Draw_GrapplingHook_trace_callback_tex;
45 float Draw_GrapplingHook_trace_callback_rnd;
46 void Draw_GrapplingHook_trace_callback(vector start, vector hit, vector end)
47 {
48         Draw_CylindricLine(hit, start, 8, Draw_GrapplingHook_trace_callback_tex, 0.25, Draw_GrapplingHook_trace_callback_rnd, '1 1 1', 1, DRAWFLAG_NORMAL);
49         Draw_GrapplingHook_trace_callback_rnd += 0.25 * vlen(hit - start) / 8;
50 }
51
52 void Draw_GrapplingHook()
53 {
54         vector a, b;
55         string tex;
56         vector rgb;
57         float t;
58
59         if(time < self.HookKillTime)
60         {
61                 if(self.sv_entnum == player_localentnum - 1)
62                         a = view_origin + view_forward * hook_shotorigin_x + view_right * hook_shotorigin_y + view_up * hook_shotorigin_z;
63                 else
64                         a = self.HookStart;
65                 b = self.HookEnd;
66
67                 t = GetPlayerColorForce(self.sv_entnum);
68
69                 if(t == COLOR_TEAM1)
70                 {
71                         tex = "particles/hook_red";
72                         rgb = '1 .3 .3';
73                 }
74                 else if(t == COLOR_TEAM2)
75                 {
76                         tex = "particles/hook_blue";
77                         rgb = '.3 .3 1';
78                 }
79                 else if(t == COLOR_TEAM3)
80                 {
81                         tex = "particles/hook_yellow";
82                         rgb = '1 1 .3';
83                 }
84                 else if(t == COLOR_TEAM4)
85                 {
86                         tex = "particles/hook_pink";
87                         rgb = '1 .3 1';
88                 }
89                 else
90                 {
91                         tex = "particles/hook_green";
92                         rgb = '.3 1 .3';
93                 }
94
95                 Draw_GrapplingHook_trace_callback_tex = tex;
96                 Draw_GrapplingHook_trace_callback_rnd = random();
97                 WarpZone_TraceBox_ThroughZone(a, '0 0 0', '0 0 0', b, MOVE_NOMONSTERS, world, world, Draw_GrapplingHook_trace_callback);
98                 Draw_GrapplingHook_trace_callback_tex = string_null;
99         }
100
101         if(time < self.LGBeamKillTime)
102         {
103                 if(self.sv_entnum == player_localentnum - 1)
104                         a = view_origin + view_forward * electro_shotorigin_x + view_right * electro_shotorigin_y + view_up * electro_shotorigin_z;
105                 else
106                         a = self.LGBeamStart;
107                 b = self.LGBeamEnd;
108
109                 tex = "particles/lgbeam";
110                 rgb = '1 1 1';
111
112                 Draw_GrapplingHook_trace_callback_tex = tex;
113                 Draw_GrapplingHook_trace_callback_rnd = random();
114                 WarpZone_TraceBox_ThroughZone(a, '0 0 0', '0 0 0', b, MOVE_NOMONSTERS, world, world, Draw_GrapplingHook_trace_callback);
115                 Draw_GrapplingHook_trace_callback_tex = string_null;
116         }
117
118         if(time < self.LGBeamKillTime && !self.LGBeamSilent)
119         {
120                 if(!self.LGBeamSound)
121                 {
122                         sound (self, CHAN_PROJECTILE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTN_NORM);
123                         self.LGBeamSound = 1;
124                 }
125         }
126         else
127         {
128                 if(self.LGBeamSound)
129                 {
130                         sound (self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM);
131                         self.LGBeamSound = 0;
132                 }
133         }
134 }
135
136 void Net_GrapplingHook()
137 {
138         float i, t;
139         vector start, end;
140         entity p;
141
142         i = ReadByte();
143         t = ReadByte();
144         end_x = ReadCoord();
145         end_y = ReadCoord();
146         end_z = ReadCoord();
147         start_x = ReadCoord();
148         start_y = ReadCoord();
149         start_z = ReadCoord();
150
151         if(i <= 0 || i >= 256) // not owned by a client
152                 return;
153         --i;
154
155         p = playerslots[i];
156         if(!p)
157                 return;
158
159         switch(t)
160         {
161                 case 0: // hook beam
162                         p.HookKillTime = time + 0.1;
163                         p.HookStart = start;
164                         p.HookEnd = end;
165                         p.draw = Draw_GrapplingHook;
166                         break;
167                 case 1: // electro lgbeam
168                         p.LGBeamKillTime = time + 0.1;
169                         p.LGBeamStart = start;
170                         p.LGBeamEnd = end;
171                         p.LGBeamSilent = 0;
172                         p.draw = Draw_GrapplingHook;
173                         break;
174                 case 2: // silent electro lgbeam
175                         p.LGBeamKillTime = time + 0.1;
176                         p.LGBeamStart = start;
177                         p.LGBeamEnd = end;
178                         p.LGBeamSilent = 1;
179                         p.draw = Draw_GrapplingHook;
180                         break;
181         }
182 }