mirror of
https://gitlab.com/GaryOderNichts/re3-wiiu.git
synced 2024-12-23 08:11:49 +01:00
commit
3271467976
@ -40,6 +40,48 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float LimitRadianAngle(float angle)
|
||||||
|
{
|
||||||
|
if (angle < -25.0f)
|
||||||
|
angle = -25.0f;
|
||||||
|
|
||||||
|
if (angle > 25.0f)
|
||||||
|
angle = 25.0f;
|
||||||
|
|
||||||
|
float result = angle;
|
||||||
|
|
||||||
|
while (result >= PI) {
|
||||||
|
result -= 2 * PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (result < -PI) {
|
||||||
|
result += 2 * PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float GetRadianAngleBetweenPoints(float x1, float y1, float x2, float y2)
|
||||||
|
{
|
||||||
|
float x = x2 - x1;
|
||||||
|
float y = y2 - y1;
|
||||||
|
|
||||||
|
if (y == 0.0f)
|
||||||
|
y = 0.0001f;
|
||||||
|
|
||||||
|
if (x > 0.0f) {
|
||||||
|
if (y > 0.0f)
|
||||||
|
return 2 * PI - atan2(x / y, 1.0f);
|
||||||
|
else
|
||||||
|
return -atan2(x / y, 1.0f);
|
||||||
|
} else {
|
||||||
|
if (y > 0.0f)
|
||||||
|
return -(PI + atan2(x / y, 1.0f));
|
||||||
|
else
|
||||||
|
return -atan2(x / y, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// not too sure about all these...
|
// not too sure about all these...
|
||||||
static uint16 GetRandomNumber(void)
|
static uint16 GetRandomNumber(void)
|
||||||
{ return myrand() & 0xFFFF; }
|
{ return myrand() & 0xFFFF; }
|
||||||
|
@ -208,6 +208,8 @@ enum AnimationId
|
|||||||
ANIM_PHONE_IN,
|
ANIM_PHONE_IN,
|
||||||
ANIM_PHONE_OUT,
|
ANIM_PHONE_OUT,
|
||||||
ANIM_PHONE_TALK,
|
ANIM_PHONE_TALK,
|
||||||
|
|
||||||
|
NUM_ANIMS
|
||||||
};
|
};
|
||||||
|
|
||||||
class CAnimBlendAssociation;
|
class CAnimBlendAssociation;
|
||||||
|
@ -17,3 +17,4 @@ WRAPPER bool cDMAudio::CheckForAnAudioFileOnCD() { EAXJMP(0x57CA70); }
|
|||||||
WRAPPER void cDMAudio::ChangeMusicMode(uint8 mode) { EAXJMP(0x57CCF0); }
|
WRAPPER void cDMAudio::ChangeMusicMode(uint8 mode) { EAXJMP(0x57CCF0); }
|
||||||
|
|
||||||
WRAPPER void cDMAudio::PlayFrontEndSound(uint32, uint32) { EAXJMP(0x57CC20); }
|
WRAPPER void cDMAudio::PlayFrontEndSound(uint32, uint32) { EAXJMP(0x57CC20); }
|
||||||
|
WRAPPER void cDMAudio::PlayOneShot(int, uint16, float) { EAXJMP(0x57C840); }
|
||||||
|
@ -51,9 +51,9 @@ enum eSound
|
|||||||
SOUND_WEAPON_BAT_ATTACK = 46,
|
SOUND_WEAPON_BAT_ATTACK = 46,
|
||||||
SOUND_WEAPON_SHOT_FIRED = 47,
|
SOUND_WEAPON_SHOT_FIRED = 47,
|
||||||
SOUND_WEAPON_RELOAD = 48,
|
SOUND_WEAPON_RELOAD = 48,
|
||||||
SOUND_31 = 49,
|
SOUND_WEAPON_AK47_BULLET_ECHO = 49,
|
||||||
SOUND_32 = 50,
|
SOUND_WEAPON_UZI_BULLET_ECHO = 50,
|
||||||
SOUND_33 = 51,
|
SOUND_WEAPON_M16_BULLET_ECHO = 51,
|
||||||
SOUND_WEAPON_FLAMETHROWER_FIRE = 52,
|
SOUND_WEAPON_FLAMETHROWER_FIRE = 52,
|
||||||
SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM = 53,
|
SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM = 53,
|
||||||
SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM = 54,
|
SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM = 54,
|
||||||
@ -188,5 +188,6 @@ public:
|
|||||||
bool CheckForAnAudioFileOnCD(void);
|
bool CheckForAnAudioFileOnCD(void);
|
||||||
void ChangeMusicMode(uint8 mode);
|
void ChangeMusicMode(uint8 mode);
|
||||||
void PlayFrontEndSound(uint32, uint32);
|
void PlayFrontEndSound(uint32, uint32);
|
||||||
|
void PlayOneShot(int, uint16, float);
|
||||||
};
|
};
|
||||||
extern cDMAudio &DMAudio;
|
extern cDMAudio &DMAudio;
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
#include "Stats.h"
|
#include "Stats.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "DMaudio.h"
|
#include "DMaudio.h"
|
||||||
|
#include "RpAnimBlend.h"
|
||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
#include "PedType.h"
|
#include "PlayerPed.h"
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
|
|
||||||
bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
|
bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
|
||||||
@ -20,6 +21,10 @@ WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC43
|
|||||||
WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); }
|
WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); }
|
||||||
WRAPPER void CPed::SetDie(AnimationId anim, float arg1, float arg2) { EAXJMP(0x4D37D0); }
|
WRAPPER void CPed::SetDie(AnimationId anim, float arg1, float arg2) { EAXJMP(0x4D37D0); }
|
||||||
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::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",
|
||||||
@ -176,6 +181,97 @@ static char WaitStateText[21][16] = {
|
|||||||
"Finish Flee",
|
"Finish Flee",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PedOnGroundState
|
||||||
|
CheckForPedsOnGroundToAttack(CPlayerPed *player, CPed **pedOnGround)
|
||||||
|
{
|
||||||
|
PedOnGroundState stateToReturn;
|
||||||
|
float angleToFace;
|
||||||
|
CPed *currentPed = nil;
|
||||||
|
PedState currentPedState;
|
||||||
|
CPed *pedOnTheFloor = nil;
|
||||||
|
CPed *deadPed = nil;
|
||||||
|
CPed *pedBelow = nil;
|
||||||
|
bool foundDead = false;
|
||||||
|
bool foundOnTheFloor = false;
|
||||||
|
bool foundBelow = false;
|
||||||
|
float angleDiff;
|
||||||
|
float distance;
|
||||||
|
|
||||||
|
if (!CGame::nastyGame)
|
||||||
|
return NO_PED;
|
||||||
|
|
||||||
|
for (int currentPedId = 0; currentPedId < player->m_numNearPeds; currentPedId++) {
|
||||||
|
|
||||||
|
currentPed = player->m_nearPeds[currentPedId];
|
||||||
|
|
||||||
|
CVector posDifference = currentPed->GetPosition() - player->GetPosition();
|
||||||
|
distance = posDifference.Magnitude();
|
||||||
|
|
||||||
|
if (distance < 2.0f) {
|
||||||
|
angleToFace = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
currentPed->GetPosition().x, currentPed->GetPosition().y,
|
||||||
|
player->GetPosition().x, player->GetPosition().y);
|
||||||
|
|
||||||
|
angleToFace = CGeneral::LimitRadianAngle(angleToFace);
|
||||||
|
player->m_fRotationCur = CGeneral::LimitRadianAngle(player->m_fRotationCur);
|
||||||
|
|
||||||
|
angleDiff = fabs(angleToFace - player->m_fRotationCur);
|
||||||
|
|
||||||
|
if (angleDiff > PI)
|
||||||
|
angleDiff = 2 * PI - angleDiff;
|
||||||
|
|
||||||
|
currentPedState = currentPed->m_nPedState;
|
||||||
|
|
||||||
|
if (currentPedState == PED_FALL || currentPedState == PED_GETUP || currentPedState == PED_DIE || currentPedState == PED_DEAD) {
|
||||||
|
if (distance < 2.0f && angleDiff < DEGTORAD(65.0f)) {
|
||||||
|
if (currentPedState == PED_DEAD) {
|
||||||
|
foundDead = 1;
|
||||||
|
if (!deadPed)
|
||||||
|
deadPed = (CPed*)currentPed;
|
||||||
|
} else if (currentPed->IsPedHeadAbovePos(-0.6f)) {
|
||||||
|
foundOnTheFloor = 1;
|
||||||
|
if (!pedOnTheFloor)
|
||||||
|
pedOnTheFloor = (CPed*)currentPed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((distance >= 0.8f || angleDiff >= DEGTORAD(75.0f))
|
||||||
|
&& (distance >= 1.3f || angleDiff >= DEGTORAD(55.0f))
|
||||||
|
&& (distance >= 1.7f || angleDiff >= DEGTORAD(35.0f))
|
||||||
|
&& (distance >= 2.0f || angleDiff >= DEGTORAD(30.0f))) {
|
||||||
|
|
||||||
|
if (angleDiff < DEGTORAD(75.0f)) {
|
||||||
|
foundBelow = 1;
|
||||||
|
if (!pedBelow)
|
||||||
|
pedBelow = (CPed*)currentPed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foundBelow = 1;
|
||||||
|
pedBelow = (CPed*)currentPed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundOnTheFloor) {
|
||||||
|
currentPed = pedOnTheFloor;
|
||||||
|
stateToReturn = PED_ON_THE_FLOOR;
|
||||||
|
} else if (foundDead) {
|
||||||
|
currentPed = deadPed;
|
||||||
|
stateToReturn = PED_DEAD_ON_THE_FLOOR;
|
||||||
|
} else if (foundBelow) {
|
||||||
|
currentPed = pedBelow;
|
||||||
|
stateToReturn = PED_BELOW_PLAYER;
|
||||||
|
} else {
|
||||||
|
currentPed = nil;
|
||||||
|
stateToReturn = NO_PED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pedOnGround)
|
||||||
|
* pedOnGround = (CPed*)currentPed;
|
||||||
|
|
||||||
|
return stateToReturn;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CPed::IsPlayer(void)
|
CPed::IsPlayer(void)
|
||||||
{
|
{
|
||||||
@ -195,7 +291,7 @@ CPed::UseGroundColModel(void)
|
|||||||
void
|
void
|
||||||
CPed::AddWeaponModel(int id)
|
CPed::AddWeaponModel(int id)
|
||||||
{
|
{
|
||||||
RpAtomic* atm;
|
RpAtomic *atm;
|
||||||
|
|
||||||
if (id != -1) {
|
if (id != -1) {
|
||||||
atm = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
|
atm = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance();
|
||||||
@ -207,14 +303,14 @@ CPed::AddWeaponModel(int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPed::AimGun()
|
CPed::AimGun(void)
|
||||||
{
|
{
|
||||||
RwV3d pos;
|
RwV3d pos;
|
||||||
CVector vector;
|
CVector vector;
|
||||||
|
|
||||||
if (m_pSeekTarget) {
|
if (m_pSeekTarget) {
|
||||||
if (m_pSeekTarget->m_status == STATUS_PHYSICS) {
|
if (m_pSeekTarget->m_status == STATUS_PHYSICS) {
|
||||||
m_pSeekTarget->m_pedIK.GetComponentPosition(&pos, 1);
|
m_pSeekTarget->m_pedIK.GetComponentPosition(&pos, PED_TORSO);
|
||||||
vector.x = pos.x;
|
vector.x = pos.x;
|
||||||
vector.y = pos.y;
|
vector.y = pos.y;
|
||||||
vector.z = pos.z;
|
vector.z = pos.z;
|
||||||
@ -254,7 +350,7 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
|
|||||||
CPed::SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
|
CPed::SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ped_flagC20 = 1;
|
m_ped_flagC20 = true;
|
||||||
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 150;
|
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 150;
|
||||||
|
|
||||||
CParticle::AddParticle(PARTICLE_TEST, pos2,
|
CParticle::AddParticle(PARTICLE_TEST, pos2,
|
||||||
@ -309,7 +405,7 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 unk)
|
|||||||
nil, 0.0f, 0, 0, 0, 0);
|
nil, 0.0f, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_ped_flagC20 = 1;
|
m_ped_flagC20 = true;
|
||||||
m_bodyPartBleeding = nodeId;
|
m_bodyPartBleeding = nodeId;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -343,7 +439,7 @@ CPed::SetLookFlag(CPed *target, bool unknown)
|
|||||||
m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget);
|
m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget);
|
||||||
m_fLookDirection = 999999.0f;
|
m_fLookDirection = 999999.0f;
|
||||||
m_lookTimer = 0;
|
m_lookTimer = 0;
|
||||||
m_ped_flagA20_look = unknown;
|
m_ped_flagA20 = unknown;
|
||||||
if (m_nPedState != PED_DRIVING) {
|
if (m_nPedState != PED_DRIVING) {
|
||||||
m_pedIK.m_flags &= ~CPedIK::FLAG_2;
|
m_pedIK.m_flags &= ~CPedIK::FLAG_2;
|
||||||
}
|
}
|
||||||
@ -359,7 +455,7 @@ CPed::SetLookFlag(float direction, bool unknown)
|
|||||||
m_pLookTarget = nil;
|
m_pLookTarget = nil;
|
||||||
m_fLookDirection = direction;
|
m_fLookDirection = direction;
|
||||||
m_lookTimer = 0;
|
m_lookTimer = 0;
|
||||||
m_ped_flagA20_look = unknown;
|
m_ped_flagA20 = unknown;
|
||||||
if (m_nPedState != PED_DRIVING) {
|
if (m_nPedState != PED_DRIVING) {
|
||||||
m_pedIK.m_flags &= ~CPedIK::FLAG_2;
|
m_pedIK.m_flags &= ~CPedIK::FLAG_2;
|
||||||
}
|
}
|
||||||
@ -444,6 +540,331 @@ CPed::Avoid(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::ClearAimFlag(void)
|
||||||
|
{
|
||||||
|
if (bIsAimingGun) {
|
||||||
|
bIsAimingGun = false;
|
||||||
|
bIsRestoringGun = true;
|
||||||
|
m_pedIK.m_flags &= ~CPedIK:: FLAG_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CPed::IsPlayer())
|
||||||
|
((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::ClearLookFlag(void) {
|
||||||
|
if (bIsLooking) {
|
||||||
|
bIsLooking = false;
|
||||||
|
bIsRestoringLook = true;
|
||||||
|
m_ped_flagI1 = false;
|
||||||
|
|
||||||
|
m_pedIK.m_flags &= ~CPedIK::FLAG_2;
|
||||||
|
if (CPed::IsPlayer())
|
||||||
|
m_lookTimer = CTimer::GetTimeInMilliseconds() + 2000;
|
||||||
|
else
|
||||||
|
m_lookTimer = CTimer::GetTimeInMilliseconds() + 4000;
|
||||||
|
|
||||||
|
if (m_nPedState == PED_LOOK_HEADING || m_nPedState == PED_LOOK_ENTITY) {
|
||||||
|
CPed::RestorePreviousState();
|
||||||
|
CPed::ClearLookFlag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPed::IsPedHeadAbovePos(float zOffset)
|
||||||
|
{
|
||||||
|
RwMatrix mat;
|
||||||
|
|
||||||
|
CPedIK::GetWorldMatrix(GetNodeFrame(PED_HEAD), &mat);
|
||||||
|
return zOffset + GetPosition().z >= mat.pos.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
|
||||||
|
{
|
||||||
|
CWeaponInfo *currentWeapon;
|
||||||
|
CAnimBlendAssociation *newAnim;
|
||||||
|
CPed *ped = (CPed*)arg;
|
||||||
|
|
||||||
|
if (attackAssoc) {
|
||||||
|
switch (attackAssoc->animId) {
|
||||||
|
case ANIM_WEAPON_START_THROW:
|
||||||
|
if ((!ped->IsPlayer() || ((CPlayerPed*)ped)->field_1376) && ped->IsPlayer())
|
||||||
|
{
|
||||||
|
attackAssoc->blendDelta = -1000.0;
|
||||||
|
newAnim = CAnimManager::AddAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_WEAPON_THROWU);
|
||||||
|
} else {
|
||||||
|
attackAssoc->blendDelta = -1000.0;
|
||||||
|
newAnim = CAnimManager::AddAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_WEAPON_THROW);
|
||||||
|
}
|
||||||
|
|
||||||
|
newAnim->SetFinishCallback(CPed::FinishedAttackCB, ped);
|
||||||
|
break;
|
||||||
|
case ANIM_FIGHT_PPUNCH:
|
||||||
|
attackAssoc->blendDelta = -8.0;
|
||||||
|
attackAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
ped->ClearAttack();
|
||||||
|
break;
|
||||||
|
case ANIM_WEAPON_THROW:
|
||||||
|
case ANIM_WEAPON_THROWU:
|
||||||
|
if (ped->GetWeapon()->m_nAmmoTotal > 0) {
|
||||||
|
currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType);
|
||||||
|
ped->AddWeaponModel(currentWeapon->m_nModelId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!ped->m_ped_flagA4)
|
||||||
|
ped->ClearAttack();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!ped->m_ped_flagA4)
|
||||||
|
ped->ClearAttack();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::Attack(void)
|
||||||
|
{
|
||||||
|
CAnimBlendAssociation *weaponAnimAssoc;
|
||||||
|
int32 weaponAnim;
|
||||||
|
float animStart;
|
||||||
|
RwFrame *f;
|
||||||
|
eWeaponType ourWeaponType;
|
||||||
|
float weaponAnimTime;
|
||||||
|
RwFrame *i;
|
||||||
|
eWeaponFire ourWeaponFire;
|
||||||
|
float animEnd;
|
||||||
|
CWeaponInfo *ourWeapon;
|
||||||
|
bool lastReloadWasInFuture;
|
||||||
|
AnimationId reloadAnim;
|
||||||
|
CAnimBlendAssociation *reloadAnimAssoc;
|
||||||
|
float delayBetweenAnimAndFire;
|
||||||
|
CVector firePos;
|
||||||
|
|
||||||
|
ourWeaponType = GetWeapon()->m_eWeaponType;
|
||||||
|
ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType);
|
||||||
|
ourWeaponFire = ourWeapon->m_eWeaponFire;
|
||||||
|
weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ourWeapon->m_AnimToPlay);
|
||||||
|
lastReloadWasInFuture = m_ped_flagA4;
|
||||||
|
reloadAnimAssoc = 0;
|
||||||
|
reloadAnim = NUM_ANIMS;
|
||||||
|
delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire;
|
||||||
|
weaponAnim = ourWeapon->m_AnimToPlay;
|
||||||
|
|
||||||
|
if (weaponAnim == ANIM_WEAPON_HGUN_BODY)
|
||||||
|
reloadAnim = ANIM_HGUN_RELOAD;
|
||||||
|
else if (weaponAnim == ANIM_WEAPON_AK_BODY)
|
||||||
|
reloadAnim = ANIM_AK_RELOAD;
|
||||||
|
|
||||||
|
if (reloadAnim != NUM_ANIMS)
|
||||||
|
reloadAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, reloadAnim);
|
||||||
|
|
||||||
|
if (m_ped_flagE10)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (reloadAnimAssoc) {
|
||||||
|
if (!CPed::IsPlayer() || ((CPlayerPed*)this)->field_1380)
|
||||||
|
CPed::ClearAttack();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BUG: We currently don't know any situation this cond. could be true.
|
||||||
|
if (CTimer::GetTimeInMilliseconds() < m_lastHitTime)
|
||||||
|
lastReloadWasInFuture = true;
|
||||||
|
|
||||||
|
if (!weaponAnimAssoc) {
|
||||||
|
if (ourWeapon->m_bThrow) {
|
||||||
|
weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_WEAPON_THROWU);
|
||||||
|
delayBetweenAnimAndFire = 0.2f;
|
||||||
|
} else {
|
||||||
|
weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ourWeapon->m_Anim2ToPlay);
|
||||||
|
delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (weaponAnimAssoc) {
|
||||||
|
animStart = ourWeapon->m_fAnimLoopStart;
|
||||||
|
weaponAnimTime = weaponAnimAssoc->currentTime;
|
||||||
|
if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
|
||||||
|
if (ourWeapon->m_bCanAimWithArm)
|
||||||
|
m_pedIK.m_flags |= CPedIK::FLAG_4;
|
||||||
|
else
|
||||||
|
m_pedIK.m_flags &= ~CPedIK::FLAG_4;
|
||||||
|
}
|
||||||
|
if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
|
||||||
|
if (weaponAnimAssoc->speed < 1.0f)
|
||||||
|
weaponAnimAssoc->speed = 1.0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
firePos = ourWeapon->m_vecFireOffset;
|
||||||
|
if (ourWeaponType == WEAPONTYPE_BASEBALLBAT) {
|
||||||
|
if (weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
|
||||||
|
firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
|
||||||
|
|
||||||
|
firePos = GetMatrix() * firePos;
|
||||||
|
} else if (ourWeaponType != WEAPONTYPE_UNARMED) {
|
||||||
|
if (weaponAnimAssoc->animId == ANIM_KICK_FLOOR)
|
||||||
|
f = GetNodeFrame(PED_FOOTR);
|
||||||
|
else
|
||||||
|
f = GetNodeFrame(PED_HANDR);
|
||||||
|
|
||||||
|
while (f) {
|
||||||
|
RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, &f->modelling);
|
||||||
|
f = RwFrameGetParent(f);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
firePos = GetMatrix() * firePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetWeapon()->Fire(this, &firePos);
|
||||||
|
|
||||||
|
if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE) {
|
||||||
|
RemoveWeaponModel(ourWeapon->m_nModelId);
|
||||||
|
}
|
||||||
|
if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
|
||||||
|
SelectGunIfArmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetWeapon()->m_eWeaponState != WEAPONSTATE_MELEE_MADECONTACT) {
|
||||||
|
// If reloading just began, start the animation
|
||||||
|
if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING && reloadAnim != NUM_ANIMS && !reloadAnimAssoc) {
|
||||||
|
CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, reloadAnim, 8.0f);
|
||||||
|
CPed::ClearLookFlag();
|
||||||
|
CPed::ClearAimFlag();
|
||||||
|
m_ped_flagA4 = false;
|
||||||
|
m_ped_flagA8 = false;
|
||||||
|
m_lastHitTime = CTimer::GetTimeInMilliseconds();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (weaponAnimAssoc->animId <= ANIM_WEAPON_BAT_V) {
|
||||||
|
DMAudio.PlayOneShot(uAudioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
|
||||||
|
} else if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH) {
|
||||||
|
DMAudio.PlayOneShot(uAudioEntityId, SOUND_WEAPON_PUNCH_ATTACK, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
weaponAnimAssoc->speed = 0.5;
|
||||||
|
|
||||||
|
// BUG: We currently don't know any situation this cond. could be true.
|
||||||
|
if (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime) {
|
||||||
|
weaponAnimAssoc->callbackType = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastReloadWasInFuture = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ourWeaponType == WEAPONTYPE_SHOTGUN) {
|
||||||
|
weaponAnimTime = weaponAnimAssoc->currentTime;
|
||||||
|
if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
|
||||||
|
for (i = GetNodeFrame(PED_HANDR); i; i = RwFrameGetParent(i))
|
||||||
|
RwV3dTransformPoints((RwV3d*)ourWeapon->m_vecFireOffset, (RwV3d*)ourWeapon->m_vecFireOffset, 1, &i->modelling);
|
||||||
|
|
||||||
|
CVector gunshellPos(
|
||||||
|
ourWeapon->m_vecFireOffset.x - 0.6f * GetForward().x,
|
||||||
|
ourWeapon->m_vecFireOffset.y - 0.6f * GetForward().y,
|
||||||
|
ourWeapon->m_vecFireOffset.z - 0.15f * GetUp().z
|
||||||
|
);
|
||||||
|
CVector2D gunshellRot(
|
||||||
|
GetRight().x,
|
||||||
|
GetRight().y
|
||||||
|
);
|
||||||
|
|
||||||
|
gunshellRot.Normalise();
|
||||||
|
CWeapon::AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
animEnd = ourWeapon->m_fAnimLoopEnd;
|
||||||
|
if (ourWeaponFire == WEAPON_FIRE_MELEE && weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
|
||||||
|
animEnd = 0.56f;
|
||||||
|
|
||||||
|
weaponAnimTime = weaponAnimAssoc->currentTime;
|
||||||
|
|
||||||
|
// End of the attack
|
||||||
|
if (weaponAnimTime > animEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) {
|
||||||
|
|
||||||
|
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)
|
||||||
|
&& GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
|
||||||
|
|
||||||
|
weaponAnim = weaponAnimAssoc->animId;
|
||||||
|
if (ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), 0) < PED_ON_THE_FLOOR) {
|
||||||
|
if (weaponAnim != ourWeapon->m_Anim2ToPlay || weaponAnim == ANIM_RBLOCK_CSHOOT) {
|
||||||
|
weaponAnimAssoc->Start(ourWeapon->m_fAnimLoopStart);
|
||||||
|
} else {
|
||||||
|
CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (weaponAnim == ourWeapon->m_Anim2ToPlay)
|
||||||
|
weaponAnimAssoc->SetCurrentTime(0.1f);
|
||||||
|
else
|
||||||
|
CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CPed::ClearAimFlag();
|
||||||
|
|
||||||
|
// Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading)
|
||||||
|
if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < ourWeapon->m_fAnimLoopEnd) {
|
||||||
|
if (ourWeaponType < WEAPONTYPE_SNIPERRIFLE) {
|
||||||
|
switch (ourWeaponType) {
|
||||||
|
case WEAPONTYPE_UZI:
|
||||||
|
DMAudio.PlayOneShot(uAudioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f);
|
||||||
|
break;
|
||||||
|
case WEAPONTYPE_AK47:
|
||||||
|
DMAudio.PlayOneShot(uAudioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
|
||||||
|
break;
|
||||||
|
case WEAPONTYPE_M16:
|
||||||
|
DMAudio.PlayOneShot(uAudioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fun fact: removing this part leds to reloading flamethrower
|
||||||
|
if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
|
||||||
|
weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
|
||||||
|
weaponAnimAssoc->blendDelta = -4.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire)
|
||||||
|
lastReloadWasInFuture = false;
|
||||||
|
|
||||||
|
m_ped_flagA4 = lastReloadWasInFuture;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastReloadWasInFuture) {
|
||||||
|
if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !CPed::IsPlayer() || ((CPlayerPed*)this)->field_1380) {
|
||||||
|
if (!CGame::nastyGame || ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), 0) < PED_ON_THE_FLOOR) {
|
||||||
|
weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
|
||||||
|
} else {
|
||||||
|
weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
weaponAnimAssoc->SetFinishCallback(CPed::FinishedAttackCB, this);
|
||||||
|
weaponAnimAssoc->flags |= ASSOC_RUNNING;
|
||||||
|
|
||||||
|
if (weaponAnimAssoc->currentTime == weaponAnimAssoc->hierarchy->totalLength)
|
||||||
|
weaponAnimAssoc->SetCurrentTime(0.0f);
|
||||||
|
|
||||||
|
if (CPed::IsPlayer()) {
|
||||||
|
((CPlayerPed*)this)->field_1376 = 0.0f;
|
||||||
|
((CPlayerPed*)this)->field_1380 = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CPed::FinishedAttackCB(0, this);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -454,4 +875,10 @@ STARTPATCHES
|
|||||||
InjectHook(0x4D12E0, &CPed::SetLookTimer, PATCH_JUMP);
|
InjectHook(0x4D12E0, &CPed::SetLookTimer, PATCH_JUMP);
|
||||||
InjectHook(0x4C5700, &CPed::OurPedCanSeeThisOne, PATCH_JUMP);
|
InjectHook(0x4C5700, &CPed::OurPedCanSeeThisOne, PATCH_JUMP);
|
||||||
InjectHook(0x4D2BB0, &CPed::Avoid, PATCH_JUMP);
|
InjectHook(0x4D2BB0, &CPed::Avoid, PATCH_JUMP);
|
||||||
|
InjectHook(0x4C6A50, &CPed::ClearAimFlag, PATCH_JUMP);
|
||||||
|
InjectHook(0x4C64F0, &CPed::ClearLookFlag, PATCH_JUMP);
|
||||||
|
InjectHook(0x4E5BD0, &CPed::IsPedHeadAbovePos, PATCH_JUMP);
|
||||||
|
InjectHook(0x4E68A0, &CPed::FinishedAttackCB, PATCH_JUMP);
|
||||||
|
InjectHook(0x4E5BD0, &CheckForPedsOnGroundToAttack, PATCH_JUMP);
|
||||||
|
InjectHook(0x4E6BA0, &CPed::Attack, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
#include "Physical.h"
|
#include "Physical.h"
|
||||||
#include "Weapon.h"
|
#include "Weapon.h"
|
||||||
#include "PedIK.h"
|
|
||||||
#include "PedStats.h"
|
#include "PedStats.h"
|
||||||
|
#include "PedType.h"
|
||||||
|
#include "PedIK.h"
|
||||||
#include "AnimManager.h"
|
#include "AnimManager.h"
|
||||||
#include "AnimBlendClumpData.h"
|
#include "AnimBlendClumpData.h"
|
||||||
|
#include "AnimBlendAssociation.h"
|
||||||
|
#include "WeaponInfo.h"
|
||||||
|
|
||||||
struct CPathNode;
|
struct CPathNode;
|
||||||
|
|
||||||
@ -13,6 +16,13 @@ enum {
|
|||||||
PED_MAX_WEAPONS = 13
|
PED_MAX_WEAPONS = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PedOnGroundState {
|
||||||
|
NO_PED,
|
||||||
|
PED_BELOW_PLAYER,
|
||||||
|
PED_ON_THE_FLOOR,
|
||||||
|
PED_DEAD_ON_THE_FLOOR
|
||||||
|
};
|
||||||
|
|
||||||
enum PedState
|
enum PedState
|
||||||
{
|
{
|
||||||
PED_NONE,
|
PED_NONE,
|
||||||
@ -98,7 +108,7 @@ public:
|
|||||||
uint8 m_ped_flagA4 : 1; // stores (CTimer::GetTimeInMilliseconds() < m_lastHitTime)
|
uint8 m_ped_flagA4 : 1; // stores (CTimer::GetTimeInMilliseconds() < m_lastHitTime)
|
||||||
uint8 m_ped_flagA8 : 1;
|
uint8 m_ped_flagA8 : 1;
|
||||||
uint8 bIsLooking : 1;
|
uint8 bIsLooking : 1;
|
||||||
uint8 m_ped_flagA20_look : 1; // probably missing in SA
|
uint8 m_ped_flagA20 : 1; // "look" method? - probably missing in SA
|
||||||
uint8 bIsRestoringLook : 1;
|
uint8 bIsRestoringLook : 1;
|
||||||
uint8 bIsAimingGun : 1;
|
uint8 bIsAimingGun : 1;
|
||||||
uint8 bIsRestoringGun : 1;
|
uint8 bIsRestoringGun : 1;
|
||||||
@ -178,7 +188,7 @@ public:
|
|||||||
CPedIK m_pedIK;
|
CPedIK m_pedIK;
|
||||||
uint8 stuff1[8];
|
uint8 stuff1[8];
|
||||||
uint32 m_nPedStateTimer;
|
uint32 m_nPedStateTimer;
|
||||||
int32 m_nPedState;
|
PedState m_nPedState;
|
||||||
int32 m_nLastPedState;
|
int32 m_nLastPedState;
|
||||||
int32 m_nMoveState;
|
int32 m_nMoveState;
|
||||||
int32 m_nStoredActionState;
|
int32 m_nStoredActionState;
|
||||||
@ -206,7 +216,7 @@ public:
|
|||||||
CVector m_vecOffsetFromPhysSurface;
|
CVector m_vecOffsetFromPhysSurface;
|
||||||
CEntity *m_pCurSurface;
|
CEntity *m_pCurSurface;
|
||||||
uint8 stuff3[12];
|
uint8 stuff3[12];
|
||||||
CPed* m_pSeekTarget;
|
CPed *m_pSeekTarget;
|
||||||
CVehicle *m_pMyVehicle;
|
CVehicle *m_pMyVehicle;
|
||||||
bool bInVehicle;
|
bool bInVehicle;
|
||||||
uint8 stuff4[23];
|
uint8 stuff4[23];
|
||||||
@ -235,7 +245,8 @@ public:
|
|||||||
uint8 m_bodyPartBleeding;
|
uint8 m_bodyPartBleeding;
|
||||||
uint8 m_field_4F3;
|
uint8 m_field_4F3;
|
||||||
CPed *m_nearPeds[10];
|
CPed *m_nearPeds[10];
|
||||||
uint8 stuff11[32];
|
uint16 m_numNearPeds;
|
||||||
|
uint8 stuff11[30];
|
||||||
|
|
||||||
static void *operator new(size_t);
|
static void *operator new(size_t);
|
||||||
static void operator delete(void*, size_t);
|
static void operator delete(void*, size_t);
|
||||||
@ -243,7 +254,7 @@ public:
|
|||||||
bool IsPlayer(void);
|
bool IsPlayer(void);
|
||||||
bool UseGroundColModel(void);
|
bool UseGroundColModel(void);
|
||||||
void AddWeaponModel(int id);
|
void AddWeaponModel(int id);
|
||||||
void AimGun();
|
void AimGun(void);
|
||||||
void KillPedWithCar(CVehicle *veh, float impulse);
|
void KillPedWithCar(CVehicle *veh, float impulse);
|
||||||
void Say(uint16 audio);
|
void Say(uint16 audio);
|
||||||
void SetLookFlag(CPed *target, bool unknown);
|
void SetLookFlag(CPed *target, bool unknown);
|
||||||
@ -255,8 +266,17 @@ public:
|
|||||||
void SpawnFlyingComponent(int, int8 unknown);
|
void SpawnFlyingComponent(int, int8 unknown);
|
||||||
bool OurPedCanSeeThisOne(CEntity *target);
|
bool OurPedCanSeeThisOne(CEntity *target);
|
||||||
void Avoid(void);
|
void Avoid(void);
|
||||||
|
void Attack(void);
|
||||||
|
void ClearAimFlag(void);
|
||||||
|
void ClearLookFlag(void);
|
||||||
|
void RestorePreviousState(void);
|
||||||
|
void ClearAttack(void);
|
||||||
|
bool IsPedHeadAbovePos(float zOffset);
|
||||||
|
void RemoveWeaponModel(int);
|
||||||
|
void SelectGunIfArmed(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);
|
||||||
|
|
||||||
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; }
|
||||||
@ -265,6 +285,7 @@ public:
|
|||||||
static bool &bPedCheat2;
|
static bool &bPedCheat2;
|
||||||
static bool &bPedCheat3;
|
static bool &bPedCheat3;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
|
static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
|
static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
|
static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
|
||||||
|
@ -1,7 +1,39 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
|
#include "PedIK.h"
|
||||||
#include "Ped.h"
|
#include "Ped.h"
|
||||||
|
|
||||||
WRAPPER void CPedIK::GetComponentPosition(RwV3d* pos, int id) { EAXJMP(0x4ED0F0); }
|
|
||||||
WRAPPER bool CPedIK::PointGunInDirection(float phi, float theta) { EAXJMP(0x4ED9B0); }
|
WRAPPER bool CPedIK::PointGunInDirection(float phi, float theta) { EAXJMP(0x4ED9B0); }
|
||||||
WRAPPER bool CPedIK::PointGunAtPosition(CVector* position) { EAXJMP(0x4ED920); }
|
WRAPPER bool CPedIK::PointGunAtPosition(CVector *position) { EAXJMP(0x4ED920); }
|
||||||
|
|
||||||
|
void
|
||||||
|
CPedIK::GetComponentPosition(RwV3d *pos, PedNode node)
|
||||||
|
{
|
||||||
|
RwFrame *f;
|
||||||
|
RwMatrix *mat;
|
||||||
|
|
||||||
|
f = m_ped->GetNodeFrame(node);
|
||||||
|
mat = &f->modelling;
|
||||||
|
*pos = mat->pos;
|
||||||
|
|
||||||
|
for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f))
|
||||||
|
RwV3dTransformPoints(pos, pos, 1, &f->modelling);
|
||||||
|
}
|
||||||
|
|
||||||
|
RwMatrix*
|
||||||
|
CPedIK::GetWorldMatrix(RwFrame *source, RwMatrix *destination)
|
||||||
|
{
|
||||||
|
RwFrame *i;
|
||||||
|
|
||||||
|
*destination = source->modelling;
|
||||||
|
|
||||||
|
for (i = RwFrameGetParent(source); i; i = RwFrameGetParent(i))
|
||||||
|
RwMatrixTransform(destination, &i->modelling, rwCOMBINEPOSTCONCAT);
|
||||||
|
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x4ED0F0, &CPedIK::GetComponentPosition, PATCH_JUMP);
|
||||||
|
InjectHook(0x4ED060, &CPedIK::GetWorldMatrix, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "PedModelInfo.h"
|
||||||
|
|
||||||
struct LimbOrientation
|
struct LimbOrientation
|
||||||
{
|
{
|
||||||
@ -14,20 +15,21 @@ class CPedIK
|
|||||||
public:
|
public:
|
||||||
// TODO
|
// TODO
|
||||||
enum {
|
enum {
|
||||||
FLAG_1,
|
FLAG_1 = 1,
|
||||||
FLAG_2,
|
FLAG_2 = 2, // related to looking somewhere
|
||||||
FLAG_4, // aims with arm
|
FLAG_4 = 4, // aims with arm
|
||||||
};
|
};
|
||||||
|
|
||||||
CPed* m_ped;
|
CPed *m_ped;
|
||||||
LimbOrientation m_headOrient;
|
LimbOrientation m_headOrient;
|
||||||
LimbOrientation m_torsoOrient;
|
LimbOrientation m_torsoOrient;
|
||||||
LimbOrientation m_upperArmOrient;
|
LimbOrientation m_upperArmOrient;
|
||||||
LimbOrientation m_lowerArmOrient;
|
LimbOrientation m_lowerArmOrient;
|
||||||
int32 m_flags;
|
int32 m_flags;
|
||||||
|
|
||||||
void GetComponentPosition(RwV3d* pos, int id);
|
|
||||||
bool PointGunInDirection(float phi, float theta);
|
bool PointGunInDirection(float phi, float theta);
|
||||||
bool PointGunAtPosition(CVector* position);
|
bool PointGunAtPosition(CVector *position);
|
||||||
|
void GetComponentPosition(RwV3d *pos, PedNode node);
|
||||||
|
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CPedIK) == 0x28, "CPedIK: error");
|
static_assert(sizeof(CPedIK) == 0x28, "CPedIK: error");
|
||||||
|
@ -2,3 +2,5 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "Weapon.h"
|
#include "Weapon.h"
|
||||||
|
|
||||||
|
WRAPPER bool CWeapon::Fire(CEntity*, CVector*) { EAXJMP(0x55C380); }
|
||||||
|
WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, float) { EAXJMP(0x55F770); }
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
enum eWeaponType
|
enum eWeaponType
|
||||||
{
|
{
|
||||||
@ -18,14 +19,35 @@ enum eWeaponType
|
|||||||
WEAPONTYPE_HELICANNON
|
WEAPONTYPE_HELICANNON
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eWeaponFire {
|
||||||
|
WEAPON_FIRE_MELEE,
|
||||||
|
WEAPON_FIRE_INSTANT_HIT,
|
||||||
|
WEAPON_FIRE_PROJECTILE,
|
||||||
|
WEAPON_FIRE_AREA_EFFECT,
|
||||||
|
WEAPON_FIRE_USE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Taken from MTA SA, seems it's unchanged
|
||||||
|
enum eWeaponState
|
||||||
|
{
|
||||||
|
WEAPONSTATE_READY,
|
||||||
|
WEAPONSTATE_FIRING,
|
||||||
|
WEAPONSTATE_RELOADING,
|
||||||
|
WEAPONSTATE_OUT_OF_AMMO,
|
||||||
|
WEAPONSTATE_MELEE_MADECONTACT
|
||||||
|
};
|
||||||
|
|
||||||
class CWeapon
|
class CWeapon
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
eWeaponType m_eWeaponType;
|
eWeaponType m_eWeaponType;
|
||||||
int32 m_eWeaponState;
|
eWeaponState m_eWeaponState;
|
||||||
int32 m_nAmmoInClip;
|
int32 m_nAmmoInClip;
|
||||||
int32 m_nAmmoTotal;
|
int32 m_nAmmoTotal;
|
||||||
int32 m_nTimer;
|
int32 m_nTimer;
|
||||||
bool m_bAddRotOffset;
|
bool m_bAddRotOffset;
|
||||||
|
|
||||||
|
bool Fire(CEntity*, CVector*);
|
||||||
|
static void AddGunshell(CEntity*, CVector const&, CVector2D const&, float);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");
|
||||||
|
14
src/weapons/WeaponInfo.cpp
Normal file
14
src/weapons/WeaponInfo.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "WeaponInfo.h"
|
||||||
|
|
||||||
|
CWeaponInfo (&CWeaponInfo::ms_apWeaponInfos)[14] = * (CWeaponInfo(*)[14]) * (uintptr*)0x6503EC;
|
||||||
|
|
||||||
|
CWeaponInfo*
|
||||||
|
CWeaponInfo::GetWeaponInfo(eWeaponType weaponType) {
|
||||||
|
return &CWeaponInfo::ms_apWeaponInfos[weaponType];
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x564FD0, &CWeaponInfo::GetWeaponInfo, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
45
src/weapons/WeaponInfo.h
Normal file
45
src/weapons/WeaponInfo.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
#include "Weapon.h"
|
||||||
|
#include "AnimManager.h"
|
||||||
|
|
||||||
|
class CWeaponInfo {
|
||||||
|
public:
|
||||||
|
eWeaponFire m_eWeaponFire;
|
||||||
|
float m_fRange;
|
||||||
|
uint32 m_nFiringRate;
|
||||||
|
uint32 m_nReload;
|
||||||
|
uint32 m_nAmountofAmmunition;
|
||||||
|
uint32 m_nDamage;
|
||||||
|
float m_fSpeed;
|
||||||
|
float m_fRadius;
|
||||||
|
float m_fLifespan;
|
||||||
|
float m_fSpread;
|
||||||
|
CVector m_vecFireOffset;
|
||||||
|
AnimationId m_AnimToPlay;
|
||||||
|
AnimationId m_Anim2ToPlay;
|
||||||
|
float m_fAnimLoopStart;
|
||||||
|
float m_fAnimLoopEnd;
|
||||||
|
float m_fAnimFrameFire;
|
||||||
|
float m_fAnim2FrameFire;
|
||||||
|
int32 m_nModelId;
|
||||||
|
// flags
|
||||||
|
uint8 m_bUseGravity : 1;
|
||||||
|
uint8 m_bSlowsDown : 1;
|
||||||
|
uint8 m_bDissipates : 1;
|
||||||
|
uint8 m_bRandSpeed : 1;
|
||||||
|
uint8 m_bExpands : 1;
|
||||||
|
uint8 m_bExplodes : 1;
|
||||||
|
uint8 m_bCanAim : 1;
|
||||||
|
uint8 m_bCanAimWithArm : 1;
|
||||||
|
uint8 m_b1stPerson : 1;
|
||||||
|
uint8 m_bHeavy : 1;
|
||||||
|
uint8 m_bThrow : 1;
|
||||||
|
uint8 stuff;
|
||||||
|
|
||||||
|
static CWeaponInfo (&ms_apWeaponInfos)[14];
|
||||||
|
|
||||||
|
static CWeaponInfo *GetWeaponInfo(eWeaponType weaponType);
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(CWeaponInfo) == 0x54, "CWeaponInfo: error");
|
Loading…
Reference in New Issue
Block a user