summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animation/AnimBlendAssociation.h2
-rw-r--r--src/animation/AnimManager.cpp2
-rw-r--r--src/control/Script.cpp11
-rw-r--r--src/control/Script.h4
-rw-r--r--src/core/Cam.cpp2
-rw-r--r--src/core/Camera.h2
-rw-r--r--src/core/Frontend.cpp21
-rw-r--r--src/core/Pad.cpp22
-rw-r--r--src/core/Pad.h5
-rw-r--r--src/peds/Ped.cpp10
-rw-r--r--src/peds/PlayerPed.cpp123
-rw-r--r--src/peds/PlayerPed.h1
-rw-r--r--src/render/Hud.cpp3
-rw-r--r--src/weapons/Weapon.cpp1
14 files changed, 156 insertions, 53 deletions
diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h
index f6d98fc3..dbfcb722 100644
--- a/src/animation/AnimBlendAssociation.h
+++ b/src/animation/AnimBlendAssociation.h
@@ -14,7 +14,7 @@ enum {
ASSOC_HAS_TRANSLATION = 0x40,
ASSOC_HAS_X_TRANSLATION = 0x80, // for 2d velocity extraction
ASSOC_WALK = 0x100, // for CPed::PlayFootSteps(void)
- ASSOC_FLAG_XPRESS = 0x200, // only used by xpress scratch, see CPed::Chat(void)
+ ASSOC_IDLE = 0x200, // only xpress scratch has it by default, but game adds it to player's idle animations later
ASSOC_NOWALK = 0x400, // see CPed::PlayFootSteps(void)
ASSOC_BLOCK = 0x800, // unused in assoc description, blocks other anims from being played
ASSOC_FRONTAL = 0x1000, // anims that we fall to front
diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp
index 16207f54..fab28c8d 100644
--- a/src/animation/AnimManager.cpp
+++ b/src/animation/AnimManager.cpp
@@ -174,7 +174,7 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FALL_FRONT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_EV_STEP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_FLAG_XPRESS },
+ { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
{ ANIM_ROAD_CROSS, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index b9ce5073..d696c090 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -1,4 +1,3 @@
-#define WITHWINDOWS // for our script loading hack
#include "common.h"
#include "Script.h"
@@ -599,13 +598,15 @@ void CRunningScript::Init()
}
#ifdef USE_DEBUG_SCRIPT_LOADER
+int scriptToLoad = 0;
+const char *scriptfile = "main.scm";
-const char* scriptfile = "main.scm";
-
+#ifdef _WIN32
+#include <Windows.h>
+#endif
int open_script()
{
- static int scriptToLoad = 1;
-
+ // glfwGetKey doesn't work because of CGame::Initialise is blocking
#ifdef _WIN32
if (GetAsyncKeyState('G') & 0x8000)
scriptToLoad = 0;
diff --git a/src/control/Script.h b/src/control/Script.h
index 57b997b1..68d1dc7b 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -520,3 +520,7 @@ private:
static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami);
};
+
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern int scriptToLoad;
+#endif \ No newline at end of file
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index d04e8683..1c74598c 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -308,7 +308,7 @@ CCam::Process(void)
}
if(Mode == MODE_SNIPER || Mode == MODE_ROCKETLAUNCHER || Mode == MODE_M16_1STPERSON ||
- Mode == MODE_1STPERSON || Mode == MODE_HELICANNON_1STPERSON || GetWeaponFirstPersonOn())
+ Mode == MODE_1STPERSON || Mode == MODE_HELICANNON_1STPERSON || Mode == MODE_CAMERA || GetWeaponFirstPersonOn())
ClipIfPedInFrontOfPlayer();
}
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 4e90855b..18144ef5 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -85,6 +85,7 @@ public:
MODE_SPECIAL_FIXED_FOR_SYPHON,
MODE_FIGHT_CAM,
MODE_TOP_DOWN_PED,
+ MODE_LIGHTHOUSE,
MODE_SNIPER_RUNABOUT,
MODE_ROCKETLAUNCHER_RUNABOUT,
MODE_1STPERSON_RUNABOUT,
@@ -92,7 +93,6 @@ public:
MODE_FIGHT_CAM_RUNABOUT,
MODE_EDITOR,
MODE_HELICANNON_1STPERSON,
- MODE_45,
MODE_CAMERA,
};
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 5c861cf5..d4c251c3 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -3470,6 +3470,24 @@ CMenuManager::ProcessButtonPresses(void)
bool assumeIncrease = false;
#endif
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
+#ifdef RW_GL3
+ if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
+ scriptToLoad = 1;
+ DoSettingsBeforeStartingAGame();
+ return;
+ }
+#elif defined _WIN32
+ if (GetAsyncKeyState('R') & 0x8000) {
+ scriptToLoad = 1;
+ DoSettingsBeforeStartingAGame();
+ return;
+ }
+#endif
+ }
+#endif
+
if (!m_bShowMouse && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) {
m_bShowMouse = true;
}
@@ -4894,6 +4912,9 @@ CMenuManager::ProcessFileActions()
}
if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) {
if (CheckSlotDataValid(m_nCurrSaveSlot)) {
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ scriptToLoad = 0;
+#endif
DoSettingsBeforeStartingAGame();
m_bWantToLoad = true;
}
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index c52c7c36..89b3f053 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -378,15 +378,13 @@ void AltDodoCheat(void)
}
#endif
-#ifdef DETECT_PAD_INPUT_SWITCH
bool
-CControllerState::IsAnyButtonPressed(void)
+CControllerState::CheckForInput(void)
{
return !!LeftStickX || !!LeftStickY || !!RightStickX || !!RightStickY || !!LeftShoulder1 || !!LeftShoulder2 || !!RightShoulder1 || !!RightShoulder2 ||
- !!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight || !!Start || !!Select || !!Square || !!Triangle || !!Cross || !!Circle || !!LeftShock ||
- !!RightShock || !!NetworkTalk;
+ !!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight || !!Start || !!Select || !!Square || !!Triangle || !!Cross || !!Circle || !!LeftShock ||
+ !!RightShock;
}
-#endif
void
CControllerState::Clear(void)
@@ -484,6 +482,11 @@ void CPad::Clear(bool bResetPlayerControls)
AverageEntries = 0;
}
+uint32 CPad::InputHowLongAgo()
+{
+ return CTimer::GetTimeInMilliseconds() - LastTimeTouched;
+}
+
void CPad::ClearMouseHistory()
{
PCTempMouseControllerState.Clear();
@@ -1155,7 +1158,7 @@ void CPad::UpdatePads(void)
CapturePad(0);
#endif
#ifdef DETECT_PAD_INPUT_SWITCH
- if (GetPad(0)->PCTempJoyState.IsAnyButtonPressed())
+ if (GetPad(0)->PCTempJoyState.CheckForInput())
IsAffectedByController = true;
else {
#endif
@@ -1165,11 +1168,11 @@ void CPad::UpdatePads(void)
#ifdef DETECT_PAD_INPUT_SWITCH
}
- if (IsAffectedByController && (GetPad(0)->PCTempKeyState.IsAnyButtonPressed() || GetPad(0)->PCTempMouseState.IsAnyButtonPressed()))
+ if (IsAffectedByController && (GetPad(0)->PCTempKeyState.CheckForInput() || GetPad(0)->PCTempMouseState.CheckForInput()))
IsAffectedByController = false;
#endif
- if ( CReplay::IsPlayingBackFromFile() )
+ if ( CReplay::IsPlayingBackFromFile() && !FrontEndMenuManager.m_bMenuActive )
bUpdate = false;
if ( bUpdate )
@@ -1209,6 +1212,9 @@ void CPad::Update(int16 unk)
PCTempMouseState.Clear();
ProcessPCSpecificStuff();
+
+ if (NewState.CheckForInput())
+ LastTimeTouched = CTimer::GetTimeInMilliseconds();
if ( ++iCurrHornHistory >= HORNHISTORY_SIZE )
iCurrHornHistory = 0;
diff --git a/src/core/Pad.h b/src/core/Pad.h
index ad93fb49..46ed9b39 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -29,9 +29,7 @@ public:
float GetRightStickX(void) { return RightStickX/32767.0f; };
float GetRightStickY(void) { return RightStickY/32767.0f; };
-#ifdef DETECT_PAD_INPUT_SWITCH
- bool IsAnyButtonPressed();
-#endif
+ bool CheckForInput();
void Clear(void);
};
VALIDATE_SIZE(CControllerState, 0x2A);
@@ -260,6 +258,7 @@ public:
static void ResetCheats(void);
static char *EditString(char *pStr, int32 nSize);
static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize);
+ uint32 InputHowLongAgo(void);
#ifdef XINPUT
void AffectFromXinput(uint32 pad);
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 5eb82638..687f9da1 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -3664,7 +3664,7 @@ CPed::Chat(void)
} else
Say(SOUND_PED_CHAT);
- } else if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FLAG_XPRESS)) {
+ } else if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_IDLE)) {
if (CGeneral::GetRandomNumber() < 20) {
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
@@ -6608,22 +6608,22 @@ CPed::RemoveWeaponAnims(int unused, float animDelta)
weaponAssoc->blendDelta = animDelta;
weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHFIRE);
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE_2ND);
if (weaponAssoc) {
weaponAssoc->blendDelta = animDelta;
weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD);
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE_3RD);
if (weaponAssoc) {
weaponAssoc->blendDelta = animDelta;
weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_RELOAD);
if (weaponAssoc) {
weaponAssoc->blendDelta = animDelta;
weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_SPECIAL);
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
if (weaponAssoc) {
weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
if (weaponAssoc->flags & ASSOC_PARTIAL)
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index aafb80c7..3896efa5 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -17,6 +17,7 @@
#include "Darkel.h"
#include "CarCtrl.h"
#include "MBlur.h"
+#include "Streaming.h"
#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
@@ -27,6 +28,8 @@ const uint32 CPlayerPed::nSaveStructSize =
sizeof(CPlayerPed);
#endif
+int32 idleAnimBlockIndex;
+
CPlayerPed::~CPlayerPed()
{
delete m_pWanted;
@@ -79,7 +82,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_nCheckPlayersIndex = 0;
m_nPadUpPressedInMilliseconds = 0;
m_nPadDownPressedInMilliseconds = 0;
- // TODO(Miami): Idle anim block index
+ idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
}
void CPlayerPed::ClearWeaponTarget()
@@ -113,11 +116,7 @@ void
CPlayerPed::MakeObjectTargettable(int32 handle)
{
for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- if (
-#ifdef FIX_BUGS
- m_nTargettableObjects[i] == -1 ||
-#endif
- CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
+ if (CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
m_nTargettableObjects[i] = handle;
return;
}
@@ -633,7 +632,7 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed)
GetWeapon()->Update(m_audioEntityId, nil);
}
-// --MIAMI: Made compatible with slots, but still TODO
+// --MIAMI: Done except commented thing
// I think R* also used goto in here.
void
CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
@@ -641,6 +640,7 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
if (CDarkel::FrenzyOnGoing() || m_attachedTo)
goto switchDetectDone;
+ // TODO(Miami): byte_A10B57
if (!m_pPointGunAt && /* !byte_A10B57 && */ GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) {
if (padUsed->CycleWeaponRightJustDown()) {
@@ -649,7 +649,8 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_CAMERA) {
for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < TOTAL_WEAPON_SLOTS; ++m_nSelectedWepSlot) {
if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
@@ -661,7 +662,8 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
} else if (padUsed->CycleWeaponLeftJustDown()) {
if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
&& TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_CAMERA) {
for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
if (m_nSelectedWepSlot < 0)
@@ -682,31 +684,31 @@ spentAmmoCheck:
if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_eWeaponFire != WEAPON_FIRE_MELEE
&& (!padUsed->GetWeapon() || GetWeapon()->m_eWeaponType != WEAPONTYPE_MINIGUN)) {
if (GetWeapon()->m_nAmmoTotal <= 0) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
+ if (TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON
+ || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_SNIPER
+ || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER)
+ return;
- if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR
- || GetWeapon(2).m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE)
- m_nSelectedWepSlot = m_currentWeapon - 1;
- else
- m_nSelectedWepSlot = 2;
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR
+ || GetWeapon(2).m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE)
+ m_nSelectedWepSlot = m_currentWeapon - 1;
+ else
+ m_nSelectedWepSlot = 2;
- for (; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
+ for (; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
- // BUG: m_nSelectedWepSlot and GetWeapon(..) takes slot in VC but they compared them against weapon types in whole condition! jeez
+ // BUG: m_nSelectedWepSlot and GetWeapon(..) takes slot in VC but they compared them against weapon types in whole condition! jeez
#ifdef FIX_BUGS
- if (m_nSelectedWepSlot == 1 || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != 2) {
+ if (m_nSelectedWepSlot == 1 || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != 2) {
#else
- if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(WEAPONTYPE_BASEBALLBAT).m_eWeaponType == WEAPONTYPE_BASEBALLBAT
- || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0
- && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE && m_nSelectedWepSlot != WEAPONTYPE_TEARGAS) {
+ if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(WEAPONTYPE_BASEBALLBAT).m_eWeaponType == WEAPONTYPE_BASEBALLBAT
+ || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0
+ && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE && m_nSelectedWepSlot != WEAPONTYPE_TEARGAS) {
#endif
- goto switchDetectDone;
- }
+ goto switchDetectDone;
}
- m_nSelectedWepSlot = 0;
}
+ m_nSelectedWepSlot = 0;
}
}
@@ -1337,6 +1339,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
SetJump();
}
}
+ PlayIdleAnimations(padUsed);
}
void
@@ -1630,6 +1633,74 @@ CPlayerPed::DoesPlayerWantNewWeapon(eWeaponType weapon, bool onlyIfSlotIsEmpty)
return m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN || slot != m_currentWeapon;
}
+// TODO(Miami): This only works on gamepad cam! This isn't fair
+void
+CPlayerPed::PlayIdleAnimations(CPad *padUsed)
+{
+ CAnimBlendAssociation* assoc;
+
+ if (TheCamera.m_WideScreenOn || bIsDucking)
+ return;
+
+ struct animAndGroup {
+ AnimationId animId;
+ AssocGroupId groupId;
+ };
+
+ const animAndGroup idleAnims[] = {
+ {ANIM_IDLE_STRETCH, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_IDLE_TIME, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_IDLE_SHOULDER, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_IDLE_STRETCH_LEG, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_XPRESS_SCRATCH, ASSOCGRP_STD},
+ };
+
+ static int32 lastTime = 0;
+ static int32 lastAnim = -1;
+
+ bool hasIdleAnim = false;
+ CAnimBlock *idleAnimBlock = CAnimManager::GetAnimationBlock(idleAnimBlockIndex);
+ uint32 sinceLastInput = padUsed->InputHowLongAgo();
+ if (sinceLastInput <= 30000) {
+ if (idleAnimBlock->isLoaded) {
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ if (assoc->flags & ASSOC_IDLE) {
+ hasIdleAnim = true;
+ assoc->blendDelta = -8.0f;
+ }
+ }
+ if (!hasIdleAnim)
+ CStreaming::RemoveAnim(idleAnimBlockIndex);
+ } else {
+ lastTime = 0;
+ }
+ } else {
+ CStreaming::RequestAnim(idleAnimBlockIndex, STREAMFLAGS_DONT_REMOVE);
+ if (idleAnimBlock->isLoaded) {
+ for(CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ int firstIdle = idleAnimBlock->firstIndex;
+ int index = assoc->hierarchy - CAnimManager::GetAnimation(0);
+ if (index >= firstIdle && index < firstIdle + idleAnimBlock->numAnims) {
+ hasIdleAnim = true;
+ break;
+ }
+ }
+
+ if (!hasIdleAnim && !bIsLooking && !bIsRestoringLook && sinceLastInput - lastTime > 25000) {
+ int anim;
+ do
+ anim = CGeneral::GetRandomNumberInRange(0, ARRAY_SIZE(idleAnims));
+ while (lastAnim == anim);
+
+ assoc = CAnimManager::BlendAnimation(GetClump(), idleAnims[anim].groupId, idleAnims[anim].animId, 8.0f);
+ assoc->flags |= ASSOC_IDLE;
+ lastAnim = anim;
+ lastTime = sinceLastInput;
+ }
+ }
+ }
+}
+
#ifdef COMPATIBLE_SAVES
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index 1042fe16..cc56af9f 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -83,6 +83,7 @@ public:
void ProcessPlayerWeapon(CPad*);
void PlayerControlZelda(CPad*);
bool DoesPlayerWantNewWeapon(eWeaponType, bool);
+ void PlayIdleAnimations(CPad*);
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index 5d1542ef..85d30216 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -160,8 +160,7 @@ void CHud::Draw()
eWeaponType WeaponType = playerPed->GetWeapon()->m_eWeaponType;
int32 Mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
- // TODO(Miami): New cam mode
- if ((Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON/* || Mode == 46*/)
+ if ((Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON || Mode == CCam::MODE_CAMERA)
&& playerPed && !playerPed->GetWeapon()->IsTypeMelee())
DrawCrossHair = true;
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index eaf86bfc..0ac37e31 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -1965,6 +1965,7 @@ CWeapon::FireM16_1stPerson(CEntity *shooter)
if (!( mode == CCam::MODE_M16_1STPERSON
|| mode == CCam::MODE_SNIPER
+ || mode == CCam::MODE_CAMERA
|| mode == CCam::MODE_ROCKETLAUNCHER
|| mode == CCam::MODE_M16_1STPERSON_RUNABOUT
|| mode == CCam::MODE_SNIPER_RUNABOUT