[nexuiz-commits] r8687 - in trunk/data/qcsrc: . client common server warpzonelib
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Feb 28 14:42:26 EST 2010
Author: div0
Date: 2010-02-28 14:42:26 -0500 (Sun, 28 Feb 2010)
New Revision: 8687
Added:
trunk/data/qcsrc/warpzonelib/
trunk/data/qcsrc/warpzonelib/COPYING
trunk/data/qcsrc/warpzonelib/anglestransform.qc
trunk/data/qcsrc/warpzonelib/anglestransform.qh
trunk/data/qcsrc/warpzonelib/client.qc
trunk/data/qcsrc/warpzonelib/client.qh
trunk/data/qcsrc/warpzonelib/common.qc
trunk/data/qcsrc/warpzonelib/common.qh
trunk/data/qcsrc/warpzonelib/server.qc
trunk/data/qcsrc/warpzonelib/server.qh
trunk/data/qcsrc/warpzonelib/util_server.qc
trunk/data/qcsrc/warpzonelib/util_server.qh
Modified:
trunk/data/qcsrc/client/Main.qc
trunk/data/qcsrc/client/View.qc
trunk/data/qcsrc/client/progs.src
trunk/data/qcsrc/common/util.qc
trunk/data/qcsrc/common/util.qh
trunk/data/qcsrc/server/miscfunctions.qc
trunk/data/qcsrc/server/portals.qc
trunk/data/qcsrc/server/progs.src
trunk/data/qcsrc/server/t_teleporters.qc
trunk/data/qcsrc/server/w_campingrifle.qc
Log:
warpzonelib - the beginning
NOTE: this patch breaks something on CLIENT side.
Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/client/Main.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -839,51 +839,6 @@
psrandom(s);
}
-float FL_CAMERA = 8192;
-.vector warpzone_transform;
-void Ent_WarpZone(float isnew)
-{
- if not(self.enemy)
- {
- self.enemy = spawn();
- self.enemy.classname = "warpzone_from";
- }
- self.classname = "warpzone_to";
- self.origin_x = ReadCoord();
- self.origin_y = ReadCoord();
- self.origin_z = ReadCoord();
- self.modelindex = ReadShort();
- self.mins_x = ReadCoord();
- self.mins_y = ReadCoord();
- self.mins_z = ReadCoord();
- self.maxs_x = ReadCoord();
- self.maxs_y = ReadCoord();
- self.maxs_z = ReadCoord();
- self.enemy.oldorigin_x = ReadCoord();
- self.enemy.oldorigin_y = ReadCoord();
- self.enemy.oldorigin_z = ReadCoord();
- self.enemy.avelocity_x = ReadCoord();
- self.enemy.avelocity_y = ReadCoord();
- self.enemy.avelocity_z = ReadCoord();
- self.oldorigin_x = ReadCoord();
- self.oldorigin_y = ReadCoord();
- self.oldorigin_z = ReadCoord();
- self.avelocity_x = ReadCoord();
- self.avelocity_y = ReadCoord();
- self.avelocity_z = ReadCoord();
-
- self.avelocity = AnglesTransform_TurnDirection(self.avelocity);
- self.warpzone_transform = AnglesTransform_Divide(self.avelocity, self.enemy.avelocity);
-
- self.flags = FL_CAMERA;
- self.drawmask = MASK_NORMAL;
-
- // link me
- //setmodel(self, self.model);
- setorigin(self, self.origin);
- setsize(self, self.mins, self.maxs);
-}
-
// CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
// The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
void Ent_RadarLink();
@@ -941,7 +896,7 @@
case ENT_CLIENT_WALL: Ent_Wall(); break;
case ENT_CLIENT_MODELEFFECT: Ent_ModelEffect(bIsNewEntity); break;
case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break;
- case ENT_CLIENT_WARPZONE: Ent_WarpZone(bIsNewEntity); break;
+ case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break;
default:
error(strcat("unknown entity type in CSQC_Ent_Update: ", ftos(self.enttype), "\n"));
break;
Modified: trunk/data/qcsrc/client/View.qc
===================================================================
--- trunk/data/qcsrc/client/View.qc 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/client/View.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -358,22 +358,11 @@
ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
vo = '0 0 1' * getstati(STAT_VIEWHEIGHT);
- // if view origin is INSIDE a warpzone, we are screwed and must
- // temporarily move the origin to the other side of the warp
- pmove_org = pmove_org + vo;
- for(e = world; (e = find(e, classname, "warpzone_to")); )
- {
- //print(sprintf("does %s (%s to %s) touch %s?\n", e.model, vtos(e.absmin), vtos(e.absmax), vtos(pmove_org)));
- if(BoxTouchesBrush(pmove_org, pmove_org, e, world))
- {
- pmove_org = AnglesTransform_Apply(e.warpzone_transform, pmove_org - e.enemy.oldorigin) + e.oldorigin;
- input_angles = AnglesTransform_Multiply(e.warpzone_transform, input_angles);
- R_SetView(VF_ORIGIN, pmove_org);
- R_SetView(VF_ANGLES, input_angles);
- break;
- }
- }
- pmove_org = pmove_org - vo;
+ warpzone_fixview_origin = pmove_org + vo;
+ warpzone_fixview_angles = input_angles;
+ WarpZone_FixView();
+ pmove_org = warpzone_fixview_origin - vo;
+ input_angles = warpzone_fixview_angles;
// Render the Scene
if(!intermission || !view_set)
Modified: trunk/data/qcsrc/client/progs.src
===================================================================
--- trunk/data/qcsrc/client/progs.src 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/client/progs.src 2010-02-28 19:42:26 UTC (rev 8687)
@@ -6,6 +6,11 @@
csqc_constants.qc
../common/constants.qh
csqc_builtins.qc
+
+../warpzonelib/anglestransform.qh
+../warpzonelib/common.qh
+../warpzonelib/client.qh
+
../common/mathlib.qh
../common/util.qh
../common/items.qh
@@ -61,3 +66,7 @@
../common/items.qc
../common/mathlib.qc
+
+../warpzonelib/anglestransform.qc
+../warpzonelib/common.qc
+../warpzonelib/client.qc
Modified: trunk/data/qcsrc/common/util.qc
===================================================================
--- trunk/data/qcsrc/common/util.qc 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/common/util.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -686,13 +686,6 @@
traceline(v0 + dvy + dvz, v0 + dvx + dvy + dvz, TRUE, forent); if(trace_fraction < 1) return 0;
return 1;
}
-
-void fixedmakevectors(vector a)
-{
- // a makevectors that actually inverts vectoangles
- a_x = -a_x;
- makevectors(a);
-}
#endif
string fixPriorityList(string order, float from, float to, float subtract, float complete)
@@ -1211,53 +1204,6 @@
float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) {return smins_x >= bmins_x && smaxs_x <= bmaxs_x && smins_y >= bmins_y && smaxs_y <= bmaxs_y && smins_z >= bmins_z && smaxs_z <= bmaxs_z;};
#ifndef MENUQC
-// angles transforms
-// angles in fixedmakevectors/fixedvectoangles space
-vector AnglesTransform_Apply(vector transform, vector v)
-{
- fixedmakevectors(transform);
- return v_forward * v_x
- + v_right * (-v_y)
- + v_up * v_z;
-}
-
-vector AnglesTransform_Multiply(vector t1, vector t2)
-{
- vector m_forward, m_up;
- fixedmakevectors(t2); m_forward = v_forward; m_up = v_up;
- m_forward = AnglesTransform_Apply(t1, m_forward); m_up = AnglesTransform_Apply(t1, m_up);
- return fixedvectoangles2(m_forward, m_up);
-}
-
-vector AnglesTransform_Invert(vector transform)
-{
- vector i_forward, i_up;
- fixedmakevectors(transform);
- // we want angles that turn v_forward into '1 0 0', v_right into '0 1 0' and v_up into '0 0 1'
- // but these are orthogonal unit vectors!
- // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix
- // TODO is this always -transform?
- i_forward_x = v_forward_x;
- i_forward_y = -v_right_x;
- i_forward_z = v_up_x;
- i_up_x = v_forward_z;
- i_up_y = -v_right_z;
- i_up_z = v_up_z;
- return fixedvectoangles2(i_forward, i_up);
-}
-
-vector AnglesTransform_TurnDirection(vector transform)
-{
- // turn 180 degrees around v_up
- // changes in-direction to out-direction
- fixedmakevectors(transform);
- return fixedvectoangles2(-1 * v_forward, 1 * v_up);
-}
-
-vector AnglesTransform_Divide(vector to_transform, vector from_transform)
-{
- return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform));
-}
#endif
float textLengthUpToWidth(string theText, float maxWidth, vector theSize, textLengthUpToWidth_widthFunction_t w)
Modified: trunk/data/qcsrc/common/util.qh
===================================================================
--- trunk/data/qcsrc/common/util.qh 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/common/util.qh 2010-02-28 19:42:26 UTC (rev 8687)
@@ -77,10 +77,6 @@
#ifndef MENUQC
float CheckWireframeBox(entity forent, vector v0, vector dvx, vector dvy, vector dvz);
-
-void fixedmakevectors(vector a);
-#define fixedvectoangles2 vectoangles2
-#define fixedvectoangles vectoangles
#endif
string fixPriorityList(string pl, float from, float to, float subtract, float complete);
@@ -132,14 +128,6 @@
float boxesoverlap(vector m1, vector m2, vector m3, vector m4);
float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs);
-#ifndef MENUQC
-vector AnglesTransform_Apply(vector transform, vector v);
-vector AnglesTransform_Multiply(vector t1, vector t2);
-vector AnglesTransform_Invert(vector transform);
-vector AnglesTransform_TurnDirection(vector transform);
-vector AnglesTransform_Divide(vector to_transform, vector from_transform);
-#endif
-
typedef float(string s, vector size) textLengthUpToWidth_widthFunction_t;
typedef float(string s) textLengthUpToLength_lenFunction_t;
float textLengthUpToWidth(string theText, float maxWidth, vector size, textLengthUpToWidth_widthFunction_t tw);
Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/server/miscfunctions.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -51,61 +51,9 @@
return f;
}
-void move_out_of_solid_expand(entity e, vector by)
-{
- float eps = 0.0625;
- tracebox(e.origin, e.mins - '1 1 1' * eps, e.maxs + '1 1 1' * eps, e.origin + by, MOVE_WORLDONLY, e);
- if (trace_startsolid)
- return;
- if (trace_fraction < 1)
- {
- // hit something
- // adjust origin in the other direction...
- setorigin(e,e.origin - by * (1 - trace_fraction));
- }
-}
+#define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e)
-float move_out_of_solid(entity e)
-{
- vector o, m0, m1;
- o = e.origin;
- traceline(o, o, MOVE_WORLDONLY, e);
- if (trace_startsolid)
- return 0;
-
- tracebox(o, e.mins, e.maxs, o, MOVE_WORLDONLY, e);
- if (!trace_startsolid)
- return 1;
-
- m0 = e.mins;
- m1 = e.maxs;
- e.mins = '0 0 0';
- e.maxs = '0 0 0';
- move_out_of_solid_expand(e, '1 0 0' * m0_x);
- e.mins_x = m0_x;
- move_out_of_solid_expand(e, '1 0 0' * m1_x);
- e.maxs_x = m1_x;
- move_out_of_solid_expand(e, '0 1 0' * m0_y);
- e.mins_y = m0_y;
- move_out_of_solid_expand(e, '0 1 0' * m1_y);
- e.maxs_y = m1_y;
- move_out_of_solid_expand(e, '0 0 1' * m0_z);
- e.mins_z = m0_z;
- move_out_of_solid_expand(e, '0 0 1' * m1_z);
- e.maxs_z = m1_z;
- setorigin(e, e.origin);
-
- tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e);
- if (trace_startsolid)
- {
- setorigin(e, o);
- return 0;
- }
-
- return 1;
-}
-
string STR_PLAYER = "player";
string STR_SPECTATOR = "spectator";
string STR_OBSERVER = "observer";
Modified: trunk/data/qcsrc/server/portals.qc
===================================================================
--- trunk/data/qcsrc/server/portals.qc 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/server/portals.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -351,7 +351,7 @@
void Portal_Connect(entity teleporter, entity destination)
{
- teleporter.portal_transform = AnglesTransform_Divide(AnglesTransform_TurnDirection(destination.angles), teleporter.angles);
+ teleporter.portal_transform = AnglesTransform_Divide(AnglesTransform_TurnDirectionFR(destination.angles), teleporter.angles);
teleporter.enemy = destination;
destination.enemy = teleporter;
Modified: trunk/data/qcsrc/server/progs.src
===================================================================
--- trunk/data/qcsrc/server/progs.src 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/server/progs.src 2010-02-28 19:42:26 UTC (rev 8687)
@@ -6,6 +6,12 @@
builtins.qh
extensions.qh
post-builtins.qh
+
+../warpzonelib/anglestransform.qh
+../warpzonelib/common.qh
+../warpzonelib/util_server.qh
+../warpzonelib/server.qh
+
../common/mathlib.qh
constants.qh
../common/constants.qh
@@ -165,3 +171,8 @@
anticheat.qc
cheats.qc
+
+../warpzonelib/anglestransform.qc
+../warpzonelib/common.qc
+../warpzonelib/util_server.qc
+../warpzonelib/server.qc
Modified: trunk/data/qcsrc/server/t_teleporters.qc
===================================================================
--- trunk/data/qcsrc/server/t_teleporters.qc 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/server/t_teleporters.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -298,199 +298,19 @@
}
}
-
-// the transform
-.vector warpzone_origin, warpzone_angles;
-.vector warpzone_forward;
-.vector warpzone_transform;
-
-void warpzone_updatetransform()
+void WarpZone_PostTeleportPlayer(entity pl)
{
- if(!self.enemy || self.enemy.enemy != self)
+ UpdateCSQCProjectileAfterTeleport(pl);
+ if(pl.classname == "player")
{
- objerror("Invalid warp zone detected. Killed.");
- return;
+ // reset tracking of oldvelocity for impact damage (sudden velocity changes)
+ pl.oldvelocity = pl.velocity;
}
-
- // 1. update this, and the enemy, warp zone
- self.warpzone_origin = self.aiment.origin;
- self.warpzone_angles = self.aiment.angles;
- self.enemy.warpzone_origin = self.enemy.aiment.origin;
- self.enemy.warpzone_angles = self.enemy.aiment.angles;
-
- // 2. combine the angle transforms
- // current forward must be turned into previous backward
- self.warpzone_transform = AnglesTransform_Divide(AnglesTransform_TurnDirection(self.enemy.warpzone_angles), self.warpzone_angles);
-
- // 3. store off a saved forward vector for plane hit decisions
- fixedmakevectors(self.warpzone_angles);
- self.warpzone_forward = v_forward;
}
-float warpzone_teleport(entity player)
-{
- vector o0, a0, v0, o1, a1, v1;
-
- o0 = player.origin + player.view_ofs;
- v0 = player.velocity;
- a0 = player.angles;
-
- if((o0 - self.warpzone_origin) * self.warpzone_forward >= 0) // wrong side of the portal
- return 2;
- // no failure, we simply don't want to teleport yet; TODO in
- // this situation we may want to create a temporary clone
- // entity of the player to fix graphics glitch
-
- o1 = AnglesTransform_Apply(self.warpzone_transform, o0 - self.warpzone_origin) + self.enemy.warpzone_origin;
- v1 = AnglesTransform_Apply(self.warpzone_transform, v0);
- if(player.classname == "player")
- a1 = Portal_ApplyTransformToPlayerAngle(self.warpzone_transform, player.v_angle);
- else
- a1 = AnglesTransform_Multiply(self.warpzone_transform, a0);
-
- // put him inside solid
- tracebox(o1 - player.view_ofs, player.mins, player.maxs, o1 - player.view_ofs, MOVE_NOMONSTERS, player);
- if(trace_startsolid)
- {
- setorigin(player, o1 - player.view_ofs);
- if(move_out_of_solid(player))
- {
- setorigin(player, o0);
- o1 = player.origin + player.view_ofs;
- }
- else
- {
- setorigin(player, o0 - player.view_ofs);
- return 0; // cannot fix
- }
- }
-
- if((o1 - self.enemy.warpzone_origin) * self.enemy.warpzone_forward <= 0) // wrong side of the portal post-teleport
- {
- print("inconsistent warp zones or evil roundoff error\n");
- return 0;
- }
-
- //print(sprintf("warpzone: %f %f %f -> %f %f %f\n", o0_x, o0_y, o0_z, o1_x, o1_y, o1_z));
-
- //o1 = trace_endpos;
- TeleportPlayer(self, other, o1 - player.view_ofs, a1, v1, '0 0 0', '0 0 0', TELEPORT_FLAGS_WARPZONE);
-
- return 1;
-}
-
-void warpzone_touch (void)
-{
- entity oldself, e;
-
- if (other.health < 1)
- return;
-
- if(self.team)
- if((self.spawnflags & 4 == 0) == (self.team != other.team))
- return;
-
- EXACTTRIGGER_TOUCH;
-
- e = self.enemy;
- if(warpzone_teleport(other))
- {
- if(self.aiment.target)
- {
- oldself = self;
- activator = other;
- self = self.aiment;
- SUB_UseTargets();
- self = oldself;
- }
- }
- else
- {
- dprint("WARPZONE FAIL AHAHAHAHAH))\n");
- }
-}
-void warpzone_findtarget (void)
-{
- entity e;
-
- if(self.killtarget == "")
- {
- objerror("Warp zone with no killtarget");
- return;
- }
- self.aiment = find(world, targetname, self.killtarget);
- if(self.aiment == world)
- {
- objerror("Warp zone with nonexisting killtarget");
- return;
- }
-
- // this way only one of the two ents needs to target
- if(self.target != "")
- {
- e = find(world, targetname, self.target);
- if(e)
- {
- self.enemy = e;
- self.enemy.enemy = self;
- }
- }
-
- // now enable touch
- self.touch = warpzone_touch;
-}
-
-float warpzone_send(entity to, float sendflags)
-{
- WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE);
-
- // we need THESE to render the warpzone (and cull properly)...
- WriteCoord(MSG_ENTITY, self.origin_x);
- WriteCoord(MSG_ENTITY, self.origin_y);
- WriteCoord(MSG_ENTITY, self.origin_z);
-
- WriteShort(MSG_ENTITY, self.modelindex);
- WriteCoord(MSG_ENTITY, self.mins_x);
- WriteCoord(MSG_ENTITY, self.mins_y);
- WriteCoord(MSG_ENTITY, self.mins_z);
- WriteCoord(MSG_ENTITY, self.maxs_x);
- WriteCoord(MSG_ENTITY, self.maxs_y);
- WriteCoord(MSG_ENTITY, self.maxs_z);
-
- // we need THESE to calculate the proper transform
- WriteCoord(MSG_ENTITY, self.warpzone_origin_x);
- WriteCoord(MSG_ENTITY, self.warpzone_origin_y);
- WriteCoord(MSG_ENTITY, self.warpzone_origin_z);
- WriteCoord(MSG_ENTITY, self.warpzone_angles_x);
- WriteCoord(MSG_ENTITY, self.warpzone_angles_y);
- WriteCoord(MSG_ENTITY, self.warpzone_angles_z);
- WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_x);
- WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_y);
- WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_z);
- WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_x);
- WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_y);
- WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_z);
-
- return TRUE;
-}
-
void spawnfunc_trigger_warpzone(void)
{
- // warp zone entities must have:
- // "killtarget" pointing to a target_position with a direction arrow
- // that points AWAY from the warp zone, and that is inside
- // the warp zone trigger
- // "target" pointing to an identical warp zone at another place in
- // the map, with another killtarget to designate its
- // orientation
-
- string m;
- m = self.model;
- EXACTTRIGGER_INIT;
- setmodel(self, m);
-
- self.use = trigger_teleport_use; // set team
- InitializeEntity(self, warpzone_findtarget, INITPRIO_FINDTARGET);
- InitializeEntity(self, warpzone_updatetransform, INITPRIO_LAST);
- Net_LinkEntity(self, FALSE, 0, warpzone_send);
+ WarpZone_InitStep_SpawnFunc();
+ InitializeEntity(self, WarpZone_InitStep_FindTarget, INITPRIO_FINDTARGET);
+ InitializeEntity(self, WarpZone_InitStep_UpdateTransform, INITPRIO_LAST);
}
Modified: trunk/data/qcsrc/server/w_campingrifle.qc
===================================================================
--- trunk/data/qcsrc/server/w_campingrifle.qc 2010-02-28 19:42:21 UTC (rev 8686)
+++ trunk/data/qcsrc/server/w_campingrifle.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -239,3 +239,84 @@
return TRUE;
};
#endif
+ Ç[Kg|º^fÆ,9Þ@ª w_deathtypestring = "sniped themself somehow";
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ w_deathtypestring = "failed to hide from #'s bullet hail";
+ else
+ w_deathtypestring = "died in #'s bullet hail";
+ }
+ else
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ {
+ // TODO special headshot message here too?
+ w_deathtypestring = "failed to hide from #'s rifle";
+ }
+ else
+ {
+ if(w_deathtype & HITTYPE_HEADSHOT)
+ w_deathtypestring = "got hit in the head by #";
+ else
+ w_deathtypestring = "was sniped by #";
+ }
+ }
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_CampingRifle_Reload();
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ self.campingrifle_accumulator = time - cvar("g_balance_campingrifle_bursttime");
+ self.campingrifle_bulletcounter = cvar("g_balance_campingrifle_magazinecapacity");
+ W_CampingRifle_CheckMaxBullets(FALSE);
+ }
+ return TRUE;
+};
+#endif
+ tì{³ío¸?~á
Ñ w_deathtypestring = "sniped themself somehow";
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_SECONDARY)
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ w_deathtypestring = "failed to hide from #'s bullet hail";
+ else
+ w_deathtypestring = "died in #'s bullet hail";
+ }
+ else
+ {
+ if(w_deathtype & HITTYPE_BOUNCE)
+ {
+ // TODO special headshot message here too?
+ w_deathtypestring = "failed to hide from #'s rifle";
+ }
+ else
+ {
+ if(w_deathtype & HITTYPE_HEADSHOT)
+ w_deathtypestring = "got hit in the head by #";
+ else
+ w_deathtypestring = "was sniped by #";
+ }
+ }
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_CampingRifle_Reload();
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ self.campingrifle_accumulator = time - cvar("g_balance_campingrifle_bursttime");
+ self.campingrifle_bulletcounter = cvar("g_balance_campingrifle_magazinecapacity");
+ W_CampingRifle_CheckMaxBullets(FALSE);
+ }
+ return TRUE;
+};
+#endif
+
\ No newline at end of file
Added: trunk/data/qcsrc/warpzonelib/COPYING
===================================================================
--- trunk/data/qcsrc/warpzonelib/COPYING (rev 0)
+++ trunk/data/qcsrc/warpzonelib/COPYING 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,21 @@
+/*
+Copyright (c) 2010 Rudolf Polzer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
Added: trunk/data/qcsrc/warpzonelib/anglestransform.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/anglestransform.qc (rev 0)
+++ trunk/data/qcsrc/warpzonelib/anglestransform.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,99 @@
+// helper function
+void fixedmakevectors(vector a)
+{
+ // a makevectors that actually inverts vectoangles
+ a_x = -a_x;
+ makevectors(a);
+}
+
+// angles transforms
+// angles in fixedmakevectors/fixedvectoangles space
+vector AnglesTransform_Apply(vector transform, vector v)
+{
+ fixedmakevectors(transform);
+ return v_forward * v_x
+ + v_right * (-v_y)
+ + v_up * v_z;
+}
+
+vector AnglesTransform_Multiply(vector t1, vector t2)
+{
+ vector m_forward, m_up;
+ fixedmakevectors(t2); m_forward = v_forward; m_up = v_up;
+ m_forward = AnglesTransform_Apply(t1, m_forward); m_up = AnglesTransform_Apply(t1, m_up);
+ return fixedvectoangles2(m_forward, m_up);
+}
+
+vector AnglesTransform_Invert(vector transform)
+{
+ vector i_forward, i_up;
+ fixedmakevectors(transform);
+ // we want angles that turn v_forward into '1 0 0', v_right into '0 1 0' and v_up into '0 0 1'
+ // but these are orthogonal unit vectors!
+ // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix
+ // TODO is this always -transform?
+ i_forward_x = v_forward_x;
+ i_forward_y = -v_right_x;
+ i_forward_z = v_up_x;
+ i_up_x = v_forward_z;
+ i_up_y = -v_right_z;
+ i_up_z = v_up_z;
+ return fixedvectoangles2(i_forward, i_up);
+}
+
+vector AnglesTransform_TurnDirectionFR(vector transform)
+{
+ // turn 180 degrees around v_up
+ // changes in-direction to out-direction
+ //fixedmakevectors(transform);
+ //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
+ transform_x = 180 - transform_x;
+ transform_y = 180 + transform_y;
+ transform_z = -transform_z;
+ return transform;
+}
+
+vector AnglesTransform_TurnDirectionFU(vector transform)
+{
+ // turn 180 degrees around v_up
+ // changes in-direction to out-direction
+ //fixedmakevectors(transform);
+ //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
+ transform_x = 180 - transform_x;
+ transform_y = 180 + transform_y;
+ transform_z = 180 - transform_z;
+ return transform;
+}
+
+vector AnglesTransform_Divide(vector to_transform, vector from_transform)
+{
+ return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform));
+}
+
+vector AnglesTransform_Normalize(vector t, float minimize_roll)
+{
+ float need_flip;
+ // first, bring all angles in their range...
+ t_x = t_x - 360 * rint(t_x / 360);
+ t_y = t_y - 360 * rint(t_y / 360);
+ t_z = t_z - 360 * rint(t_z / 360);
+ if(minimize_roll)
+ need_flip = (t_z > 90 || t_z <= -90);
+ else
+ need_flip = (t_x > 90 || t_x < -90); // for pitch we prefer to allow exactly -90 degrees for looking straight down
+ if(need_flip)
+ {
+ if(t_x >= 0) t_x = 180 - t_x; else t_x = -180 - t_x;
+ if(t_y > 0) t_y -= 180; else t_y += 180;
+ if(t_z > 0) t_z -= 180; else t_z += 180;
+ }
+ return t;
+}
+
+vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
+{
+ v_x = -v_x;
+ v = AnglesTransform_ApplyToAngles(transform, v);
+ v_x = -v_x;
+ return v;
+}
Added: trunk/data/qcsrc/warpzonelib/anglestransform.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/anglestransform.qh (rev 0)
+++ trunk/data/qcsrc/warpzonelib/anglestransform.qh 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,15 @@
+void fixedmakevectors(vector a);
+#define fixedvectoangles2 vectoangles2
+#define fixedvectoangles vectoangles
+
+vector AnglesTransform_Apply(vector transform, vector v);
+vector AnglesTransform_Multiply(vector t1, vector t2);
+vector AnglesTransform_Invert(vector transform);
+vector AnglesTransform_TurnDirectionFU(vector transform);
+vector AnglesTransform_TurnDirectionFR(vector transform);
+vector AnglesTransform_Divide(vector to_transform, vector from_transform);
+
+vector AnglesTransform_Normalize(vector t, float minimize_roll); // makes sure all angles are in their range: yaw in -180..180, pitch in -90..90, roll in -180..180 (or if minimize_roll is set, pitch in -180..180, roll in -90..90)
+
+#define AnglesTransform_ApplyToAngles(t,v) AnglesTransform_Multiply(t, v)
+vector AnglesTransform_ApplyToVAngles(vector transform, vector v);
Added: trunk/data/qcsrc/warpzonelib/client.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/client.qc (rev 0)
+++ trunk/data/qcsrc/warpzonelib/client.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,84 @@
+float FL_CAMERA = 8192;
+.vector warpzone_transform;
+void WarpZone_Read(float isnew)
+{
+ if not(self.enemy)
+ {
+ self.enemy = spawn();
+ self.enemy.classname = "warpzone_from";
+ }
+ self.classname = "warpzone_to";
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ self.modelindex = ReadShort();
+ self.mins_x = ReadCoord();
+ self.mins_y = ReadCoord();
+ self.mins_z = ReadCoord();
+ self.maxs_x = ReadCoord();
+ self.maxs_y = ReadCoord();
+ self.maxs_z = ReadCoord();
+ self.enemy.oldorigin_x = ReadCoord();
+ self.enemy.oldorigin_y = ReadCoord();
+ self.enemy.oldorigin_z = ReadCoord();
+ self.enemy.avelocity_x = ReadCoord();
+ self.enemy.avelocity_y = ReadCoord();
+ self.enemy.avelocity_z = ReadCoord();
+ self.oldorigin_x = ReadCoord();
+ self.oldorigin_y = ReadCoord();
+ self.oldorigin_z = ReadCoord();
+ self.avelocity_x = ReadCoord();
+ self.avelocity_y = ReadCoord();
+ self.avelocity_z = ReadCoord();
+
+ self.avelocity = AnglesTransform_TurnDirectionFR(self.avelocity);
+ self.warpzone_transform = AnglesTransform_Divide(self.avelocity, self.enemy.avelocity);
+
+ print(vtos(AnglesTransform_Apply(self.warpzone_transform, '0 0 1')), "\n");
+
+ self.flags = FL_CAMERA;
+ self.drawmask = MASK_NORMAL;
+
+ // link me
+ //setmodel(self, self.model);
+ setorigin(self, self.origin);
+ setsize(self, self.mins, self.maxs);
+}
+
+float warpzone_saved;
+vector warpzone_saved_origin;
+vector warpzone_saved_angles;
+void WarpZone_FixView()
+{
+ entity e;
+ float roll;
+ warpzone_saved = 0;
+ for(e = world; (e = find(e, classname, "warpzone_to")); )
+ {
+ //print(sprintf("does %s (%s to %s) touch %s?\n", e.model, vtos(e.absmin), vtos(e.absmax), vtos(pmove_org)));
+ if(BoxTouchesBrush(pmove_org, pmove_org, e, world))
+ {
+ warpzone_saved_origin = warpzone_fixview_origin;
+ warpzone_saved_angles = warpzone_fixview_angles;
+ warpzone_saved = 1;
+ roll = warpzone_fixview_angles_z;
+ warpzone_fixview_angles_z = 0;
+ warpzone_fixview_origin = AnglesTransform_Apply(e.warpzone_transform, warpzone_fixview_origin - e.enemy.oldorigin) + e.oldorigin;
+ warpzone_fixview_angles = AnglesTransform_Normalize(AnglesTransform_ApplyToVAngles(e.warpzone_transform, warpzone_fixview_angles), TRUE);
+ warpzone_fixview_angles_z = roll;
+ R_SetView(VF_ORIGIN, warpzone_fixview_origin);
+ R_SetView(VF_ANGLES, warpzone_fixview_angles);
+ break;
+ }
+ }
+}
+void WarpZone_UnFixView()
+{
+ if(warpzone_saved)
+ {
+ warpzone_fixview_origin = warpzone_saved_origin;
+ warpzone_fixview_angles = warpzone_saved_angles;
+ R_SetView(VF_ORIGIN, warpzone_fixview_origin);
+ R_SetView(VF_ANGLES, warpzone_fixview_angles);
+ }
+}
Added: trunk/data/qcsrc/warpzonelib/client.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/client.qh (rev 0)
+++ trunk/data/qcsrc/warpzonelib/client.qh 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,6 @@
+void WarpZone_Read(float bIsNewEntity);
+
+vector warpzone_fixview_origin;
+vector warpzone_fixview_angles;
+void WarpZone_FixView(); // this saves the previous values
+void WarpZone_UnFixView(); // and restores them
Added: trunk/data/qcsrc/warpzonelib/common.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/common.qc (rev 0)
+++ trunk/data/qcsrc/warpzonelib/common.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1 @@
+// empty yet
Added: trunk/data/qcsrc/warpzonelib/common.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/common.qh (rev 0)
+++ trunk/data/qcsrc/warpzonelib/common.qh 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1 @@
+// empty
Added: trunk/data/qcsrc/warpzonelib/server.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/server.qc (rev 0)
+++ trunk/data/qcsrc/warpzonelib/server.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,214 @@
+void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags)
+{
+ vector from;
+
+ makevectors (to_angles);
+
+ from = player.origin;
+ setorigin (player, to);
+ player.oldorigin = to; // for DP's unsticking
+ player.angles = to_angles;
+ player.fixangle = TRUE;
+ player.velocity = to_velocity;
+
+ if(player.effects & EF_TELEPORT_BIT)
+ player.effects &~= EF_TELEPORT_BIT;
+ else
+ player.effects |= EF_TELEPORT_BIT;
+
+ if(player.classname == "player")
+ player.flags &~= FL_ONGROUND;
+
+ WarpZone_PostTeleportPlayer(player);
+}
+
+// the transform
+.vector warpzone_origin, warpzone_angles;
+.vector warpzone_forward;
+.vector warpzone_transform;
+
+float WarpZone_Teleport(entity player)
+{
+ vector o0, a0, v0, o1, a1, v1;
+
+ o0 = player.origin + player.view_ofs;
+ v0 = player.velocity;
+ a0 = player.angles;
+
+ if((o0 - self.warpzone_origin) * self.warpzone_forward >= 0) // wrong side of the portal
+ return 2;
+ // no failure, we simply don't want to teleport yet; TODO in
+ // this situation we may want to create a temporary clone
+ // entity of the player to fix graphics glitch
+
+ o1 = AnglesTransform_Apply(self.warpzone_transform, o0 - self.warpzone_origin) + self.enemy.warpzone_origin;
+ v1 = AnglesTransform_Apply(self.warpzone_transform, v0);
+ if(player.classname == "player")
+ a1 = AnglesTransform_Normalize(AnglesTransform_ApplyToVAngles(self.warpzone_transform, player.v_angle), TRUE);
+ else
+ a1 = AnglesTransform_ApplyToAngles(self.warpzone_transform, a0);
+
+ // put him inside solid
+ tracebox(o1 - player.view_ofs, player.mins, player.maxs, o1 - player.view_ofs, MOVE_NOMONSTERS, player);
+ if(trace_startsolid)
+ {
+ setorigin(player, o1 - player.view_ofs);
+ if(WarpZoneLib_MoveOutOfSolid(player))
+ {
+ setorigin(player, o0);
+ o1 = player.origin + player.view_ofs;
+ }
+ else
+ {
+ setorigin(player, o0 - player.view_ofs);
+ return 0; // cannot fix
+ }
+ }
+
+ if((o1 - self.enemy.warpzone_origin) * self.enemy.warpzone_forward <= 0) // wrong side of the portal post-teleport
+ {
+ print("inconsistent warp zones or evil roundoff error\n");
+ return 0;
+ }
+
+ //print(sprintf("warpzone: %f %f %f -> %f %f %f\n", o0_x, o0_y, o0_z, o1_x, o1_y, o1_z));
+
+ //o1 = trace_endpos;
+ TeleportPlayer(self, other, o1 - player.view_ofs, a1, v1, '0 0 0', '0 0 0', TELEPORT_FLAGS_WARPZONE);
+
+ return 1;
+}
+
+void WarpZone_Touch (void)
+{
+ entity oldself, e;
+
+ // FIXME needs a better check to know what is safe to teleport and what not
+ if(other.movetype == MOVETYPE_NONE)
+ return;
+
+ EXACTTRIGGER_TOUCH;
+
+ e = self.enemy;
+ if(WarpZone_Teleport(other))
+ {
+ if(self.aiment.target)
+ {
+ oldself = self;
+ activator = other;
+ self = self.aiment;
+ SUB_UseTargets();
+ self = oldself;
+ }
+ }
+ else
+ {
+ dprint("WARPZONE FAIL AHAHAHAHAH))\n");
+ }
+}
+
+float WarpZone_Send(entity to, float sendflags)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE);
+
+ // we need THESE to render the warpzone (and cull properly)...
+ WriteCoord(MSG_ENTITY, self.origin_x);
+ WriteCoord(MSG_ENTITY, self.origin_y);
+ WriteCoord(MSG_ENTITY, self.origin_z);
+
+ WriteShort(MSG_ENTITY, self.modelindex);
+ WriteCoord(MSG_ENTITY, self.mins_x);
+ WriteCoord(MSG_ENTITY, self.mins_y);
+ WriteCoord(MSG_ENTITY, self.mins_z);
+ WriteCoord(MSG_ENTITY, self.maxs_x);
+ WriteCoord(MSG_ENTITY, self.maxs_y);
+ WriteCoord(MSG_ENTITY, self.maxs_z);
+
+ // we need THESE to calculate the proper transform
+ WriteCoord(MSG_ENTITY, self.warpzone_origin_x);
+ WriteCoord(MSG_ENTITY, self.warpzone_origin_y);
+ WriteCoord(MSG_ENTITY, self.warpzone_origin_z);
+ WriteCoord(MSG_ENTITY, self.warpzone_angles_x);
+ WriteCoord(MSG_ENTITY, self.warpzone_angles_y);
+ WriteCoord(MSG_ENTITY, self.warpzone_angles_z);
+ WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_x);
+ WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_y);
+ WriteCoord(MSG_ENTITY, self.enemy.warpzone_origin_z);
+ WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_x);
+ WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_y);
+ WriteCoord(MSG_ENTITY, self.enemy.warpzone_angles_z);
+
+ return TRUE;
+}
+
+void WarpZone_InitStep_SpawnFunc()
+{
+ // warp zone entities must have:
+ // "killtarget" pointing to a target_position with a direction arrow
+ // that points AWAY from the warp zone, and that is inside
+ // the warp zone trigger
+ // "target" pointing to an identical warp zone at another place in
+ // the map, with another killtarget to designate its
+ // orientation
+
+ // TODO nexuiz specific
+ string m;
+ m = self.model;
+ EXACTTRIGGER_INIT;
+ setmodel(self, m);
+ Net_LinkEntity(self, FALSE, 0, WarpZone_Send);
+}
+
+void WarpZone_InitStep_FindTarget()
+{
+ entity e;
+
+ if(self.killtarget == "")
+ {
+ objerror("Warp zone with no killtarget");
+ return;
+ }
+ self.aiment = find(world, targetname, self.killtarget);
+ if(self.aiment == world)
+ {
+ objerror("Warp zone with nonexisting killtarget");
+ return;
+ }
+
+ // this way only one of the two ents needs to target
+ if(self.target != "")
+ {
+ e = find(world, targetname, self.target);
+ if(e)
+ {
+ self.enemy = e;
+ self.enemy.enemy = self;
+ }
+ }
+
+ // now enable touch
+ self.touch = WarpZone_Touch;
+}
+
+void WarpZone_InitStep_UpdateTransform()
+{
+ if(!self.enemy || self.enemy.enemy != self)
+ {
+ objerror("Invalid warp zone detected. Killed.");
+ return;
+ }
+
+ // 1. update this, and the enemy, warp zone
+ self.warpzone_origin = self.aiment.origin;
+ self.warpzone_angles = self.aiment.angles;
+ self.enemy.warpzone_origin = self.enemy.aiment.origin;
+ self.enemy.warpzone_angles = self.enemy.aiment.angles;
+
+ // 2. combine the angle transforms
+ // current forward must be turned into previous backward
+ self.warpzone_transform = AnglesTransform_Divide(AnglesTransform_TurnDirectionFR(self.enemy.warpzone_angles), self.warpzone_angles);
+
+ // 3. store off a saved forward vector for plane hit decisions
+ fixedmakevectors(self.warpzone_angles);
+ self.warpzone_forward = v_forward;
+}
Added: trunk/data/qcsrc/warpzonelib/server.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/server.qh (rev 0)
+++ trunk/data/qcsrc/warpzonelib/server.qh 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,10 @@
+void WarpZone_InitStep_SpawnFunc();
+void WarpZone_InitStep_FindTarget();
+void WarpZone_InitStep_UpdateTransform();
+
+// THESE must be defined by calling QC code:
+void spawnfunc_trigger_warpzone(); // must call the init steps in order, first all spawnfunc init steps, then all findtarget init steps, then all updatetransform init steps
+void WarpZone_PostTeleportPlayer(entity pl);
+
+// server must also define a float called ENT_CLIENT_WARPZONE for the initial byte of WarpZone entities
+const float ENT_CLIENT_WARPZONE;
Added: trunk/data/qcsrc/warpzonelib/util_server.qc
===================================================================
--- trunk/data/qcsrc/warpzonelib/util_server.qc (rev 0)
+++ trunk/data/qcsrc/warpzonelib/util_server.qc 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1,55 @@
+void WarpZoneLib_MoveOutOfSolid_Expand(entity e, vector by)
+{
+ float eps = 0.0625;
+ tracebox(e.origin, e.mins - '1 1 1' * eps, e.maxs + '1 1 1' * eps, e.origin + by, MOVE_WORLDONLY, e);
+ if (trace_startsolid)
+ return;
+ if (trace_fraction < 1)
+ {
+ // hit something
+ // adjust origin in the other direction...
+ setorigin(e,e.origin - by * (1 - trace_fraction));
+ }
+}
+
+float WarpZoneLib_MoveOutOfSolid(entity e)
+{
+ vector o, m0, m1;
+
+ o = e.origin;
+ traceline(o, o, MOVE_WORLDONLY, e);
+ if (trace_startsolid)
+ return FALSE;
+
+ tracebox(o, e.mins, e.maxs, o, MOVE_WORLDONLY, e);
+ if (!trace_startsolid)
+ return TRUE;
+
+ m0 = e.mins;
+ m1 = e.maxs;
+ e.mins = '0 0 0';
+ e.maxs = '0 0 0';
+ WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m0_x);
+ e.mins_x = m0_x;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m1_x);
+ e.maxs_x = m1_x;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m0_y);
+ e.mins_y = m0_y;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m1_y);
+ e.maxs_y = m1_y;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m0_z);
+ e.mins_z = m0_z;
+ WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m1_z);
+ e.maxs_z = m1_z;
+ setorigin(e, e.origin);
+
+ tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e);
+ if (trace_startsolid)
+ {
+ setorigin(e, o);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
Added: trunk/data/qcsrc/warpzonelib/util_server.qh
===================================================================
--- trunk/data/qcsrc/warpzonelib/util_server.qh (rev 0)
+++ trunk/data/qcsrc/warpzonelib/util_server.qh 2010-02-28 19:42:26 UTC (rev 8687)
@@ -0,0 +1 @@
+float WarpZoneLib_MoveOutOfSolid(entity e);
More information about the nexuiz-commits
mailing list