Shotgun fix, CPed, CWeaponInfo
Signed-off-by: eray orçunus <erayorcunus@gmail.com>
This commit is contained in:
parent
817f8b0e3f
commit
0a7120b622
@ -9,6 +9,7 @@
|
|||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
#include "PlayerPed.h"
|
#include "PlayerPed.h"
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
|
#include "VisibilityPlugins.h"
|
||||||
|
|
||||||
bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
|
bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
|
||||||
bool &CPed::bPedCheat2 = *(bool*)0x95CD5A;
|
bool &CPed::bPedCheat2 = *(bool*)0x95CD5A;
|
||||||
@ -23,8 +24,6 @@ WRAPPER void CPed::SetDie(AnimationId anim, float arg1, float arg2) { EAXJMP(0x4
|
|||||||
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
|
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
|
||||||
WRAPPER void CPed::RestorePreviousState(void) { EAXJMP(0x4C5E30); }
|
WRAPPER void CPed::RestorePreviousState(void) { EAXJMP(0x4C5E30); }
|
||||||
WRAPPER void CPed::ClearAttack(void) { EAXJMP(0x4E6790); }
|
WRAPPER void CPed::ClearAttack(void) { EAXJMP(0x4E6790); }
|
||||||
WRAPPER void CPed::SelectGunIfArmed(void) { EAXJMP(0x4DD920); }
|
|
||||||
WRAPPER void CPed::RemoveWeaponModel(int) { EAXJMP(0x4CF980); }
|
|
||||||
|
|
||||||
static char ObjectiveText[34][28] = {
|
static char ObjectiveText[34][28] = {
|
||||||
"No Obj",
|
"No Obj",
|
||||||
@ -181,6 +180,18 @@ static char WaitStateText[21][16] = {
|
|||||||
"Finish Flee",
|
"Finish Flee",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static RwObject*
|
||||||
|
RemoveAllModelCB(RwObject *object, void *data)
|
||||||
|
{
|
||||||
|
RpAtomic* atomic = (RpAtomic*)object;
|
||||||
|
if (CVisibilityPlugins::GetAtomicModelInfo(atomic))
|
||||||
|
{
|
||||||
|
RpClumpRemoveAtomic(atomic->clump, atomic);
|
||||||
|
RpAtomicDestroy(atomic);
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
static PedOnGroundState
|
static PedOnGroundState
|
||||||
CheckForPedsOnGroundToAttack(CPlayerPed *player, CPed **pedOnGround)
|
CheckForPedsOnGroundToAttack(CPlayerPed *player, CPed **pedOnGround)
|
||||||
{
|
{
|
||||||
@ -752,29 +763,32 @@ CPed::Attack(void)
|
|||||||
if (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime) {
|
if (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime) {
|
||||||
weaponAnimAssoc->callbackType = 0;
|
weaponAnimAssoc->callbackType = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lastReloadWasInFuture = false;
|
lastReloadWasInFuture = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (ourWeaponType == WEAPONTYPE_SHOTGUN) {
|
if (ourWeaponType == WEAPONTYPE_SHOTGUN) {
|
||||||
weaponAnimTime = weaponAnimAssoc->currentTime;
|
weaponAnimTime = weaponAnimAssoc->currentTime;
|
||||||
|
firePos = ourWeapon->m_vecFireOffset;
|
||||||
|
|
||||||
if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
|
if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
|
||||||
for (i = GetNodeFrame(PED_HANDR); i; i = RwFrameGetParent(i))
|
for (i = GetNodeFrame(PED_HANDR); i; i = RwFrameGetParent(i))
|
||||||
RwV3dTransformPoints((RwV3d*)ourWeapon->m_vecFireOffset, (RwV3d*)ourWeapon->m_vecFireOffset, 1, &i->modelling);
|
RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, &i->modelling);
|
||||||
|
|
||||||
CVector gunshellPos(
|
CVector gunshellPos(
|
||||||
ourWeapon->m_vecFireOffset.x - 0.6f * GetForward().x,
|
firePos.x - 0.6f * GetForward().x,
|
||||||
ourWeapon->m_vecFireOffset.y - 0.6f * GetForward().y,
|
firePos.y - 0.6f * GetForward().y,
|
||||||
ourWeapon->m_vecFireOffset.z - 0.15f * GetUp().z
|
firePos.z - 0.15f * GetUp().z
|
||||||
);
|
);
|
||||||
|
|
||||||
CVector2D gunshellRot(
|
CVector2D gunshellRot(
|
||||||
GetRight().x,
|
GetRight().x,
|
||||||
GetRight().y
|
GetRight().y
|
||||||
);
|
);
|
||||||
|
|
||||||
gunshellRot.Normalise();
|
gunshellRot.Normalise();
|
||||||
CWeapon::AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
|
GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
animEnd = ourWeapon->m_fAnimLoopEnd;
|
animEnd = ourWeapon->m_fAnimLoopEnd;
|
||||||
@ -787,7 +801,6 @@ CPed::Attack(void)
|
|||||||
if (weaponAnimTime > animEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) {
|
if (weaponAnimTime > animEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) {
|
||||||
|
|
||||||
if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animEnd
|
if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animEnd
|
||||||
// BUG: We currently don't know any situation this cond. could be true.
|
|
||||||
&& (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime)
|
&& (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime)
|
||||||
&& GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
|
&& GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
|
||||||
|
|
||||||
@ -830,7 +843,7 @@ CPed::Attack(void)
|
|||||||
if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
|
if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
|
||||||
weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
|
weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
|
||||||
weaponAnimAssoc->blendDelta = -4.0;
|
weaponAnimAssoc->blendDelta = -4.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -865,6 +878,107 @@ CPed::Attack(void)
|
|||||||
CPed::FinishedAttackCB(0, this);
|
CPed::FinishedAttackCB(0, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::RemoveWeaponModel(int modelId)
|
||||||
|
{
|
||||||
|
// modelId is not used!! This function just removes the current weapon.
|
||||||
|
RwFrameForAllObjects(GetNodeFrame(PED_HANDR),RemoveAllModelCB,0);
|
||||||
|
m_wepModelID = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::SetCurrentWeapon(eWeaponType weaponType)
|
||||||
|
{
|
||||||
|
CWeaponInfo* weaponInfo;
|
||||||
|
|
||||||
|
if (HasWeapon(weaponType)) {
|
||||||
|
weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
|
||||||
|
RemoveWeaponModel(weaponInfo->m_nModelId);
|
||||||
|
|
||||||
|
m_currentWeapon = weaponType;
|
||||||
|
|
||||||
|
weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
|
||||||
|
AddWeaponModel(weaponInfo->m_nModelId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only used while deciding which gun ped should switch to, if no ammo left.
|
||||||
|
bool
|
||||||
|
CPed::SelectGunIfArmed(void)
|
||||||
|
{
|
||||||
|
eWeaponType weaponType;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_maxWeaponTypeAllowed; i++) {
|
||||||
|
|
||||||
|
if (m_weapons[i].m_nAmmoTotal > 0) {
|
||||||
|
weaponType = m_weapons[i].m_eWeaponType;
|
||||||
|
|
||||||
|
// Original condition was ridiculous
|
||||||
|
// if (weaponType == WEAPONTYPE_COLT45 || weaponType < WEAPONTYPE_M16 || weaponType < WEAPONTYPE_FLAMETHROWER || weaponType == WEAPONTYPE_FLAMETHROWER)
|
||||||
|
if (weaponType < WEAPONTYPE_MOLOTOV) {
|
||||||
|
SetCurrentWeapon(weaponType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetCurrentWeapon(WEAPONTYPE_UNARMED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::Duck(void)
|
||||||
|
{
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > m_duckTimer)
|
||||||
|
ClearDuck();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::ClearDuck(void)
|
||||||
|
{
|
||||||
|
CAnimBlendAssociation *animAssoc;
|
||||||
|
|
||||||
|
animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_DUCK_DOWN);
|
||||||
|
if (!animAssoc)
|
||||||
|
animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_DUCK_LOW);
|
||||||
|
|
||||||
|
if (animAssoc) {
|
||||||
|
|
||||||
|
if (m_ped_flagE8) {
|
||||||
|
|
||||||
|
if (m_nPedState == PED_ATTACK || m_nPedState == PED_AIM_GUN) {
|
||||||
|
animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_RBLOCK_CSHOOT);
|
||||||
|
if (!animAssoc || animAssoc->blendDelta < 0.0f) {
|
||||||
|
CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
m_ped_flagE10 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::ClearPointGunAt(void)
|
||||||
|
{
|
||||||
|
CAnimBlendAssociation *animAssoc;
|
||||||
|
CWeaponInfo *weaponInfo;
|
||||||
|
|
||||||
|
ClearLookFlag();
|
||||||
|
ClearAimFlag();
|
||||||
|
m_ped_flagA8 = false;
|
||||||
|
if (m_nPedState == PED_AIM_GUN) {
|
||||||
|
RestorePreviousState();
|
||||||
|
weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
|
||||||
|
animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, weaponInfo->m_AnimToPlay);
|
||||||
|
if (!animAssoc || animAssoc->blendDelta < 0.0f) {
|
||||||
|
animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, weaponInfo->m_Anim2ToPlay);
|
||||||
|
}
|
||||||
|
if (animAssoc) {
|
||||||
|
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
animAssoc->blendDelta = -4.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP);
|
InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP);
|
||||||
InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP);
|
InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP);
|
||||||
@ -881,4 +995,10 @@ STARTPATCHES
|
|||||||
InjectHook(0x4E68A0, &CPed::FinishedAttackCB, PATCH_JUMP);
|
InjectHook(0x4E68A0, &CPed::FinishedAttackCB, PATCH_JUMP);
|
||||||
InjectHook(0x4E5BD0, &CheckForPedsOnGroundToAttack, PATCH_JUMP);
|
InjectHook(0x4E5BD0, &CheckForPedsOnGroundToAttack, PATCH_JUMP);
|
||||||
InjectHook(0x4E6BA0, &CPed::Attack, PATCH_JUMP);
|
InjectHook(0x4E6BA0, &CPed::Attack, PATCH_JUMP);
|
||||||
|
InjectHook(0x4CF980, &CPed::RemoveWeaponModel, PATCH_JUMP);
|
||||||
|
InjectHook(0x4CFA60, &CPed::SetCurrentWeapon, PATCH_JUMP);
|
||||||
|
InjectHook(0x4DD920, &CPed::SelectGunIfArmed, PATCH_JUMP);
|
||||||
|
InjectHook(0x4E4A10, &CPed::Duck, PATCH_JUMP);
|
||||||
|
InjectHook(0x4E4A30, &CPed::ClearDuck, PATCH_JUMP);
|
||||||
|
InjectHook(0x4E6180, &CPed::ClearPointGunAt, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -12,10 +12,6 @@
|
|||||||
|
|
||||||
struct CPathNode;
|
struct CPathNode;
|
||||||
|
|
||||||
enum {
|
|
||||||
PED_MAX_WEAPONS = 13
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PedOnGroundState {
|
enum PedOnGroundState {
|
||||||
NO_PED,
|
NO_PED,
|
||||||
PED_BELOW_PLAYER,
|
PED_BELOW_PLAYER,
|
||||||
@ -138,7 +134,7 @@ public:
|
|||||||
uint8 m_ped_flagE1 : 1;
|
uint8 m_ped_flagE1 : 1;
|
||||||
uint8 m_ped_flagE2 : 1;
|
uint8 m_ped_flagE2 : 1;
|
||||||
uint8 m_ped_flagE4 : 1;
|
uint8 m_ped_flagE4 : 1;
|
||||||
uint8 m_ped_flagE8 : 1;
|
uint8 m_ped_flagE8 : 1; // can duck?
|
||||||
uint8 m_ped_flagE10 : 1; // can't attack if it's set
|
uint8 m_ped_flagE10 : 1; // can't attack if it's set
|
||||||
uint8 m_ped_flagE20 : 1;
|
uint8 m_ped_flagE20 : 1;
|
||||||
uint8 m_ped_flagE40 : 1;
|
uint8 m_ped_flagE40 : 1;
|
||||||
@ -225,10 +221,11 @@ public:
|
|||||||
uint8 stuff5[24];
|
uint8 stuff5[24];
|
||||||
CEntity *m_pCollidingEntity;
|
CEntity *m_pCollidingEntity;
|
||||||
uint8 stuff6[12];
|
uint8 stuff6[12];
|
||||||
CWeapon m_weapons[PED_MAX_WEAPONS];
|
CWeapon m_weapons[NUM_PED_WEAPONTYPES];
|
||||||
int32 stuff7;
|
int32 stuff7;
|
||||||
uint8 m_currentWeapon;
|
uint8 m_currentWeapon; // eWeaponType
|
||||||
uint8 stuff[3];
|
uint8 m_maxWeaponTypeAllowed; // eWeaponType
|
||||||
|
uint8 stuff[2];
|
||||||
int32 m_pPointGunAt;
|
int32 m_pPointGunAt;
|
||||||
CVector m_vecHitLastPos;
|
CVector m_vecHitLastPos;
|
||||||
uint8 stuff8[12];
|
uint8 stuff8[12];
|
||||||
@ -241,8 +238,11 @@ public:
|
|||||||
uint32 m_standardTimer;
|
uint32 m_standardTimer;
|
||||||
uint32 m_attackTimer;
|
uint32 m_attackTimer;
|
||||||
uint32 m_lastHitTime;
|
uint32 m_lastHitTime;
|
||||||
uint8 stuff9[22];
|
uint32 m_hitRecoverTimer;
|
||||||
uint8 m_bodyPartBleeding;
|
uint32 field_4E0;
|
||||||
|
uint32 m_duckTimer;
|
||||||
|
uint8 stuff9[10];
|
||||||
|
uint8 m_bodyPartBleeding; // PedNode
|
||||||
uint8 m_field_4F3;
|
uint8 m_field_4F3;
|
||||||
CPed *m_nearPeds[10];
|
CPed *m_nearPeds[10];
|
||||||
uint16 m_numNearPeds;
|
uint16 m_numNearPeds;
|
||||||
@ -272,12 +272,17 @@ public:
|
|||||||
void RestorePreviousState(void);
|
void RestorePreviousState(void);
|
||||||
void ClearAttack(void);
|
void ClearAttack(void);
|
||||||
bool IsPedHeadAbovePos(float zOffset);
|
bool IsPedHeadAbovePos(float zOffset);
|
||||||
void RemoveWeaponModel(int);
|
void RemoveWeaponModel(int modelId);
|
||||||
void SelectGunIfArmed(void);
|
void SetCurrentWeapon(eWeaponType weaponType);
|
||||||
|
bool SelectGunIfArmed(void);
|
||||||
|
void Duck(void);
|
||||||
|
void ClearDuck(void);
|
||||||
|
void ClearPointGunAt(void);
|
||||||
static RwObject *SetPedAtomicVisibilityCB(RwObject *object, void *data);
|
static RwObject *SetPedAtomicVisibilityCB(RwObject *object, void *data);
|
||||||
static RwFrame *RecurseFrameChildrenVisibilityCB(RwFrame *frame, void *data);
|
static RwFrame *RecurseFrameChildrenVisibilityCB(RwFrame *frame, void *data);
|
||||||
static void FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg);
|
static void FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg);
|
||||||
|
|
||||||
|
bool HasWeapon(eWeaponType weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
|
||||||
CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; }
|
CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; }
|
||||||
RwFrame *GetNodeFrame(int nodeId) { return m_pFrames[nodeId]->frame; }
|
RwFrame *GetNodeFrame(int nodeId) { return m_pFrames[nodeId]->frame; }
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ enum eWeaponType
|
|||||||
WEAPONTYPE_MOLOTOV,
|
WEAPONTYPE_MOLOTOV,
|
||||||
WEAPONTYPE_GRENADE,
|
WEAPONTYPE_GRENADE,
|
||||||
WEAPONTYPE_DETONATOR,
|
WEAPONTYPE_DETONATOR,
|
||||||
WEAPONTYPE_HELICANNON
|
NUM_PED_WEAPONTYPES = 13,
|
||||||
|
WEAPONTYPE_HELICANNON = 13,
|
||||||
|
NUM_WEAPONTYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eWeaponFire {
|
enum eWeaponFire {
|
||||||
@ -48,6 +50,6 @@ public:
|
|||||||
bool m_bAddRotOffset;
|
bool m_bAddRotOffset;
|
||||||
|
|
||||||
bool Fire(CEntity*, CVector*);
|
bool Fire(CEntity*, CVector*);
|
||||||
static void AddGunshell(CEntity*, CVector const&, CVector2D const&, float);
|
void AddGunshell(CEntity*, CVector const&, CVector2D const&, float);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
||||||
|
@ -1,14 +1,214 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "FileMgr.h"
|
||||||
#include "WeaponInfo.h"
|
#include "WeaponInfo.h"
|
||||||
|
#include "AnimBlendAssociation.h"
|
||||||
|
|
||||||
CWeaponInfo (&CWeaponInfo::ms_apWeaponInfos)[14] = * (CWeaponInfo(*)[14]) * (uintptr*)0x6503EC;
|
//CWeaponInfo (&CWeaponInfo::ms_apWeaponInfos)[14] = * (CWeaponInfo(*)[14]) * (uintptr*)0x6503EC;
|
||||||
|
CWeaponInfo CWeaponInfo::ms_apWeaponInfos[NUM_WEAPONTYPES];
|
||||||
|
|
||||||
|
static char ms_aWeaponNames[][32] = {
|
||||||
|
"Unarmed",
|
||||||
|
"BaseballBat",
|
||||||
|
"Colt45",
|
||||||
|
"Uzi",
|
||||||
|
"Shotgun",
|
||||||
|
"AK47",
|
||||||
|
"M16",
|
||||||
|
"SniperRifle",
|
||||||
|
"RocketLauncher",
|
||||||
|
"FlameThrower",
|
||||||
|
"Molotov",
|
||||||
|
"Grenade",
|
||||||
|
"Detonator",
|
||||||
|
"HeliCannon"
|
||||||
|
};
|
||||||
|
|
||||||
CWeaponInfo*
|
CWeaponInfo*
|
||||||
CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) {
|
CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) {
|
||||||
return &CWeaponInfo::ms_apWeaponInfos[weaponType];
|
return &CWeaponInfo::ms_apWeaponInfos[weaponType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWeaponInfo::Initialise(void)
|
||||||
|
{
|
||||||
|
debug("Initialising CWeaponInfo...\n");
|
||||||
|
for (int i = 0; i < NUM_WEAPONTYPES; i++) {
|
||||||
|
ms_apWeaponInfos[i].m_eWeaponFire = WEAPON_FIRE_INSTANT_HIT;
|
||||||
|
ms_apWeaponInfos[i].m_AnimToPlay = ANIM_PUNCH_R;
|
||||||
|
ms_apWeaponInfos[i].m_Anim2ToPlay = NUM_ANIMS;
|
||||||
|
ms_apWeaponInfos[i].m_bUseGravity = 1;
|
||||||
|
ms_apWeaponInfos[i].m_bSlowsDown = 1;
|
||||||
|
ms_apWeaponInfos[i].m_bRandSpeed = 1;
|
||||||
|
ms_apWeaponInfos[i].m_bExpands = 1;
|
||||||
|
ms_apWeaponInfos[i].m_bExplodes = 1;
|
||||||
|
}
|
||||||
|
debug("Loading weapon data...\n");
|
||||||
|
LoadWeaponData();
|
||||||
|
debug("CWeaponInfo ready\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWeaponInfo::LoadWeaponData(void)
|
||||||
|
{
|
||||||
|
float spread, speed, lifeSpan, radius;
|
||||||
|
float range, fireOffsetX, fireOffsetY, fireOffsetZ;
|
||||||
|
float delayBetweenAnimAndFire, delayBetweenAnim2AndFire, animLoopStart, animLoopEnd;
|
||||||
|
int flags, ammoAmount, damage, reload, weaponType;
|
||||||
|
int firingRate, modelId;
|
||||||
|
char line[256], weaponName[32], fireType[32];
|
||||||
|
char animToPlay[32], anim2ToPlay[32];
|
||||||
|
|
||||||
|
CAnimBlendAssociation *animAssoc;
|
||||||
|
AnimationId animId, anim2Id;
|
||||||
|
|
||||||
|
int bp, buflen;
|
||||||
|
int lp, linelen;
|
||||||
|
|
||||||
|
CFileMgr::SetDir("DATA");
|
||||||
|
buflen = CFileMgr::LoadFile("WEAPON.DAT", work_buff, sizeof(work_buff), "r");
|
||||||
|
CFileMgr::SetDir("");
|
||||||
|
|
||||||
|
for (bp = 0; bp < buflen; ) {
|
||||||
|
// read file line by line
|
||||||
|
for (linelen = 0; work_buff[bp] != '\n' && bp < buflen; bp++) {
|
||||||
|
line[linelen++] = work_buff[bp];
|
||||||
|
}
|
||||||
|
bp++;
|
||||||
|
line[linelen] = '\0';
|
||||||
|
|
||||||
|
// skip white space
|
||||||
|
for (lp = 0; line[lp] <= ' '; lp++);
|
||||||
|
|
||||||
|
if (lp >= linelen || // FIX: game uses == here, but this is safer if we have empty lines
|
||||||
|
line[lp] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
spread = 0.0f;
|
||||||
|
flags = 0;
|
||||||
|
speed = 0.0f;
|
||||||
|
ammoAmount = 0;
|
||||||
|
lifeSpan = 0.0f;
|
||||||
|
radius = 0.0f;
|
||||||
|
range = 0.0f;
|
||||||
|
damage = 0;
|
||||||
|
reload = 0;
|
||||||
|
firingRate = 0;
|
||||||
|
fireOffsetX = 0.0f;
|
||||||
|
weaponName[0] = '\0';
|
||||||
|
fireType[0] = '\0';
|
||||||
|
fireOffsetY = 0.0f;
|
||||||
|
fireOffsetZ = 0.0f;
|
||||||
|
animId = ANIM_WALK;
|
||||||
|
anim2Id = ANIM_WALK;
|
||||||
|
sscanf(
|
||||||
|
&line[lp],
|
||||||
|
"%s %s %f %d %d %d %d %f %f %f %f %f %f %f %s %s %f %f %f %f %d %d",
|
||||||
|
&weaponName,
|
||||||
|
&fireType,
|
||||||
|
&range,
|
||||||
|
&firingRate,
|
||||||
|
&reload,
|
||||||
|
&ammoAmount,
|
||||||
|
&damage,
|
||||||
|
&speed,
|
||||||
|
&radius,
|
||||||
|
&lifeSpan,
|
||||||
|
&spread,
|
||||||
|
&fireOffsetX,
|
||||||
|
&fireOffsetY,
|
||||||
|
&fireOffsetZ,
|
||||||
|
&animToPlay,
|
||||||
|
&anim2ToPlay,
|
||||||
|
&animLoopStart,
|
||||||
|
&animLoopEnd,
|
||||||
|
&delayBetweenAnimAndFire,
|
||||||
|
&delayBetweenAnim2AndFire,
|
||||||
|
&modelId,
|
||||||
|
&flags);
|
||||||
|
|
||||||
|
if (strncmp(weaponName, "ENDWEAPONDATA", 13) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
weaponType = FindWeaponType(weaponName);
|
||||||
|
|
||||||
|
animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animToPlay);
|
||||||
|
animId = static_cast<AnimationId>(animAssoc->animId);
|
||||||
|
|
||||||
|
if (strncmp(anim2ToPlay, "null", 5) != 0) {
|
||||||
|
animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, anim2ToPlay);
|
||||||
|
anim2Id = static_cast<AnimationId>(animAssoc->animId);
|
||||||
|
}
|
||||||
|
|
||||||
|
CVector vecFireOffset(fireOffsetX, fireOffsetY, fireOffsetZ);
|
||||||
|
|
||||||
|
ms_apWeaponInfos[weaponType].m_eWeaponFire = FindWeaponFireType(fireType);
|
||||||
|
ms_apWeaponInfos[weaponType].m_fRange = range;
|
||||||
|
ms_apWeaponInfos[weaponType].m_nFiringRate = firingRate;
|
||||||
|
ms_apWeaponInfos[weaponType].m_nReload = reload;
|
||||||
|
ms_apWeaponInfos[weaponType].m_nAmountofAmmunition = ammoAmount;
|
||||||
|
ms_apWeaponInfos[weaponType].m_nDamage = damage;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fSpeed = speed;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fRadius = radius;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fLifespan = lifeSpan;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fSpread = spread;
|
||||||
|
ms_apWeaponInfos[weaponType].m_vecFireOffset = vecFireOffset;
|
||||||
|
ms_apWeaponInfos[weaponType].m_AnimToPlay = animId;
|
||||||
|
ms_apWeaponInfos[weaponType].m_Anim2ToPlay = anim2Id;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fAnimLoopStart = animLoopStart * 0.03f;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fAnimLoopEnd = animLoopEnd * 0.03f;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fAnimFrameFire = delayBetweenAnimAndFire * 0.03f;
|
||||||
|
ms_apWeaponInfos[weaponType].m_fAnim2FrameFire = delayBetweenAnim2AndFire * 0.03f;
|
||||||
|
ms_apWeaponInfos[weaponType].m_nModelId = modelId;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bUseGravity = flags;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bSlowsDown = flags >> 1;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bDissipates = flags >> 2;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bRandSpeed = flags >> 3;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bExpands = flags >> 4;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bExplodes = flags >> 5;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bCanAim = flags >> 6;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bCanAimWithArm = flags >> 7;
|
||||||
|
ms_apWeaponInfos[weaponType].m_b1stPerson = flags >> 8;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bHeavy = flags >> 9;
|
||||||
|
ms_apWeaponInfos[weaponType].m_bThrow = flags >> 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eWeaponType
|
||||||
|
CWeaponInfo::FindWeaponType(char *name)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_WEAPONTYPES; i++) {
|
||||||
|
if (strcmp(ms_aWeaponNames[i], name) == 0) {
|
||||||
|
return static_cast<eWeaponType>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return WEAPONTYPE_UNARMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
eWeaponFire
|
||||||
|
CWeaponInfo::FindWeaponFireType(char *name)
|
||||||
|
{
|
||||||
|
if (strcmp(name, "MELEE") == 0) return WEAPON_FIRE_MELEE;
|
||||||
|
if (strcmp(name, "INSTANT_HIT") == 0) return WEAPON_FIRE_INSTANT_HIT;
|
||||||
|
if (strcmp(name, "PROJECTILE") == 0) return WEAPON_FIRE_PROJECTILE;
|
||||||
|
if (strcmp(name, "AREA_EFFECT") == 0) return WEAPON_FIRE_AREA_EFFECT;
|
||||||
|
Error("Unknown weapon fire type, WeaponInfo.cpp");
|
||||||
|
return WEAPON_FIRE_INSTANT_HIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CWeaponInfo::Shutdown(void)
|
||||||
|
{
|
||||||
|
debug("Shutting down CWeaponInfo...\n");
|
||||||
|
debug("CWeaponInfo shut down\n");
|
||||||
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
|
InjectHook(0x564EA0, &CWeaponInfo::Initialise, PATCH_JUMP);
|
||||||
InjectHook(0x564FD0, &CWeaponInfo::GetWeaponInfo, PATCH_JUMP);
|
InjectHook(0x564FD0, &CWeaponInfo::GetWeaponInfo, PATCH_JUMP);
|
||||||
|
InjectHook(0x5653E0, &CWeaponInfo::FindWeaponType, PATCH_JUMP);
|
||||||
|
InjectHook(0x5653B0, &CWeaponInfo::FindWeaponFireType, PATCH_JUMP);
|
||||||
|
InjectHook(0x564FE0, &CWeaponInfo::LoadWeaponData, PATCH_JUMP);
|
||||||
|
InjectHook(0x564FB0, &CWeaponInfo::Shutdown, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
@ -4,6 +4,8 @@
|
|||||||
#include "AnimManager.h"
|
#include "AnimManager.h"
|
||||||
|
|
||||||
class CWeaponInfo {
|
class CWeaponInfo {
|
||||||
|
// static CWeaponInfo(&ms_apWeaponInfos)[14];
|
||||||
|
static CWeaponInfo ms_apWeaponInfos[14];
|
||||||
public:
|
public:
|
||||||
eWeaponFire m_eWeaponFire;
|
eWeaponFire m_eWeaponFire;
|
||||||
float m_fRange;
|
float m_fRange;
|
||||||
@ -37,9 +39,12 @@ public:
|
|||||||
uint8 m_bThrow : 1;
|
uint8 m_bThrow : 1;
|
||||||
uint8 stuff;
|
uint8 stuff;
|
||||||
|
|
||||||
static CWeaponInfo (&ms_apWeaponInfos)[14];
|
static void Initialise(void);
|
||||||
|
static void LoadWeaponData(void);
|
||||||
static CWeaponInfo *GetWeaponInfo(eWeaponType weaponType);
|
static CWeaponInfo *GetWeaponInfo(eWeaponType weaponType);
|
||||||
|
static eWeaponFire FindWeaponFireType(char *name);
|
||||||
|
static eWeaponType FindWeaponType(char *name);
|
||||||
|
static void Shutdown(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(CWeaponInfo) == 0x54, "CWeaponInfo: error");
|
static_assert(sizeof(CWeaponInfo) == 0x54, "CWeaponInfo: error");
|
Loading…
Reference in New Issue
Block a user