if(is_new)
{
self.origin = spn_origin;
- setsize(self, PL_MIN, PL_MAX);
+ setsize(self, '-16 -16 -24', '16 16 45');
droptofloor();
/*if(autocvar_cl_spawn_point_model) // needs a model first
../warpzonelib/client.qc
../warpzonelib/common.qc
../warpzonelib/mathlib.qc
+../warpzonelib/util_server.qc
vector autocvar_sv_player_crouch_viewoffset = '0 0 20';
vector autocvar_sv_player_headsize = '24 24 12';
+
+#ifdef SVQC
#define PL_VIEW_OFS autocvar_sv_player_viewoffset
#define PL_MIN autocvar_sv_player_mins
#define PL_MAX autocvar_sv_player_maxs
#define PL_CROUCH_MIN autocvar_sv_player_crouch_mins
#define PL_CROUCH_MAX autocvar_sv_player_crouch_maxs
#define PL_HEAD autocvar_sv_player_headsize
-
-// helpers
-#define PL_VIEW_OFS_z autocvar_sv_player_viewoffset.z
-#define PL_MIN_z autocvar_sv_player_mins.z
-#define PL_MAX_z autocvar_sv_player_maxs.z
-#define PL_CROUCH_VIEW_OFS_z autocvar_sv_player_crouch_viewoffset.z
-#define PL_CROUCH_MIN_z autocvar_sv_player_mins.z
-#define PL_HEAD_x autocvar_sv_player_headsize.x
-#define PL_HEAD_y autocvar_sv_player_headsize.y
-#define PL_HEAD_z autocvar_sv_player_headsize.z
+#elif defined(CSQC)
+#define PL_VIEW_OFS vec3(getstatf(STAT_PL_VIEW_OFS1), getstatf(STAT_PL_VIEW_OFS2), getstatf(STAT_PL_VIEW_OFS3))
+#define PL_MIN vec3(getstatf(STAT_PL_MIN1), getstatf(STAT_PL_MIN2), getstatf(STAT_PL_MIN3))
+#define PL_MAX vec3(getstatf(STAT_PL_MAX1), getstatf(STAT_PL_MAX2), getstatf(STAT_PL_MAX3))
+#define PL_CROUCH_VIEW_OFS vec3(getstatf(STAT_PL_CROUCH_VIEW_OFS1), getstatf(STAT_PL_CROUCH_VIEW_OFS2), getstatf(STAT_PL_CROUCH_VIEW_OFS3))
+#define PL_CROUCH_MIN vec3(getstatf(STAT_PL_CROUCH_MIN1), getstatf(STAT_PL_CROUCH_MIN2), getstatf(STAT_PL_CROUCH_MIN3))
+#define PL_CROUCH_MAX vec3(getstatf(STAT_PL_CROUCH_MAX1), getstatf(STAT_PL_CROUCH_MAX2), getstatf(STAT_PL_CROUCH_MAX3))
+#endif
// spawnpoint prios
const int SPAWN_PRIO_NEAR_TEAMMATE_FOUND = 200;
--- /dev/null
+void _Movetype_Physics_Follow() // SV_Physics_Follow
+{
+ entity e = self.move_aiment; // TODO: networking?
+
+ // LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects
+ if(self.move_angles == self.move_punchangle)
+ {
+ self.move_origin = e.move_origin + self.view_ofs;
+ }
+ else
+ {
+ vector ang, v;
+ ang_x = -self.move_punchangle_x;
+ ang_y = self.move_punchangle_y;
+ ang_z = self.move_punchangle_z;
+ makevectors(ang);
+ v_x = self.view_ofs_x * v_forward_x + self.view_ofs_y * v_right_x + self.view_ofs_z * v_up_x;
+ v_y = self.view_ofs_x * v_forward_y + self.view_ofs_y * v_right_y + self.view_ofs_z * v_up_y;
+ v_z = self.view_ofs_x * v_forward_z + self.view_ofs_y * v_right_z + self.view_ofs_z * v_up_z;
+ ang_x = -e.move_angles_x;
+ ang_y = e.move_angles_y;
+ ang_z = e.move_angles_z;
+ makevectors(ang);
+ self.move_origin_x = v_x * v_forward_x + v_y * v_forward_y + v_z * v_forward_z + e.move_origin_x;
+ self.move_origin_x = v_x * v_right_x + v_y * v_right_y + v_z * v_right_z + e.move_origin_y;
+ self.move_origin_x = v_x * v_up_x + v_y * v_up_y + v_z * v_up_z + e.move_origin_z;
+ }
+
+ self.move_angles = e.move_angles + self.v_angle;
+ _Movetype_LinkEdict(false);
+}
#include "push.qc"
#include "toss.qc"
#include "walk.qc"
+#include "step.qc"
+#include "follow.qc"
#include "movetypes.qc"
case MOVETYPE_NONE:
break;
case MOVETYPE_FOLLOW:
- error("SV_Physics_Follow not implemented");
+ _Movetype_Physics_Follow();
break;
case MOVETYPE_NOCLIP:
_Movetype_CheckWater(self);
_Movetype_LinkEdict(false);
break;
case MOVETYPE_STEP:
- error("SV_Physics_Step not implemented");
+ _Movetype_Physics_Step(movedt);
break;
case MOVETYPE_WALK:
_Movetype_Physics_Walk(movedt);
.float move_bounce_stopspeed;
.float move_nomonsters; // -1 for MOVE_NORMAL, otherwise a MOVE_ constant
+.entity move_aiment;
+.vector move_punchangle;
+
// should match sv_gameplayfix_fixedcheckwatertransition
float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
#ifdef SVQC
+.int stat_gameplayfix_upvelocityclearsonground;
+
#define GRAVITY_UNAFFECTED_BY_TICRATE autocvar_sv_gameplayfix_gravityunaffectedbyticrate
+#define UPWARD_VELOCITY_CLEARS_ONGROUND autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag
#define TICRATE sys_frametime
#elif defined(CSQC)
#define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
+#define UPWARD_VELOCITY_CLEARS_ONGROUND getstati(STAT_GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND)
#define TICRATE ticrate
#endif
--- /dev/null
+void _Movetype_Physics_Step(float dt) // SV_Physics_Step
+{
+ if(self.move_flags & FL_ONGROUND)
+ {
+ if(self.velocity_z >= (1.0 / 32.0) && UPWARD_VELOCITY_CLEARS_ONGROUND)
+ {
+ self.move_flags &= ~FL_ONGROUND;
+ _Movetype_CheckVelocity();
+ _Movetype_FlyMove(dt, true, '0 0 0', 0);
+ _Movetype_LinkEdict(true);
+ }
+ }
+ else
+ {
+ _Movetype_CheckVelocity();
+ _Movetype_FlyMove(dt, true, '0 0 0', 0);
+ _Movetype_LinkEdict(true);
+
+ // TODO? movetypesteplandevent
+ }
+
+ _Movetype_CheckWaterTransition(self);
+}
vector upmove = self.move_origin + '0 0 1';
vector downmove = self.move_origin - '0 0 1';
int type;
- if (self.move_movetype == MOVETYPE_FLYMISSILE) type = MOVE_MISSILE; else if (self.move_movetype == MOVETYPE_FLY_WORLDONLY)
+ if (self.move_movetype == MOVETYPE_FLYMISSILE)
+ type = MOVE_MISSILE;
+ else if (self.move_movetype == MOVETYPE_FLY_WORLDONLY)
type = MOVE_WORLDONLY;
else if (self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
type = MOVE_NOMONSTERS;
- else type = MOVE_NORMAL;
+ else type = MOVE_NORMAL;
tracebox(upmove, self.mins, self.maxs, downmove, type, self);
if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
clip |= 1; // but we HAVE found a floor
void Physics_AddStats()
{
+ // static view offset and hitbox vectors
+ // networked for all you bandwidth pigs out there
+ addstat(STAT_PL_VIEW_OFS1, AS_FLOAT, stat_pl_view_ofs_x);
+ addstat(STAT_PL_VIEW_OFS2, AS_FLOAT, stat_pl_view_ofs_y);
+ addstat(STAT_PL_VIEW_OFS3, AS_FLOAT, stat_pl_view_ofs_z);
+ addstat(STAT_PL_CROUCH_VIEW_OFS1, AS_FLOAT, stat_pl_crouch_view_ofs_x);
+ addstat(STAT_PL_CROUCH_VIEW_OFS2, AS_FLOAT, stat_pl_crouch_view_ofs_y);
+ addstat(STAT_PL_CROUCH_VIEW_OFS3, AS_FLOAT, stat_pl_crouch_view_ofs_z);
+
+ addstat(STAT_PL_MIN1, AS_FLOAT, stat_pl_min_x);
+ addstat(STAT_PL_MIN2, AS_FLOAT, stat_pl_min_y);
+ addstat(STAT_PL_MIN3, AS_FLOAT, stat_pl_min_z);
+ addstat(STAT_PL_MAX1, AS_FLOAT, stat_pl_max_x);
+ addstat(STAT_PL_MAX2, AS_FLOAT, stat_pl_max_y);
+ addstat(STAT_PL_MAX3, AS_FLOAT, stat_pl_max_z);
+ addstat(STAT_PL_CROUCH_MIN1, AS_FLOAT, stat_pl_crouch_min_x);
+ addstat(STAT_PL_CROUCH_MIN2, AS_FLOAT, stat_pl_crouch_min_y);
+ addstat(STAT_PL_CROUCH_MIN3, AS_FLOAT, stat_pl_crouch_min_z);
+ addstat(STAT_PL_CROUCH_MAX1, AS_FLOAT, stat_pl_crouch_max_x);
+ addstat(STAT_PL_CROUCH_MAX2, AS_FLOAT, stat_pl_crouch_max_y);
+ addstat(STAT_PL_CROUCH_MAX3, AS_FLOAT, stat_pl_crouch_max_z);
+
// g_movementspeed hack
addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
addstat(STAT_MOVEVARS_FRICTION_ONLAND, AS_FLOAT, stat_sv_friction_on_land);
addstat(STAT_MOVEVARS_FRICTION_SLICK, AS_FLOAT, stat_sv_friction_slick);
addstat(STAT_GAMEPLAYFIX_EASIERWATERJUMP, AS_INT, stat_gameplayfix_easierwaterjump);
+
+ addstat(STAT_GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, AS_INT, stat_gameplayfix_upvelocityclearsonground);
}
void Physics_UpdateStats(float maxspd_mod)
{
+ // blah
+ self.stat_pl_view_ofs = PL_VIEW_OFS;
+ self.stat_pl_crouch_view_ofs = PL_CROUCH_VIEW_OFS;
+
+ self.stat_pl_min = PL_MIN;
+ self.stat_pl_max = PL_MAX;
+ self.stat_pl_crouch_min = PL_CROUCH_MIN;
+ self.stat_pl_crouch_max = PL_CROUCH_MAX;
+
self.stat_sv_airaccel_qw = AdjustAirAccelQW(autocvar_sv_airaccel_qw, maxspd_mod);
if (autocvar_sv_airstrafeaccel_qw)
self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(autocvar_sv_airstrafeaccel_qw, maxspd_mod);
self.stat_sv_friction_slick = PHYS_FRICTION_SLICK;
self.stat_gameplayfix_easierwaterjump = GAMEPLAYFIX_EASIERWATERJUMP;
+
+ self.stat_gameplayfix_upvelocityclearsonground = UPWARD_VELOCITY_CLEARS_ONGROUND;
}
#endif
-float IsMoveInDirection(vector mv, float angle) // key mix factor
+float IsMoveInDirection(vector mv, float ang) // key mix factor
{
if (mv_x == 0 && mv_y == 0)
return 0; // avoid division by zero
- angle -= RAD2DEG * atan2(mv_y, mv_x);
- angle = remainder(angle, 360) / 45;
- return angle > 1 ? 0 : angle < -1 ? 0 : 1 - fabs(angle);
+ ang -= RAD2DEG * atan2(mv_y, mv_x);
+ ang = remainder(ang, 360) / 45;
+ return ang > 1 ? 0 : ang < -1 ? 0 : 1 - fabs(ang);
}
float GeomLerp(float a, float lerp, float b)
origin1_z += self.mins_z + 1;
self.waterlevel = WATERLEVEL_NONE;
- self.watertype = (pointcontents(origin1) == CONTENT_WATER);
+ int thepoint = pointcontents(origin1);
+
+ self.watertype = (thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME);
if(self.watertype)
{
self.waterlevel = WATERLEVEL_WETFEET;
origin1_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5;
- if(pointcontents(origin1) == CONTENT_WATER)
+ thepoint = pointcontents(origin1);
+ if(thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
{
self.waterlevel = WATERLEVEL_SWIMMING;
origin1_z = self.origin_z + 22;
- if(pointcontents(origin1) == CONTENT_WATER)
+ thepoint = pointcontents(origin1);
+ if(thepoint == CONTENT_WATER || thepoint == CONTENT_LAVA || thepoint == CONTENT_SLIME)
self.waterlevel = WATERLEVEL_SUBMERGED;
}
}
void PM_ClientMovement_Move()
{
#ifdef CSQC
- float t = PHYS_INPUT_TIMELENGTH;
- vector primalvelocity = self.velocity;
+ int bump;
+ float t;
+ float f;
+ vector neworigin;
+ vector currentorigin2;
+ vector neworigin2;
+ vector primalvelocity;
+
+ vector trace1_endpos = '0 0 0';
+ vector trace2_endpos = '0 0 0';
+ vector trace3_endpos = '0 0 0';
+ float trace1_fraction = 0;
+ float trace2_fraction = 0;
+ float trace3_fraction = 0;
+ vector trace1_plane_normal = '0 0 0';
+ vector trace2_plane_normal = '0 0 0';
+ vector trace3_plane_normal = '0 0 0';
+
+
PM_ClientMovement_UpdateStatus(false);
- float bump = 0;
- for (bump = 0; bump < MAX_CLIP_PLANES && (self.velocity * self.velocity) > 0; bump++)
+ primalvelocity = self.velocity;
+ for(bump = 0, t = PHYS_INPUT_TIMELENGTH; bump < 8 && (self.velocity * self.velocity) > 0; bump++)
{
- vector neworigin = self.origin + t * self.velocity;
+ neworigin = self.origin + t * self.velocity;
tracebox(self.origin, self.mins, self.maxs, neworigin, MOVE_NORMAL, self);
- float old_trace1_fraction = trace_fraction;
- vector old_trace1_endpos = trace_endpos;
- vector old_trace1_plane_normal = trace_plane_normal;
- if (trace_fraction < 1 && trace_plane_normal_z == 0)
+ trace1_endpos = trace_endpos;
+ trace1_fraction = trace_fraction;
+ trace1_plane_normal = trace_plane_normal;
+ if(trace1_fraction < 1 && trace1_plane_normal_z == 0)
{
// may be a step or wall, try stepping up
// first move forward at a higher level
- vector currentorigin2 = self.origin;
+ currentorigin2 = self.origin;
currentorigin2_z += PHYS_STEPHEIGHT;
- vector neworigin2 = neworigin;
- neworigin2_z = self.origin_z + PHYS_STEPHEIGHT;
+ neworigin2 = neworigin;
+ neworigin2_z += PHYS_STEPHEIGHT;
tracebox(currentorigin2, self.mins, self.maxs, neworigin2, MOVE_NORMAL, self);
- if (!trace_startsolid)
+ trace2_endpos = trace_endpos;
+ trace2_fraction = trace_fraction;
+ trace2_plane_normal = trace_plane_normal;
+ if(!trace_startsolid)
{
// then move down from there
- currentorigin2 = trace_endpos;
- neworigin2 = trace_endpos;
+ currentorigin2 = trace2_endpos;
+ neworigin2 = trace2_endpos;
neworigin2_z = self.origin_z;
- float old_trace2_fraction = trace_fraction;
- vector old_trace2_plane_normal = trace_plane_normal;
tracebox(currentorigin2, self.mins, self.maxs, neworigin2, MOVE_NORMAL, self);
+ trace3_endpos = trace_endpos;
+ trace3_fraction = trace_fraction;
+ trace3_plane_normal = trace_plane_normal;
// accept the new trace if it made some progress
- if (fabs(trace_endpos_x - old_trace1_endpos_x) >= 0.03125 || fabs(trace_endpos_y - old_trace1_endpos_y) >= 0.03125)
+ if(fabs(trace3_endpos_x - trace1_endpos_x) >= 0.03125 || fabs(trace3_endpos_y - trace1_endpos_y) >= 0.03125)
{
- trace_fraction = old_trace2_fraction;
- trace_endpos = trace_endpos;
- trace_plane_normal = old_trace2_plane_normal;
- }
- else
- {
- trace_fraction = old_trace1_fraction;
- trace_endpos = old_trace1_endpos;
- trace_plane_normal = old_trace1_plane_normal;
+ trace1_endpos = trace2_endpos;
+ trace1_fraction = trace2_fraction;
+ trace1_plane_normal = trace2_plane_normal;
+ trace1_endpos = trace3_endpos;
}
}
}
// check if it moved at all
- if (trace_fraction >= 0.001)
- setorigin(self, trace_endpos);
+ if(trace1_fraction >= 0.001)
+ setorigin(self, trace1_endpos);
// check if it moved all the way
- if (trace_fraction == 1)
+ if(trace1_fraction == 1)
break;
// this is only really needed for nogravityonground combined with gravityunaffectedbyticrate
// <LordHavoc> I'm pretty sure I commented it out solely because it seemed redundant
// this got commented out in a change that supposedly makes the code match QW better
- // so if this is broken, maybe put it in an if (cls.protocol != PROTOCOL_QUAKEWORLD) block
- if (trace_plane_normal_z > 0.7)
+ // so if this is broken, maybe put it in an if(cls.protocol != PROTOCOL_QUAKEWORLD) block
+ if(trace1_plane_normal_z > 0.7)
SET_ONGROUND(self);
- t -= t * trace_fraction;
+ t -= t * trace1_fraction;
- float f = self.velocity * trace_plane_normal;
- self.velocity -= f * trace_plane_normal;
+ f = (self.velocity * trace1_plane_normal);
+ self.velocity = self.velocity + -f * trace1_plane_normal;
}
- if (pmove_waterjumptime > 0)
+ if(pmove_waterjumptime > 0)
self.velocity = primalvelocity;
#endif
}
void CPM_PM_Aircontrol(vector wishdir, float wishspeed)
{
- float k = 32 * (2 * IsMoveInDirection(PHYS_INPUT_MOVEVALUES(self), 0) - 1);
+ float k = 32 * (2 * IsMoveInDirection(self.movement, 0) - 1);
if (k <= 0)
return;
void CheckWaterJump()
{
// check for a jump-out-of-water
- makevectors(PHYS_INPUT_ANGLES(self));
+ makevectors(self.v_angle);
vector start = self.origin;
start_z += 8;
v_forward_z = 0;
vector rigvel;
vector angles_save = self.angles;
- float accel = bound(-1, PHYS_INPUT_MOVEVALUES(self).x / PHYS_MAXSPEED(self), 1);
- float steer = bound(-1, PHYS_INPUT_MOVEVALUES(self).y / PHYS_MAXSPEED(self), 1);
+ float accel = bound(-1, self.movement.x / PHYS_MAXSPEED(self), 1);
+ float steer = bound(-1, self.movement.y / PHYS_MAXSPEED(self), 1);
if (g_bugrigs_reverse_speeding)
{
if (self.nickspamcount >= autocvar_g_nick_flood_penalty_yellow)
{
// slight annoyance for nick change scripts
- PHYS_INPUT_MOVEVALUES(self) = -1 * PHYS_INPUT_MOVEVALUES(self);
+ self.movement = -1 * self.movement;
self.BUTTON_ATCK = self.BUTTON_JUMP = self.BUTTON_ATCK2 = self.BUTTON_ZOOM = self.BUTTON_CROUCH = self.BUTTON_HOOK = self.BUTTON_USE = 0;
if (self.nickspamcount >= autocvar_g_nick_flood_penalty_red) // if you are persistent and the slight annoyance above does not stop you, I'll show you!
{
- PHYS_INPUT_ANGLES(self)_x = random() * 360;
- PHYS_INPUT_ANGLES(self)_y = random() * 360;
+ self.v_angle_x = random() * 360;
+ self.v_angle_y = random() * 360;
// at least I'm not forcing retardedview by also assigning to angles_z
self.fixangle = true;
}
#endif
)
{
- PHYS_INPUT_MOVEVALUES(self)_x = bound(-5, PHYS_INPUT_MOVEVALUES(self).x, 5);
- PHYS_INPUT_MOVEVALUES(self)_y = bound(-5, PHYS_INPUT_MOVEVALUES(self).y, 5);
- PHYS_INPUT_MOVEVALUES(self)_z = bound(-5, PHYS_INPUT_MOVEVALUES(self).z, 5);
+ self.movement_x = bound(-5, self.movement.x, 5);
+ self.movement_y = bound(-5, self.movement.y, 5);
+ self.movement_z = bound(-5, self.movement.z, 5);
}
else
- PHYS_INPUT_MOVEVALUES(self) = '0 0 0';
+ self.movement = '0 0 0';
vector midpoint = ((self.absmin + self.absmax) * 0.5);
if (pointcontents(midpoint) == CONTENT_WATER)
#ifdef SVQC
if (!self.player_blocked)
return;
- PHYS_INPUT_MOVEVALUES(self) = '0 0 0';
+ self.movement = '0 0 0';
self.disableclientprediction = 1;
#endif
}
UNSET_ONGROUND(self);
self.velocity = self.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION);
- makevectors(PHYS_INPUT_ANGLES(self));
- //wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x + v_right * PHYS_INPUT_MOVEVALUES(self).y + v_up * PHYS_INPUT_MOVEVALUES(self).z;
- vector wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x
- + v_right * PHYS_INPUT_MOVEVALUES(self).y
- + '0 0 1' * PHYS_INPUT_MOVEVALUES(self).z;
+ makevectors(self.v_angle);
+ //wishvel = v_forward * self.movement.x + v_right * self.movement.y + v_up * self.movement.z;
+ vector wishvel = v_forward * self.movement.x
+ + v_right * self.movement.y
+ + '0 0 1' * self.movement.z;
// acceleration
vector wishdir = normalize(wishvel);
float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(self) * maxspd_mod);
// this mimics quakeworld code
if (jump && self.waterlevel == WATERLEVEL_SWIMMING && self.velocity_z >= -180)
{
- vector yawangles = '0 1 0' * PHYS_INPUT_ANGLES(self).y;
+ vector yawangles = '0 1 0' * self.v_angle.y;
makevectors(yawangles);
vector forward = v_forward;
vector spot = self.origin + 24 * forward;
}
}
}
- makevectors(PHYS_INPUT_ANGLES(self));
- //wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x + v_right * PHYS_INPUT_MOVEVALUES(self).y + v_up * PHYS_INPUT_MOVEVALUES(self).z;
- vector wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x
- + v_right * PHYS_INPUT_MOVEVALUES(self).y
- + '0 0 1' * PHYS_INPUT_MOVEVALUES(self).z;
+ makevectors(self.v_angle);
+ //wishvel = v_forward * self.movement.x + v_right * self.movement.y + v_up * self.movement.z;
+ vector wishvel = v_forward * self.movement.x
+ + v_right * self.movement.y
+ + '0 0 1' * self.movement.z;
if (wishvel == '0 0 0')
wishvel = '0 0 -60'; // drift towards bottom
}
self.velocity = self.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION);
- makevectors(PHYS_INPUT_ANGLES(self));
- //wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x + v_right * PHYS_INPUT_MOVEVALUES(self).y + v_up * PHYS_INPUT_MOVEVALUES(self).z;
- vector wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self)_x
- + v_right * PHYS_INPUT_MOVEVALUES(self)_y
- + '0 0 1' * PHYS_INPUT_MOVEVALUES(self)_z;
+ makevectors(self.v_angle);
+ //wishvel = v_forward * self.movement.x + v_right * self.movement.y + v_up * self.movement.z;
+ vector wishvel = v_forward * self.movement_x
+ + v_right * self.movement_y
+ + '0 0 1' * self.movement_z;
self.velocity_z += g;
if (self.ladder_entity.classname == "func_water")
{
void PM_jetpack(float maxspd_mod)
{
- //makevectors(PHYS_INPUT_ANGLES(self).y * '0 1 0');
- makevectors(PHYS_INPUT_ANGLES(self));
- vector wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self)_x
- + v_right * PHYS_INPUT_MOVEVALUES(self)_y;
+ //makevectors(self.v_angle.y * '0 1 0');
+ makevectors(self.v_angle);
+ vector wishvel = v_forward * self.movement_x
+ + v_right * self.movement_y;
// add remaining speed as Z component
float maxairspd = PHYS_MAXAIRSPEED * max(1, maxspd_mod);
// fix speedhacks :P
}
// walking
- makevectors(PHYS_INPUT_ANGLES(self).y * '0 1 0');
- vector wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x
- + v_right * PHYS_INPUT_MOVEVALUES(self).y;
+ makevectors(self.v_angle.y * '0 1 0');
+ vector wishvel = v_forward * self.movement.x
+ + v_right * self.movement.y;
// acceleration
vector wishdir = normalize(wishvel);
float wishspeed = vlen(wishvel);
void PM_air(float buttons_prev, float maxspd_mod)
{
- makevectors(PHYS_INPUT_ANGLES(self).y * '0 1 0');
- vector wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x
- + v_right * PHYS_INPUT_MOVEVALUES(self).y;
+ makevectors(self.v_angle.y * '0 1 0');
+ vector wishvel = v_forward * self.movement.x
+ + v_right * self.movement.y;
// acceleration
vector wishdir = normalize(wishvel);
float wishspeed = vlen(wishvel);
// dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
// log dv/dt = logaccel + logmaxspeed (when slow)
// log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
- float strafity = IsMoveInDirection(PHYS_INPUT_MOVEVALUES(self), -90) + IsMoveInDirection(PHYS_INPUT_MOVEVALUES(self), +90); // if one is nonzero, other is always zero
+ float strafity = IsMoveInDirection(self.movement, -90) + IsMoveInDirection(self.movement, +90); // if one is nonzero, other is always zero
if (PHYS_MAXAIRSTRAFESPEED)
wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod));
if (PHYS_AIRSTRAFEACCELERATE)
(1 - GeomLerp(1 - fabs(PHYS_AIRACCEL_QW(self)), strafity, 1 - fabs(PHYS_AIRSTRAFEACCEL_QW(self))));
// !CPM
- if (PHYS_WARSOWBUNNY_TURNACCEL && accelerating && PHYS_INPUT_MOVEVALUES(self).y == 0 && PHYS_INPUT_MOVEVALUES(self).x != 0)
+ if (PHYS_WARSOWBUNNY_TURNACCEL && accelerating && self.movement.y == 0 && self.movement.x != 0)
PM_AirAccelerate(wishdir, wishspeed2);
else
PM_Accelerate(wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, PHYS_AIRACCEL_QW_STRETCHFACTOR(self), PHYS_AIRACCEL_SIDEWAYS_FRICTION / maxairspd, PHYS_AIRSPEEDLIMIT_NONQW(self));
#ifdef CSQC
self.items = getstati(STAT_ITEMS, 0, 24);
+ self.movement = PHYS_INPUT_MOVEVALUES(self);
+
+ self.v_angle = PHYS_INPUT_ANGLES(self);
+ self.angles = PHYS_WORLD_ANGLES(self);
+
self.team = myteam + 1; // is this correct?
if (!(PHYS_INPUT_BUTTON_JUMP(self))) // !jump
UNSET_JUMP_HELD(self); // canjump = true
#ifdef SVQC
if (sv_maxidle > 0)
{
- if (buttons != self.buttons_old || PHYS_INPUT_MOVEVALUES(self) != self.movement_old || PHYS_INPUT_ANGLES(self) != self.v_angle_old)
+ if (buttons != self.buttons_old || self.movement != self.movement_old || self.v_angle != self.v_angle_old)
self.parm_idlesince = time;
}
#endif
float buttons_prev = self.buttons_old;
self.buttons_old = buttons;
- self.movement_old = PHYS_INPUT_MOVEVALUES(self);
- self.v_angle_old = PHYS_INPUT_ANGLES(self);
+ self.movement_old = self.movement;
+ self.v_angle_old = self.v_angle;
PM_check_nickspam();
#ifdef SVQC
if (!IS_PLAYER(self))
{
- maxspeed_mod *= autocvar_sv_spectator_speed_multiplier;
+ maxspeed_mod = autocvar_sv_spectator_speed_multiplier;
if (!self.spectatorspeed)
self.spectatorspeed = maxspeed_mod;
if (self.impulse && self.impulse <= 19 || (self.impulse >= 200 && self.impulse <= 209) || (self.impulse >= 220 && self.impulse <= 229))
} // otherwise just clear
self.impulse = 0;
}
- maxspeed_mod *= self.spectatorspeed;
+ maxspeed_mod = self.spectatorspeed;
+ }
+
+ float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED) * maxspeed_mod;
+ if(self.speed != spd)
+ {
+ self.speed = spd;
+ string temps = ftos(spd);
+ stuffcmd(self, strcat("cl_forwardspeed ", temps, "\n"));
+ stuffcmd(self, strcat("cl_backspeed ", temps, "\n"));
+ stuffcmd(self, strcat("cl_sidespeed ", temps, "\n"));
+ stuffcmd(self, strcat("cl_upspeed ", temps, "\n"));
}
#endif
#ifdef SVQC
if (!self.fixangle && !g_bugrigs)
- self.angles = '0 1 0' * PHYS_INPUT_ANGLES(self).y;
+ self.angles = '0 1 0' * self.v_angle.y;
#endif
PM_check_hitground();
.float watertype;
.int items;
+ .vector movement;
+ .vector v_angle;
+
// TODO
#define IS_CLIENT(s) (s).isplayermodel
#define IS_PLAYER(s) (s).isplayermodel
#elif defined(SVQC)
+ .vector stat_pl_view_ofs;
+ .vector stat_pl_crouch_view_ofs;
+
+ .vector stat_pl_min;
+ .vector stat_pl_max;
+ .vector stat_pl_crouch_min;
+ .vector stat_pl_crouch_max;
+
.float stat_sv_airaccel_qw;
.float stat_sv_airstrafeaccel_qw;
.float stat_sv_airspeedlimit_nonqw;
#define SET_JUMP_HELD(s) s.flags &= ~FL_JUMPRELEASED
#define UNSET_JUMP_HELD(s) s.flags |= FL_JUMPRELEASED
- #define IS_ONGROUND(s) !!(self.flags & FL_ONGROUND)
+ #define IS_ONGROUND(s) !!(s.flags & FL_ONGROUND)
#define SET_ONGROUND(s) s.flags |= FL_ONGROUND
#define UNSET_ONGROUND(s) s.flags &= ~FL_ONGROUND
const int STAT_PLASMA = 84;
const int STAT_OK_AMMO_CHARGE = 85;
const int STAT_OK_AMMO_CHARGEPOOL = 86;
-// 87 empty?
-// 88 empty?
+const int STAT_FROZEN = 87;
+const int STAT_REVIVE_PROGRESS = 88;
// 89 empty?
// 90 empty?
// 91 empty?
/* Gamemode-specific stats end here */
-
-const int STAT_FROZEN = 105;
-const int STAT_REVIVE_PROGRESS = 106;
-// 107 empty?
-// 108 empty?
-// 109 empty?
-// 110 empty?
-// 111 empty?
-// 112 empty?
-// 113 empty?
-// 114 empty?
-// 115 empty?
-// 116 empty?
-// 117 empty?
-// 118 empty?
-// 119 empty?
+const int STAT_PL_VIEW_OFS1 = 105;
+const int STAT_PL_VIEW_OFS2 = 106;
+const int STAT_PL_VIEW_OFS3 = 107;
+const int STAT_PL_MIN1 = 108;
+const int STAT_PL_MIN2 = 109;
+const int STAT_PL_MIN3 = 110;
+const int STAT_PL_MAX1 = 111;
+const int STAT_PL_MAX2 = 112;
+const int STAT_PL_MAX3 = 113;
+const int STAT_PL_CROUCH_MIN1 = 114;
+const int STAT_PL_CROUCH_MIN2 = 115;
+const int STAT_PL_CROUCH_MIN3 = 116;
+const int STAT_PL_CROUCH_MAX1 = 117;
+const int STAT_PL_CROUCH_MAX2 = 118;
+const int STAT_PL_CROUCH_MAX3 = 119;
+const int STAT_PL_CROUCH_VIEW_OFS1 = 117;
+const int STAT_PL_CROUCH_VIEW_OFS2 = 118;
+const int STAT_PL_CROUCH_VIEW_OFS3 = 119;
// 120 empty?
// 121 empty?
// 122 empty?
// 165 empty?
// 166 empty?
// 167 empty?
-// 168 empty?
+const int STAT_GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND = 168;
const int STAT_BUGRIGS_REVERSE_STOPPING = 169;
const int STAT_BUGRIGS_REVERSE_SPINNING = 170;
const int STAT_BUGRIGS_CAR_JUMPING = 171;
button_fire ();
}
-void button_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+void button_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
if(self.spawnflags & DOOR_NOSPLASH)
if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
}
}
-void door_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+void door_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
entity oself;
if(self.spawnflags & DOOR_NOSPLASH)
void door_link()
{
// set size now, as everything is loaded
- FixSize(self);
- Net_LinkEntity(self, false, 0, door_send);
+ //FixSize(self);
+ //Net_LinkEntity(self, false, 0, door_send);
}
#endif
sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
}
-void fd_secret_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+void fd_secret_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
fd_secret_use();
}
WriteString(MSG_ENTITY, self.classname);
WriteByte(MSG_ENTITY, self.skin);
WriteByte(MSG_ENTITY, self.speed);
+ WriteString(MSG_ENTITY, self.mdl);
trigger_common_write(false);
void func_ladder_link()
{
- Net_LinkEntity(self, false, 0, func_ladder_send);
+ //self.SendEntity = func_ladder_send;
+ //self.SendFlags = 0xFFFFFF;
+ //self.model = "null";
}
void spawnfunc_func_ladder()
{
+ self.mdl = self.model;
EXACTTRIGGER_INIT;
self.touch = func_ladder_touch;
void spawnfunc_func_water()
{
+ self.mdl = self.model;
EXACTTRIGGER_INIT;
self.touch = func_ladder_touch;
self.classname = strzone(ReadString());
self.skin = ReadByte();
self.speed = ReadByte();
+ self.model = strzone(ReadString());
trigger_common_read(false);
+ self.mins = self.maxs = '0 0 0';
self.solid = SOLID_TRIGGER;
self.draw = trigger_draw_generic;
self.drawmask = MASK_NORMAL;
self.move_time = time;
self.entremove = trigger_remove_generic;
+
+ //precache_model(self.mdl);
+ EXACTTRIGGER_INIT;
}
#endif
void plat_link()
{
- Net_LinkEntity(self, 0, false, plat_send);
+ //Net_LinkEntity(self, 0, false, plat_send);
}
void spawnfunc_func_plat()
void train_link()
{
- Net_LinkEntity(self, 0, false, train_send);
+ //Net_LinkEntity(self, 0, false, train_send);
}
void func_train_find()
void corner_link()
{
- Net_LinkEntity(self, false, 0, corner_send);
+ //Net_LinkEntity(self, false, 0, corner_send);
}
void spawnfunc_path_corner()
{
EXACTTRIGGER_INIT;
self.active = ACTIVE_ACTIVE;
- self.trigger_touch = trigger_hurt_touch;
- self.think = trigger_think_generic;
- self.nextthink = time;
+ self.touch = trigger_hurt_touch;
self.use = trigger_hurt_use;
self.enemy = world; // I hate you all
if (!self.dmg)
void trigger_impulse_link()
{
- Net_LinkEntity(self, 0, false, trigger_impulse_send);
+ //Net_LinkEntity(self, 0, false, trigger_impulse_send);
}
void spawnfunc_trigger_impulse()
// first calculate a typical start point for the jump
org = (self.absmin + self.absmax) * 0.5;
- org_z = self.absmax.z - PL_MIN_z;
+ org_z = self.absmax.z - PL_MIN.z;
if (self.target)
{
void trigger_push_link()
{
- Net_LinkEntity(self, false, 0, trigger_push_send);
+ //Net_LinkEntity(self, false, 0, trigger_push_send);
}
#endif
#ifdef SVQC
self.active = ACTIVE_ACTIVE;
self.use = trigger_push_use;
- self.trigger_touch = trigger_push_touch;
- self.think = trigger_think_generic;
- self.nextthink = time;
+ self.touch = trigger_push_touch;
// normal push setup
if (!self.speed)
multi_trigger ();
}
-void multi_eventdamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+void multi_eventdamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
if (!self.takedamage)
return;
other = otemp;
}
-#ifdef SVQC
-void trigger_think_generic()
-{
- self.nextthink = time;
-
- entity e;
- if(self.trigger_touch)
- for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
- {
- vector emin = e.absmin, emax = e.absmax;
- if(self.solid == SOLID_BSP)
- {
- emin -= '1 1 1';
- emax += '1 1 1';
- }
- if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
- if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
- {
- other = e;
- self.trigger_touch();
- }
- }
-}
-#endif
-
#ifdef CSQC
void trigger_touch_generic(void() touchfunc)
{
void trigger_common_read(bool withtarget);
void trigger_remove_generic();
-float WarpZoneLib_ExactTrigger_Touch();
-#define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
-
.float active;
.string target;
.string targetname;
norm = trace_plane_normal;
if(trace_ent.iscreature)
{
- traceline(trace_ent.origin, trace_ent.origin + '0 0 2' * PL_MIN_z, MOVE_WORLDONLY, self);
+ traceline(trace_ent.origin, trace_ent.origin + '0 0 2' * PL_MIN.z, MOVE_WORLDONLY, self);
if(trace_fraction >= 1)
return;
if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
// get crouch state from the server
- if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z)
+ if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
self.flags &= ~FL_DUCKED;
- else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z)
+ else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
self.flags |= FL_DUCKED;
// get onground state from the server
self.velocity = v;
// get crouch state from the server
- if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z)
+ if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
self.flags &= ~FL_DUCKED;
- else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z)
+ else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
self.flags |= FL_DUCKED;
// get onground state from the server
#ifdef CSQCMODEL_SERVERSIDE_CROUCH
// get crouch state from the server (LAG)
- if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z)
+ if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
self.flags &= ~FL_DUCKED;
- else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z)
+ else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
self.flags |= FL_DUCKED;
#endif
#define autocvar_utf8_enable cvar("utf8_enable")
float autocvar_waypoint_benchmark;
float autocvar_sv_gameplayfix_gravityunaffectedbyticrate;
+bool autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag;
float autocvar_g_trueaim_minrange;
float autocvar_g_debug_defaultsounds;
float autocvar_g_grab_range;
float autocvar_g_buffs_invisible_alpha;
float autocvar_g_buffs_flight_gravity;
float autocvar_g_buffs_jump_height;
+float autocvar_sv_player_scale;
#endif
// Flying
self.BUTTON_HOOK = true;
- if(self.navigation_jetpack_point.z - PL_MAX_z + PL_MIN_z < self.origin.z)
+ if(self.navigation_jetpack_point.z - PL_MAX.z + PL_MIN.z < self.origin.z)
{
self.movement_x = dir * v_forward * maxspeed;
self.movement_y = dir * v_right * maxspeed;
}
org = ent.origin + 0.5 * (ent.mins + ent.maxs);
- org.z = ent.origin.z + ent.mins.z - PL_MIN_z; // player height
+ org.z = ent.origin.z + ent.mins.z - PL_MIN.z; // player height
// TODO possibly make other code have the same support for bboxes
if(ent.tag_entity)
org = org + ent.tag_entity.origin;
float zdistance, xydistance, cost, t, fuel;
vector down, npa, npb;
- down = '0 0 -1' * (PL_MAX_z - PL_MIN_z) * 10;
+ down = '0 0 -1' * (PL_MAX.z - PL_MIN.z) * 10;
do{
npa = pointa + down;
navigation_testtracewalk = 0;
if (!self.wpisbox)
{
- tracebox(sv - PL_MIN_z * '0 0 1', PL_MIN, PL_MAX, sv, false, self);
+ tracebox(sv - PL_MIN.z * '0 0 1', PL_MIN, PL_MAX, sv, false, self);
if (!trace_startsolid)
{
//dprint("sv deviation", vtos(trace_endpos - sv), "\n");
}
if (!e.wpisbox)
{
- tracebox(ev - PL_MIN_z * '0 0 1', PL_MIN, PL_MAX, ev, false, e);
+ tracebox(ev - PL_MIN.z * '0 0 1', PL_MIN, PL_MAX, ev, false, e);
if (!trace_startsolid)
{
//dprint("ev deviation", vtos(trace_endpos - ev), "\n");
vector waypoint_fixorigin(vector position)
{
- tracebox(position + '0 0 1' * (1 - PL_MIN_z), PL_MIN, PL_MAX, position + '0 0 -512', MOVE_NOMONSTERS, world);
+ tracebox(position + '0 0 1' * (1 - PL_MIN.z), PL_MIN, PL_MAX, position + '0 0 -512', MOVE_NOMONSTERS, world);
if(trace_fraction < 1)
position = trace_endpos;
//traceline(position, position + '0 0 -512', MOVE_NOMONSTERS, world);
self.respawn_flags = 0;
self.respawn_time = 0;
self.stat_respawn_time = 0;
- self.scale = 0;
+ self.scale = autocvar_sv_player_scale;
self.fade_time = 0;
self.pain_frame = 0;
self.pain_finished = 0;
.float ebouncefactor, ebouncestop; // electro's values
// TODO do we need all these fields, or should we stop autodetecting runtime
// changes and just have a console command to update this?
-float ClientInit_SendEntity(entity to, float sf)
+float ClientInit_SendEntity(entity to, int sf)
{
WriteByte(MSG_ENTITY, ENT_CLIENT_INIT);
WriteByte(MSG_ENTITY, g_nexball_meter_period * 32);
void GetPressedKeys(void) {
MUTATOR_CALLHOOK(GetPressedKeys);
#define X(var,bit,flag) (flag ? var |= bit : var &= ~bit)
- X(self.pressedkeys, KEY_FORWARD, PHYS_INPUT_MOVEVALUES(self)_x > 0);
- X(self.pressedkeys, KEY_BACKWARD, PHYS_INPUT_MOVEVALUES(self)_x < 0);
- X(self.pressedkeys, KEY_RIGHT, PHYS_INPUT_MOVEVALUES(self)_y > 0);
- X(self.pressedkeys, KEY_LEFT, PHYS_INPUT_MOVEVALUES(self)_y < 0);
+ X(self.pressedkeys, KEY_FORWARD, self.movement_x > 0);
+ X(self.pressedkeys, KEY_BACKWARD, self.movement_x < 0);
+ X(self.pressedkeys, KEY_RIGHT, self.movement_y > 0);
+ X(self.pressedkeys, KEY_LEFT, self.movement_y < 0);
X(self.pressedkeys, KEY_JUMP, PHYS_INPUT_BUTTON_JUMP(self));
X(self.pressedkeys, KEY_CROUCH, PHYS_INPUT_BUTTON_CROUCH(self));
const float SND_LARGEENTITY = 8;
const float SND_LARGESOUND = 16;
-// WARNING: this kills the trace globals
-#define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
-#define EXACTTRIGGER_INIT WarpZoneLib_ExactTrigger_Init()
-
const float INITPRIO_FIRST = 0;
const float INITPRIO_GAMETYPE = 0;
const float INITPRIO_GAMETYPE_FALLBACK = 1;
void ctf_RespawnFlag(entity flag);
// score rule declarations
-const float ST_CTF_CAPS = 1;
-const float SP_CTF_CAPS = 4;
-const float SP_CTF_CAPTIME = 5;
-const float SP_CTF_PICKUPS = 6;
-const float SP_CTF_DROPS = 7;
-const float SP_CTF_FCKILLS = 8;
-const float SP_CTF_RETURNS = 9;
+const int ST_CTF_CAPS = 1;
+const int SP_CTF_CAPS = 4;
+const int SP_CTF_CAPTIME = 5;
+const int SP_CTF_PICKUPS = 6;
+const int SP_CTF_DROPS = 7;
+const int SP_CTF_FCKILLS = 8;
+const int SP_CTF_RETURNS = 9;
// flag constants // for most of these, there is just one question to be asked: WHYYYYY?
-#define FLAG_MIN (PL_MIN + '0 0 -13')
-#define FLAG_MAX (PL_MAX + '0 0 -13')
+#define FLAG_MIN ('-16 -16 -24' + '0 0 -13')
+#define FLAG_MAX ('16 16 45' + '0 0 -13')
const float FLAG_SCALE = 0.6;
const float FLAG_TOUCHRATE = 0.5;
const float WPFE_THINKRATE = 0.5;
-#define FLAG_DROP_OFFSET ('0 0 32')
-#define FLAG_CARRY_OFFSET ('-16 0 8')
-#define FLAG_SPAWN_OFFSET ('0 0 1' * (PL_MAX_z - 13))
-#define FLAG_WAYPOINT_OFFSET ('0 0 64')
-#define FLAG_FLOAT_OFFSET ('0 0 32')
-#define FLAG_PASS_ARC_OFFSET ('0 0 -10')
+const vector FLAG_DROP_OFFSET = ('0 0 32');
+const vector FLAG_CARRY_OFFSET = ('-16 0 8');
+#define FLAG_SPAWN_OFFSET ('0 0 1' * (45 - 13))
+const vector FLAG_WAYPOINT_OFFSET = ('0 0 64');
+const vector FLAG_FLOAT_OFFSET = ('0 0 32');
+const vector FLAG_PASS_ARC_OFFSET = ('0 0 -10');
-#define VEHICLE_FLAG_OFFSET ('0 0 96')
+const vector VEHICLE_FLAG_OFFSET = ('0 0 96');
const float VEHICLE_FLAG_SCALE = 1.0;
// waypoint colors
float wpforenemy_nextthink;
// statuses
-const float FLAG_BASE = 1;
-const float FLAG_DROPPED = 2;
-const float FLAG_CARRY = 3;
-const float FLAG_PASSING = 4;
+const int FLAG_BASE = 1;
+const int FLAG_DROPPED = 2;
+const int FLAG_CARRY = 3;
+const int FLAG_PASSING = 4;
-const float DROP_NORMAL = 1;
-const float DROP_THROW = 2;
-const float DROP_PASS = 3;
-const float DROP_RESET = 4;
+const int DROP_NORMAL = 1;
+const int DROP_THROW = 2;
+const int DROP_PASS = 3;
+const int DROP_RESET = 4;
-const float PICKUP_BASE = 1;
-const float PICKUP_DROPPED = 2;
+const int PICKUP_BASE = 1;
+const int PICKUP_DROPPED = 2;
-const float CAPTURE_NORMAL = 1;
-const float CAPTURE_DROPPED = 2;
+const int CAPTURE_NORMAL = 1;
+const int CAPTURE_DROPPED = 2;
-const float RETURN_TIMEOUT = 1;
-const float RETURN_DROPPED = 2;
-const float RETURN_DAMAGE = 3;
-const float RETURN_SPEEDRUN = 4;
-const float RETURN_NEEDKILL = 5;
+const int RETURN_TIMEOUT = 1;
+const int RETURN_DROPPED = 2;
+const int RETURN_DAMAGE = 3;
+const int RETURN_SPEEDRUN = 4;
+const int RETURN_NEEDKILL = 5;
// flag properties
#define ctf_spawnorigin dropped_origin
float ctf_captureshield_force; // push force of the shield
// bot player logic
-const float HAVOCBOT_CTF_ROLE_NONE = 0;
-const float HAVOCBOT_CTF_ROLE_DEFENSE = 2;
-const float HAVOCBOT_CTF_ROLE_MIDDLE = 4;
-const float HAVOCBOT_CTF_ROLE_OFFENSE = 8;
-const float HAVOCBOT_CTF_ROLE_CARRIER = 16;
-const float HAVOCBOT_CTF_ROLE_RETRIEVER = 32;
-const float HAVOCBOT_CTF_ROLE_ESCORT = 64;
-
-.float havocbot_cantfindflag;
+const int HAVOCBOT_CTF_ROLE_NONE = 0;
+const int HAVOCBOT_CTF_ROLE_DEFENSE = 2;
+const int HAVOCBOT_CTF_ROLE_MIDDLE = 4;
+const int HAVOCBOT_CTF_ROLE_OFFENSE = 8;
+const int HAVOCBOT_CTF_ROLE_CARRIER = 16;
+const int HAVOCBOT_CTF_ROLE_RETRIEVER = 32;
+const int HAVOCBOT_CTF_ROLE_ESCORT = 64;
+
+.bool havocbot_cantfindflag;
vector havocbot_ctf_middlepoint;
float havocbot_ctf_middlepoint_radius;
}
// in any case:
setattachment(key, world, "");
- setorigin(key, key.owner.origin + '0 0 1' * (PL_MIN_z - KH_KEY_MIN_z));
+ setorigin(key, key.owner.origin + '0 0 1' * (PL_MIN.z - KH_KEY_MIN_z));
key.angles = key.owner.angles;
#else
setorigin(key, key.owner.origin + key.origin.z * '0 0 1');
.float dodging_velocity_gain;
#ifdef CSQC
-.float pressedkeys;
+.int pressedkeys;
#elif defined(SVQC)
#endif
// returns 1 if the player is close to a wall
-float check_close_to_wall(float threshold)
+bool check_close_to_wall(float threshold)
{
if (PHYS_DODGING_WALL == 0) { return false; }
return false;
}
-float check_close_to_ground(float threshold)
+bool check_close_to_ground(float threshold)
{
return IS_ONGROUND(self) ? true : false;
}
if ((time - self.last_dodging_time) < PHYS_DODGING_DELAY)
return false;
- makevectors(PHYS_WORLD_ANGLES(self));
+ makevectors(self.angles);
if (check_close_to_ground(PHYS_DODGING_HEIGHT_THRESHOLD) != 1
&& check_close_to_wall(PHYS_DODGING_DISTANCE_THRESHOLD) != 1)
float dodge_detected = 0;
#define X(COND,BTN,RESULT) \
- if (PHYS_INPUT_MOVEVALUES(self)_##COND) \
+ if (self.movement_##COND) \
/* is this a state change? */ \
if(!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_##BTN) || frozen_no_doubletap) { \
tap_direction_##RESULT; \
}
// make sure v_up, v_right and v_forward are sane
- makevectors(PHYS_WORLD_ANGLES(self));
+ makevectors(self.angles);
// if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
// will be called ramp_time/frametime times = 2 times. so, we need to
if (self.dodging_action == 1)
{
//disable jump key during dodge accel phase
- if(PHYS_INPUT_MOVEVALUES(self)_z > 0) { PHYS_INPUT_MOVEVALUES(self)_z = 0; }
+ if(self.movement_z > 0) { self.movement_z = 0; }
self.velocity += ((self.dodging_direction_y * velocity_difference) * v_right)
+ ((self.dodging_direction_x * velocity_difference) * v_forward);
if(player_multijump)
{
- if(PHYS_INPUT_MOVEVALUES(self)_x != 0 || PHYS_INPUT_MOVEVALUES(self)_y != 0) // don't remove all speed if player isnt pressing any movement keys
+ if(self.movement_x != 0 || self.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys
{
float curspeed;
vector wishvel, wishdir;
curspeed = vlen(vec2(self.velocity));
#endif
- makevectors(PHYS_INPUT_ANGLES(self)_y * '0 1 0');
- wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self)_x + v_right * PHYS_INPUT_MOVEVALUES(self)_y;
+ makevectors(self.v_angle_y * '0 1 0');
+ wishvel = v_forward * self.movement_x + v_right * self.movement_y;
wishdir = normalize(wishvel);
self.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump
return;
/*
- if(other.mins_x < PL_MIN_x || other.mins_y < PL_MIN_y || other.mins_z < PL_MIN_z
- || other.maxs_x > PL_MAX_x || other.maxs_y > PL_MAX_y || other.maxs_z > PL_MAX_z)
+ if(other.mins_x < PL_MIN.x || other.mins_y < PL_MIN.y || other.mins_z < PL_MIN.z
+ || other.maxs_x > PL_MAX.x || other.maxs_y > PL_MAX.y || other.maxs_z > PL_MAX.z)
{
// can't teleport this
return;
#endif
float WarpZoneLib_MoveOutOfSolid(entity e);
#define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e)
+
+float WarpZoneLib_ExactTrigger_Touch();
+void WarpZoneLib_ExactTrigger_Init();
+
+// WARNING: this kills the trace globals
+#define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
+#define EXACTTRIGGER_INIT WarpZoneLib_ExactTrigger_Init()
#endif