From b8ba56ad8d1e2d812bab6cdaf54ed79c55eb4bb3 Mon Sep 17 00:00:00 2001 From: div0 Date: Sun, 28 Feb 2010 19:44:11 +0000 Subject: [PATCH] fix RL git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8709 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/w_rocketlauncher.qc | 6 +- data/qcsrc/warpzonelib/TODO | 2 +- data/qcsrc/warpzonelib/anglestransform.qc | 15 ++++ data/qcsrc/warpzonelib/anglestransform.qh | 4 + data/qcsrc/warpzonelib/common.qc | 89 ++++++++++++++++++++++- data/qcsrc/warpzonelib/common.qh | 8 ++ data/qcsrc/warpzonelib/server.qc | 5 +- 7 files changed, 121 insertions(+), 8 deletions(-) diff --git a/data/qcsrc/server/w_rocketlauncher.qc b/data/qcsrc/server/w_rocketlauncher.qc index d43ad9488..68cd5e959 100644 --- a/data/qcsrc/server/w_rocketlauncher.qc +++ b/data/qcsrc/server/w_rocketlauncher.qc @@ -228,8 +228,8 @@ void W_Rocket_Think (void) velspeed = vlen(self.velocity); makevectors(self.owner.v_angle); - desireddir = v_forward; - desiredorigin = self.owner.origin + self.owner.view_ofs; + desireddir = WarpZone_RefSys_TransformVelocity(self.owner, self, v_forward); + desiredorigin = WarpZone_RefSys_TransformOrigin(self.owner, self, self.owner.origin + self.owner.view_ofs); olddir = normalize(self.velocity); #if 0 @@ -298,7 +298,7 @@ void W_Rocket_Attack (void) W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 5, "weapons/rocket_fire.wav", cvar("g_balance_rocketlauncher_damage")); pointparticles(particleeffectnum("rocketlauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1); - missile = spawn (); + missile = WarpZone_RefSys_SpawnSameRefSys(self); missile.owner = self; self.lastrocket = missile; if(cvar("g_balance_rocketlauncher_detonatedelay") >= 0) diff --git a/data/qcsrc/warpzonelib/TODO b/data/qcsrc/warpzonelib/TODO index aa979800f..2e6dbeb25 100644 --- a/data/qcsrc/warpzonelib/TODO +++ b/data/qcsrc/warpzonelib/TODO @@ -11,12 +11,12 @@ Weapon support: - crylink: YES - nex: YES - hagar: YES +- rocketlauncher: YES (except for trail bug) - porto: YES (bwahahahaha) - hlac: YES - minstanex: YES - rifle: YES - fireball: YES (BFG effect cannot work through warpzones by design, so it's not available through warpzones) -- rocketlauncher: NO (guiding not working, trail bug) - hook: NO (hook beam, pull not working) - tuba: NO (sound) diff --git a/data/qcsrc/warpzonelib/anglestransform.qc b/data/qcsrc/warpzonelib/anglestransform.qc index c542698c7..9d974afe5 100644 --- a/data/qcsrc/warpzonelib/anglestransform.qc +++ b/data/qcsrc/warpzonelib/anglestransform.qc @@ -168,3 +168,18 @@ vector AnglesTransform_ApplyToVAngles(vector transform, vector v) return v; } #endif + +vector AnglesTransform_Multiply_GetPreShift(vector sf0, vector t0, vector st0, vector sf1, vector t1, vector st1) +{ + // we want the result of: + // t0 * (t1 * (p - sf1) + st1 - sf0) + st0 + // t0 * t1 * (p - sf1) + t0 * (st1 - sf0) + st0 + return sf1; +} +vector AnglesTransform_Multiply_GetPostShift(vector sf0, vector t0, vector st0, vector sf1, vector t1, vector st1) +{ + // we want the result of: + // t0 * (t1 * (p - sf1) + st1 - sf0) + st0 + // t0 * t1 * (p - sf1) + t0 * (st1 - sf0) + st0 + return AnglesTransform_Apply(t0, st1 - sf0) + st0; +} diff --git a/data/qcsrc/warpzonelib/anglestransform.qh b/data/qcsrc/warpzonelib/anglestransform.qh index 714c4a382..363f75e50 100644 --- a/data/qcsrc/warpzonelib/anglestransform.qh +++ b/data/qcsrc/warpzonelib/anglestransform.qh @@ -21,3 +21,7 @@ vector AnglesTransform_Normalize(vector t, float minimize_roll); // makes sure a vector AnglesTransform_ApplyToAngles(vector transform, vector v); vector AnglesTransform_ApplyToVAngles(vector transform, vector v); + +// transformed = (original - preshift) * transform + postshift +vector AnglesTransform_Multiply_GetPreShift(vector sf0, vector t0, vector st0, vector sf1, vector t1, vector st1); +vector AnglesTransform_Multiply_GetPostShift(vector sf0, vector t0, vector st0, vector sf1, vector t1, vector st1); diff --git a/data/qcsrc/warpzonelib/common.qc b/data/qcsrc/warpzonelib/common.qc index 13587ede3..89599ea8f 100644 --- a/data/qcsrc/warpzonelib/common.qc +++ b/data/qcsrc/warpzonelib/common.qc @@ -298,6 +298,7 @@ void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, vector org_new; vector org0_new; vector shift0_new, transform_new, shift1_new; + vector transform_second; vector p; entity e, e0; entity wz; @@ -345,9 +346,11 @@ void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, org0_new = WarpZone_TransformOrigin(e, org); traceline(e.warpzone_targetorigin, org0_new, MOVE_NOMONSTERS, e); org_new = trace_endpos; - transform_new = AnglesTransform_Multiply(transform, AnglesTransform_Invert(e.warpzone_transform)); - shift0_new = e.warpzone_targetorigin; - shift1_new = AnglesTransform_Apply(transform, e.warpzone_origin - shift0) + shift1; + + transform_second = AnglesTransform_Invert(e.warpzone_transform); + transform_new = AnglesTransform_Multiply(transform, transform_second); + shift0_new = AnglesTransform_Multiply_GetPreShift(shift0, transform, shift1, e.warpzone_targetorigin, transform_second, e.warpzone_origin); + shift1_new = AnglesTransform_Multiply_GetPostShift(shift0, transform, shift1, e.warpzone_targetorigin, transform_second, e.warpzone_origin); WarpZone_FindRadius_Recurse( org_new, bound(0, rad - vlen(org_new - org0_new), rad - 8), @@ -367,3 +370,83 @@ entity WarpZone_FindRadius(vector org, float rad, float needlineofsight) e.WarpZone_findradius_hit = 0; return e0; } + +void WarpZone_Accumulator_Clear(entity acc) +{ + acc.warpzone_transform = '0 0 0'; + acc.warpzone_origin = '0 0 0'; + acc.warpzone_targetorigin = '0 0 0'; +} +void WarpZone_Accumulator_Add(entity acc, entity wz) +{ + vector sf, t, st; + sf = AnglesTransform_Multiply_GetPreShift(wz.warpzone_origin, wz.warpzone_transform, wz.warpzone_targetorigin, acc.warpzone_origin, acc.warpzone_transform, acc.warpzone_targetorigin); + t = AnglesTransform_Multiply(wz.warpzone_transform, acc.warpzone_transform); + st = AnglesTransform_Multiply_GetPostShift(wz.warpzone_origin, wz.warpzone_transform, wz.warpzone_targetorigin, acc.warpzone_origin, acc.warpzone_transform, acc.warpzone_targetorigin); + acc.warpzone_origin = sf; + acc.warpzone_transform = t; + acc.warpzone_targetorigin = st; +} + +.entity WarpZone_refsys; +void WarpZone_RefSys_GC() +{ + // garbage collect unused reference systems + self.nextthink = time + 1; + if(self.owner.WarpZone_refsys != self) + remove(self); +} +void WarpZone_RefSys_Add(entity me, entity wz) +{ + if(me.WarpZone_refsys.owner != me) + { + me.WarpZone_refsys = spawn(); + me.WarpZone_refsys.classname = "warpzone_refsys"; + me.WarpZone_refsys.owner = me; + me.WarpZone_refsys.think = WarpZone_RefSys_GC; + me.WarpZone_refsys.nextthink = time + 1; + WarpZone_Accumulator_Clear(me.WarpZone_refsys); + } + if(wz) + WarpZone_Accumulator_Add(me.WarpZone_refsys, wz); +} +vector WarpZone_RefSys_TransformOrigin(entity from, entity to, vector org) +{ + if(from.WarpZone_refsys) + org = WarpZone_UnTransformOrigin(from.WarpZone_refsys, org); + if(to.WarpZone_refsys) + org = WarpZone_TransformOrigin(to.WarpZone_refsys, org); + return org; +} +vector WarpZone_RefSys_TransformVelocity(entity from, entity to, vector vel) +{ + if(from.WarpZone_refsys) + vel = WarpZone_UnTransformVelocity(from.WarpZone_refsys, vel); + if(to.WarpZone_refsys) + vel = WarpZone_TransformVelocity(to.WarpZone_refsys, vel); + return vel; +} +vector WarpZone_RefSys_TransformAngles(entity from, entity to, vector ang) +{ + if(from.WarpZone_refsys) + ang = WarpZone_UnTransformAngles(from.WarpZone_refsys, ang); + if(to.WarpZone_refsys) + ang = WarpZone_TransformAngles(to.WarpZone_refsys, ang); + return ang; +} +vector WarpZone_RefSys_TransformVAngles(entity from, entity to, vector ang) +{ + if(from.WarpZone_refsys) + ang = WarpZone_UnTransformVAngles(from.WarpZone_refsys, ang); + if(to.WarpZone_refsys) + ang = WarpZone_TransformVAngles(to.WarpZone_refsys, ang); + return ang; +} +entity WarpZone_RefSys_SpawnSameRefSys(entity me) +{ + entity e; + e = spawn(); + if(me.WarpZone_refsys) + WarpZone_RefSys_Add(e, me.WarpZone_refsys); + return e; +} diff --git a/data/qcsrc/warpzonelib/common.qh b/data/qcsrc/warpzonelib/common.qh index 53e18714a..622bab927 100644 --- a/data/qcsrc/warpzonelib/common.qh +++ b/data/qcsrc/warpzonelib/common.qh @@ -45,3 +45,11 @@ vector WarpZone_UnTransformOrigin(entity wz, vector v); vector WarpZone_UnTransformVelocity(entity wz, vector v); vector WarpZone_UnTransformAngles(entity wz, vector v); vector WarpZone_UnTransformVAngles(entity wz, vector v); + +// reference systems (chained warpzone transforms) +void WarpZone_RefSys_Add(entity me, entity wz); +vector WarpZone_RefSys_TransformOrigin(entity from, entity to, vector org); +vector WarpZone_RefSys_TransformVelocity(entity from, entity to, vector vel); +vector WarpZone_RefSys_TransformAngles(entity from, entity to, vector ang); +vector WarpZone_RefSys_TransformVAngles(entity from, entity to, vector ang); +entity WarpZone_RefSys_SpawnSameRefSys(entity me); diff --git a/data/qcsrc/warpzonelib/server.qc b/data/qcsrc/warpzonelib/server.qc index cb29d6d74..2bab197d8 100644 --- a/data/qcsrc/warpzonelib/server.qc +++ b/data/qcsrc/warpzonelib/server.qc @@ -86,7 +86,8 @@ float WarpZone_Teleport(entity player) //print(sprintf("warpzone: %f %f %f -> %f %f %f\n", o0_x, o0_y, o0_z, o1_x, o1_y, o1_z)); //o1 = trace_endpos; - WarpZone_TeleportPlayer(self, other, o1 - player.view_ofs, a1, v1); + WarpZone_RefSys_Add(player, self); + WarpZone_TeleportPlayer(self, player, o1 - player.view_ofs, a1, v1); WarpZone_StoreProjectileData(player); player.warpzone_teleport_time = time; @@ -237,6 +238,7 @@ float WarpZone_CheckProjectileImpact() v0 = self.velocity; a0 = self.angles; + // FIXME this code assumes the trace goes through just one warpzone. // this approach transports the projectile at its full speed, but does // not properly retain the projectile trail (but we can't retain it // easily anyway without delaying the projectile by two frames, so who @@ -263,6 +265,7 @@ float WarpZone_CheckProjectileImpact() return FALSE; } } + WarpZone_RefSys_Add(self, wz); WarpZone_StoreProjectileData(self); self.warpzone_teleport_time = time; -- 2.39.2