This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

382 lines
12 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef FUNC_TANK_H
#define FUNC_TANK_H
#ifdef _WIN32
#pragma once
#endif
#include "triggers.h"
#define SF_TANK_ACTIVE 0x0001
#define SF_TANK_PLAYER 0x0002
#define SF_TANK_HUMANS 0x0004
#define SF_TANK_ALIENS 0x0008
#define SF_TANK_LINEOFSIGHT 0x0010
#define SF_TANK_CANCONTROL 0x0020
#define SF_TANK_DAMAGE_KICK 0x0040 // Kick when take damage
#define SF_TANK_AIM_AT_POS 0x0080 // Aim at a particular position
#define SF_TANK_AIM_ASSISTANCE 0x0100
#define SF_TANK_NPC 0x0200
#define SF_TANK_NPC_CONTROLLABLE 0x0400 // 1024
#define SF_TANK_NPC_SET_CONTROLLER 0x0800 // 2048
#define SF_TANK_ALLOW_PLAYER_HITS \
0x1000 // 4096 Allow friendly NPCs to fire upon enemies near the
// player
#define SF_TANK_IGNORE_RANGE_IN_VIEWCONE \
0x2000 // 8192 Don't use range as a factor in determining if something is
// in view cone
#define SF_TANK_NOTSOLID 0x8000 // 32768
#define SF_TANK_SOUNDON \
0x10000 // FIXME: This is not really a spawnflag! It holds transient
// state!!!
#define SF_TANK_HACKPLAYERHIT \
0x20000 // 131072 Make this func_tank cheat and hit the player regularly
#define FUNCTANK_DISTANCE_MAX 1200 // 100 ft.
#define FUNCTANK_DISTANCE_MIN_TO_ENEMY 180
#define FUNCTANK_FIREVOLUME 1000
#define FUNCTANK_NPC_ROUTE_TIME 5.0f
// Effect handling
// If the func_tank has a chosen method of handling effects, use that
// instead of the individual effect settings. (muzzleflash, sound, tracer, etc)
enum FUNCTANK_EFFECT_HANDLING {
EH_NONE, // Use the effect settings
EH_AR2, // Use AR2 effects
EH_COMBINE_CANNON // Large Combine cannon
};
enum TANKBULLET {
TANK_BULLET_NONE = 0,
TANK_BULLET_SMALL = 1,
TANK_BULLET_MEDIUM = 2,
TANK_BULLET_LARGE = 3,
};
#define MORTAR_BLAST_RADIUS 350
// Custom damage
// env_laser (duration is 0.5 rate of fire)
// rockets
// explosion?
class CFuncTank : public CBaseEntity {
DECLARE_CLASS(CFuncTank, CBaseEntity);
public:
CFuncTank();
~CFuncTank();
void Spawn(void);
void Activate(void);
void Precache(void);
bool CreateVPhysics(void);
bool KeyValue(const char *szKeyName, const char *szValue);
void UpdateOnRemove();
void SetYawRate(float flYawRate) { m_yawRate = flYawRate; }
void SetPitchRate(float flPitchRate) { m_pitchRate = flPitchRate; }
int ObjectCaps(void) {
return (BaseClass::ObjectCaps() | FCAP_IMPULSE_USE |
FCAP_USE_IN_RADIUS);
}
void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType,
float value);
virtual void FuncTankPreThink() { return; }
void Think(void);
virtual void FuncTankPostThink() { return; }
int GetAmmoCount(void) { return m_iAmmoCount; }
// NPC
bool NPC_FindManPoint(Vector &vecPos);
bool NPC_HasEnemy(void);
void NPC_Fire(void);
void NPC_InterruptRoute(void);
void NPC_JustSawPlayer(CBaseEntity *pTarget);
void NPC_SetInRoute(bool bInRoute) { m_bNPCInRoute = bInRoute; }
void NPC_SetIdleAngle(Vector vecIdle) { m_vecNPCIdleTarget = vecIdle; }
// LOS
bool IsEntityInViewCone(CBaseEntity *pEntity);
bool HasLOSTo(CBaseEntity *pEntity);
// Controller
CBaseCombatCharacter *GetController(void);
bool StartControl(CBaseCombatCharacter *pController);
void StopControl(void);
Vector GetTargetPosition() { return m_vTargetPosition; }
void SetTargetPosition(const Vector &vecPos) { m_vTargetPosition = vecPos; }
const float YawCenter() const { return m_yawCenter; }
const float YawCenterWorld() const { return m_yawCenterWorld; }
const float YawRange() const { return m_yawRange; }
const float PitchCenter() const { return m_pitchCenter; }
const float PitchCenterWorld() const { return m_pitchCenterWorld; }
const float PitchRange() const { return m_pitchRange; }
virtual void PhysicsSimulate(void);
virtual void OnStartControlled() {}
virtual void OnStopControlled() {}
// SF Tests.
inline bool IsControllable(void) {
return (m_spawnflags & SF_TANK_CANCONTROL) ? true : false;
}
inline bool IsActive(void) {
return (m_spawnflags & SF_TANK_ACTIVE) ? true : false;
}
inline bool IsNPCControllable(void) {
return (m_spawnflags & SF_TANK_NPC_CONTROLLABLE) ? true : false;
}
inline bool IsNPCSetController(void) {
return (m_spawnflags & SF_TANK_NPC_SET_CONTROLLER) ? true : false;
}
virtual void DoMuzzleFlash(void);
virtual const char *GetTracerType(void);
protected:
virtual float GetShotSpeed() { return 0; }
virtual Vector WorldBarrelPosition(void);
void UpdateMatrix(void);
float GetNextAttack() const { return m_flNextAttack; }
virtual void SetNextAttack(float flWait) { m_flNextAttack = flWait; }
virtual void Fire(int bulletCount, const Vector &barrelEnd,
const Vector &forward, CBaseEntity *pAttacker,
bool bIgnoreSpread);
void TankTrace(const Vector &vecStart, const Vector &vecForward,
const Vector &vecSpread, trace_t &tr);
int GetRandomBurst(void);
float GetRandomFireTime(void);
void CalcPlayerCrosshairTarget(Vector *pVecTarget);
void CalcNPCEnemyTarget(Vector *pVecTarget);
inline bool IsPlayerManned(void) {
return m_hController && m_hController->IsPlayer() &&
(m_spawnflags & SF_TANK_PLAYER);
}
inline bool IsNPCManned(void) {
return m_hController && m_hController->MyNPCPointer() &&
(m_spawnflags & SF_TANK_NPC);
}
private:
void TrackTarget(void);
int DrawDebugTextOverlays(void);
void DrawDebugGeometryOverlays(void);
virtual void FiringSequence(const Vector &barrelEnd, const Vector &forward,
CBaseEntity *pAttacker);
void StartRotSound(void);
void StopRotSound(void);
// Input handlers.
void InputActivate(inputdata_t &inputdata);
void InputDeactivate(inputdata_t &inputdata);
void InputSetFireRate(inputdata_t &inputdata);
void InputSetDamage(inputdata_t &inputdata);
void InputSetTargetDir(inputdata_t &inputdata);
void InputSetTargetPosition(inputdata_t &inputdata);
void InputSetTargetEntityName(inputdata_t &inputdata);
protected:
virtual void InputSetTargetEntity(inputdata_t &inputdata);
virtual void InputClearTargetEntity(inputdata_t &inputdata);
private:
void InputFindNPCToManTank(inputdata_t &inputdata);
void InputStopFindingNPCs(inputdata_t &inputdata);
void InputStartFindingNPCs(inputdata_t &inputdata);
void InputForceNPCOff(inputdata_t &inputdata);
void InputSetMaxRange(inputdata_t &inputdata);
inline bool CanFire(void);
bool InRange(float range);
bool InRange2(float flRange2);
void TraceAttack(CBaseEntity *pAttacker, float flDamage,
const Vector &vecDir, trace_t *ptr, int bitsDamageType);
QAngle AimBarrelAt(const Vector &parentTarget);
DECLARE_DATADESC();
bool OnControls(CBaseEntity *pTest);
bool HasController(void);
CBaseEntity *FindTarget(string_t targetName, CBaseEntity *pActivator);
// NPC
void NPC_FindController(void);
bool NPC_InRoute(void) { return m_bNPCInRoute; }
bool NPC_InterruptController(void);
// Aim the tank at the player crosshair
void AimBarrelAtPlayerCrosshair(QAngle *pAngles);
// Aim the tank at the NPC's enemy
void AimBarrelAtNPCEnemy(QAngle *pAngles);
// Aim the tank at the func_tank's enemy
void AimFuncTankAtTarget(void);
// Returns true if the desired angles are out of range
bool RotateTankToAngles(const QAngle &angles, float *pDistX = NULL,
float *pDistY = NULL);
// We lost our target!
void LostTarget(void);
// Purpose:
void ComputeLeadingPosition(const Vector &vecShootPosition,
CBaseEntity *pTarget, Vector *pLeadPosition);
protected:
virtual void ControllerPostFrame(void);
virtual void TankActivate(void);
virtual void TankDeactivate(void);
float m_fireLast; // Last time I fired
float m_fireRate; // How many rounds/second
EHANDLE m_hTarget;
TANKBULLET m_bulletType; // Bullet type
int m_iBulletDamage; // 0 means use Bullet type's default damage
int m_iBulletDamageVsPlayer; // Damage vs player. 0 means use
// m_iBulletDamage
#ifdef HL2_EPISODIC
string_t m_iszAmmoType; // The name of the ammodef that we use when we
// fire. Bullet damage still comes from keyvalues.
int m_iAmmoType; // The cached index of the ammodef that we use when we
// fire.
#else
int m_iSmallAmmoType;
int m_iMediumAmmoType;
int m_iLargeAmmoType;
#endif // HL2_EPISODIC
int m_spread; // firing spread
EntityMatrix m_parentMatrix;
Vector m_sightOrigin; // Last sight of target
EHANDLE m_hFuncTankTarget;
int m_nBulletCount;
private:
// This is either the player manning the func_tank, or an NPC. The NPC is
// either manning the tank, or running to the man point. If he's en-route,
// m_bNPCInRoute will be true.
CHandle<CBaseCombatCharacter> m_hController;
float m_flNextAttack;
Vector m_vecControllerUsePos;
float m_yawCenter; // "Center" yaw
float m_yawCenterWorld; // "Center" yaw in world space
float m_yawRate; // Max turn rate to track targets
float m_yawRange; // Range of turning motion (one-sided: 30 is +/- 30
// degress from center) Zero is full rotation
float m_yawTolerance; // Tolerance angle
float m_pitchCenter; // "Center" pitch
float m_pitchCenterWorld; // "Center" pitch in world space
float m_pitchRate; // Max turn rate on pitch
float m_pitchRange; // Range of pitch motion as above
float m_pitchTolerance; // Tolerance angle
float m_fireTime; // How much time has been used to fire the weapon so far.
float m_lastSightTime; // Last time I saw target
float m_persist; // Persistence of firing (how long do I shoot when I can't
// see)
float m_persist2; // Secondary persistence of firing (randomly shooting
// when I can't see)
float m_persist2burst; // How long secondary persistence burst lasts
float m_minRange; // Minimum range to aim/track
float m_maxRange; // Max range to aim/track
float m_flMinRange2;
float m_flMaxRange2;
int m_iAmmoCount; // ammo
Vector m_barrelPos; // Length of the freakin barrel
float m_spriteScale; // Scale of any sprites we shoot
string_t m_iszSpriteSmoke;
string_t m_iszSpriteFlash;
string_t m_iszMaster; // Master entity (game_team_master or multisource)
string_t m_soundStartRotate;
string_t m_soundStopRotate;
string_t m_soundLoopRotate;
float m_flPlayerGracePeriod;
float m_flIgnoreGraceUpto;
float m_flPlayerLockTimeBeforeFire;
float m_flLastSawNonPlayer;
string_t m_targetEntityName;
Vector m_vTargetPosition;
Vector m_vecNPCIdleTarget;
// Used for when the gun is attached to another entity
string_t m_iszBarrelAttachment;
int m_nBarrelAttachment;
string_t m_iszBaseAttachment;
// Used when the gun is actually a part of the parent entity, and pose
// params aim it
string_t m_iszYawPoseParam;
string_t m_iszPitchPoseParam;
float m_flYawPoseCenter;
float m_flPitchPoseCenter;
bool m_bUsePoseParameters;
// Lead the target?
bool m_bPerformLeading;
float m_flStartLeadFactor;
float m_flStartLeadFactorTime;
float m_flNextLeadFactor;
float m_flNextLeadFactorTime;
COutputEvent m_OnFire;
COutputEvent m_OnLoseTarget;
COutputEvent m_OnAquireTarget;
COutputEvent m_OnAmmoDepleted;
COutputEvent m_OnGotController;
COutputEvent m_OnLostController;
COutputEvent m_OnGotPlayerController;
COutputEvent m_OnLostPlayerController;
COutputEvent m_OnReadyToFire;
CHandle<CBaseTrigger> m_hControlVolume;
string_t m_iszControlVolume;
float m_flNextControllerSearch;
bool m_bShouldFindNPCs;
bool m_bNPCInRoute;
string_t m_iszNPCManPoint;
bool m_bReadyToFire;
int m_iEffectHandling;
};
#endif // FUNC_TANK_H