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