X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fphysics%2Fmovetypes%2Fmovetypes.qc;h=e31b4076beca1072f2e1870f61fa0b73ec6800da;hp=78429dda97100b517462121029605caab979cbb0;hb=1ff1288152dd20786853bed28c9d9aad1f21c8a5;hpb=c6ebaefab2aca7df4648dac3ccdd4b52de45d0ed diff --git a/qcsrc/common/physics/movetypes/movetypes.qc b/qcsrc/common/physics/movetypes/movetypes.qc index 78429dda9..e31b4076b 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qc +++ b/qcsrc/common/physics/movetypes/movetypes.qc @@ -1,15 +1,19 @@ -#include "../player.qh" - -#if defined(CSQC) - #include - #include - #include - #include "movetypes.qh" - #include - #include -#elif defined(MENUQC) -#elif defined(SVQC) - #include +#include "movetypes.qh" + +#ifdef SVQC +void set_movetype(entity this, int mt) +{ + this.move_movetype = mt; + if (mt == MOVETYPE_PHYSICS || mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH) { + this.move_qcphysics = false; + } + this.movetype = (this.move_qcphysics) ? MOVETYPE_NONE : mt; +} +#elif defined(CSQC) +void set_movetype(entity this, int mt) +{ + this.move_movetype = mt; +} #endif void _Movetype_WallFriction(entity this, vector stepnormal) // SV_WallFriction @@ -21,18 +25,18 @@ void _Movetype_WallFriction(entity this, vector stepnormal) // SV_WallFriction if(d < 0) { - i = (stepnormal * this.move_velocity); + i = (stepnormal * this.velocity); into = i * stepnormal; - side = this.move_velocity - into; - this.move_velocity_x = side.x * (1 * d); - this.move_velocity_y = side.y * (1 * d); + side = this.velocity - into; + this.velocity_x = side.x * (1 * d); + this.velocity_y = side.y * (1 * d); }*/ } vector planes[MAX_CLIP_PLANES]; int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnormal, float stepheight) // SV_FlyMove { - int blocked = 0, bumpcount; + int blocked = 0; int i, j, numplanes = 0; float time_left = dt, grav = 0; vector push; @@ -46,23 +50,23 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma this.move_didgravity = 1; grav = dt * (PHYS_ENTGRAVITY(this) ? PHYS_ENTGRAVITY(this) : 1) * PHYS_GRAVITY(this); - if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND)) + if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this)) { if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE) - this.move_velocity_z -= grav * 0.5; + this.velocity_z -= grav * 0.5; else - this.move_velocity_z -= grav; + this.velocity_z -= grav; } } - original_velocity = primal_velocity = restore_velocity = this.move_velocity; + original_velocity = primal_velocity = restore_velocity = this.velocity; - for(bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++) + for(int bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++) { - if(this.move_velocity == '0 0 0') + if(this.velocity == '0 0 0') break; - push = this.move_velocity * time_left; + push = this.velocity * time_left; _Movetype_PushEntity(this, push, true); if(trace_startsolid) { @@ -76,7 +80,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma // abort move if we're stuck in the world (and didn't make it out) if(trace_startsolid && trace_allsolid) { - this.move_velocity = restore_velocity; + this.velocity = restore_velocity; return 3; } @@ -99,14 +103,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma trace_ent = NULL; } - this.move_flags |= FL_ONGROUND; - this.move_groundentity = trace_ent; + SET_ONGROUND(this); + this.groundentity = trace_ent; } } else if(stepheight) { // step - handle it immediately - vector org = this.move_origin; + vector org = this.origin; vector steppush = '0 0 1' * stepheight; _Movetype_PushEntity(this, steppush, true); @@ -122,7 +126,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma break; } float trace2_fraction = trace_fraction; - steppush = '0 0 1' * (org_z - this.move_origin_z); + steppush = '0 0 1' * (org.z - this.origin_z); _Movetype_PushEntity(this, steppush, true); if(trace_startsolid) { @@ -131,15 +135,15 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma } // accept the new position if it made some progress... - if(fabs(this.move_origin_x - org_x) >= 0.03125 || fabs(this.move_origin_y - org_y) >= 0.03125) + if(fabs(this.origin_x - org.x) >= 0.03125 || fabs(this.origin_y - org.y) >= 0.03125) { - trace_endpos = this.move_origin; + trace_endpos = this.origin; time_left *= 1 - trace2_fraction; numplanes = 0; continue; } else - this.move_origin = org; + this.origin = org; } else { @@ -153,7 +157,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma if(my_trace_fraction >= 0.001) { // actually covered some distance - original_velocity = this.move_velocity; + original_velocity = this.velocity; numplanes = 0; } @@ -163,7 +167,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma if(numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen - this.move_velocity = '0 0 0'; + this.velocity = '0 0 0'; blocked = 3; break; } @@ -192,14 +196,14 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma if(i != numplanes) { // go along this plane - this.move_velocity = new_velocity; + this.velocity = new_velocity; } else { // go along the crease if(numplanes != 2) { - this.move_velocity = '0 0 0'; + this.velocity = '0 0 0'; blocked = 7; break; } @@ -211,29 +215,32 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma dir.x *= ilength; dir.y *= ilength; dir.z *= ilength; - float d = (dir * this.move_velocity); - this.move_velocity = dir * d; + float d = (dir * this.velocity); + this.velocity = dir * d; } // if current velocity is against the original velocity, // stop dead to avoid tiny occilations in sloping corners - if((this.move_velocity * primal_velocity) <= 0) + if((this.velocity * primal_velocity) <= 0) { - this.move_velocity = '0 0 0'; + this.velocity = '0 0 0'; break; } } // LordHavoc: this came from QW and allows you to get out of water more easily - if(GAMEPLAYFIX_EASIERWATERJUMP(this) && (this.move_flags & FL_WATERJUMP) && !(blocked & 8)) - this.move_velocity = primal_velocity; + if(GAMEPLAYFIX_EASIERWATERJUMP(this) && (this.flags & FL_WATERJUMP) && !(blocked & 8)) + this.velocity = primal_velocity; + + if(PHYS_WALLCLIP(this) && this.pm_time && !(this.flags & FL_WATERJUMP) && !(blocked & 8)) + this.velocity = primal_velocity; if(applygravity) { - if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND)) + if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this)) { if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE) - this.move_velocity_z -= grav * 0.5f; + this.velocity_z -= grav * 0.5f; } } @@ -242,74 +249,74 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma void _Movetype_CheckVelocity(entity this) // SV_CheckVelocity { - // if(vlen(this.move_velocity) < 0.0001) - // this.move_velocity = '0 0 0'; + // if(vlen(this.velocity) < 0.0001) + // this.velocity = '0 0 0'; } bool _Movetype_CheckWater(entity this) // SV_CheckWater { - vector point = this.move_origin; + vector point = this.origin; point.z += this.mins.z + 1; int nativecontents = pointcontents(point); - if(this.move_watertype && this.move_watertype != nativecontents) + if(this.watertype && this.watertype != nativecontents) { - // dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", this.move_watertype, nativecontents); + // dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", this.watertype, nativecontents); if(this.contentstransition) - this.contentstransition(this.move_watertype, nativecontents); + this.contentstransition(this.watertype, nativecontents); } - this.move_waterlevel = WATERLEVEL_NONE; - this.move_watertype = CONTENT_EMPTY; + this.waterlevel = WATERLEVEL_NONE; + this.watertype = CONTENT_EMPTY; int supercontents = Mod_Q1BSP_SuperContentsFromNativeContents(nativecontents); if(supercontents & DPCONTENTS_LIQUIDSMASK) { - this.move_watertype = nativecontents; - this.move_waterlevel = WATERLEVEL_WETFEET; - point.z = this.move_origin.z + (this.mins.z + this.maxs.z) * 0.5; + this.watertype = nativecontents; + this.waterlevel = WATERLEVEL_WETFEET; + point.z = this.origin.z + (this.mins.z + this.maxs.z) * 0.5; if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK) { - this.move_waterlevel = WATERLEVEL_SWIMMING; - point.z = this.move_origin.z + this.view_ofs.z; + this.waterlevel = WATERLEVEL_SWIMMING; + point.z = this.origin.z + this.view_ofs.z; if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK) - this.move_waterlevel = WATERLEVEL_SUBMERGED; + this.waterlevel = WATERLEVEL_SUBMERGED; } } - return this.move_waterlevel > 1; + return this.waterlevel > 1; } void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition { - int contents = pointcontents(ent.move_origin); + int contents = pointcontents(ent.origin); - if(!ent.move_watertype) + if(!ent.watertype) { // just spawned here - if(!autocvar_cl_gameplayfix_fixedcheckwatertransition) + if(!GAMEPLAYFIX_WATERTRANSITION(ent)) { - ent.move_watertype = contents; - ent.move_waterlevel = 1; + ent.watertype = contents; + ent.waterlevel = 1; return; } } - else if(ent.move_watertype != contents) + else if(ent.watertype != contents) { - // dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.move_origin), pointcontents(ent.move_origin), ent.move_watertype, contents); + // dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.origin), pointcontents(ent.origin), ent.watertype, contents); if(ent.contentstransition) - ent.contentstransition(ent.move_watertype, contents); + ent.contentstransition(ent.watertype, contents); } if(contents <= CONTENT_WATER) { - ent.move_watertype = contents; - ent.move_waterlevel = 1; + ent.watertype = contents; + ent.waterlevel = 1; } else { - ent.move_watertype = CONTENT_EMPTY; - ent.move_waterlevel = (autocvar_cl_gameplayfix_fixedcheckwatertransition ? 0 : contents); + ent.watertype = CONTENT_EMPTY; + ent.waterlevel = (GAMEPLAYFIX_WATERTRANSITION(ent) ? 0 : contents); } } @@ -337,7 +344,7 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGr trace_fraction = 1; trace_inwater = false; trace_inopen = true; - trace_endpos = it.move_origin; + trace_endpos = it.origin; trace_plane_normal = '0 0 1'; trace_plane_dist = 0; trace_ent = this; @@ -347,45 +354,50 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGr }); } +bool autocvar__movetype_debug = false; void _Movetype_LinkEdict(entity this, bool touch_triggers) // SV_LinkEdict { - vector mi, ma; - if(this.solid == SOLID_BSP) + if(autocvar__movetype_debug) { - // TODO set the absolute bbox - mi = this.mins; - ma = this.maxs; - } - else - { - mi = this.mins; - ma = this.maxs; - } - mi += this.move_origin; - ma += this.move_origin; + vector mi, ma; + if(this.solid == SOLID_BSP) + { + // TODO set the absolute bbox + mi = this.mins; + ma = this.maxs; + } + else + { + mi = this.mins; + ma = this.maxs; + } + mi += this.origin; + ma += this.origin; - if(this.move_flags & FL_ITEM) - { - mi.x -= 15; - mi.y -= 15; - mi.z -= 1; - ma.x += 15; - ma.y += 15; - ma.z += 1; + if(this.flags & FL_ITEM) + { + mi -= '15 15 1'; + ma += '15 15 1'; + } + else + { + mi -= '1 1 1'; + ma += '1 1 1'; + } + + this.absmin = mi; + this.absmax = ma; } else { - mi.x -= 1; - mi.y -= 1; - mi.z -= 1; - ma.x += 1; - ma.y += 1; - ma.z += 1; + setorigin(this, this.origin); // calls SV_LinkEdict + #ifdef CSQC + // NOTE: CSQC's version of setorigin doesn't expand + this.absmin -= '1 1 1'; + this.absmax += '1 1 1'; + #endif } - this.absmin = mi; - this.absmax = ma; - if(touch_triggers) _Movetype_LinkEdict_TouchAreaGrid(this); } @@ -394,26 +406,26 @@ entity _Movetype_TestEntityPosition_ent; bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition { entity this = _Movetype_TestEntityPosition_ent; -// vector org = this.move_origin + ofs; + vector org = this.origin + ofs; int cont = this.dphitcontentsmask; this.dphitcontentsmask = DPCONTENTS_SOLID; - tracebox(this.move_origin, this.mins, this.maxs, this.move_origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this); + tracebox(org, this.mins, this.maxs, org, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this); this.dphitcontentsmask = cont; if(trace_startsolid) return true; - if(vdist(trace_endpos - this.move_origin, >, 0.0001)) - this.move_origin = trace_endpos; + if(vdist(trace_endpos - this.origin, >, 0.0001)) + this.origin = trace_endpos; return false; } -bool _Movetype_UnstickEntity(entity this) // SV_UnstickEntity +int _Movetype_UnstickEntity(entity this) // SV_UnstickEntity { _Movetype_TestEntityPosition_ent = this; if (!_Movetype_TestEntityPosition(' 0 0 0')) { - return true; + return UNSTICK_FINE; } #define X(v) if (_Movetype_TestEntityPosition(v)) X('-1 0 0') X(' 1 0 0') @@ -430,15 +442,34 @@ bool _Movetype_UnstickEntity(entity this) // SV_UnstickEntity X(17) #undef X { - LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n", - etof(this), this.classname, vtos(this.move_origin)); - return false; + LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)", + etof(this), this.classname, vtos(this.origin)); + return UNSTICK_STUCK; } } - LOG_DEBUGF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n", - etof(this), this.classname, vtos(this.move_origin)); + LOG_DEBUGF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)", + etof(this), this.classname, vtos(this.origin)); _Movetype_LinkEdict(this, true); - return true; + return UNSTICK_FIXED; +} + +void _Movetype_CheckStuck(entity this) // SV_CheckStuck +{ + int unstick = _Movetype_UnstickEntity(this); // sets test position entity + switch(unstick) + { + case UNSTICK_FINE: + this.oldorigin = this.origin; + break; + case UNSTICK_FIXED: + break; // already sorted + case UNSTICK_STUCK: + vector offset = this.oldorigin - this.origin; + if(!_Movetype_TestEntityPosition(offset)) + _Movetype_LinkEdict(this, false); + // couldn't unstick, should we warn about this? + break; + } } vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity @@ -454,7 +485,7 @@ vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVeloc void _Movetype_PushEntityTrace(entity this, vector push) { - vector end = this.move_origin + push; + vector end = this.origin + push; int type; if(this.move_nomonsters) type = max(0, this.move_nomonsters); @@ -467,7 +498,7 @@ void _Movetype_PushEntityTrace(entity this, vector push) else type = MOVE_NORMAL; - tracebox(this.move_origin, this.mins, this.maxs, end, type, this); + tracebox(this.origin, this.mins, this.maxs, end, type, this); } float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid) // SV_PushEntity @@ -477,10 +508,10 @@ float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid) // if(trace_startsolid && failonstartsolid) return trace_fraction; - this.move_origin = trace_endpos; + this.origin = trace_endpos; if(trace_fraction < 1) - if(this.solid >= SOLID_TRIGGER && (!(this.move_flags & FL_ONGROUND) || (this.move_groundentity != trace_ent))) + if(this.solid >= SOLID_TRIGGER && (!IS_ONGROUND(this) || (this.groundentity != trace_ent))) _Movetype_Impact(this, trace_ent); return trace_fraction; @@ -489,60 +520,6 @@ float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid) // .float ltime; .void() blocked; -// matrix version of makevectors, sets v_forward, v_right and v_up -void makevectors_matrix(vector myangles) // AngleVectorsFLU -{ - v_forward = v_right = v_up = '0 0 0'; - - float y = myangles.y * (M_PI * 2 / 360); - float sy = sin(y); - float cy = cos(y); - float p = myangles.x * (M_PI * 2 / 360); - float sp = sin(p); - float cp = cos(p); - if(v_forward) - { - v_forward.x = cp * cy; - v_forward.y = cp * sy; - v_forward.z = -sp; - } - if(v_right || v_up) - { - if(myangles.z) - { - float r = myangles.z * (M_PI * 2 / 360); - float sr = sin(r); - float cr = cos(r); - if(v_right) - { - v_right.x = sr * sp * cy + cr * -sy; - v_right.y = sr * sp * sy + cr * cy; - v_right.z = sr * cp; - } - if(v_up) - { - v_up.x = cr * sp * cy + -sr * -sy; - v_up.y = cr * sp * sy + -sr * cy; - v_up.z = cr * cp; - } - } - else - { - if(v_right) - { - v_right.x = -sy; - v_right.y = cy; - v_right.z = 0; - } - if(v_up) - { - v_up.x = sp * cy; - v_up.y = sp * sy; - v_up.z = cp; - } - } - } -} void _Movetype_Physics_Frame(entity this, float movedt) { @@ -551,7 +528,7 @@ void _Movetype_Physics_Frame(entity this, float movedt) { case MOVETYPE_PUSH: case MOVETYPE_FAKEPUSH: - _Movetype_Physics_Pusher(this, movedt); + LOG_DEBUGF("Physics: Lacking QuakeC support for Push movetype, FIX ME by using engine physics!"); break; case MOVETYPE_NONE: break; @@ -560,8 +537,8 @@ void _Movetype_Physics_Frame(entity this, float movedt) break; case MOVETYPE_NOCLIP: _Movetype_CheckWater(this); - this.move_origin = this.move_origin + TICRATE * this.move_velocity; - this.move_angles = this.move_angles + TICRATE * this.move_avelocity; + this.origin = this.origin + movedt * this.velocity; + this.angles = this.angles + movedt * this.avelocity; _Movetype_LinkEdict(this, false); break; case MOVETYPE_STEP: @@ -577,6 +554,8 @@ void _Movetype_Physics_Frame(entity this, float movedt) case MOVETYPE_FLY: case MOVETYPE_FLY_WORLDONLY: _Movetype_Physics_Toss(this, movedt); + if(wasfreed(this)) + return; _Movetype_LinkEdict(this, true); break; case MOVETYPE_PHYSICS: @@ -591,7 +570,7 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt) { case MOVETYPE_PUSH: case MOVETYPE_FAKEPUSH: - _Movetype_Physics_Pusher(this, movedt); + LOG_DEBUGF("Physics: Lacking QuakeC support for Push movetype, FIX ME by using engine physics!"); break; case MOVETYPE_NONE: break; @@ -600,9 +579,8 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt) break; case MOVETYPE_NOCLIP: _Movetype_CheckWater(this); - this.move_origin = this.move_origin + movedt * this.move_velocity; - this.move_angles = this.move_angles + movedt * this.move_avelocity; - _Movetype_LinkEdict(this, false); + this.origin = this.origin + movedt * this.velocity; + this.angles = this.angles + movedt * this.avelocity; break; case MOVETYPE_STEP: _Movetype_Physics_Step(this, movedt); @@ -621,6 +599,26 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt) case MOVETYPE_PHYSICS: break; } + + //_Movetype_CheckVelocity(this); + + _Movetype_LinkEdict(this, true); + + //_Movetype_CheckVelocity(this); +} + +void Movetype_Physics_NoMatchTicrate(entity this, float movedt, bool isclient) // to be run every move frame +{ + this.move_time = time; + + if(isclient) + _Movetype_Physics_ClientFrame(this, movedt); + else + _Movetype_Physics_Frame(this, movedt); + if(wasfreed(this)) + return; + + setorigin(this, this.origin); } void Movetype_Physics_NoMatchServer(entity this) // optimized @@ -632,10 +630,7 @@ void Movetype_Physics_NoMatchServer(entity this) // optimized if(wasfreed(this)) return; - this.avelocity = this.move_avelocity; - this.velocity = this.move_velocity; - this.angles = this.move_angles; - setorigin(this, this.move_origin); + setorigin(this, this.origin); } void Movetype_Physics_MatchServer(entity this, bool sloppy) @@ -643,11 +638,49 @@ void Movetype_Physics_MatchServer(entity this, bool sloppy) Movetype_Physics_MatchTicrate(this, TICRATE, sloppy); } +.vector tic_origin; +.vector tic_velocity; +.int tic_flags; +.vector tic_avelocity; +.vector tic_angles; + +.vector tic_saved_origin; +.vector tic_saved_velocity; +.int tic_saved_flags; +.vector tic_saved_avelocity; +.vector tic_saved_angles; void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy) // SV_Physics_Entity { +#define X(s) \ + if(this.(s) != this.tic_saved_##s) \ + this.tic_##s = this.(s) + + X(origin); + X(velocity); + X(flags); + X(avelocity); + X(angles); +#undef X + if(tr <= 0) { + this.flags = this.tic_flags; + this.velocity = this.tic_velocity; + this.origin = this.tic_origin; + this.avelocity = this.tic_avelocity; + this.angles = this.tic_angles; Movetype_Physics_NoMatchServer(this); + this.tic_origin = this.origin; + this.tic_velocity = this.velocity; + this.tic_avelocity = this.avelocity; + this.tic_angles = this.angles; + this.tic_flags = this.flags; + + this.tic_saved_flags = this.flags; + this.tic_saved_velocity = this.velocity; + this.tic_saved_origin = this.origin; + this.tic_saved_avelocity = this.avelocity; + this.tic_saved_angles = this.angles; return; } @@ -658,21 +691,31 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy) // SV_Ph this.move_time += n * tr; if(!this.move_didgravity) - this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.move_flags & FL_ONGROUND)); + this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.tic_flags & FL_ONGROUND)); for (int i = 0; i < n; ++i) { + this.flags = this.tic_flags; + this.velocity = this.tic_velocity; + setorigin(this, this.tic_origin); + this.avelocity = this.tic_avelocity; + this.angles = this.tic_angles; _Movetype_Physics_Frame(this, tr); + this.tic_origin = this.origin; + this.tic_velocity = this.velocity; + this.tic_avelocity = this.avelocity; + this.tic_angles = this.angles; + this.tic_flags = this.flags; if(wasfreed(this)) return; } - this.avelocity = this.move_avelocity; + this.avelocity = this.tic_avelocity; - if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.move_flags & FL_ONGROUND)) + if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.tic_flags & FL_ONGROUND)) { // now continue the move from move_time to time - this.velocity = this.move_velocity; + this.velocity = this.tic_velocity; if(this.move_didgravity > 0) { @@ -682,15 +725,18 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy) // SV_Ph * PHYS_GRAVITY(this); } - this.angles = this.move_angles + dt * this.avelocity; + this.angles = this.tic_angles + dt * this.avelocity; if(sloppy || this.move_movetype == MOVETYPE_NOCLIP) { - setorigin(this, this.move_origin + dt * this.velocity); + setorigin(this, this.tic_origin + dt * this.velocity); } else { + vector oldorg = this.origin; + this.origin = this.tic_origin; _Movetype_PushEntityTrace(this, dt * this.velocity); + this.origin = oldorg; if(!trace_startsolid) setorigin(this, trace_endpos); } @@ -700,8 +746,14 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy) // SV_Ph } else { - this.velocity = this.move_velocity; - this.angles = this.move_angles; - setorigin(this, this.move_origin); + this.velocity = this.tic_velocity; + this.angles = this.tic_angles; + setorigin(this, this.tic_origin); } + + this.tic_saved_flags = this.flags; + this.tic_saved_velocity = this.velocity; + this.tic_saved_origin = this.origin; + this.tic_saved_avelocity = this.avelocity; + this.tic_saved_angles = this.angles; }