X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fweapons%2Fweapon%2Fporto.qc;h=0e482d8ae82db239dbdd14160070da41befea332;hb=7a450de6b250eccb737d4c428b634496b933e4ff;hp=9f79bf440c44bf6b42950d5595c1e99af5f39c16;hpb=76de60deecae125795551ba1a4576a265d7ae7de;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index 9f79bf440..0e482d8ae 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -1,7 +1,87 @@ #include "porto.qh" +#ifdef CSQC +STATIC_INIT(Porto) +{ + entity e = new_pure(porto); + e.draw = Porto_Draw; + IL_PUSH(g_drawables, e); + e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; +} + +const int polyline_length = 16; +.vector polyline[polyline_length]; +void Porto_Draw(entity this) +{ + if (spectatee_status || intermission == 1 || intermission == 2 || STAT(HEALTH) <= 0 || WEP_CVAR(porto, secondary)) return; + + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + entity wepent = viewmodels[slot]; + + if (wepent.activeweapon != WEP_PORTO) continue; + + vector pos = view_origin; + vector dir = view_forward; + makevectors(((autocvar_chase_active) ? warpzone_save_view_angles : view_angles)); + pos += v_right * -wepent.movedir.y + + v_up * wepent.movedir.z; + + if (wepent.angles_held_status) + { + makevectors(wepent.angles_held); + dir = v_forward; + } + + wepent.polyline[0] = pos; + + 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; ) + { + traceline(pos, pos + 65536 * dir, true, this); + dir = reflect(dir, trace_plane_normal); + pos = trace_endpos; + wepent.polyline[++idx] = pos; + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP) + { + n += 1; + continue; + } + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) + { + n = max(2, idx); + break; + } + // check size + { + 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; + } + } + 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 = wepent.polyline[idx], q = wepent.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); + } + } +} +#endif + #ifdef SVQC #include +#include REGISTER_MUTATOR(porto_ticker, true); MUTATOR_HOOKFUNCTION(porto_ticker, SV_StartFrame) { @@ -20,7 +100,6 @@ void W_Porto_Success(entity this) delete(this); } -string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo, .entity weaponentity); void W_Porto_Fail(entity this, float failhard) { if(this.realowner == NULL) @@ -198,11 +277,11 @@ void W_Porto_Touch(entity this, entity toucher) } } -void W_Porto_Attack(entity actor, .entity weaponentity, float type) +void W_Porto_Attack(Weapon thiswep, entity actor, .entity weaponentity, float type) { entity gren; - W_SetupShot(actor, weaponentity, false, 4, SND_PORTO_FIRE, CH_WEAPON_A, 0, WEP_PORTO.m_id); // TODO: does the deathtype even need to be set here? porto can't hurt people + W_SetupShot(actor, weaponentity, false, 4, SND_PORTO_FIRE, CH_WEAPON_A, 0, thiswep.m_id); // TODO: does the deathtype even need to be set here? porto can't hurt people // always shoot from the eye w_shotdir = v_forward; w_shotorg = actor.origin + actor.view_ofs + ((w_shotorg - actor.origin - actor.view_ofs) * v_forward) * v_forward; @@ -270,7 +349,7 @@ METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weapone if(!actor.porto_forbidden) if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(porto, refire))) { - W_Porto_Attack(actor, weaponentity, 0); + W_Porto_Attack(thiswep, actor, weaponentity, 0); weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); } @@ -279,7 +358,7 @@ METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weapone if(!actor.porto_forbidden) if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(porto, refire))) { - W_Porto_Attack(actor, weaponentity, 1); + W_Porto_Attack(thiswep, actor, weaponentity, 1); weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(porto, animtime), w_ready); } } @@ -306,7 +385,7 @@ METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weapone if(!actor.porto_forbidden) if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(porto, refire))) { - W_Porto_Attack(actor, weaponentity, -1); + W_Porto_Attack(thiswep, actor, weaponentity, -1); weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); } }