From ae82f85be7a1ccc080e5ea620976a03c43eeb962 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 5 Jan 2015 19:56:19 +1100 Subject: [PATCH] Predict conveyors --- qcsrc/client/Main.qc | 2 + qcsrc/client/autocvars.qh | 1 + qcsrc/client/main.qh | 2 + qcsrc/client/progs.src | 1 + qcsrc/common/constants.qh | 1 + qcsrc/common/physics.qc | 30 ++++---- qcsrc/common/physics.qh | 10 +++ qcsrc/common/stats.qh | 2 +- qcsrc/dpdefs/csprogsdefs.qc | 1 + qcsrc/server/defs.qh | 2 - qcsrc/server/miscfunctions.qc | 2 - qcsrc/server/t_plats.qc | 123 ++++++++++++++++++++++++++++++- qcsrc/warpzonelib/common.qc | 56 ++++++++++++++ qcsrc/warpzonelib/common.qh | 3 + qcsrc/warpzonelib/util_server.qc | 55 -------------- 15 files changed, 214 insertions(+), 77 deletions(-) diff --git a/qcsrc/client/Main.qc b/qcsrc/client/Main.qc index 5985c34e2..aff71b806 100644 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@ -745,6 +745,7 @@ void Ent_ScoresInfo(); void ent_func_ladder(); void ent_trigger_push(); void ent_target_push(); +void ent_conveyor(); void CSQC_Ent_Update(float bIsNewEntity) { float t; @@ -832,6 +833,7 @@ void CSQC_Ent_Update(float bIsNewEntity) case ENT_CLIENT_LADDER: ent_func_ladder(); break; case ENT_CLIENT_TRIGGER_PUSH: ent_trigger_push(); break; case ENT_CLIENT_TARGET_PUSH: ent_target_push(); break; + case ENT_CLIENT_CONVEYOR: ent_conveyor(); break; default: //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype)); diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index f06c5bfb3..adc587764 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -463,3 +463,4 @@ var vector autocvar_crosshair_rpc_color = '0.2 1.0 0.2'; var float autocvar_crosshair_rpc_alpha = 1; var float autocvar_crosshair_rpc_size = 1; float autocvar_cl_nade_timer; +float autocvar_speedmeter; diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index c9aa2fb40..ca211274b 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -148,3 +148,5 @@ entity entcs_receiver[255]; // 255 is the engine limit on maxclients float hud; float view_quality; float framecount; + +.float jumppadcount; diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 4fa790229..e414576c3 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -125,6 +125,7 @@ command/cl_cmd.qc ../server/mutators/mutator_multijump.qc ../server/t_halflife.qc ../server/t_jumppads.qc +../server/t_plats.qc ../common/nades.qc ../common/buffs.qc diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 8392d1dad..28cf97f5d 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -103,6 +103,7 @@ const float ENT_CLIENT_VEHICLE = 60; const float ENT_CLIENT_LADDER = 61; const float ENT_CLIENT_TRIGGER_PUSH = 62; const float ENT_CLIENT_TARGET_PUSH = 63; +const float ENT_CLIENT_CONVEYOR = 64; const float ENT_CLIENT_HEALING_ORB = 80; diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index ad2e97944..233e3c33d 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -513,21 +513,19 @@ float PlayerJump (void) } } -#ifdef SVQC - if (!(self.lastflags & FL_ONGROUND)) + if (!WAS_ONGROUND(self)) { - if (autocvar_speedmeter) + if(autocvar_speedmeter) dprint(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n")); - if (self.lastground < time - 0.3) + if(self.lastground < time - 0.3) { - self.velocity_x *= (1 - autocvar_sv_friction_on_land); - self.velocity_y *= (1 - autocvar_sv_friction_on_land); + self.velocity_x *= (1 - PHYS_FRICTION_ONLAND); + self.velocity_y *= (1 - PHYS_FRICTION_ONLAND); } - if (self.jumppadcount > 1) + if(self.jumppadcount > 1) dprint(strcat(ftos(self.jumppadcount), "x jumppad combo\n")); self.jumppadcount = 0; } -#endif self.velocity_z += mjumpheight; @@ -1572,18 +1570,16 @@ void SV_WalkMove () #endif void PM_walk(float buttons_prev, float maxspd_mod) { -#ifdef SVQC - if (!(self.lastflags & FL_ONGROUND)) + if (!WAS_ONGROUND(self)) { if (autocvar_speedmeter) dprint(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n")); if (self.lastground < time - 0.3) - self.velocity *= (1 - autocvar_sv_friction_on_land); + self.velocity *= (1 - PHYS_FRICTION_ONLAND); if (self.jumppadcount > 1) dprint(strcat(ftos(self.jumppadcount), "x jumppad combo\n")); self.jumppadcount = 0; } -#endif // walking makevectors(PHYS_INPUT_ANGLES(self).y * '0 1 0'); vector wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self).x @@ -1844,11 +1840,9 @@ void PM_Main() } #endif -#ifdef SVQC // conveyors: first fix velocity if (self.conveyor.state) self.velocity -= self.conveyor.movedir; -#endif #ifdef SVQC MUTATOR_CALLHOOK(PlayerPhysics); @@ -1984,12 +1978,16 @@ void PM_Main() if (IS_ONGROUND(self)) self.lastground = time; -#ifdef SVQC // conveyors: then break velocity again if (self.conveyor.state) self.velocity += self.conveyor.movedir; -#endif + +#ifdef SVQC self.lastflags = self.flags; +#elif defined(CSQC) + self.lastflags = self.pmove_flags; +#endif + self.lastclassname = self.classname; } diff --git a/qcsrc/common/physics.qh b/qcsrc/common/physics.qh index 7a9bd3c54..3ddb24486 100644 --- a/qcsrc/common/physics.qh +++ b/qcsrc/common/physics.qh @@ -1,5 +1,7 @@ // Client/server mappings +.entity conveyor; + #ifdef CSQC float player_multijump; @@ -10,6 +12,7 @@ #define PHYS_WORLD_ANGLES(s) input_angles #define PHYS_INPUT_TIMELENGTH input_timelength + #define PHYS_INPUT_FRAMETIME serverdeltatime #define PHYS_INPUT_MOVEVALUES(s) input_movevalues @@ -45,6 +48,8 @@ #define SET_ONGROUND(s) s.pmove_flags |= PMF_ONGROUND #define UNSET_ONGROUND(s) s.pmove_flags &= ~PMF_ONGROUND + #define WAS_ONGROUND(s) !!(s.lastflags & PMF_ONGROUND) + #define ITEMS(s) getstati(STAT_ITEMS, 0, 24) #define PHYS_AMMO_FUEL(s) getstati(STAT_FUEL) @@ -72,6 +77,7 @@ #define PHYS_AIRSTRAFEACCELERATE getstatf(STAT_MOVEVARS_AIRSTRAFEACCELERATE) #define PHYS_ENTGRAVITY(s) getstatf(STAT_MOVEVARS_ENTGRAVITY) #define PHYS_FRICTION getstatf(STAT_MOVEVARS_FRICTION) + #define PHYS_FRICTION_ONLAND getstatf(STAT_MOVEVARS_FRICTION_ONLAND) #define PHYS_GRAVITY getstatf(STAT_MOVEVARS_GRAVITY) #define PHYS_HIGHSPEED getstatf(STAT_MOVEVARS_HIGHSPEED) #define PHYS_JUMPVELOCITY getstatf(STAT_MOVEVARS_JUMPVELOCITY) @@ -101,6 +107,7 @@ #define PHYS_WORLD_ANGLES(s) s.angles #define PHYS_INPUT_TIMELENGTH frametime + #define PHYS_INPUT_FRAMETIME sys_frametime #define PHYS_INPUT_MOVEVALUES(s) s.movement // TODO: cache @@ -136,6 +143,8 @@ #define SET_ONGROUND(s) s.flags |= FL_ONGROUND #define UNSET_ONGROUND(s) s.flags &= ~FL_ONGROUND + #define WAS_ONGROUND(s) !!((s).lastflags & FL_ONGROUND) + #define ITEMS(s) s.items #define PHYS_AMMO_FUEL(s) s.ammo_fuel @@ -163,6 +172,7 @@ #define PHYS_AIRSTRAFEACCELERATE autocvar_sv_airstrafeaccelerate #define PHYS_ENTGRAVITY(s) s.gravity #define PHYS_FRICTION autocvar_sv_friction + #define PHYS_FRICTION_ONLAND autocvar_sv_friction_on_land #define PHYS_GRAVITY autocvar_sv_gravity #define PHYS_HIGHSPEED autocvar_g_movement_highspeed #define PHYS_JUMPVELOCITY autocvar_sv_jumpvelocity diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index 9b383fa92..ef4472d9f 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -224,7 +224,7 @@ const float STAT_REVIVE_PROGRESS = 106; // 189 empty? // 190 empty? // 191 empty? -// 192 empty? +const float STAT_MOVEVARS_FRICTION_ONLAND = 192; const float STAT_MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS = 193; const float STAT_MOVEVARS_JUMPSPEEDCAP_MAX = 194; const float STAT_MOVEVARS_JUMPSPEEDCAP_MIN = 195; diff --git a/qcsrc/dpdefs/csprogsdefs.qc b/qcsrc/dpdefs/csprogsdefs.qc index 8f4ec8b41..d7ae8c3bb 100644 --- a/qcsrc/dpdefs/csprogsdefs.qc +++ b/qcsrc/dpdefs/csprogsdefs.qc @@ -420,6 +420,7 @@ float( float a, ... ) min = #94; float( float b, ... ) max = #95; float(float minimum, float val, float maximum) bound = #96; float(float f, float f) pow = #97; +entity(entity start, .entity fld, entity match) findentity = #98; entity(entity start, .float fld, float match) findfloat = #98; float(string s) checkextension = #99; // FrikaC and Telejano range #100-#199 diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index fd217f0ab..870c61c75 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -584,8 +584,6 @@ void PlayerUseKey(); typedef vector(entity player, entity spot, vector current) spawn_evalfunc_t; .spawn_evalfunc_t spawn_evalfunc; -.entity conveyor; - string modname; .float missile_flags; diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index e6fda399e..22fa4e3a4 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -77,8 +77,6 @@ float DistributeEvenly_GetRandomized(float weight) return f; } -#define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e) - const string STR_PLAYER = "player"; const string STR_SPECTATOR = "spectator"; const string STR_OBSERVER = "observer"; diff --git a/qcsrc/server/t_plats.qc b/qcsrc/server/t_plats.qc index 315abe152..7bf3c70a8 100644 --- a/qcsrc/server/t_plats.qc +++ b/qcsrc/server/t_plats.qc @@ -1,3 +1,5 @@ +#ifdef SVQC + .float dmgtime2; void generic_plat_blocked() { @@ -2169,8 +2171,15 @@ void spawnfunc_func_vectormamamam() InitializeEntity(self, func_vectormamamam_findtarget, INITPRIO_FINDTARGET); } +#endif + void conveyor_think() { +#ifdef CSQC + float dt = time - self.move_time; + self.move_time = time; + if(dt <= 0) { return; } +#endif entity e; // set myself as current conveyor where possible @@ -2181,7 +2190,11 @@ void conveyor_think() { for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain) if(!e.conveyor.state) +#ifdef SVQC if(isPushable(e)) +#elif defined(CSQC) + if(e.isplayermodel) +#endif { vector emin = e.absmin; vector emax = e.absmax; @@ -2197,12 +2210,19 @@ void conveyor_think() for(e = world; (e = findentity(e, conveyor, self)); ) { +#ifdef SVQC if(IS_CLIENT(e)) // doing it via velocity has quite some advantages continue; // done in SV_PlayerPhysics +#elif defined(CSQC) + if(e.isplayermodel) + continue; +#endif - setorigin(e, e.origin + self.movedir * sys_frametime); + setorigin(e, e.origin + self.movedir * PHYS_INPUT_FRAMETIME); move_out_of_solid(e); +#ifdef SVQC UpdateCSQCProjectile(e); +#endif /* // stupid conveyor code tracebox(e.origin, e.mins, e.maxs, e.origin + self.movedir * sys_frametime, MOVE_NORMAL, e); @@ -2212,17 +2232,61 @@ void conveyor_think() } } +#ifdef SVQC self.nextthink = time; +#endif } +#ifdef SVQC + void conveyor_use() { self.state = !self.state; + + self.SendFlags |= 2; } void conveyor_reset() { self.state = (self.spawnflags & 1); + + self.SendFlags |= 2; +} + +float conveyor_send(entity to, float sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_CONVEYOR); + WriteByte(MSG_ENTITY, sf); + + if(sf & 1) + { + WriteByte(MSG_ENTITY, self.warpzone_isboxy); + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + + WriteCoord(MSG_ENTITY, self.mins_x); + WriteCoord(MSG_ENTITY, self.mins_y); + WriteCoord(MSG_ENTITY, self.mins_z); + WriteCoord(MSG_ENTITY, self.maxs_x); + WriteCoord(MSG_ENTITY, self.maxs_y); + WriteCoord(MSG_ENTITY, self.maxs_z); + + WriteCoord(MSG_ENTITY, self.movedir_x); + WriteCoord(MSG_ENTITY, self.movedir_y); + WriteCoord(MSG_ENTITY, self.movedir_z); + + WriteByte(MSG_ENTITY, self.speed); + WriteByte(MSG_ENTITY, self.state); + + WriteString(MSG_ENTITY, self.targetname); + WriteString(MSG_ENTITY, self.target); + } + + if(sf & 2) + WriteByte(MSG_ENTITY, self.state); + + return TRUE; } void conveyor_init() @@ -2240,6 +2304,10 @@ void conveyor_init() } else self.state = 1; + + Net_LinkEntity(self, 0, FALSE, conveyor_send); + + self.SendFlags |= 1; } void spawnfunc_trigger_conveyor() @@ -2256,3 +2324,56 @@ void spawnfunc_func_conveyor() self.movetype = MOVETYPE_NONE; conveyor_init(); } + +#elif defined(CSQC) + +void conveyor_init() +{ + self.draw = conveyor_think; + self.drawmask = MASK_NORMAL; + + self.movetype = MOVETYPE_NONE; + self.model = ""; + self.solid = SOLID_TRIGGER; + self.move_origin = self.origin; + self.move_time = time; +} + +void ent_conveyor() +{ + float sf = ReadByte(); + + if(sf & 1) + { + self.warpzone_isboxy = ReadByte(); + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + setorigin(self, self.origin); + + self.mins_x = ReadCoord(); + self.mins_y = ReadCoord(); + self.mins_z = ReadCoord(); + self.maxs_x = ReadCoord(); + self.maxs_y = ReadCoord(); + self.maxs_z = ReadCoord(); + setsize(self, self.mins, self.maxs); + + self.movedir_x = ReadCoord(); + self.movedir_y = ReadCoord(); + self.movedir_z = ReadCoord(); + + self.speed = ReadByte(); + self.state = ReadByte(); + + self.targetname = strzone(ReadString()); + self.target = strzone(ReadString()); + + conveyor_init(); + } + + if(sf & 2) + self.state = ReadByte(); +} + +#endif diff --git a/qcsrc/warpzonelib/common.qc b/qcsrc/warpzonelib/common.qc index 3f9835959..521cf343b 100644 --- a/qcsrc/warpzonelib/common.qc +++ b/qcsrc/warpzonelib/common.qc @@ -768,3 +768,59 @@ float WarpZoneLib_ExactTrigger_Touch() { return !WarpZoneLib_BoxTouchesBrush(other.absmin, other.absmax, self, other); } + + +void WarpZoneLib_MoveOutOfSolid_Expand(entity e, vector by) +{ + float eps = 0.0625; + tracebox(e.origin, e.mins - '1 1 1' * eps, e.maxs + '1 1 1' * eps, e.origin + by, MOVE_WORLDONLY, e); + if (trace_startsolid) + return; + if (trace_fraction < 1) + { + // hit something + // adjust origin in the other direction... + setorigin(e,e.origin - by * (1 - trace_fraction)); + } +} + +float WarpZoneLib_MoveOutOfSolid(entity e) +{ + vector o, m0, m1; + + o = e.origin; + traceline(o, o, MOVE_WORLDONLY, e); + if (trace_startsolid) + return FALSE; + + tracebox(o, e.mins, e.maxs, o, MOVE_WORLDONLY, e); + if (!trace_startsolid) + return TRUE; + + m0 = e.mins; + m1 = e.maxs; + e.mins = '0 0 0'; + e.maxs = '0 0 0'; + WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m0_x); + e.mins_x = m0_x; + WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m1_x); + e.maxs_x = m1_x; + WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m0_y); + e.mins_y = m0_y; + WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m1_y); + e.maxs_y = m1_y; + WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m0_z); + e.mins_z = m0_z; + WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m1_z); + e.maxs_z = m1_z; + setorigin(e, e.origin); + + tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e); + if (trace_startsolid) + { + setorigin(e, o); + return FALSE; + } + + return TRUE; +} diff --git a/qcsrc/warpzonelib/common.qh b/qcsrc/warpzonelib/common.qh index c79ee95d6..8a8cfb227 100644 --- a/qcsrc/warpzonelib/common.qh +++ b/qcsrc/warpzonelib/common.qh @@ -100,3 +100,6 @@ entity WarpZone_RefSys_SpawnSameRefSys(entity me); // spawn().R = me.R #ifndef BITXOR_ASSIGN # define BITXOR_ASSIGN(a,b) ((a) = ((a) | (b)) - ((a) & (b))) #endif + +float WarpZoneLib_MoveOutOfSolid(entity e); +#define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e) diff --git a/qcsrc/warpzonelib/util_server.qc b/qcsrc/warpzonelib/util_server.qc index eafe2d47c..87f737a46 100644 --- a/qcsrc/warpzonelib/util_server.qc +++ b/qcsrc/warpzonelib/util_server.qc @@ -1,58 +1,3 @@ -void WarpZoneLib_MoveOutOfSolid_Expand(entity e, vector by) -{ - float eps = 0.0625; - tracebox(e.origin, e.mins - '1 1 1' * eps, e.maxs + '1 1 1' * eps, e.origin + by, MOVE_WORLDONLY, e); - if (trace_startsolid) - return; - if (trace_fraction < 1) - { - // hit something - // adjust origin in the other direction... - setorigin(e,e.origin - by * (1 - trace_fraction)); - } -} - -float WarpZoneLib_MoveOutOfSolid(entity e) -{ - vector o, m0, m1; - - o = e.origin; - traceline(o, o, MOVE_WORLDONLY, e); - if (trace_startsolid) - return FALSE; - - tracebox(o, e.mins, e.maxs, o, MOVE_WORLDONLY, e); - if (!trace_startsolid) - return TRUE; - - m0 = e.mins; - m1 = e.maxs; - e.mins = '0 0 0'; - e.maxs = '0 0 0'; - WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m0_x); - e.mins_x = m0_x; - WarpZoneLib_MoveOutOfSolid_Expand(e, '1 0 0' * m1_x); - e.maxs_x = m1_x; - WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m0_y); - e.mins_y = m0_y; - WarpZoneLib_MoveOutOfSolid_Expand(e, '0 1 0' * m1_y); - e.maxs_y = m1_y; - WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m0_z); - e.mins_z = m0_z; - WarpZoneLib_MoveOutOfSolid_Expand(e, '0 0 1' * m1_z); - e.maxs_z = m1_z; - setorigin(e, e.origin); - - tracebox(e.origin, e.mins, e.maxs, e.origin, MOVE_WORLDONLY, e); - if (trace_startsolid) - { - setorigin(e, o); - return FALSE; - } - - return TRUE; -} - void WarpZoneLib_ExactTrigger_Init() { vector mi, ma; -- 2.39.2