Merge remote branch 'refs/remotes/origin/fruitiex/xpmbalance'
[xonotic/xonotic-data.pk3dir.git] / 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 /*
20         print("from ", vtos(from), "\n");
21         print("to ", vtos(to), "\n");
22         print("org ", vtos(view_origin), "\n");
23         print("dir ", vtos(thickdir), "\n");
24 */
25
26         A = from - thickdir * (thickness / 2);
27         B = from + thickdir * (thickness / 2);
28         C = to + thickdir * (thickness / 2);
29         D = to - thickdir * (thickness / 2);
30
31         R_BeginPolygon(texture, drawflag);
32         R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, alpha);
33         R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, alpha);
34         R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
35         R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
36         R_EndPolygon();
37 }
38
39 string Draw_GrapplingHook_trace_callback_tex;
40 float Draw_GrapplingHook_trace_callback_rnd;
41 void Draw_GrapplingHook_trace_callback(vector start, vector hit, vector end)
42 {
43         Draw_CylindricLine(hit, start, 8, Draw_GrapplingHook_trace_callback_tex, 0.25, Draw_GrapplingHook_trace_callback_rnd, '1 1 1', 1, DRAWFLAG_NORMAL);
44         Draw_GrapplingHook_trace_callback_rnd += 0.25 * vlen(hit - start) / 8;
45 }
46
47 void Draw_GrapplingHook()
48 {
49         vector a, b;
50         string tex;
51         vector rgb;
52         float t;
53
54         if(time >= self.HookKillTime)
55                 return;
56         if(self.sv_entnum == player_localentnum - 1)
57                 a = view_origin + view_forward * hook_shotorigin_x + view_right * hook_shotorigin_y + view_up * hook_shotorigin_z;
58         else
59                 a = self.HookStart;
60         b = self.HookEnd;
61
62         t = GetPlayerColorForce(self.sv_entnum);
63
64         if(t == COLOR_TEAM1)
65         {
66                 tex = "particles/hook_red";
67                 rgb = '1 .3 .3';
68         }
69         else if(t == COLOR_TEAM2)
70         {
71                 tex = "particles/hook_blue";
72                 rgb = '.3 .3 1';
73         }
74         else if(t == COLOR_TEAM3)
75         {
76                 tex = "particles/hook_yellow";
77                 rgb = '1 1 .3';
78         }
79         else if(t == COLOR_TEAM4)
80         {
81                 tex = "particles/hook_pink";
82                 rgb = '1 .3 1';
83         }
84         else
85         {
86                 tex = "particles/hook_green";
87                 rgb = '.3 1 .3';
88         }
89
90         Draw_GrapplingHook_trace_callback_tex = tex;
91         Draw_GrapplingHook_trace_callback_rnd = random();
92         WarpZone_TraceBox_ThroughZone(a, '0 0 0', '0 0 0', b, MOVE_NOMONSTERS, world, world, Draw_GrapplingHook_trace_callback);
93         Draw_GrapplingHook_trace_callback_tex = string_null;
94 }
95
96 void Net_GrapplingHook()
97 {
98         float i;
99         vector start, end;
100         entity p;
101
102         i = ReadShort();
103         end_x = ReadCoord();
104         end_y = ReadCoord();
105         end_z = ReadCoord();
106         start_x = ReadCoord();
107         start_y = ReadCoord();
108         start_z = ReadCoord();
109
110         if(i <= 0 || i >= 256) // not owned by a client
111                 return;
112         --i;
113
114         p = playerslots[i];
115         if(!p)
116                 return;
117
118         p.HookKillTime = time + 0.1;
119         p.HookStart = start;
120         p.HookEnd = end;
121         p.draw = Draw_GrapplingHook;
122 }