hook now working!
[divverent/nexuiz.git] / data / qcsrc / client / hook.qc
1 .vector HookStart;
2 .vector HookEnd;
3 .float HookKillTime;
4
5 void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float alpha, float drawflag)
6 {
7         // I want to draw a quad...
8         // from and to are MIDPOINTS.
9         
10         vector axis, thickdir, A, B, C, D;
11         float length_tex;
12
13         axis = normalize(to - from);
14         length_tex = aspect * vlen(to - from) / thickness;
15
16         // direction is perpendicular to the view normal, and perpendicular to the axis
17         thickdir = normalize(cross(axis, view_origin - from));
18
19         A = from - thickdir * (thickness / 2);
20         B = from + thickdir * (thickness / 2);
21         C = to + thickdir * (thickness / 2);
22         D = to - thickdir * (thickness / 2);
23
24         R_BeginPolygon(texture, drawflag);
25         R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, alpha);
26         R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, alpha);
27         R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
28         R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
29         R_EndPolygon();
30 }
31
32 string Draw_GrapplingHook_trace_callback_tex;
33 float Draw_GrapplingHook_trace_callback_rnd;
34 void Draw_GrapplingHook_trace_callback(vector start, vector hit, vector end)
35 {
36         Draw_CylindricLine(hit, start, 8, Draw_GrapplingHook_trace_callback_tex, 0.25, Draw_GrapplingHook_trace_callback_rnd, '1 1 1', 1, DRAWFLAG_NORMAL);
37         Draw_GrapplingHook_trace_callback_rnd += 0.25 * vlen(hit - start) / 8;
38 }
39
40 void Draw_GrapplingHook()
41 {
42         vector a, b;
43         string tex;
44         vector rgb;
45         float t;
46
47         if(time >= self.HookKillTime)
48                 return;
49         if(self.sv_entnum == player_localentnum - 1)
50                 a = view_origin + view_forward * hook_shotorigin_x + view_right * hook_shotorigin_y + view_up * hook_shotorigin_z;
51         else
52                 a = self.HookStart;
53         b = self.HookEnd;
54
55         t = GetPlayerColorForce(self.sv_entnum);
56
57         if(t == COLOR_TEAM1)
58         {
59                 tex = "particles/hook_red";
60                 rgb = '1 .3 .3';
61         }
62         else if(t == COLOR_TEAM2)
63         {
64                 tex = "particles/hook_blue";
65                 rgb = '.3 .3 1';
66         }
67         else if(t == COLOR_TEAM3)
68         {
69                 tex = "particles/hook_yellow";
70                 rgb = '1 1 .3';
71         }
72         else if(t == COLOR_TEAM4)
73         {
74                 tex = "particles/hook_pink";
75                 rgb = '1 .3 1';
76         }
77         else
78         {
79                 tex = "particles/hook_green";
80                 rgb = '.3 1 .3';
81         }
82
83         WarpZone_trace_callback = Draw_GrapplingHook_trace_callback;
84         Draw_GrapplingHook_trace_callback_tex = tex;
85         Draw_GrapplingHook_trace_callback_rnd = random();
86         WarpZone_TraceLine(a, b, MOVE_NOMONSTERS, world);
87         WarpZone_trace_callback = func_null;
88         Draw_GrapplingHook_trace_callback_tex = string_null;
89 }
90
91 void Net_GrapplingHook()
92 {
93         float i;
94         vector start, end;
95         entity p;
96
97         i = ReadShort();
98         end_x = ReadCoord();
99         end_y = ReadCoord();
100         end_z = ReadCoord();
101         start_x = ReadCoord();
102         start_y = ReadCoord();
103         start_z = ReadCoord();
104
105         if(i <= 0 || i >= 256) // not owned by a client
106                 return;
107         --i;
108
109         p = playerslots[i];
110         if(!p)
111                 return;
112
113         p.HookKillTime = time + 0.1;
114         p.HookStart = start;
115         p.HookEnd = end;
116         p.draw = Draw_GrapplingHook;
117 }