diff options
Diffstat (limited to 'src/weapons')
-rw-r--r-- | src/weapons/Explosion.cpp | 2 | ||||
-rw-r--r-- | src/weapons/ShotInfo.cpp | 140 | ||||
-rw-r--r-- | src/weapons/ShotInfo.h | 23 | ||||
-rw-r--r-- | src/weapons/Weapon.cpp | 2 | ||||
-rw-r--r-- | src/weapons/Weapon.h | 15 | ||||
-rw-r--r-- | src/weapons/WeaponInfo.cpp | 2 | ||||
-rw-r--r-- | src/weapons/WeaponInfo.h | 7 |
7 files changed, 181 insertions, 10 deletions
diff --git a/src/weapons/Explosion.cpp b/src/weapons/Explosion.cpp index 05087335..e99dc918 100644 --- a/src/weapons/Explosion.cpp +++ b/src/weapons/Explosion.cpp @@ -6,8 +6,6 @@ CExplosion(&gaExplosion)[48] = *(CExplosion(*)[48])*(uintptr*)0x64E208; WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); } -//WRAPPER void CExplosion::RemoveAllExplosionsInArea(CVector, float) { EAXJMP(0x55AD40); } -//WRAPPER bool CExplosion::TestForExplosionInArea(eExplosionType, float, float, float, float, float, float) { EAXJMP(0x55AC80); } int AudioHandle = AEHANDLE_NONE; diff --git a/src/weapons/ShotInfo.cpp b/src/weapons/ShotInfo.cpp new file mode 100644 index 00000000..43d0579d --- /dev/null +++ b/src/weapons/ShotInfo.cpp @@ -0,0 +1,140 @@ +#include "common.h" +#include "patcher.h" +#include "ShotInfo.h" +#include "Entity.h" +#include "Weapon.h" +#include "World.h" +#include "WeaponInfo.h" +#include "General.h" +#include "Timer.h" +#include "Ped.h" +#include "Fire.h" + +CShotInfo gaShotInfo[NUMSHOTINFOS]; +float CShotInfo::ms_afRandTable[20]; + +// CShotInfo (&gaShotInfo)[100] = *(CShotInfo(*)[100])*(uintptr*)0x64F0D0; +// float (&CShotInfo::ms_afRandTable)[20] = *(float(*)[20])*(uintptr*)0x6E9878; + +/* + Used for flamethrower. I don't know why it's name is CShotInfo. + Has no relation with any visual, just calculates the area fire affects + (including spreading and slowing of fire) and make entities burn/flee. +*/ + +void +CShotInfo::Initialise() +{ + debug("Initialising CShotInfo...\n"); + for(int i=0; i<ARRAY_SIZE(gaShotInfo); i++) { + gaShotInfo[i].m_inUse = false; + gaShotInfo[i].m_weapon = WEAPONTYPE_COLT45; + gaShotInfo[i].m_startPos = CVector(0.0f, 0.0f, 0.0f); + gaShotInfo[i].m_areaAffected = CVector(0.0f, 0.0f, 0.0f); + gaShotInfo[i].m_radius = 1.0f; + gaShotInfo[i].m_sourceEntity = nil; + gaShotInfo[i].m_timeout = 0; + } + + // Not random for sure + float nextVal = -0.05f; + for (int i = 0; i < ARRAY_SIZE(ms_afRandTable); i++) { + ms_afRandTable[i] = nextVal; + nextVal += 0.005f; + } + debug("CShotInfo ready\n"); +} + +bool +CShotInfo::AddShot(CEntity *sourceEntity, eWeaponType weapon, CVector startPos, CVector endPos) +{ + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(weapon); + + int slot; + for (slot = 0; slot < ARRAY_SIZE(gaShotInfo) && gaShotInfo[slot].m_inUse; slot++); + + if (slot == ARRAY_SIZE(gaShotInfo)) + return false; + + gaShotInfo[slot].m_inUse = true; + gaShotInfo[slot].m_weapon = weapon; + gaShotInfo[slot].m_startPos = startPos; + gaShotInfo[slot].m_areaAffected = endPos - startPos; + gaShotInfo[slot].m_radius = weaponInfo->m_fRadius; + + if (weaponInfo->m_fSpread != 0.0f) { + gaShotInfo[slot].m_areaAffected.x += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] * weaponInfo->m_fSpread; + gaShotInfo[slot].m_areaAffected.y += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] * weaponInfo->m_fSpread; + gaShotInfo[slot].m_areaAffected.z += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)]; + } + gaShotInfo[slot].m_areaAffected.Normalise(); + if (weaponInfo->m_bRandSpeed) + gaShotInfo[slot].m_areaAffected *= CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] + weaponInfo->m_fSpeed; + else + gaShotInfo[slot].m_areaAffected *= weaponInfo->m_fSpeed; + + gaShotInfo[slot].m_sourceEntity = sourceEntity; + gaShotInfo[slot].m_timeout = CTimer::GetTimeInMilliseconds() + weaponInfo->m_fLifespan; + + return true; +} + +void +CShotInfo::Shutdown() +{ + debug("Shutting down CShotInfo...\n"); + debug("CShotInfo shut down\n"); +} + +void +CShotInfo::Update() +{ + for (int slot = 0; slot < ARRAY_SIZE(gaShotInfo); slot++) { + CShotInfo &shot = gaShotInfo[slot]; + if (shot.m_sourceEntity && shot.m_sourceEntity->IsPed() && !((CPed*)shot.m_sourceEntity)->IsPointerValid()) + shot.m_sourceEntity = nil; + + if (!shot.m_inUse) + continue; + + CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(shot.m_weapon); + if (CTimer::GetTimeInMilliseconds() > shot.m_timeout) + shot.m_inUse = false; + + if (weaponInfo->m_bSlowsDown) + shot.m_areaAffected *= pow(0.96, CTimer::GetTimeStep()); // FRAMERATE + + if (weaponInfo->m_bExpands) + shot.m_radius += 0.075f * CTimer::GetTimeStep(); + + shot.m_startPos += CTimer::GetTimeStep() * shot.m_areaAffected; + if (shot.m_sourceEntity) { + assert(shot.m_sourceEntity->IsPed()); + CPed *ped = (CPed*) shot.m_sourceEntity; + float radius = max(1.0f, shot.m_radius); + + for (int i = 0; i < ped->m_numNearPeds; ++i) { + CPed *nearPed = ped->m_nearPeds[i]; + if (nearPed->IsPointerValid()) { + if (nearPed->IsPedInControl() && (nearPed->GetPosition() - shot.m_startPos).MagnitudeSqr() < radius && !nearPed->bFireProof) { + + if (!nearPed->IsPlayer()) { + nearPed->SetFindPathAndFlee(shot.m_sourceEntity, 10000); + nearPed->SetMoveState(PEDMOVE_SPRINT); + } + gFireManager.StartFire(nearPed, shot.m_sourceEntity, 0.8f, true); + } + } + } + } + if (!((CTimer::GetFrameCounter() + slot) & 3)) + CWorld::SetCarsOnFire(shot.m_startPos.x, shot.m_startPos.y, shot.m_startPos.z, 4.0f, shot.m_sourceEntity); + } +} + +STARTPATCHES + InjectHook(0x55BFF0, &CShotInfo::Update, PATCH_JUMP); + InjectHook(0x55BD70, &CShotInfo::AddShot, PATCH_JUMP); + InjectHook(0x55BC60, &CShotInfo::Initialise, PATCH_JUMP); + InjectHook(0x55BD50, &CShotInfo::Shutdown, PATCH_JUMP); +ENDPATCHES
\ No newline at end of file diff --git a/src/weapons/ShotInfo.h b/src/weapons/ShotInfo.h new file mode 100644 index 00000000..a5e5fd35 --- /dev/null +++ b/src/weapons/ShotInfo.h @@ -0,0 +1,23 @@ +#pragma once + +class CEntity; +enum eWeaponType; + +class CShotInfo +{ +public: + eWeaponType m_weapon; + CVector m_startPos; + CVector m_areaAffected; + float m_radius; + CEntity *m_sourceEntity; + float m_timeout; + bool m_inUse; + + static float ms_afRandTable[20]; + + static void Initialise(void); + static bool AddShot(CEntity*, eWeaponType, CVector, CVector); + static void Shutdown(void); + static void Update(void); +}; diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 8019a1cf..0f41264f 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -6,6 +6,7 @@ #include "Ped.h" #include "World.h" +WRAPPER void CWeapon::ShutdownWeapons(void) { EAXJMP(0x55C2F0); } WRAPPER void CWeapon::UpdateWeapons(void) { EAXJMP(0x55C310); } WRAPPER bool CWeapon::Fire(CEntity*, CVector*) { EAXJMP(0x55C380); } WRAPPER void CWeapon::FireFromCar(CAutomobile *car, bool left) { EAXJMP(0x55C940); } @@ -13,6 +14,7 @@ WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, fl 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::InitialiseWeapons(void) { EAXJMP(0x55C2D0); } +WRAPPER void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage) { EAXJMP(0x563B00); } void CWeapon::Initialise(eWeaponType type, int ammo) diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index 1db66720..84760550 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -15,17 +15,19 @@ enum eWeaponType WEAPONTYPE_MOLOTOV, WEAPONTYPE_GRENADE, WEAPONTYPE_DETONATOR, - WEAPONTYPE_TOTAL_INVENTORY_WEAPONS = 13, - WEAPONTYPE_HELICANNON = 13, - WEAPONTYPE_TOTALWEAPONS, + WEAPONTYPE_HELICANNON, + WEAPONTYPE_LAST_WEAPONTYPE, WEAPONTYPE_ARMOUR, WEAPONTYPE_RAMMEDBYCAR, WEAPONTYPE_RUNOVERBYCAR, WEAPONTYPE_EXPLOSION, WEAPONTYPE_UZI_DRIVEBY, - WEAPONTYPE_WATER, - WEAPONTYPE_FALL_DAMAGE, + WEAPONTYPE_DROWNING, + WEAPONTYPE_FALL, WEAPONTYPE_UNIDENTIFIED, + + WEAPONTYPE_TOTALWEAPONS = WEAPONTYPE_LAST_WEAPONTYPE, + WEAPONTYPE_TOTAL_INVENTORY_WEAPONS = 13, }; enum eWeaponFire { @@ -63,6 +65,7 @@ public: m_bAddRotOffset = false; } + static void ShutdownWeapons(void); void Initialise(eWeaponType type, int ammo); void Update(int32 audioEntity); void Reload(void); @@ -78,3 +81,5 @@ public: static void UpdateWeapons(void); }; static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error"); + +void FireOneInstantHitRound(CVector* shotSource, CVector* shotTarget, int32 damage);
\ No newline at end of file diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp index 6884d347..a4a1a085 100644 --- a/src/weapons/WeaponInfo.cpp +++ b/src/weapons/WeaponInfo.cpp @@ -3,7 +3,9 @@ #include "main.h" #include "FileMgr.h" #include "WeaponInfo.h" +#include "AnimManager.h" #include "AnimBlendAssociation.h" +#include "Weapon.h" //CWeaponInfo (&CWeaponInfo::ms_apWeaponInfos)[14] = * (CWeaponInfo(*)[14]) * (uintptr*)0x6503EC; CWeaponInfo CWeaponInfo::ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS]; diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h index faa8bf7b..e2e71d23 100644 --- a/src/weapons/WeaponInfo.h +++ b/src/weapons/WeaponInfo.h @@ -1,7 +1,8 @@ #pragma once -#include "common.h" -#include "Weapon.h" -#include "AnimManager.h" + +enum AnimationId; +enum eWeaponFire; +enum eWeaponType; class CWeaponInfo { // static CWeaponInfo(&ms_apWeaponInfos)[14]; |