diff options
author | eray orçunus <erayorcunus@gmail.com> | 2019-07-28 19:39:39 +0200 |
---|---|---|
committer | eray orçunus <erayorcunus@gmail.com> | 2019-07-28 19:39:39 +0200 |
commit | 8102ace7b67dcf8d511a708072f6f032120df949 (patch) | |
tree | f0fc7f6609f95d20ddbbdf89ea856f052dd51f35 /src/peds/Ped.cpp | |
parent | Merge pull request #170 from Nick007J/master (diff) | |
download | re3-8102ace7b67dcf8d511a708072f6f032120df949.tar re3-8102ace7b67dcf8d511a708072f6f032120df949.tar.gz re3-8102ace7b67dcf8d511a708072f6f032120df949.tar.bz2 re3-8102ace7b67dcf8d511a708072f6f032120df949.tar.lz re3-8102ace7b67dcf8d511a708072f6f032120df949.tar.xz re3-8102ace7b67dcf8d511a708072f6f032120df949.tar.zst re3-8102ace7b67dcf8d511a708072f6f032120df949.zip |
Diffstat (limited to 'src/peds/Ped.cpp')
-rw-r--r-- | src/peds/Ped.cpp | 323 |
1 files changed, 312 insertions, 11 deletions
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 1e3b7394..0728777b 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -5,7 +5,6 @@ #include "Particle.h" #include "Stats.h" #include "World.h" -#include "DMAudio.h" #include "RpAnimBlend.h" #include "Ped.h" #include "PlayerPed.h" @@ -33,7 +32,6 @@ #include "TempColModels.h" WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); } -WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); } WRAPPER void CPed::SetDead(void) { EAXJMP(0x4D3970); } WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); } WRAPPER void CPed::SetPedPositionInCar(void) { EAXJMP(0x4D4970); } @@ -50,14 +48,16 @@ WRAPPER void CPed::SetSeek(CVector, float) { EAXJMP(0x4D14B0); } WRAPPER bool CPed::Seek(void) { EAXJMP(0x4D1640); } WRAPPER void CPed::SetFollowPath(CVector) { EAXJMP(0x4D2EA0); } WRAPPER void CPed::RemoveInCarAnims(void) { EAXJMP(0x4E4E20); } -WRAPPER void CPed::SetWaitState(eWaitState, void*) { EAXJMP(0x4D58D0); } WRAPPER void CPed::StartFightDefend(uint8, uint8, uint8) { EAXJMP(0x4E7780); } -WRAPPER void CPed::PlayHitSound(CPed*) { EAXJMP(0x4E8E20); } bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44; bool &CPed::bPedCheat2 = *(bool*)0x95CD5A; bool &CPed::bPedCheat3 = *(bool*)0x95CD59; + CColPoint &CPed::ms_tempColPoint = *(CColPoint*)0x62DB14; + +CPedAudioData (&CPed::PedAudioData)[38] = *(CPedAudioData(*)[38]) * (uintptr*)0x5F94C4; + uint16 &CPed::unknownFightThing = *(uint16*)0x95CC58; FightMove (&CPed::ms_fightMoves)[24] = * (FightMove(*)[24]) * (uintptr*)0x5F9844; @@ -287,10 +287,10 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_fHealth = 100.0f; m_fArmour = 0.0f; m_nPedType = pedType; - field_520 = 0; + m_currentSoundStart = 0; m_talkTimer = 0; - m_talkTypeLast = 167; - m_talkType = 167; + m_lastQueuedSound = SOUND_TOTAL_PED_SOUNDS; + m_queuedSound = SOUND_TOTAL_PED_SOUNDS; m_objective = OBJECTIVE_NONE; m_prevObjective = OBJECTIVE_NONE; CharCreatedBy = RANDOM_CHAR; @@ -401,7 +401,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_ped_flagD4 = false; m_ped_flagD8 = false; bIsPedDieAnimPlaying = false; - m_ped_flagD20 = false; + bIsFleeing = false; m_ped_flagD40 = false; bScriptObjectiveCompleted = false; @@ -1137,7 +1137,7 @@ CPed::Attack(void) if (weaponAnimAssoc->animId == ANIM_WEAPON_BAT_V || weaponAnimAssoc->animId == ANIM_WEAPON_BAT_H) { DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f); } else if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_PUNCH_ATTACK, 0.0f); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f); } weaponAnimAssoc->speed = 0.5f; @@ -2471,7 +2471,7 @@ CPed::SetObjective(eObjective newObj, void *entity) case OBJECTIVE_KILL_CHAR_ANY_MEANS: case OBJECTIVE_MUG_CHAR: m_pLastPathNode = nil; - m_ped_flagD20 = false; + bIsFleeing = false; m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f); m_pedInObjective = (CPed*)entity; m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective); @@ -3659,7 +3659,7 @@ void CPed::ClearFlee(void) { RestorePreviousState(); - m_ped_flagD20 = false; + bIsFleeing = false; m_standardTimer = 0; m_fleeTimer = 0; } @@ -4748,6 +4748,302 @@ CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl) bIsFell = true; } +void +CPed::SetFlee(CEntity* fleeFrom, int time) +{ + if (!IsPedInControl() || bKindaStayInSamePlace || !fleeFrom) + return; + + SetStoredState(); + m_nPedState = PED_FLEE_ENTITY; + bIsFleeing = true; + SetMoveState(PEDMOVE_RUN); + m_fleeFrom = fleeFrom; + m_fleeFrom->RegisterReference((CEntity **) &m_fleeFrom); + + if (time <= 0) + m_fleeTimer = 0; + else + m_fleeTimer = CTimer::GetTimeInMilliseconds() + time; + + float angleToFace = CGeneral::GetRadianAngleBetweenPoints( + GetPosition().x, GetPosition().y, + fleeFrom->GetPosition().x, fleeFrom->GetPosition().y); + + m_fRotationDest = CGeneral::LimitRadianAngle(angleToFace); + if (m_fRotationCur - PI > m_fRotationDest) { + m_fRotationDest += 2 * PI; + } else if (PI + m_fRotationCur < m_fRotationDest) { + m_fRotationDest -= 2 * PI; + } +} + +void +CPed::SetFlee(CVector2D &from, int time) +{ + if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer || !IsPedInControl() || bKindaStayInSamePlace) + return; + + if (m_nPedState != PED_FLEE_ENTITY) { + SetStoredState(); + m_nPedState = PED_FLEE_POS; + SetMoveState(PEDMOVE_RUN); + m_fleeFromPosX = from.x; + m_fleeFromPosY = from.y; + } + + bIsFleeing = true; + m_pLastPathNode = nil; + m_fleeTimer = CTimer::GetTimeInMilliseconds() + time; + + float angleToFace = CGeneral::GetRadianAngleBetweenPoints( + GetPosition().x, GetPosition().y, + from.x, from.y); + + m_fRotationDest = CGeneral::LimitRadianAngle(angleToFace); + if (m_fRotationCur - PI > m_fRotationDest) { + m_fRotationDest += 2 * PI; + } else if (PI + m_fRotationCur < m_fRotationDest) { + m_fRotationDest -= 2 * PI; + } +} + +void +CPed::SetWaitState(eWaitState state, void *time) +{ + AnimationId waitAnim = NUM_ANIMS; + CAnimBlendAssociation *animAssoc; + + if (!IsPedInControl()) + return; + + if (state != m_nWaitState) + FinishedWaitCB(nil, this); + + switch (state) { + case WAITSTATE_TRAFFIC_LIGHTS: + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500; + SetMoveState(PEDMOVE_STILL); + break; + case WAITSTATE_CROSS_ROAD: + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 1000; + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 3000.0f); + break; + case WAITSTATE_CROSS_ROAD_LOOK: + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 8.0f); + + if (time) + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; + else + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2000,5000); + + break; + case WAITSTATE_LOOK_PED: + case WAITSTATE_LOOK_SHOP: + case WAITSTATE_LOOK_ACCIDENT: + case WAITSTATE_FACEOFF_GANG: + break; + case WAITSTATE_DOUBLEBACK: + m_headingRate = 0.0f; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3500; + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 3000.0f); + break; + case WAITSTATE_HITWALL: + m_headingRate = 2.0f; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000; + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 16.0f); + animAssoc->flags |= ASSOC_DELETEFADEDOUT; + animAssoc->flags |= ASSOC_FADEOUTWHENDONE; + animAssoc->SetDeleteCallback(FinishedWaitCB, this); + + if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == RANDOM_CHAR && m_nPedState == PED_SEEK_CAR) { + ClearObjective(); + RestorePreviousState(); + } + break; + case WAITSTATE_TURN180: + m_headingRate = 0.0f; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000; + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TURN_180, 3000.0f); + animAssoc->SetFinishCallback(FinishedWaitCB, this); + animAssoc->SetDeleteCallback(RestoreHeadingRateCB, this); + break; + case WAITSTATE_SURPRISE: + m_headingRate = 0.0f; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000; + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 3000.0f); + animAssoc->SetFinishCallback(FinishedWaitCB, this); + break; + case WAITSTATE_STUCK: + SetMoveState(PEDMOVE_STILL); + SetMoveAnim(); + m_headingRate = 0.0f; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000; + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 3000.0f); + + if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == RANDOM_CHAR && m_nPedState == PED_SEEK_CAR) { + ClearObjective(); + RestorePreviousState(); + } + break; + case WAITSTATE_LOOK_ABOUT: + SetMoveState(PEDMOVE_STILL); + SetMoveAnim(); + m_headingRate = 0.0f; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000; + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 3000.0f); + break; + case WAITSTATE_PLAYANIM_COWER: + waitAnim = ANIM_HANDSCOWER; + case WAITSTATE_PLAYANIM_HANDSUP: + if (waitAnim == NUM_ANIMS) + waitAnim = ANIM_HANDSUP; + case WAITSTATE_PLAYANIM_HANDSCOWER: + if (waitAnim == NUM_ANIMS) + waitAnim = ANIM_HANDSCOWER; + m_headingRate = 0.0f; + if (time) + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; + else + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3000; + + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, waitAnim, 3000.0f); + animAssoc->SetDeleteCallback(FinishedWaitCB, this); + break; + case WAITSTATE_PLAYANIM_DUCK: + waitAnim = ANIM_DUCK_DOWN; + case WAITSTATE_PLAYANIM_TAXI: + if (waitAnim == NUM_ANIMS) + waitAnim = ANIM_IDLE_TAXI; + case WAITSTATE_PLAYANIM_CHAT: + if (waitAnim == NUM_ANIMS) + waitAnim = ANIM_IDLE_CHAT; + if (time) + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; + else + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3000; + + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, waitAnim, 3000.0f); + animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE; + animAssoc->flags |= ASSOC_DELETEFADEDOUT; + animAssoc->SetDeleteCallback(FinishedWaitCB, this); + break; + case WAITSTATE_FINISH_FLEE: + SetMoveState(PEDMOVE_STILL); + SetMoveAnim(); + m_headingRate = 0.0f; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2500; + CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 3000.0f); + break; + default: + m_nWaitState = WAITSTATE_FALSE; + RestoreHeadingRate(); + return; + } + m_nWaitState = state; +} + + +void +CPed::PlayHitSound(CPed *hitTo) +{ + // That was very complicated to reverse for me... + // First index is our fight move ID (from 1 to 12, total 12), second is the one of we fight with (from 13 to 22, total 10). + + uint16 hitSoundsByFightMoves[12][10] = { + {S39,S42,S43,S43,S39,S39,S39,S39,S39,S42}, + {NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND}, + {NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND,NO_SND}, + {S39,S39,S39,S39,S33,S43,S39,S39,S39,S39}, + {S39,S39,S39,S39,S35,S39,S38,S38,S39,S39}, + {S39,S39,S39,S39,S33,S39,S41,S36,S39,S39}, + {S39,S39,S39,S39,S37,S40,S38,S38,S39,S39}, + {S39,S39,S39,S39,S34,S43,S44,S37,S39,S39}, + {S39,S39,S39,S39,S34,S43,S44,S37,S39,S39}, + {S39,S39,S39,S39,S34,S43,S44,S37,S39,S40}, + {S39,S39,S39,S39,S33,S39,S41,S37,S39,S40}, + {S39,S39,S39,S39,S39,S39,S39,S39,S33,S33} + }; + + // This is why first dimension is between FightMove 1 and 12. + if (m_lastFightMove == FIGHTMOVE_NULL || m_lastFightMove >= FIGHTMOVE_HITFRONT) + return; + + uint16 soundId; + + // And this is why second dimension is between 13 and 22. + if (hitTo->m_lastFightMove <= FIGHTMOVE_GROUNDKICK || hitTo->m_lastFightMove >= FIGHTMOVE_IDLE2NORM) { + + if (hitTo->m_nPedState == PED_DEAD || hitTo->UseGroundColModel()) { + soundId = hitSoundsByFightMoves[m_lastFightMove - FIGHTMOVE_STDPUNCH][FIGHTMOVE_HITONFLOOR - FIGHTMOVE_HITFRONT]; + } else { + soundId = hitSoundsByFightMoves[m_lastFightMove - FIGHTMOVE_STDPUNCH][FIGHTMOVE_HITFRONT - FIGHTMOVE_HITFRONT]; + } + } else { + soundId = hitSoundsByFightMoves[m_lastFightMove - FIGHTMOVE_STDPUNCH][hitTo->m_lastFightMove - FIGHTMOVE_HITFRONT]; + } + + if (soundId != NO_SND) + DMAudio.PlayOneShot(m_audioEntityId, soundId, 0.0f); +} + +void +CPed::Say(uint16 audio) +{ + uint16 audioToPlay = audio; + + if (IsPlayer()) { + switch (audio) { + case SOUND_PED_DEATH: + audioToPlay = SOUND_PED_DAMAGE; + break; + case SOUND_PED_DAMAGE: + case SOUND_PED_HIT: + case SOUND_PED_LAND: + break; + case SOUND_PED_BULLET_HIT: + case SOUND_PED_CAR_JACKED: + case SOUND_PED_DEFEND: + audioToPlay = SOUND_PED_HIT; + break; + default: + return; + } + } else { + if (3.0f + TheCamera.GetPosition().z < GetPosition().z) + return; + + if (TheCamera.m_CameraAverageSpeed > 1.65f) { + return; + } else if (TheCamera.m_CameraAverageSpeed > 1.25f) { + if (audio != SOUND_PED_DEATH && audio != SOUND_PED_TAXI_WAIT && audio != SOUND_PED_EVADE) + return; + + } else if (TheCamera.m_CameraAverageSpeed > 0.9f) { + switch (audio) { + case SOUND_PED_DEATH: + case SOUND_PED_BURNING: + case SOUND_PED_FLEE_SPRINT: + case SOUND_PED_TAXI_WAIT: + case SOUND_PED_EVADE: + case SOUND_PED_CAR_COLLISION: + break; + default: + return; + } + } + } + + if (audioToPlay < m_queuedSound) { + if (audioToPlay != m_lastQueuedSound || audioToPlay == SOUND_PED_DEATH + || PedAudioData[audioToPlay - SOUND_PED_DEATH].m_nOverrideMaxRandomDelayTime + + m_currentSoundStart + + (uint32) CGeneral::GetRandomNumberInRange(0, PedAudioData[audioToPlay - SOUND_PED_DEATH].m_nMaxRandomDelayTime) <= CTimer::GetTimeInMilliseconds()) { + m_queuedSound = audioToPlay; + } + } +} + WRAPPER void CPed::PedGetupCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE810); } WRAPPER void CPed::PedStaggerCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8D0); } WRAPPER void CPed::PedEvadeCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D36E0); } @@ -4884,4 +5180,9 @@ STARTPATCHES InjectHook(0x4E9870, &CPed::LoadFightData, PATCH_JUMP); InjectHook(0x4E8EC0, &CPed::FightStrike, PATCH_JUMP); InjectHook(0x4CCE20, &CPed::GetLocalDirection, PATCH_JUMP); + InjectHook(0x4E8E20, &CPed::PlayHitSound, PATCH_JUMP); + InjectHook(0x4E5A10, &CPed::Say, PATCH_JUMP); + InjectHook(0x4D58D0, &CPed::SetWaitState, PATCH_JUMP); + InjectHook(0x4D1D70, (void (CPed::*)(CEntity*, int)) &CPed::SetFlee, PATCH_JUMP); + InjectHook(0x4D1D70, (void (CPed::*)(CVector2D&, int)) &CPed::SetFlee, PATCH_JUMP); ENDPATCHES
\ No newline at end of file |