r4307 - in trunk/data/qcsrc: client common server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Wed Sep 3 08:20:01 EDT 2008


Author: div0
Date: 2008-09-03 08:20:00 -0400 (Wed, 03 Sep 2008)
New Revision: 4307

Modified:
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/View.qc
   trunk/data/qcsrc/common/constants.qh
   trunk/data/qcsrc/server/portals.qc
   trunk/data/qcsrc/server/w_porto.qc
Log:
Porto (untested): secondary fire button "holds" the shooting angles, so you can turn the view and look where the portals go


Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2008-09-03 08:22:25 UTC (rev 4306)
+++ trunk/data/qcsrc/client/Main.qc	2008-09-03 12:20:00 UTC (rev 4307)
@@ -766,6 +766,7 @@
 // CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
 // You must ALWAYS first acquire the temporary ID, which is sent as a byte.
 // Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
+void Net_ReadHoldAngles();
 float CSQC_Parse_TempEntity()
 {
 	local float bHandled;
@@ -817,6 +818,10 @@
 			Net_ReadZoomNotify();
 			bHandled = true;
 			break;
+		case TE_CSQC_HOLDANGLES:
+			Net_ReadHoldAngles();
+			bHandled = true;
+			break;
 		default:
 			// No special logic for this temporary entity; return 0 so the engine can handle it
 			bHandled = false;

Modified: trunk/data/qcsrc/client/View.qc
===================================================================
--- trunk/data/qcsrc/client/View.qc	2008-09-03 08:22:25 UTC (rev 4306)
+++ trunk/data/qcsrc/client/View.qc	2008-09-03 12:20:00 UTC (rev 4307)
@@ -1,3 +1,21 @@
+float angles_held_status[24];
+vector angles_held[24];
+void Net_ReadHoldAngles()
+{
+	float wpn;
+	vector v;
+	wpn = ReadByte();
+	--wpn;
+	angles_held_status[wpn] = ReadByte();
+	if(angles_held_status[wpn])
+	{
+		v_x = ReadCoord();
+		v_y = ReadCoord();
+		v_z = 0;
+		angles_held[wpn] = v;
+	}
+}
+
 entity porto;
 void Porto_Draw()
 {
@@ -7,6 +25,13 @@
 		return;
 
 	dir = view_forward;
+
+	if(angles_held_status[WEP_PORTO-1])
+	{
+		makevectors(angles_held[WEP_PORTO-1]);
+		dir = v_forward;
+	}
+
 	v0 = view_origin;
 	traceline(v0, v0 + 65536 * dir, TRUE, world);
 	if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)

Modified: trunk/data/qcsrc/common/constants.qh
===================================================================
--- trunk/data/qcsrc/common/constants.qh	2008-09-03 08:22:25 UTC (rev 4306)
+++ trunk/data/qcsrc/common/constants.qh	2008-09-03 12:20:00 UTC (rev 4307)
@@ -201,6 +201,7 @@
 const float TE_CSQC_SPECTATING = 111;
 const float TE_CSQC_SPAWN = 112;
 const float TE_CSQC_ZOOMNOTIFY = 113;
+const float TE_CSQC_HOLDANGLES = 114;
 
 const float STAT_KH_KEYS = 32;
 const float STAT_CTF_STATE = 33;

Modified: trunk/data/qcsrc/server/portals.qc
===================================================================
--- trunk/data/qcsrc/server/portals.qc	2008-09-03 08:22:25 UTC (rev 4306)
+++ trunk/data/qcsrc/server/portals.qc	2008-09-03 12:20:00 UTC (rev 4307)
@@ -175,6 +175,7 @@
 	portal.touch = SUB_Null;
 	portal.effects = 0;
 	portal.colormod = '1 1 1';
+	portal.nextthink = 0;
 }
 
 void Portal_MakeInPortal(entity portal)
@@ -183,6 +184,7 @@
 	portal.touch = Portal_Touch;
 	portal.effects = EF_RED;
 	portal.colormod = '1 0 0';
+	portal.nextthink = time;
 }
 
 void Portal_MakeOutPortal(entity portal)
@@ -191,6 +193,7 @@
 	portal.touch = SUB_Null;
 	portal.effects = EF_STARDUST;
 	portal.colormod = '0 0 1';
+	portal.nextthink = 0;
 }
 
 void Portal_Disconnect(entity teleporter, entity destination)
@@ -214,84 +217,116 @@
 	destination.portal_wants_to_vanish = 0;
 }
 
-void Portal_Think()
+void Portal_Remove(entity portal)
 {
-	entity e, o;
-	float m;
+	entity e;
+	e = portal.enemy;
 
-	if(self.solid == SOLID_TRIGGER)
+	if(e)
 	{
-		m = self.modelindex;
-		o = self.owner;
-		self.solid = SOLID_BBOX;
-		self.owner = world;
-		self.modelindex = 0;
-		FOR_EACH_PLAYER(e)
-		{
-			if(time < self.portal_activatetime)
-				if(e == o)
-					continue;
-			// if e would hit the portal in a frame...
-			// already teleport him
-			tracebox(e.origin, e.mins, e.maxs, e.origin + e.velocity * 3 * frametime, MOVE_NORMAL, e);
-			if(trace_ent == self)
-				Portal_TeleportPlayer(self, e);
-		}
-		self.solid = SOLID_TRIGGER;
-		self.owner = o;
-		self.modelindex = m;
+		Portal_Disconnect(portal, e);
+		Portal_Remove(e);
 	}
 
-	self.nextthink = time;
+	if(portal == portal.owner.portal_in)
+		portal.owner.portal_in = world;
+	if(portal == portal.owner.portal_out)
+		portal.owner.portal_out = world;
+	portal.owner = world;
 
-	if(time < self.fade_time)
-		return;
+	// makes the portal vanish
+	Portal_MakeBrokenPortal(portal);
+	SUB_SetFade(portal, time, 0.5);
+}
 
-	self.portal_wants_to_vanish = 1;
+void Portal_Think()
+{
+	entity e, o;
 
-	if(self.enemy)
-		if(!self.enemy.portal_wants_to_vanish)
-			return;
+	if(self.solid != SOLID_TRIGGER)
+		error("Portal_Think called for a portal that should not be thinking");
 
-	SUB_SetFade(self, time + 1, 1);
-	if(self.enemy)
+	o = self.owner;
+	self.solid = SOLID_BBOX;
+	self.owner = world;
+	FOR_EACH_PLAYER(e)
 	{
-		SUB_SetFade(self.enemy, time + 1, 1);
-		Portal_Disconnect(self, self.enemy);
+		if(time < self.portal_activatetime)
+			if(e == o)
+				continue;
+		// if e would hit the portal in a frame...
+		// already teleport him
+		tracebox(e.origin, e.mins, e.maxs, e.origin + e.velocity * 3 * frametime, MOVE_NORMAL, e);
+		if(trace_ent == self)
+			Portal_TeleportPlayer(self, e);
 	}
-	if(self.owner.portal_in == self)
-	{
-		self.owner.portal_in = world;
-		print("fixed in-portal ownership\n");
-	}
-	if(self.owner.portal_out == self)
-	{
-		self.owner.portal_out = world;
-		print("fixed out-portal ownership\n");
-	}
+	self.solid = SOLID_TRIGGER;
+	self.owner = o;
+
+	self.nextthink = time;
+
+	if(time > self.fade_time)
+		Portal_Remove(self);
 }
 
-void Portal_RequestVanish(entity portal)
+
+// cleanup:
+//   when creating in-portal:
+//     disconnect
+//     clear existing out-portal
+//     make existing in-portal an out-portal and connect
+//     set as in-portal
+//   when creating out-portal:
+//     disconnect
+//     clear existing out-portal
+//     set as out-portal
+//   when player dies:
+//     disconnect portals
+//     clear both portals
+//   after timeout of in-portal:
+//     disconnect portals
+//     clear both portals
+//   TODO: ensure only one portal shot at once
+float Portal_SetInPortal(entity own, entity portal)
 {
-	entity oldself;
-	oldself = self;
-	self = portal;
-	if(self.enemy)
-	{
-		self.enemy.portal_wants_to_vanish = 1;
-		self.enemy.fade_time = time;
-	}
-	self.fade_time = time;
-	Portal_Think();
-	self = oldself;
+	if(own.portal_out)
+		Portal_Remove(own.portal_out);
+	if(own.portal_in)
+		own.portal_out = own.portal_in;
+	own.portal_in = portal;
+	if(own.portal_out)
+		Portal_Connect(own.portal_in, own.portal_out);
+	return 1;
 }
-
-entity Portal_Spawn(entity own, vector org, vector ang)
+float Portal_SetOutPortal(entity own, entity portal)
 {
+	if(!own.portal_in)
+		return 0;
+	if(own.portal_out)
+		Portal_Remove(own.portal_out);
+	own.portal_out = portal;
+	Portal_Connect(own.portal_in, own.portal_out);
+	return 1;
+}
+void Portal_ClearAll(entity own)
+{
+	if(own.portal_in)
+		Portal_Remove(own.portal_in);
+	if(own.portal_out)
+		Portal_Remove(own.portal_out);
+}
+float Portal_VerifyPortalAtTrace(vector ang)
+{
+	if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+		return 0;
 	fixedmakevectors(ang);
-	if(!CheckWireframeBox(org - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 16 * v_forward))
-		return world;
+	if(!CheckWireframeBox(trace_endpos - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 16 * v_forward))
+		return 0;
+	return 1;
+}
 
+entity Portal_Spawn(entity own, vector org, vector ang)
+{
 	entity portal;
 	portal = spawn();
 	portal.classname = "portal";
@@ -319,8 +354,8 @@
 
 float Portal_SpawnInPortalAtTrace(entity own, vector dir, float portal_id_val)
 {
-	if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-		return 0;
+	entity portal;
+	vector ang;
 
 	if(trace_ent.classname == "player")
 	{
@@ -329,85 +364,46 @@
 		trace_plane_normal = '0 0 1';
 	}
 
-	if(own.portal_in)
+	if(!Portal_VerifyPortalAtTrace(dir))
 	{
-		if(own.portal_out)
-		{
-			Portal_Disconnect(own.portal_in, own.portal_out);
-			Portal_RequestVanish(own.portal_out);
-		}
-		own.portal_out = own.portal_in;
-		own.portal_in = world;
-		own.portal_out.portal_id = portal_id_val;
-	}
-	else if(own.portal_out)
-	{
-		print("this DID happen, no idea why (1)\n");
-		Portal_RequestVanish(own.portal_out);
-		own.portal_out = world;
-	}
-		
-	own.portal_in = Portal_Spawn(own, trace_endpos + trace_plane_normal, fixedvectoangles2(trace_plane_normal, dir));
-	if(!own.portal_in)
-	{
-		if(own.portal_out)
-		{
-			Portal_RequestVanish(own.portal_out);
-			own.portal_out = world;
-		}
+		// cannot create a portal here
+		// clear all to make sure
+		Portal_ClearAll(own);
 		return 0;
 	}
-	own.portal_in.portal_id = portal_id_val;
 
-	if(own.portal_out)
-		Portal_Connect(own.portal_in, own.portal_out);
+	ang = fixedvectoangles2(trace_plane_normal, dir);
+	portal = Portal_Spawn(own, trace_endpos, ang);
+	Portal_SetInPortal(own, portal);
 
 	return 1;
 }
 
 float Portal_SpawnOutPortalAtTrace(entity own, vector dir, float portal_id_val)
 {
-	if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-	{
-		if(own.portal_in.portal_id == portal_id_val)
-		{
-			Portal_RequestVanish(own.portal_in);
-			own.portal_in = world;
-		}
-		return 0;
-	}
+	entity portal;
+	vector ang;
 
 	if(trace_ent.classname == "player")
 	{
 		print("hit a player, adjusting...\n");
 		trace_endpos = trace_ent.origin + '0 0 1' * PL_MIN_z;
 		trace_plane_normal = '0 0 1';
-		dir = -1 * dir; // fix orientation
 	}
+	else
+		dir = -1 * dir; // invert the sense of the second portal
 
-	if(!own.portal_in)
-		return 0; // sorry
-
-	if(own.portal_in.portal_id != portal_id_val)
-		return 0; // we need MATCHING portals
-
-	if(own.portal_out)
+	if(!Portal_VerifyPortalAtTrace(dir))
 	{
-		Portal_Disconnect(own.portal_in, own.portal_out);
-		Portal_RequestVanish(own.portal_out);
-		own.portal_out = world;
-	}
-		
-	own.portal_out = Portal_Spawn(own, trace_endpos + trace_plane_normal, fixedvectoangles2(trace_plane_normal, -1 * dir));
-	if(!own.portal_out)
-	{
-		Portal_RequestVanish(own.portal_in);
-		own.portal_in = world;
+		// cannot create a portal here
+		// clear all to make sure
+		Portal_ClearAll(own);
 		return 0;
 	}
-	own.portal_out.portal_id = portal_id_val;
 
-	Portal_Connect(own.portal_in, own.portal_out);
+	ang = fixedvectoangles2(trace_plane_normal, dir);
+	portal = Portal_Spawn(own, trace_endpos, ang);
+	Portal_SetOutPortal(own, portal);
 
 	return 1;
 }

Modified: trunk/data/qcsrc/server/w_porto.qc
===================================================================
--- trunk/data/qcsrc/server/w_porto.qc	2008-09-03 08:22:25 UTC (rev 4306)
+++ trunk/data/qcsrc/server/w_porto.qc	2008-09-03 12:20:00 UTC (rev 4307)
@@ -1,26 +1,29 @@
 .float porto_grenade_id;
+.vector porto_v_angle; // holds "held" view angles
+.float porto_v_angle_held;
 
 void W_Porto_Explode (void)
 {
+	self.owner.porto_grenade_id = 0;
 	remove(self);
 }
 
 void W_Porto_Touch1 (void)
 {
-	if(self.porto_grenade_id == 0)
+	if(self.owner.playerid != self.playerid)
 	{
-		self.porto_grenade_id = time;
+		remove(self);
+	}
+	else if(self.cnt == 0)
+	{
+		self.cnt = 1;
 		if(!Portal_SpawnInPortalAtTrace(self.owner, self.velocity, self.porto_grenade_id))
-		{
-			self.porto_grenade_id = 0;
-			remove(self);
-		}
+			W_Porto_Explode();
 	}
 	else
 	{
 		Portal_SpawnOutPortalAtTrace(self.owner, self.velocity, self.porto_grenade_id);
-		self.porto_grenade_id = 0;
-		remove(self);
+		W_Porto_Explode();
 	}
 }
 
@@ -55,11 +58,8 @@
 
 	gren.angles = vectoangles (gren.velocity);
 	gren.flags = FL_PROJECTILE;
-}
 
-void W_Porto_Attack2 (void)
-{
-	// nothing yet (maybe find the last one and detonate it?)
+	self.porto_grenade_id = gren.porto_grenade_id = time;
 }
 
 void spawnfunc_weapon_porto (void)
@@ -69,6 +69,8 @@
 
 float w_porto(float req)
 {
+	vector v_angle_save;
+
 	if (req == WR_AIM)
 	{
 		self.BUTTON_ATCK = FALSE;
@@ -78,12 +80,48 @@
 	}
 	else if (req == WR_THINK)
 	{
+		if(self.porto_v_angle_held)
+		{
+			if(!self.BUTTON_ATCK2)
+			{
+				msg_entity = self;
+				WRITESPECTATABLE_MSG_ONE({
+					WriteByte(MSG_ONE, SVC_TEMPENTITY);
+					WriteByte(MSG_ONE, TE_CSQC_HOLDANGLES);
+					WriteByte(MSG_ONE, WEP_PORTO);
+					WriteByte(MSG_ONE, 0);
+				});
+				self.porto_v_angle_held = 0;
+			}
+		}
+		else
+		{
+			if(self.BUTTON_ATCK2)
+			{
+				self.porto_v_angle = self.v_angle;
+				msg_entity = self;
+				WRITESPECTATABLE_MSG_ONE({
+					WriteByte(MSG_ONE, SVC_TEMPENTITY);
+					WriteByte(MSG_ONE, TE_CSQC_HOLDANGLES);
+					WriteByte(MSG_ONE, WEP_PORTO);
+					WriteByte(MSG_ONE, 1);
+					WriteCoord(MSG_ONE, self.v_angle_x);
+					WriteCoord(MSG_ONE, self.v_angle_y);
+				});
+				self.porto_v_angle_held = 1;
+			}
+		}
+		v_angle_save = self.v_angle;
+		if(self.porto_v_angle_held)
+			self.v_angle = self.porto_v_angle;
 		if (self.BUTTON_ATCK)
+		if (!self.porto_grenade_id)
 		if (weapon_prepareattack(0, cvar("g_balance_porto_primary_refire")))
 		{
 			W_Porto_Attack();
 			weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_porto_primary_animtime"), w_ready);
 		}
+		self.v_angle = v_angle_save;
 	}
 	else if (req == WR_PRECACHE)
 	{




More information about the nexuiz-commits mailing list