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

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Feb 28 14:44:25 EST 2010


Author: div0
Date: 2010-02-28 14:44:25 -0500 (Sun, 28 Feb 2010)
New Revision: 8712

Modified:
   trunk/data/qcsrc/client/hook.qc
   trunk/data/qcsrc/server/g_hook.qc
   trunk/data/qcsrc/server/w_common.qc
   trunk/data/qcsrc/warpzonelib/TODO
   trunk/data/qcsrc/warpzonelib/common.qc
   trunk/data/qcsrc/warpzonelib/common.qh
Log:
hook now working!

Modified: trunk/data/qcsrc/client/hook.qc
===================================================================
--- trunk/data/qcsrc/client/hook.qc	2010-02-28 19:44:20 UTC (rev 8711)
+++ trunk/data/qcsrc/client/hook.qc	2010-02-28 19:44:25 UTC (rev 8712)
@@ -29,6 +29,14 @@
 	R_EndPolygon();
 }
 
+string Draw_GrapplingHook_trace_callback_tex;
+float Draw_GrapplingHook_trace_callback_rnd;
+void Draw_GrapplingHook_trace_callback(vector start, vector hit, vector end)
+{
+	Draw_CylindricLine(hit, start, 8, Draw_GrapplingHook_trace_callback_tex, 0.25, Draw_GrapplingHook_trace_callback_rnd, '1 1 1', 1, DRAWFLAG_NORMAL);
+	Draw_GrapplingHook_trace_callback_rnd += 0.25 * vlen(hit - start) / 8;
+}
+
 void Draw_GrapplingHook()
 {
 	vector a, b;
@@ -71,7 +79,13 @@
 		tex = "particles/hook_green";
 		rgb = '.3 1 .3';
 	}
-	Draw_CylindricLine(b, a, 8, tex, 0.25, random(), '1 1 1', 1, DRAWFLAG_NORMAL);
+
+	WarpZone_trace_callback = Draw_GrapplingHook_trace_callback;
+	Draw_GrapplingHook_trace_callback_tex = tex;
+	Draw_GrapplingHook_trace_callback_rnd = random();
+	WarpZone_TraceLine(a, b, MOVE_NOMONSTERS, world);
+	WarpZone_trace_callback = func_null;
+	Draw_GrapplingHook_trace_callback_tex = string_null;
 }
 
 void Net_GrapplingHook()

Modified: trunk/data/qcsrc/server/g_hook.qc
===================================================================
--- trunk/data/qcsrc/server/g_hook.qc	2010-02-28 19:44:20 UTC (rev 8711)
+++ trunk/data/qcsrc/server/g_hook.qc	2010-02-28 19:44:25 UTC (rev 8712)
@@ -51,8 +51,9 @@
 .float aiment_deadflag;
 void SetMovetypeFollow(entity ent, entity e)
 {
+	// FIXME this may not be warpzone aware
 	ent.movetype = MOVETYPE_FOLLOW; // make the hole follow
-	ent.solid = SOLID_NOT; // MOVETYPE_FOLLOW is always non-solid
+	ent.solid = SOLID_NOT; // MOVETYPE_FOLLOW is always non-solid - this means this cannot be teleported by warpzones any more! Instead, we must notice when our owner gets teleported.
 	ent.aiment = e; // make the hole follow bmodel
 	ent.punchangle = e.angles; // the original angles of bmodel
 	ent.view_ofs = ent.origin - e.origin; // relative origin
@@ -116,7 +117,7 @@
 void GrapplingHookThink()
 {
 	float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
-	vector dir, org, end, v0, dv;
+	vector dir, org, end, v0, dv, v, myorg;
 	if(self.owner.health <= 0 || self.owner.hook != self)	// how did that happen?
 	{														// well, better fix it anyway
 		remove(self);
@@ -127,39 +128,17 @@
 		RemoveGrapplingHook(self.owner);
 		return;
 	}
+	if(self.aiment)
+		WarpZone_RefSys_AddIncrementally(self, self.aiment);
 
 	self.nextthink = time;
 
 	makevectors(self.owner.v_angle);
 	org = self.owner.origin + self.owner.view_ofs + v_forward * hook_shotorigin_x + v_right * hook_shotorigin_y + v_up * hook_shotorigin_z;
+	myorg = WarpZone_RefSys_TransformOrigin(self.owner, self, org);
 
-#if 0
-	tracebox(org, self.mins, self.maxs, self.origin, MOVE_NOMONSTERS, self.owner);
-	// do not hit players with this, as they tend to get in the way just too often
-	// NOTE: this assumes sky brushes cannot get in the way
-	// if they can, assume the map is broken! :P
-	if(trace_fraction < 1 && (!self.aiment || trace_ent != self.aiment))
-	{
-		// 0. stop it
-		if(self.state != 1)
-			GrapplingHook_Stop();
-
-		// 1. detach the hook
-		if(self.aiment)
-			UnsetMovetypeFollow(self);
-
-		// 2. cut it off
-		setorigin(self, trace_endpos);
-
-		// 3. reattach the hook
-		if(trace_ent)
-			if(trace_ent.movetype != MOVETYPE_NONE)
-				SetMovetypeFollow(self, trace_ent);
-	}
-#endif
-
 	if(self.hook_length < 0)
-		self.hook_length = vlen(org - self.origin);
+		self.hook_length = vlen(myorg - self.origin);
 
 	if(self.state == 1)
 	{
@@ -184,13 +163,13 @@
 		// while hanging on the rope, this friction component will help you a
 		// bit to control the rope
 
-		dir = self.origin - org;
+		dir = self.origin - myorg;
 		dist = vlen(dir);
 		dir = normalize(dir);
 
 		if(cvar("g_grappling_hook_tarzan"))
 		{
-			v0 = self.owner.velocity;
+			v = v0 = WarpZone_RefSys_TransformVelocity(self.owner, self, self.owner.velocity);
 
 			// first pull the rope...
 			if(self.owner.hook_state & HOOK_PULLING)
@@ -201,8 +180,8 @@
 				if(newlength < dist - ropestretch) // overstretched?
 				{
 					newlength = dist - ropestretch;
-					if(self.owner.velocity * dir < 0) // only if not already moving in hook direction
-						self.owner.velocity = self.owner.velocity + frametime * dir * rubberforce_overstretch;
+					if(v * dir < 0) // only if not already moving in hook direction
+						v = v + frametime * dir * rubberforce_overstretch;
 				}
 
 				self.hook_length = newlength;
@@ -217,15 +196,15 @@
 			{
 				// then pull the player
 				spd = bound(0, (dist - self.hook_length) / ropestretch, 1);
-				self.owner.velocity = self.owner.velocity * (1 - frametime * ropeairfriction);
-				self.owner.velocity = self.owner.velocity + frametime * dir * spd * rubberforce;
+				v = v * (1 - frametime * ropeairfriction);
+				v = v + frametime * dir * spd * rubberforce;
 
-				dv = ((self.owner.velocity - v0) * dir) * dir;
+				dv = ((v - v0) * dir) * dir;
 				if(cvar("g_grappling_hook_tarzan") >= 2)
 				{
 					if(self.aiment.movetype == MOVETYPE_WALK)
 					{
-						self.owner.velocity = self.owner.velocity - dv * 0.5;
+						v = v - dv * 0.5;
 						self.aiment.velocity = self.aiment.velocity - dv * 0.5;
 						self.aiment.flags &~= FL_ONGROUND;
 						self.aiment.pusher = self.owner;
@@ -235,11 +214,13 @@
 
 				self.owner.flags &~= FL_ONGROUND;
 			}
+
+			self.owner.velocity = WarpZone_RefSys_TransformVelocity(self, self.owner, v);
 		}
 		else
 		{
 			end = self.origin - dir*50;
-			dist = vlen(end - org);
+			dist = vlen(end - myorg);
 			if(dist < 200)
 				spd = dist * (pullspeed / 200);
 			else
@@ -254,7 +235,7 @@
 	}
 
 	makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0');
-	te_beam(self.owner, self.origin + v_forward * (-9), org);
+	te_beam(self.owner, WarpZone_RefSys_TransformOrigin(self, self.owner, self.origin) + v_forward * (-9), org);
 }
 
 void GrapplingHookTouch (void)
@@ -266,30 +247,16 @@
 		RemoveGrapplingHook(self.owner);
 		return;
 	}
+	PROJECTILE_TOUCH;
 
-	if(other == world)
-	{
-		vector tic;
-		tic = self.velocity * sys_frametime;
-		tic = tic + normalize(tic) * vlen(self.maxs - self.mins);
-		traceline(self.origin - tic, self.origin + tic, MOVE_NORMAL, self);
-		if(trace_fraction >= 1)
-		{
-			dprint("Odd... did not hit...?\n");
-		}
-		else if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-		{
-			dprint("Detected and prevented the sky-grapple bug.\n");
-			RemoveGrapplingHook(self.owner);
-			return;
-		}
-	}
-
 	GrapplingHook_Stop();
 
 	if(other)
 		if(other.movetype != MOVETYPE_NONE)
+		{
 			SetMovetypeFollow(self, other);
+			WarpZone_RefSys_BeginAddingIncrementally(self, self.aiment);
+		}
 
 	//self.owner.disableclientprediction = TRUE;
 }
@@ -326,7 +293,7 @@
 	org = self.origin + self.view_ofs + v_forward * hook_shotorigin_x + v_right * hook_shotorigin_y + v_up * hook_shotorigin_z;
 	pointparticles(particleeffectnum("grapple_muzzleflash"), org, '0 0 0', 1);
 
-	missile = spawn ();
+	missile = WarpZone_RefSys_SpawnSameRefSys(self);
 	missile.owner = self;
 	self.hook = missile;
 	missile.classname = "grapplinghook";

Modified: trunk/data/qcsrc/server/w_common.qc
===================================================================
--- trunk/data/qcsrc/server/w_common.qc	2010-02-28 19:44:20 UTC (rev 8711)
+++ trunk/data/qcsrc/server/w_common.qc	2010-02-28 19:44:25 UTC (rev 8712)
@@ -324,7 +324,7 @@
 
 entity fireBallisticBullet_trace_callback_ent;
 float fireBallisticBullet_trace_callback_eff;
-void fireBallisticBullet_trace_callback()
+void fireBallisticBullet_trace_callback(vector start, vector hit, vector end)
 {
 	if(vlen(trace_endpos - fireBallisticBullet_trace_callback_ent.origin) > 16)
 		zcurveparticles_from_tracetoss(fireBallisticBullet_trace_callback_eff, fireBallisticBullet_trace_callback_ent.origin, trace_endpos, fireBallisticBullet_trace_callback_ent.velocity);

Modified: trunk/data/qcsrc/warpzonelib/TODO
===================================================================
--- trunk/data/qcsrc/warpzonelib/TODO	2010-02-28 19:44:20 UTC (rev 8711)
+++ trunk/data/qcsrc/warpzonelib/TODO	2010-02-28 19:44:25 UTC (rev 8712)
@@ -17,6 +17,6 @@
 - minstanex: YES
 - rifle: YES
 - fireball: YES (BFG effect cannot work through warpzones by design, so it's not available through warpzones)
+- hook: YES
 
-- 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:44:20 UTC (rev 8711)
+++ trunk/data/qcsrc/warpzonelib/common.qc	2010-02-28 19:44:25 UTC (rev 8712)
@@ -108,7 +108,7 @@
 	{
 		tracebox(org, mi, ma, end, nomonsters, forent);
 		if(WarpZone_trace_callback)
-			WarpZone_trace_callback();
+			WarpZone_trace_callback(org, trace_endpos, end);
 		if(sol < 0)
 			sol = trace_startsolid;
 		if(trace_fraction >= 1)
@@ -156,7 +156,7 @@
 	{
 		tracebox(org, mi, ma, end, nomonsters, forent);
 		if(WarpZone_trace_callback)
-			WarpZone_trace_callback();
+			WarpZone_trace_callback(org, trace_endpos, end);
 		if(sol < 0)
 			sol = trace_startsolid;
 		if(trace_fraction >= 1)
@@ -208,7 +208,7 @@
 	{
 		tracetoss(e, forent);
 		if(WarpZone_trace_callback)
-			WarpZone_trace_callback();
+			WarpZone_trace_callback(e.origin, trace_endpos, trace_endpos);
 		e.origin = trace_endpos;
 		dt = vlen(e.origin - o0) / vlen(e.velocity);
 		WarpZone_tracetoss_time += dt;
@@ -430,6 +430,14 @@
 	acc.warpzone_transform = '0 0 0';
 	acc.warpzone_shift = '0 0 0';
 }
+void WarpZone_Accumulator_AddTransform(entity acc, vector t, vector s)
+{
+	vector t, st;
+	t = AnglesTransform_Multiply(t, acc.warpzone_transform);
+	st = AnglesTransform_Multiply_GetPostShift(t, s, acc.warpzone_transform, acc.warpzone_shift);
+	acc.warpzone_transform = t;
+	acc.warpzone_shift = st;
+}
 void WarpZone_Accumulator_Add(entity acc, entity wz)
 {
 	vector t, st;
@@ -461,6 +469,35 @@
 	if(wz)
 		WarpZone_Accumulator_Add(me.WarpZone_refsys, wz);
 }
+.vector WarpZone_refsys_incremental_shift;
+.vector WarpZone_refsys_incremental_transform;
+void WarpZone_RefSys_AddIncrementally(entity me, entity ref)
+{
+	vector t, s;
+	if(me.WarpZone_refsys_incremental_transform == ref.WarpZone_refsys.warpzone_transform)
+	if(me.WarpZone_refsys_incremental_shift == ref.WarpZone_refsys.warpzone_shift)
+		return;
+	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);
+	}
+	t = AnglesTransform_Invert(me.WarpZone_refsys_incremental_transform);
+	s = AnglesTransform_PrePostShift_GetPostShift(me.WarpZone_refsys_incremental_shift, t, '0 0 0');
+	WarpZone_Accumulator_AddTransform(me.WarpZone_refsys, t, s);
+	WarpZone_Accumulator_Add(me.WarpZone_refsys, ref);
+	me.WarpZone_refsys_incremental_shift = ref.WarpZone_refsys.warpzone_shift;
+	me.WarpZone_refsys_incremental_transform = ref.WarpZone_refsys.warpzone_transform;
+}
+void WarpZone_RefSys_BeginAddingIncrementally(entity me, entity ref)
+{
+	me.WarpZone_refsys_incremental_shift = ref.WarpZone_refsys.warpzone_shift;
+	me.WarpZone_refsys_incremental_transform = ref.WarpZone_refsys.warpzone_transform;
+}
 vector WarpZone_RefSys_TransformOrigin(entity from, entity to, vector org)
 {
 	if(from.WarpZone_refsys)
@@ -498,6 +535,14 @@
 	entity e;
 	e = spawn();
 	if(me.WarpZone_refsys)
-		WarpZone_RefSys_Add(e, me.WarpZone_refsys);
+	{
+		e.WarpZone_refsys = spawn();
+		e.WarpZone_refsys.classname = "warpzone_refsys";
+		e.WarpZone_refsys.owner = e;
+		e.WarpZone_refsys.think = WarpZone_RefSys_GC;
+		e.WarpZone_refsys.nextthink = time + 1;
+		e.WarpZone_refsys.warpzone_shift = me.WarpZone_refsys.warpzone_shift;
+		e.WarpZone_refsys.warpzone_transform = me.WarpZone_refsys.warpzone_transform;
+	}
 	return e;
 }

Modified: trunk/data/qcsrc/warpzonelib/common.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/common.qh	2010-02-28 19:44:20 UTC (rev 8711)
+++ trunk/data/qcsrc/warpzonelib/common.qh	2010-02-28 19:44:25 UTC (rev 8712)
@@ -17,7 +17,8 @@
 void WarpZone_MakeAllSolid();
 void WarpZone_MakeAllOther();
 
-var void(void) WarpZone_trace_callback; // called after every trace
+var void(vector start, vector hit, vector end) WarpZone_trace_callback; // called after every trace
+vector WarpZone_trace_startpos; // start pos of the current segment (useful for the callback)
 vector WarpZone_trace_angles; // total angles accumulator
 vector WarpZone_trace_v_angle; // total v_angle accumulator
 vector WarpZone_trace_velocity; // total velocity
@@ -50,6 +51,8 @@
 
 // reference systems (chained warpzone transforms)
 void WarpZone_RefSys_Add(entity me, entity wz);
+void WarpZone_RefSys_AddIncrementally(entity me, entity ref);
+void WarpZone_RefSys_BeginAddingIncrementally(entity me, entity ref);
 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);



More information about the nexuiz-commits mailing list