Merge branch 'miami' into miami

This commit is contained in:
erorcun 2020-06-16 23:02:21 +03:00 committed by GitHub
commit d322a8033e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 2738 additions and 1531 deletions

View File

@ -233,6 +233,7 @@ enum AnimationId
ANIM_MELEE_ATTACK = ANIM_WEAPON_FIRE, ANIM_MELEE_ATTACK = ANIM_WEAPON_FIRE,
ANIM_MELEE_ATTACK_2ND, ANIM_MELEE_ATTACK_2ND,
ANIM_MELEE_ATTACK_START, ANIM_MELEE_ATTACK_START,
ANIM_MELEE_IDLE_FIGHTMODE,
ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE, ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE,
ANIM_THROWABLE_THROWU, ANIM_THROWABLE_THROWU,
ANIM_THROWABLE_START_THROW, ANIM_THROWABLE_START_THROW,

View File

@ -123,6 +123,7 @@ char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE];
CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations; CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations;
CVector CCutsceneMgr::ms_cutsceneOffset; CVector CCutsceneMgr::ms_cutsceneOffset;
float CCutsceneMgr::ms_cutsceneTimer; float CCutsceneMgr::ms_cutsceneTimer;
bool CCutsceneMgr::ms_wasCutsceneSkipped;
uint32 CCutsceneMgr::ms_cutsceneLoadStatus; uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
RpAtomic * RpAtomic *
@ -145,6 +146,7 @@ CCutsceneMgr::Initialise(void)
{ {
ms_numCutsceneObjs = 0; ms_numCutsceneObjs = 0;
ms_loaded = false; ms_loaded = false;
ms_wasCutsceneSkipped = false;
ms_running = false; ms_running = false;
ms_animLoaded = false; ms_animLoaded = false;
ms_cutsceneProcessing = false; ms_cutsceneProcessing = false;
@ -169,9 +171,10 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CPlayerPed *pPlayerPed; CPlayerPed *pPlayerPed;
ms_cutsceneProcessing = true; ms_cutsceneProcessing = true;
ms_wasCutsceneSkipped = false;
if (!strcasecmp(szCutsceneName, "jb")) if (!strcasecmp(szCutsceneName, "jb"))
ms_useLodMultiplier = true; ms_useLodMultiplier = true;
CTimer::Stop(); CTimer::Suspend();
ms_pCutsceneDir->numEntries = 0; ms_pCutsceneDir->numEntries = 0;
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR"); ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
@ -225,18 +228,19 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
ms_cutsceneOffset = CVector(0.0f, 0.0f, 0.0f); ms_cutsceneOffset = CVector(0.0f, 0.0f, 0.0f);
pPlayerPed = FindPlayerPed(); pPlayerPed = FindPlayerPed();
CTimer::Update();
pPlayerPed->m_pWanted->ClearQdCrimes(); pPlayerPed->m_pWanted->ClearQdCrimes();
pPlayerPed->bIsVisible = false; pPlayerPed->bIsVisible = false;
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina; pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80; CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(true); CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(true);
CTimer::Resume();
} }
void void
CCutsceneMgr::FinishCutscene() CCutsceneMgr::FinishCutscene()
{ {
ms_wasCutsceneSkipped = true;
CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f; CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
TheCamera.FinishCutscene(); TheCamera.FinishCutscene();
@ -258,11 +262,14 @@ CCutsceneMgr::SetupCutsceneToStart(void)
if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) { if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) {
assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation()); assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation());
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation); ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation);
CWorld::Add(ms_pCutsceneObjects[i]);
pAnimBlendAssoc->SetRun(); pAnimBlendAssoc->SetRun();
} else { } else {
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset); ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset);
} }
CWorld::Add(ms_pCutsceneObjects[i]);
if (RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP) {
ms_pCutsceneObjects[i]->UpdateRpHAnim();
}
} }
CTimer::Update(); CTimer::Update();
@ -289,6 +296,12 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
pAnimBlendClumpData->link.Prepend(&pNewAnim->link); pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
} }
void
CCutsceneMgr::SetCutsceneAnimToLoop(const char* animName)
{
ms_cutsceneAssociations.GetAnimation(animName)->flags |= ASSOC_REPEAT;
}
CCutsceneHead * CCutsceneHead *
CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId) CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId)
{ {
@ -329,6 +342,7 @@ void
CCutsceneMgr::DeleteCutsceneData(void) CCutsceneMgr::DeleteCutsceneData(void)
{ {
if (!ms_loaded) return; if (!ms_loaded) return;
CTimer::Suspend();
ms_cutsceneProcessing = false; ms_cutsceneProcessing = false;
ms_useLodMultiplier = false; ms_useLodMultiplier = false;
@ -359,9 +373,8 @@ CCutsceneMgr::DeleteCutsceneData(void)
if (CGeneral::faststricmp(ms_cutsceneName, "bet")) if (CGeneral::faststricmp(ms_cutsceneName, "bet"))
DMAudio.ChangeMusicMode(MUSICMODE_GAME); DMAudio.ChangeMusicMode(MUSICMODE_GAME);
} }
CTimer::Stop();
CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2); CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2);
CTimer::Update(); CTimer::Resume();
} }
void void

View File

@ -21,6 +21,7 @@ class CCutsceneMgr
static CAnimBlendAssocGroup ms_cutsceneAssociations; static CAnimBlendAssocGroup ms_cutsceneAssociations;
static CVector ms_cutsceneOffset; static CVector ms_cutsceneOffset;
static float ms_cutsceneTimer; static float ms_cutsceneTimer;
static bool ms_wasCutsceneSkipped;
static bool ms_cutsceneProcessing; static bool ms_cutsceneProcessing;
public: public:
static CDirectory *ms_pCutsceneDir; static CDirectory *ms_pCutsceneDir;
@ -30,6 +31,7 @@ public:
static bool IsRunning(void) { return ms_running; } static bool IsRunning(void) { return ms_running; }
static bool HasLoaded(void) { return ms_loaded; } static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; } static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool WasCutsceneSkipped(void) { return ms_wasCutsceneSkipped; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; } static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; } static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; } static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; }
@ -43,6 +45,7 @@ public:
static void FinishCutscene(void); static void FinishCutscene(void);
static void SetupCutsceneToStart(void); static void SetupCutsceneToStart(void);
static void SetCutsceneAnim(const char *animName, CObject *pObject); static void SetCutsceneAnim(const char *animName, CObject *pObject);
static void SetCutsceneAnimToLoop(const char *animName);
static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId); static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId);
static CCutsceneObject *CreateCutsceneObject(int modelId); static CCutsceneObject *CreateCutsceneObject(int modelId);
static void DeleteCutsceneData(void); static void DeleteCutsceneData(void);

View File

@ -71,11 +71,6 @@ uint8 aWeaponBlues[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
0, 128, 255, 0, 0 }; 0, 128, 255, 0, 0 };
float aWeaponScale[] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f };
void void
CPickup::RemoveKeepType() CPickup::RemoveKeepType()
{ {
@ -699,41 +694,51 @@ CPickups::DoPickUpEffects(CEntity *entity)
int16 colorId; int16 colorId;
bool doInnerGlow = false;
bool doOuterGlow = true;
if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) {
colorId = WEAPONTYPE_TOTALWEAPONS; colorId = WEAPONTYPE_TOTALWEAPONS;
else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE) doInnerGlow = true;
doOuterGlow = false;
} else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR) {
colorId = WEAPONTYPE_TOTALWEAPONS + 1; colorId = WEAPONTYPE_TOTALWEAPONS + 1;
else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) } else if (entity->GetModelIndex() == MI_PICKUP_BRIBE) {
doInnerGlow = true;
doOuterGlow = false;
} else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) {
colorId = WEAPONTYPE_TOTALWEAPONS + 2; colorId = WEAPONTYPE_TOTALWEAPONS + 2;
else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) doInnerGlow = true;
colorId = WEAPONTYPE_TOTALWEAPONS + 3; doOuterGlow = false;
else } else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) {
colorId = WEAPONTYPE_TOTALWEAPONS;
doInnerGlow = true;
doOuterGlow = false;
} else
colorId = WeaponForModel(entity->GetModelIndex()); colorId = WeaponForModel(entity->GetModelIndex());
assert(colorId >= 0); const CVector& pos = entity->GetPosition();
if (doOuterGlow) {
float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f;
CShadows::StoreStaticShadow(
(uintptr)entity,
SHADOWTYPE_ADDITIVE,
gpShadowExplosionTex,
&pos,
2.0f, 0.0f, 0.0f, -2.0f,
255, // this is 0 on PC which results in no shadow
aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier,
4.0f, 1.0f, 40.0f, false, 0.0f);
const CVector &pos = entity->GetPosition(); float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f;
CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true);
float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f; float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f;
CShadows::StoreStaticShadow( CCoronas::RegisterCorona((uintptr)entity,
(uintptr)entity, aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f,
SHADOWTYPE_ADDITIVE, 255,
gpShadowExplosionTex, pos,
&pos, size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
2.0f, 0.0f, 0.0f, -2.0f, }
255, // this is 0 on PC which results in no shadow
aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier,
4.0f, 1.0f, 40.0f, false, 0.0f);
float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f;
CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true);
float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f;
CCoronas::RegisterCorona( (uintptr)entity,
aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f,
255,
pos,
size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
CObject *object = (CObject*)entity; CObject *object = (CObject*)entity;
if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) { if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) {
@ -760,7 +765,19 @@ CPickups::DoPickUpEffects(CEntity *entity)
} }
} }
entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]); uint32 model = entity->GetModelIndex();
CColModel* colModel = entity->GetColModel();
CVector colLength = colModel->boundingBox.max - colModel->boundingBox.min;
float scale = (Max(1.f, 1.2f / Max(colLength.x, Max(colLength.y, colLength.z))) - 1.0f) * 0.6f + 1.0f;
if (model == MI_MINIGUN || model == MI_MINIGUN2)
scale = 1.2f;
entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), scale);
if (doInnerGlow)
CCoronas::RegisterCorona((uintptr)entity + 1, 126, 69, 121, 255, entity->GetPosition(), 1.2f, 50.0f,
CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.f, false);
} }
} }

View File

@ -166,7 +166,6 @@ bool doingMissionRetry;
#endif #endif
const uint32 CRunningScript::nSaveStructSize = const uint32 CRunningScript::nSaveStructSize =
#ifdef COMPATIBLE_SAVES #ifdef COMPATIBLE_SAVES
136; 136;
@ -2032,7 +2031,13 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
ped->ClearAll(); ped->ClearAll();
int8 path = ScriptParams[1]; int8 path = ScriptParams[1];
if (ScriptParams[1] < 0 || ScriptParams[1] > 7) if (ScriptParams[1] < 0 || ScriptParams[1] > 7)
// Max number GetRandomNumberInRange returns is max-1
#ifdef FIX_BUGS
path = CGeneral::GetRandomNumberInRange(0, 8);
#else
path = CGeneral::GetRandomNumberInRange(0, 7); path = CGeneral::GetRandomNumberInRange(0, 7);
#endif
ped->SetWanderPath(path); ped->SetWanderPath(path);
return 0; return 0;
} }
@ -2051,10 +2056,11 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
eMoveState state; eMoveState state;
switch (ScriptParams[5]) { switch (ScriptParams[5]) {
case 0: state = PEDMOVE_WALK; break; case 0: state = PEDMOVE_WALK; break;
case 1: state = PEDMOVE_SPRINT; break; case 1: state = PEDMOVE_RUN; break;
default: assert(0); default: assert(0);
} }
ped->ClearAll(); ped->ClearAll();
ped->m_pathNodeTimer = 0;
ped->SetFollowPath(pos, radius, state, nil, nil, 999999); ped->SetFollowPath(pos, radius, state, nil, nil, 999999);
return 0; return 0;
} }
@ -9126,6 +9132,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL: case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL:
{ {
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2) if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2)
return 0; return 0;
#ifdef MISSION_REPLAY #ifdef MISSION_REPLAY
@ -9989,7 +9996,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
continue; continue;
if (pPed->CharCreatedBy != RANDOM_CHAR) if (pPed->CharCreatedBy != RANDOM_CHAR)
continue; continue;
if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING /* && pPed->GetPedState() != PED_ONROPE */) // TODO(MIAMI)! if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING && pPed->GetPedState() != PED_ABSEIL)
continue; continue;
if (pPed->bRemoveFromWorld) if (pPed->bRemoveFromWorld)
continue; continue;
@ -10633,7 +10640,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
char key[KEY_LENGTH_IN_SCRIPT]; char key[KEY_LENGTH_IN_SCRIPT];
CTheScripts::ReadTextLabelFromScript(&m_nIp, key); CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
m_nIp += KEY_LENGTH_IN_SCRIPT; m_nIp += KEY_LENGTH_IN_SCRIPT;
debug("SET_CUTSCENE_ANIM_TO_LOOP not implemented yet, skipping\n"); CCutsceneMgr::SetCutsceneAnimToLoop(key);
return 0; return 0;
} }
case COMMAND_MARK_CAR_AS_CONVOY_CAR: case COMMAND_MARK_CAR_AS_CONVOY_CAR:
@ -10676,7 +10683,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]); CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
assert(pTargetPed); assert(pTargetPed);
pPed->bScriptObjectiveCompleted = false; pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pPed); pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pTargetPed);
return 0; return 0;
} }
//case COMMAND_IS_PICKUP_IN_ZONE: //case COMMAND_IS_PICKUP_IN_ZONE:
@ -11332,6 +11339,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{ {
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
debug("ATTACH_CUTSCENE_OBJECT_TO_COMPONENT not implemented, skipping\n"); // TODO(MIAMI) debug("ATTACH_CUTSCENE_OBJECT_TO_COMPONENT not implemented, skipping\n"); // TODO(MIAMI)
m_nIp += KEY_LENGTH_IN_SCRIPT;
return 0; return 0;
} }
case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED: case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED:
@ -11457,7 +11465,15 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_FIRE_HUNTER_GUN: case COMMAND_FIRE_HUNTER_GUN:
{ {
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
debug("FIRE_HUNTER_GUN is not implemented, skipping\n"); // TODO(MIAMI) CVehicle *pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nGunFiringTime + 150) {
CWeapon gun(WEAPONTYPE_HELICANNON, 5000);
CVector worldGunPos = (pVehicle->GetMatrix() * vecHunterGunPos) + (CTimer::GetTimeStep() * pVehicle->m_vecMoveSpeed);
gun.FireInstantHit(pVehicle, &worldGunPos);
gun.AddGunshell(pVehicle, worldGunPos, CVector2D(0.f, 0.1f), 0.025f);
DMAudio.PlayOneShot(pVehicle->m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.f);
pVehicle->m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
}
return 0; return 0;
} }
case COMMAND_SET_PROPERTY_AS_OWNED: case COMMAND_SET_PROPERTY_AS_OWNED:
@ -11697,7 +11713,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS: case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS:
{ {
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pPed); assert(pPed);
pPed->bIgnoreThreatsBehindObjects = ScriptParams[1]; pPed->bIgnoreThreatsBehindObjects = ScriptParams[1];
return 0; return 0;
@ -11762,12 +11778,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
} }
case COMMAND_WAS_CUTSCENE_SKIPPED: case COMMAND_WAS_CUTSCENE_SKIPPED:
{ {
static bool bShowed = false; UpdateCompareFlag(CCutsceneMgr::WasCutsceneSkipped());
if (!bShowed) {
debug("COMMAND_WAS_CUTSCENE_SKIPPED not implemented, default to TRUE\n");
bShowed = true;
}
UpdateCompareFlag(true);
return 0; return 0;
} }
case COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED: case COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED:
@ -14220,7 +14231,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
pPed->CharCreatedBy = RANDOM_CHAR; pPed->CharCreatedBy = RANDOM_CHAR;
if (pPed->m_nPedType == PEDTYPE_PROSTITUTE) if (pPed->m_nPedType == PEDTYPE_PROSTITUTE)
pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000; pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000;
if (pPed->bInVehicle) { if (pPed->InVehicle()) {
if (pPed->m_pMyVehicle->pDriver == pPed) { if (pPed->m_pMyVehicle->pDriver == pPed) {
if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) { if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle); CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle);
@ -14245,10 +14256,14 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
pPed->ClearObjective(); pPed->ClearObjective();
pPed->bRespondsToThreats = true; pPed->bRespondsToThreats = true;
pPed->bScriptObjectiveCompleted = false; pPed->bScriptObjectiveCompleted = false;
pPed->bKindaStayInSamePlace = false;
pPed->ClearLeader(); pPed->ClearLeader();
if (pPed->IsPedInControl()) if (pPed->IsPedInControl())
pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7); pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7);
if (flees) { if (flees) {
if (pPed->m_nPedState == PED_FOLLOW_PATH && state != PED_FOLLOW_PATH)
pPed->ClearFollowPath();
pPed->m_nPedState = state; pPed->m_nPedState = state;
pPed->SetMoveState(ms); pPed->SetMoveState(ms);
} }
@ -14451,3 +14466,54 @@ void RetryMission(int type, int unk)
} }
#endif #endif
#ifdef MISSION_SWITCHER
void
CTheScripts::SwitchToMission(int32 mission)
{
for (CRunningScript* pScript = CTheScripts::pActiveScripts; pScript != nil; pScript = pScript->GetNext()) {
if (!pScript->m_bIsMissionScript || !pScript->m_bDeatharrestEnabled) {
continue;
}
while (pScript->m_nStackPointer > 0)
--pScript->m_nStackPointer;
pScript->m_nIp = pScript->m_anStack[pScript->m_nStackPointer];
*(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0;
pScript->m_nWakeTime = 0;
pScript->m_bDeatharrestExecuted = true;
while (!pScript->ProcessOneCommand());
CMessages::ClearMessages();
}
if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && mission <= UINT16_MAX - 2)
return;
#ifdef MISSION_REPLAY
missionRetryScriptIndex = mission;
if (missionRetryScriptIndex == 19)
CStats::LastMissionPassedName[0] = '\0';
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[mission];
#ifdef USE_DEBUG_SCRIPT_LOADER
CFileMgr::ChangeDir("\\data\\");
int handle = CFileMgr::OpenFile(scriptfile, "rb");
CFileMgr::ChangeDir("\\");
#else
CFileMgr::ChangeDir("\\");
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
#endif
CFileMgr::Seek(handle, offset, 0);
CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT);
CFileMgr::CloseFile(handle);
CRunningScript* pMissionScript = CTheScripts::StartNewScript(SIZE_MAIN_SCRIPT);
CTimer::Resume();
pMissionScript->m_bIsMissionScript = true;
pMissionScript->m_bMissionFlag = true;
CTheScripts::bAlreadyRunningAMissionScript = true;
CGameLogic::ClearShortCut();
}
#endif

View File

@ -375,6 +375,11 @@ private:
static void RemoveScriptTextureDictionary(); static void RemoveScriptTextureDictionary();
static void RemoveThisPed(CPed* pPed); static void RemoveThisPed(CPed* pPed);
#ifdef MISSION_SWITCHER
public:
static void SwitchToMission(int32 mission);
#endif
friend class CRunningScript; friend class CRunningScript;
friend class CHud; friend class CHud;
friend void CMissionCleanup::Process(); friend void CMissionCleanup::Process();
@ -526,6 +531,8 @@ private:
bool CheckDamagedWeaponType(int32 actual, int32 type); bool CheckDamagedWeaponType(int32 actual, int32 type);
static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami); static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami);
friend class CTheScripts;
}; };
#ifdef USE_DEBUG_SCRIPT_LOADER #ifdef USE_DEBUG_SCRIPT_LOADER

File diff suppressed because it is too large Load Diff

View File

@ -76,6 +76,16 @@ float CCamera::m_f3rdPersonCHairMultY;
#define CTRLDOWN(key) ((KEYDOWN(rsLCTRL) || KEYDOWN(rsRCTRL)) && KEYDOWN((RsKeyCodes)key)) #define CTRLDOWN(key) ((KEYDOWN(rsLCTRL) || KEYDOWN(rsRCTRL)) && KEYDOWN((RsKeyCodes)key))
#endif #endif
const float ZOOM_ONE_DISTANCE[] = { -0.6f, 0.05f, -3.2f, 0.05f, -2.41f };
const float ZOOM_TWO_DISTANCE[] = { 1.9f, 1.4f, 0.65f, 1.9f, 6.49f };
const float ZOOM_THREE_DISTANCE[] = { 15.9f, 15.9f, 15.9f, 15.9f, 25.25f };
#ifdef FREE_CAM
const float LCS_ZOOM_ONE_DISTANCE[] = { -1.0f, -0.2f, -3.2f, 0.05f, -2.41f };
const float LCS_ZOOM_TWO_DISTANCE[] = { 2.0f, 2.2f, 1.65f, 2.9f, 6.49f };
const float LCS_ZOOM_THREE_DISTANCE[] = { 6.0f, 6.0f, 15.9f, 15.9f, 15.0f };
#endif
CCamera::CCamera(void) CCamera::CCamera(void)
{ {
Init(); Init();
@ -670,6 +680,10 @@ CCamera::CamControl(void)
if(CarZoomIndicator != CAM_ZOOM_1STPRS && CarZoomIndicator != CAM_ZOOM_TOPDOWN) if(CarZoomIndicator != CAM_ZOOM_1STPRS && CarZoomIndicator != CAM_ZOOM_TOPDOWN)
ReqMode = CCam::MODE_CAM_ON_A_STRING; ReqMode = CCam::MODE_CAM_ON_A_STRING;
int vehApp = ((CVehicle*)pTargetEntity)->GetVehicleAppearance();
int vehArrPos = 0;
GetArrPosForVehicleType(vehApp, vehArrPos);
switch(((CVehicle*)pTargetEntity)->m_vehType){ switch(((CVehicle*)pTargetEntity)->m_vehType){
case VEHICLE_TYPE_CAR: case VEHICLE_TYPE_CAR:
case VEHICLE_TYPE_BIKE: case VEHICLE_TYPE_BIKE:
@ -758,26 +772,26 @@ CCamera::CamControl(void)
} }
// Car zoom value // Car zoom value
if(CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage){ if (CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage) {
CarZoomValue = 0.0f; CarZoomValue = 0.0f;
ReqMode = CCam::MODE_1STPERSON; ReqMode = CCam::MODE_1STPERSON;
} }
#ifdef FREE_CAM #ifdef FREE_CAM
else if (bFreeCam) { else if (bFreeCam) {
if (CarZoomIndicator == CAM_ZOOM_1) if (CarZoomIndicator == CAM_ZOOM_1)
CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; CarZoomValue = LCS_ZOOM_ONE_DISTANCE[vehArrPos];
else if (CarZoomIndicator == CAM_ZOOM_2) else if (CarZoomIndicator == CAM_ZOOM_2)
CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2; CarZoomValue = LCS_ZOOM_TWO_DISTANCE[vehArrPos];
else if (CarZoomIndicator == CAM_ZOOM_3) else if (CarZoomIndicator == CAM_ZOOM_3)
CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3; CarZoomValue = LCS_ZOOM_THREE_DISTANCE[vehArrPos];
} }
#endif #endif
else if(CarZoomIndicator == CAM_ZOOM_1) else if (CarZoomIndicator == CAM_ZOOM_1)
CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_1; CarZoomValue = ZOOM_ONE_DISTANCE[vehArrPos];
else if(CarZoomIndicator == CAM_ZOOM_2) else if(CarZoomIndicator == CAM_ZOOM_2)
CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_2; CarZoomValue = ZOOM_TWO_DISTANCE[vehArrPos];
else if(CarZoomIndicator == CAM_ZOOM_3) else if(CarZoomIndicator == CAM_ZOOM_3)
CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_3; CarZoomValue = ZOOM_THREE_DISTANCE[vehArrPos];
if(CarZoomIndicator == CAM_ZOOM_TOPDOWN && !m_bPlayerIsInGarage){ if(CarZoomIndicator == CAM_ZOOM_TOPDOWN && !m_bPlayerIsInGarage){
CarZoomValue = 1.0f; CarZoomValue = 1.0f;
@ -2960,6 +2974,13 @@ CCamera::Process_Train_Camera_Control(void)
if(node >= m_uiNumberOfTrainCamNodes) if(node >= m_uiNumberOfTrainCamNodes)
node = 0; node = 0;
} }
#ifdef FIX_BUGS
// Not really a bug but be nice and respect the debug mode
if(DebugCamMode){
TakeControl(target, DebugCamMode, JUMP_CUT, CAMCONTROL_SCRIPT);
return;
}
#endif
if(found){ if(found){
SetWideScreenOn(); SetWideScreenOn();
@ -3103,26 +3124,42 @@ CCamera::SetZoomValueFollowPedScript(int16 dist)
void void
CCamera::SetZoomValueCamStringScript(int16 dist) CCamera::SetZoomValueCamStringScript(int16 dist)
{ {
#ifdef FREE_CAM if (Cams[ActiveCam].CamTargetEntity->IsVehicle()) {
if (bFreeCam) { int vehApp = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->GetVehicleAppearance();
switch (dist) { int vehArrPos = 0;
case 0: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; break; GetArrPosForVehicleType(vehApp, vehArrPos);
case 1: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2; break;
case 2: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3; break;
default: break;
}
} else
#endif
{
switch (dist) {
case 0: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_1; break;
case 1: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_2; break;
case 2: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_3; break;
default: break;
}
}
m_bUseScriptZoomValueCar = true; #ifdef FREE_CAM
if (bFreeCam) {
switch (dist) {
case 0: m_fCarZoomValueScript = LCS_ZOOM_ONE_DISTANCE[vehArrPos]; break;
case 1: m_fCarZoomValueScript = LCS_ZOOM_TWO_DISTANCE[vehArrPos]; break;
case 2: m_fCarZoomValueScript = LCS_ZOOM_THREE_DISTANCE[vehArrPos]; break;
default: break;
}
}
else
#endif
{
switch (dist) {
case 0: m_fCarZoomValueScript = ZOOM_ONE_DISTANCE[vehArrPos]; break;
case 1: m_fCarZoomValueScript = ZOOM_TWO_DISTANCE[vehArrPos]; break;
case 2: m_fCarZoomValueScript = ZOOM_THREE_DISTANCE[vehArrPos]; break;
default: break;
}
}
m_bUseScriptZoomValueCar = true;
} else {
switch (dist) {
case 0: m_fPedZoomValueScript = 0.25f; break;
case 1: m_fPedZoomValueScript = 1.5f; break;
case 2: m_fPedZoomValueScript = 2.9f; break;
default: break;
}
m_bUseScriptZoomValuePed = true;
}
} }
void void

View File

@ -26,20 +26,6 @@ enum
CAM_ZOOM_CINEMATIC, CAM_ZOOM_CINEMATIC,
}; };
#ifdef FREE_CAM // LCS values
#define FREE_CAR_ZOOM_VALUE_1 (-1.0f)
#define FREE_CAR_ZOOM_VALUE_2 (2.0f)
#define FREE_CAR_ZOOM_VALUE_3 (6.0f)
#define FREE_BOAT_ZOOM_VALUE_1 (-2.41f)
#define FREE_BOAT_ZOOM_VALUE_2 (6.49f)
#define FREE_BOAT_ZOOM_VALUE_3 (15.0f)
#endif
#define DEFAULT_CAR_ZOOM_VALUE_1 (0.05f)
#define DEFAULT_CAR_ZOOM_VALUE_2 (1.9f)
#define DEFAULT_CAR_ZOOM_VALUE_3 (3.9f)
const float DefaultFOV = 70.0f; // beta: 80.0f const float DefaultFOV = 70.0f; // beta: 80.0f
class CCam class CCam
@ -121,9 +107,8 @@ public:
float f_max_role_angle; //=DEGTORAD(5.0f); float f_max_role_angle; //=DEGTORAD(5.0f);
float f_Roll; //used for adding a slight roll to the camera in the float f_Roll; //used for adding a slight roll to the camera in the
float f_rollSpeed; //TODO(MIAMI): remove float f_rollSpeed;
float m_fSyphonModeTargetZOffSet; float m_fSyphonModeTargetZOffSet;
float m_fRoadOffSet;
float m_fAmountFractionObscured; float m_fAmountFractionObscured;
float m_fAlphaSpeedOverOneFrame; float m_fAlphaSpeedOverOneFrame;
float m_fBetaSpeedOverOneFrame; float m_fBetaSpeedOverOneFrame;
@ -208,11 +193,11 @@ public:
void ProcessSpecialHeightRoutines(void); void ProcessSpecialHeightRoutines(void);
void GetVectorsReadyForRW(void); void GetVectorsReadyForRW(void);
CVector DoAverageOnVector(const CVector &vec); CVector DoAverageOnVector(const CVector &vec);
float GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies);
void WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight); void WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight);
bool RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation); bool RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation);
void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist); void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist);
void FixCamWhenObscuredByVehicle(const CVector &TargetCoors); void FixCamWhenObscuredByVehicle(const CVector &TargetCoors);
bool GetBoatLook_L_R_HeightOffset(float &Offset);
void LookBehind(void); void LookBehind(void);
void LookLeft(void); void LookLeft(void);
void LookRight(void); void LookRight(void);
@ -246,26 +231,14 @@ public:
bool Process_WheelCam(const CVector&, float, float, float); bool Process_WheelCam(const CVector&, float, float, float);
void Process_Fixed(const CVector &CameraTarget, float, float, float); void Process_Fixed(const CVector &CameraTarget, float, float, float);
void Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Circle(const CVector &CameraTarget, float, float, float);
void Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float); void Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float);
void Process_LightHouse(const CVector &CameraTarget, float, float, float);
void ProcessPedsDeadBaby(void); void ProcessPedsDeadBaby(void);
bool ProcessArrestCamOne(void); bool ProcessArrestCamOne(void);
bool ProcessArrestCamTwo(void); bool ProcessArrestCamTwo(void);
bool GetLookAlongGroundPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
/* Some of the unused PS2 cams */ bool GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
void Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float, float, float); bool GetLookOverShoulderPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
void Process_ReactionCam(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOrientation, float, float);
// TODO:
// CCam::Process_CushyPillows_Arse
// CCam::Process_Look_At_Cars
// CCam::Process_CheesyZoom
// CCam::Process_Aiming
// CCam::Process_Bill // same as BehindCar due to unused variables
// CCam::Process_Im_The_Passenger_Woo_Woo
// CCam::Process_Blood_On_The_Tracks
// CCam::Process_Cam_Running_Side_Train
// CCam::Process_Cam_On_Train_Roof
// custom stuff // custom stuff
void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float);

View File

@ -1801,6 +1801,21 @@ CColSphere::Set(float radius, const CVector &center, uint8 surf, uint8 piece)
this->piece = piece; this->piece = piece;
} }
bool
CColSphere::IntersectRay(CVector const& from, CVector const& dir, CVector &entry, CVector &exit)
{
CVector distToCenter = from - center;
float distToTouchSqr = distToCenter.MagnitudeSqr() - sq(radius);
float root1, root2;
if (!CGeneral::SolveQuadratic(1.0f, DotProduct(distToCenter, dir) * 2.f, distToTouchSqr, root1, root2))
return false;
entry = from + dir * root1;
exit = from + dir * root2;
return true;
}
void void
CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece) CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece)
{ {

View File

@ -31,6 +31,7 @@ struct CColSphere : public CSphere
uint8 piece; uint8 piece;
void Set(float radius, const CVector &center, uint8 surf, uint8 piece); void Set(float radius, const CVector &center, uint8 surf, uint8 piece);
bool IntersectRay(CVector const &from, CVector const &dir, CVector &entry, CVector &exit);
using CSphere::Set; using CSphere::Set;
}; };

View File

@ -134,6 +134,18 @@ public:
return *str2 != '\0'; return *str2 != '\0';
} }
static bool SolveQuadratic(float a, float b, float c, float &root1, float &root2)
{
float discriminant = b * b - 4.f * a * c;
if (discriminant < 0.f)
return false;
float discriminantSqrt = Sqrt(discriminant);
root2 = (-b + discriminantSqrt) / (2.f * a);
root1 = (-b - discriminantSqrt) / (2.f * a);
return true;
}
// not too sure about all these... // not too sure about all these...
static uint16 GetRandomNumber(void) static uint16 GetRandomNumber(void)
{ return myrand() & MYRAND_MAX; } { return myrand() & MYRAND_MAX; }

View File

@ -27,7 +27,7 @@ public:
static uint32 GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; } static uint32 GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; }
static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; } static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; } static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
static uint32 GetTimeStepNonClippedInMilliseconds(void) { return ms_fTimeStepNonClipped / 50.0f * 1000.0f; } static float GetTimeStepNonClippedInMilliseconds(void) { return ms_fTimeStepNonClipped / 50.0f * 1000.0f; }
static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; } static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; }
static const uint32 &GetFrameCounter(void) { return m_FrameCounter; } static const uint32 &GetFrameCounter(void) { return m_FrameCounter; }
static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; } static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; }

View File

@ -649,8 +649,8 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo
} }
void void
CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector &centre, float radius, bool ignoreZ, short *nextObject, CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector &centre, float radius, bool ignoreZ, int16 *numObjects,
short lastObject, CEntity **objects) int16 lastObject, CEntity **objects)
{ {
float radiusSqr = radius * radius; float radiusSqr = radius * radius;
float objDistSqr; float objDistSqr;
@ -666,16 +666,16 @@ CWorld::FindObjectsInRangeSectorList(CPtrList &list, Const CVector &centre, floa
else else
objDistSqr = diff.MagnitudeSqr(); objDistSqr = diff.MagnitudeSqr();
if(objDistSqr < radiusSqr && *nextObject < lastObject) { if(objDistSqr < radiusSqr && *numObjects < lastObject) {
if(objects) { objects[*nextObject] = object; } if(objects) { objects[*numObjects] = object; }
(*nextObject)++; (*numObjects)++;
} }
} }
} }
} }
void void
CWorld::FindObjectsInRange(Const CVector &centre, float radius, bool ignoreZ, short *nextObject, short lastObject, CWorld::FindObjectsInRange(Const CVector &centre, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject,
CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds,
bool checkObjects, bool checkDummies) bool checkObjects, bool checkDummies)
{ {
@ -701,39 +701,39 @@ CWorld::FindObjectsInRange(Const CVector &centre, float radius, bool ignoreZ, sh
AdvanceCurrentScanCode(); AdvanceCurrentScanCode();
*nextObject = 0; *numObjects = 0;
for(int curY = minY; curY <= maxY; curY++) { for(int curY = minY; curY <= maxY; curY++) {
for(int curX = minX; curX <= maxX; curX++) { for(int curX = minX; curX <= maxX; curX++) {
CSector *sector = GetSector(curX, curY); CSector *sector = GetSector(curX, curY);
if(checkBuildings) { if(checkBuildings) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius,
ignoreZ, nextObject, lastObject, objects); ignoreZ, numObjects, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre,
radius, ignoreZ, nextObject, lastObject, objects); radius, ignoreZ, numObjects, lastObject, objects);
} }
if(checkVehicles) { if(checkVehicles) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius,
ignoreZ, nextObject, lastObject, objects); ignoreZ, numObjects, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre,
radius, ignoreZ, nextObject, lastObject, objects); radius, ignoreZ, numObjects, lastObject, objects);
} }
if(checkPeds) { if(checkPeds) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, ignoreZ, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, ignoreZ,
nextObject, lastObject, objects); numObjects, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius,
ignoreZ, nextObject, lastObject, objects); ignoreZ, numObjects, lastObject, objects);
} }
if(checkObjects) { if(checkObjects) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius,
ignoreZ, nextObject, lastObject, objects); ignoreZ, numObjects, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre,
radius, ignoreZ, nextObject, lastObject, objects); radius, ignoreZ, numObjects, lastObject, objects);
} }
if(checkDummies) { if(checkDummies) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius,
ignoreZ, nextObject, lastObject, objects); ignoreZ, numObjects, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre,
radius, ignoreZ, nextObject, lastObject, objects); radius, ignoreZ, numObjects, lastObject, objects);
} }
} }
} }
@ -941,7 +941,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
if(e != entityToIgnore && e->bUsesCollision && if(e != entityToIgnore && e->bUsesCollision &&
!(ignoreSomeObjects && CameraToIgnoreThisObject(e))) { !(ignoreSomeObjects && CameraToIgnoreThisObject(e))) {
CVector diff = spherePos - e->GetPosition(); CVector diff = spherePos - e->GetBoundCentre();
float distance = diff.Magnitude(); float distance = diff.Magnitude();
if(e->GetBoundRadius() + radius > distance) { if(e->GetBoundRadius() + radius > distance) {

View File

@ -103,8 +103,8 @@ public:
static CEntity *TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects); static CEntity *TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects);
static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool); static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
static void FindObjectsInRangeSectorList(CPtrList&, Const CVector&, float, bool, short*, short, CEntity**); static void FindObjectsInRangeSectorList(CPtrList &list, Const CVector &centre, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects);
static void FindObjectsInRange(Const CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool); static void FindObjectsInRange(Const CVector &centre, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies);
static void FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities); static void FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
static void FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies); static void FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
static float FindGroundZForCoord(float x, float y); static float FindGroundZForCoord(float x, float y);

View File

@ -202,12 +202,11 @@ enum Config {
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
#define FIX_HIGH_FPS_BUGS_ON_FRONTEND #define FIX_HIGH_FPS_BUGS_ON_FRONTEND
// Rendering/display
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios
// Just debug menu entries // Just debug menu entries
#ifdef DEBUGMENU #ifdef DEBUGMENU
#define TOGGLEABLE_BETA_FEATURES // not too many things #define TOGGLEABLE_BETA_FEATURES // not too many things
#define RELOADABLES // some debug menu options to reload TXD files #define RELOADABLES // some debug menu options to reload TXD files
#define MISSION_SWITCHER // from debug menu
#endif #endif
// Rendering/display // Rendering/display

View File

@ -31,6 +31,7 @@
#include "Text.h" #include "Text.h"
#include "WaterLevel.h" #include "WaterLevel.h"
#include "main.h" #include "main.h"
#include "Script.h"
#ifndef _WIN32 #ifndef _WIN32
#include "assert.h" #include "assert.h"
@ -212,7 +213,7 @@ SpawnCar(int id)
CVehicle *v; CVehicle *v;
if(CModelInfo::IsBoatModel(id)) if(CModelInfo::IsBoatModel(id))
v = new CBoat(id, RANDOM_VEHICLE); v = new CBoat(id, RANDOM_VEHICLE);
if(CModelInfo::IsBikeModel(id)) else if(CModelInfo::IsBikeModel(id))
v = new CBike(id, RANDOM_VEHICLE); v = new CBike(id, RANDOM_VEHICLE);
else else
v = new CAutomobile(id, RANDOM_VEHICLE); v = new CAutomobile(id, RANDOM_VEHICLE);
@ -309,6 +310,15 @@ ResetCamStatics(void)
TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true; TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
} }
#ifdef MISSION_SWITCHER
int8 nextMissionToSwitch = 0;
static void
SwitchToMission(void)
{
CTheScripts::SwitchToMission(nextMissionToSwitch);
}
#endif
static const char *carnames[] = { static const char *carnames[] = {
"landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "rio", "firetruk", "trash", "stretch", "manana", "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "rio", "firetruk", "trash", "stretch", "manana",
"infernus", "voodoo", "pony", "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "washing", "infernus", "voodoo", "pony", "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "washing",
@ -512,7 +522,10 @@ DebugMenuPopulate(void)
#ifdef TIMEBARS #ifdef TIMEBARS
DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil); DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil);
#endif #endif
#ifdef MISSION_SWITCHER
DebugMenuAddInt8("Debug", "Select mission no", &nextMissionToSwitch, nil, 1, 0, 96, nil);
DebugMenuAddCmd("Debug", "Start selected mission ", SwitchToMission);
#endif
extern bool PrintDebugCode; extern bool PrintDebugCode;
extern int16 DebugCamMode; extern int16 DebugCamMode;
DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil); DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil);

View File

@ -483,6 +483,21 @@ IsLightObject(int16 id)
id == MI_TRAFFICLIGHTS_TWOVERTICAL; id == MI_TRAFFICLIGHTS_TWOVERTICAL;
} }
inline bool
IsLampPost(int16 id)
{
return id == MI_SINGLESTREETLIGHTS1 ||
id == MI_SINGLESTREETLIGHTS2 ||
id == MI_SINGLESTREETLIGHTS3 ||
id == MI_BOLLARDLIGHT ||
id == MI_MLAMPPOST ||
id == MI_STREETLAMP1 ||
id == MI_STREETLAMP2 ||
id == MI_TELPOLE02 ||
id == MI_TRAFFICLIGHTS_MIAMI ||
id == MI_TRAFFICLIGHTS_TWOVERTICAL;
}
inline bool inline bool
IsBodyPart(int16 id) IsBodyPart(int16 id)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -10,11 +10,11 @@
#include "Weapon.h" #include "Weapon.h"
#include "WeaponInfo.h" #include "WeaponInfo.h"
#include "AnimationId.h" #include "AnimationId.h"
#include "PathFind.h"
#define FEET_OFFSET 1.04f #define FEET_OFFSET 1.04f
#define CHECK_NEARBY_THINGS_MAX_DIST 15.0f #define CHECK_NEARBY_THINGS_MAX_DIST 15.0f
struct CPathNode;
class CAccident; class CAccident;
class CObject; class CObject;
class CFire; class CFire;
@ -346,6 +346,9 @@ enum eMoveState {
PEDMOVE_NONE, PEDMOVE_NONE,
PEDMOVE_STILL, PEDMOVE_STILL,
PEDMOVE_WALK, PEDMOVE_WALK,
PEDMOVE_UNK,
PEDMOVE_RUN, PEDMOVE_RUN,
PEDMOVE_SPRINT, PEDMOVE_SPRINT,
}; };
@ -521,13 +524,20 @@ public:
int32 m_nPrevMoveState; int32 m_nPrevMoveState;
eWaitState m_nWaitState; eWaitState m_nWaitState;
uint32 m_nWaitTimer; uint32 m_nWaitTimer;
void *m_pPathNodesStates[8]; // unused, probably leftover from VC CPathNode* m_pathNodesToGo[8];
CVector2D m_stPathNodeStates[10]; int16 m_nNumPathNodes;
uint16 m_nPathNodes; int16 m_nCurPathNodeId;
int16 m_nCurPathNode; CEntity* m_followPathWalkAroundEnt;
int8 m_nPathDir; CEntity* m_followPathTargetEnt;
CPathNode *m_pLastPathNode; uint32 m_pathNodeTimer;
CPathNode *m_pNextPathNode; CPathNode m_pathNodeObjPool[8];
CPathNode* m_pCurPathNode;
char m_nPathDir;
CPathNode* m_pLastPathNode;
CPathNode* m_pNextPathNode;
CVector m_followPathDestPos;
float m_followPathAbortDist;
eMoveState m_followPathMoveState;
float m_fHealth; float m_fHealth;
float m_fArmour; float m_fArmour;
uint32 m_nExtendedRangeTimer; uint32 m_nExtendedRangeTimer;
@ -584,6 +594,7 @@ public:
CEntity *m_pPointGunAt; CEntity *m_pPointGunAt;
CVector m_vecHitLastPos; CVector m_vecHitLastPos;
uint32 m_lastFightMove; uint32 m_lastFightMove;
uint32 m_lastHitState; // TODO(Miami): What's this?
uint8 m_fightButtonPressure; uint8 m_fightButtonPressure;
FightState m_fightState; FightState m_fightState;
bool m_takeAStepAfterAttack; bool m_takeAStepAfterAttack;
@ -746,7 +757,8 @@ public:
void SetAttack(CEntity*); void SetAttack(CEntity*);
void StartFightAttack(uint8); void StartFightAttack(uint8);
void SetWaitState(eWaitState, void*); void SetWaitState(eWaitState, void*);
bool FightStrike(CVector&); bool FightStrike(CVector&, bool);
void FightHitPed(CPed*, CVector&, CVector&, int16);
int GetLocalDirection(const CVector2D &); int GetLocalDirection(const CVector2D &);
void StartFightDefend(uint8, uint8, uint8); void StartFightDefend(uint8, uint8, uint8);
void PlayHitSound(CPed*); void PlayHitSound(CPed*);
@ -756,6 +768,7 @@ public:
void RemoveInCarAnims(void); void RemoveInCarAnims(void);
void CollideWithPed(CPed*); void CollideWithPed(CPed*);
void SetDirectionToWalkAroundObject(CEntity*); void SetDirectionToWalkAroundObject(CEntity*);
bool SetDirectionToWalkAroundVehicle(CVehicle*);
void RemoveWeaponAnims(int, float); void RemoveWeaponAnims(int, float);
void CreateDeadPedMoney(void); void CreateDeadPedMoney(void);
void CreateDeadPedWeaponPickups(void); void CreateDeadPedWeaponPickups(void);
@ -778,7 +791,7 @@ public:
bool FindBestCoordsFromNodes(CVector, CVector*); bool FindBestCoordsFromNodes(CVector, CVector*);
void Wait(void); void Wait(void);
void ProcessObjective(void); void ProcessObjective(void);
bool SeekFollowingPath(CVector*); CVector *SeekFollowingPath(void);
void Flee(void); void Flee(void);
void FollowPath(void); void FollowPath(void);
CVector GetFormationPosition(void); CVector GetFormationPosition(void);
@ -1009,6 +1022,13 @@ public:
else else
return (AnimationId)0; return (AnimationId)0;
} }
static AnimationId GetFightIdleWithMeleeAnim(CWeaponInfo* weapon) {
if (!!weapon->m_bFightMode)
return ANIM_MELEE_IDLE_FIGHTMODE;
else
return (AnimationId)0;
}
// -- // --
// My additions, because there were many, many instances of that. // My additions, because there were many, many instances of that.

View File

@ -4,47 +4,65 @@
#include "General.h" #include "General.h"
#include "Ped.h" #include "Ped.h"
// --MIAMI: Done
// Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL) // Corresponds to ped sounds (from SOUND_PED_DEATH to SOUND_PED_TAXI_CALL)
PedAudioData CommentWaitTime[39] = { PedAudioData CommentWaitTime[56] = {
{500, 800, 500, 2}, { 500, 800, 500, 2 },
{500, 800, 500, 2}, { 500, 800, 500, 2 },
{500, 800, 500, 2}, { 500, 800, 500, 2 },
{500, 800, 500, 2}, { 500, 800, 500, 2 },
{100, 2, 100, 2}, { 100, 2, 100, 2 },
{700, 500, 1000, 500}, { 500, 500, 2000, 1000 },
{700, 500, 1000, 500}, { 2000, 50, 2050, 1000 },
{5000, 2000, 15000, 3000}, { 5000, 2000, 7000, 3000 },
{5000, 2000, 15000, 3000}, { 5000, 2000, 7000, 3000 },
{5000, 2000, 15000, 3000}, { 300, 200, 500, 200 },
{6000, 6000, 6000, 6000}, { 3000, 1000, 4000, 1000 },
{1000, 1000, 2000, 2000}, { 6000, 6000, 6000, 6000 },
{1000, 500, 2000, 1500}, { 4000, 1000, 5000, 1000 },
{1000, 500, 2000, 1500}, { 3000, 1000, 4000, 1000 },
{800, 200, 1000, 500}, { 1000, 1000, 2000, 2000 },
{800, 200, 1000, 500}, { 1000, 500, 2000, 1500 },
{800, 400, 2000, 1000}, { 1700, 1000, 3000, 1000 },
{800, 400, 2000, 1000}, { 800, 200, 1000, 500 },
{400, 300, 2000, 1000}, { 800, 200, 1000, 500 },
{2000, 1000, 2500, 1500}, { 800, 400, 2000, 1000 },
{200, 200, 200, 200}, { 800, 400, 2000, 1000 },
{6000, 3000, 5000, 6000}, { 2000, 2000, 4000, 4000 },
{6000, 3000, 9000, 5000}, { 2000, 2000, 4000, 1000 },
{6000, 3000, 9000, 5000}, { 4000, 1000, 5000, 1000 },
{6000, 3000, 9000, 5000}, { 800, 400, 1200, 500 },
{400, 300, 4000, 1000}, { 5000, 1000, 6000, 2000 },
{400, 300, 4000, 1000}, { 5000, 1000, 6000, 2000 },
{400, 300, 4000, 1000}, { 5000, 1000, 6000, 2000 },
{1000, 500, 3000, 1000}, { 5000, 1000, 6000, 2000 },
{1000, 500, 1000, 1000}, { 5000, 1000, 6000, 2000 },
{3000, 2000, 3000, 2000}, { 5000, 1000, 6000, 2000 },
{1000, 500, 3000, 6000}, { 5000, 1000, 6000, 2000 },
{1000, 500, 2000, 4000}, { 4000, 2000, 7000, 2000 },
{1000, 500, 2000, 5000}, { 1000, 300, 2000, 1000 },
{1000, 500, 3000, 2000}, { 1500, 1000, 2500, 1000 },
{1600, 1000, 2000, 2000}, { 200, 200, 200, 200 },
{3000, 2000, 5000, 3000}, { 2000, 1000, 4000, 1000 },
{1000, 1000, 1000, 1000}, { 2000, 1000, 4000, 1000 },
{1000, 1000, 5000, 5000}, { 1000, 500, 3000, 1000 },
{ 1000, 500, 1000, 1000 },
{ 3000, 2000, 5000, 1000 },
{ 3000, 2000, 5000, 1000 },
{ 3000, 2000, 3000, 2000 },
{ 2000, 1000, 3000, 1000 },
{ 2500, 1000, 5000, 5000 },
{ 2000, 1000, 3000, 2000 },
{ 4000, 1000, 5000, 1000 },
{ 1000, 500, 2000, 4000 },
{ 1000, 500, 2000, 5000 },
{ 2000, 500, 2500, 500 },
{ 1000, 500, 3000, 2000 },
{ 1600, 1000, 2000, 2000 },
{ 2000, 1000, 4000, 2000 },
{ 1500, 1000, 2500, 1000 },
{ 1000, 1000, 5000, 5000 },
{ 0, 0, 0, 0 }
}; };
// --MIAMI: Done // --MIAMI: Done
@ -54,7 +72,7 @@ CPed::ServiceTalkingWhenDead(void)
return m_queuedSound == SOUND_PED_DEATH; return m_queuedSound == SOUND_PED_DEATH;
} }
// --MIAMI: Done except ifdef // --MIAMI: Done
void void
CPed::ServiceTalking(void) CPed::ServiceTalking(void)
{ {
@ -84,7 +102,7 @@ CPed::ServiceTalking(void)
} }
} }
// --MIAMI: Done except ifdef // --MIAMI: Done
void void
CPed::Say(uint16 audio) CPed::Say(uint16 audio)
{ {

View File

@ -52,6 +52,7 @@ public:
bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch); bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch);
bool PointGunAtPosition(CVector const& position); bool PointGunAtPosition(CVector const& position);
void GetComponentPosition(RwV3d &pos, uint32 node); void GetComponentPosition(RwV3d &pos, uint32 node);
void GetComponentPosition(CVector &pos, uint32 node) { GetComponentPosition(*(RwV3d*)pos, node); }
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll); void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch); void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch); void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch);

View File

@ -81,7 +81,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f); m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
m_pPedAtSafePos[i] = nil; m_pPedAtSafePos[i] = nil;
m_pCheckPlayers[i] = nil; m_pMeleeList[i] = nil;
} }
m_nCheckPlayersIndex = 0; m_nCheckPlayersIndex = 0;
m_nPadUpPressedInMilliseconds = 0; m_nPadUpPressedInMilliseconds = 0;
@ -1711,6 +1711,18 @@ CPlayerPed::PlayIdleAnimations(CPad *padUsed)
} }
} }
void
CPlayerPed::RemovePedFromMeleeList(CPed *ped)
{
int i = 0;
for (; m_pMeleeList[i] != ped; i++) {
if (i >= ARRAY_SIZE(m_pMeleeList))
return;
}
m_pMeleeList[i] = nil;
ped->m_attackTimer = 0;
}
#ifdef COMPATIBLE_SAVES #ifdef COMPATIBLE_SAVES
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data)); #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)); #define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));

View File

@ -34,7 +34,7 @@ public:
bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else
CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree
CPed *m_pPedAtSafePos[6]; CPed *m_pPedAtSafePos[6];
CPlayerPed* m_pCheckPlayers[6]; //checks something with players, could be a leftover from original multiplayer CPlayerPed* m_pMeleeList[6];
char unused1; char unused1;
int16 m_nCheckPlayersIndex; int16 m_nCheckPlayersIndex;
float m_fWalkAngle; //angle between heading and walking direction float m_fWalkAngle; //angle between heading and walking direction
@ -84,6 +84,7 @@ public:
void PlayerControlZelda(CPad*); void PlayerControlZelda(CPad*);
bool DoesPlayerWantNewWeapon(eWeaponType, bool); bool DoesPlayerWantNewWeapon(eWeaponType, bool);
void PlayIdleAnimations(CPad*); void PlayIdleAnimations(CPad*);
void RemovePedFromMeleeList(CPed*);
static void SetupPlayerPed(int32); static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32); static void DeactivatePlayerPed(int32);

View File

@ -160,11 +160,11 @@ void CMovingThings::Init()
void CMovingThings::Shutdown() void CMovingThings::Shutdown()
{ {
int i; int i;
for (i = 0; i < 11; ++i) for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
aScrollBars[i].SetVisibility(false); aScrollBars[i].SetVisibility(false);
for (i = 0; i < 2; ++i) for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
aTowerClocks[i].SetVisibility(false); aTowerClocks[i].SetVisibility(false);
for (i = 0; i < 3; ++i) for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
aDigitalClocks[i].SetVisibility(false); aDigitalClocks[i].SetVisibility(false);
} }
@ -186,17 +186,17 @@ void CMovingThings::Update()
aMovingThings[i].Update(); aMovingThings[i].Update();
} }
/* I don't think these are done yet? /* I don't think these are done yet?
for (i = 0; i < 11; ++i) for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
{ {
if (aScrollBars[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0) if (aScrollBars[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0)
aScrollBars[i].Update(); aScrollBars[i].Update();
} }
for (i = 0; i < 2; ++i) for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
{ {
if (aTowerClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0) if (aTowerClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0)
aTowerClocks[i].Update(); aTowerClocks[i].Update();
} }
for (i = 0; i < 3; ++i) for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
{ {
if (aDigitalClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0) if (aDigitalClocks[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0)
aDigitalClocks[i].Update(); aDigitalClocks[i].Update();
@ -209,17 +209,17 @@ void CMovingThings::Render()
CSmokeTrails::Update(); CSmokeTrails::Update();
int i; int i;
for (i = 0; i < 11; ++i) for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
{ {
if (aScrollBars[i].IsVisible()) if (aScrollBars[i].IsVisible())
aScrollBars[i].Render(); aScrollBars[i].Render();
} }
for (i = 0; i < 2; ++i) for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
{ {
if (aTowerClocks[i].IsVisible()) if (aTowerClocks[i].IsVisible())
aTowerClocks[i].Render(); aTowerClocks[i].Render();
} }
for (i = 0; i < 3; ++i) for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
{ {
if (aDigitalClocks[i].IsVisible()) if (aDigitalClocks[i].IsVisible())
aDigitalClocks[i].Render(); aDigitalClocks[i].Render();
@ -320,7 +320,8 @@ const char* FindDigitalClockMessage()
} }
else else
{ {
int temperature = 13.0f - 6.0f * Cos((CClock::GetMinutes() + 60.0f * CClock::GetHours()) * 0.0043611112f - 1.0f); // they didn't use rad2deg here because of 3.14
int temperature = 13.0f - 6.0f * Cos((CClock::GetMinutes() + 60.0f * CClock::GetHours()) / (4.0f * 180.0f / 3.14f) - 1.0f);
String_DigitalClock[0] = '0' + temperature / 10; String_DigitalClock[0] = '0' + temperature / 10;
if (String_DigitalClock[0] == '0') if (String_DigitalClock[0] == '0')
String_DigitalClock[0] = ' '; String_DigitalClock[0] = ' ';
@ -335,7 +336,7 @@ const char* FindDigitalClockMessage()
// ---------- CScrollBar ---------- // ---------- CScrollBar ----------
void CScrollBar::Init(CVector position, uint8 type, float sizeX, float sizeY, float sizeZ, uint8 red, uint8 green, uint8 blue, float scale) void CScrollBar::Init(CVector position, uint8 type, float sizeX, float sizeY, float sizeZ, uint8 red, uint8 green, uint8 blue, float scale)
{ {
for (int i = 0; i < 40; ++i) for (int i = 0; i < ARRAY_SIZE(m_MessageBar); ++i)
m_MessageBar[i] = 0; m_MessageBar[i] = 0;
m_pMessage = ". "; m_pMessage = ". ";
@ -641,16 +642,16 @@ void CScrollBar::Update()
} }
// Scroll // Scroll
for (int i = 0; i < 39; i++) for (int i = 0; i < ARRAY_SIZE(m_MessageBar)-1; i++)
m_MessageBar[i] = m_MessageBar[i + 1]; m_MessageBar[i] = m_MessageBar[i + 1];
m_MessageBar[39] = m_Counter < 5 ? ScrollCharSet[m_pMessage[m_MessageCurrentChar] - ' '][m_Counter] : 0; m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = m_Counter < 5 ? ScrollCharSet[m_pMessage[m_MessageCurrentChar] - ' '][m_Counter] : 0;
// Introduce some random displaying glitches; signs aren't supposed to be perfect :P // Introduce some random displaying glitches; signs aren't supposed to be perfect :P
switch (CGeneral::GetRandomNumber() & 0xFF) switch (CGeneral::GetRandomNumber() & 0xFF)
{ {
case 0x0D: m_MessageBar[39] = 0; break; case 0x0D: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = 0; break;
case 0xE3: m_MessageBar[39] = 0xE3; break; case 0xE3: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = 0xE3; break;
case 0x64: m_MessageBar[39] = ~m_MessageBar[39]; break; case 0x64: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = ~m_MessageBar[ARRAY_SIZE(m_MessageBar)-1]; break;
} }
} }
@ -677,7 +678,7 @@ void CScrollBar::Render()
CVector coronaCoord, screenCoord; CVector coronaCoord, screenCoord;
float screenW, screenH; float screenW, screenH;
for (int i = 1; i < 40; ++i) for (int i = 1; i < ARRAY_SIZE(m_MessageBar); ++i)
{ {
for (int j = 0; j < 5; ++j) for (int j = 0; j < 5; ++j)
{ {

View File

@ -154,8 +154,8 @@ void CHud::Draw()
return; return;
if (m_Wants_To_Draw_Hud && !TheCamera.m_WideScreenOn) { if (m_Wants_To_Draw_Hud && !TheCamera.m_WideScreenOn) {
bool DrawCrossHair = 0; bool DrawCrossHair = false;
bool DrawCrossHairPC = 0; bool DrawCrossHairPC = false;
CPlayerPed *playerPed = FindPlayerPed(); CPlayerPed *playerPed = FindPlayerPed();
eWeaponType WeaponType = playerPed->GetWeapon()->m_eWeaponType; eWeaponType WeaponType = playerPed->GetWeapon()->m_eWeaponType;

View File

@ -165,4 +165,6 @@ public:
static const uint32 nSaveStructSize; static const uint32 nSaveStructSize;
static void SetAllTaxiLights(bool set); static void SetAllTaxiLights(bool set);
}; };
extern CVector vecHunterGunPos;

View File

@ -411,13 +411,13 @@ CBike::ProcessControl(void)
fDx = fDAxisXExtra; fDx = fDAxisXExtra;
if(!(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f) && if(!(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f) &&
GetForward().z > 0.0f) GetForward().z > 0.0f)
res.x -= Max(0.25f*Abs(pBikeHandling->fWheelieAng-GetForward().z), 0.07f); res.x -= Min(0.25f*Abs(pBikeHandling->fWheelieAng-GetForward().z), 0.07f);
else else
res.x = fInAirXRes; res.x = fInAirXRes;
}else if(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f){ }else if(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f){
fDx = fDAxisXExtra; fDx = fDAxisXExtra;
if(GetForward().z < 0.0f) if(GetForward().z < 0.0f)
res.x *= Max(0.3f*Abs(pBikeHandling->fStoppieAng-GetForward().z), 0.1f) + 0.9f; res.x *= Min(0.3f*Abs(pBikeHandling->fStoppieAng-GetForward().z), 0.1f) + 0.9f;
} }
} }
@ -1014,7 +1014,7 @@ CBike::ProcessControl(void)
m_vecAvgSurfaceRight.Normalise(); m_vecAvgSurfaceRight.Normalise();
float lean; float lean;
if(m_nWheelsOnGround == 0) if(m_nWheelsOnGround == 0)
lean = -m_fSteerAngle/DEGTORAD(pHandling->fSteeringLock)*0.5f*GRAVITY*CTimer::GetTimeStep(); lean = -(m_fSteerAngle/DEGTORAD(pHandling->fSteeringLock))*0.5f*GRAVITY*CTimer::GetTimeStep();
else else
lean = DotProduct(m_vecMoveSpeed-initialMoveSpeed, m_vecAvgSurfaceRight); lean = DotProduct(m_vecMoveSpeed-initialMoveSpeed, m_vecAvgSurfaceRight);
lean /= GRAVITY*Max(CTimer::GetTimeStep(), 0.01f); lean /= GRAVITY*Max(CTimer::GetTimeStep(), 0.01f);

View File

@ -957,8 +957,8 @@ CBoat::AddWakePoint(CVector point)
} }
m_avec2dWakePoints[0] = point; m_avec2dWakePoints[0] = point;
m_afWakePointLifeTime[0] = 150.0f; m_afWakePointLifeTime[0] = 150.0f;
if (m_nNumWakePoints < 32) if (m_nNumWakePoints < ARRAY_SIZE(m_afWakePointLifeTime))
++m_nNumWakePoints; m_nNumWakePoints++;
} }
} }
else { else {

View File

@ -663,8 +663,8 @@ PlayAnnouncement(uint8 sound, uint8 station)
void void
ProcessTrainAnnouncements(void) ProcessTrainAnnouncements(void)
{ {
for (int i = 0; i < 3; i++) { for (int i = 0; i < ARRAY_SIZE(StationDist); i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < ARRAY_SIZE(EngineTrackPosition); j++) {
if (!bTrainArrivalAnnounced[i]) { if (!bTrainArrivalAnnounced[i]) {
float preDist = StationDist[i] - 100.0f; float preDist = StationDist[i] - 100.0f;
if (preDist < 0.0f) if (preDist < 0.0f)

View File

@ -22,6 +22,7 @@
#include "Weapon.h" #include "Weapon.h"
#include "WeaponInfo.h" #include "WeaponInfo.h"
#include "World.h" #include "World.h"
#include "SurfaceTable.h"
#define BULLET_LIFETIME (1000) #define BULLET_LIFETIME (1000)
#define NUM_PED_BLOOD_PARTICLES (8) #define NUM_PED_BLOOD_PARTICLES (8)
@ -228,7 +229,7 @@ bool CBulletInfo::TestForSniperBullet(float x1, float x2, float y1, float y2, fl
#ifdef FIX_BUGS // original code is not going work anyway... #ifdef FIX_BUGS // original code is not going work anyway...
CColLine line(PlayerSniperBulletStart, PlayerSniperBulletEnd); CColLine line(PlayerSniperBulletStart, PlayerSniperBulletEnd);
CColBox box; CColBox box;
box.Set(CVector(x1, y1, z1), CVector(x2, y2, z2), 0, 0); box.Set(CVector(x1, y1, z1), CVector(x2, y2, z2), SURFACE_DEFAULT, 0);
return CCollision::TestLineBox(line, box); return CCollision::TestLineBox(line, box);
#else #else
float minP = 0.0f; float minP = 0.0f;

View File

@ -603,18 +603,12 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
newDir.z = 0.01f; newDir.z = 0.01f;
CParticle::AddParticle(PARTICLE_DEBRIS2, bloodPos, newDir); CParticle::AddParticle(PARTICLE_DEBRIS2, bloodPos, newDir);
// TODO(Miami): New particle CVector dropDir(CGeneral::GetRandomNumberInRange(-0.15f, 0.15f), CGeneral::GetRandomNumberInRange(0.1f, 0.35f), 0.f);
/* CVector dropPos(CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_X(50.0f), SCREEN_STRETCH_FROM_RIGHT(50.0f)),
v116.z = 0.0; CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_Y(50.0f), SCREEN_STRETCH_FROM_BOTTOM(50.0f)), 1.f);
v116.x = CGeneral::GetRandomNumberInRange(-0.15f, 0.15f); CParticle::AddParticle(PARTICLE_BLOODDROP, dropPos, dropDir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.15f),
v116.y = CGeneral::GetRandomNumberInRange(0.1f, 0.35f);
v115.x = CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_X(50.0f), SCREEN_STRETCH_FROM_RIGHT(50.0f));
v115.z = 1.0;
v115.y = CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_Y(50.0f), SCREEN_STRETCH_FROM_BOTTOM(50.0f));
CParticle::AddParticle(41, v115, v116, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.15f),
CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 0); CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 0);
*/
} }
if (info->m_AnimToPlay == ASSOCGRP_KNIFE) if (info->m_AnimToPlay == ASSOCGRP_KNIFE)
{ {
@ -705,8 +699,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
{ {
nearCar->VehicleDamage(info->m_nDamage * (0.00075f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB); nearCar->VehicleDamage(info->m_nDamage * (0.00075f * nearCar->pHandling->fMass), gaTempSphereColPoints[0].pieceB);
// TODO(Miami): Particle not in III CParticle::AddParticle(PARTICLE_HEATHAZE, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
// CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
} }
else else
{ {
@ -783,8 +776,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
CParticle::AddParticle(PARTICLE_SPARK, gaTempSphereColPoints[0].point, 0.1f * gaTempSphereColPoints[0].normal, 0, 0.0f, 0, 0, 0, 0); CParticle::AddParticle(PARTICLE_SPARK, gaTempSphereColPoints[0].point, 0.1f * gaTempSphereColPoints[0].normal, 0, 0.0f, 0, 0, 0, 0);
} }
// TODO(Miami): Particle not in III CParticle::AddParticle(PARTICLE_HEATHAZE, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
//CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
if (!damageEntityRegistered) if (!damageEntityRegistered)
{ {
@ -803,6 +795,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
return true; return true;
} }
// --MIAMI: Done except comments
bool bool
CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource) CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
{ {
@ -850,19 +843,40 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
target = threatAttack->GetPosition(); target = threatAttack->GetPosition();
target -= *fireSource; target -= *fireSource;
target *= info->m_fRange / target.Magnitude(); float distToTarget = target.Magnitude();
target *= info->m_fRange / distToTarget;
target += *fireSource; target += *fireSource;
if ( inaccuracy != 0 ) if (shooter == FindPlayerPed() && inaccuracy != 0.f)
{ {
float newInaccuracy = 2.5f * FindPlayerPed()->m_fAttackButtonCounter * (inaccuracy * Min(1.f, 5.f / distToTarget));
if (FindPlayerPed()->bIsDucking)
newInaccuracy *= 0.4f;
target.x += CGeneral::GetRandomNumberInRange(-0.15f, 0.15f) * newInaccuracy;
target.y += CGeneral::GetRandomNumberInRange(-0.15f, 0.15f) * newInaccuracy;
target.z += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * newInaccuracy;
FindPlayerPed()->m_fAttackButtonCounter += info->m_nDamage * 0.04f;
}
else if (inaccuracy > 0.f)
{
if (threatAttack == FindPlayerPed())
{
float speed = Min(0.33f, FindPlayerPed()->m_vecMoveSpeed.Magnitude());
inaccuracy *= (0.3f * speed * 100.f / 33.f + 0.8f);
}
target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy; target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy;
target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy; target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy;
target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracy; target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracy;
} }
CWorld::bIncludeDeadPeds = true; if (shooter == FindPlayerPed())
ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); CWorld::bIncludeDeadPeds = true;
// bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false; CWorld::bIncludeDeadPeds = false;
// bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
} }
else else
{ {
@ -872,7 +886,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
shooterPed->TransformToNode(target, PED_HANDR); shooterPed->TransformToNode(target, PED_HANDR);
ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); // bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
// bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
} }
} }
else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() ) else if ( shooter == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam() )
@ -880,9 +896,17 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
CVector src, trgt; CVector src, trgt;
TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt); TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt);
// bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
CWorld::bIncludeDeadPeds = true; CWorld::bIncludeDeadPeds = true;
ProcessLineOfSight(src, trgt,point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false); // bProcessVehicleWheels = true; // TODO(Miami)
CWorld::ProcessLineOfSight(src, trgt, point, victim, true, true, true, true, true, false, false, true);
// bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
CWorld::bIncludeDeadPeds = false; CWorld::bIncludeDeadPeds = false;
// bProcessVehicleWheels = false; // TODO(Miami)
// TODO(Miami)
// if (victim)
// CWeapon::CheckForShootingVehicleOccupant(v39, victim, point, m_eWeaponType, src, trgt);
int32 rotSpeed = 1; int32 rotSpeed = 1;
if ( m_eWeaponType == WEAPONTYPE_M4 ) if ( m_eWeaponType == WEAPONTYPE_M4 )
@ -897,30 +921,77 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
} }
else else
{ {
float shooterHeading = RADTODEG(shooter->GetForward().Heading()); uint32 model = shooter->GetModelIndex();
float shooterAngle = DEGTORAD(shooterHeading); if (model == MI_HUNTER || model == MI_SEASPAR || model == MI_SPARROW)
CVector2D rotOffset(-Sin(shooterAngle), Cos(shooterAngle));
rotOffset.Normalise();
target = *fireSource;
target.x += rotOffset.x * info->m_fRange;
target.y += rotOffset.y * info->m_fRange;
if ( shooter->IsPed() )
DoDoomAiming(shooter, fireSource, &target);
ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
int32 rotSpeed = 1;
if ( m_eWeaponType == WEAPONTYPE_M4 )
rotSpeed = 4;
CVector bulletPos;
if ( CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4) )
{ {
for ( int32 i = 0; i < 16; i++ ) float inaccuracyMult = 0.6f;
CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed); target = shooter->GetForward();
if (shooter->GetStatus() == STATUS_PLAYER)
{
target *= info->m_fRange;
target += *fireSource;
CWeapon::DoDriveByAutoAiming(FindPlayerPed(), (CVehicle*)shooter, fireSource, &target);
target -= *fireSource;
target.Normalise();
if (model == MI_SEASPAR || model == MI_SPARROW)
inaccuracyMult = 0.1f;
else
inaccuracyMult = 0.3f;
}
target.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracyMult;
target.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracyMult;
target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracyMult;
target.Normalise();
target *= info->m_fRange;
target += *fireSource;
CWorld::pIgnoreEntity = shooter;
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::pIgnoreEntity = nil;
int32 rotSpeed = 1;
if (m_eWeaponType == WEAPONTYPE_M4)
rotSpeed = 4;
CVector bulletPos;
if (CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4))
{
for (int32 i = 0; i < 16; i++)
CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
}
}
else
{
float shooterHeading = RADTODEG(shooter->GetForward().Heading());
float shooterAngle = DEGTORAD(shooterHeading);
CVector2D rotOffset(-Sin(shooterAngle), Cos(shooterAngle));
rotOffset.Normalise();
target = *fireSource;
target.x += rotOffset.x * info->m_fRange;
target.y += rotOffset.y * info->m_fRange;
CParticle::HandleShootableBirdsStuff(shooter, *fireSource);
if (shooter->IsPed() && ((CPed*)shooter)->bDoomAim && (shooter != FindPlayerPed() || !info->m_bCanAim))
{
CWeapon::DoDoomAiming(shooter, fireSource, &target);
}
// CWorld::bProcessPedsOnBoatsAndBikes = 1; // TODO(Miami)
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
// CWorld::bProcessPedsOnBoatsAndBikes = 0; // TODO(Miami)
int32 rotSpeed = 1;
if (m_eWeaponType == WEAPONTYPE_M4)
rotSpeed = 4;
CVector bulletPos;
if (CHeli::TestBulletCollision(fireSource, &target, &bulletPos, 4))
{
for (int32 i = 0; i < 16; i++)
CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
}
} }
} }
@ -940,7 +1011,6 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
if ( shooter == FindPlayerPed() ) if ( shooter == FindPlayerPed() )
{ {
CStats::InstantHitsFiredByPlayer++;
if ( !(CTimer::GetFrameCounter() & 3) ) if ( !(CTimer::GetFrameCounter() & 3) )
MakePedsJumpAtShot((CPhysical*)shooter, fireSource, &target); MakePedsJumpAtShot((CPhysical*)shooter, fireSource, &target);
} }
@ -1353,6 +1423,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
BlowUpExplosiveThings(victim); BlowUpExplosiveThings(victim);
} }
// --MIAMI: Done except comments, and didn't check particle coords precisely
bool bool
CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{ {
@ -1446,7 +1517,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
//bProcessVehicleWheels = true; // TODO(Miami): bProcessVehicleWheels //bProcessVehicleWheels = true; // TODO(Miami): bProcessVehicleWheels
//bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
ProcessLineOfSight(source, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); // TODO(Miami): New parameter: ,true); CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false; CWorld::bIncludeDeadPeds = false;
//bProcessVehicleWheels = false; // TODO(Miami): bProcessVehicleWheels //bProcessVehicleWheels = false; // TODO(Miami): bProcessVehicleWheels
} }
@ -1479,7 +1550,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
CWorld::bIncludeDeadPeds = true; CWorld::bIncludeDeadPeds = true;
//bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes //bProcessPedsOnBoatsAndBikes = true; // TODO(Miami): bProcessPedsOnBoatsAndBikes
ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, false, false); // TODO(Miami): New parameter: ,true); CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false; CWorld::bIncludeDeadPeds = false;
} }
//bProcessPedsOnBoatsAndBikes = false; // TODO(Miami): bProcessPedsOnBoatsAndBikes //bProcessPedsOnBoatsAndBikes = false; // TODO(Miami): bProcessPedsOnBoatsAndBikes
@ -2064,7 +2135,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f, float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f,
float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f); float(CGeneral::GetRandomNumber()&255)*0.01f-1.28f);
DoDriveByAutoAiming(FindPlayerPed(), &source, &target); DoDriveByAutoAiming(FindPlayerPed(), shooter, &source, &target);
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000); CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
@ -2184,6 +2255,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
return true; return true;
} }
// --MIAMI: Done
void void
CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target) CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
{ {
@ -2196,8 +2268,6 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
#endif #endif
CPed *shooterPed = (CPed*)shooter; CPed *shooterPed = (CPed*)shooter;
if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
return;
int16 lastEntity; int16 lastEntity;
CEntity *entities[16]; CEntity *entities[16];
@ -2216,7 +2286,8 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
if ( !(victim->GetStatus() == STATUS_TRAIN_MOVING if ( !(victim->GetStatus() == STATUS_TRAIN_MOVING
|| victim->GetStatus() == STATUS_TRAIN_NOT_MOVING || victim->GetStatus() == STATUS_TRAIN_NOT_MOVING
|| victim->GetStatus() == STATUS_HELI || victim->GetStatus() == STATUS_HELI
|| victim->GetStatus() == STATUS_PLANE) ) || victim->GetStatus() == STATUS_PLANE
|| victim->GetStatus() == STATUS_WRECKED) )
{ {
float distToVictim = (shooterPed->GetPosition()-victim->GetPosition()).Magnitude2D(); float distToVictim = (shooterPed->GetPosition()-victim->GetPosition()).Magnitude2D();
float distToVictimZ = Abs(shooterPed->GetPosition().z-victim->GetPosition().z); float distToVictimZ = Abs(shooterPed->GetPosition().z-victim->GetPosition().z);
@ -2235,7 +2306,10 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
} }
} }
if ( closestEntityDist < DOOMAUTOAIMING_MAXDIST ) CColPoint foundCol;
CEntity *foundEnt;
if (closestEntityDist < DOOMAUTOAIMING_MAXDIST
&& !CWorld::ProcessLineOfSight(*source, entities[closestEntity]->GetPosition(), foundCol, foundEnt, true, false, false, false, false, false, false, true))
{ {
CEntity *victim = entities[closestEntity]; CEntity *victim = entities[closestEntity];
ASSERT(victim !=nil); ASSERT(victim !=nil);
@ -2324,10 +2398,11 @@ CWeapon::DoTankDoomAiming(CEntity *shooter, CEntity *driver, CVector *source, CV
} }
} }
// --MIAMI: Done
void void
CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target) CWeapon::DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target)
{ {
ASSERT(shooter!=nil); ASSERT(driver!=nil);
ASSERT(source!=nil); ASSERT(source!=nil);
ASSERT(target!=nil); ASSERT(target!=nil);
@ -2335,27 +2410,36 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
CEntity entity; // unused CEntity entity; // unused
#endif #endif
CPed *shooterPed = (CPed*)shooter; CPed *shooterPed = (CPed*)driver;
if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
return;
int16 lastEntity; int16 lastEntity;
CEntity *entities[16]; CEntity *peds[16];
CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, entities, false, false, true, false, false); CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, peds, false, false, true, false, false);
float closestEntityDist = 10000.0f; float closestEntityDist = 10000.0f;
int16 closestEntity; int16 closestEntity;
for ( int32 i = 0; i < lastEntity; i++ ) for ( int32 i = 0; i < lastEntity; i++ )
{ {
CEntity *victim = entities[i]; CPed *victim = (CPed*)peds[i];
ASSERT(victim!=nil); ASSERT(victim!=nil);
if ( shooter != victim ) if (driver != victim && !victim->DyingOrDead() && victim->m_attachedTo != vehicle)
{ {
float lineDist = CCollision::DistToLine(source, target, &victim->GetPosition()); float lineDist = CCollision::DistToLine(source, target, &victim->GetPosition());
float distToVictim = (victim->GetPosition() - shooter->GetPosition()).Magnitude();
float pedDist = 0.15f*distToVictim + lineDist; uint32 model = vehicle->GetModelIndex();
float pedDist;
if (model == MI_HUNTER || model == MI_SEASPAR || model == MI_SPARROW)
{
float distToVictim = (victim->GetPosition() - vehicle->GetPosition()).Magnitude();
pedDist = lineDist / Max(5.f, distToVictim);
}
else
{
float distToVictim = (victim->GetPosition() - driver->GetPosition()).Magnitude();
pedDist = 0.15f * distToVictim + lineDist;
}
if ( DotProduct((*target-*source), victim->GetPosition()-*source) > 0.0f && pedDist < closestEntityDist) if ( DotProduct((*target-*source), victim->GetPosition()-*source) > 0.0f && pedDist < closestEntityDist)
{ {
@ -2364,14 +2448,24 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
} }
} }
} }
uint32 model = vehicle->GetModelIndex();
if ( closestEntityDist < DRIVEBYAUTOAIMING_MAXDIST ) float maxAimDistance = CAR_DRIVEBYAUTOAIMING_MAXDIST;
if (model == MI_HUNTER)
{ {
CEntity *victim = entities[closestEntity]; maxAimDistance = Tan(DEGTORAD(30.f));
}
else if (model == MI_SEASPAR || model == MI_SPARROW)
{
maxAimDistance = Tan(DEGTORAD(10.f));
}
if ( closestEntityDist < maxAimDistance )
{
CEntity *victim = peds[closestEntity];
ASSERT(victim!=nil); ASSERT(victim!=nil);
float distToTarget = (*source - *target).Magnitude(); float distToTarget = (*source - *target).Magnitude();
float distToSource = (*source - victim->GetPosition()).Magnitude(); float distToSource = (*source - victim->GetPosition()).Magnitude();
*target = (distToTarget / distToSource) * (victim->GetPosition() - *source) + *source; *target = (distToTarget / distToSource) * (victim->GetPosition() - *source) + *source;
} }
} }

View File

@ -2,7 +2,7 @@
#include "WeaponType.h" #include "WeaponType.h"
#define DRIVEBYAUTOAIMING_MAXDIST (2.5f) #define CAR_DRIVEBYAUTOAIMING_MAXDIST (2.5f)
#define DOOMAUTOAIMING_MAXDIST (9000.0f) #define DOOMAUTOAIMING_MAXDIST (9000.0f)
class CEntity; class CEntity;
@ -56,7 +56,7 @@ public:
static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target); static void DoDoomAiming (CEntity *shooter, CVector *source, CVector *target);
static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target); static void DoTankDoomAiming (CEntity *shooter, CEntity *driver, CVector *source, CVector *target);
static void DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target); static void DoDriveByAutoAiming(CEntity *driver, CVehicle *vehicle, CVector *source, CVector *target);
void Reload(void); void Reload(void);
void Update(int32 audioEntity, CPed *pedToAdjustSound); void Update(int32 audioEntity, CPed *pedToAdjustSound);