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_2ND,
ANIM_MELEE_ATTACK_START,
ANIM_MELEE_IDLE_FIGHTMODE,
ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE,
ANIM_THROWABLE_THROWU,
ANIM_THROWABLE_START_THROW,

View File

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

View File

@ -21,6 +21,7 @@ class CCutsceneMgr
static CAnimBlendAssocGroup ms_cutsceneAssociations;
static CVector ms_cutsceneOffset;
static float ms_cutsceneTimer;
static bool ms_wasCutsceneSkipped;
static bool ms_cutsceneProcessing;
public:
static CDirectory *ms_pCutsceneDir;
@ -30,6 +31,7 @@ public:
static bool IsRunning(void) { return ms_running; }
static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool WasCutsceneSkipped(void) { return ms_wasCutsceneSkipped; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; }
@ -43,6 +45,7 @@ public:
static void FinishCutscene(void);
static void SetupCutsceneToStart(void);
static void SetCutsceneAnim(const char *animName, CObject *pObject);
static void SetCutsceneAnimToLoop(const char *animName);
static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId);
static CCutsceneObject *CreateCutsceneObject(int modelId);
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,
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
CPickup::RemoveKeepType()
{
@ -699,41 +694,51 @@ CPickups::DoPickUpEffects(CEntity *entity)
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;
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;
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;
else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS)
colorId = WEAPONTYPE_TOTALWEAPONS + 3;
else
doInnerGlow = true;
doOuterGlow = false;
} else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) {
colorId = WEAPONTYPE_TOTALWEAPONS;
doInnerGlow = true;
doOuterGlow = false;
} else
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 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);
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);
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;
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
const uint32 CRunningScript::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
136;
@ -2032,7 +2031,13 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
ped->ClearAll();
int8 path = ScriptParams[1];
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);
#endif
ped->SetWanderPath(path);
return 0;
}
@ -2051,10 +2056,11 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
eMoveState state;
switch (ScriptParams[5]) {
case 0: state = PEDMOVE_WALK; break;
case 1: state = PEDMOVE_SPRINT; break;
case 1: state = PEDMOVE_RUN; break;
default: assert(0);
}
ped->ClearAll();
ped->m_pathNodeTimer = 0;
ped->SetFollowPath(pos, radius, state, nil, nil, 999999);
return 0;
}
@ -9126,6 +9132,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL:
{
CollectParameters(&m_nIp, 1);
if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2)
return 0;
#ifdef MISSION_REPLAY
@ -9989,7 +9996,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
continue;
if (pPed->CharCreatedBy != RANDOM_CHAR)
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;
if (pPed->bRemoveFromWorld)
continue;
@ -10633,7 +10640,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
char key[KEY_LENGTH_IN_SCRIPT];
CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
m_nIp += KEY_LENGTH_IN_SCRIPT;
debug("SET_CUTSCENE_ANIM_TO_LOOP not implemented yet, skipping\n");
CCutsceneMgr::SetCutsceneAnimToLoop(key);
return 0;
}
case COMMAND_MARK_CAR_AS_CONVOY_CAR:
@ -10676,7 +10683,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
assert(pTargetPed);
pPed->bScriptObjectiveCompleted = false;
pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pPed);
pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING, pTargetPed);
return 0;
}
//case COMMAND_IS_PICKUP_IN_ZONE:
@ -11332,6 +11339,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
{
CollectParameters(&m_nIp, 2);
debug("ATTACH_CUTSCENE_OBJECT_TO_COMPONENT not implemented, skipping\n"); // TODO(MIAMI)
m_nIp += KEY_LENGTH_IN_SCRIPT;
return 0;
}
case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED:
@ -11457,7 +11465,15 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_FIRE_HUNTER_GUN:
{
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;
}
case COMMAND_SET_PROPERTY_AS_OWNED:
@ -11697,7 +11713,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS:
{
CollectParameters(&m_nIp, 2);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pPed);
pPed->bIgnoreThreatsBehindObjects = ScriptParams[1];
return 0;
@ -11762,12 +11778,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
}
case COMMAND_WAS_CUTSCENE_SKIPPED:
{
static bool bShowed = false;
if (!bShowed) {
debug("COMMAND_WAS_CUTSCENE_SKIPPED not implemented, default to TRUE\n");
bShowed = true;
}
UpdateCompareFlag(true);
UpdateCompareFlag(CCutsceneMgr::WasCutsceneSkipped());
return 0;
}
case COMMAND_SET_CHAR_CROUCH_WHEN_THREATENED:
@ -14220,7 +14231,7 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
pPed->CharCreatedBy = RANDOM_CHAR;
if (pPed->m_nPedType == PEDTYPE_PROSTITUTE)
pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000;
if (pPed->bInVehicle) {
if (pPed->InVehicle()) {
if (pPed->m_pMyVehicle->pDriver == pPed) {
if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle);
@ -14245,10 +14256,14 @@ void CTheScripts::CleanUpThisPed(CPed* pPed)
pPed->ClearObjective();
pPed->bRespondsToThreats = true;
pPed->bScriptObjectiveCompleted = false;
pPed->bKindaStayInSamePlace = false;
pPed->ClearLeader();
if (pPed->IsPedInControl())
pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7);
if (flees) {
if (pPed->m_nPedState == PED_FOLLOW_PATH && state != PED_FOLLOW_PATH)
pPed->ClearFollowPath();
pPed->m_nPedState = state;
pPed->SetMoveState(ms);
}
@ -14451,3 +14466,54 @@ void RetryMission(int type, int unk)
}
#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 RemoveThisPed(CPed* pPed);
#ifdef MISSION_SWITCHER
public:
static void SwitchToMission(int32 mission);
#endif
friend class CRunningScript;
friend class CHud;
friend void CMissionCleanup::Process();
@ -526,6 +531,8 @@ private:
bool CheckDamagedWeaponType(int32 actual, int32 type);
static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami);
friend class CTheScripts;
};
#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))
#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)
{
Init();
@ -670,6 +680,10 @@ CCamera::CamControl(void)
if(CarZoomIndicator != CAM_ZOOM_1STPRS && CarZoomIndicator != CAM_ZOOM_TOPDOWN)
ReqMode = CCam::MODE_CAM_ON_A_STRING;
int vehApp = ((CVehicle*)pTargetEntity)->GetVehicleAppearance();
int vehArrPos = 0;
GetArrPosForVehicleType(vehApp, vehArrPos);
switch(((CVehicle*)pTargetEntity)->m_vehType){
case VEHICLE_TYPE_CAR:
case VEHICLE_TYPE_BIKE:
@ -758,26 +772,26 @@ CCamera::CamControl(void)
}
// Car zoom value
if(CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage){
if (CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage) {
CarZoomValue = 0.0f;
ReqMode = CCam::MODE_1STPERSON;
}
#ifdef FREE_CAM
else if (bFreeCam) {
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)
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)
CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3;
CarZoomValue = LCS_ZOOM_THREE_DISTANCE[vehArrPos];
}
#endif
else if(CarZoomIndicator == CAM_ZOOM_1)
CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_1;
else if (CarZoomIndicator == CAM_ZOOM_1)
CarZoomValue = ZOOM_ONE_DISTANCE[vehArrPos];
else if(CarZoomIndicator == CAM_ZOOM_2)
CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_2;
CarZoomValue = ZOOM_TWO_DISTANCE[vehArrPos];
else if(CarZoomIndicator == CAM_ZOOM_3)
CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_3;
CarZoomValue = ZOOM_THREE_DISTANCE[vehArrPos];
if(CarZoomIndicator == CAM_ZOOM_TOPDOWN && !m_bPlayerIsInGarage){
CarZoomValue = 1.0f;
@ -2960,6 +2974,13 @@ CCamera::Process_Train_Camera_Control(void)
if(node >= m_uiNumberOfTrainCamNodes)
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){
SetWideScreenOn();
@ -3103,26 +3124,42 @@ CCamera::SetZoomValueFollowPedScript(int16 dist)
void
CCamera::SetZoomValueCamStringScript(int16 dist)
{
#ifdef FREE_CAM
if (bFreeCam) {
switch (dist) {
case 0: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; break;
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;
}
}
if (Cams[ActiveCam].CamTargetEntity->IsVehicle()) {
int vehApp = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->GetVehicleAppearance();
int vehArrPos = 0;
GetArrPosForVehicleType(vehApp, vehArrPos);
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

View File

@ -26,20 +26,6 @@ enum
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
class CCam
@ -121,9 +107,8 @@ public:
float f_max_role_angle; //=DEGTORAD(5.0f);
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_fRoadOffSet;
float m_fAmountFractionObscured;
float m_fAlphaSpeedOverOneFrame;
float m_fBetaSpeedOverOneFrame;
@ -208,11 +193,11 @@ public:
void ProcessSpecialHeightRoutines(void);
void GetVectorsReadyForRW(void);
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);
bool RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation);
void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist);
void FixCamWhenObscuredByVehicle(const CVector &TargetCoors);
bool GetBoatLook_L_R_HeightOffset(float &Offset);
void LookBehind(void);
void LookLeft(void);
void LookRight(void);
@ -246,26 +231,14 @@ public:
bool Process_WheelCam(const CVector&, 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_Circle(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);
bool ProcessArrestCamOne(void);
bool ProcessArrestCamTwo(void);
/* Some of the unused PS2 cams */
void Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float, float, float);
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
bool GetLookAlongGroundPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
bool GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
bool GetLookOverShoulderPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, CVector &SourceOut);
// custom stuff
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;
}
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
CColBox::Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece)
{

View File

@ -31,6 +31,7 @@ struct CColSphere : public CSphere
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;
};

View File

@ -134,6 +134,18 @@ public:
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...
static uint16 GetRandomNumber(void)
{ return myrand() & MYRAND_MAX; }

View File

@ -27,7 +27,7 @@ public:
static uint32 GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; }
static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
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 const uint32 &GetFrameCounter(void) { return m_FrameCounter; }
static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; }

View File

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

View File

@ -202,12 +202,11 @@ enum Config {
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
#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
#ifdef DEBUGMENU
#define TOGGLEABLE_BETA_FEATURES // not too many things
#define RELOADABLES // some debug menu options to reload TXD files
#define MISSION_SWITCHER // from debug menu
#endif
// Rendering/display

View File

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

View File

@ -483,6 +483,21 @@ IsLightObject(int16 id)
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
IsBodyPart(int16 id)
{

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -52,6 +52,7 @@ public:
bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch);
bool PointGunAtPosition(CVector const& position);
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 ExtractYawAndPitchLocal(RwMatrix *mat, 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++) {
m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
m_pPedAtSafePos[i] = nil;
m_pCheckPlayers[i] = nil;
m_pMeleeList[i] = nil;
}
m_nCheckPlayersIndex = 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
#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));

View File

@ -34,7 +34,7 @@ public:
bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else
CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree
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;
int16 m_nCheckPlayersIndex;
float m_fWalkAngle; //angle between heading and walking direction
@ -84,6 +84,7 @@ public:
void PlayerControlZelda(CPad*);
bool DoesPlayerWantNewWeapon(eWeaponType, bool);
void PlayIdleAnimations(CPad*);
void RemovePedFromMeleeList(CPed*);
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);

View File

@ -160,11 +160,11 @@ void CMovingThings::Init()
void CMovingThings::Shutdown()
{
int i;
for (i = 0; i < 11; ++i)
for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
aScrollBars[i].SetVisibility(false);
for (i = 0; i < 2; ++i)
for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
aTowerClocks[i].SetVisibility(false);
for (i = 0; i < 3; ++i)
for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
aDigitalClocks[i].SetVisibility(false);
}
@ -186,17 +186,17 @@ void CMovingThings::Update()
aMovingThings[i].Update();
}
/* 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)
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)
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)
aDigitalClocks[i].Update();
@ -209,17 +209,17 @@ void CMovingThings::Render()
CSmokeTrails::Update();
int i;
for (i = 0; i < 11; ++i)
for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
{
if (aScrollBars[i].IsVisible())
aScrollBars[i].Render();
}
for (i = 0; i < 2; ++i)
for (i = 0; i < ARRAY_SIZE(aTowerClocks); ++i)
{
if (aTowerClocks[i].IsVisible())
aTowerClocks[i].Render();
}
for (i = 0; i < 3; ++i)
for (i = 0; i < ARRAY_SIZE(aDigitalClocks); ++i)
{
if (aDigitalClocks[i].IsVisible())
aDigitalClocks[i].Render();
@ -320,7 +320,8 @@ const char* FindDigitalClockMessage()
}
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;
if (String_DigitalClock[0] == '0')
String_DigitalClock[0] = ' ';
@ -335,7 +336,7 @@ const char* FindDigitalClockMessage()
// ---------- CScrollBar ----------
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_pMessage = ". ";
@ -641,16 +642,16 @@ void CScrollBar::Update()
}
// 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[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
switch (CGeneral::GetRandomNumber() & 0xFF)
{
case 0x0D: m_MessageBar[39] = 0; break;
case 0xE3: m_MessageBar[39] = 0xE3; break;
case 0x64: m_MessageBar[39] = ~m_MessageBar[39]; break;
case 0x0D: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = 0; break;
case 0xE3: m_MessageBar[ARRAY_SIZE(m_MessageBar)-1] = 0xE3; 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;
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)
{

View File

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

View File

@ -166,3 +166,5 @@ public:
static void SetAllTaxiLights(bool set);
};
extern CVector vecHunterGunPos;

View File

@ -411,13 +411,13 @@ CBike::ProcessControl(void)
fDx = fDAxisXExtra;
if(!(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 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
res.x = fInAirXRes;
}else if(m_aWheelTimer[BIKESUSP_R1] == 0.0f && m_aWheelTimer[BIKESUSP_R2] == 0.0f){
fDx = fDAxisXExtra;
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();
float lean;
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
lean = DotProduct(m_vecMoveSpeed-initialMoveSpeed, m_vecAvgSurfaceRight);
lean /= GRAVITY*Max(CTimer::GetTimeStep(), 0.01f);

View File

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

View File

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

View File

@ -22,6 +22,7 @@
#include "Weapon.h"
#include "WeaponInfo.h"
#include "World.h"
#include "SurfaceTable.h"
#define BULLET_LIFETIME (1000)
#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...
CColLine line(PlayerSniperBulletStart, PlayerSniperBulletEnd);
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);
#else
float minP = 0.0f;

View File

@ -603,18 +603,12 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
newDir.z = 0.01f;
CParticle::AddParticle(PARTICLE_DEBRIS2, bloodPos, newDir);
// TODO(Miami): New particle
/*
v116.z = 0.0;
v116.x = CGeneral::GetRandomNumberInRange(-0.15f, 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),
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)),
CGeneral::GetRandomNumberInRange(SCREEN_STRETCH_Y(50.0f), SCREEN_STRETCH_FROM_BOTTOM(50.0f)), 1.f);
CParticle::AddParticle(PARTICLE_BLOODDROP, dropPos, dropDir, nil, CGeneral::GetRandomNumberInRange(0.1f, 0.15f),
CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 0);
*/
}
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);
// TODO(Miami): Particle not in III
// CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
CParticle::AddParticle(PARTICLE_HEATHAZE, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
}
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);
}
// TODO(Miami): Particle not in III
//CParticle::AddParticle(81, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
CParticle::AddParticle(PARTICLE_HEATHAZE, gaTempSphereColPoints[0].point, CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
if (!damageEntityRegistered)
{
@ -803,6 +795,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
return true;
}
// --MIAMI: Done except comments
bool
CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
{
@ -850,19 +843,40 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
target = threatAttack->GetPosition();
target -= *fireSource;
target *= info->m_fRange / target.Magnitude();
float distToTarget = target.Magnitude();
target *= info->m_fRange / distToTarget;
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.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f) * inaccuracy;
target.z += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f) * inaccuracy;
}
CWorld::bIncludeDeadPeds = true;
ProcessLineOfSight(*fireSource, target, point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
if (shooter == FindPlayerPed())
CWorld::bIncludeDeadPeds = true;
// bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
// bProcessPedsOnBoatsAndBikes = false; // TODO(Miami)
}
else
{
@ -872,7 +886,9 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
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() )
@ -880,9 +896,17 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
CVector src, trgt;
TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt);
// bProcessPedsOnBoatsAndBikes = true; // TODO(Miami)
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;
// bProcessVehicleWheels = false; // TODO(Miami)
// TODO(Miami)
// if (victim)
// CWeapon::CheckForShootingVehicleOccupant(v39, victim, point, m_eWeaponType, src, trgt);
int32 rotSpeed = 1;
if ( m_eWeaponType == WEAPONTYPE_M4 )
@ -897,30 +921,77 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
}
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;
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) )
uint32 model = shooter->GetModelIndex();
if (model == MI_HUNTER || model == MI_SEASPAR || model == MI_SPARROW)
{
for ( int32 i = 0; i < 16; i++ )
CParticle::AddParticle(PARTICLE_SPARK, bulletPos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, rotSpeed);
float inaccuracyMult = 0.6f;
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() )
{
CStats::InstantHitsFiredByPlayer++;
if ( !(CTimer::GetFrameCounter() & 3) )
MakePedsJumpAtShot((CPhysical*)shooter, fireSource, &target);
}
@ -1353,6 +1423,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
BlowUpExplosiveThings(victim);
}
// --MIAMI: Done except comments, and didn't check particle coords precisely
bool
CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
@ -1446,7 +1517,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
//bProcessVehicleWheels = true; // TODO(Miami): bProcessVehicleWheels
//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;
//bProcessVehicleWheels = false; // TODO(Miami): bProcessVehicleWheels
}
@ -1479,7 +1550,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
CWorld::bIncludeDeadPeds = true;
//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;
}
//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);
DoDriveByAutoAiming(FindPlayerPed(), &source, &target);
DoDriveByAutoAiming(FindPlayerPed(), shooter, &source, &target);
CEventList::RegisterEvent(EVENT_GUNSHOT, EVENT_ENTITY_PED, FindPlayerPed(), FindPlayerPed(), 1000);
@ -2184,6 +2255,7 @@ CWeapon::FireInstantHitFromCar(CVehicle *shooter, bool left, bool right)
return true;
}
// --MIAMI: Done
void
CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
{
@ -2196,8 +2268,6 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
#endif
CPed *shooterPed = (CPed*)shooter;
if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
return;
int16 lastEntity;
CEntity *entities[16];
@ -2216,7 +2286,8 @@ CWeapon::DoDoomAiming(CEntity *shooter, CVector *source, CVector *target)
if ( !(victim->GetStatus() == STATUS_TRAIN_MOVING
|| victim->GetStatus() == STATUS_TRAIN_NOT_MOVING
|| victim->GetStatus() == STATUS_HELI
|| victim->GetStatus() == STATUS_PLANE) )
|| victim->GetStatus() == STATUS_PLANE
|| victim->GetStatus() == STATUS_WRECKED) )
{
float distToVictim = (shooterPed->GetPosition()-victim->GetPosition()).Magnitude2D();
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];
ASSERT(victim !=nil);
@ -2324,10 +2398,11 @@ CWeapon::DoTankDoomAiming(CEntity *shooter, CEntity *driver, CVector *source, CV
}
}
// --MIAMI: Done
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(target!=nil);
@ -2335,27 +2410,36 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
CEntity entity; // unused
#endif
CPed *shooterPed = (CPed*)shooter;
if ( shooterPed->IsPed() && shooterPed->bCrouchWhenShooting )
return;
CPed *shooterPed = (CPed*)driver;
int16 lastEntity;
CEntity *entities[16];
CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, entities, false, false, true, false, false);
CEntity *peds[16];
CWorld::FindObjectsInRange(*source, (*target-*source).Magnitude(), true, &lastEntity, 15, peds, false, false, true, false, false);
float closestEntityDist = 10000.0f;
int16 closestEntity;
for ( int32 i = 0; i < lastEntity; i++ )
{
CEntity *victim = entities[i];
CPed *victim = (CPed*)peds[i];
ASSERT(victim!=nil);
if ( shooter != victim )
if (driver != victim && !victim->DyingOrDead() && victim->m_attachedTo != vehicle)
{
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)
{
@ -2364,14 +2448,24 @@ CWeapon::DoDriveByAutoAiming(CEntity *shooter, CVector *source, CVector *target)
}
}
}
if ( closestEntityDist < DRIVEBYAUTOAIMING_MAXDIST )
uint32 model = vehicle->GetModelIndex();
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);
float distToTarget = (*source - *target).Magnitude();
float distToSource = (*source - victim->GetPosition()).Magnitude();
float distToSource = (*source - victim->GetPosition()).Magnitude();
*target = (distToTarget / distToSource) * (victim->GetPosition() - *source) + *source;
}
}

View File

@ -2,7 +2,7 @@
#include "WeaponType.h"
#define DRIVEBYAUTOAIMING_MAXDIST (2.5f)
#define CAR_DRIVEBYAUTOAIMING_MAXDIST (2.5f)
#define DOOMAUTOAIMING_MAXDIST (9000.0f)
class CEntity;
@ -56,7 +56,7 @@ public:
static void DoDoomAiming (CEntity *shooter, 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 Update(int32 audioEntity, CPed *pedToAdjustSound);