Map triggers are more sane.
Really buggy example custom prediction code in this commit. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3180 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
a96b5ee4e9
commit
b3b0f3da9f
10 changed files with 350 additions and 177 deletions
|
@ -1,48 +1,294 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
WARNING: This entire file is pretty much GPLed.
|
||||||
|
If you want to release your csqc mod free from the GPL, do not define OWNPLAYERPHYSICS, and remove this file from your progs.src
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef OWNPLAYERPHYSICS
|
#ifdef OWNPLAYERPHYSICS
|
||||||
|
|
||||||
void PMove_Move(vector dest) //move forwards (preferably on the level) (does step ups)
|
/*
|
||||||
|
be very careful about the fields/globals that are read/written in this code.
|
||||||
|
Using any that are changed elsewhere can and will result in prediction errors.
|
||||||
|
Any fields that are expected to persist need to be added to csqc code to revert them.
|
||||||
|
Any fields that are read need to be the same between csqc and ssqc code somehow. Changing such fields will result in brief errors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define movevars_stepheight 22
|
||||||
|
#define movevars_friction 4
|
||||||
|
#define movevars_gravity 800
|
||||||
|
#define movevars_accelerate 10
|
||||||
|
#define movevars_stopspeed 100
|
||||||
|
#define movevars_maxspeed 320
|
||||||
|
#define movevars_jumpheight 270
|
||||||
|
|
||||||
|
.float pmove_flags;
|
||||||
|
|
||||||
|
#ifdef HAVE_DOTGRAVITY
|
||||||
|
.float gravity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enumflags
|
||||||
{
|
{
|
||||||
vector src;
|
PMF_JUMP_HELD,
|
||||||
|
PMF_RESERVED,
|
||||||
|
PMF_ONGROUND
|
||||||
|
};
|
||||||
|
|
||||||
|
static void(entity tother) dotouch =
|
||||||
|
{
|
||||||
|
entity oself;
|
||||||
|
//if (tother.touch == __NULL__)
|
||||||
|
return;
|
||||||
|
|
||||||
|
oself = self;
|
||||||
|
|
||||||
|
other = self;
|
||||||
|
self = tother;
|
||||||
|
|
||||||
|
self.touch();
|
||||||
|
|
||||||
|
self = oself;
|
||||||
|
};
|
||||||
|
|
||||||
|
//this function 'bounces' off any surfaces that were hit
|
||||||
|
void(vector surfnorm) PMove_Rebound =
|
||||||
|
{
|
||||||
|
float v;
|
||||||
|
v = self.velocity*surfnorm;
|
||||||
|
self.velocity = self.velocity - surfnorm*(v);
|
||||||
|
};
|
||||||
|
|
||||||
|
void(void) PMove_Move = //move forwards (preferably on the level) (does step ups)
|
||||||
|
{
|
||||||
|
vector dest;
|
||||||
|
vector saved_plane_normal;
|
||||||
float stepped;
|
float stepped;
|
||||||
tracebox(pmove_org, pmove_mins, pmove_maxs, dest, false, self); //try going straight there
|
float movetime;
|
||||||
|
float attempts;
|
||||||
|
|
||||||
|
//we need to bounce off surfaces (in order to slide along them), so we need at 2 attempts
|
||||||
|
for (attempts = 3, movetime = input_timelength; movetime>0 && attempts; attempts--)
|
||||||
|
{
|
||||||
|
dest = self.origin + self.velocity*movetime;
|
||||||
|
tracebox(self.origin, self.mins, self.maxs, dest, false, self); //try going straight there
|
||||||
|
self.origin = trace_endpos;
|
||||||
|
|
||||||
if (trace_fraction < 1)
|
if (trace_fraction < 1)
|
||||||
{ //step up
|
{
|
||||||
|
saved_plane_normal = trace_plane_normal;
|
||||||
|
|
||||||
|
movetime -= movetime * trace_fraction;
|
||||||
|
|
||||||
|
if (movetime)
|
||||||
|
{
|
||||||
|
//step up if we can
|
||||||
|
trace_endpos = self.origin;
|
||||||
|
trace_endpos_z += movevars_stepheight;
|
||||||
|
tracebox(self.origin, self.mins, self.maxs, trace_endpos, false, self);
|
||||||
|
stepped = trace_endpos_z - self.origin_z;
|
||||||
|
|
||||||
|
dest = trace_endpos + self.velocity*movetime;
|
||||||
|
dest_z = trace_endpos_z;
|
||||||
|
//move forwards
|
||||||
|
tracebox(trace_endpos, self.mins, self.maxs, dest, false, self);
|
||||||
|
|
||||||
|
//if we got anywhere, make this raised-step move count
|
||||||
|
if (trace_fraction != 0)
|
||||||
|
{
|
||||||
|
if (trace_fraction < 1)
|
||||||
|
PMove_Rebound(trace_plane_normal);
|
||||||
|
|
||||||
|
//move down
|
||||||
|
dest = trace_endpos;
|
||||||
|
dest_z -= stepped+1;
|
||||||
|
tracebox(trace_endpos, self.mins, self.maxs, dest, false, self);
|
||||||
|
if (trace_fraction < 1)
|
||||||
|
PMove_Rebound(trace_plane_normal);
|
||||||
|
|
||||||
|
self.origin = trace_endpos;
|
||||||
|
|
||||||
|
movetime -= movetime * input_timelength;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//stepping failed, just bounce off
|
||||||
|
PMove_Rebound(saved_plane_normal);
|
||||||
|
|
||||||
|
dotouch(trace_ent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
void(vector dest) PMove_StepMove =
|
||||||
|
{
|
||||||
|
//we hit something...
|
||||||
|
|
||||||
|
//step up
|
||||||
src = trace_endpos;
|
src = trace_endpos;
|
||||||
trace_endpos_z += movevars_stepheight;
|
trace_endpos_z += movevars_stepheight;
|
||||||
tracebox(src, pmove_mins, pmove_maxs, dest, false, self);
|
tracebox(src, self.mins, self.maxs, dest, false, self);
|
||||||
stepped = trace_endpos_z - src_z;
|
stepped = trace_endpos_z - src_z;
|
||||||
dest_z += stepped;
|
dest_z += stepped;
|
||||||
|
|
||||||
//move forwards
|
//move forwards
|
||||||
tracebox(trace_endpos, pmove_mins, pmove_maxs, dest, false, self);
|
tracebox(trace_endpos, self.mins, self.maxs, dest, false, self);
|
||||||
|
|
||||||
//move down
|
//move down
|
||||||
dest_z -= stepped;
|
dest_z -= stepped;
|
||||||
tracebox(trace_endpos, pmove_mins, pmove_maxs, dest, false, self);
|
tracebox(trace_endpos, self.mins, self.maxs, dest, false, self);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void() PMove_ApplyFriction =
|
||||||
|
{
|
||||||
|
float newspeed, oldspeed;
|
||||||
|
oldspeed = vlen(self.velocity);
|
||||||
|
if (oldspeed < 1)
|
||||||
|
{
|
||||||
|
self.velocity = '0 0 0';
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
pmove_org = trace_endpos;
|
|
||||||
|
//calculate what their new speed should be
|
||||||
|
newspeed = oldspeed - oldspeed*movevars_friction*input_timelength;
|
||||||
|
|
||||||
|
//and slow them
|
||||||
|
if (newspeed < 0)
|
||||||
|
newspeed = 0;
|
||||||
|
self.velocity = self.velocity * (newspeed/oldspeed);
|
||||||
};
|
};
|
||||||
|
|
||||||
void PMove(void)
|
void(vector wishdir, float wishspeed, float accel) PMove_Accelerate =
|
||||||
{
|
{
|
||||||
|
float addspeed, accelspeed;
|
||||||
|
float d;
|
||||||
|
d = self.velocity*wishdir;
|
||||||
|
addspeed = wishspeed - (d);
|
||||||
|
if (addspeed <= 0)
|
||||||
|
return;
|
||||||
|
accelspeed = accel*input_timelength*wishspeed;
|
||||||
|
if (accelspeed > addspeed)
|
||||||
|
accelspeed = addspeed;
|
||||||
|
|
||||||
|
self.velocity = self.velocity + accelspeed*wishdir;
|
||||||
|
};
|
||||||
|
|
||||||
|
void() PMove_InAirAccelerate =
|
||||||
|
{
|
||||||
|
vector hforward;
|
||||||
|
vector hright;
|
||||||
|
vector desireddir;
|
||||||
|
float desiredspeed;
|
||||||
|
|
||||||
|
hforward = v_forward;
|
||||||
|
hforward_z = 0;
|
||||||
|
hforward = normalize(hforward);
|
||||||
|
hright = v_right;
|
||||||
|
hright_z = 0;
|
||||||
|
hright = normalize(hright);
|
||||||
|
|
||||||
|
desireddir = hforward*input_movevalues_x + hright*input_movevalues_y;
|
||||||
|
desiredspeed = vlen(desireddir);
|
||||||
|
desireddir = normalize(desireddir);
|
||||||
|
|
||||||
|
if (desiredspeed > movevars_maxspeed)
|
||||||
|
desiredspeed = movevars_maxspeed;
|
||||||
|
|
||||||
|
if (self.pmove_flags & PMF_ONGROUND)
|
||||||
|
{
|
||||||
|
if (input_buttons & 2)
|
||||||
|
{
|
||||||
|
if (!(self.pmove_flags & PMF_JUMP_HELD))
|
||||||
|
{
|
||||||
|
self.velocity_z += movevars_jumpheight;
|
||||||
|
self.pmove_flags (+) PMF_ONGROUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.pmove_flags & PMF_ONGROUND)
|
||||||
|
{
|
||||||
|
PMove_ApplyFriction();
|
||||||
|
PMove_Accelerate(desireddir, desiredspeed, movevars_accelerate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//there's no friction in air...
|
||||||
|
if (desiredspeed > 30)
|
||||||
|
desiredspeed = 30;
|
||||||
|
PMove_Accelerate(desireddir, desiredspeed, movevars_accelerate);
|
||||||
|
|
||||||
|
#ifdef HAVE_DOTGRAVITY
|
||||||
|
if (self.gravity)
|
||||||
|
self.velocity_z -= self.gravity * movevars_gravity * input_timelength;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
self.velocity_z -= movevars_gravity * input_timelength;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void() PMove_NoclipAccelerate =
|
||||||
|
{
|
||||||
|
vector desireddir;
|
||||||
|
float desiredspeed;
|
||||||
|
|
||||||
|
desireddir = v_forward*input_movevalues_x + v_right*input_movevalues_y+v_up*input_movevalues_z;
|
||||||
|
desiredspeed = vlen(desireddir);
|
||||||
|
desireddir = normalize(desireddir);
|
||||||
|
|
||||||
|
PMove_ApplyFriction();
|
||||||
|
PMove_Accelerate(desireddir, desiredspeed, movevars_accelerate);
|
||||||
|
};
|
||||||
|
|
||||||
|
void() PMove_Categorise =
|
||||||
|
{
|
||||||
|
//if we're moving up, we're not on the ground
|
||||||
|
if (self.velocity_z > 0)
|
||||||
|
self.pmove_flags (-) PMF_ONGROUND;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//don't know, maybe we are, maybe we're not
|
||||||
|
tracebox(self.origin, self.mins, self.maxs, self.origin-'0 0 1', false, self);
|
||||||
|
if (trace_fraction == 1 || trace_plane_normal_z < 0.7)
|
||||||
|
{
|
||||||
|
self.pmove_flags (-) PMF_ONGROUND;
|
||||||
|
// self.groundentity = trace_ent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
self.pmove_flags (+) PMF_ONGROUND;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void(entity ent) PMove =
|
||||||
|
{
|
||||||
|
self = ent;
|
||||||
makevectors(input_angles);
|
makevectors(input_angles);
|
||||||
|
|
||||||
|
if (!(input_buttons & PMF_JUMP_HELD))
|
||||||
|
self.pmove_flags (-) PMF_JUMP_HELD;
|
||||||
|
|
||||||
pmove_vel *= movevars_friction*input_timelength;
|
PMove_Categorise();
|
||||||
pmove_vel += input_timelength*(
|
|
||||||
v_forward * input_movevalues_x +
|
|
||||||
v_right * input_movevalues_y +
|
|
||||||
v_up * input_movevalues_z);
|
|
||||||
|
|
||||||
switch(pmove_type)
|
self.movetype = MOVETYPE_WALK;
|
||||||
|
|
||||||
|
switch(self.movetype)
|
||||||
{
|
{
|
||||||
case MOVETYPE_WALK:
|
case MOVETYPE_WALK:
|
||||||
pmove_vel_z += movevars_gravity*input_timelength;
|
PMove_InAirAccelerate();
|
||||||
PMove_Move(pmove_org + pmove_vel*input_timelength);
|
PMove_Move();
|
||||||
|
break;
|
||||||
|
case MOVETYPE_FLY:
|
||||||
|
PMove_NoclipAccelerate();
|
||||||
|
PMove_Move();
|
||||||
break;
|
break;
|
||||||
case MOVETYPE_NOCLIP:
|
case MOVETYPE_NOCLIP:
|
||||||
pmove_org += pmove_vel*input_timelength;
|
PMove_NoclipAccelerate();
|
||||||
|
self.origin += self.velocity*input_timelength;
|
||||||
break;
|
break;
|
||||||
case MOVETYPE_NONE:
|
case MOVETYPE_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,15 +9,3 @@ noref float input_impulse;
|
||||||
//float input_weapon;
|
//float input_weapon;
|
||||||
//float input_servertime;
|
//float input_servertime;
|
||||||
|
|
||||||
float pmove_type;
|
|
||||||
vector pmove_org;
|
|
||||||
vector pmove_vel;
|
|
||||||
vector pmove_mins;
|
|
||||||
vector pmove_maxs;
|
|
||||||
float pmove_jump_held;
|
|
||||||
float pmove_waterjumptime;
|
|
||||||
|
|
||||||
float movevars_friction;
|
|
||||||
float movevars_gravity;
|
|
||||||
|
|
||||||
const float movevars_stepheight = 22;
|
|
|
@ -62,7 +62,7 @@ string(float keynum) getkeybind = #342; // (EXT_CSQC)
|
||||||
float(float framenum) getinputstate = #345; // (EXT_CSQC)
|
float(float framenum) getinputstate = #345; // (EXT_CSQC)
|
||||||
void(float sens) setsensitivityscaler = #346; // (EXT_CSQC)
|
void(float sens) setsensitivityscaler = #346; // (EXT_CSQC)
|
||||||
|
|
||||||
void() runstandardplayerphysics = #347; // (EXT_CSQC)
|
void(entity ent) runstandardplayerphysics = #347; // (EXT_CSQC_1)
|
||||||
|
|
||||||
string(float playernum, string keyname) getplayerkeyvalue = #348; // (EXT_CSQC)
|
string(float playernum, string keyname) getplayerkeyvalue = #348; // (EXT_CSQC)
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,8 @@ float(string skinname) Anim_GetHeadSkinNumber;
|
||||||
vector(string skinname) Anim_GetHeadOffset;
|
vector(string skinname) Anim_GetHeadOffset;
|
||||||
|
|
||||||
//prediction
|
//prediction
|
||||||
void() Pred_PlayerUpdated;
|
void(entity ent) Pred_PlayerUpdated;
|
||||||
void() Pred_UpdateLocalMovement;
|
void(entity ent) Pred_UpdateLocalMovement;
|
||||||
vector vieworg;
|
vector vieworg;
|
||||||
|
|
||||||
//menu
|
//menu
|
||||||
|
|
|
@ -245,7 +245,6 @@ void() CSQC_Init =
|
||||||
|
|
||||||
drawloadingscreen ();
|
drawloadingscreen ();
|
||||||
|
|
||||||
Pred_ResetPlayerPrediction();
|
|
||||||
regcommands();
|
regcommands();
|
||||||
|
|
||||||
#ifndef FTEDEPENDANT
|
#ifndef FTEDEPENDANT
|
||||||
|
|
|
@ -5,62 +5,24 @@
|
||||||
|
|
||||||
string() getentitytoken = #355;
|
string() getentitytoken = #355;
|
||||||
|
|
||||||
//fixme: I want an engine solution
|
void() cs_teleport_touch =
|
||||||
entity triggerchain;
|
|
||||||
.entity nexttrigger;
|
|
||||||
void() pmovetouchtriggers =
|
|
||||||
{
|
{
|
||||||
vector amin = pmove_org+pmove_mins;
|
local entity t;
|
||||||
vector amax = pmove_org+pmove_maxs;
|
|
||||||
vector emin;
|
|
||||||
vector emax;
|
|
||||||
entity t;
|
|
||||||
entity oself = self;
|
|
||||||
for (self = triggerchain; self; self = self.nexttrigger)
|
|
||||||
{
|
|
||||||
emin = self.origin+self.mins;
|
|
||||||
if (emin_x > amax_x)
|
|
||||||
continue;
|
|
||||||
if (emin_y > amax_y)
|
|
||||||
continue;
|
|
||||||
if (emin_z > amax_z)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
emax = self.origin+self.maxs;
|
|
||||||
if (emax_x < amin_x)
|
|
||||||
continue;
|
|
||||||
if (emax_y < amin_y)
|
|
||||||
continue;
|
|
||||||
if (emax_z < amin_z)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (self.classname == "trigger_teleport")
|
|
||||||
{
|
|
||||||
t = find(world, targetname, self.target);
|
t = find(world, targetname, self.target);
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
makevectors(t.angles);
|
makevectors(t.angles);
|
||||||
Pred_Predict_Teleport(t.origin + '0 0 27', v_forward*300, t.angles);
|
Pred_Predict_Teleport(t.origin + '0 0 27', v_forward*300, t.angles);
|
||||||
}
|
}
|
||||||
//maybe they use a mod that uses some other choice pattern
|
};
|
||||||
}
|
|
||||||
if (self.classname == "trigger_push")
|
|
||||||
{
|
|
||||||
//fixme: add support for trigger_push
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self = oself;
|
|
||||||
}
|
|
||||||
|
|
||||||
void() spawn_trigger_teleport =
|
void() spawn_trigger_teleport =
|
||||||
{
|
{
|
||||||
self.solid = SOLID_NOT;//SOLID_TRIGGER;
|
self.solid = SOLID_TRIGGER;
|
||||||
setmodel(self, self.model);
|
setmodel(self, self.model);
|
||||||
self.model = "";
|
self.model = "";
|
||||||
|
|
||||||
self.nexttrigger = triggerchain;
|
self.touch = cs_teleport_touch;
|
||||||
triggerchain = self;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void() spawn_info_teleport_destination =
|
void() spawn_info_teleport_destination =
|
||||||
|
@ -69,18 +31,16 @@ void() spawn_info_teleport_destination =
|
||||||
|
|
||||||
void() spawn_trigger_push =
|
void() spawn_trigger_push =
|
||||||
{
|
{
|
||||||
self.solid = SOLID_NOT;//SOLID_TRIGGER;
|
self.solid = SOLID_TRIGGER;
|
||||||
setmodel(self, self.model);
|
setmodel(self, self.model);
|
||||||
self.model = "";
|
self.model = "";
|
||||||
|
|
||||||
self.nexttrigger = triggerchain;
|
// self.touch = cs_teleport_touch;
|
||||||
triggerchain = self;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void() spawn_worldspawn =
|
void() spawn_worldspawn =
|
||||||
{
|
{
|
||||||
levelname = self.message;
|
levelname = self.message;
|
||||||
mapname = "that was the mapname, dumbass";
|
|
||||||
remove(self);
|
remove(self);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,7 @@ static void() Player_Interpolate =
|
||||||
{ //do some frame interpolation.
|
{ //do some frame interpolation.
|
||||||
if (self.entnum == player_localentnum)
|
if (self.entnum == player_localentnum)
|
||||||
{
|
{
|
||||||
Pred_UpdateLocalMovement();
|
Pred_UpdateLocalMovement(self);
|
||||||
self.origin = pmove_org;
|
|
||||||
self.angles = input_angles;
|
|
||||||
self.angles_x = self.angles_x * -0.3333;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(self.modelstyle)
|
switch(self.modelstyle)
|
||||||
|
@ -99,6 +96,10 @@ static void(float g) Player_SetLocalInfoGender =
|
||||||
{
|
{
|
||||||
if (player_local == self)
|
if (player_local == self)
|
||||||
{
|
{
|
||||||
|
//if it was forced, don't lie to everyone else.
|
||||||
|
if (cvar_string("cg_forceskin") != "")
|
||||||
|
return;
|
||||||
|
|
||||||
switch(g)
|
switch(g)
|
||||||
{
|
{
|
||||||
case GENDER_FEMALE:
|
case GENDER_FEMALE:
|
||||||
|
@ -299,10 +300,12 @@ void(float isnew) RefreshPlayer =
|
||||||
JustRessed();
|
JustRessed();
|
||||||
self.haddied = false;
|
self.haddied = false;
|
||||||
}
|
}
|
||||||
|
self.solid = SOLID_BBOX;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self.haddied = true;
|
self.haddied = true;
|
||||||
|
self.solid = SOLID_NOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.lastorg = self.origin;
|
self.lastorg = self.origin;
|
||||||
|
@ -372,7 +375,7 @@ void(float isnew) RefreshPlayer =
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pred_PlayerUpdated();
|
Pred_PlayerUpdated(self);
|
||||||
};
|
};
|
||||||
|
|
||||||
//this is sent after the server has run our movement command.
|
//this is sent after the server has run our movement command.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
UpdateLocalMovement: runs the local prediction (called from player.qc - local players are drawn for mirrors etc)
|
UpdateLocalMovement: runs the local prediction (called from player.qc - local players are drawn for mirrors etc)
|
||||||
out: vieworg (view origin, with chasecam/viewheight added)
|
out: vieworg (view origin, with chasecam/viewheight added)
|
||||||
out: pmove_org (raw player ent origin)
|
out: ` (raw player ent origin)
|
||||||
|
|
||||||
PlayerUpdated: updates internal state, called from player.qc any time we got an update from the server.
|
PlayerUpdated: updates internal state, called from player.qc any time we got an update from the server.
|
||||||
in: self (the player ent origin/velocity/mins/maxs)
|
in: self (the player ent origin/velocity/mins/maxs)
|
||||||
|
@ -14,8 +14,9 @@ ResetPlayerPrediction: call if you broke the special pmove globals
|
||||||
|
|
||||||
vector player_org;
|
vector player_org;
|
||||||
vector player_vel;
|
vector player_vel;
|
||||||
float player_jump_held;
|
float player_pmflags;
|
||||||
float player_sequence;
|
float player_sequence;
|
||||||
|
|
||||||
float player_steptime;
|
float player_steptime;
|
||||||
float player_step;
|
float player_step;
|
||||||
|
|
||||||
|
@ -26,16 +27,16 @@ float pmove_step;
|
||||||
float pmove_steptime;
|
float pmove_steptime;
|
||||||
float pmove_step_oldz;
|
float pmove_step_oldz;
|
||||||
|
|
||||||
void() pmovetouchtriggers;
|
.float pmove_flags;
|
||||||
|
|
||||||
float pmoveframe;
|
float pmoveframe;
|
||||||
nonstatic void() Pred_ResetPlayerPrediction =
|
nonstatic void(entity ent) Pred_ResetPlayerPrediction =
|
||||||
{
|
{
|
||||||
//reset the pmove to lerp from the new position
|
//reset the pmove to lerp from the new position
|
||||||
pmove_org = player_org;
|
ent.origin = player_org;
|
||||||
pmove_vel = player_vel;
|
ent.velocity = player_vel;
|
||||||
pmoveframe = player_sequence+1; //+1 because the recieved frame has the move already done (server side)
|
pmoveframe = player_sequence+1; //+1 because the recieved frame has the move already done (server side)
|
||||||
pmove_jump_held = player_jump_held;
|
ent.pmove_flags = player_pmflags;
|
||||||
|
|
||||||
if (pmoveframe < clientcommandframe-128)
|
if (pmoveframe < clientcommandframe-128)
|
||||||
pmoveframe = clientcommandframe-128; //avoid an infinate loop
|
pmoveframe = clientcommandframe-128; //avoid an infinate loop
|
||||||
|
@ -54,32 +55,37 @@ void(vector newteleorg, vector newtelevel, vector newteleang) Pred_Predict_Telep
|
||||||
setviewprop(33, newteleang);
|
setviewprop(33, newteleang);
|
||||||
view_angles = newteleang;
|
view_angles = newteleang;
|
||||||
}
|
}
|
||||||
pmove_org = newteleorg;
|
other.origin = newteleorg;
|
||||||
pmove_vel = newtelevel;
|
other.velocity = newtelevel;
|
||||||
input_angles = newteleang;
|
input_angles = newteleang;
|
||||||
};
|
};
|
||||||
|
|
||||||
void(float endframe) Pred_RunMovement;
|
void(entity ent, float endframe) Pred_RunMovement;
|
||||||
|
|
||||||
nonstatic void() Pred_PlayerUpdated =
|
nonstatic void(entity ent) Pred_PlayerUpdated =
|
||||||
{
|
{
|
||||||
local float noerror;
|
local float noerror;
|
||||||
local vector o;
|
local vector o;
|
||||||
|
local vector v;
|
||||||
|
local float pmf;
|
||||||
|
|
||||||
|
o = ent.origin;
|
||||||
|
v = ent.velocity;
|
||||||
|
pmf = ent.pmove_flags;
|
||||||
|
|
||||||
noerror = cvar("cg_noerror");
|
noerror = cvar("cg_noerror");
|
||||||
|
|
||||||
//reset the prediction to last-known-good state
|
//reset the prediction to last-known-good state
|
||||||
Pred_ResetPlayerPrediction();
|
Pred_ResetPlayerPrediction(ent);
|
||||||
Pred_RunMovement(servercommandframe+1);
|
Pred_RunMovement(ent, servercommandframe+1);
|
||||||
player_jump_held = pmove_jump_held;
|
player_pmflags = ent.pmove_flags;
|
||||||
|
|
||||||
player_step = pmove_step;
|
player_step = pmove_step;
|
||||||
player_steptime = pmove_steptime;
|
player_steptime = pmove_steptime;
|
||||||
|
|
||||||
//pull out the new values
|
//pull out the new values
|
||||||
player_org = self.origin;
|
player_org = o;
|
||||||
player_vel = self.velocity;
|
player_vel = v;
|
||||||
pmove_mins = self.mins;
|
|
||||||
pmove_maxs = self.maxs;
|
|
||||||
player_sequence = servercommandframe;
|
player_sequence = servercommandframe;
|
||||||
|
|
||||||
if (noerror)
|
if (noerror)
|
||||||
|
@ -87,25 +93,25 @@ nonstatic void() Pred_PlayerUpdated =
|
||||||
pmove_error = '0 0 0';
|
pmove_error = '0 0 0';
|
||||||
pmove_errortime = time;
|
pmove_errortime = time;
|
||||||
|
|
||||||
Pred_ResetPlayerPrediction();
|
Pred_ResetPlayerPrediction(ent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Pred_RunMovement(clientcommandframe); //make sure we're up to date
|
Pred_RunMovement(ent, clientcommandframe); //make sure we're up to date
|
||||||
o = pmove_org; //save off the old for the teleport check below.
|
o = ent.origin; //save off the old for the teleport check below.
|
||||||
|
|
||||||
//reset it, then update to now to guage how much our previous prediction was incorrect by
|
//reset it, then update to now to guage how much our previous prediction was incorrect by
|
||||||
Pred_ResetPlayerPrediction();
|
Pred_ResetPlayerPrediction(ent);
|
||||||
Pred_RunMovement(clientcommandframe);
|
Pred_RunMovement(ent, clientcommandframe);
|
||||||
|
|
||||||
if (vlen(o - pmove_org) > 64)
|
if (vlen(o - ent.origin) > 64)
|
||||||
{//teleport
|
{//teleport
|
||||||
pmove_error = '0 0 0';
|
pmove_error = '0 0 0';
|
||||||
pmove_errortime = time;
|
pmove_errortime = time;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //figure out the error ammount, and lerp back to it, without forgetting about any current inaccuracies.
|
{ //figure out the error ammount, and lerp back to it, without forgetting about any current inaccuracies.
|
||||||
pmove_error = (pmove_errortime - time)*ERRORTIME * pmove_error + (o - pmove_org);
|
pmove_error = (pmove_errortime - time)*ERRORTIME * pmove_error + (o - ent.origin);
|
||||||
if (vlen(pmove_error) < 1)
|
if (vlen(pmove_error) < 1)
|
||||||
pmove_error = '0 0 0';
|
pmove_error = '0 0 0';
|
||||||
pmove_errortime = time + 1/ERRORTIME;
|
pmove_errortime = time + 1/ERRORTIME;
|
||||||
|
@ -113,7 +119,7 @@ nonstatic void() Pred_PlayerUpdated =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void(float endframe) Pred_RunMovement =
|
void(entity ent, float endframe) Pred_RunMovement =
|
||||||
{
|
{
|
||||||
if (servercommandframe >= player_sequence+63)
|
if (servercommandframe >= player_sequence+63)
|
||||||
{
|
{
|
||||||
|
@ -160,9 +166,7 @@ void(float endframe) Pred_RunMovement =
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
runstandardplayerphysics();
|
runstandardplayerphysics(ent);
|
||||||
|
|
||||||
pmovetouchtriggers();
|
|
||||||
|
|
||||||
pmoveframe++;
|
pmoveframe++;
|
||||||
}
|
}
|
||||||
|
@ -171,13 +175,13 @@ void(float endframe) Pred_RunMovement =
|
||||||
input_angles = view_angles;
|
input_angles = view_angles;
|
||||||
};
|
};
|
||||||
|
|
||||||
nonstatic void() Pred_UpdateLocalMovement =
|
nonstatic void(entity ent) Pred_UpdateLocalMovement =
|
||||||
{
|
{
|
||||||
local float viewheight;
|
local float viewheight;
|
||||||
|
|
||||||
Pred_RunMovement(clientcommandframe);
|
Pred_RunMovement(ent, clientcommandframe);
|
||||||
|
|
||||||
if (pmove_org_z > pmove_step_oldz+8 && pmove_org_z < pmove_step_oldz+24 && pmove_vel_z == 0)
|
if (ent.origin_z > pmove_step_oldz+8 && ent.origin_z < pmove_step_oldz+24 && pmove_vel_z == 0)
|
||||||
{
|
{
|
||||||
//evaluate out the remaining old step
|
//evaluate out the remaining old step
|
||||||
if (pmove_steptime - time > 0)
|
if (pmove_steptime - time > 0)
|
||||||
|
@ -186,10 +190,10 @@ nonstatic void() Pred_UpdateLocalMovement =
|
||||||
pmove_step = 0;
|
pmove_step = 0;
|
||||||
|
|
||||||
//work out the new step
|
//work out the new step
|
||||||
pmove_step += (pmove_step_oldz-pmove_org_z);
|
pmove_step += (pmove_step_oldz-self.origin_z);
|
||||||
pmove_steptime = time + 1/STEPTIME;
|
pmove_steptime = time + 1/STEPTIME;
|
||||||
}
|
}
|
||||||
pmove_step_oldz = pmove_org_z;
|
pmove_step_oldz = ent.origin_z;
|
||||||
|
|
||||||
//allow the user to move the viewheight down 6 units so it's at +16, where projectiles come from.
|
//allow the user to move the viewheight down 6 units so it's at +16, where projectiles come from.
|
||||||
viewheight = cvar("v_viewheight");
|
viewheight = cvar("v_viewheight");
|
||||||
|
@ -198,7 +202,7 @@ nonstatic void() Pred_UpdateLocalMovement =
|
||||||
else if (viewheight > 7)
|
else if (viewheight > 7)
|
||||||
viewheight = 7;
|
viewheight = 7;
|
||||||
|
|
||||||
vieworg = pmove_org; //the default view height
|
vieworg = ent.origin; //the default view height
|
||||||
vieworg_z += getstati(STAT_VIEWHEIGHT) + viewheight;
|
vieworg_z += getstati(STAT_VIEWHEIGHT) + viewheight;
|
||||||
|
|
||||||
//correct the view position to compensate for any errors, slowly over time, 0.1 seconds.
|
//correct the view position to compensate for any errors, slowly over time, 0.1 seconds.
|
||||||
|
@ -211,9 +215,10 @@ nonstatic void() Pred_UpdateLocalMovement =
|
||||||
|
|
||||||
if (chasecam)
|
if (chasecam)
|
||||||
{
|
{
|
||||||
view_angles_y += 180;
|
view_angles_y += cvar("cg_thirdPersonAngle");
|
||||||
|
|
||||||
makevectors(view_angles);
|
makevectors(view_angles);
|
||||||
traceline(pmove_org, vieworg - v_forward * 72+v_up*32, TRUE, self);
|
traceline(self.origin, vieworg - v_forward * cvar("cg_thirdPersonRange")+v_up*cvar("cg_thirdPersonHeight"), TRUE, self);
|
||||||
vieworg = trace_endpos + v_forward*8;
|
vieworg = trace_endpos + v_forward*8;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,12 +17,12 @@ common/econstants.qc
|
||||||
cs/constants.qc
|
cs/constants.qc
|
||||||
|
|
||||||
common/pmovedefs.qc
|
common/pmovedefs.qc
|
||||||
|
common/pmove.qc
|
||||||
|
|
||||||
cs/keys.qc
|
cs/keys.qc
|
||||||
|
|
||||||
common/makeallstatic.qc
|
common/makeallstatic.qc
|
||||||
|
|
||||||
common/pmove.qc
|
|
||||||
cs/prediction.qc
|
cs/prediction.qc
|
||||||
cs/q3playerm.qc
|
cs/q3playerm.qc
|
||||||
cs/hlpm.qc
|
cs/hlpm.qc
|
||||||
|
|
|
@ -781,12 +781,15 @@ void() PlayerJump =
|
||||||
|
|
||||||
if (self.waterlevel >= 2)
|
if (self.waterlevel >= 2)
|
||||||
{
|
{
|
||||||
|
//pmove code predicts this
|
||||||
|
/*
|
||||||
if (self.watertype == CONTENT_WATER)
|
if (self.watertype == CONTENT_WATER)
|
||||||
self.velocity_z = 100;
|
self.velocity_z = 100;
|
||||||
else if (self.watertype == CONTENT_SLIME)
|
else if (self.watertype == CONTENT_SLIME)
|
||||||
self.velocity_z = 80;
|
self.velocity_z = 80;
|
||||||
else
|
else
|
||||||
self.velocity_z = 50;
|
self.velocity_z = 50;
|
||||||
|
*/
|
||||||
|
|
||||||
// play swiming sound
|
// play swiming sound
|
||||||
if (self.swim_flag < time)
|
if (self.swim_flag < time)
|
||||||
|
@ -814,7 +817,9 @@ void() PlayerJump =
|
||||||
self.button2 = 0;
|
self.button2 = 0;
|
||||||
// player jumping sound
|
// player jumping sound
|
||||||
sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
|
sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
|
||||||
self.velocity_z = self.velocity_z + 270;
|
|
||||||
|
//pmove code predicts this
|
||||||
|
// self.velocity_z = self.velocity_z + 270;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1547,44 +1552,11 @@ void(entity targ, entity attacker) ClientObituary =
|
||||||
void() DefaultPlayerPhysics = #347;
|
void() DefaultPlayerPhysics = #347;
|
||||||
void() SV_RunClientCommand =
|
void() SV_RunClientCommand =
|
||||||
{
|
{
|
||||||
pmove_org = self.origin;
|
|
||||||
pmove_vel = self.velocity;
|
|
||||||
pmove_mins = self.mins;
|
|
||||||
pmove_maxs = self.maxs;
|
|
||||||
// pmove_jump_held = self.jump_held;
|
|
||||||
pmove_waterjumptime = self.teleport_time;
|
|
||||||
|
|
||||||
//should match the one used by csqc.
|
//should match the one used by csqc.
|
||||||
#ifdef OWNPLAYERPHYSICS
|
#ifdef OWNPLAYERPHYSICS
|
||||||
PMove();
|
PMove(self);
|
||||||
#else
|
#else
|
||||||
DefaultPlayerPhysics();
|
DefaultPlayerPhysics(self);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
self.origin = pmove_org;
|
|
||||||
self.velocity = pmove_vel;
|
|
||||||
// self.jump_held = pmove_jump_held;
|
|
||||||
self.teleport_time = pmove_waterjumptime;
|
|
||||||
|
|
||||||
self.waterlevel = 0;//FIXME
|
|
||||||
self.watertype = 0;//FIXME
|
|
||||||
|
|
||||||
self.button0 = (input_buttons & 1);
|
|
||||||
self.button2 = !!(input_buttons & 2);
|
|
||||||
/*
|
|
||||||
self.button3 = !!(input_buttons & 4);
|
|
||||||
self.button4 = !!(input_buttons & 8);
|
|
||||||
self.button5 = !!(input_buttons & 16);
|
|
||||||
self.button6 = !!(input_buttons & 32);
|
|
||||||
self.button7 = !!(input_buttons & 64);
|
|
||||||
self.button8 = !!(input_buttons & 128);
|
|
||||||
*/
|
|
||||||
self.v_angle = input_angles;
|
|
||||||
self.angles = input_angles;
|
|
||||||
self.angles_x *= -1/3;
|
|
||||||
self.impulse = input_impulse;
|
|
||||||
|
|
||||||
//we don't need this DP extension
|
|
||||||
// self.movement = input_movevalues;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue