From c548a2368c2321d3c85d669a09f433cb98582a08 Mon Sep 17 00:00:00 2001 From: TimePath Date: Sun, 13 Mar 2016 20:31:56 +1100 Subject: [PATCH] Porto launch: fix laser tracer --- qcsrc/client/main.qc | 2 - qcsrc/client/view.qc | 119 +++++++++++++++++++------------------------ qcsrc/lib/vector.qh | 14 ++++- 3 files changed, 65 insertions(+), 70 deletions(-) diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 7fbdd9d18..ded6d5b32 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -332,7 +332,6 @@ void Playerchecker_Think() this.nextthink = time + 0.2; } -void Porto_Init(); void TrueAim_Init(); void PostInit() { @@ -340,7 +339,6 @@ void PostInit() playerchecker.think = Playerchecker_Think; playerchecker.nextthink = time + 0.2; - Porto_Init(); TrueAim_Init(); postinit = true; diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index c1786f41f..70a4f2eeb 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -340,90 +340,75 @@ STATIC_INIT(viewmodel) { viewmodel = new(viewmodel); } -entity porto; -vector polyline[16]; -void Porto_Draw(entity this) +void Porto_Draw(entity this); +STATIC_INIT(Porto) { - vector p, dir, ang, q, nextdir; - float portal_number, portal1_idx; - - if(activeweapon != WEP_PORTO || spectatee_status || gametype == MAPINFO_TYPE_NEXBALL) - return; - if(WEP_CVAR(porto, secondary)) - return; - if(intermission == 1) - return; - if(intermission == 2) - return; - if (STAT(HEALTH) <= 0) - return; + entity e = new_pure(porto); + e.draw = Porto_Draw; + e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; +} - dir = view_forward; +const int polyline_length = 16; +vector polyline[polyline_length]; +void Porto_Draw(entity this) +{ + if (activeweapon != WEP_PORTO) return; + if (spectatee_status) return; + if (WEP_CVAR(porto, secondary)) return; + if (intermission == 1) return; + if (intermission == 2) return; + if (STAT(HEALTH) <= 0) return; - if(angles_held_status) + vector pos = view_origin; + vector dir = view_forward; + if (angles_held_status) { makevectors(angles_held); dir = v_forward; } - p = view_origin; - - polyline[0] = p; - int idx = 1; - portal_number = 0; - nextdir = dir; + polyline[0] = pos; - for (;;) + int portal_number = 0, portal1_idx = 1, portal_max = 2; + int n = 1 + 2; // 2 lines == 3 points + for (int idx = 0; idx < n && idx < polyline_length - 1; ) { - dir = nextdir; - traceline(p, p + 65536 * dir, true, porto); - if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) - return; - nextdir = dir - 2 * (dir * trace_plane_normal) * trace_plane_normal; // mirror dir at trace_plane_normal - p = trace_endpos; - polyline[idx] = p; - ++idx; - if(idx >= 16) - return; - if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP) - continue; - ++portal_number; - ang = vectoangles2(trace_plane_normal, dir); - ang.x = -ang.x; - makevectors(ang); - if(!CheckWireframeBox(porto, p - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward)) - return; - if(portal_number == 1) + traceline(pos, pos + 65536 * dir, true, this); + dir = reflect(dir, trace_plane_normal); + pos = trace_endpos; + polyline[++idx] = pos; + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP) { - portal1_idx = idx; - if(portal_number >= 2) - break; + n += 1; + continue; } - } - - while(idx >= 2) - { - p = polyline[idx-2]; - q = polyline[idx-1]; - if(idx == 2) - p = p - view_up * 16; - if(idx-1 >= portal1_idx) + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) { - Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL, view_origin); + n = max(2, idx); + break; } - else + // check size { - Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL, view_origin); + vector ang = vectoangles2(trace_plane_normal, dir); + ang.x = -ang.x; + makevectors(ang); + if (!CheckWireframeBox(this, pos - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward)) + { + n = max(2, idx); + break; + } } - --idx; + portal_number += 1; + if (portal_number >= portal_max) break; + if (portal_number == 1) portal1_idx = idx; + } + for (int idx = 0; idx < n - 1; ++idx) + { + vector p = polyline[idx], q = polyline[idx + 1]; + if (idx == 0) p -= view_up * 16; // line from player + vector rgb = (idx < portal1_idx) ? '1 0 0' : '0 0 1'; + Draw_CylindricLine(p, q, 4, "", 1, 0, rgb, 0.5, DRAWFLAG_NORMAL, view_origin); } -} - -void Porto_Init() -{ - porto = new_pure(porto); - porto.draw = Porto_Draw; - porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; } float drawtime; diff --git a/qcsrc/lib/vector.qh b/qcsrc/lib/vector.qh index 21b931e93..def1dae2d 100644 --- a/qcsrc/lib/vector.qh +++ b/qcsrc/lib/vector.qh @@ -87,7 +87,9 @@ float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { ret } MACRO_END noref vector _vec2; -#define vec2(v) (_vec2 = (v), _vec2.z = 0, _vec2) +#define vec2(...) EVAL(OVERLOAD(vec2, __VA_ARGS__)) +#define vec2_1(v) (_vec2 = (v), _vec2.z = 0, _vec2) +#define vec2_2(x, y) (_vec2_x = (x), _vec2_y = (y), _vec2) noref vector _vec3; #define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3) @@ -104,6 +106,16 @@ vector rotate(vector v, float a) noref vector _yinvert; #define yinvert(v) (_yinvert = (v), _yinvert.y = 1 - _yinvert.y, _yinvert) +/** + * @param dir the directional vector + * @param norm the normalized normal + * @returns dir reflected by norm + */ +vector reflect(vector dir, vector norm) +{ + return dir - 2 * (dir * norm) * norm; +} + #ifndef MENUQC vector get_corner_position(entity box, int corner) { -- 2.39.2