func_vehicle: It was 20 years ago today, this entity came out to play. It got everyone to smile, at least for a little while. Happy birthday Counter-Strike 7.0, introducing: func_vehicle!
This commit is contained in:
parent
641f68c6be
commit
f9241d86ea
4 changed files with 680 additions and 0 deletions
|
@ -11,6 +11,7 @@ server/basetrigger.cpp
|
|||
server/basemonster.cpp
|
||||
server/basenpc.cpp
|
||||
server/basephysics.cpp
|
||||
server/basevehicle.cpp
|
||||
server/button_target.cpp
|
||||
server/ambient_generic.cpp
|
||||
server/cycler.cpp
|
||||
|
@ -44,6 +45,8 @@ server/func_wall_toggle.cpp
|
|||
server/func_conveyor.cpp
|
||||
server/func_rotating.cpp
|
||||
server/func_pendulum.cpp
|
||||
server/func_vehicle.cpp
|
||||
server/func_vehiclecontrols.cpp
|
||||
server/light.cpp
|
||||
server/stubs.cpp
|
||||
server/infodecal.cpp
|
||||
|
|
72
src/gs-entbase/server/basevehicle.cpp
Normal file
72
src/gs-entbase/server/basevehicle.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
class CBaseVehicle:CBaseEntity
|
||||
{
|
||||
entity m_eDriver;
|
||||
|
||||
void(void) CBaseVehicle;
|
||||
vector m_vecPlayerPos;
|
||||
|
||||
virtual void(void) PlayerAlign;
|
||||
virtual void(base_player) PlayerEnter;
|
||||
virtual void(base_player) PlayerLeave;
|
||||
};
|
||||
|
||||
void
|
||||
CBaseVehicle::PlayerAlign(void)
|
||||
{
|
||||
vector vecPlayerPos;
|
||||
|
||||
if (!m_eDriver)
|
||||
return;
|
||||
|
||||
makevectors(angles);
|
||||
vecPlayerPos = origin + v_forward * m_vecPlayerPos[0];
|
||||
vecPlayerPos += v_right * m_vecPlayerPos[1];
|
||||
vecPlayerPos += v_up * m_vecPlayerPos[2];
|
||||
|
||||
setorigin(m_eDriver, vecPlayerPos);
|
||||
}
|
||||
|
||||
void
|
||||
CBaseVehicle::PlayerEnter(base_player pl)
|
||||
{
|
||||
vector offs;
|
||||
|
||||
/* cache the position */
|
||||
offs = pl.origin - origin;
|
||||
|
||||
makevectors(angles);
|
||||
m_vecPlayerPos[0] = dotproduct(offs, v_forward);
|
||||
m_vecPlayerPos[1] = dotproduct(offs, v_right);
|
||||
m_vecPlayerPos[2] = dotproduct(offs, v_up);
|
||||
pl.movetype = MOVETYPE_NOCLIP;
|
||||
m_eDriver = (entity)pl;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseVehicle::PlayerLeave(base_player pl)
|
||||
{
|
||||
pl.movetype = MOVETYPE_WALK;
|
||||
m_eDriver = __NULL__;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseVehicle::CBaseVehicle(void)
|
||||
{
|
||||
CBaseEntity::CBaseEntity();
|
||||
}
|
566
src/gs-entbase/server/func_vehicle.cpp
Normal file
566
src/gs-entbase/server/func_vehicle.cpp
Normal file
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*QUAKED func_vehicle (0 .5 .8) ?
|
||||
"targetname" Name
|
||||
"target" Name of the first path_track/corner (See Notes)
|
||||
"acceleration" Acceleration multiplier
|
||||
"speed" Top-speed of the vehicle in q-units per second
|
||||
"height" Wheel-height in units
|
||||
"width" Width of the vehicle, used to calculate the wheels
|
||||
"length" Length of the vehicle, used to calculate the wheels
|
||||
"bouncefactor" Multiplier for the bouncyness of the vehicle
|
||||
"skidspeed" At which speed the vehicle starts skidding
|
||||
"traction" Multiplier for the traction affecting the vehicle
|
||||
"breakfactor" Multiplier for the breaking mechanics
|
||||
"steerfactor" Multiplier for the steering speed
|
||||
"straightenfactor" Multiplier for affecting the straightening mechanism
|
||||
"gravitydir" Normalized vector setting the direction of gravity
|
||||
|
||||
Unimplemented:
|
||||
"sounds" A sound-set to use
|
||||
"volume" Volume at which said sounds play at (from 0-10)
|
||||
"dmg" Damage inflicted upon entities when blocked
|
||||
|
||||
Primitive brush-based vehicle entity.
|
||||
|
||||
The vehicle's position is set via the 'target' key, which sets the first
|
||||
path_track/corner. The vehicle is then teleported to the 'target' but
|
||||
it stays at the same vertical position as originally placed.
|
||||
|
||||
The angle is calculated by aiming the 'target' path_track/corner entity
|
||||
to its own 'target' entity. So yes, you need two of these path_track/corner
|
||||
entities.
|
||||
*/
|
||||
|
||||
enumflags
|
||||
{
|
||||
FUNCVEH_NOPITCH,
|
||||
FUNCVEH_NOUSER,
|
||||
FUNCVEH_UNUSED,
|
||||
FUNCVEH_PASSABLE,
|
||||
FUNCVEH_FWDRIVE,
|
||||
FUNCVEH_RWDRIVE
|
||||
};
|
||||
|
||||
class func_vehicle_wheel
|
||||
{
|
||||
void() func_vehicle_wheel;
|
||||
|
||||
virtual void(void) Move;
|
||||
virtual void(vector) Bounce;
|
||||
virtual void(float, float m_flTurn) Accel;
|
||||
virtual void(float) Physics;
|
||||
};
|
||||
|
||||
class func_vehicle:CBaseVehicle
|
||||
{
|
||||
/* map-entity fields */
|
||||
float m_flBounceFactor;
|
||||
float m_flAcceleration;
|
||||
float m_flSkidSpeed;
|
||||
float m_flTraction;
|
||||
float m_flBreakFactor;
|
||||
float m_flSteerFactor;
|
||||
float m_flStraightenFactor;
|
||||
vector m_vecGravityDir;
|
||||
|
||||
func_vehicle_wheel m_wlFL;
|
||||
func_vehicle_wheel m_wlFR;
|
||||
func_vehicle_wheel m_wlBL;
|
||||
func_vehicle_wheel m_wlBR;
|
||||
vector m_vecControlMins;
|
||||
vector m_vecControlMaxs;
|
||||
float m_flHeight;
|
||||
float m_flWidth;
|
||||
float m_flLength;
|
||||
float m_flTurn;
|
||||
|
||||
void(void) func_vehicle;
|
||||
virtual void(void) customphysics;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Realign;
|
||||
virtual void(void) PlayerUse;
|
||||
};
|
||||
|
||||
void
|
||||
func_vehicle_wheel::Bounce(vector normal)
|
||||
{
|
||||
func_vehicle vehParent;
|
||||
vehParent = (func_vehicle)owner;
|
||||
velocity -= (velocity * normal) * normal * vehParent.m_flBounceFactor;
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle_wheel::Move(void)
|
||||
{
|
||||
vector vecDest;
|
||||
vector vecSavedNormal;
|
||||
float flStepped;
|
||||
float flMovetime;
|
||||
int i;
|
||||
|
||||
/* have a few attempts */
|
||||
for (i = 3, flMovetime = frametime; flMovetime > 0 && i; i--) {
|
||||
vecDest = origin + (velocity * flMovetime);
|
||||
tracebox(origin, mins, maxs, vecDest, MOVE_NOMONSTERS, this);
|
||||
|
||||
if (trace_startsolid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
origin = trace_endpos;
|
||||
|
||||
if (trace_fraction < 1) {
|
||||
vecSavedNormal = trace_plane_normal;
|
||||
flMovetime -= flMovetime * trace_fraction;
|
||||
|
||||
if (flMovetime) {
|
||||
float roof_fraction;
|
||||
vector roof_plane_normal;
|
||||
|
||||
/* step up if we can */
|
||||
trace_endpos = origin;
|
||||
trace_endpos[2] += 4;
|
||||
|
||||
tracebox(origin, mins, maxs, trace_endpos, MOVE_NOMONSTERS, this);
|
||||
flStepped = trace_endpos[2] - origin[2];
|
||||
|
||||
roof_fraction = trace_fraction;
|
||||
roof_plane_normal = trace_plane_normal;
|
||||
|
||||
vecDest = trace_endpos + velocity * flMovetime;
|
||||
|
||||
/* only horizontally */
|
||||
vecDest[2] = trace_endpos[2];
|
||||
|
||||
/* move forwards */
|
||||
tracebox(trace_endpos, mins, maxs, vecDest, MOVE_NOMONSTERS, this);
|
||||
|
||||
/* if we got anywhere, make this raised-step move count */
|
||||
if (trace_fraction != 0) {
|
||||
float fwfrac;
|
||||
vector fwplane;
|
||||
|
||||
fwfrac = trace_fraction;
|
||||
fwplane = trace_plane_normal;
|
||||
|
||||
/* move down */
|
||||
vecDest = trace_endpos;
|
||||
vecDest[2] -= flStepped + 1;
|
||||
tracebox(trace_endpos, mins, maxs, vecDest, MOVE_NOMONSTERS, this);
|
||||
|
||||
if (trace_fraction < 1 && trace_plane_normal[2] > 0.7f) {
|
||||
flMovetime -= flMovetime * fwfrac;
|
||||
|
||||
if (roof_fraction < 1) {
|
||||
Bounce(roof_plane_normal);
|
||||
}
|
||||
|
||||
/* FIXME: do we need velocity < 0? */
|
||||
if (trace_fraction < 1 && self.velocity[2] < 0) {
|
||||
Bounce(trace_plane_normal);
|
||||
} else if (fwfrac < 1) {
|
||||
Bounce(fwplane);
|
||||
}
|
||||
|
||||
origin = trace_endpos;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* stepping failed, assume crash? */
|
||||
if (trace_ent == world) {
|
||||
if (vlen(velocity) > 300) {
|
||||
float impact;
|
||||
impact = -dotproduct(trace_plane_normal, velocity);
|
||||
int iImpactDamage = impact / 100;
|
||||
}
|
||||
}
|
||||
|
||||
Bounce(vecSavedNormal);
|
||||
/* Physics_DoTouch(this, trace_ent); */
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle_wheel::Accel(float flMoveTime, float m_flTurn)
|
||||
{
|
||||
func_vehicle vehParent;
|
||||
entity eDriver;
|
||||
float flTraction;
|
||||
vector vecAngle;
|
||||
|
||||
vehParent = (func_vehicle)owner;
|
||||
eDriver = vehParent.m_eDriver;
|
||||
vecAngle = vehParent.angles;
|
||||
|
||||
makevectors(vecAngle);
|
||||
|
||||
if (m_flTurn) {
|
||||
/* rotates v_forward */
|
||||
rotatevectorsbyangle([ 0, m_flTurn * 50, 0]);
|
||||
}
|
||||
|
||||
tracebox(origin, mins, maxs, origin - v_up, MOVE_NOMONSTERS, owner);
|
||||
|
||||
/* allow a range, for 1qu's worth of spare tyre pressure. or something */
|
||||
flTraction = 1 - trace_fraction;
|
||||
|
||||
/* air friction, doubles up for general rolling friction, ish */
|
||||
velocity *= 1 - flMoveTime * 0.1;
|
||||
|
||||
if (flTraction) {
|
||||
if (eDriver) {
|
||||
velocity -= v_forward * bound(-1, vehParent.m_eDriver.movement[0] / 400, 1) * vehParent.m_flAcceleration * flMoveTime * flTraction;
|
||||
}
|
||||
|
||||
/* nuke sideways velocity. if a wheel is off the ground this probably
|
||||
means that it'll be pushed further. players should try not to roll
|
||||
too much. */
|
||||
/* FIXME: push opposite wheel up slightly to model chassis momentum
|
||||
not slowing as much as the wheel itself (zomg: race conditions!) */
|
||||
velocity -= (velocity * v_right) * v_right * vehParent.m_flTraction * flMoveTime * flTraction;
|
||||
|
||||
if (eDriver.button2 || eDriver.movement[2] > 0) {
|
||||
vector t;
|
||||
|
||||
/* empty cars are assumed to have their brakes on.
|
||||
nuke forward velocity. if a wheel is off the ground this probably
|
||||
means that it'll be pushed further. players should try not to
|
||||
roll too much.
|
||||
|
||||
Note: really we ought to be applying some axel friction even
|
||||
when not breaking, but we'll just depend on air friction for
|
||||
that. */
|
||||
velocity -= (velocity * v_forward) * v_forward * vehParent.m_flBreakFactor * flMoveTime * flTraction;
|
||||
|
||||
/* if break is on, nuke the final part of the velocity, so we can
|
||||
become truely motionless.*/
|
||||
t = velocity - velocity * dotproduct(velocity, vehParent.m_vecGravityDir);
|
||||
if (vlen(t) < 15) {
|
||||
velocity -= t;
|
||||
}
|
||||
|
||||
/* don't bother with gravity if we're already on the ground and
|
||||
breaking. this avoids weird slides. */
|
||||
if (!trace_fraction && trace_plane_normal * vehParent.m_vecGravityDir < -0.7f) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* apply gravity */
|
||||
velocity += vehParent.m_vecGravityDir * flMoveTime * serverkeyfloat("phy_gravity") * trace_fraction;
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle_wheel::Physics(float turnrate)
|
||||
{
|
||||
vector owner_pos;
|
||||
|
||||
/* try to correct the wheel's position, in case it got stuck */
|
||||
owner_pos = owner.origin + (owner.mins + owner.maxs) * 0.5f;
|
||||
tracebox(owner_pos, mins, maxs, origin, MOVE_NOMONSTERS, owner);
|
||||
setorigin(this, trace_endpos);
|
||||
|
||||
Accel(frametime * 0.5f, turnrate);
|
||||
Move();
|
||||
Accel(frametime * 0.5f, turnrate);
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle_wheel::func_vehicle_wheel(void)
|
||||
{
|
||||
hitcontentsmaski = CONTENTBIT_SOLID | CONTENTBIT_BODY;
|
||||
mins = '-8 -8 -8';
|
||||
maxs = '8 8 8';
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle::customphysics(void)
|
||||
{
|
||||
/* eject the dead */
|
||||
if (m_eDriver && m_eDriver.health <= 0) {
|
||||
PlayerLeave((base_player)m_eDriver);
|
||||
}
|
||||
|
||||
if (m_eDriver) {
|
||||
float y;
|
||||
|
||||
y = m_eDriver.movement[1];
|
||||
y = bound(-200, y, 200) / 200;
|
||||
y *= m_flSteerFactor;
|
||||
|
||||
if (y) {
|
||||
if (y < 0 && m_flTurn < 0) {
|
||||
m_flTurn = 0.0f;
|
||||
} else if (y > 0 && m_flTurn > 0) {
|
||||
m_flTurn = 0.0f;
|
||||
} else {
|
||||
m_flTurn = bound(-1, m_flTurn - y * frametime, 1);
|
||||
}
|
||||
} else {
|
||||
/* straighten wheels forward over time */
|
||||
if (m_flTurn < 0) {
|
||||
m_flTurn = min(0, m_flTurn + frametime * m_flStraightenFactor);
|
||||
} else if (m_flTurn > 0) {
|
||||
m_flTurn = max(0, m_flTurn - frametime * m_flStraightenFactor);
|
||||
}
|
||||
}
|
||||
m_eDriver.flags |= FL_FROZEN;
|
||||
}
|
||||
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
makevectors(angles);
|
||||
|
||||
setorigin(m_wlFR, origin + v_right * m_flWidth + v_forward * m_flLength);
|
||||
setorigin(m_wlFL, origin - v_right * m_flWidth + v_forward * m_flLength);
|
||||
setorigin(m_wlBR, origin + v_right * m_flWidth - v_forward * m_flLength);
|
||||
setorigin(m_wlBL, origin - v_right * m_flWidth - v_forward * m_flLength);
|
||||
|
||||
if (spawnflags & FUNCVEH_FWDRIVE) {
|
||||
m_wlFL.Physics(0);
|
||||
m_wlFR.Physics(0);
|
||||
m_wlBL.Physics(m_flTurn);
|
||||
m_wlBR.Physics(m_flTurn);
|
||||
} else if (spawnflags & FUNCVEH_RWDRIVE) {
|
||||
m_wlFL.Physics(-m_flTurn);
|
||||
m_wlFR.Physics(-m_flTurn);
|
||||
m_wlBL.Physics(0);
|
||||
m_wlBR.Physics(0);
|
||||
} else {
|
||||
m_wlFL.Physics(-m_flTurn);
|
||||
m_wlFR.Physics(-m_flTurn);
|
||||
m_wlBL.Physics(m_flTurn);
|
||||
m_wlBR.Physics(m_flTurn);
|
||||
}
|
||||
|
||||
velocity = m_wlFL.velocity;
|
||||
velocity += m_wlFR.velocity;
|
||||
velocity += m_wlBL.velocity;
|
||||
velocity += m_wlBR.velocity;
|
||||
velocity *= 0.25f;
|
||||
|
||||
v_right = (m_wlFR.origin - m_wlFL.origin);
|
||||
v_right += (m_wlBR.origin - m_wlBL.origin);
|
||||
v_forward = (m_wlFL.origin + m_wlFR.origin);
|
||||
v_forward -= (m_wlBL.origin + m_wlBR.origin);
|
||||
v_up = -crossproduct(v_forward, v_right);
|
||||
angles = vectoangles(v_forward, v_up);
|
||||
|
||||
/* figure out the new chassis position */
|
||||
vector new_origin;
|
||||
new_origin = m_wlFL.origin;
|
||||
new_origin += m_wlFR.origin;
|
||||
new_origin += m_wlBL.origin;
|
||||
new_origin += m_wlBR.origin;
|
||||
new_origin *= 0.25f;
|
||||
setorigin(this, new_origin);
|
||||
PlayerAlign();
|
||||
|
||||
/* support for think/nextthink */
|
||||
if (think && nextthink > 0.0f) {
|
||||
if (nextthink < time) {
|
||||
nextthink = 0.0f;
|
||||
think();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle::PlayerUse(void)
|
||||
{
|
||||
vector matrix;
|
||||
vector offs;
|
||||
offs = eActivator.origin - origin;
|
||||
|
||||
makevectors(angles);
|
||||
matrix[0] = dotproduct(offs, v_forward);
|
||||
matrix[1] = -dotproduct(offs, v_right);
|
||||
matrix[2] = dotproduct(offs, v_up);
|
||||
|
||||
if not (matrix[0] >= m_vecControlMins[0] && matrix[0] <= m_vecControlMaxs[0])
|
||||
return;
|
||||
if not (matrix[1] >= m_vecControlMins[1] && matrix[1] <= m_vecControlMaxs[1])
|
||||
return;
|
||||
if not (matrix[2] >= m_vecControlMins[2] && matrix[2] <= m_vecControlMaxs[2])
|
||||
return;
|
||||
|
||||
if (m_eDriver == eActivator) {
|
||||
PlayerLeave((base_player)eActivator);
|
||||
} else if (!m_eDriver) {
|
||||
PlayerEnter((base_player)eActivator);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle::Realign(void)
|
||||
{
|
||||
entity t;
|
||||
entity f;
|
||||
CBaseEntity first, second;
|
||||
string strFirst, strSecond;
|
||||
|
||||
first = second = t = f = __NULL__;
|
||||
|
||||
for (f = world; (f = find(f, CBaseEntity::m_strTarget, m_strTargetName));) {
|
||||
/* we found the right entity */
|
||||
if (f.classname == "func_vehiclecontrols") {
|
||||
t = f;
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
vector offs;
|
||||
offs = t.origin - origin;
|
||||
m_vecControlMins = t.mins + offs;
|
||||
m_vecControlMaxs = t.maxs + offs;
|
||||
}
|
||||
|
||||
/* we rotate and position ourselves after the first path_track/corner */
|
||||
strFirst = m_strTarget;
|
||||
for (f = world; (f = find(f, CBaseEntity::m_strTargetName, strFirst));) {
|
||||
/* we found the right entity */
|
||||
if (f.classname == "path_track" || f.classname == "path_corner") {
|
||||
first = (CBaseEntity)f;
|
||||
}
|
||||
}
|
||||
|
||||
/* now get the second one... */
|
||||
strSecond = first.m_strTarget;
|
||||
for (f = world; (f = find(f, CBaseEntity::m_strTargetName, strSecond));) {
|
||||
/* we found the right entity */
|
||||
if (f.classname == "path_track" || f.classname == "path_corner") {
|
||||
second = (CBaseEntity)f;
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
vector end_pos;
|
||||
first = (CBaseEntity)first;
|
||||
second = (CBaseEntity)second;
|
||||
angles = vectoangles(first.origin - second.origin);
|
||||
|
||||
end_pos = first.origin;
|
||||
end_pos[2] = m_oldOrigin[2];
|
||||
setorigin(this, end_pos);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle::Respawn(void)
|
||||
{
|
||||
movetype = MOVETYPE_PUSH;
|
||||
solid = SOLID_BSP;
|
||||
SetModel(m_oldModel);
|
||||
SetOrigin(m_oldOrigin);
|
||||
owner = m_eDriver = __NULL__;
|
||||
think = Realign;
|
||||
nextthink = time + 0.1f;
|
||||
|
||||
m_wlFL.velocity =
|
||||
m_wlFR.velocity =
|
||||
m_wlBL.velocity =
|
||||
m_wlBR.velocity =
|
||||
velocity = [0,0,0];
|
||||
}
|
||||
|
||||
void
|
||||
func_vehicle::func_vehicle(void)
|
||||
{
|
||||
m_flBounceFactor = 1.0f;
|
||||
m_flAcceleration = 200.0f;
|
||||
m_flSkidSpeed = 256.0f;
|
||||
m_flTraction = 1.0f;
|
||||
m_flBreakFactor = 2.0f;
|
||||
m_flSteerFactor = 1.0f;
|
||||
m_flStraightenFactor = 1.0f;
|
||||
m_vecGravityDir = [0,0,-1];
|
||||
|
||||
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
|
||||
switch (argv(i)) {
|
||||
case "acceleration":
|
||||
// TODO
|
||||
break;
|
||||
case "speed":
|
||||
m_flAcceleration = stof(argv(i+1));
|
||||
break;
|
||||
case "height":
|
||||
m_flHeight = stof(argv(i+1));
|
||||
break;
|
||||
case "width":
|
||||
m_flWidth = stof(argv(i+1)) / 2;
|
||||
break;
|
||||
case "length":
|
||||
m_flLength = stof(argv(i+1)) / 2;
|
||||
break;
|
||||
case "bouncefactor":
|
||||
m_flBounceFactor = stof(argv(i+1));
|
||||
break;
|
||||
case "skidspeed":
|
||||
m_flSkidSpeed = stof(argv(i+1));
|
||||
break;
|
||||
case "traction":
|
||||
m_flTraction = stof(argv(i+1));
|
||||
break;
|
||||
case "breakfactor":
|
||||
m_flBreakFactor = stof(argv(i+1));
|
||||
break;
|
||||
case "steerfactor":
|
||||
m_flSteerFactor = stof(argv(i+1));
|
||||
break;
|
||||
case "straightenfactor":
|
||||
m_flStraightenFactor = stof(argv(i+1));
|
||||
break;
|
||||
case "gravitydir":
|
||||
m_vecGravityDir = stov(argv(i+1));
|
||||
break;
|
||||
case "sounds":
|
||||
// TODO
|
||||
break;
|
||||
case "volume":
|
||||
// TODO
|
||||
break;
|
||||
case "dmg":
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_wlFL = spawn(func_vehicle_wheel);
|
||||
m_wlFR = spawn(func_vehicle_wheel);
|
||||
m_wlBL = spawn(func_vehicle_wheel);
|
||||
m_wlBR = spawn(func_vehicle_wheel);
|
||||
m_wlFL.owner = m_wlFR.owner = m_wlBL.owner = m_wlBR.owner = this;
|
||||
|
||||
if (m_flHeight) {
|
||||
m_wlFL.mins[2] = m_flHeight * -1;
|
||||
m_wlFR.mins[2] = m_flHeight * -1;
|
||||
m_wlBL.mins[2] = m_flHeight * -1;
|
||||
m_wlBR.mins[2] = m_flHeight * -1;
|
||||
}
|
||||
|
||||
CBaseVehicle::CBaseVehicle();
|
||||
}
|
39
src/gs-entbase/server/func_vehiclecontrols.cpp
Normal file
39
src/gs-entbase/server/func_vehiclecontrols.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*QUAKED func_vehiclecontrols (0 .5 .8) ?
|
||||
"targetname" Name
|
||||
"target" Name of the func_vehicle to control
|
||||
|
||||
Brush that marks the usable region of a func_vehicle, in order
|
||||
to gain control.
|
||||
*/
|
||||
|
||||
class func_vehiclecontrols:CBaseTrigger
|
||||
{
|
||||
void(void) func_vehiclecontrols;
|
||||
};
|
||||
|
||||
void
|
||||
func_vehiclecontrols::func_vehiclecontrols(void)
|
||||
{
|
||||
precache_model(model);
|
||||
SetModel(model);
|
||||
SetOrigin(origin);
|
||||
SetRenderMode(RM_TRIGGER);
|
||||
SetSolid(SOLID_NOT);
|
||||
CBaseTrigger::CBaseTrigger();
|
||||
}
|
Loading…
Reference in a new issue