summaryrefslogtreecommitdiffstats
path: root/src/weapons
diff options
context:
space:
mode:
Diffstat (limited to 'src/weapons')
-rw-r--r--src/weapons/Weapon.h6
-rw-r--r--src/weapons/WeaponInfo.cpp202
-rw-r--r--src/weapons/WeaponInfo.h9
3 files changed, 212 insertions, 5 deletions
diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h
index 87134929..6009a549 100644
--- a/src/weapons/Weapon.h
+++ b/src/weapons/Weapon.h
@@ -16,7 +16,9 @@ enum eWeaponType
WEAPONTYPE_MOLOTOV,
WEAPONTYPE_GRENADE,
WEAPONTYPE_DETONATOR,
- WEAPONTYPE_HELICANNON
+ NUM_PED_WEAPONTYPES = 13,
+ WEAPONTYPE_HELICANNON = 13,
+ NUM_WEAPONTYPES
};
enum eWeaponFire {
@@ -48,6 +50,6 @@ public:
bool m_bAddRotOffset;
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");
diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp
index 155425b5..46ecfb54 100644
--- a/src/weapons/WeaponInfo.cpp
+++ b/src/weapons/WeaponInfo.cpp
@@ -1,14 +1,214 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
+#include "FileMgr.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::GetWeaponInfo(eWeaponType 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
+ InjectHook(0x564EA0, &CWeaponInfo::Initialise, 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 \ No newline at end of file
diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h
index 34790565..faa8bf7b 100644
--- a/src/weapons/WeaponInfo.h
+++ b/src/weapons/WeaponInfo.h
@@ -4,6 +4,8 @@
#include "AnimManager.h"
class CWeaponInfo {
+// static CWeaponInfo(&ms_apWeaponInfos)[14];
+ static CWeaponInfo ms_apWeaponInfos[14];
public:
eWeaponFire m_eWeaponFire;
float m_fRange;
@@ -37,9 +39,12 @@ public:
uint8 m_bThrow : 1;
uint8 stuff;
- static CWeaponInfo (&ms_apWeaponInfos)[14];
-
+ static void Initialise(void);
+ static void LoadWeaponData(void);
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"); \ No newline at end of file