From f7d31636b036cfe74ffa30962b0bbf9cdae0b73e Mon Sep 17 00:00:00 2001 From: div0 Date: Thu, 20 Nov 2008 14:18:30 +0000 Subject: [PATCH] hidden cvar: car-like physics mode; misc_gamemodel: extra spawnflags; properly support scale on SOLID_BSP misc_gamemodels by adjusting mins/maxs git-svn-id: svn://svn.icculus.org/nexuiz/trunk@5064 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/server/cl_client.qc | 5 ++- data/qcsrc/server/cl_physics.qc | 75 ++++++++++++++++++++++++++++++++- data/qcsrc/server/g_subs.qc | 8 +++- data/qcsrc/server/sv_main.qc | 1 + data/qcsrc/server/t_items.qc | 21 +++++++++ data/scripts/entities.def | 5 ++- 6 files changed, 110 insertions(+), 5 deletions(-) diff --git a/data/qcsrc/server/cl_client.qc b/data/qcsrc/server/cl_client.qc index 30ead9837..72aa88c60 100644 --- a/data/qcsrc/server/cl_client.qc +++ b/data/qcsrc/server/cl_client.qc @@ -634,7 +634,10 @@ void PutClientInServer (void) self.classname = "player"; self.iscreature = TRUE; - self.movetype = MOVETYPE_WALK; + if(cvar("g_bigrigs")) + self.movetype = MOVETYPE_PUSH; + else + self.movetype = MOVETYPE_WALK; self.solid = SOLID_SLIDEBOX; self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; if(independent_players) diff --git a/data/qcsrc/server/cl_physics.qc b/data/qcsrc/server/cl_physics.qc index c43849b4d..4e0ddaf66 100644 --- a/data/qcsrc/server/cl_physics.qc +++ b/data/qcsrc/server/cl_physics.qc @@ -249,7 +249,7 @@ void SV_PlayerPhysics() if (self.deadflag) return; - if (!self.fixangle) + if (!self.fixangle && self.movetype != MOVETYPE_PUSH) { self.angles_x = 0; self.angles_y = self.v_angle_y; @@ -331,6 +331,79 @@ void SV_PlayerPhysics() self.velocity = self.velocity + wishdir * min(f, sv_accelerate*maxspd_mod * frametime * wishspeed); } } + else if (self.movetype == MOVETYPE_PUSH) + { + // using this move type for "big rigs" + // the engine does not push the entity! + + float accel, steer, myspeed, steerfactor, accelfactor, upspeed, friction; + vector neworigin, up, angles_save; + + accel = self.movement_x / sv_maxspeed; + steer = self.movement_y / sv_maxspeed; + + angles_save = self.angles; + self.angles_x = 0; + self.angles_z = 0; + makevectors(self.angles); // new forward direction! + myspeed = self.velocity * v_forward; + upspeed = self.velocity * v_up; + if(myspeed <= 0 && accel < 0) + steerfactor = -5000; // LOL + else + steerfactor = -400 * 400 / (400 + myspeed); + accelfactor = 2000 * 400 / (400 + max(myspeed, -myspeed)); + friction = 5 * 100 / (100 + max(myspeed, -myspeed)); + + self.angles_y += steer * frametime * steerfactor; // apply steering + makevectors(self.angles); // new forward direction! + + myspeed = myspeed * (1 - frametime * friction); + myspeed += accel * accelfactor * frametime; + if(myspeed < 0) + myspeed = 0; + + self.velocity = v_forward * myspeed; + upspeed -= frametime * sv_gravity; + + tracebox(self.origin, self.mins, self.maxs, self.origin + '0 0 1024', MOVE_NORMAL, self); + up = trace_endpos - self.origin; + + // can we move? + neworigin = trace_endpos + self.velocity * frametime; + tracebox(trace_endpos, self.mins, self.maxs, neworigin, MOVE_NORMAL, self); + + // align to surface + tracebox(trace_endpos, self.mins, self.maxs, neworigin - up + '0 0 1' * upspeed * frametime, MOVE_NORMAL, self); + + if(trace_fraction >= 0.5) + self.origin = trace_endpos; + else + trace_fraction = 1; + + // now set angles_x so that the car points parallel to the surface + if(trace_fraction < 1) + { + self.angles = vectoangles(normalize( + '1 0 0' * v_forward_x * trace_plane_normal_z + + + '0 1 0' * v_forward_y * trace_plane_normal_z + + + '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y) + )); + self.flags |= FL_ONGROUND; + } + else + { + self.angles_x = angles_save_x; + self.angles_z = angles_save_z; + self.velocity += '0 0 1' * upspeed; + self.flags (-) FL_ONGROUND; + } + + // relink + setorigin(self, self.origin); + } else if (self.waterlevel >= 2) { // swimming diff --git a/data/qcsrc/server/g_subs.qc b/data/qcsrc/server/g_subs.qc index 8f730dedc..1ad8d7faf 100644 --- a/data/qcsrc/server/g_subs.qc +++ b/data/qcsrc/server/g_subs.qc @@ -372,6 +372,7 @@ float angc (float a1, float a2) .float loddistance1; .float loddistance2; +vector NearestPointOnBox(entity box, vector org); float LOD_customize() { float d; @@ -389,7 +390,7 @@ float LOD_customize() } // TODO csqc network this so it only gets sent once - d = vlen(self.origin - other.origin); + d = vlen(NearestPointOnBox(self, other.origin) - other.origin); if(d < self.loddistance1) self.modelindex = self.lodmodelindex0; else if(!self.lodmodelindex2 || d < self.loddistance2) @@ -468,7 +469,10 @@ void SetBrushEntityModel() InitializeEntity(self, LODmodel_attach, INITPRIO_FINDTARGET); } setorigin(self, self.origin); - setsize(self, self.mins, self.maxs); + if(self.scale) + setsize(self, self.mins * self.scale, self.maxs * self.scale); + else + setsize(self, self.mins, self.maxs); } /* diff --git a/data/qcsrc/server/sv_main.qc b/data/qcsrc/server/sv_main.qc index 3334de683..c4aab697c 100644 --- a/data/qcsrc/server/sv_main.qc +++ b/data/qcsrc/server/sv_main.qc @@ -143,6 +143,7 @@ void StartFrame (void) UncustomizeEntitiesRun(); InitializeEntitiesRun(); + sv_gravity = cvar("sv_gravity"); sv_maxairspeed = cvar("sv_maxairspeed"); sv_maxspeed = cvar ("sv_maxspeed"); sv_friction = cvar ("sv_friction"); diff --git a/data/qcsrc/server/t_items.qc b/data/qcsrc/server/t_items.qc index 777c8f4a0..c35660b94 100644 --- a/data/qcsrc/server/t_items.qc +++ b/data/qcsrc/server/t_items.qc @@ -948,6 +948,25 @@ void spawnfunc_func_illusionary (void) self.use = func_wall_use; } +void gamemodel_drop() +{ + if(self.spawnflags & 3 == 1) // ALIGN_ORIGIN + { + traceline(self.origin, self.origin - '0 0 1024', MOVE_NOMONSTERS, self); + setorigin(self, trace_endpos); + } + else if(self.spawnflags & 3 == 2) // ALIGN_BOTTOM + { + tracebox(self.origin, self.mins, self.maxs, self.origin - '0 0 1024', MOVE_NOMONSTERS, self); + setorigin(self, trace_endpos); + } + else if(self.spawnflags & 3 == 3) // ALIGN_ORIGIN | ALIGN_BOTTOM + { + traceline(self.origin, self.origin - '0 0 1024', MOVE_NOMONSTERS, self); + setorigin(self, trace_endpos - '0 0 1' * self.mins_z); + } +} + .float modelscale; void spawnfunc_misc_gamemodel (void) { @@ -955,6 +974,8 @@ void spawnfunc_misc_gamemodel (void) self.scale = self.modelscale; SetBrushEntityModel(); self.use = func_wall_use; + + InitializeEntity(self, gamemodel_drop, INITPRIO_DROPTOFLOOR); } float target_item_func_set(float a, float b) diff --git a/data/scripts/entities.def b/data/scripts/entities.def index 18fe4c8ad..ec812a6dd 100644 --- a/data/scripts/entities.def +++ b/data/scripts/entities.def @@ -552,7 +552,7 @@ EXTRUDE_NORMALS: for converting triangles to clip brushes, extrude along the mod EXTRUDE_TERRAIN: always extrude downwards (for terrain) */ -/*QUAKED misc_gamemodel (0 .5 .8) (-8 -8 -8) (8 8 8) +/*QUAKED misc_gamemodel (0 .5 .8) (-8 -8 -8) (8 8 8) ALIGN_ORIGIN ALIGN_BOTTOM A way to load models from a map by the engine (e.g. self-animated zym models). Is non-solid by default. The keys below actually apply to most engine-loaded model entities as they are engine features; however, they are described here as they aren't overridden by game code in misc_models. Its q3map2 keys below will work on any brush entity! @@ -579,6 +579,9 @@ _frame: frame of model to include (set equal to frame if _castshadows is set) _castshadows: Allows per-entity control over shadow casting. Defaults to 0 on entities, 1 on world. 0 = no shadow casting. 1 = cast shadows on world. > 1 = cast shadows on entities with _rs (or _receiveshadows) with the corresponding value, AND world. Negative values imply same, but DO NOT cast shadows on world. targetname: if targeted by a misc_model, its brushes get inserted into this _celshader: Sets the cel shader used for this geometry. Note: omit the "textures/" prefix. +-------- SPAWNFLAGS -------- +ALIGN_ORIGN: align the origin to the surface below the model +ALIGN_BOTTOM: align the bottom of the model to the surface below it */ /*QUAKED func_illusionary (0 .5 .8) ? -- 2.39.2