[nexuiz-commits] r8706 - in trunk/data/qcsrc: server warpzonelib

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Feb 28 14:43:54 EST 2010


Author: div0
Date: 2010-02-28 14:43:54 -0500 (Sun, 28 Feb 2010)
New Revision: 8706

Modified:
   trunk/data/qcsrc/server/g_damage.qc
   trunk/data/qcsrc/warpzonelib/TODO
   trunk/data/qcsrc/warpzonelib/common.qc
   trunk/data/qcsrc/warpzonelib/common.qh
Log:
findradius wrapper - more guns work now

Modified: trunk/data/qcsrc/server/g_damage.qc
===================================================================
--- trunk/data/qcsrc/server/g_damage.qc	2010-02-28 19:43:49 UTC (rev 8705)
+++ trunk/data/qcsrc/server/g_damage.qc	2010-02-28 19:43:54 UTC (rev 8706)
@@ -1084,7 +1084,7 @@
 	stat_damagedone = 0;
 	stat_maxdamage = 0;
 
-	targ = findradius (blastorigin, rad);
+	targ = WarpZone_FindRadius (blastorigin, rad, FALSE);
 	while (targ)
 	{
 		next = targ.chain;
@@ -1093,8 +1093,8 @@
 			{
 				// LordHavoc: measure distance to nearest point on target (not origin)
 				// (this guarentees 100% damage on a touch impact)
-				nearest = NearestPointOnBox(targ, blastorigin);
-				diff = nearest - blastorigin;
+				nearest = targ.WarpZone_findradius_nearest;
+				diff = targ.WarpZone_findradius_dist;
 				// round up a little on the damage to ensure full damage on impacts
 				// and turn the distance into a fraction of the radius
 				power = 1 - ((vlen (diff) - 2) / rad);
@@ -1115,11 +1115,13 @@
 						local float total;
 						local float hitratio;
 						local vector hitloc;
+						local vector myblastorigin;
+						myblastorigin = WarpZone_UnTransformOrigin(targ, blastorigin);
 						center = targ.origin + (targ.mins + targ.maxs) * 0.5;
 						// if it's a player, use the view origin as reference
 						if (targ.classname == "player")
 							center = targ.origin + targ.view_ofs;
-						force = normalize(center - blastorigin);
+						force = normalize(center - myblastorigin);
 						force = force * (finaldmg / coredamage) * forceintensity;
 						// test line of sight to multiple positions on box,
 						// and do damage if any of them hit
@@ -1132,7 +1134,8 @@
 						c = 0;
 						while (c < total)
 						{
-							traceline(blastorigin, nearest, MOVE_NOMONSTERS, inflictor);
+							//traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
+							WarpZone_TraceLine(blastorigin, WarpZone_TransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
 							if (trace_fraction == 1 || trace_ent == targ)
 							{
 								hits = hits + 1;

Modified: trunk/data/qcsrc/warpzonelib/TODO
===================================================================
--- trunk/data/qcsrc/warpzonelib/TODO	2010-02-28 19:43:49 UTC (rev 8705)
+++ trunk/data/qcsrc/warpzonelib/TODO	2010-02-28 19:43:54 UTC (rev 8706)
@@ -6,21 +6,21 @@
 
 Weapon support:
 
+- laser: YES
 - shotgun: YES
 - uzi: YES
+- grenadelauncher: YES
+- crylink: YES
 - nex: YES
+- hagar: YES
 - porto: YES (bwahahahaha)
+- hlac: YES
 - minstanex: YES
 - rifle: YES
-- crylink: YES
 
-- laser: PARTIAL (no radius damage)
-- grenadelauncher: PARTIAL (no radius damage)
-- electro: PARTIAL (no radius damage)
-- hagar: PARTIAL (no radius damage)
-- hlac: PARTIAL (no radius damage)
+- electro: PARTIAL (no combo detonation)
 - fireball: PARTIAL (no radius damage, laser damage)
 
 - rocketlauncher: NO (guiding not working, trail bug)
-- hook: NO (no radius damage, hook beam, pull not working)
-- tuba: NO (no radius damage, sound)
+- hook: NO (hook beam, pull not working)
+- tuba: NO (sound)

Modified: trunk/data/qcsrc/warpzonelib/common.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/common.qc	2010-02-28 19:43:49 UTC (rev 8705)
+++ trunk/data/qcsrc/warpzonelib/common.qc	2010-02-28 19:43:54 UTC (rev 8706)
@@ -94,6 +94,7 @@
 {
 	float frac, sol;
 	vector o0, e0;
+	entity e;
 	vector vf, vr, vu;
 	vf = v_forward;
 	vr = v_right;
@@ -103,6 +104,7 @@
 	e0 = end;
 	sol = -1;
 	frac = 0;
+	e = world;
 	for(;;)
 	{
 		tracebox(org, mi, ma, end, nomonsters, forent);
@@ -121,6 +123,12 @@
 		WarpZone_trace_velocity = WarpZone_TransformVelocity(trace_ent, WarpZone_trace_velocity);
 		WarpZone_trace_angles = WarpZone_TransformAngles(trace_ent, WarpZone_trace_angles);
 		WarpZone_trace_v_angle = WarpZone_TransformVAngles(trace_ent, WarpZone_trace_v_angle);
+		if(trace_ent == e)
+		{
+			dprint("I transformed into the same zone again, wtf, aborting the trace\n");
+			break;
+		}
+		e = trace_ent;
 	}
 	WarpZone_MakeAllOther();
 	trace_startsolid = sol;
@@ -215,7 +223,7 @@
 
 vector WarpZone_TransformOrigin(entity wz, vector v)
 {
-	return wz.enemy.warpzone_origin + AnglesTransform_Apply(wz.warpzone_transform, v - wz.warpzone_origin);
+	return wz.warpzone_targetorigin + AnglesTransform_Apply(wz.warpzone_transform, v - wz.warpzone_origin);
 }
 
 vector WarpZone_TransformVelocity(entity wz, vector v)
@@ -242,3 +250,120 @@
 	ang_z = roll;
 	return ang;
 }
+
+vector WarpZone_UnTransformOrigin(entity wz, vector v)
+{
+	return wz.warpzone_origin + AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v - wz.warpzone_targetorigin);
+}
+
+vector WarpZone_UnTransformVelocity(entity wz, vector v)
+{
+	return AnglesTransform_Apply(AnglesTransform_Invert(wz.warpzone_transform), v);
+}
+
+vector WarpZone_UnTransformAngles(entity wz, vector v)
+{
+	return AnglesTransform_ApplyToAngles(AnglesTransform_Invert(wz.warpzone_transform), v);
+}
+
+vector WarpZone_UnTransformVAngles(entity wz, vector ang)
+{
+	float roll;
+
+	roll = ang_z;
+	ang_z = 0;
+
+	ang = AnglesTransform_ApplyToVAngles(AnglesTransform_Invert(wz.warpzone_transform), ang);
+	ang = AnglesTransform_Normalize(ang, TRUE);
+	ang = AnglesTransform_CancelRoll(ang);
+
+	ang_z = roll;
+	return ang;
+}
+
+vector WarpZoneLib_NearestPointOnBox(vector mi, vector ma, vector org)
+{
+	vector nearest;
+	nearest_x = bound(mi_x, org_x, ma_x);
+	nearest_y = bound(mi_y, org_y, ma_y);
+	nearest_z = bound(mi_z, org_z, ma_z);
+	return nearest;
+}
+
+.float WarpZone_findradius_hit;
+.entity WarpZone_findradius_next;
+void WarpZone_FindRadius_Recurse(vector org, float rad,        vector org0,            vector shift0, vector transform, vector shift1, float needlineofsight)
+//                               blast origin of current search   original blast origin   how to untransform (victim to blast system)
+{
+	vector org_new;
+	vector org0_new;
+	vector shift0_new, transform_new, shift1_new;
+	vector p;
+	entity e, e0;
+	entity wz;
+	if(rad <= 0)
+		return;
+	e0 = findradius(org, rad);
+	wz = world;
+
+	for(e = e0; e; e = e.chain)
+	{
+		p = WarpZoneLib_NearestPointOnBox(e.origin + e.mins, e.origin + e.maxs, org0);
+		if(needlineofsight)
+		{
+			traceline(org, p, MOVE_NOMONSTERS, e);
+			if(trace_fraction < 1)
+				continue;
+		}
+		if(!e.WarpZone_findradius_hit || vlen(e.WarpZone_findradius_dist) > vlen(org0 - p))
+		{
+			e.WarpZone_findradius_nearest = p;
+			e.WarpZone_findradius_dist = org0 - p;
+			e.WarpZone_findradius_findorigin = org;
+			e.WarpZone_findradius_findradius = rad;
+			if(e.classname == "trigger_warpzone")
+			{
+				e.WarpZone_findradius_next = wz;
+				wz = e;
+
+				e.WarpZone_findradius_hit = 1;
+				e.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again
+				e.enemy.WarpZone_findradius_hit = 1;
+			}
+			else
+			{
+				e.warpzone_transform = transform;
+				e.warpzone_origin = shift0;
+				e.warpzone_targetorigin = shift1;
+
+				e.WarpZone_findradius_hit = 1;
+			}
+		}
+	}
+	for(e = wz; e; e = e.WarpZone_findradius_next)
+	{
+		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;
+		WarpZone_FindRadius_Recurse(
+			org_new,
+			bound(0, rad - vlen(org_new - org0_new), rad - 8),
+			org0_new,
+			shift0_new, transform_new, shift1_new,
+			needlineofsight);
+		e.WarpZone_findradius_hit = 0;
+		e.enemy.WarpZone_findradius_hit = 0;
+	}
+}
+entity WarpZone_FindRadius(vector org, float rad, float needlineofsight)
+{
+	entity e0, e;
+	WarpZone_FindRadius_Recurse(org, rad, org, '0 0 0', '0 0 0', '0 0 0', needlineofsight);
+	e0 = findchainfloat(WarpZone_findradius_hit, 1);
+	for(e = e0; e; e = e.chain)
+		e.WarpZone_findradius_hit = 0;
+	return e0;
+}

Modified: trunk/data/qcsrc/warpzonelib/common.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/common.qh	2010-02-28 19:43:49 UTC (rev 8705)
+++ trunk/data/qcsrc/warpzonelib/common.qh	2010-02-28 19:43:54 UTC (rev 8706)
@@ -10,6 +10,7 @@
 float FL_CAMERA = 8192;
 
 float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig);
+vector WarpZoneLib_NearestPointOnBox(vector mi, vector ma, vector org);
 
 entity WarpZone_Find(vector mi, vector ma);
 void WarpZone_MakeAllSolid();
@@ -27,9 +28,20 @@
 void WarpZone_TraceToss(entity e, entity forent);
 void WarpZone_TrailParticles(entity own, float eff, vector org, vector end);
 
+.vector WarpZone_findradius_dist;
+.vector WarpZone_findradius_nearest;
+// also set: warpzone parameters, so WarpZone_TransformOrigin can transform vectors from victim's to blast's system
+.vector WarpZone_findradius_findorigin;
+.float WarpZone_findradius_findradius;
+entity WarpZone_FindRadius(vector org, float radius, float needlineofsight);
+
 float WarpZone_PlaneDist(entity wz, vector v);
 float WarpZone_TargetPlaneDist(entity wz, vector v);
 vector WarpZone_TransformOrigin(entity wz, vector v);
 vector WarpZone_TransformVelocity(entity wz, vector v);
 vector WarpZone_TransformAngles(entity wz, vector v);
 vector WarpZone_TransformVAngles(entity wz, vector v);
+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);



More information about the nexuiz-commits mailing list