[HL25] Backport func_vehicle entity

This commit is contained in:
Joël Troch 2024-08-28 15:17:52 +02:00
parent e9986c06f6
commit 33b2b3acd4
9 changed files with 1271 additions and 14 deletions

View file

@ -110,6 +110,8 @@ typedef void (CBaseEntity::*USEPTR)(CBaseEntity* pActivator, CBaseEntity* pCalle
#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace
#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures.
#define CLASS_VEHICLE 14
class CBaseEntity;
class CBaseMonster;
class CBasePlayerItem;

View file

@ -996,6 +996,7 @@ void ClientPrecache()
PRECACHE_SOUND("debris/wood3.wav");
PRECACHE_SOUND("plats/train_use1.wav"); // use a train
PRECACHE_SOUND("plats/vehicle_ignition.wav");
PRECACHE_SOUND("buttons/spark5.wav"); // hit computer texture
PRECACHE_SOUND("buttons/spark6.wav");

View file

@ -27,6 +27,7 @@
#include "items.h"
#include "voice_gamemgr.h"
#include "hltv.h"
#include "trains.h"
#include "UserMessages.h"
#define ITEM_RESPAWN_TIME 30
@ -537,16 +538,26 @@ int CHalfLifeMultiplay::IPointsForKill(CBasePlayer* pAttacker, CBasePlayer* pKil
//=========================================================
void CHalfLifeMultiplay::PlayerKilled(CBasePlayer* pVictim, entvars_t* pKiller, entvars_t* pInflictor)
{
DeathNotice(pVictim, pKiller, pInflictor);
pVictim->m_iDeaths += 1;
FireTargets("game_playerdie", pVictim, pVictim, USE_TOGGLE, 0);
CBasePlayer* peKiller = NULL;
CBaseEntity* ktmp = CBaseEntity::Instance(pKiller);
if (ktmp && (ktmp->Classify() == CLASS_PLAYER))
peKiller = (CBasePlayer*)ktmp;
else if (ktmp && (ktmp->Classify() == CLASS_VEHICLE))
{
CBasePlayer* pDriver = ((CFuncVehicle*)ktmp)->m_pDriver;
if (pDriver != NULL)
{
peKiller = pDriver;
ktmp = pDriver;
pKiller = pDriver->pev;
}
}
DeathNotice(pVictim, pKiller, pInflictor);
pVictim->m_iDeaths += 1;
FireTargets("game_playerdie", pVictim, pVictim, USE_TOGGLE, 0);
if (pVictim->pev == pKiller)
{ // killed self

View file

@ -1438,6 +1438,9 @@ void CBasePlayer::PlayerUse()
{
m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = TRAIN_NEW | TRAIN_OFF;
CBaseEntity* pTrain = CBaseEntity::Instance(pev->groundentity);
if (pTrain && (pTrain->Classify() == CLASS_VEHICLE))
((CFuncVehicle*)pTrain)->m_pDriver = NULL;
return;
}
else
@ -1449,7 +1452,13 @@ void CBasePlayer::PlayerUse()
m_afPhysicsFlags |= PFLAG_ONTRAIN;
m_iTrain = TrainSpeed(pTrain->pev->speed, pTrain->pev->impulse);
m_iTrain |= TRAIN_NEW;
EMIT_SOUND(ENT(pev), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM);
if (pTrain->Classify() == CLASS_VEHICLE)
{
EMIT_SOUND(ENT(pev), CHAN_ITEM, "plats/vehicle_ignition.wav", 0.8, ATTN_NORM);
((CFuncVehicle*)pTrain)->m_pDriver = this;
}
else
EMIT_SOUND(ENT(pev), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM);
return;
}
}
@ -1569,6 +1578,15 @@ void CBasePlayer::Jump()
{
pev->velocity = pev->velocity + pev->basevelocity;
}
// JoshA: CS behaviour does this for tracktrain + train as well,
// but let's just do this for func_vehicle to avoid breaking existing content.
//
// If you're standing on a moving train... then add the velocity of the train to yours.
if (pevGround && (/*(!strcmp( "func_tracktrain", STRING(pevGround->classname))) ||
(!strcmp( "func_train", STRING(pevGround->classname))) ) ||*/
(!strcmp("func_vehicle", STRING(pevGround->classname)))))
pev->velocity = pev->velocity + pevGround->velocity;
}
@ -1873,12 +1891,15 @@ void CBasePlayer::PreThink()
//ALERT( at_error, "In train mode with no train!\n" );
m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = TRAIN_NEW | TRAIN_OFF;
if (pTrain->Classify() == CLASS_VEHICLE)
((CFuncVehicle*)pTrain)->m_pDriver = NULL;
return;
}
}
else if (!FBitSet(pev->flags, FL_ONGROUND) || FBitSet(pTrain->pev->spawnflags, SF_TRACKTRAIN_NOCONTROL) || (pev->button & (IN_MOVELEFT | IN_MOVERIGHT)) != 0)
else if (!FBitSet(pev->flags, FL_ONGROUND) || FBitSet(pTrain->pev->spawnflags, SF_TRACKTRAIN_NOCONTROL) || ((pev->button & (IN_MOVELEFT | IN_MOVERIGHT)) != 0 && pTrain->Classify() != CLASS_VEHICLE))
{
// Turn off the train if you jump, strafe, or the train controls go dead
// and it isn't a func_vehicle
m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = TRAIN_NEW | TRAIN_OFF;
return;
@ -1886,15 +1907,41 @@ void CBasePlayer::PreThink()
pev->velocity = g_vecZero;
vel = 0;
if ((m_afButtonPressed & IN_FORWARD) != 0)
if (pTrain->Classify() == CLASS_VEHICLE)
{
vel = 1;
pTrain->Use(this, this, USE_SET, (float)vel);
if (pev->button & IN_FORWARD)
{
vel = 1;
pTrain->Use(this, this, USE_SET, (float)vel);
}
if (pev->button & IN_BACK)
{
vel = -1;
pTrain->Use(this, this, USE_SET, (float)vel);
}
if (pev->button & IN_MOVELEFT)
{
vel = 20;
pTrain->Use(this, this, USE_SET, (float)vel);
}
if (pev->button & IN_MOVERIGHT)
{
vel = 30;
pTrain->Use(this, this, USE_SET, (float)vel);
}
}
else if ((m_afButtonPressed & IN_BACK) != 0)
else
{
vel = -1;
pTrain->Use(this, this, USE_SET, (float)vel);
if ((m_afButtonPressed & IN_FORWARD) != 0)
{
vel = 1;
pTrain->Use(this, this, USE_SET, (float)vel);
}
else if ((m_afButtonPressed & IN_BACK) != 0)
{
vel = -1;
pTrain->Use(this, this, USE_SET, (float)vel);
}
}
if (0 != vel)

View file

@ -123,3 +123,81 @@ public:
private:
unsigned short m_usAdjustPitch;
};
class CFuncVehicle : public CBaseEntity
{
public:
void Spawn(void);
void Precache(void);
void Blocked(CBaseEntity* pOther);
void Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value);
bool KeyValue(KeyValueData* pkvd);
void EXPORT Next(void);
void EXPORT Find(void);
void EXPORT NearestPath(void);
void EXPORT DeadEnd(void);
void NextThink(float thinkTime, bool alwaysThink);
int Classify(void);
void CollisionDetection(void);
void TerrainFollowing(void);
void CheckTurning(void);
void SetTrack(CPathTrack* track) { m_ppath = track->Nearest(pev->origin); }
void SetControls(entvars_t* pevControls);
bool OnControls(entvars_t* pev);
void StopSound(void);
void UpdateSound(void);
static CFuncVehicle* Instance(edict_t* pent);
bool Save(CSave& save);
bool Restore(CRestore& restore);
static TYPEDESCRIPTION m_SaveData[];
int ObjectCaps() { return (CBaseEntity ::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DIRECTIONAL_USE; }
void OverrideReset();
CPathTrack* m_ppath;
float m_length;
float m_width;
float m_height;
float m_speed;
float m_dir;
float m_startSpeed;
Vector m_controlMins;
Vector m_controlMaxs;
int m_soundPlaying;
int m_sounds;
int m_acceleration;
float m_flVolume;
float m_flBank;
float m_oldSpeed;
int m_iTurnAngle;
float m_flSteeringWheelDecay;
float m_flAcceleratorDecay;
float m_flTurnStartTime;
float m_flLaunchTime; // Time at which the vehicle has become airborne
float m_flLastNormalZ;
float m_flCanTurnNow;
float m_flUpdateSound;
Vector m_vFrontLeft;
Vector m_vFront;
Vector m_vFrontRight;
Vector m_vBackLeft;
Vector m_vBack;
Vector m_vBackRight;
Vector m_vSurfaceNormal;
Vector m_vVehicleDirection;
CBasePlayer* m_pDriver;
// GOOSEMAN
void Restart();
private:
unsigned short m_usAdjustPitch;
};

1113
dlls/vehicle.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -117,6 +117,7 @@ HLDLL_OBJS = \
$(HLDLL_OBJ_DIR)/turret.o \
$(HLDLL_OBJ_DIR)/UserMessages.o \
$(HLDLL_OBJ_DIR)/util.o \
$(HLDLL_OBJ_DIR)/vehicle.o \
$(HLDLL_OBJ_DIR)/weapons.o \
$(HLDLL_OBJ_DIR)/weapons_shared.o \
$(HLDLL_OBJ_DIR)/world.o \

View file

@ -207,6 +207,7 @@ cmd /c ""$(ProjectDir)..\..\filecopy.bat" "$(SolutionDir)../../network" "" "delt
<ClCompile Include="..\..\dlls\turret.cpp" />
<ClCompile Include="..\..\dlls\UserMessages.cpp" />
<ClCompile Include="..\..\dlls\util.cpp" />
<ClCompile Include="..\..\dlls\vehicle.cpp" />
<ClCompile Include="..\..\dlls\weapons.cpp" />
<ClCompile Include="..\..\dlls\weapons_shared.cpp" />
<ClCompile Include="..\..\dlls\world.cpp" />

View file

@ -327,6 +327,9 @@
<ClCompile Include="..\..\dlls\util.cpp">
<Filter>Source Files\dlls</Filter>
</ClCompile>
<ClCompile Include="..\..\dlls\vehicle.cpp">
<Filter>Source Files\dlls</Filter>
</ClCompile>
<ClCompile Include="..\..\game_shared\voice_gamemgr.cpp">
<Filter>Source Files\game_shared</Filter>
</ClCompile>