diff options
Diffstat (limited to 'src/weapons')
-rw-r--r-- | src/weapons/Weapon.h | 6 | ||||
-rw-r--r-- | src/weapons/WeaponInfo.cpp | 202 | ||||
-rw-r--r-- | src/weapons/WeaponInfo.h | 9 |
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 |