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

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Sep 4 05:00:40 EDT 2008


Author: div0
Date: 2008-09-04 05:00:23 -0400 (Thu, 04 Sep 2008)
New Revision: 4325

Modified:
   trunk/data/qcsrc/client/View.qc
   trunk/data/qcsrc/common/util.qc
   trunk/data/qcsrc/common/util.qh
   trunk/data/qcsrc/server/cl_weapons.qc
   trunk/data/qcsrc/server/miscfunctions.qc
   trunk/data/qcsrc/server/portals.qc
   trunk/data/qcsrc/server/w_porto.qc
Log:
fix portal math


Modified: trunk/data/qcsrc/client/View.qc
===================================================================
--- trunk/data/qcsrc/client/View.qc	2008-09-03 19:59:40 UTC (rev 4324)
+++ trunk/data/qcsrc/client/View.qc	2008-09-04 09:00:23 UTC (rev 4325)
@@ -43,7 +43,7 @@
 	ang = vectoangles(trace_plane_normal, dir);
 	ang_x = -ang_x;
 	makevectors(ang);
-	if(!CheckWireframeBox(v1 - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 16 * v_forward))
+	if(!CheckWireframeBox(porto, v1 - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
 		return;
 
 	traceline(v1, v1 + 65536 * dir, TRUE, world);
@@ -54,16 +54,20 @@
 	ang = vectoangles(trace_plane_normal, -1 * dir);
 	ang_x = -ang_x;
 	makevectors(ang);
-	if(!CheckWireframeBox(v2 - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 16 * v_forward))
+	if(!CheckWireframeBox(porto, v2 - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
 		return;
 
 	Draw_CylindricLine(v1, v2, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL);
 }
+float DPCONTENTS_SOLID = 1; // hit a bmodel, not a bounding box
+float DPCONTENTS_BODY = 32; // hit a bounding box, not a bmodel
+float DPCONTENTS_PLAYERCLIP = 256; // blocks player movement
 void Porto_Init()
 {
 	porto = spawn();
 	porto.classname = "porto";
 	porto.draw = Porto_Draw;
+	porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
 }
 
 float drawtime;

Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc	2008-09-03 19:59:40 UTC (rev 4324)
+++ trunk/data/qcsrc/common/util.qc	2008-09-04 09:00:23 UTC (rev 4325)
@@ -616,20 +616,27 @@
 }
 
 #ifndef MENUQC
-float CheckWireframeBox(vector v0, vector dvx, vector dvy, vector dvz)
+float CheckWireframeBox(entity forent, vector v0, vector dvx, vector dvy, vector dvz)
 {
-	traceline(v0, v0 + dvx, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0, v0 + dvy, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0, v0 + dvz, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvx, v0 + dvx + dvy, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvx, v0 + dvx + dvz, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvy, v0 + dvy + dvx, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvy, v0 + dvy + dvz, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvz, v0 + dvz + dvx, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvz, v0 + dvz + dvy, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvx + dvy, v0 + dvx + dvy + dvz, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvx + dvz, v0 + dvx + dvy + dvz, TRUE, world); if(trace_fraction < 1) return 0;
-	traceline(v0 + dvy + dvz, v0 + dvx + dvy + dvz, TRUE, world); if(trace_fraction < 1) return 0;
+	traceline(v0, v0 + dvx, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0, v0 + dvy, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0, v0 + dvz, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvx, v0 + dvx + dvy, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvx, v0 + dvx + dvz, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvy, v0 + dvy + dvx, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvy, v0 + dvy + dvz, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvz, v0 + dvz + dvx, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvz, v0 + dvz + dvy, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvx + dvy, v0 + dvx + dvy + dvz, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvx + dvz, v0 + dvx + dvy + dvz, TRUE, forent); if(trace_fraction < 1) return 0;
+	traceline(v0 + dvy + dvz, v0 + dvx + dvy + dvz, TRUE, forent); if(trace_fraction < 1) return 0;
 	return 1;
 }
 #endif
+
+// a makevectors that inverts vectoangles
+void fixedmakevectors(vector a)
+{
+	a_x = -a_x;
+	makevectors(a);
+}

Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh	2008-09-03 19:59:40 UTC (rev 4324)
+++ trunk/data/qcsrc/common/util.qh	2008-09-04 09:00:23 UTC (rev 4325)
@@ -67,5 +67,7 @@
 float compressShortVector(vector vec);
 
 #ifndef MENUQC
-float CheckWireframeBox(vector v0, vector dvx, vector dvy, vector dvz);
+float CheckWireframeBox(entity forent, vector v0, vector dvx, vector dvy, vector dvz);
 #endif
+
+void fixedmakevectors(vector a);

Modified: trunk/data/qcsrc/server/cl_weapons.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weapons.qc	2008-09-03 19:59:40 UTC (rev 4324)
+++ trunk/data/qcsrc/server/cl_weapons.qc	2008-09-04 09:00:23 UTC (rev 4325)
@@ -160,97 +160,96 @@
 	return (get_weaponinfo(wpn)).items;
 }
 
-// think function for tossed weapons
 void thrown_wep_think()
 {
 	self.solid = SOLID_TRIGGER;
 	self.owner = world;
 	SUB_SetFade(self, time + 20, 1);
-	setorigin(self, self.origin);
-};
+}
 
-// toss current weapon
-void W_ThrowWeapon(vector velo, vector delta, float doreduce)
+// returns amount of ammo used, or -1 for failure, or 0 for no ammo count
+float W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo)
 {
-	local float w, ammo, wb, wa;
-	local entity wep, e;
-	local .float ammofield;
+	entity oldself, wep;
+	float wa, ammo;
+	var .float ammofield;
 
-	w = self.weapon;
-	if (w == 0)
-		return; // just in case
-	if (w == WEP_LASER)
-		return;
-	if (g_rocketarena)
-		return;
-	if (g_lms)
-		return;
-	if (g_nixnex)
-		return;
-	if (!cvar("g_pickup_items"))
-		return;
-
-	e = self;
 	wep = spawn();
-	self = wep;
 
-	setorigin(wep, e.origin + delta);
-	makevectors(e.angles);
+	setorigin(wep, org);
 	wep.classname = "droppedweapon";
-	wep.velocity = velo; // e.velocity * 0.5 + v_forward * 750;
-	SUB_SetFade(wep, time + 20, 1);
+	wep.velocity = velo;
+	wep.owner = own;
+	wep.classname = "droppedweapon";
+	wep.flags = wep.flags | FL_TOSSED;
+	wep.colormap = own.colormap;
 
-	wa = W_AmmoItemCode(w);
+	wa = W_AmmoItemCode(wpn);
 	if(wa == IT_SUPERWEAPON || wa == 0)
 	{
-		wb = W_WeaponBit(w);
-		if(!(e.weapons & wb))
-		{
-			remove(wep);
-			goto leave;
-		}
-		Item_SpawnByWeaponCode(w);
+		oldself = self;
+		self = wep;
+		Item_SpawnByWeaponCode(wpn);
+		self = oldself;
 		if(startitem_failed)
-			goto leave;
-		if(e.weapons & wb)
-			if(e.health >= 1)
-				sprint(e, strcat("You dropped the ^2", wep.netname, "\n"));
+			return -1;
+		wep.think = thrown_wep_think;
+		wep.nextthink = time + 0.5;
+		return 0;
 	}
 	else
 	{
 		ammofield = Item_CounterField(wa);
-		wb = W_WeaponBit(w);
-		if(!(e.weapons & wb))
-		{
-			remove(wep);
-			goto leave;
-		}
-		Item_SpawnByWeaponCode(w);
+		oldself = self;
+		self = wep;
+		Item_SpawnByWeaponCode(wpn);
+		self = oldself;
 		if(startitem_failed)
-			goto leave;
+			return -1;
 		if(doreduce)
 		{
-			ammo = min(e.ammofield, wep.ammofield);
+			ammo = min(own.ammofield, wep.ammofield);
 			wep.ammofield = ammo;
-			e.ammofield -= ammo;
+			own.ammofield -= ammo;
 		}
-		if(e.weapons & wb)
-			if(e.health >= 1)
-				sprint(e, strcat("You dropped the ^2", wep.netname, " with ", ftos(wep.ammofield), " ammo", "\n"));
+		wep.think = thrown_wep_think;
+		wep.nextthink = time + 0.5;
+		return wep.ammofield;
 	}
+}
 
-	wep.owner = e;
-	setorigin(wep, wep.origin);
-	wep.nextthink = time + 0.5;
-	wep.think = thrown_wep_think;
-	wep.classname = "droppedweapon";
-	wep.flags = wep.flags | FL_TOSSED;
-	e.weapons = e.weapons - (e.weapons & wb);
-	wep.colormap = e.colormap;
-	W_SwitchWeapon_Force(e, w_getbestweapon(e));
+// toss current weapon
+void W_ThrowWeapon(vector velo, vector delta, float doreduce)
+{
+	local float w, a, wb;
 
-:leave
-	self = e;
+	w = self.weapon;
+	if (w == 0)
+		return; // just in case
+	if (w == WEP_LASER)
+		return; // just in case
+	if (g_rocketarena)
+		return;
+	if (g_lms)
+		return;
+	if (g_nixnex)
+		return;
+	if (!cvar("g_pickup_items"))
+		return;
+
+	wb = W_WeaponBit(w);
+	self.weapons = self.weapons - (self.weapons & wb);
+	W_SwitchWeapon_Force(self, w_getbestweapon(self));
+	a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo);
+	if(a < 0)
+		return;
+	if(self.health >= 1)
+	{
+		if(a == 0)
+			sprint(self, strcat("You dropped the ^2", W_Name(w), "\n"));
+		else
+			sprint(self, strcat("You dropped the ^2", W_Name(w), " with ", ftos(a), " ", Item_CounterFieldName(W_AmmoItemCode(w)), "\n"));
+	}
 };
 
 // Bringed back weapon frame

Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc	2008-09-03 19:59:40 UTC (rev 4324)
+++ trunk/data/qcsrc/server/miscfunctions.qc	2008-09-04 09:00:23 UTC (rev 4325)
@@ -100,7 +100,10 @@
 
 	tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e);
 	if(trace_startsolid)
+	{
+		setorigin(e, o);
 		return 0;
+	}
 
 	return 1;
 }

Modified: trunk/data/qcsrc/server/portals.qc
===================================================================
--- trunk/data/qcsrc/server/portals.qc	2008-09-03 19:59:40 UTC (rev 4324)
+++ trunk/data/qcsrc/server/portals.qc	2008-09-04 09:00:23 UTC (rev 4325)
@@ -5,28 +5,6 @@
 
 .entity portal_in, portal_out;
 
-vector fixedvectoangles(vector v)
-{
-	vector a;
-	a = vectoangles(v);
-	a_x = -a_x;
-	return a;
-}
-
-vector fixedvectoangles2(vector v, vector w)
-{
-	vector a;
-	a = vectoangles2(v, w);
-	a_x = -a_x;
-	return a;
-}
-
-void fixedmakevectors(vector a)
-{
-	//a_x = -a_x;
-	makevectors(a);
-}
-
 vector Portal_Transform_Apply(vector transform, vector v)
 {
 	fixedmakevectors(transform);
@@ -41,7 +19,7 @@
 	fixedmakevectors(t2); m_forward = v_forward; m_up = v_up;
 	m_forward = Portal_Transform_Apply(t1, m_forward);
 	m_up = Portal_Transform_Apply(t1, m_up);
-	return fixedvectoangles2(m_forward, m_up);
+	return vectoangles2(m_forward, m_up);
 }
 
 vector Portal_Transform_Invert(vector transform)
@@ -60,7 +38,7 @@
 	i_up_z = v_up_z;
 #ifdef DEBUG
 	vector v;
-	v = fixedvectoangles2(i_forward, i_up);
+	v = vectoangles2(i_forward, i_up);
 	print("Transform: ", vtos(transform), "\n");
 	print("Inverted: ", vtos(v), "\n");
 	print("Verify: ", vtos(Portal_Transform_Multiply(v, transform)), "\n");
@@ -69,16 +47,15 @@
 	print("Verify: ", vtos(v_right), "\n");
 	print("Verify: ", vtos(v_up), "\n");
 #endif
-	return fixedvectoangles2(i_forward, i_up);
+	return vectoangles2(i_forward, i_up);
 }
 
 vector Portal_Transform_TurnDirection(vector transform)
 {
-	vector t_angles;
-	t_angles_x = -transform_x;
-	t_angles_y = mod(transform_y + 180, 360);
-	t_angles_z = -transform_z;
-	return t_angles;
+	// turn 180 degrees around v_up
+	// changes in-direction to out-direction
+	fixedmakevectors(transform);
+	return vectoangles2(-1 * v_forward, 1 * v_up);
 }
 
 vector Portal_Transform_Divide(vector to_transform, vector from_transform)
@@ -88,16 +65,25 @@
 
 void Portal_TeleportPlayer(entity teleporter, entity player)
 {
-	vector from, to, safe, step, transform, ang;
+	vector from, to, safe, step, transform, ang, newvel;
+	float planeshift;
 	from = teleporter.origin;
 	to = teleporter.enemy.origin;
 	transform = teleporter.portal_transform;
 
 	to = to + Portal_Transform_Apply(teleporter.portal_transform, player.origin - from);
 	// this now is INSIDE the plane... can't use that
+	
+	// shift it out
+	fixedmakevectors(teleporter.enemy.angles);
 
-	// shift it out
-	fixedmakevectors(teleporter.enemy.mangle);
+	// first shift it ON the plane if needed
+	planeshift = ((teleporter.enemy.origin - to) * v_forward);
+	if(planeshift > 0)
+		to += v_forward * planeshift;
+	else
+		print("no planeshift?\n");
+
 	safe = teleporter.enemy.portal_safe_origin; // a valid player origin
 	step = to + ((safe - to) * v_forward) * v_forward;
 	tracebox(safe, PL_MIN, PL_MAX, step, MOVE_NOMONSTERS, player);
@@ -113,21 +99,29 @@
 		error("trace_endpos in solid!");
 	to = trace_endpos;
 
+	// ang_x stuff works around weird quake angles
 	if(player.classname == "player")
 	{
-		ang = Portal_Transform_Multiply(transform, player.v_angle);
+		ang = player.v_angle;
+		ang_x = -ang_x;
+		ang = Portal_Transform_Multiply(transform, ang);
 		ang_z = player.angles_z;
 	}
 	else
 	{
-		ang = Portal_Transform_Multiply(transform, player.mangle);
+		ang = player.angles;
+		ang_x = -ang_x;
+		ang = Portal_Transform_Multiply(transform, player.angles);
 	}
+	ang_x = -ang_x;
 
-	TeleportPlayer(teleporter, player, to, ang, Portal_Transform_Apply(transform, player.velocity), teleporter.enemy.absmin, teleporter.enemy.absmax);
+	newvel = Portal_Transform_Apply(transform, player.velocity);
 
+	TeleportPlayer(teleporter, player, to, ang, newvel, teleporter.enemy.absmin, teleporter.enemy.absmax);
+
 	// reset fade counter
 	teleporter.portal_wants_to_vanish = 0;
-	teleporter.fade_time = time + 10;
+	teleporter.fade_time = time + 15;
 }
 
 float Portal_FindSafeOrigin(entity portal)
@@ -136,11 +130,13 @@
 	o = portal.origin;
 	portal.mins = PL_MIN - '8 8 8';
 	portal.maxs = PL_MAX + '8 8 8';
-	fixedmakevectors(portal.mangle);
+	fixedmakevectors(portal.angles);
 	portal.origin += 16 * v_forward;
 	if(!move_out_of_solid(portal))
 	{
+#ifdef DEBUG
 		print("NO SAFE ORIGIN\n");
+#endif
 		return 0;
 	}
 	portal.portal_safe_origin = portal.origin;
@@ -158,7 +154,7 @@
 			self.portal_activatetime = time + 0.1;
 			return;
 		}
-	fixedmakevectors(self.mangle);
+	fixedmakevectors(self.angles);
 	if((other.origin - self.origin) * v_forward < 0)
 		return;
 	if(other.mins_x < PL_MIN_x || other.mins_y < PL_MIN_y || other.mins_z < PL_MIN_z
@@ -177,6 +173,7 @@
 	portal.effects = 0;
 	//portal.colormod = '1 1 1';
 	portal.nextthink = 0;
+	portal.takedamage = DAMAGE_NO;
 }
 
 void Portal_MakeWaitingPortal(entity portal)
@@ -186,6 +183,7 @@
 	portal.effects = EF_ADDITIVE;
 	portal.colormod = '1 1 1';
 	portal.nextthink = 0;
+	portal.takedamage = DAMAGE_YES;
 }
 
 void Portal_MakeInPortal(entity portal)
@@ -195,6 +193,7 @@
 	portal.effects = EF_RED;
 	portal.colormod = '1 0 0';
 	portal.nextthink = time;
+	portal.takedamage = DAMAGE_NO;
 }
 
 void Portal_MakeOutPortal(entity portal)
@@ -204,6 +203,7 @@
 	portal.effects = EF_STARDUST | EF_BLUE;
 	portal.colormod = '0 0 1';
 	portal.nextthink = 0;
+	portal.takedamage = DAMAGE_YES;
 }
 
 void Portal_Disconnect(entity teleporter, entity destination)
@@ -216,18 +216,47 @@
 
 void Portal_Connect(entity teleporter, entity destination)
 {
-	teleporter.portal_transform = Portal_Transform_Divide(Portal_Transform_TurnDirection(destination.mangle), teleporter.mangle);
+	teleporter.portal_transform = Portal_Transform_Divide(Portal_Transform_TurnDirection(destination.angles), teleporter.angles);
+
+#ifdef DEBUG
+	{
+		// let's verify the transform
+		vector in_f, in_r, in_u;
+		vector out_f, out_r, out_u;
+		fixedmakevectors(teleporter.angles);
+		in_f = v_forward;
+		in_r = v_right;
+		in_u = v_up;
+		print("teleporter: ", vtos(in_f), " ", vtos(in_r), " ", vtos(in_u), "\n");
+		fixedmakevectors(destination.angles);
+		out_f = v_forward;
+		out_r = v_right;
+		out_u = v_up;
+		print("dest: ", vtos(out_f), " ", vtos(out_r), " ", vtos(out_u), "\n");
+		// INTENDED TRANSFORM:
+		//   in_f -> -out_f
+		//   in_r -> -out_r
+		//   in_u -> +out_u
+		print("FORWARD: ", vtos(in_f), " -> ", vtos(Portal_Transform_Apply(teleporter.portal_transform, in_f)), ", should be", vtos(-1 * out_f), "\n");
+		print("RIGHT: ", vtos(in_r), " -> ", vtos(Portal_Transform_Apply(teleporter.portal_transform, in_r)), ", should be", vtos(-1 * out_r), "\n");
+		print("UP: ", vtos(in_u), " -> ", vtos(Portal_Transform_Apply(teleporter.portal_transform, in_u)), ", should be", vtos(out_u), "\n");
+
+		te_lightning3(world, teleporter.origin, teleporter.origin + in_r * 1000);
+		te_lightning3(world, destination.origin, destination.origin + out_r * 1000);
+	}
+#endif
+
 	teleporter.enemy = destination;
 	destination.enemy = teleporter;
 	Portal_MakeInPortal(teleporter);
 	Portal_MakeOutPortal(destination);
-	teleporter.fade_time = time + 10;
-	destination.fade_time = time + 10;
+	teleporter.fade_time = time + 15;
+	destination.fade_time = time + 15;
 	teleporter.portal_wants_to_vanish = 0;
 	destination.portal_wants_to_vanish = 0;
 }
 
-void Portal_Remove(entity portal)
+void Portal_Remove(entity portal, float killed)
 {
 	entity e;
 	e = portal.enemy;
@@ -235,7 +264,7 @@
 	if(e)
 	{
 		Portal_Disconnect(portal, e);
-		Portal_Remove(e);
+		Portal_Remove(e, killed);
 	}
 
 	if(portal == portal.owner.portal_in)
@@ -245,10 +274,30 @@
 	portal.owner = world;
 
 	// makes the portal vanish
-	Portal_MakeBrokenPortal(portal);
-	SUB_SetFade(portal, time, 0.5);
+	if(killed)
+	{
+		fixedmakevectors(portal.angles);
+		pointparticles(particleeffectnum("rocket_explode"), portal.origin + v_forward * 16, v_forward * 1024, 4);
+		remove(portal);
+	}
+	else
+	{
+		Portal_MakeBrokenPortal(portal);
+		SUB_SetFade(portal, time, 0.5);
+	}
 }
 
+void Portal_Damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+	if(deathtype == DEATH_TELEFRAG)
+		return;
+	self.health -= damage;
+	if(self.health < 0)
+	{
+		Portal_Remove(self, 1);
+	}
+}
+
 void Portal_Think()
 {
 	entity e, o;
@@ -276,7 +325,7 @@
 	self.nextthink = time;
 
 	if(time > self.fade_time)
-		Portal_Remove(self);
+		Portal_Remove(self, 0);
 }
 
 
@@ -300,7 +349,11 @@
 float Portal_SetInPortal(entity own, entity portal)
 {
 	if(own.portal_out)
-		Portal_Remove(own.portal_out);
+	{
+		if(own.portal_in)
+			Portal_Disconnect(own.portal_in, own.portal_out);
+		Portal_Remove(own.portal_out, 0);
+	}
 	if(own.portal_in)
 		own.portal_out = own.portal_in;
 	own.portal_in = portal;
@@ -313,7 +366,10 @@
 	if(!own.portal_in)
 		return 0;
 	if(own.portal_out)
-		Portal_Remove(own.portal_out);
+	{
+		Portal_Disconnect(own.portal_in, own.portal_out);
+		Portal_Remove(own.portal_out, 0);
+	}
 	own.portal_out = portal;
 	Portal_Connect(own.portal_in, own.portal_out);
 	return 1;
@@ -321,14 +377,14 @@
 void Portal_ClearAll(entity own)
 {
 	if(own.portal_in)
-		Portal_Remove(own.portal_in);
+		Portal_Remove(own.portal_in, 0);
 	if(own.portal_out)
-		Portal_Remove(own.portal_out);
+		Portal_Remove(own.portal_out, 0);
 }
-float Portal_VerifyPortal(vector org, vector ang)
+float Portal_VerifyPortal(entity own, vector org, vector ang)
 {
 	fixedmakevectors(ang);
-	if(!CheckWireframeBox(org - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 16 * v_forward))
+	if(!CheckWireframeBox(own, org - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
 		return 0;
 	return 1;
 }
@@ -340,13 +396,13 @@
 	portal.classname = "portal";
 	portal.owner = own;
 	portal.origin = org;
-	portal.mangle = ang;
-	ang_x = -ang_x;
 	portal.angles = ang;
 	portal.think = Portal_Think;
 	portal.nextthink = 0;
-	portal.fade_time = time + 10;
+	portal.fade_time = time + 15;
 	portal.portal_activatetime = time + 0.1;
+	portal.event_damage = Portal_Damage;
+	portal.health = 300;
 	setmodel(portal, "models/portal.md3");
 
 	if(!Portal_FindSafeOrigin(portal))
@@ -367,17 +423,34 @@
 	vector ang;
 	vector org;
 
-	if(trace_ent.classname == "player")
+#ifdef DEBUG
 	{
-		print("hit a player, adjusting...\n");
+		vector a, b;
+		a = randomvec();
+		a = '0 0 -1';
+		a = normalize(a);
+		b = randomvec();
+		b = '1 0 0';
+		b = normalize(b - (b * a) * a);
+		print("f/u = ", vtos(a), " ", vtos(b), "\n");
+		a = vectoangles2(a, b);
+		print("ang = ", vtos(a), "\n");
+		fixedmakevectors(a);
+		print("f/u = ", vtos(v_forward), " ", vtos(v_up), "\n");
+	}
+#endif
+
+	if(trace_ent.movetype == MOVETYPE_WALK)
+	{
 		trace_endpos = trace_ent.origin + '0 0 1' * PL_MIN_z;
 		trace_plane_normal = '0 0 1';
 	}
 
 	org = trace_endpos;
-	ang = fixedvectoangles2(trace_plane_normal, dir);
+	ang = vectoangles2(trace_plane_normal, dir);
+	fixedmakevectors(ang);
 
-	if((trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) || !Portal_VerifyPortal(org, ang))
+	if((trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) || !Portal_VerifyPortal(own, org, ang))
 	{
 		// cannot create a portal here
 		// clear all to make sure
@@ -397,22 +470,17 @@
 	vector ang;
 	vector org;
 
-	if(trace_ent.classname == "player")
+	if(trace_ent.movetype == MOVETYPE_WALK)
 	{
-		print("hit a player, adjusting...\n");
 		trace_endpos = trace_ent.origin + '0 0 1' * PL_MIN_z;
 		trace_plane_normal = '0 0 1';
 	}
-	/*
-	else
-		dir = -1 * dir; // invert the sense of the second portal
-		// no, better don't, it is weirder IF it is inverted
-	*/
 
 	org = trace_endpos;
-	ang = fixedvectoangles2(trace_plane_normal, dir);
+	ang = vectoangles2(trace_plane_normal, dir);
+	fixedmakevectors(ang);
 
-	if((trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) || !Portal_VerifyPortal(org, ang))
+	if((trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) || !Portal_VerifyPortal(own, org, ang))
 	{
 		// cannot create a portal here
 		// clear all to make sure

Modified: trunk/data/qcsrc/server/w_porto.qc
===================================================================
--- trunk/data/qcsrc/server/w_porto.qc	2008-09-03 19:59:40 UTC (rev 4324)
+++ trunk/data/qcsrc/server/w_porto.qc	2008-09-04 09:00:23 UTC (rev 4325)
@@ -1,30 +1,79 @@
 .float porto_grenade_id;
 .vector porto_v_angle; // holds "held" view angles
 .float porto_v_angle_held;
+.vector right_vector;
 
-void W_Porto_Explode (void)
+void W_Porto_Success (void)
 {
 	self.owner.porto_grenade_id = 0;
 	remove(self);
 }
 
-void W_Porto_Touch1 (void)
+float W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo);
+void W_Porto_Fail (void)
 {
+	centerprint(self.owner, "^1Portal deployment failed.\n\n^2Catch it to try again!");
+	self.owner.porto_grenade_id = 0;
+	// TODO maybe instead throw the portal gun there?
+	// self.owner.weapons = self.owner.weapons | WEPBIT_PORTO;
+	setsize (self, '-16 -16 0', '16 16 32');
+	setorigin(self, self.origin + trace_plane_normal);
+	if(move_out_of_solid(self))
+	{
+		self.flags = FL_ITEM;
+		self.velocity = trigger_push_calculatevelocity(self.origin, self.owner, 128);
+		tracetoss(self, self);
+		if(vlen(trace_endpos - self.owner.origin) > 128)
+			self.velocity = '0 0 0';
+		W_ThrowNewWeapon(self.owner, WEP_PORTO, 0, self.origin, self.velocity);
+	}
+	else
+	{
+		W_ThrowNewWeapon(self.owner, WEP_PORTO, 0, self.origin, '0 0 0');
+	}
+	remove(self);
+}
+
+void W_Porto_Think (void)
+{
+	trace_plane_normal = '0 0 0';
 	if(self.owner.playerid != self.playerid)
+		remove(self);
+	else
+		W_Porto_Fail();
+}
+
+void W_Porto_Touch (void)
+{
+	vector norm;
+	norm = trace_plane_normal;
+	if(self.owner.playerid != self.playerid)
 	{
 		remove(self);
 	}
 	else if(self.cnt == 0)
 	{
 		self.cnt = 1;
-		if(!Portal_SpawnInPortalAtTrace(self.owner, self.velocity, self.porto_grenade_id))
-			W_Porto_Explode();
+		if(!Portal_SpawnInPortalAtTrace(self.owner, self.right_vector, self.porto_grenade_id))
+		{
+			trace_plane_normal = norm;
+			W_Porto_Fail();
+			return;
+		}
+		trace_plane_normal = norm;
+		self.right_vector = self.right_vector - 2 * trace_plane_normal * (self.right_vector * trace_plane_normal);
 	}
 	else
 	{
-		Portal_SpawnOutPortalAtTrace(self.owner, self.velocity, self.porto_grenade_id);
-		W_Porto_Explode();
+		if(!Portal_SpawnOutPortalAtTrace(self.owner, self.right_vector, self.porto_grenade_id))
+		{
+			trace_plane_normal = norm;
+			W_Porto_Fail();
+		}
+		else
+			W_Porto_Success();
 	}
+
 }
 
 void W_Porto_Attack (void)
@@ -51,8 +100,8 @@
 	setorigin(gren, w_shotorg);
 
 	gren.nextthink = time + cvar("g_balance_porto_primary_lifetime");
-	gren.think = W_Porto_Explode;
-	gren.touch = W_Porto_Touch1;
+	gren.think = W_Porto_Think;
+	gren.touch = W_Porto_Touch;
 	gren.velocity = w_shotdir * cvar("g_balance_porto_primary_speed");
 	W_SetupProjectileVelocity(gren);
 
@@ -61,6 +110,10 @@
 
 	self.porto_grenade_id = gren.porto_grenade_id = time;
 	gren.playerid = self.playerid;
+	fixedmakevectors(vectoangles(gren.velocity));
+	gren.right_vector = v_right;
+
+	gren.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
 }
 
 void spawnfunc_weapon_porto (void)




More information about the nexuiz-commits mailing list