game logic

This commit is contained in:
Nikolay Korolev 2020-05-31 20:59:01 +03:00
parent 49a897c3b3
commit c1c163d78c
20 changed files with 470 additions and 56 deletions

View File

@ -126,10 +126,10 @@ public:
void StartChannel (uint32 nChannel);
void StopChannel (uint32 nChannel);
void PreloadStreamedFile (uint8 nFile, uint8 nStream);
void PreloadStreamedFile (uint32 nFile, uint8 nStream);
void PauseStream (uint8 nPauseFlag, uint8 nStream);
void StartPreloadedStreamedFile (uint8 nStream);
bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
bool StartStreamedFile (uint32 nFile, uint32 nPos, uint8 nStream);
void StopStreamedFile (uint8 nStream);
int32 GetStreamedFilePosition (uint8 nStream);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);

View File

@ -2030,7 +2030,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
if ( m_bInitialised )
{
@ -2081,7 +2081,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool
cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
uint32 position = nPos;
char filename[MAX_PATH];
@ -2287,7 +2287,12 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect
if ( mp3Stream[nStream] )
{
if ( nEffectFlag )
AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
{
if ( nStream == 1 ) // TODO(MIAMI): || nStream == 2 when we have second mission channel?
AIL_set_stream_volume(mp3Stream[nStream], 64*vol*m_nEffectsVolume >> 14);
else
AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
}
else
AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14);

View File

@ -297,7 +297,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
}
@ -315,7 +315,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool
cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );

View File

@ -1168,7 +1168,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
char filename[256];
@ -1226,7 +1226,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool
cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
char filename[256];
@ -1317,8 +1317,12 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect
if ( stream )
{
if ( nEffectFlag )
stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
if ( nEffectFlag ) {
if ( nStream == 1 ) // TODO(MIAMI): || nStream == 2 when we have second mission channel?
stream->SetVolume(64*vol*m_nEffectsVolume >> 14)
else
stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
}
else
stream->SetVolume(m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14);

View File

@ -13,6 +13,7 @@
#include "Font.h"
#include "Text.h"
#include "Vehicle.h"
#include "GameLogic.h"
#define FRENZY_ANY_PED -1
#define FRENZY_ANY_CAR -2
@ -246,6 +247,8 @@ CDarkel::ResetOnPlayerDeath()
void
CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot)
{
CGameLogic::ClearShortCut();
CGameLogic::RemoveShortCutDropOffPointForMission();
eWeaponType fixedWeapon;
if (weaponType == WEAPONTYPE_UZI_DRIVEBY)
fixedWeapon = WEAPONTYPE_UZI;

View File

@ -19,13 +19,42 @@
#include "Fire.h"
#include "Script.h"
#include "Garages.h"
#include "Population.h"
#include "General.h"
#include "DMAudio.h"
#include "Radar.h"
#include "Pools.h"
#include "Hud.h"
#include "Particle.h"
#include "ColStore.h"
#include "Automobile.h"
uint8 CGameLogic::ActivePlayers;
uint8 CGameLogic::ShortCutState;
CAutomobile* CGameLogic::pShortCutTaxi;
uint32 CGameLogic::NumAfterDeathStartPoints;
CVector CGameLogic::ShortCutStart;
float CGameLogic::ShortCutStartOrientation;
CVector CGameLogic::ShortCutDestination;
float CGameLogic::ShortCutDestinationOrientation;
uint32 CGameLogic::ShortCutTimer;
CVector CGameLogic::AfterDeathStartPoints[NUM_SHORTCUT_START_POINTS];
float CGameLogic::AfterDeathStartPointOrientation[NUM_SHORTCUT_START_POINTS];
CVector CGameLogic::ShortCutDropOffForMission;
float CGameLogic::ShortCutDropOffOrientationForMission;
bool CGameLogic::MissionDropOffReadyToBeUsed;
//--MIAMI: file done except TODO
#define SHORTCUT_TAXI_COST (9)
void
CGameLogic::InitAtStartOfGame()
{
ActivePlayers = 1;
ShortCutState = SHORTCUT_NONE;
pShortCutTaxi = nil;
NumAfterDeathStartPoints = 0;
}
void
@ -58,7 +87,10 @@ CGameLogic::SortOutStreamingAndMemory(const CVector &pos)
CStreaming::DeleteRwObjectsAfterDeath(pos);
CStreaming::RemoveUnusedModelsInLoadedList();
CGame::DrasticTidyUpMemory(true);
CWorld::Players[CWorld::PlayerInFocus].m_pPed->Undress("player");
CStreaming::LoadSceneCollision(pos);
CStreaming::LoadScene(pos);
CWorld::Players[CWorld::PlayerInFocus].m_pPed->Dress();
CTimer::Update();
}
@ -70,7 +102,9 @@ CGameLogic::Update()
if (CCutsceneMgr::IsCutsceneProcessing()) return;
UpdateShortCut();
CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus];
switch (pPlayerInfo.m_WBState) {
case WBSTATE_PLAYING:
if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) {
@ -93,7 +127,7 @@ CGameLogic::Update()
if (pPlayerInfo.m_bGetOutOfHospitalFree) {
pPlayerInfo.m_bGetOutOfHospitalFree = false;
} else {
pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - 1000);
pPlayerInfo.m_nMoney = Max(0, pPlayerInfo.m_nMoney - 100);
pPlayerInfo.m_pPed->ClearWeapons();
}
@ -117,17 +151,20 @@ CGameLogic::Update()
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
AfterDeathArrestSetUpShortCutTaxi();
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
TheCamera.m_fCamShakeForce = 0.0f;
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
CPad::GetPad(0)->StopShaking(0);
CReferences::RemoveReferencesToPlayer();
CCarCtrl::CountDownToCarsAtStart = 2;
CPopulation::m_CountDownToPedsAtStart = 10;
CCarCtrl::CountDownToCarsAtStart = 10;
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
if (CRestart::bFadeInAfterNextDeath) {
TheCamera.SetFadeColour(200, 200, 200);
TheCamera.Fade(4.0f, FADE_IN);
} else CRestart::bFadeInAfterNextDeath = true;
} else
CRestart::bFadeInAfterNextDeath = true;
}
break;
case WBSTATE_BUSTED:
@ -135,7 +172,30 @@ CGameLogic::Update()
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(2.0f, FADE_OUT);
}
if (!CTheScripts::IsPlayerOnAMission() && pPlayerInfo.m_nBustedAudioStatus == 0) {
if (CGeneral::GetRandomNumberInRange(0, 4) == 0)
pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_DONE;
else {
pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_LOADING;
char name[12];
sprintf(name, pPlayerInfo.m_nCurrentBustedAudio >= 10 ? "bust_%d" : "bust_0%d", pPlayerInfo.m_nCurrentBustedAudio);
DMAudio.ClearMissionAudio(); // TODO(MIAMI): argument is 0
DMAudio.PreloadMissionAudio(name); // TODO(MIAMI): argument is 0
pPlayerInfo.m_nCurrentBustedAudio = pPlayerInfo.m_nCurrentBustedAudio % 28 + 1; // enum? const? TODO
}
}
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 4000 &&
pPlayerInfo.m_nBustedAudioStatus == BUSTEDAUDIO_LOADING &&
DMAudio.GetMissionAudioLoadingStatus() == 1) { // TODO: argument is 0
DMAudio.PlayLoadedMissionAudio(); // TODO: argument is 0
pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_DONE;
}
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
#ifdef FIX_BUGS
pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
#endif
pPlayerInfo.m_WBState = WBSTATE_PLAYING;
int takeMoney;
@ -188,18 +248,21 @@ CGameLogic::Update()
CRestart::OverridePoliceStationLevel = LEVEL_NONE;
PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
AfterDeathArrestSetUpShortCutTaxi();
pPlayerInfo.m_pPed->ClearWeapons();
SortOutStreamingAndMemory(pPlayerInfo.GetPos());
TheCamera.m_fCamShakeForce = 0.0f;
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
CPad::GetPad(0)->StopShaking(0);
CReferences::RemoveReferencesToPlayer();
CCarCtrl::CountDownToCarsAtStart = 2;
CPopulation::m_CountDownToPedsAtStart = 10;
CCarCtrl::CountDownToCarsAtStart = 10;
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
if (CRestart::bFadeInAfterNextArrest) {
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(4.0f, FADE_IN);
} else CRestart::bFadeInAfterNextArrest = true;
} else
CRestart::bFadeInAfterNextArrest = true;
}
break;
case WBSTATE_FAILED_CRITICAL_MISSION:
@ -233,7 +296,8 @@ CGameLogic::Update()
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
CPad::GetPad(0)->StopShaking(0);
CReferences::RemoveReferencesToPlayer();
CCarCtrl::CountDownToCarsAtStart = 2;
CPopulation::m_CountDownToPedsAtStart = 10;
CCarCtrl::CountDownToCarsAtStart = 10;
CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(4.0f, FADE_IN);
@ -247,11 +311,14 @@ CGameLogic::Update()
void
CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle)
{
pPlayerPed->m_fHealth = 100.0f;
ClearShortCut();
CPlayerInfo* pPlayerInfo = pPlayerPed->GetPlayerInfoForThisPlayerPed();
pPlayerPed->m_fHealth = pPlayerInfo->m_nMaxHealth;
pPlayerPed->m_fArmour = 0.0f;
pPlayerPed->bIsVisible = true;
pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
pPlayerPed->bDoBloodyFootprints = false;
//TODO(MIAMI): clear drunk stuff
pPlayerPed->ClearAdrenaline();
pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
if (pPlayerPed->m_pFire)
@ -260,27 +327,258 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
pPlayerPed->m_pMyVehicle = nil;
pPlayerPed->m_pVehicleAnim = nil;
pPlayerPed->m_pWanted->Reset();
pPlayerPed->bCancelEnteringCar = false;
pPlayerPed->RestartNonPartialAnims();
pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false);
pPlayerInfo->MakePlayerSafe(false);
pPlayerPed->bRemoveFromWorld = false;
pPlayerPed->ClearWeaponTarget();
pPlayerPed->SetInitialState();
CCarCtrl::ClearInterestingVehicleList();
pos.z += 1.0f;
pPlayerPed->Teleport(pos);
pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f));
pPlayerPed->Teleport(pos + CVector(0.0f, 0.0f, 1.0f));
pPlayerPed->SetMoveSpeed(0.0f, 0.0f, 0.0f);
pPlayerPed->m_fRotationCur = DEGTORAD(angle);
pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur;
pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur);
CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed);
CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
pPlayerPed->RestoreHeadingRate();
CGame::currArea = AREA_MAIN_MAP;
//CStreaming::RemoveBuildingsNotInArea(0); // TODO(MIAMI)
TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
TheCamera.Restore();
CReferences::RemoveReferencesToPlayer();
CGarages::PlayerArrestedOrDied();
CStats::CheckPointReachedUnsuccessfully();
CWorld::Remove(pPlayerPed);
CWorld::Add(pPlayerPed);
//CHud::ResetWastedText() // TODO(MIAMI)
CStreaming::StreamZoneModels(pos);
clearWaterDrop = true;
}
void
CGameLogic::ClearShortCut()
{
if (pShortCutTaxi) {
if (pShortCutTaxi->VehicleCreatedBy == MISSION_VEHICLE) {
pShortCutTaxi->VehicleCreatedBy = RANDOM_VEHICLE;
--CCarCtrl::NumMissionCars;
++CCarCtrl::NumRandomCars;
}
CRadar::ClearBlipForEntity(BLIP_CAR, CPools::GetVehiclePool()->GetIndex(pShortCutTaxi));
pShortCutTaxi = nil;
}
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_SHORTCUT_TAXI);
}
void
CGameLogic::SetUpShortCut(CVector vStartPos, float fStartAngle, CVector vEndPos, float fEndAngle)
{
ClearShortCut();
ShortCutState = SHORTCUT_INIT;
ShortCutStart = vStartPos;
ShortCutStartOrientation = fStartAngle;
ShortCutDestination = vEndPos;
ShortCutDestinationOrientation = fEndAngle;
CStreaming::RequestModel(MI_KAUFMAN, 0);
}
void
CGameLogic::AbandonShortCutIfTaxiHasBeenMessedWith()
{
if (!pShortCutTaxi)
return;
if (pShortCutTaxi->pDriver == nil ||
pShortCutTaxi->pDriver->DyingOrDead() ||
pShortCutTaxi->pDriver->GetPedState() == PED_DRAG_FROM_CAR ||
pShortCutTaxi->pDriver->GetPedState() == PED_ON_FIRE ||
pShortCutTaxi->pDriver->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE ||
pShortCutTaxi->m_fHealth < 250.0f ||
pShortCutTaxi->bRenderScorched)
ClearShortCut();
}
void
CGameLogic::AbandonShortCutIfPlayerMilesAway()
{
if (!pShortCutTaxi)
return;
if ((FindPlayerCoors() - pShortCutTaxi->GetPosition()).Magnitude() > 120.0f)
ClearShortCut();
}
void
CGameLogic::UpdateShortCut()
{
switch (ShortCutState) {
case SHORTCUT_INIT:
if (!CStreaming::HasModelLoaded(MI_KAUFMAN)) {
CStreaming::RequestModel(MI_KAUFMAN, 0);
return;
}
pShortCutTaxi = new CAutomobile(MI_KAUFMAN, RANDOM_VEHICLE);
if (!pShortCutTaxi)
return;
pShortCutTaxi->SetPosition(ShortCutStart);
pShortCutTaxi->SetHeading(DEGTORAD(ShortCutStartOrientation));
pShortCutTaxi->PlaceOnRoadProperly();
pShortCutTaxi->SetStatus(STATUS_PHYSICS);
pShortCutTaxi->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER;
pShortCutTaxi->AutoPilot.m_nCruiseSpeed = 0;
pShortCutTaxi->SetUpDriver();
pShortCutTaxi->VehicleCreatedBy = MISSION_VEHICLE;
++CCarCtrl::NumMissionCars;
--CCarCtrl::NumRandomCars;
CTheScripts::ClearSpaceForMissionEntity(ShortCutStart, pShortCutTaxi);
CWorld::Add(pShortCutTaxi);
CRadar::SetEntityBlip(BLIP_CAR, CPools::GetVehiclePool()->GetIndex(pShortCutTaxi), 0, BLIP_DISPLAY_MARKER_ONLY);
ShortCutState = SHORTCUT_IDLE;
break;
case SHORTCUT_IDLE:
if (FindPlayerPed()->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && FindPlayerPed()->m_carInObjective == pShortCutTaxi) {
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_SHORTCUT_TAXI);
FindPlayerPed()->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, pShortCutTaxi);
ShortCutState = SHORTCUT_GETTING_IN;
}
AbandonShortCutIfTaxiHasBeenMessedWith();
AbandonShortCutIfPlayerMilesAway();
break;
case SHORTCUT_GETTING_IN:
if (pShortCutTaxi->pPassengers[0] == FindPlayerPed() ||
pShortCutTaxi->pPassengers[1] == FindPlayerPed() ||
pShortCutTaxi->pPassengers[2] == FindPlayerPed()) {
pShortCutTaxi->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
pShortCutTaxi->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2500;
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(2.5f, 0);
ShortCutState = SHORTCUT_TRANSITION;
ShortCutTimer = CTimer::GetTimeInMilliseconds() + 3000;
CMessages::AddBigMessage(TheText.Get("TAXI"), 4500, 1);
}
AbandonShortCutIfTaxiHasBeenMessedWith();
break;
case SHORTCUT_TRANSITION:
if (CTimer::GetTimeInMilliseconds() > ShortCutTimer) {
CTimer::Suspend();
CColStore::RequestCollision(ShortCutDestination);
CStreaming::LoadSceneCollision(ShortCutDestination);
CStreaming::LoadScene(ShortCutDestination);
CTheScripts::ClearSpaceForMissionEntity(ShortCutDestination, pShortCutTaxi);
pShortCutTaxi->Teleport(ShortCutDestination);
pShortCutTaxi->SetHeading(DEGTORAD(ShortCutDestinationOrientation));
pShortCutTaxi->PlaceOnRoadProperly();
pShortCutTaxi->SetMoveSpeed(pShortCutTaxi->GetForward() * 0.4f);
ShortCutTimer = CTimer::GetTimeInMilliseconds() + 1500;
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, 1);
ShortCutState = SHORTCUT_ARRIVING;
CTimer::Resume();
}
break;
case SHORTCUT_ARRIVING:
if (CTimer::GetTimeInMilliseconds() > ShortCutTimer) {
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - SHORTCUT_TAXI_COST);
FindPlayerPed()->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pShortCutTaxi);
FindPlayerPed()->m_carInObjective = pShortCutTaxi;
ShortCutState = SHORTCUT_GETTING_OUT;
}
AbandonShortCutIfTaxiHasBeenMessedWith();
break;
case SHORTCUT_GETTING_OUT:
if (pShortCutTaxi->pPassengers[0] != FindPlayerPed() &&
pShortCutTaxi->pPassengers[1] != FindPlayerPed() &&
pShortCutTaxi->pPassengers[2] != FindPlayerPed()) {
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_SHORTCUT_TAXI);
pShortCutTaxi->AutoPilot.m_nCarMission = MISSION_CRUISE;
pShortCutTaxi->AutoPilot.m_nCruiseSpeed = 18;
CCarCtrl::JoinCarWithRoadSystem(pShortCutTaxi);
pShortCutTaxi->VehicleCreatedBy = RANDOM_VEHICLE;
++CCarCtrl::NumRandomCars;
--CCarCtrl::NumMissionCars;
CRadar::ClearBlipForEntity(BLIP_CAR, CPools::GetVehiclePool()->GetIndex(pShortCutTaxi));
ShortCutState = SHORTCUT_NONE;
pShortCutTaxi = nil;
}
AbandonShortCutIfTaxiHasBeenMessedWith();
break;
}
}
void
CGameLogic::AddShortCutPointAfterDeath(CVector point, float angle)
{
if (NumAfterDeathStartPoints >= NUM_SHORTCUT_START_POINTS)
return;
AfterDeathStartPoints[NumAfterDeathStartPoints] = point;
AfterDeathStartPointOrientation[NumAfterDeathStartPoints] = angle;
NumAfterDeathStartPoints++;
}
void
CGameLogic::AddShortCutDropOffPointForMission(CVector point, float angle)
{
ShortCutDropOffForMission = point;
ShortCutDropOffOrientationForMission = angle;
MissionDropOffReadyToBeUsed = true;
}
void
CGameLogic::RemoveShortCutDropOffPointForMission()
{
MissionDropOffReadyToBeUsed = false;
}
void
CGameLogic::AfterDeathArrestSetUpShortCutTaxi()
{
if (!MissionDropOffReadyToBeUsed)
return;
int nClosestPoint = -1;
float fDistanceToPoint = 999999.9f;
for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
float dist = (AfterDeathStartPoints[i] - FindPlayerCoors()).Magnitude();
if (dist < fDistanceToPoint) {
fDistanceToPoint = dist;
nClosestPoint = i;
}
}
if (fDistanceToPoint < 100.0f)
SetUpShortCut(AfterDeathStartPoints[nClosestPoint],
AfterDeathStartPointOrientation[nClosestPoint],
ShortCutDropOffForMission,
ShortCutDropOffOrientationForMission);
MissionDropOffReadyToBeUsed = false;
}
void
CGameLogic::Save(uint8* buf, uint32* size)
{
INITSAVEBUF
WriteSaveBuf(buf, NumAfterDeathStartPoints);
*size += sizeof(NumAfterDeathStartPoints);
for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
WriteSaveBuf(buf, AfterDeathStartPoints[i].x);
*size += sizeof(AfterDeathStartPoints[i].x);
WriteSaveBuf(buf, AfterDeathStartPoints[i].y);
*size += sizeof(AfterDeathStartPoints[i].y);
WriteSaveBuf(buf, AfterDeathStartPoints[i].z);
*size += sizeof(AfterDeathStartPoints[i].z);
WriteSaveBuf(buf, AfterDeathStartPointOrientation[i]);
*size += sizeof(AfterDeathStartPointOrientation[i]);
}
VALIDATESAVEBUF(*size)
}
void
CGameLogic::Load(uint8* buf, uint32 size)
{
INITSAVEBUF
NumAfterDeathStartPoints = ReadSaveBuf<uint32>(buf);
for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
AfterDeathStartPoints[i].x = ReadSaveBuf<float>(buf);
AfterDeathStartPoints[i].y = ReadSaveBuf<float>(buf);
AfterDeathStartPoints[i].z = ReadSaveBuf<float>(buf);
AfterDeathStartPointOrientation[i] = ReadSaveBuf<float>(buf);
}
VALIDATESAVEBUF(size)
}

View File

@ -1,13 +1,51 @@
#pragma once
class CAutomobile;
class CGameLogic
{
public:
enum {
SHORTCUT_NONE = 0,
SHORTCUT_INIT,
SHORTCUT_IDLE,
SHORTCUT_GETTING_IN,
SHORTCUT_TRANSITION,
SHORTCUT_ARRIVING,
SHORTCUT_GETTING_OUT
};
static void InitAtStartOfGame();
static void PassTime(uint32 time);
static void SortOutStreamingAndMemory(const CVector &pos);
static void Update();
static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle);
static void ClearShortCut();
static void SetUpShortCut(CVector, float, CVector, float);
static void AbandonShortCutIfTaxiHasBeenMessedWith();
static void AbandonShortCutIfPlayerMilesAway();
static void UpdateShortCut();
static void AddShortCutPointAfterDeath(CVector, float);
static void AddShortCutDropOffPointForMission(CVector, float);
static void RemoveShortCutDropOffPointForMission();
static void AfterDeathArrestSetUpShortCutTaxi();
static void Save(uint8*, uint32*);
static void Load(uint8*, uint32);
static uint8 ActivePlayers;
static uint8 ShortCutState;
static CAutomobile* pShortCutTaxi;
static uint32 NumAfterDeathStartPoints;
static CVector ShortCutStart;
static float ShortCutStartOrientation;
static CVector ShortCutDestination;
static float ShortCutDestinationOrientation;
static uint32 ShortCutTimer;
static CVector AfterDeathStartPoints[NUM_SHORTCUT_START_POINTS];
static float AfterDeathStartPointOrientation[NUM_SHORTCUT_START_POINTS];
static CVector ShortCutDropOffForMission;
static float ShortCutDropOffOrientationForMission;
static bool MissionDropOffReadyToBeUsed;
};

View File

@ -26,6 +26,7 @@
#include "Fire.h"
#include "Frontend.h"
#include "Gangs.h"
#include "GameLogic.h"
#include "Garages.h"
#include "General.h"
#include "HandlingMgr.h"
@ -300,7 +301,7 @@ void CMissionCleanup::Process()
//DMAudio::ShutUpPlayerTalking(0);
CVehicle::bDisableRemoteDetonation = false;
CVehicle::bDisableRemoteDetonationOnContact = false;
//CGameLogic::ClearShortCut(); // TODO(MIAMI)
CGameLogic::ClearShortCut();
CTheScripts::RiotIntensity = 0;
CTheScripts::StoreVehicleIndex = -1;
CTheScripts::StoreVehicleWasRandom = true;
@ -6506,7 +6507,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
++CStats::MissionsPassed;
CStats::CheckPointReachedSuccessfully();
CTheScripts::LastMissionPassedTime = CTimer::GetTimeInMilliseconds();
//CGameLogic::RemoveShortCutDropOffPointForMission() // TODO(MIAMI)
CGameLogic::RemoveShortCutDropOffPointForMission();
return 0;
}
case COMMAND_SET_CHAR_RUNNING:
@ -7153,13 +7154,8 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CTheScripts::ReadTextLabelFromScript(&m_nIp, name);
for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
name[i] = tolower(name[i]);
int mi = pPed->GetModelIndex();
pPed->DeleteRwObject();
if (pPed->IsPlayer())
mi = 0;
CStreaming::RequestSpecialModel(mi, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
m_nIp += KEY_LENGTH_IN_SCRIPT;
CWorld::Remove(pPed);
pPed->Undress(name);
return 0;
}
case COMMAND_DRESS_CHAR:
@ -7167,10 +7163,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pPed);
int mi = pPed->GetModelIndex();
pPed->m_modelIndex = -1;
pPed->SetModelIndex(mi);
CWorld::Add(pPed);
pPed->Dress();
return 0;
}
/*
@ -9045,7 +9038,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
pMissionScript->m_bIsMissionScript = true;
pMissionScript->m_bMissionFlag = true;
CTheScripts::bAlreadyRunningAMissionScript = true;
//CGameLogic::ClearShortcut(); // TODO(MIAMI)
CGameLogic::ClearShortCut();
return 0;
}
case COMMAND_SET_OBJECT_DRAW_LAST:
@ -11440,11 +11433,13 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_SET_UP_TAXI_SHORTCUT:
{
CollectParameters(&m_nIp, 8);
debug("SET_UP_TAXI_SHORTCUT is not implemented\n"); // TODO(MIAMI)
CGameLogic::SetUpShortCut(
*(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3],
*(CVector*)&ScriptParams[4], *(float*)&ScriptParams[7]);
return 0;
}
case COMMAND_CLEAR_TAXI_SHORTCUT:
debug("CLEAR_TAXI_SHORTCUT is not implemented\n"); // TODO(MIAMI)
CGameLogic::ClearShortCut();
return 0;
//case COMMAND_SET_CHAR_OBJ_GOTO_CAR_ON_FOOT:
//case COMMAND_GET_CLOSEST_WATER_NODE:
@ -11910,13 +11905,13 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
case COMMAND_SET_SHORTCUT_PICKUP_POINT:
{
CollectParameters(&m_nIp, 4);
debug("SET_SHORTCUT_PICKUP_POINT not implemented, skipping\n");
CGameLogic::AddShortCutPointAfterDeath(*(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3]);
return 0;
}
case COMMAND_SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION:
{
CollectParameters(&m_nIp, 4);
debug("SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION not implemented, skipping");
CGameLogic::AddShortCutDropOffPointForMission(*(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3]);
return 0;
}
case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA:
@ -11948,16 +11943,14 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
++CStats::MissionsPassed;
CStats::CheckPointReachedSuccessfully();
CTheScripts::LastMissionPassedTime = CTimer::GetTimeInMilliseconds();
// CGameLogic::RemoveShortCutDropOffPointForMission(); // TODO(MIAMI)
CGameLogic::RemoveShortCutDropOffPointForMission();
return 0;
case COMMAND_IS_PLAYER_IN_SHORTCUT_TAXI:
{
CollectParameters(&m_nIp, 1);
static bool bShowed = false;
if (!bShowed) {
debug("IS_PLAYER_IN_SHORTCUT_TAXI not implemented, default to FALSE\n");
bShowed = true;
}
UpdateCompareFlag(false);
CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
assert(pPed);
UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle && pPed->m_pMyVehicle == CGameLogic::pShortCutTaxi);
return 0;
}
case COMMAND_IS_CHAR_DUCKING:
@ -11980,6 +11973,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
return 0;
case COMMAND_IS_AUSTRALIAN_GAME:
UpdateCompareFlag(false); // should we make some check?
return 0;
case COMMAND_DISARM_CAR_BOMB:
{
CollectParameters(&m_nIp, 1);

View File

@ -3123,7 +3123,7 @@ CCamera::Fade(float timeout, int16 direction)
void
CCamera::SetFadeColour(uint8 r, uint8 g, uint8 b)
{
m_FadeTargetIsSplashScreen = r == 0 && g == 0 && b == 0;
m_FadeTargetIsSplashScreen = r == 2 && g == 2 && b == 2;
CDraw::FadeRed = r;
CDraw::FadeGreen = g;
CDraw::FadeBlue = b;

View File

@ -15,6 +15,7 @@
#include "DamageManager.h"
#include "Ped.h"
#include "Fire.h"
#include "GameLogic.h"
CFireManager gFireManager;
@ -59,6 +60,12 @@ CFire::ProcessFire(void)
Extinguish();
return;
}
#if defined GTAVC_JP_PATCH && !defined FIX_BUGS
if (m_pEntity == CGameLogic::pShortCutTaxi && CGameLogic::ShortCutState == CGameLogic::SHORTCUT_TRANSITION) {
Extinguish();
return;
}
#endif
if (ped->m_nMoveState != PEDMOVE_RUN)
m_vecPos.z -= 1.0f;
if (ped->bInVehicle && ped->m_pMyVehicle) {
@ -84,6 +91,12 @@ CFire::ProcessFire(void)
Extinguish();
return;
}
#ifdef FIX_BUGS
if (m_pEntity == CGameLogic::pShortCutTaxi && CGameLogic::ShortCutState == CGameLogic::SHORTCUT_TRANSITION) {
Extinguish();
return;
}
#endif
if (!m_bIsScriptFire) {
fDamageVehicle = 1.2f * CTimer::GetTimeStep();
veh->InflictDamage((CVehicle *)m_pSource, WEAPONTYPE_FLAMETHROWER, fDamageVehicle);

View File

@ -523,6 +523,7 @@ void CGame::ShutDownForRestart(void)
CTheScripts::UndoBuildingSwaps();
CTheScripts::UndoEntityInvisibilitySettings();
CWorld::ClearForRestart();
CGameLogic::ClearShortCut();
CTimer::Shutdown();
CStreaming::FlushRequestList();
CStreaming::DeleteAllRwObjects();

View File

@ -10,6 +10,7 @@ enum {
PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe
PLAYERCONTROL_DISABLED_40 = 64, // used on phone calls
PLAYERCONTROL_DISABLED_80 = 128,// used on cutscenes
PLAYERCONTROL_SHORTCUT_TAXI = 256,
};
class CControllerState
@ -150,10 +151,10 @@ public:
int16 Phase;
int16 Mode;
int16 ShakeDur;
uint16 DisablePlayerControls;
uint8 ShakeFreq;
bool bHornHistory[HORNHISTORY_SIZE];
uint8 iCurrHornHistory;
uint8 DisablePlayerControls;
int8 bApplyBrakes;
char CheatString[12];
int32 LastTimeTouched;
@ -449,9 +450,9 @@ public:
int16 GetRightStickY(void) { return NewState.RightStickY; }
bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; }
void SetDisablePlayerControls(uint8 who) { DisablePlayerControls |= who; }
void SetEnablePlayerControls(uint8 who) { DisablePlayerControls &= ~who; }
bool IsPlayerControlsDisabledBy(uint8 who) { return DisablePlayerControls & who; }
void SetDisablePlayerControls(uint16 who) { DisablePlayerControls |= who; }
void SetEnablePlayerControls(uint16 who) { DisablePlayerControls &= ~who; }
bool IsPlayerControlsDisabledBy(uint16 who) { return DisablePlayerControls & who; }
};
VALIDATE_SIZE(CPad, 0xFC);

View File

@ -146,6 +146,8 @@ CPlayerInfo::Clear(void)
m_bDriveByAllowed = true;
m_nPreviousTimeRewardedForExplosion = 0;
m_nExplosionsSinceLastReward = 0;
m_nCurrentBustedAudio = 1;
m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
}
void

View File

@ -10,6 +10,13 @@ enum eWastedBustedState
WBSTATE_FAILED_CRITICAL_MISSION,
};
enum eBustedAudioState : uint8
{
BUSTEDAUDIO_NONE,
BUSTEDAUDIO_LOADING,
BUSTEDAUDIO_DONE
};
class CEntity;
class CPed;
class CVehicle;
@ -60,6 +67,8 @@ public:
bool m_bGetOutOfJailFree;
bool m_bGetOutOfHospitalFree;
bool m_bDriveByAllowed;
eBustedAudioState m_nBustedAudioStatus;
int16 m_nCurrentBustedAudio;
char m_aSkinName[32];
RwTexture *m_pSkinTexture;

View File

@ -1,6 +1,6 @@
#include "common.h"
#include "GameLogic.h"
#include "Hud.h"
#include "PlayerPed.h"
#include "Replay.h"
@ -99,7 +99,7 @@ void
CCurrentVehicle::Display()
{
wchar *text = nil;
if (m_pCurrentVehicle != nil)
if (m_pCurrentVehicle != nil && m_pCurrentVehicle != CGameLogic::pShortCutTaxi)
text = TheText.Get(((CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pCurrentVehicle->GetModelIndex()))->m_gameName);
CHud::SetVehicleName(text);
}

View File

@ -137,7 +137,8 @@ enum Config {
NUM_EXPLOSIONS = 48,
NUM_SETPIECES = 96
NUM_SETPIECES = 96,
NUM_SHORTCUT_START_POINTS = 16
};
// We'll use this once we're ready to become independent of the game
@ -167,6 +168,7 @@ enum Config {
#elif defined GTA_PC
# define GTA3_1_1_PATCH
//# define GTA3_STEAM_PATCH
//# define GTAVC_JP_PATCH
# ifdef GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2

View File

@ -60,6 +60,7 @@
#include "Streaming.h"
#include "PedAttractor.h"
#include "Debug.h"
#include "GameLogic.h"
#define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f)
@ -16228,6 +16229,12 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
return;
}
if (!someoneExitsFromOurExitDoor || m_nPedType == PEDTYPE_COP && veh->bIsBus) {
#if defined GTAVC_JP_PATCH || defined FIX_BUGS
if (veh->pDriver == this && !IsPlayer() && veh == CGameLogic::pShortCutTaxi) {
m_objective = OBJECTIVE_NONE;
return;
}
#endif
// Again, unused...
// CVector exitPos = GetPositionToOpenCarDoor(veh, optedDoorNode);
bool thereIsRoom = veh->IsRoomForPedToLeaveCar(optedDoorNode, nil);
@ -18666,6 +18673,35 @@ CPed::CanBeDamagedByThisGangMember(CPed* who)
return m_gangFlags & (1 << (uint8)(who->m_nPedType - PEDTYPE_GANG1));
}
void
CPed::Undress(const char* name)
{
int mi = GetModelIndex();
CAnimBlendAssociation* pAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_OUT);
//if (pAnim)
// FinishTalkingOnMobileCB(pAnim, this); // TODO(MIAMI)
DeleteRwObject();
if (m_nPedType == PEDTYPE_PLAYER1)
mi = MI_PLAYER;
CStreaming::RequestSpecialModel(mi, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
CWorld::Remove(this);
}
void
CPed::Dress(void)
{
int mi = GetModelIndex();
m_modelIndex = -1;
SetModelIndex(mi);
m_nPedState = PED_IDLE;
m_nLastPedState = PED_NONE;
m_objective = OBJECTIVE_NONE;
m_prevObjective = OBJECTIVE_NONE;
m_nWaitState = WAITSTATE_FALSE;
CWorld::Add(this);
m_headingRate = m_pedStats->m_headingChangeRate;
}
bool
IsPedPointerValid_NotInWorld(CPed* pPed)
{

View File

@ -916,6 +916,8 @@ public:
void SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float, float, int);
void ClearWaitState(void);
void Undress(const char*);
void Dress(void);
bool HasWeaponSlot(uint8 slot) { return m_weapons[slot].m_eWeaponType != WEAPONTYPE_UNARMED; }
CWeapon& GetWeapon(uint8 slot) { return m_weapons[slot]; }

View File

@ -97,4 +97,6 @@ public:
static void HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos);
};
extern bool clearWaterDrop;
VALIDATE_SIZE(CParticle, 0x58);

View File

@ -84,6 +84,7 @@ do {\
#define WriteSaveDataBlock(save_func)\
do {\
size = 0;\
buf = work_buff;\
reserved = 0;\
MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\
@ -192,6 +193,7 @@ GenericSave(int file)
// Save the rest
WriteSaveDataBlock(CPools::SavePedPool);
WriteSaveDataBlock(CGarages::Save);
WriteSaveDataBlock(CGameLogic::Save);
WriteSaveDataBlock(CPools::SaveVehiclePool);
WriteSaveDataBlock(CPools::SaveObjectPool);
WriteSaveDataBlock(ThePaths.Save);
@ -306,6 +308,8 @@ GenericLoad()
LoadSaveDataBlock();
ReadDataFromBlock("Loading Garages \n", CGarages::Load);
LoadSaveDataBlock();
ReadDataFromBlock("Loading GameLogic \n", CGameLogic::Load);
LoadSaveDataBlock();
ReadDataFromBlock("Loading Vehicles \n", CPools::LoadVehiclePool);
LoadSaveDataBlock();
CProjectileInfo::RemoveAllProjectiles();