summaryrefslogtreecommitdiffstats
path: root/src/weapons
diff options
context:
space:
mode:
Diffstat (limited to 'src/weapons')
-rw-r--r--src/weapons/Explosion.cpp2
-rw-r--r--src/weapons/ShotInfo.cpp140
-rw-r--r--src/weapons/ShotInfo.h23
-rw-r--r--src/weapons/Weapon.cpp1
-rw-r--r--src/weapons/Weapon.h13
5 files changed, 172 insertions, 7 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..09844c23 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); }
diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h
index 1db66720..74145564 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);