vehicles missing functions + fixes
This commit is contained in:
parent
e34631adce
commit
347f0a0e9c
@ -2078,14 +2078,12 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle)
|
|||||||
return;
|
return;
|
||||||
if (IsAnyOtherPedTouchingGarage(FindPlayerPed()))
|
if (IsAnyOtherPedTouchingGarage(FindPlayerPed()))
|
||||||
return;
|
return;
|
||||||
float posX = pVehicle->GetPosition().x;
|
CVector pos = pVehicle->GetPosition();
|
||||||
float posY = pVehicle->GetPosition().y;
|
|
||||||
float posZ = pVehicle->GetPosition().z;
|
|
||||||
float garageX = GetGarageCenterX();
|
float garageX = GetGarageCenterX();
|
||||||
float garageY = GetGarageCenterY();
|
float garageY = GetGarageCenterY();
|
||||||
float offsetX = garageX - posX;
|
float offsetX = garageX - pos.x;
|
||||||
float offsetY = garageY - posY;
|
float offsetY = garageY - pos.y;
|
||||||
float offsetZ = posZ - posZ;
|
float offsetZ = pos.z - pos.z;
|
||||||
float distance = CVector(offsetX, offsetY, offsetZ).Magnitude();
|
float distance = CVector(offsetX, offsetY, offsetZ).Magnitude();
|
||||||
if (distance < RESPRAY_CENTERING_COEFFICIENT) {
|
if (distance < RESPRAY_CENTERING_COEFFICIENT) {
|
||||||
pVehicle->GetPosition().x = GetGarageCenterX();
|
pVehicle->GetPosition().x = GetGarageCenterX();
|
||||||
@ -2096,7 +2094,7 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle)
|
|||||||
pVehicle->GetPosition().y += offsetY * RESPRAY_CENTERING_COEFFICIENT / distance;
|
pVehicle->GetPosition().y += offsetY * RESPRAY_CENTERING_COEFFICIENT / distance;
|
||||||
}
|
}
|
||||||
if (!IsEntityEntirelyInside3D(pVehicle, 0.1f))
|
if (!IsEntityEntirelyInside3D(pVehicle, 0.1f))
|
||||||
pVehicle->GetPosition() = CVector(posX, posY, posZ);
|
pVehicle->GetPosition() = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGarages::CloseHideOutGaragesBeforeSave()
|
void CGarages::CloseHideOutGaragesBeforeSave()
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
#include "Fire.h"
|
#include "Fire.h"
|
||||||
#include "PointLights.h"
|
#include "PointLights.h"
|
||||||
#include "Pools.h"
|
#include "Pools.h"
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
#include "Replay.h"
|
||||||
|
#endif
|
||||||
#include "Script.h"
|
#include "Script.h"
|
||||||
#include "Shadows.h"
|
#include "Shadows.h"
|
||||||
#include "SpecialFX.h"
|
#include "SpecialFX.h"
|
||||||
@ -642,32 +645,26 @@ CPickups::AddToCollectedPickupsArray(int32 index)
|
|||||||
void
|
void
|
||||||
CPickups::Update()
|
CPickups::Update()
|
||||||
{
|
{
|
||||||
#ifndef FIX_BUGS
|
#ifdef FIX_BUGS // RIP speedrunning (solution from SA)
|
||||||
// BUG: this code can only reach 318 out of 320 pickups
|
if (CReplay::IsPlayingBack())
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
#define PICKUPS_FRAME_SPAN (6)
|
#define PICKUPS_FRAME_SPAN (6)
|
||||||
#define PICKUPS_PER_FRAME (NUMGENERALPICKUPS/PICKUPS_FRAME_SPAN)
|
#ifdef FIX_BUGS
|
||||||
|
for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
|
||||||
for (uint32 i = PICKUPS_PER_FRAME * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < PICKUPS_PER_FRAME * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
|
#else // BUG: this code can only reach 318 out of 320 pickups
|
||||||
|
for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
|
||||||
|
#endif
|
||||||
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
||||||
AddToCollectedPickupsArray(i);
|
AddToCollectedPickupsArray(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#undef PICKUPS_FRAME_SPAN
|
||||||
for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) {
|
for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) {
|
||||||
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
||||||
AddToCollectedPickupsArray(i);
|
AddToCollectedPickupsArray(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef PICKUPS_FRAME_SPAN
|
|
||||||
#undef PICKUPS_PER_FRAME
|
|
||||||
#else
|
|
||||||
for (uint32 i = 0; i < NUMPICKUPS; i++) {
|
|
||||||
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
|
|
||||||
AddToCollectedPickupsArray(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -31,10 +31,17 @@ void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehicleP
|
|||||||
void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||||
void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
|
||||||
|
|
||||||
WRAPPER bool CVehicle::ShufflePassengersToMakeSpace(void) { EAXJMP(0x5528A0); }
|
#ifdef FIX_BUGS
|
||||||
// or Weapon.cpp?
|
// I think they meant that
|
||||||
WRAPPER void FireOneInstantHitRound(CVector *shotSource, CVector *shotTarget, int32 damage) { EAXJMP(0x563B00); }
|
#define DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE (MYRAND_MAX * 35 / 100)
|
||||||
WRAPPER void CVehicle::InflictDamage(CEntity *damagedBy, uint32 weaponType, float damage) { EAXJMP(0x551950); }
|
#define DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE (MYRAND_MAX * 70 / 100)
|
||||||
|
#else
|
||||||
|
#define DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE (35000)
|
||||||
|
#define DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE (70000)
|
||||||
|
#endif
|
||||||
|
#define DAMAGE_HEALTH_TO_FLEE_ALWAYS (200.0f)
|
||||||
|
#define DAMAGE_HEALTH_TO_CATCH_FIRE (250.0f)
|
||||||
|
|
||||||
|
|
||||||
CVehicle::CVehicle(uint8 CreatedBy)
|
CVehicle::CVehicle(uint8 CreatedBy)
|
||||||
{
|
{
|
||||||
@ -361,6 +368,119 @@ CVehicle::ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVec
|
|||||||
return angularVelocity * CTimer::GetTimeStep();
|
return angularVelocity * CTimer::GetTimeStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage)
|
||||||
|
{
|
||||||
|
if (!bCanBeDamaged)
|
||||||
|
return;
|
||||||
|
if (bOnlyDamagedByPlayer && (damagedBy != FindPlayerPed() && damagedBy != FindPlayerVehicle()))
|
||||||
|
return;
|
||||||
|
bool bFrightensDriver = false;
|
||||||
|
switch (weaponType) {
|
||||||
|
case WEAPONTYPE_UNARMED:
|
||||||
|
case WEAPONTYPE_BASEBALLBAT:
|
||||||
|
if (bMeleeProof)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case WEAPONTYPE_COLT45:
|
||||||
|
case WEAPONTYPE_UZI:
|
||||||
|
case WEAPONTYPE_SHOTGUN:
|
||||||
|
case WEAPONTYPE_AK47:
|
||||||
|
case WEAPONTYPE_M16:
|
||||||
|
case WEAPONTYPE_SNIPERRIFLE:
|
||||||
|
case WEAPONTYPE_TOTAL_INVENTORY_WEAPONS:
|
||||||
|
case WEAPONTYPE_UZI_DRIVEBY:
|
||||||
|
if (bBulletProof)
|
||||||
|
return;
|
||||||
|
bFrightensDriver = true;
|
||||||
|
break;
|
||||||
|
case WEAPONTYPE_ROCKETLAUNCHER:
|
||||||
|
case WEAPONTYPE_MOLOTOV:
|
||||||
|
case WEAPONTYPE_GRENADE:
|
||||||
|
case WEAPONTYPE_EXPLOSION:
|
||||||
|
if (bExplosionProof)
|
||||||
|
return;
|
||||||
|
bFrightensDriver = true;
|
||||||
|
break;
|
||||||
|
case WEAPONTYPE_FLAMETHROWER:
|
||||||
|
if (bFireProof)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case WEAPONTYPE_RAMMEDBYCAR:
|
||||||
|
if (bCollisionProof)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m_fHealth > 0.0f) {
|
||||||
|
if (VehicleCreatedBy == RANDOM_VEHICLE && pDriver &&
|
||||||
|
(m_status == STATUS_SIMPLE || m_status == STATUS_PHYSICS) &&
|
||||||
|
AutoPilot.m_nCarMission == MISSION_CRUISE) {
|
||||||
|
if (m_randomSeed < DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE) {
|
||||||
|
CCarCtrl::SwitchVehicleToRealPhysics(this);
|
||||||
|
AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * pHandling->Transmission.fUnkMaxVelocity;
|
||||||
|
m_status = STATUS_PHYSICS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_nLastWeaponDamage = weaponType;
|
||||||
|
float oldHealth = m_fHealth;
|
||||||
|
if (m_fHealth > damage) {
|
||||||
|
m_fHealth -= damage;
|
||||||
|
if (VehicleCreatedBy == RANDOM_VEHICLE &&
|
||||||
|
(m_fHealth < DAMAGE_HEALTH_TO_FLEE_ALWAYS ||
|
||||||
|
bFrightensDriver && m_randomSeed > DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE)) {
|
||||||
|
switch (m_status) {
|
||||||
|
case STATUS_SIMPLE:
|
||||||
|
case STATUS_PHYSICS:
|
||||||
|
if (pDriver) {
|
||||||
|
m_status = STATUS_ABANDONED;
|
||||||
|
pDriver->bFleeAfterExitingCar = true;
|
||||||
|
pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m_nNumMaxPassengers; i++) {
|
||||||
|
if (pPassengers[i]) {
|
||||||
|
pPassengers[i]->bFleeAfterExitingCar = true;
|
||||||
|
pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oldHealth > DAMAGE_HEALTH_TO_CATCH_FIRE && m_fHealth < DAMAGE_HEALTH_TO_CATCH_FIRE) {
|
||||||
|
if (IsCar()) {
|
||||||
|
CAutomobile* pThisCar = (CAutomobile*)this;
|
||||||
|
pThisCar->Damage.SetEngineStatus(ENGINE_STATUS_ON_FIRE);
|
||||||
|
pThisCar->m_pSetOnFireEntity = damagedBy;
|
||||||
|
if (damagedBy)
|
||||||
|
damagedBy->RegisterReference((CEntity**)&pThisCar->m_pSetOnFireEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_fHealth = 0.0f;
|
||||||
|
if (weaponType == WEAPONTYPE_EXPLOSION) {
|
||||||
|
// between 1000 and 3047. Also not very nice: can't be saved by respray or cheat
|
||||||
|
m_nBombTimer = 1000 + CGeneral::GetRandomNumber() & 0x7FF;
|
||||||
|
m_pBlowUpEntity = damagedBy;
|
||||||
|
if (damagedBy)
|
||||||
|
damagedBy->RegisterReference((CEntity**)&m_pBlowUpEntity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BlowUpCar(damagedBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef FIX_BUGS // removing dumb case when shooting police car in player's own garage gives wanted level
|
||||||
|
if (GetModelIndex() == MI_POLICE && damagedBy == FindPlayerPed() && !bHasBeenOwnedByPlayer)
|
||||||
|
#else
|
||||||
|
if (GetModelIndex() == MI_POLICE && damagedBy == FindPlayerPed())
|
||||||
|
#endif
|
||||||
|
FindPlayerPed()->SetWantedLevelNoDrop(1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CVehicle::ExtinguishCarFire(void)
|
CVehicle::ExtinguishCarFire(void)
|
||||||
{
|
{
|
||||||
@ -375,6 +495,65 @@ CVehicle::ExtinguishCarFire(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CVehicle::ShufflePassengersToMakeSpace(void)
|
||||||
|
{
|
||||||
|
if (m_nNumPassengers >= m_nNumMaxPassengers)
|
||||||
|
return false;
|
||||||
|
if (pPassengers[1] &&
|
||||||
|
!(m_nGettingInFlags & CAR_DOOR_FLAG_LR) &&
|
||||||
|
IsRoomForPedToLeaveCar(COMPONENT_DOOR_REAR_LEFT, nil)) {
|
||||||
|
if (!pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR)) {
|
||||||
|
pPassengers[2] = pPassengers[1];
|
||||||
|
pPassengers[1] = nil;
|
||||||
|
pPassengers[2]->m_vehEnterType = CAR_DOOR_RR;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!pPassengers[0] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RF)) {
|
||||||
|
pPassengers[0] = pPassengers[1];
|
||||||
|
pPassengers[1] = nil;
|
||||||
|
pPassengers[0]->m_vehEnterType = CAR_DOOR_RF;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pPassengers[2] &&
|
||||||
|
!(m_nGettingInFlags & CAR_DOOR_FLAG_RR) &&
|
||||||
|
IsRoomForPedToLeaveCar(COMPONENT_DOOR_REAR_RIGHT, nil)) {
|
||||||
|
if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) {
|
||||||
|
pPassengers[1] = pPassengers[2];
|
||||||
|
pPassengers[2] = nil;
|
||||||
|
pPassengers[1]->m_vehEnterType = CAR_DOOR_LR;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!pPassengers[0] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RF)) {
|
||||||
|
pPassengers[0] = pPassengers[2];
|
||||||
|
pPassengers[2] = nil;
|
||||||
|
pPassengers[0]->m_vehEnterType = CAR_DOOR_RF;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pPassengers[0] &&
|
||||||
|
!(m_nGettingInFlags & CAR_DOOR_FLAG_RF) &&
|
||||||
|
IsRoomForPedToLeaveCar(COMPONENT_DOOR_FRONT_RIGHT, nil)) {
|
||||||
|
if (!pPassengers[1] && !(m_nGettingInFlags & CAR_DOOR_FLAG_LR)) {
|
||||||
|
pPassengers[1] = pPassengers[0];
|
||||||
|
pPassengers[0] = nil;
|
||||||
|
pPassengers[1]->m_vehEnterType = CAR_DOOR_LR;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!pPassengers[2] && !(m_nGettingInFlags & CAR_DOOR_FLAG_RR)) {
|
||||||
|
pPassengers[2] = pPassengers[0];
|
||||||
|
pPassengers[0] = nil;
|
||||||
|
pPassengers[2]->m_vehEnterType = CAR_DOOR_RR;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CVehicle::ProcessDelayedExplosion(void)
|
CVehicle::ProcessDelayedExplosion(void)
|
||||||
{
|
{
|
||||||
@ -831,4 +1010,5 @@ STARTPATCHES
|
|||||||
InjectHook(0x551EB0, &CVehicle::RemovePassenger, PATCH_JUMP);
|
InjectHook(0x551EB0, &CVehicle::RemovePassenger, PATCH_JUMP);
|
||||||
InjectHook(0x5525A0, &CVehicle::ProcessCarAlarm, PATCH_JUMP);
|
InjectHook(0x5525A0, &CVehicle::ProcessCarAlarm, PATCH_JUMP);
|
||||||
InjectHook(0x552620, &CVehicle::IsSphereTouchingVehicle, PATCH_JUMP);
|
InjectHook(0x552620, &CVehicle::IsSphereTouchingVehicle, PATCH_JUMP);
|
||||||
|
InjectHook(0x551950, &CVehicle::InflictDamage, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "AutoPilot.h"
|
#include "AutoPilot.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
#include "AnimManager.h"
|
#include "AnimManager.h"
|
||||||
|
#include "Weapon.h"
|
||||||
|
|
||||||
class CPed;
|
class CPed;
|
||||||
class CFire;
|
class CFire;
|
||||||
@ -266,7 +267,7 @@ public:
|
|||||||
void ProcessCarAlarm(void);
|
void ProcessCarAlarm(void);
|
||||||
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
|
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
|
||||||
bool ShufflePassengersToMakeSpace(void);
|
bool ShufflePassengersToMakeSpace(void);
|
||||||
void InflictDamage(CEntity *damagedBy, uint32 weaponType, float damage);
|
void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage);
|
||||||
|
|
||||||
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
|
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
|
||||||
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
|
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
|
||||||
|
@ -14,6 +14,7 @@ WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, fl
|
|||||||
WRAPPER void CWeapon::Update(int32 audioEntity) { EAXJMP(0x563A10); }
|
WRAPPER void CWeapon::Update(int32 audioEntity) { EAXJMP(0x563A10); }
|
||||||
WRAPPER void CWeapon::DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end) { EAXJMP(0x563200); }
|
WRAPPER void CWeapon::DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end) { EAXJMP(0x563200); }
|
||||||
WRAPPER void CWeapon::InitialiseWeapons(void) { EAXJMP(0x55C2D0); }
|
WRAPPER void CWeapon::InitialiseWeapons(void) { EAXJMP(0x55C2D0); }
|
||||||
|
WRAPPER void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage) { EAXJMP(0x563B00); }
|
||||||
|
|
||||||
void
|
void
|
||||||
CWeapon::Initialise(eWeaponType type, int ammo)
|
CWeapon::Initialise(eWeaponType type, int ammo)
|
||||||
|
@ -81,3 +81,5 @@ public:
|
|||||||
static void UpdateWeapons(void);
|
static void UpdateWeapons(void);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
||||||
|
|
||||||
|
void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage);
|
Loading…
Reference in New Issue
Block a user