From 56e92d7ca743ccbfdee61d85d0dba040848cca06 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Tue, 9 Nov 2010 15:11:50 +0100 Subject: [PATCH] add a helper W_Crylink_LinkJoin to be used by tZork's balance in the future --- qcsrc/server/w_crylink.qc | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/qcsrc/server/w_crylink.qc b/qcsrc/server/w_crylink.qc index 86306e5fa3..1a05c8a4a2 100644 --- a/qcsrc/server/w_crylink.qc +++ b/qcsrc/server/w_crylink.qc @@ -20,6 +20,82 @@ void W_Crylink_LinkExplode (entity e, entity e2) remove (e); } +// adjust towards center +// returns the origin where they will meet... and the time till the meeting is +// stored in w_crylink_linkjoin_time. +// could possibly network this origin and time, and display a special particle +// effect when projectiles meet there :P +float w_crylink_linkjoin_time; +vector W_Crylink_LinkJoin(entity e, float joinspeed) +{ + vector avg_origin, avg_velocity; + vector targ_origin; + float avg_dist, n; + entity p; + + avg_origin = e.origin; + avg_velocity = e.velocity; + n = 1; + for(p = e; (p = p.queuenext) != e; ) + { + avg_origin += p.origin; + avg_velocity += p.velocity; + ++n; + } + avg_origin *= (1.0 / n); + avg_velocity *= (1.0 / n); + + // yes, mathematically we can do this in ONE step, but beware of 32bit floats... + avg_dist = pow(vlen(e.origin - avg_origin), 2); + for(p = e; (p = p.queuenext) != e; ) + avg_dist += pow(vlen(e.origin - avg_origin), 2); + avg_dist *= (1.0 / n); + + w_crylink_linkjoin_time = 0; + if(avg_dist == 0) + return avg_origin; // no change needed + + if(joinspeed == 0) + { + e.velocity = avg_velocity; + UpdateCSQCProjectile(e); + for(p = e; (p = p.queuenext) != e; ) + { + p.velocity = avg_velocity; + UpdateCSQCProjectile(p); + } + } + else + { + w_crylink_linkjoin_time = avg_dist / joinspeed; + targ_origin = avg_origin + w_crylink_linkjoin_time * avg_velocity; + + e.velocity = (targ_origin - e.origin) * (joinspeed / avg_dist); + UpdateCSQCProjectile(e); + for(p = e; (p = p.queuenext) != e; ) + { + p.velocity = (targ_origin - p.origin) * (joinspeed / avg_dist); + UpdateCSQCProjectile(p); + } + + // analysis: + // joinspeed -> +infinity: + // w_crylink_linkjoin_time -> +0 + // targ_origin -> avg_origin + // p->velocity -> HUEG towards center + // joinspeed -> 0: + // w_crylink_linkjoin_time -> +/- infinity + // targ_origin -> avg_velocity * +/- infinity + // p->velocity -> avg_velocity + // joinspeed -> -infinity: + // w_crylink_linkjoin_time -> -0 + // targ_origin -> avg_origin + // p->velocity -> HUEG away from center + } + + return targ_origin; +} + // NO bounce protection, as bounces are limited! void W_Crylink_Touch (void) { -- 2.39.2