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