diff options
-rw-r--r-- | src/collision/ColStore.h | 1 | ||||
-rw-r--r-- | src/control/CarAI.cpp | 13 | ||||
-rw-r--r-- | src/control/CarCtrl.cpp | 341 | ||||
-rw-r--r-- | src/control/CarCtrl.h | 11 | ||||
-rw-r--r-- | src/control/Script.cpp | 550 | ||||
-rw-r--r-- | src/control/Script.h | 75 | ||||
-rw-r--r-- | src/control/Script2.cpp | 10 | ||||
-rw-r--r-- | src/control/Script4.cpp | 4 | ||||
-rw-r--r-- | src/control/Script5.cpp | 2 | ||||
-rw-r--r-- | src/control/Script7.cpp | 2 | ||||
-rw-r--r-- | src/control/ScriptCommands.h | 5 | ||||
-rw-r--r-- | src/core/IniFile.cpp | 4 | ||||
-rw-r--r-- | src/core/Pad.h | 2 | ||||
-rw-r--r-- | src/core/Streaming.h | 1 | ||||
-rw-r--r-- | src/core/config.h | 2 |
15 files changed, 691 insertions, 332 deletions
diff --git a/src/collision/ColStore.h b/src/collision/ColStore.h index 8e2a3a70..e0da92ca 100644 --- a/src/collision/ColStore.h +++ b/src/collision/ColStore.h @@ -33,6 +33,7 @@ public: static void RequestCollision(const CVector2D &pos); static void EnsureCollisionIsInMemory(const CVector2D &pos); static bool HasCollisionLoaded(const CVector2D &pos); + static bool HasCollisionLoaded(eLevelName level) { return true; }; // TODO static ColDef *GetSlot(int slot) { assert(slot >= 0); diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp index e7f3a546..06438e0a 100644 --- a/src/control/CarAI.cpp +++ b/src/control/CarAI.cpp @@ -4,6 +4,7 @@ #include "Accident.h" #include "AutoPilot.h" +#include "Bridge.h" #include "CarCtrl.h" #include "General.h" #include "HandlingMgr.h" @@ -74,6 +75,18 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle) case STATUS_PLAYER_DISABLED: break; case STATUS_SIMPLE: + { + if (pVehicle->m_pCurGroundEntity && CBridge::ThisIsABridgeObjectMovingUp(pVehicle->m_pCurGroundEntity->GetModelIndex())) + pVehicle->SetStatus(STATUS_PHYSICS); + CColPoint colPoint; + CEntity* pEntity; + if ((pVehicle->m_randomSeed & 0x3F) == (CTimer::GetFrameCounter() & 0x3F) && + !CWorld::ProcessVerticalLine(pVehicle->GetPosition(), -2.0f, colPoint, pEntity, true, false, false, false, true, false, nil)) { + debug("FLOATING CAR TURNED INTO PHYSICS CAR!\n"); + pVehicle->SetStatus(STATUS_PHYSICS); + } + } + // fallthough case STATUS_PHYSICS: switch (pVehicle->AutoPilot.m_nCarMission) { case MISSION_RAMPLAYER_FARAWAY: diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 1023f2a3..056c7713 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -11,6 +11,7 @@ #include "Cranes.h" #include "Curves.h" #include "CutsceneMgr.h" +#include "Frontend.h" #include "Gangs.h" #include "Game.h" #include "Garages.h" @@ -76,10 +77,11 @@ #define DISTANCE_BETWEEN_CAR_AND_DEAD_PED (6.0f) #define PROBABILITY_OF_PASSENGER_IN_VEHICLE (0.125f) -#define ONSCREEN_DESPAWN_RANGE (120.0f) -#define MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN (100.0f) -#define REQUEST_ONSCREEN_DISTANCE ((ONSCREEN_DESPAWN_RANGE + MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN) / 2) -#define OFFSCREEN_DESPAWN_RANGE (40.0f) +#define ONSCREEN_DESPAWN_RANGE (190.0f) +#define MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN (130.0f) +#define REQUEST_ONSCREEN_DISTANCE (140.0f) +#define OFFSCREEN_DESPAWN_RANGE (60.0f) +#define MINIMAL_DISTANCE_TO_SPAWN_OFFSCREEN (40.0f) #define EXTENDED_RANGE_DESPAWN_MULTIPLIER (1.5f) //--MIAMI: file done @@ -95,7 +97,7 @@ int32 CCarCtrl::NumRandomCars; int32 CCarCtrl::NumParkedCars; int32 CCarCtrl::NumPermanentCars; int8 CCarCtrl::CountDownToCarsAtStart; -int32 CCarCtrl::MaxNumberOfCarsInUse = 12; +int32 CCarCtrl::MaxNumberOfCarsInUse = 30; uint32 CCarCtrl::LastTimeLawEnforcerCreated; uint32 CCarCtrl::LastTimeFireTruckCreated; uint32 CCarCtrl::LastTimeAmbulanceCreated; @@ -161,14 +163,19 @@ CCarCtrl::GenerateOneRandomCar() carClass = COPS; carModel = ChoosePoliceCarModel(); }else{ - carModel = ChooseModel(&zone, &carClass); - if (carModel == -1 || (carClass == COPS && pWanted->m_nWantedLevel >= 1)) - /* All cop spawns with wanted level are handled by condition above. */ - /* In particular it means that cop cars never spawn if player has wanted level of 1. */ - return; + for (int i = 0; i < 5; i++) { + carModel = ChooseModel(&zone, &carClass); + if (carModel == -1) + return; + if (!(carClass == COPS && pWanted->m_nWantedLevel >= 1)) + /* All cop spawns with wanted level are handled by condition above. */ + /* In particular it means that cop cars never spawn if player has wanted level of 1. */ + break; + } } float frontX, frontY; float preferredDistance, angleLimit; + float requestMultiplier; bool invertAngleLimitTest; CVector spawnPosition; int32 curNodeId, nextNodeId; @@ -188,11 +195,14 @@ CCarCtrl::GenerateOneRandomCar() angleLimit = -1.0f; bTopDownCamera = true; invertAngleLimitTest = true; - preferredDistance = OFFSCREEN_DESPAWN_RANGE + 15.0f; + preferredDistance = MINIMAL_DISTANCE_TO_SPAWN_OFFSCREEN + 15.0f; /* BUG: testForCollision not initialized in original game. */ testForCollision = false; }else if (!pPlayerVehicle){ /* Player is not in vehicle. */ + requestMultiplier = 13.0f / 20.0f; + if (FrontEndMenuManager.m_PrefsUseWideScreen) // TODO(LCS): static + requestMultiplier *= 4.0f / 3.0f; testForCollision = true; frontX = TheCamera.CamFrontXNorm; frontY = TheCamera.CamFrontYNorm; @@ -202,95 +212,105 @@ CCarCtrl::GenerateOneRandomCar() /* Forward to his current direction (camera direction). */ angleLimit = 0.707f; /* 45 degrees */ invertAngleLimitTest = true; - preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier; + preferredDistance = REQUEST_ONSCREEN_DISTANCE * requestMultiplier * TheCamera.GenerationDistMultiplier; break; case 1: /* Spawn a vehicle close to player to his side. */ /* Kinda not within camera angle. */ angleLimit = 0.707f; /* 45 degrees */ invertAngleLimitTest = false; - preferredDistance = OFFSCREEN_DESPAWN_RANGE; + preferredDistance = MINIMAL_DISTANCE_TO_SPAWN_OFFSCREEN; break; } - }else if (fPlayerVehicleSpeed > 0.4f){ /* 72 km/h */ + } + else { + requestMultiplier = 13.0f / 20.0f; + if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON && !FrontEndMenuManager.m_PrefsUseWideScreen) + requestMultiplier *= 0.9f; + if (FrontEndMenuManager.m_PrefsUseWideScreen) // TODO(LCS): static + requestMultiplier *= 4.0f / 3.0f; + if (fPlayerVehicleSpeed > 0.4f) { /* 72 km/h */ /* Player is moving fast in vehicle */ /* Prefer spawning vehicles very far away from him. */ - frontX = vecPlayerVehicleSpeed.x / fPlayerVehicleSpeed; - frontY = vecPlayerVehicleSpeed.y / fPlayerVehicleSpeed; - testForCollision = false; - switch (CTimer::GetFrameCounter() & 3) { - case 0: - case 1: - /* Spawn a vehicle in a very narrow gap in front of a player */ - angleLimit = 0.85f; /* approx 30 degrees */ - invertAngleLimitTest = true; - preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier; - break; - case 2: - /* Spawn a vehicle relatively far away from player. */ - /* Forward to his current direction (camera direction). */ - angleLimit = 0.707f; /* 45 degrees */ - invertAngleLimitTest = true; - preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier; - break; - case 3: - /* Spawn a vehicle close to player to his side. */ - /* Kinda not within camera angle. */ - angleLimit = 0.707f; /* 45 degrees */ - invertAngleLimitTest = false; - preferredDistance = OFFSCREEN_DESPAWN_RANGE; - break; + frontX = vecPlayerVehicleSpeed.x / fPlayerVehicleSpeed; + frontY = vecPlayerVehicleSpeed.y / fPlayerVehicleSpeed; + testForCollision = false; + switch (CTimer::GetFrameCounter() & 3) { + case 0: + case 1: + /* Spawn a vehicle in a very narrow gap in front of a player */ + angleLimit = 0.85f; /* approx 30 degrees */ + invertAngleLimitTest = true; + preferredDistance = REQUEST_ONSCREEN_DISTANCE * requestMultiplier * TheCamera.GenerationDistMultiplier; + break; + case 2: + /* Spawn a vehicle relatively far away from player. */ + /* Forward to his current direction (camera direction). */ + angleLimit = 0.707f; /* 45 degrees */ + invertAngleLimitTest = true; + preferredDistance = REQUEST_ONSCREEN_DISTANCE * requestMultiplier * TheCamera.GenerationDistMultiplier; + break; + case 3: + /* Spawn a vehicle close to player to his side. */ + /* Kinda not within camera angle. */ + angleLimit = 0.707f; /* 45 degrees */ + invertAngleLimitTest = false; + preferredDistance = MINIMAL_DISTANCE_TO_SPAWN_OFFSCREEN; + break; + } } - }else if (fPlayerVehicleSpeed > 0.1f){ /* 18 km/h */ - /* Player is moving moderately fast in vehicle */ - /* Spawn more vehicles to player's side. */ - frontX = vecPlayerVehicleSpeed.x / fPlayerVehicleSpeed; - frontY = vecPlayerVehicleSpeed.y / fPlayerVehicleSpeed; - testForCollision = false; - switch (CTimer::GetFrameCounter() & 3) { - case 0: - /* Spawn a vehicle in a very narrow gap in front of a player */ - angleLimit = 0.85f; /* approx 30 degrees */ - invertAngleLimitTest = true; - preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier; - break; - case 1: - /* Spawn a vehicle relatively far away from player. */ - /* Forward to his current direction (camera direction). */ - angleLimit = 0.707f; /* 45 degrees */ - invertAngleLimitTest = true; - preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier; - break; - case 2: - case 3: - /* Spawn a vehicle close to player to his side. */ - /* Kinda not within camera angle. */ - angleLimit = 0.707f; /* 45 degrees */ - invertAngleLimitTest = false; - preferredDistance = OFFSCREEN_DESPAWN_RANGE; - break; + else if (fPlayerVehicleSpeed > 0.1f) { /* 18 km/h */ + /* Player is moving moderately fast in vehicle */ + /* Spawn more vehicles to player's side. */ + frontX = vecPlayerVehicleSpeed.x / fPlayerVehicleSpeed; + frontY = vecPlayerVehicleSpeed.y / fPlayerVehicleSpeed; + testForCollision = false; + switch (CTimer::GetFrameCounter() & 3) { + case 0: + /* Spawn a vehicle in a very narrow gap in front of a player */ + angleLimit = 0.85f; /* approx 30 degrees */ + invertAngleLimitTest = true; + preferredDistance = REQUEST_ONSCREEN_DISTANCE * requestMultiplier * TheCamera.GenerationDistMultiplier; + break; + case 1: + /* Spawn a vehicle relatively far away from player. */ + /* Forward to his current direction (camera direction). */ + angleLimit = 0.707f; /* 45 degrees */ + invertAngleLimitTest = true; + preferredDistance = REQUEST_ONSCREEN_DISTANCE * requestMultiplier * TheCamera.GenerationDistMultiplier; + break; + case 2: + case 3: + /* Spawn a vehicle close to player to his side. */ + /* Kinda not within camera angle. */ + angleLimit = 0.707f; /* 45 degrees */ + invertAngleLimitTest = false; + preferredDistance = MINIMAL_DISTANCE_TO_SPAWN_OFFSCREEN; + break; + } } - }else{ - /* Player is in vehicle but moving very slow. */ - /* Then use camera direction instead of vehicle direction. */ - testForCollision = true; - frontX = TheCamera.CamFrontXNorm; - frontY = TheCamera.CamFrontYNorm; - switch (CTimer::GetFrameCounter() & 1) { - case 0: - /* Spawn a vehicle relatively far away from player. */ - /* Forward to his current direction (camera direction). */ - angleLimit = 0.707f; /* 45 degrees */ - invertAngleLimitTest = true; - preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier; - break; - case 1: - /* Spawn a vehicle close to player to his side. */ - /* Kinda not within camera angle. */ - angleLimit = 0.707f; /* 45 degrees */ - invertAngleLimitTest = false; - preferredDistance = OFFSCREEN_DESPAWN_RANGE; - break; + else { + /* Player is in vehicle but moving very slow. */ + /* Then use camera direction instead of vehicle direction. */ + testForCollision = true; + frontX = TheCamera.CamFrontXNorm; + frontY = TheCamera.CamFrontYNorm; + switch (CTimer::GetFrameCounter() & 1) { + case 0: + /* Spawn a vehicle relatively far away from player. */ + /* Forward to his current direction (camera direction). */ + angleLimit = 0.707f; /* 45 degrees */ + invertAngleLimitTest = true; + preferredDistance = REQUEST_ONSCREEN_DISTANCE * requestMultiplier * TheCamera.GenerationDistMultiplier; + break; + case 1: + /* Spawn a vehicle close to player to his side. */ + /* Kinda not within camera angle. */ + angleLimit = 0.707f; /* 45 degrees */ + invertAngleLimitTest = false; + preferredDistance = MINIMAL_DISTANCE_TO_SPAWN_OFFSCREEN; + break; + } } } if (!ThePaths.GenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY, @@ -300,6 +320,8 @@ CCarCtrl::GenerateOneRandomCar() CPathNode* pCurNode = &ThePaths.m_pathNodes[curNodeId]; CPathNode* pNextNode = &ThePaths.m_pathNodes[nextNodeId]; bool bBoatGenerated = false; + if (!OkToCreateVehicleAtThisPosition(spawnPosition)) + return; if ((CGeneral::GetRandomNumber() & 0xF) > Min(pCurNode->spawnRate, pNextNode->spawnRate)) return; if (pCurNode->bWaterPath) { @@ -599,12 +621,12 @@ CCarCtrl::GenerateOneRandomCar() return; } }else{ - if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * (pVehicle->bExtendedRange ? EXTENDED_RANGE_DESPAWN_MULTIPLIER : 1.0f) * ONSCREEN_DESPAWN_RANGE || - (vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN) { + if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * requestMultiplier * (pVehicle->bExtendedRange ? EXTENDED_RANGE_DESPAWN_MULTIPLIER : 1.0f) * ONSCREEN_DESPAWN_RANGE || + (vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * requestMultiplier * MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN) { delete pVehicle; return; } - if ((TheCamera.GetPosition() - pVehicle->GetPosition()).Magnitude2D() < 82.5f * TheCamera.GenerationDistMultiplier || bTopDownCamera) { + if ((TheCamera.GetPosition() - pVehicle->GetPosition()).Magnitude2D() < 105.0f * requestMultiplier * TheCamera.GenerationDistMultiplier || bTopDownCamera) { delete pVehicle; return; } @@ -654,13 +676,13 @@ CCarCtrl::GenerateOneRandomCar() int nMadDrivers; switch (pVehicle->GetVehicleAppearance()) { case VEHICLE_APPEARANCE_BIKE: - nMadDrivers = 30; + nMadDrivers = 20; break; case VEHICLE_APPEARANCE_BOAT: nMadDrivers = 40; break; default: - nMadDrivers = 6; + nMadDrivers = 3; break; } if ((CGeneral::GetRandomNumber() & 0x7F) < nMadDrivers || bMadDriversCheat) { @@ -719,12 +741,6 @@ CCarCtrl::GenerateOneRandomCar() } } -bool -CCarCtrl::BoatWithTallMast(int32 mi) -{ - return mi == MI_RIO || mi == MI_TROPIC || mi == MI_MARQUIS; -} - int32 CCarCtrl::ChooseBoatModel(int32 rating) { @@ -944,6 +960,7 @@ CCarCtrl::RemoveCarsIfThePoolGetsFull(void) } } if (pClosestVehicle) { + debug(":::::::::::\'Nearest removed\' cause pools was full -> NumRandomCars %d\n", NumRandomCars); CWorld::Remove(pClosestVehicle); delete pClosestVehicle; } @@ -966,7 +983,10 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle) return; } float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D(); - float threshold = OFFSCREEN_DESPAWN_RANGE; + float despawnMultiplier = 1.0f; + if (FindPlayerVehicle() && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON && !FrontEndMenuManager.m_PrefsUseWideScreen) + despawnMultiplier = 0.75f; + float threshold = OFFSCREEN_DESPAWN_RANGE * despawnMultiplier; if (pVehicle->GetIsOnScreen() || TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight || @@ -979,7 +999,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle) pVehicle->bIsCarParkVehicle || CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime ){ - threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier; + threshold = ONSCREEN_DESPAWN_RANGE * despawnMultiplier * TheCamera.GenerationDistMultiplier; } if (TheCamera.GetForward().z < -0.9f) threshold = 70.0f; @@ -1572,7 +1592,7 @@ void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMCAR_CLOSE && pOtherEntity == pVehicle->AutoPilot.m_pTargetCar) return; CVector2D vecDiff = pOtherCar->GetPosition() - pVehicle->GetPosition(); - float angleBetweenVehicles = CGeneral::GetATanOfXY(vecDiff.x, vecDiff.y); + float angleBetweenVehicles = GetATanOfXY(vecDiff.x, vecDiff.y); float distance = vecDiff.Magnitude(); if (distance < 1.0f) return; @@ -1582,7 +1602,7 @@ void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float return; CVector2D forward = pVehicle->GetForward(); forward.Normalise(); - float forwardAngle = CGeneral::GetATanOfXY(forward.x, forward.y); + float forwardAngle = GetATanOfXY(forward.x, forward.y); float angleDiff = angleBetweenVehicles - forwardAngle; float lenProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.y * sin(angleDiff)); float widthProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.x * cos(angleDiff)); @@ -1591,16 +1611,12 @@ void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float diffToLeftAngle = ABS(diffToLeftAngle); float angleToWeave = lengthToEvade / 2; if (diffToLeftAngle < angleToWeave){ - *pAngleToWeaveLeft = angleBetweenVehicles - angleToWeave; - while (*pAngleToWeaveLeft < -PI) - *pAngleToWeaveLeft += TWOPI; + *pAngleToWeaveLeft = LimitRadianAngle(angleBetweenVehicles - angleToWeave); } float diffToRightAngle = LimitRadianAngle(angleBetweenVehicles - *pAngleToWeaveRight); diffToRightAngle = ABS(diffToRightAngle); if (diffToRightAngle < angleToWeave){ - *pAngleToWeaveRight = angleBetweenVehicles + angleToWeave; - while (*pAngleToWeaveRight > PI) - *pAngleToWeaveRight -= TWOPI; + *pAngleToWeaveRight = LimitRadianAngle(angleBetweenVehicles + angleToWeave); } } @@ -1632,23 +1648,19 @@ void CCarCtrl::WeaveForPed(CEntity* pOtherEntity, CVehicle* pVehicle, float* pAn return; CPed* pPed = (CPed*)pOtherEntity; CVector2D vecDiff = pPed->GetPosition() - pVehicle->GetPosition(); - float angleBetweenVehicleAndPed = CGeneral::GetATanOfXY(vecDiff.x, vecDiff.y); + float angleBetweenVehicleAndPed = GetATanOfXY(vecDiff.x, vecDiff.y); float distance = vecDiff.Magnitude(); float lengthToEvade = (WIDTH_COEF_TO_WEAVE_SAFELY * 2 * pVehicle->GetColModel()->boundingBox.max.x + PED_WIDTH_TO_WEAVE) / distance; float diffToLeftAngle = LimitRadianAngle(angleBetweenVehicleAndPed - *pAngleToWeaveLeft); diffToLeftAngle = ABS(diffToLeftAngle); float angleToWeave = lengthToEvade / 2; if (diffToLeftAngle < angleToWeave) { - *pAngleToWeaveLeft = angleBetweenVehicleAndPed - angleToWeave; - while (*pAngleToWeaveLeft < -PI) - *pAngleToWeaveLeft += TWOPI; + *pAngleToWeaveLeft = LimitRadianAngle(angleBetweenVehicleAndPed - angleToWeave); } float diffToRightAngle = LimitRadianAngle(angleBetweenVehicleAndPed - *pAngleToWeaveRight); diffToRightAngle = ABS(diffToRightAngle); if (diffToRightAngle < angleToWeave) { - *pAngleToWeaveRight = angleBetweenVehicleAndPed + angleToWeave; - while (*pAngleToWeaveRight > PI) - *pAngleToWeaveRight -= TWOPI; + *pAngleToWeaveRight = LimitRadianAngle(angleBetweenVehicleAndPed + angleToWeave); } } @@ -1704,23 +1716,19 @@ void CCarCtrl::WeaveForObject(CEntity* pOtherEntity, CVehicle* pVehicle, float* rightCoef * pObject->GetRight() + forwardCoef * pObject->GetForward() - pVehicle->GetPosition(); - float angleBetweenVehicleAndObject = CGeneral::GetATanOfXY(vecDiff.x, vecDiff.y); + float angleBetweenVehicleAndObject = GetATanOfXY(vecDiff.x, vecDiff.y); float distance = vecDiff.Magnitude(); float lengthToEvade = (WIDTH_COEF_TO_WEAVE_SAFELY * 2 * pVehicle->GetColModel()->boundingBox.max.x + OBJECT_WIDTH_TO_WEAVE) / distance; float diffToLeftAngle = LimitRadianAngle(angleBetweenVehicleAndObject - *pAngleToWeaveLeft); diffToLeftAngle = ABS(diffToLeftAngle); float angleToWeave = lengthToEvade / 2; if (diffToLeftAngle < angleToWeave) { - *pAngleToWeaveLeft = angleBetweenVehicleAndObject - angleToWeave; - while (*pAngleToWeaveLeft < -PI) - *pAngleToWeaveLeft += TWOPI; + *pAngleToWeaveLeft = LimitRadianAngle(angleBetweenVehicleAndObject - angleToWeave); } float diffToRightAngle = LimitRadianAngle(angleBetweenVehicleAndObject - *pAngleToWeaveRight); diffToRightAngle = ABS(diffToRightAngle); if (diffToRightAngle < angleToWeave) { - *pAngleToWeaveRight = angleBetweenVehicleAndObject + angleToWeave; - while (*pAngleToWeaveRight > PI) - *pAngleToWeaveRight -= TWOPI; + *pAngleToWeaveRight = LimitRadianAngle(angleBetweenVehicleAndObject + angleToWeave); } } @@ -1762,7 +1770,7 @@ bool CCarCtrl::PickNextNodeAccordingStrategy(CVehicle* pVehicle) void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle) { if (pVehicle->m_nRouteSeed) - CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed); + CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed++); int32 prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode; int32 curNode = pVehicle->AutoPilot.m_nNextRouteNode; uint8 totalLinks = ThePaths.m_pathNodes[curNode].numLinks; @@ -1848,13 +1856,15 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle) pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode]; if ((!pNextPathNode->bDisabled || pPrevPathNode->bDisabled) && (!pNextPathNode->bBetweenLevels || pPrevPathNode->bBetweenLevels || !pVehicle->AutoPilot.m_bStayInCurrentLevel)) - /* Nice way to exit loop but this will fail because this is used for indexing! */ - nextLink = 1000; + break; } } - if (nextLink < 999) + if (nextLink >= totalLinks) { /* If everything else failed, turn vehicle around */ + nextLink = 0; + debug("Couldn\'t find ANYTHING. Just go back from where we came.\n"); pVehicle->AutoPilot.m_nNextRouteNode = prevNode; + } } pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode]; pNextLink = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[nextLink + pCurPathNode->firstLink]]; @@ -1967,7 +1977,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t #endif { if (pVehicle->m_nRouteSeed) - CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed); + CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed++); int prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode; int curNode = pVehicle->AutoPilot.m_nNextRouteNode; CPathNode* pPrevNode = &ThePaths.m_pathNodes[prevNode]; @@ -1987,7 +1997,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t int nextLink; if (numNodes != 1 && numNodes != 2 || pTargetNode[0] == pCurNode){ if (numNodes != 2 || pTargetNode[1] == pCurNode) { - float currentAngle = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y); + float currentAngle = GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y); nextLink = 0; float lowestAngleChange = 10.0f; int numLinks = pCurNode->numLinks; @@ -1997,7 +2007,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t if (conNode == prevNode && i > 1) continue; CPathNode* pTestNode = &ThePaths.m_pathNodes[conNode]; - float angle = CGeneral::GetATanOfXY(pTestNode->GetX() - pCurNode->GetX(), pTestNode->GetY() - pCurNode->GetY()); + float angle = GetATanOfXY(pTestNode->GetX() - pCurNode->GetX(), pTestNode->GetY() - pCurNode->GetY()); angle = LimitRadianAngle(angle - currentAngle); angle = ABS(angle); if (angle < lowestAngleChange) { @@ -2415,6 +2425,16 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe *pHandbrake = true; return; case MISSION_CRUISE: + if (CTrafficLights::ShouldCarStopForBridge(pVehicle)) { + *pAccel = 0.0f; + *pBrake = 1.0f; + *pHandbrake = true; +#ifdef FIX_BUGS + *pSwerve = 0.0f; +#endif + break; + } + // fallthough case MISSION_RAMPLAYER_FARAWAY: case MISSION_BLOCKPLAYER_FARAWAY: case MISSION_GOTOCOORDS: @@ -2485,11 +2505,19 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe *pHandbrake = false; return; case MISSION_RAMCAR_CLOSE: + if (!pVehicle->AutoPilot.m_pTargetCar) { + debug("NO TARGET VEHICLE FOR MISSION_RAMCAR_CLOSE\n"); + return; + } SteerAICarWithPhysicsHeadingForTarget(pVehicle, pVehicle->AutoPilot.m_pTargetCar, pVehicle->AutoPilot.m_pTargetCar->GetPosition().x, pVehicle->AutoPilot.m_pTargetCar->GetPosition().y, pSwerve, pAccel, pBrake, pHandbrake); return; case MISSION_BLOCKCAR_CLOSE: + if (!pVehicle->AutoPilot.m_pTargetCar) { + debug("NO TARGET VEHICLE FOR MISSION_BLOCKCAR_CLOSE\n"); + return; + } SteerAICarWithPhysicsTryingToBlockTarget(pVehicle, pVehicle->AutoPilot.m_pTargetCar->GetPosition().x, pVehicle->AutoPilot.m_pTargetCar->GetPosition().y, @@ -2498,6 +2526,9 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe pSwerve, pAccel, pBrake, pHandbrake); return; case MISSION_BLOCKCAR_HANDBRAKESTOP: + if (!pVehicle->AutoPilot.m_pTargetCar) { + return; + } SteerAICarWithPhysicsTryingToBlockTarget_Stop(pVehicle, pVehicle->AutoPilot.m_pTargetCar->GetPosition().x, pVehicle->AutoPilot.m_pTargetCar->GetPosition().y, @@ -2575,8 +2606,8 @@ void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CVehicle* pVehicle, float { CVector2D forward = pVehicle->GetForward(); forward.Normalise(); - float angleToTarget = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y); - float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y); + float angleToTarget = GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y); + float angleForward = GetATanOfXY(forward.x, forward.y); float steerAngle = LimitRadianAngle(angleToTarget - angleForward); steerAngle = clamp(steerAngle, -DEFAULT_MAX_STEER_ANGLE, DEFAULT_MAX_STEER_ANGLE); #ifdef FIX_BUGS @@ -2607,8 +2638,8 @@ void CCarCtrl::SteerAIBoatWithPhysicsAttackingPlayer(CVehicle* pVehicle, float* CVector2D forward = pVehicle->GetForward(); forward.Normalise(); CVector2D vecToProjection = FindPlayerCoors() + FindPlayerSpeed() * projection * GAME_SPEED_TO_CARAI_SPEED; - float angleToTarget = CGeneral::GetATanOfXY(vecToProjection.x - pVehicle->GetPosition().x, vecToProjection.y - pVehicle->GetPosition().y); - float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y); + float angleToTarget = GetATanOfXY(vecToProjection.x - pVehicle->GetPosition().x, vecToProjection.y - pVehicle->GetPosition().y); + float angleForward = GetATanOfXY(forward.x, forward.y); float steerAngle = LimitRadianAngle(angleToTarget - angleForward); #ifdef FIX_BUGS float speedTarget = pVehicle->AutoPilot.GetCruiseSpeed(); @@ -2696,7 +2727,7 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli) if (distanceToTarget < 8.0f && pHeli->m_fHeliOrientation < 0.0f) ZTurnSpeedTarget = 0.0f; else { - float fAngleTarget = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y) + PI; + float fAngleTarget = GetATanOfXY(vecToTarget.x, vecToTarget.y) + PI; if (pHeli->m_fHeliOrientation >= 0.0f) fAngleTarget = pHeli->m_fHeliOrientation; fAngleTarget -= pHeli->m_fOrientation; @@ -2739,7 +2770,7 @@ void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane) CVector2D vecToTarget = pPlane->AutoPilot.m_vecDestinationCoors - pPlane->GetPosition(); float fForwardZ = (pPlane->AutoPilot.m_vecDestinationCoors.z - pPlane->GetPosition().z) / vecToTarget.Magnitude(); fForwardZ = clamp(fForwardZ, -0.3f, 0.3f); - float angle = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y); + float angle = GetATanOfXY(vecToTarget.x, vecToTarget.y); while (angle > TWOPI) angle -= TWOPI; float difference = LimitRadianAngle(angle - pPlane->m_fOrientation); @@ -2836,8 +2867,8 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv projectedPosition.y = positionOnCurrentLinkIncludingLane.y; } CVector2D distanceToProjectedPosition = projectedPosition - pVehicle->GetPosition(); - float angleCurrentLink = CGeneral::GetATanOfXY(distanceToProjectedPosition.x, distanceToProjectedPosition.y); - float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y); + float angleCurrentLink = GetATanOfXY(distanceToProjectedPosition.x, distanceToProjectedPosition.y); + float angleForward = GetATanOfXY(forward.x, forward.y); if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_AVOID_CARS) angleCurrentLink = FindAngleToWeaveThroughTraffic(pVehicle, nil, angleCurrentLink, angleForward); float steerAngle = LimitRadianAngle(angleCurrentLink - angleForward); @@ -2882,11 +2913,11 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv pCurrentLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x); trajectory -= pVehicle->GetPosition(); float speedAngleMultiplier = FindSpeedMultiplier( - CGeneral::GetATanOfXY(trajectory.x, trajectory.y) - angleForward, + GetATanOfXY(trajectory.x, trajectory.y) - angleForward, MIN_ANGLE_FOR_SPEED_LIMITING, MAX_ANGLE_FOR_SPEED_LIMITING, MIN_LOWERING_SPEED_COEFFICIENT); float tmpWideMultiplier = FindSpeedMultiplier( - CGeneral::GetATanOfXY(currentPathLinkForward.x, currentPathLinkForward.y) - - CGeneral::GetATanOfXY(nextPathLinkForwardX, nextPathLinkForwardY), + GetATanOfXY(currentPathLinkForward.x, currentPathLinkForward.y) - + GetATanOfXY(nextPathLinkForwardX, nextPathLinkForwardY), MIN_ANGLE_FOR_SPEED_LIMITING_BETWEEN_NODES, MAX_ANGLE_FOR_SPEED_LIMITING, MIN_LOWERING_SPEED_COEFFICIENT); float speedNodesMultiplier; if (scalarDistanceToNextNode > DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN || pVehicle->AutoPilot.m_nCruiseSpeed < 12) @@ -2920,8 +2951,8 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic *pHandbrake = false; CVector2D forward = pVehicle->GetForward(); forward.Normalise(); - float angleToTarget = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y); - float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y); + float angleToTarget = GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y); + float angleForward = GetATanOfXY(forward.x, forward.y); if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_AVOID_CARS) angleToTarget = FindAngleToWeaveThroughTraffic(pVehicle, pTarget, angleToTarget, angleForward); float steerAngle = LimitRadianAngle(angleToTarget - angleForward); @@ -3127,7 +3158,7 @@ bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle* pVehicle, CVector vecTar void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle) { if (pVehicle->m_nRouteSeed) - CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed); + CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed++); int nextLink; CPathNode* pCurNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nCurrentRouteNode]; for (nextLink = 0; nextLink < 12; nextLink++) @@ -3169,10 +3200,12 @@ void CCarCtrl::GenerateEmergencyServicesCar(void) return; if (CGame::IsInInterior()) return; + if (TheCamera.m_WideScreenOn) // TODO(LCS): verify + return; if (NumFiretrucksOnDuty + NumAmbulancesOnDuty + NumParkedCars + NumMissionCars + NumLawEnforcerCars + NumRandomCars > MaxNumberOfCarsInUse) return; - if (NumAmbulancesOnDuty == 0){ + if (NumAmbulancesOnDuty == 0 /* TODO(LCS): && gbEmergencyVehiclesEnabled */){ if (gAccidentManager.CountActiveAccidents() < 2){ if (CStreaming::HasModelLoaded(MI_AMBULAN)) CStreaming::SetModelIsDeletable(MI_MEDIC); @@ -3191,7 +3224,7 @@ void CCarCtrl::GenerateEmergencyServicesCar(void) } } } - if (NumFiretrucksOnDuty == 0){ + if (NumFiretrucksOnDuty == 0 /* TODO(LCS): && gbEmergencyVehiclesEnabled */){ if (gFireManager.GetTotalActiveFires() < 3){ if (CStreaming::HasModelLoaded(MI_FIRETRUCK)) CStreaming::SetModelIsDeletable(MI_FIREMAN); @@ -3348,6 +3381,17 @@ bool CCarCtrl::MapCouldMoveInThisArea(float x, float y) #endif } +bool +CCarCtrl::BoatWithTallMast(int32 mi) +{ + return mi == MI_RIO || mi == MI_TROPIC || mi == MI_MARQUIS; +} + +bool CCarCtrl::OkToCreateVehicleAtThisPosition(const CVector& pos) +{ + return true; +} + float CCarCtrl::FindSpeedMultiplierWithSpeedFromNodes(int8 type) { switch (type) @@ -3357,3 +3401,8 @@ float CCarCtrl::FindSpeedMultiplierWithSpeedFromNodes(int8 type) } return 1.0f; } + +void CCarCtrl::RenderDebugInfo(CVehicle*) +{ + //TODO(LCS) +} diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h index 5efbe275..fcb7929b 100644 --- a/src/control/CarCtrl.h +++ b/src/control/CarCtrl.h @@ -1,6 +1,7 @@ #pragma once #include "PathFind.h" #include "Boat.h" +#include "General.h" #include "Vehicle.h" #define GAME_SPEED_TO_METERS_PER_SECOND 50.0f @@ -130,6 +131,10 @@ public: static void SteerAIBoatWithPhysicsAttackingPlayer(CVehicle*, float*, float*, float*, bool*); static void SteerAICarBlockingPlayerForwardAndBack(CVehicle*, float*, float*, float*, bool*); + static bool OkToCreateVehicleAtThisPosition(const CVector&); + static void RenderDebugInfo(CVehicle*); + static float GetATanOfXY(float x, float y) { float t = CGeneral::GetATanOfXY(x, y); if (t < 0.0f) t += TWOPI; return t; } + static float GetPositionAlongCurrentCurve(CVehicle* pVehicle) { uint32 timeInCurve = CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeEnteredCurve; @@ -138,11 +143,7 @@ public: static float LimitRadianAngle(float angle) { - while (angle < -PI) - angle += TWOPI; - while (angle > PI) - angle -= TWOPI; - return angle; + return CGeneral::LimitRadianAngle(angle); } static bool bMadDriversCheat; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 735c2c6f..414e3f67 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -49,18 +49,20 @@ #include "Timecycle.h" #include "TxdStore.h" #include "Bike.h" +#include "memoryManager.h" #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT #include <stdarg.h> #endif //--MIAMI: file done -uint8 CTheScripts::ScriptSpace[SIZE_SCRIPT_SPACE]; +uint8* CTheScripts::ScriptSpace; CRunningScript CTheScripts::ScriptsArray[MAX_NUM_SCRIPTS]; intro_text_line CTheScripts::IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; intro_script_rectangle CTheScripts::IntroRectangles[MAX_NUM_INTRO_RECTANGLES]; CSprite2d CTheScripts::ScriptSprites[MAX_NUM_SCRIPT_SRPITES]; script_sphere_struct CTheScripts::ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES]; +tCollectiveData CTheScripts::CollectiveArray[MAX_NUM_COLLECTIVES]; tUsedObject CTheScripts::UsedObjectArray[MAX_NUM_USED_OBJECTS]; int32 CTheScripts::MultiScriptArray[MAX_NUM_MISSION_SCRIPTS]; tBuildingSwap CTheScripts::BuildingSwapArray[MAX_NUM_BUILDING_SWAPS]; @@ -100,6 +102,14 @@ bool CTheScripts::bPlayerIsInTheStatium; int16 CTheScripts::CardStack[CARDS_IN_DECK * MAX_DECKS]; int16 CTheScripts::CardStackPosition; #endif +int CTheScripts::AllowedCollision[MAX_ALLOWED_COLLISIONS]; +bool CTheScripts::FSDestroyedFlag; +short* CTheScripts::SavedVarIndices; +int CTheScripts::NumSaveVars; +int gScriptsFile = -1; +int CTheScripts::NextProcessId = 1; +bool CTheScripts::InTheScripts; +CRunningScript* pCurrent; #ifdef MISSION_REPLAY @@ -225,7 +235,7 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_GOSUB, INPUT_ARGUMENTS(ARGTYPE_LABEL,), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_RETURN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_LINE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""), - REGISTER_COMMAND(COMMAND_CREATE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_CREATE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""), REGISTER_COMMAND(COMMAND_GET_PLAYER_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""), REGISTER_COMMAND(COMMAND_SET_PLAYER_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_BOOL,), OUTPUT_ARGUMENTS(), true, -1, ""), @@ -356,6 +366,11 @@ const tScriptCommandData commands[] = { REGISTER_COMMAND(COMMAND_WHILE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_WHILENOT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_ENDWHILE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_214, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_215, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_216, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_217, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), + REGISTER_COMMAND(COMMAND_218, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_ANDOR, INPUT_ARGUMENTS(ARGTYPE_ANDOR,), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_LAUNCH_MISSION, INPUT_ARGUMENTS(ARGTYPE_LABEL,), OUTPUT_ARGUMENTS(), false, -1, ""), REGISTER_COMMAND(COMMAND_MISSION_HAS_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""), @@ -1659,11 +1674,13 @@ const uint32 CRunningScript::nSaveStructSize = sizeof(CRunningScript); #endif +// done(LCS) CMissionCleanup::CMissionCleanup() { Init(); } +// done(LCS) void CMissionCleanup::Init() { m_nCount = 0; @@ -1673,6 +1690,7 @@ void CMissionCleanup::Init() } } +// done(LCS) cleanup_entity_struct* CMissionCleanup::FindFree() { for (int i = 0; i < MAX_CLEANUP; i++){ @@ -1683,6 +1701,26 @@ cleanup_entity_struct* CMissionCleanup::FindFree() return nil; } +// done(LCS) +void SleepThisPed(cleanup_entity_struct* pCleanup, CPed* pPed) +{ + printf("*** SLEEPING PED %i %i\n", pCleanup->id, pPed->GetModelIndex()); + if (!pPed->GetIsStatic()) + pPed->RemoveFromMovingList(); + pPed->bIsStaticWaitingForCollision = true; +} + +// done(LCS) +void WakeThisPed(cleanup_entity_struct* pCleanup, CPed* pPed) +{ + printf("*** WAKING UP PED %i %i\n", pCleanup->id, pPed->GetModelIndex()); + pPed->bIsStaticWaitingForCollision = false; + if (!pPed->bIsStatic) + pPed->AddToMovingList(); + +} + +// done(LCS) void CMissionCleanup::AddEntityToList(int32 id, uint8 type) { cleanup_entity_struct* pNew = FindFree(); @@ -1693,6 +1731,7 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type) m_nCount++; } +// done(LCS) void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) { for (int i = 0; i < MAX_CLEANUP; i++){ @@ -1744,6 +1783,7 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) } } +// done(LCS) void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects() { for (int i = 0; i < MAX_CLEANUP; i++) { @@ -1752,50 +1792,105 @@ void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects() { CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); if (pVehicle) { - if (pVehicle->bIsStaticWaitingForCollision) { - if (CColStore::HasCollisionLoaded(pVehicle->GetPosition())) { - pVehicle->bIsStaticWaitingForCollision = false; + eLevelName level = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition()); + if (level == LEVEL_GENERIC) + level = CGame::currLevel; + if (!CColStore::HasCollisionLoaded(level)) { + if (!pVehicle->bIsStaticWaitingForCollision) { + if (!pVehicle->IsHeli() && !pVehicle->IsPlane() && pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI && + pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BOAT && pVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE) { + printf("*** SLEEPING VEHICLE %i %i\n", m_sEntities[i].id, pVehicle->GetModelIndex()); if (!pVehicle->GetIsStatic()) - pVehicle->AddToMovingList(); + pVehicle->RemoveFromMovingList(); + pVehicle->bIsStaticWaitingForCollision = true; + } } } - } - break; - } - case CLEANUP_CHAR: - { - CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id); - if (pPed) { - if (pPed->bIsStaticWaitingForCollision) { - if (CColStore::HasCollisionLoaded(pPed->GetPosition())) { - pPed->bIsStaticWaitingForCollision = false; - if (!pPed->GetIsStatic()) - pPed->AddToMovingList(); + else { + if (pVehicle->bIsStaticWaitingForCollision) { + printf("*** WAKING UP VEHICLE %i %i\n", m_sEntities[i].id, pVehicle->GetModelIndex()); + pVehicle->bIsStaticWaitingForCollision = false; + if (!pVehicle->bIsStatic) + pVehicle->AddToMovingList(); } } } - break; } + break; case CLEANUP_OBJECT: - { CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); if (pObject) { - if (pObject->bIsStaticWaitingForCollision) { - if (CColStore::HasCollisionLoaded(pObject->GetPosition())) { - pObject->bIsStaticWaitingForCollision = false; + eLevelName level = CTheZones::GetLevelFromPosition(&pObject->GetPosition()); + if (level == LEVEL_GENERIC) + level = CGame::currLevel; + if (!CColStore::HasCollisionLoaded(level)) { + if (!pObject->bIsStaticWaitingForCollision) { if (!pObject->GetIsStatic()) + pObject->RemoveFromMovingList(); + pObject->bIsStaticWaitingForCollision = true; + } + } + else { + if (pObject->bIsStaticWaitingForCollision) { + pObject->bIsStaticWaitingForCollision = false; + if (!pObject->bIsStatic) pObject->AddToMovingList(); } } } - break; } - default: - break; + } + for (int i = 0; i < MAX_CLEANUP; i++) { + switch (m_sEntities[i].type) { + case CLEANUP_CHAR: + { + CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id); + if (pPed) { + eLevelName level = CTheZones::GetLevelFromPosition(&pPed->GetPosition()); + if (level == LEVEL_GENERIC) + level = CGame::currLevel; + if (!pPed->bIsStaticWaitingForCollision) { + if (pPed->bInVehicle) { + if (pPed->m_pMyVehicle->GetIsStatic()) { + SleepThisPed(&m_sEntities[i], pPed); + continue; + } + } + if (!CColStore::HasCollisionLoaded(level)) { + if (pPed->bInVehicle && pPed->m_pMyVehicle->GetIsStatic() || + pPed->m_attachedTo && pPed->m_attachedTo->GetIsStatic()) + SleepThisPed(&m_sEntities[i], pPed); + } + } + else { + if (!pPed->bInVehicle) { + if (CColStore::HasCollisionLoaded(level)) { + if (!(pPed->bInVehicle && pPed->m_pMyVehicle->GetIsStatic() || + pPed->m_attachedTo && pPed->m_attachedTo->GetIsStatic())) + WakeThisPed(&m_sEntities[i], pPed); + } + } + else { + if (!pPed->m_pMyVehicle->GetIsStatic()) { + WakeThisPed(&m_sEntities[i], pPed); + continue; + } + if (CColStore::HasCollisionLoaded(level)) { + if (!(pPed->bInVehicle && pPed->m_pMyVehicle->GetIsStatic() || + pPed->m_attachedTo && pPed->m_attachedTo->GetIsStatic())) + WakeThisPed(&m_sEntities[i], pPed); + } + } + } + + } + } + break; } } } +// done(LCS) except TODO void CMissionCleanup::Process() { CPopulation::m_AllRandomPedsThisType = -1; @@ -1803,6 +1898,8 @@ void CMissionCleanup::Process() CCarCtrl::CarDensityMultiplier = 1.0f; CPed::nThreatReactionRangeMultiplier = 1; CPed::nEnterCarRangeMultiplier = 1; + for (int i = 0; i < MAX_ALLOWED_COLLISIONS; i++) + CTheScripts::AllowedCollision[i] = 0; FindPlayerPed()->m_pWanted->m_fCrimeSensitivity = 1.0f; CRoadBlocks::ClearScriptRoadBlocks(); CRouteNode::Initialise(); @@ -1810,20 +1907,19 @@ void CMissionCleanup::Process() TheCamera.Restore(); TheCamera.SetWideScreenOff(); CSpecialFX::bLiftCam = false; - CSpecialFX::bVideoCam = false; - CTimeCycle::StopExtraColour(0); + // TODO(LCS): CHud::m_ClockEventWarningMinutes = 0; + // TODO(LCS): CHud::m_ClockEventFlashTimer = 0; + CTimeCycle::StopExtraColour(0); // TODO: thiscall for (int i = 0; i < MISSION_AUDIO_SLOTS; i++) DMAudio.ClearMissionAudio(i); CWeather::ReleaseWeather(); for (int i = 0; i < NUM_OF_SPECIAL_CHARS; i++) CStreaming::SetMissionDoesntRequireSpecialChar(i); - for (int i = 0; i < NUM_OF_CUTSCENE_OBJECTS; i++) - CStreaming::SetMissionDoesntRequireModel(MI_CUTOBJ01 + i); CStreaming::ms_disableStreaming = false; - CHud::m_ItemToFlash = -1; - CHud::SetHelpMessage(nil, false); + if (CHud::m_ItemToFlash != ITEM_ARMOUR && CHud::m_ItemToFlash != ITEM_HEALTH) + CHud::m_ItemToFlash = -1; + CHud::SetHelpMessage(nil, false); // nil, false, false, true TODO(LCS) CUserDisplay::OnscnTimer.m_bDisabled = false; - CTheScripts::RemoveScriptTextureDictionary(); CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByCops = false; CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByEveryone = false; CWorld::Players[0].MakePlayerSafe(false); @@ -1831,10 +1927,11 @@ void CMissionCleanup::Process() CWorld::Players[0].m_pPed->m_nDrunkCountdown = 0; CPad::GetPad(0)->SetDrunkInputDelay(0); CWorld::Players[0].m_bDriveByAllowed = true; + CPad::GetPad(0)->unk_B4 = 1.0f; + CPad::GetPad(0)->unk_B8 = 0.5f; DMAudio.ShutUpPlayerTalking(0); CVehicle::bDisableRemoteDetonation = false; CVehicle::bDisableRemoteDetonationOnContact = false; - CGameLogic::ClearShortCut(); CTheScripts::RiotIntensity = 0; CTheScripts::StoreVehicleIndex = -1; CTheScripts::StoreVehicleWasRandom = true; @@ -1872,12 +1969,17 @@ void CMissionCleanup::Process() m_sEntities[i].type = CLEANUP_UNUSED; m_nCount--; } + for (int i = 1; i < NUMSTREAMINFO; i++) { + if (CStreaming::IsScriptOwnedModel(i)) + CStreaming::SetMissionDoesntRequireModel(i); + } } /* NB: CUpsideDownCarCheck is not used by actual script at all * It has a weird usage: AreAnyCarsUpsideDown would fail any mission * just like death or arrest. */ + // done(LCS) except TODO void CUpsideDownCarCheck::Init() { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ @@ -1886,12 +1988,14 @@ void CUpsideDownCarCheck::Init() } } +// done(LCS) bool CUpsideDownCarCheck::IsCarUpsideDown(int32 id) { CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(id); return IsCarUpsideDown(pVehicle); } +// done(LCS) bool CUpsideDownCarCheck::IsCarUpsideDown(CVehicle* pVehicle) { assert(pVehicle); @@ -1900,6 +2004,7 @@ bool CUpsideDownCarCheck::IsCarUpsideDown(CVehicle* pVehicle) pVehicle->GetTurnSpeed().Magnitude() < UPSIDEDOWN_TURN_SPEED_THRESHOLD; } +// done(LCS) void CUpsideDownCarCheck::UpdateTimers() { uint32 timeStep = CTimer::GetTimeStepInMilliseconds(); @@ -1917,6 +2022,7 @@ void CUpsideDownCarCheck::UpdateTimers() } } +// done(LCS) bool CUpsideDownCarCheck::AreAnyCarsUpsideDown() { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ @@ -1926,6 +2032,7 @@ bool CUpsideDownCarCheck::AreAnyCarsUpsideDown() return false; } +// done(LCS) void CUpsideDownCarCheck::AddCarToCheck(int32 id) { uint16 index = 0; @@ -1939,6 +2046,7 @@ void CUpsideDownCarCheck::AddCarToCheck(int32 id) m_sCars[index].m_nUpsideDownTimer = 0; } +// done(LCS) void CUpsideDownCarCheck::RemoveCarFromCheck(int32 id) { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ @@ -1949,6 +2057,7 @@ void CUpsideDownCarCheck::RemoveCarFromCheck(int32 id) } } +// done(LCS) bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id) { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ @@ -1958,6 +2067,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id) return false; } +// done(LCS) void stuck_car_data::Reset() { m_nVehicleIndex = -1; @@ -1968,6 +2078,7 @@ void stuck_car_data::Reset() m_bStuck = false; } +// done(LCS) void CStuckCarCheck::Init() { for (int i = 0; i < MAX_STUCK_CAR_CHECKS; i++) { @@ -1975,6 +2086,7 @@ void CStuckCarCheck::Init() } } +// done(LCS) void CStuckCarCheck::Process() { uint32 timer = CTimer::GetTimeInMilliseconds(); @@ -1995,6 +2107,7 @@ void CStuckCarCheck::Process() } } +// done(LCS) void CStuckCarCheck::AddCarToCheck(int32 id, float radius, uint32 time) { CVehicle* pv = CPools::GetVehiclePool()->GetAt(id); @@ -2015,6 +2128,7 @@ void CStuckCarCheck::AddCarToCheck(int32 id, float radius, uint32 time) m_sCars[index].m_bStuck = false; } +// done(LCS) void CStuckCarCheck::RemoveCarFromCheck(int32 id) { for (int i = 0; i < MAX_STUCK_CAR_CHECKS; i++){ @@ -2024,6 +2138,7 @@ void CStuckCarCheck::RemoveCarFromCheck(int32 id) } } +// done(LCS) bool CStuckCarCheck::HasCarBeenStuckForAWhile(int32 id) { for (int i = 0; i < MAX_STUCK_CAR_CHECKS; i++){ @@ -2033,109 +2148,165 @@ bool CStuckCarCheck::HasCarBeenStuckForAWhile(int32 id) return false; } -void CRunningScript::CollectParameters(uint32* pIp, int16 total) +// done(LCS) +void CRunningScript::CollectParameters(uint32* pIp, int16 total, int* pParameters) { - for (int16 i = 0; i < total; i++){ - uint16 varIndex; + while (total--){ switch (CTheScripts::Read1ByteFromScript(pIp)) { - case ARGUMENT_INT32: - case ARGUMENT_FLOAT: - ScriptParams[i] = CTheScripts::Read4BytesFromScript(pIp); + case ARGUMENT_END: + return; + case ARGUMENT_INT_ZERO: + *pParameters = 0; break; - case ARGUMENT_GLOBALVAR: - varIndex = CTheScripts::Read2BytesFromScript(pIp); - script_assert(varIndex >= 8 && varIndex < CTheScripts::GetSizeOfVariableSpace()); - ScriptParams[i] = *((int32*)&CTheScripts::ScriptSpace[varIndex]); + case ARGUMENT_FLOAT_ZERO: + *pParameters = 0; break; - case ARGUMENT_LOCALVAR: - varIndex = CTheScripts::Read2BytesFromScript(pIp); - script_assert(varIndex >= 0 && varIndex < ARRAY_SIZE(m_anLocalVariables)); - ScriptParams[i] = m_anLocalVariables[varIndex]; + case ARGUMENT_FLOAT_1BYTE: + *pParameters = (uint32)(uint8)CTheScripts::Read1ByteFromScript(pIp) << 24; + break; + case ARGUMENT_FLOAT_2BYTES: + *pParameters = (uint32)(uint16)CTheScripts::Read2BytesFromScript(pIp) << 16; + break; + case ARGUMENT_FLOAT_3BYTES: + *pParameters = (uint32)(uint8)CTheScripts::Read1ByteFromScript(pIp) << 8; + *pParameters |= (uint32)(uint16)CTheScripts::Read2BytesFromScript(pIp) << 16; + break; + case ARGUMENT_INT32: + case ARGUMENT_FLOAT: + *pParameters = CTheScripts::Read4BytesFromScript(pIp); break; case ARGUMENT_INT8: - ScriptParams[i] = CTheScripts::Read1ByteFromScript(pIp); + *pParameters = CTheScripts::Read1ByteFromScript(pIp); break; case ARGUMENT_INT16: - ScriptParams[i] = CTheScripts::Read2BytesFromScript(pIp); + *pParameters = CTheScripts::Read2BytesFromScript(pIp); break; default: - script_assert(0); + *pIp -= 1; + *pParameters = *GetPointerToScriptVariable(pIp, 0); break; } + pParameters++; } } #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT -int CRunningScript::CollectParameterForDebug(char* buf, bool& var) +// done(LCS) +int32* GetPointerToScriptVariableForDebug(CRunningScript* pScript, uint32* pIp, char* buf) { - uint16 varIndex; char tmpstr[24]; + uint8 type = CTheScripts::Read1ByteFromScript(pIp); + if (type >= ARGUMENT_GLOBAL_ARRAY) { + uint8 index_in_block = CTheScripts::Read1ByteFromScript(pIp); + uint8 index_id = CTheScripts::Read1ByteFromScript(pIp); + uint8 size = CTheScripts::Read1ByteFromScript(pIp); + script_assert(size > 0); + script_assert(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id] < size); + uint8 index = Min(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id], size - 1); + sprintf(tmpstr, " $%d[%d@]", ((int)(type - ARGUMENT_GLOBAL_ARRAY) << 8) + index_in_block, index_id); + strcat(buf, tmpstr); + return (int32*)&CTheScripts::ScriptSpace[4 * (((int)(type - ARGUMENT_GLOBAL_ARRAY) << 8) + index + index_in_block)]; + } + else if (type >= ARGUMENT_GLOBAL) { + uint8 index_in_block = CTheScripts::Read1ByteFromScript(pIp); + sprintf(tmpstr, " $%d", ((int)(type - ARGUMENT_GLOBAL) << 8) + index_in_block); + strcat(buf, tmpstr); + return (int32*)&CTheScripts::ScriptSpace[4 * (((int)(type - ARGUMENT_GLOBAL) << 8) + index_in_block)]; + } + else if (type >= ARGUMENT_LOCAL_ARRAY) { + uint8 index_id = CTheScripts::Read1ByteFromScript(pIp); + uint8 size = CTheScripts::Read1ByteFromScript(pIp); + script_assert(size > 0); + script_assert(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id] < size); + uint8 index = Min(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id], size - 1); + sprintf(tmpstr, " %d@[%d@]", (type - ARGUMENT_LOCAL_ARRAY), index_id); + strcat(buf, tmpstr); + return &pScript->m_anLocalVariables[pScript->m_nLocalsPointer + (type - ARGUMENT_LOCAL_ARRAY) + index]; + } + else if (type >= ARGUMENT_LOCAL) { + sprintf(tmpstr, " %d@", (type - ARGUMENT_LOCAL)); + strcat(buf, tmpstr); + return &pScript->m_anLocalVariables[pScript->m_nLocalsPointer + (type - ARGUMENT_LOCAL)]; + } + else { + assert(type >= ARGUMENT_TIMER); + sprintf(tmpstr, " TIMER%d@", (type - ARGUMENT_LOCAL_ARRAY)); + strcat(buf, tmpstr); + return &pScript->m_anLocalVariables[NUM_LOCAL_VARS + 8 + (type - ARGUMENT_TIMER)]; // why 8? + } +} + +// done(LCS) +int CRunningScript::CollectParameterForDebug(char* buf, bool& var) +{ var = false; + int tmp; switch (CTheScripts::Read1ByteFromScript(&m_nIp)) { + case ARGUMENT_END: + return 0; // TODO(LCS) + case ARGUMENT_INT_ZERO: + return 0; + case ARGUMENT_FLOAT_ZERO: + return 0; + case ARGUMENT_FLOAT_1BYTE: + return (uint32)(uint8)CTheScripts::Read1ByteFromScript(&m_nIp) << 24; + case ARGUMENT_FLOAT_2BYTES: + return (uint32)(uint16)CTheScripts::Read2BytesFromScript(&m_nIp) << 16; + case ARGUMENT_FLOAT_3BYTES: + tmp = (uint32)(uint8)CTheScripts::Read1ByteFromScript(&m_nIp) << 8; + tmp |= (uint32)(uint16)CTheScripts::Read2BytesFromScript(&m_nIp) << 16; + return tmp; case ARGUMENT_INT32: case ARGUMENT_FLOAT: return CTheScripts::Read4BytesFromScript(&m_nIp); - case ARGUMENT_GLOBALVAR: - varIndex = CTheScripts::Read2BytesFromScript(&m_nIp); - script_assert(varIndex >= 8 && varIndex < CTheScripts::GetSizeOfVariableSpace()); - var = true; - sprintf(tmpstr, " $%d", varIndex / 4); - strcat(buf, tmpstr); - return *((int32*)&CTheScripts::ScriptSpace[varIndex]); - case ARGUMENT_LOCALVAR: - varIndex = CTheScripts::Read2BytesFromScript(&m_nIp); - script_assert(varIndex >= 0 && varIndex < ARRAY_SIZE(m_anLocalVariables)); - var = true; - sprintf(tmpstr, " %d@", varIndex); - strcat(buf, tmpstr); - return m_anLocalVariables[varIndex]; + break; case ARGUMENT_INT8: return CTheScripts::Read1ByteFromScript(&m_nIp); + break; case ARGUMENT_INT16: return CTheScripts::Read2BytesFromScript(&m_nIp); + break; default: - PrintToLog("%s - script assertion failed in CollectParameterForDebug", buf); - script_assert(0); + var = true; + --m_nIp; + GetPointerToScriptVariableForDebug(this, &m_nIp, buf); break; } return 0; } +// done(LCS) void CRunningScript::GetStoredParameterForDebug(char* buf) { - uint16 varIndex; - char tmpstr[24]; - switch (CTheScripts::Read1ByteFromScript(&m_nIp)) { - case ARGUMENT_GLOBALVAR: - varIndex = CTheScripts::Read2BytesFromScript(&m_nIp); - sprintf(tmpstr, " $%d", varIndex / 4); - strcat(buf, tmpstr); - break; - case ARGUMENT_LOCALVAR: - varIndex = CTheScripts::Read2BytesFromScript(&m_nIp); - sprintf(tmpstr, " %d@", varIndex); - strcat(buf, tmpstr); - break; - default: - PrintToLog("%s - script_assertion failed in GetStoredParameterForDebug", buf); - script_assert(0); - } + GetPointerToScriptVariableForDebug(this, &m_nIp, buf); } #endif +// done(LCS) int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip) { uint32* pIp = &ip; + int tmp; switch (CTheScripts::Read1ByteFromScript(pIp)) { + case ARGUMENT_END: + return 0; // TODO(LCS) + case ARGUMENT_INT_ZERO: + return 0; + case ARGUMENT_FLOAT_ZERO: + return 0; + case ARGUMENT_FLOAT_1BYTE: + return (uint32)(uint8)CTheScripts::Read1ByteFromScript(&m_nIp) << 24; + case ARGUMENT_FLOAT_2BYTES: + return (uint32)(uint16)CTheScripts::Read2BytesFromScript(&m_nIp) << 16; + case ARGUMENT_FLOAT_3BYTES: + tmp = (uint32)(uint8)CTheScripts::Read1ByteFromScript(&m_nIp) << 8; + tmp |= (uint32)(uint16)CTheScripts::Read2BytesFromScript(&m_nIp) << 16; + return tmp; case ARGUMENT_INT32: return CTheScripts::Read4BytesFromScript(pIp); - case ARGUMENT_GLOBALVAR: - return *((int32*)&CTheScripts::ScriptSpace[(uint16)CTheScripts::Read2BytesFromScript(pIp)]); - case ARGUMENT_LOCALVAR: - return m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)]; case ARGUMENT_INT8: return CTheScripts::Read1ByteFromScript(pIp); case ARGUMENT_INT16: @@ -2143,46 +2314,74 @@ int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip) case ARGUMENT_FLOAT: return CTheScripts::Read4BytesFromScript(pIp); default: - script_assert(0); + pIp--; + return *GetPointerToScriptVariable(pIp, 0); } return -1; } +// done(LCS) void CRunningScript::StoreParameters(uint32* pIp, int16 number) { for (int16 i = 0; i < number; i++){ - switch (CTheScripts::Read1ByteFromScript(pIp)) { - case ARGUMENT_GLOBALVAR: - *(int32*)&CTheScripts::ScriptSpace[(uint16)CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i]; - break; - case ARGUMENT_LOCALVAR: - m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)] = ScriptParams[i]; - break; - default: - script_assert(0); - } + *GetPointerToScriptVariable(pIp, 0) = ScriptParams[i]; + } +} + +// done(LCS) +int32* GetPointerToScriptVariable(CRunningScript* pScript, uint32* pIp) +{ + uint8 type = CTheScripts::Read1ByteFromScript(pIp); + if (type >= ARGUMENT_GLOBAL_ARRAY) { + uint8 index_in_block = CTheScripts::Read1ByteFromScript(pIp); + uint8 index_id = CTheScripts::Read1ByteFromScript(pIp); + uint8 size = CTheScripts::Read1ByteFromScript(pIp); + script_assert(size > 0); + script_assert(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id] < size); + uint8 index = Min(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id], size - 1); + return (int32*)&CTheScripts::ScriptSpace[((int)(type - ARGUMENT_GLOBAL_ARRAY) << 8) + index + index_in_block]; + } + else if (type >= ARGUMENT_GLOBAL) { + uint8 index_in_block = CTheScripts::Read1ByteFromScript(pIp); + return (int32*)&CTheScripts::ScriptSpace[((int)(type - ARGUMENT_GLOBAL) << 8) + index_in_block]; + } + else if (type >= ARGUMENT_LOCAL_ARRAY) { + uint8 index_id = CTheScripts::Read1ByteFromScript(pIp); + uint8 size = CTheScripts::Read1ByteFromScript(pIp); + script_assert(size > 0); + script_assert(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id] < size); + uint8 index = Min(pScript->m_anLocalVariables[pScript->m_nLocalsPointer + index_id], size - 1); + return &pScript->m_anLocalVariables[pScript->m_nLocalsPointer + (type - ARGUMENT_LOCAL_ARRAY) + index]; + } + else if (type >= ARGUMENT_LOCAL) { + return &pScript->m_anLocalVariables[pScript->m_nLocalsPointer + (type - ARGUMENT_LOCAL)]; + } + else { + assert(type >= ARGUMENT_TIMER); + return &pScript->m_anLocalVariables[NUM_LOCAL_VARS + 8 + (type - ARGUMENT_TIMER)]; } } +// done(LCS) int32 *CRunningScript::GetPointerToScriptVariable(uint32* pIp, int16 type) { - switch (CTheScripts::Read1ByteFromScript(pIp)) - { - case ARGUMENT_GLOBALVAR: - script_assert(type == VAR_GLOBAL); - return (int32*)&CTheScripts::ScriptSpace[(uint16)CTheScripts::Read2BytesFromScript(pIp)]; - case ARGUMENT_LOCALVAR: - script_assert(type == VAR_LOCAL); - return &m_anLocalVariables[CTheScripts::Read2BytesFromScript(pIp)]; - default: - script_assert(0); + return ::GetPointerToScriptVariable(this, pIp); +} + +// done(LCS) +int CTheScripts::GetSaveVarIndex(int var) +{ + for (int i = 0; i < NumSaveVars; i++) { + if (SavedVarIndices[i] == var) + return i; } - return nil; + return -1; } +// done(LCS) void CRunningScript::Init() { - strcpy(m_abScriptName, "noname"); + sprintf(m_abScriptName, "id%02i", m_nId); next = prev = nil; SetIP(0); for (int i = 0; i < MAX_STACK_DEPTH; i++) @@ -2193,13 +2392,29 @@ void CRunningScript::Init() m_bCondResult = false; m_bIsMissionScript = false; m_bSkipWakeTime = false; - for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) + for (int i = 0; i < NUM_LOCAL_VARS + 8 + NUM_TIMERS; i++) m_anLocalVariables[i] = 0; m_nAndOrState = 0; m_bNotFlag = false; m_bDeatharrestEnabled = true; m_bDeatharrestExecuted = false; m_bMissionFlag = false; + m_nLocalsPointer = 0; +} + +// done(LCS) +void CTheScripts::Shutdown() +{ + if (gScriptsFile != -1) { + CFileMgr::CloseFile(gScriptsFile); + gScriptsFile = -1; + } + if (ScriptSpace) { + base::cMainMemoryManager::Instance()->Free(ScriptSpace); + ScriptSpace = nil; + FSDestroyedFlag = false; + OnAMissionFlag = 0; + } } #ifdef USE_DEBUG_SCRIPT_LOADER @@ -2229,10 +2444,11 @@ int open_script() } #endif -void CTheScripts::Init() +// done(LCS) +bool CTheScripts::Init(bool loaddata) { - for (int i = 0; i < SIZE_SCRIPT_SPACE; i++) - ScriptSpace[i] = 0; + bool retval = false; + printf("CTheScripts::Init\n"); pActiveScripts = pIdleScripts = nil; for (int i = 0; i < MAX_NUM_SCRIPTS; i++){ ScriptsArray[i].Init(); @@ -2241,25 +2457,39 @@ void CTheScripts::Init() MissionCleanUp.Init(); UpsideDownCars.Init(); StuckCars.Init(); - CFileMgr::SetDir("data"); -#ifdef USE_DEBUG_SCRIPT_LOADER - int mainf = open_script(); -#else - int mainf = CFileMgr::OpenFile("main.scm", "rb"); -#endif - CFileMgr::Read(mainf, (char*)ScriptSpace, SIZE_MAIN_SCRIPT); - CFileMgr::CloseFile(mainf); - CFileMgr::SetDir(""); StoreVehicleIndex = -1; StoreVehicleWasRandom = true; OnAMissionFlag = 0; LastMissionPassedTime = (uint32)-1; + for (int i = 0; i < MAX_NUM_COLLECTIVES; i++) { + CollectiveArray[i].colIndex = -1; + CollectiveArray[i].pedIndex = 0; + } + NextFreeCollectiveIndex = 0; LastRandomPedId = -1; for (int i = 0; i < MAX_NUM_USED_OBJECTS; i++){ memset(&UsedObjectArray[i].name, 0, sizeof(UsedObjectArray[i].name)); UsedObjectArray[i].index = 0; } NumberOfUsedObjects = 0; + if (ScriptSpace) + Shutdown(); + CFileMgr::SetDir("DATA"); +#ifdef USE_DEBUG_SCRIPT_LOADER + int mainf = open_script(); +#else + int mainf = CFileMgr::OpenFile("main.scm", "rb"); +#endif + CFileMgr::Read(mainf, (char*)&MainScriptSize, sizeof(MainScriptSize)); + int nLargestMissionSize = 0; + CFileMgr::Read(mainf, (char*)&nLargestMissionSize, sizeof(nLargestMissionSize)); + // some cSmallHeap shit - TODO + ScriptSpace = (uint8*)base::cMainMemoryManager::Instance()->Allocate(MainScriptSize + nLargestMissionSize); + memset(ScriptSpace, 0, MainScriptSize + nLargestMissionSize); + CFileMgr::Read(mainf, (char*)ScriptSpace, MainScriptSize); + gScriptsFile = mainf; + CFileMgr::CloseFile(mainf); + CFileMgr::SetDir(""); ReadObjectNamesFromScript(); UpdateObjectIndices(); bAlreadyRunningAMissionScript = false; @@ -2269,11 +2499,10 @@ void CTheScripts::Init() NumberOfExclusiveMissionScripts = 0; NumberOfMissionScripts = 0; LargestMissionScriptSize = 0; - MainScriptSize = 0; ReadMultiScriptFileOffsetsFromScript(); FailCurrentMission = 0; DbgFlag = false; - NumScriptDebugLines = 0; + //NumScriptDebugLines = 0; RiotIntensity = 0; bPlayerHasMetDebbieHarry = false; bPlayerIsInTheStatium = false; @@ -2297,7 +2526,7 @@ void CTheScripts::Init() IntroRectangles[i].m_sColor = CRGBA(255, 255, 255, 255); } NumberOfIntroRectanglesThisFrame = 0; - RemoveScriptTextureDictionary(); + RemoveScriptTextureDictionary(); // TODO(LCS) - probably not needed for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++){ BuildingSwapArray[i].m_pBuilding = nil; BuildingSwapArray[i].m_nNewModel = -1; @@ -2305,6 +2534,12 @@ void CTheScripts::Init() } for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) InvisibilitySettingArray[i] = nil; + if (loaddata) { + printf("loaddata = true\n"); + retval = GenericLoad(); + } + for (int i = 0; i < MAX_ALLOWED_COLLISIONS; i++) + AllowedCollision[i] = 0; #if defined USE_ADVANCED_SCRIPT_DEBUG_OUTPUT && SCRIPT_LOG_FILE_LEVEL == 2 CFileMgr::SetDirMyDocuments(); @@ -2315,8 +2550,10 @@ void CTheScripts::Init() PrintToLog(init_msg); CFileMgr::SetDir(""); #endif + return retval; } +// LCS - to remove? void CTheScripts::RemoveScriptTextureDictionary() { for (int i = 0; i < ARRAY_SIZE(CTheScripts::ScriptSprites); i++) @@ -2326,6 +2563,7 @@ void CTheScripts::RemoveScriptTextureDictionary() CTxdStore::RemoveTxd(slot); } +// done(LCS) void CRunningScript::RemoveScriptFromList(CRunningScript** ppScript) { if (prev) @@ -2336,6 +2574,7 @@ void CRunningScript::RemoveScriptFromList(CRunningScript** ppScript) next->prev = prev; } +// done(LCS) void CRunningScript::AddScriptToList(CRunningScript** ppScript) { next = *ppScript; @@ -2345,11 +2584,13 @@ void CRunningScript::AddScriptToList(CRunningScript** ppScript) *ppScript = this; } +// done(LCS) CRunningScript* CTheScripts::StartNewScript(uint32 ip) { CRunningScript* pNew = pIdleScripts; script_assert(pNew); pNew->RemoveScriptFromList(&pIdleScripts); + pNew->m_nId = NextProcessId++; pNew->Init(); pNew->SetIP(ip); pNew->AddScriptToList(&pActiveScripts); @@ -2361,6 +2602,8 @@ void CTheScripts::Process() { if (CReplay::IsPlayingBack()) return; + if (!ScriptSpace) + return; CommandsExecuted = 0; ScriptsUpdated = 0; float timeStep = CTimer::GetTimeStepInMilliseconds(); @@ -2383,6 +2626,8 @@ void CTheScripts::Process() UseTextCommands = 0; } + // TODO: mCoronas + #ifdef MISSION_REPLAY static uint32 TimeToWaitTill; switch (AllowMissionReplay) { @@ -2432,6 +2677,7 @@ void CTheScripts::Process() #endif CRunningScript* script = pActiveScripts; + InTheScripts = true; while (script != nil){ CRunningScript* next = script->GetNext(); ++ScriptsUpdated; @@ -2451,21 +2697,25 @@ void CTheScripts::Process() #endif } +// done(LCS) CRunningScript* CTheScripts::StartTestScript() { return StartNewScript(0); } +// done(LCS) bool CTheScripts::IsPlayerOnAMission() { return OnAMissionFlag && *(int32*)&ScriptSpace[OnAMissionFlag] == 1; } +// done(LCS) void CRunningScript::Process() { #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT PrintToLog("\n\nProcessing script %s (id %d)\n\n", m_abScriptName, this - CTheScripts::ScriptsArray); #endif + pCurrent = this; if (m_bIsMissionScript) DoDeatharrestCheck(); if (m_bMissionFlag && CTheScripts::FailCurrentMission == 1 && m_nStackPointer == 1) @@ -2534,32 +2784,36 @@ int8 CRunningScript::ProcessOneCommand() retval = ProcessCommands0To99(command); else if (command < 200) retval = ProcessCommands100To199(command); - else if (command < 300) + else if (command < 305) retval = ProcessCommands200To299(command); - else if (command < 400) + else if (command < 405) retval = ProcessCommands300To399(command); - else if (command < 500) + else if (command < 505) retval = ProcessCommands400To499(command); - else if (command < 600) + else if (command < 605) retval = ProcessCommands500To599(command); - else if (command < 700) + else if (command < 705) retval = ProcessCommands600To699(command); - else if (command < 800) + else if (command < 805) retval = ProcessCommands700To799(command); - else if (command < 900) + else if (command < 905) retval = ProcessCommands800To899(command); - else if (command < 1000) + else if (command < 1005) retval = ProcessCommands900To999(command); - else if (command < 1100) + else if (command < 1105) retval = ProcessCommands1000To1099(command); - else if (command < 1200) + else if (command < 1205) retval = ProcessCommands1100To1199(command); - else if (command < 1300) + else if (command < 1305) retval = ProcessCommands1200To1299(command); - else if (command < 1400) + else if (command < 1405) retval = ProcessCommands1300To1399(command); - else if (command < 1500) + else if (command < 1497) retval = ProcessCommands1400To1499(command); + //else if (command < 1600) // TODO + // retval = ProcessCommands1500To1599(command); + //else if (command < 1700) + // retval = ProcessCommands1600To1699(command); #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT if (command < ARRAY_SIZE(commands)) { if (commands[command].cond || commands[command].output[0] != ARGTYPE_NONE) { @@ -3116,12 +3370,12 @@ int8 CRunningScript::ProcessCommands0To99(int32 command) case ARGUMENT_INT32: pNew->m_anLocalVariables[i] = CTheScripts::Read4BytesFromScript(&m_nIp); break; - case ARGUMENT_GLOBALVAR: - pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[(uint16)CTheScripts::Read2BytesFromScript(&m_nIp)]; - break; - case ARGUMENT_LOCALVAR: - pNew->m_anLocalVariables[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(&m_nIp)]; - break; + //case ARGUMENT_GLOBALVAR: + // pNew->m_anLocalVariables[i] = *(int32*)&CTheScripts::ScriptSpace[(uint16)CTheScripts::Read2BytesFromScript(&m_nIp)]; + // break; + //case ARGUMENT_LOCALVAR: + // pNew->m_anLocalVariables[i] = m_anLocalVariables[CTheScripts::Read2BytesFromScript(&m_nIp)]; + // break; case ARGUMENT_INT8: pNew->m_anLocalVariables[i] = CTheScripts::Read1ByteFromScript(&m_nIp); break; diff --git a/src/control/Script.h b/src/control/Script.h index aafc681c..0a7f64bf 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -47,7 +47,7 @@ void FlushLog(); #define KEY_LENGTH_IN_SCRIPT (8) -//#define GTA_SCRIPT_COLLECTIVE +#define GTA_SCRIPT_COLLECTIVE struct intro_script_rectangle { @@ -215,15 +215,33 @@ public: }; enum { + MAX_STACK_DEPTH = 16, + NUM_LOCAL_VARS = 96, + NUM_TIMERS = 2, + NUM_GLOBAL_SLOTS = 26 +}; + +enum { ARGUMENT_END = 0, + ARGUMENT_INT_ZERO, + ARGUMENT_FLOAT_ZERO, + ARGUMENT_FLOAT_1BYTE, + ARGUMENT_FLOAT_2BYTES, + ARGUMENT_FLOAT_3BYTES, ARGUMENT_INT32, - ARGUMENT_GLOBALVAR, - ARGUMENT_LOCALVAR, ARGUMENT_INT8, ARGUMENT_INT16, - ARGUMENT_FLOAT + ARGUMENT_FLOAT, + ARGUMENT_TIMER, + ARGUMENT_LOCAL = ARGUMENT_TIMER + NUM_TIMERS, + ARGUMENT_LOCAL_ARRAY = ARGUMENT_LOCAL + NUM_LOCAL_VARS, + ARGUMENT_GLOBAL = ARGUMENT_LOCAL_ARRAY + NUM_LOCAL_VARS, + ARGUMENT_GLOBAL_ARRAY = ARGUMENT_GLOBAL + NUM_GLOBAL_SLOTS, + MAX_ARGUMENT = ARGUMENT_GLOBAL_ARRAY + NUM_GLOBAL_SLOTS }; +static_assert(MAX_ARGUMENT <= 256, "MAX_ARGUMENT must be less or equal to 256"); + struct tCollectiveData { int32 colIndex; @@ -269,22 +287,25 @@ enum { MAX_NUM_INTRO_RECTANGLES = 16, MAX_NUM_SCRIPT_SRPITES = 16, MAX_NUM_SCRIPT_SPHERES = 16, - MAX_NUM_USED_OBJECTS = 220, - MAX_NUM_MISSION_SCRIPTS = 120, - MAX_NUM_BUILDING_SWAPS = 25, - MAX_NUM_INVISIBILITY_SETTINGS = 20, - MAX_NUM_STORED_LINES = 1024 + MAX_NUM_COLLECTIVES = 32, + MAX_NUM_USED_OBJECTS = 305, + MAX_NUM_MISSION_SCRIPTS = 150, + MAX_NUM_BUILDING_SWAPS = 80, + MAX_NUM_INVISIBILITY_SETTINGS = 52, + MAX_NUM_STORED_LINES = 1024, + MAX_ALLOWED_COLLISIONS = 2 }; class CTheScripts { public: - static uint8 ScriptSpace[SIZE_SCRIPT_SPACE]; + static uint8* ScriptSpace; static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS]; static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; static intro_script_rectangle IntroRectangles[MAX_NUM_INTRO_RECTANGLES]; static CSprite2d ScriptSprites[MAX_NUM_SCRIPT_SRPITES]; static script_sphere_struct ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES]; + static tCollectiveData CollectiveArray[MAX_NUM_COLLECTIVES]; static tUsedObject UsedObjectArray[MAX_NUM_USED_OBJECTS]; static int32 MultiScriptArray[MAX_NUM_MISSION_SCRIPTS]; static tBuildingSwap BuildingSwapArray[MAX_NUM_BUILDING_SWAPS]; @@ -325,11 +346,20 @@ public: static int16 CardStack[CARDS_IN_STACK]; static int16 CardStackPosition; #endif + static bool bPlayerIsInTheStatium; static uint8 RiotIntensity; static bool bPlayerHasMetDebbieHarry; - static void Init(); + static int AllowedCollision[MAX_ALLOWED_COLLISIONS]; + static short* SavedVarIndices; + static int NumSaveVars; + static bool FSDestroyedFlag; + static int NextProcessId; + static bool InTheScripts; + static CRunningScript* pCurrent; + + static bool Init(bool loaddata = false); static void Process(); static CRunningScript* StartTestScript(); @@ -420,6 +450,9 @@ public: static void SwitchToMission(int32 mission); #endif + static int GetSaveVarIndex(int); + static void Shutdown(void); + #ifdef GTA_SCRIPT_COLLECTIVE static void AdvanceCollectiveIndex() { @@ -441,12 +474,7 @@ public: }; - -enum { - MAX_STACK_DEPTH = 6, - NUM_LOCAL_VARS = 16, - NUM_TIMERS = 2 -}; +extern int ScriptParams[32]; class CRunningScript { @@ -473,11 +501,13 @@ class CRunningScript public: CRunningScript* next; CRunningScript* prev; + int m_nId; char m_abScriptName[8]; uint32 m_nIp; uint32 m_anStack[MAX_STACK_DEPTH]; uint16 m_nStackPointer; - int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS]; + int32 m_anLocalVariables[NUM_LOCAL_VARS + 8 + NUM_TIMERS]; // TODO(LCS): figure out why 106 + int32 m_nLocalsPointer; bool m_bIsActive; bool m_bCondResult; bool m_bIsMissionScript; @@ -497,8 +527,8 @@ public: void Load(uint8*& buf); void UpdateTimers(float timeStep) { - m_anLocalVariables[NUM_LOCAL_VARS] += timeStep; - m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep; + for (int i = 0; i < NUM_TIMERS; i++) + m_anLocalVariables[NUM_LOCAL_VARS + 8 + i] += timeStep; } void Init(); @@ -509,7 +539,7 @@ public: static const uint32 nSaveStructSize; - void CollectParameters(uint32*, int16); + void CollectParameters(uint32*, int16, int* pParams = (int*)&ScriptParams); int32 CollectNextParameterWithoutIncreasingPC(uint32); int32* GetPointerToScriptVariable(uint32*, int16); void StoreParameters(uint32*, int16); @@ -600,3 +630,6 @@ void RetryMission(int, int); #ifdef USE_DEBUG_SCRIPT_LOADER extern int scriptToLoad; #endif + +extern int gScriptsFile; + diff --git a/src/control/Script2.cpp b/src/control/Script2.cpp index a94bf907..10f122ca 100644 --- a/src/control/Script2.cpp +++ b/src/control/Script2.cpp @@ -168,7 +168,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) */ case COMMAND_DISPLAY_ONSCREEN_TIMER: { - script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); + //script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); m_nIp++; uint16 offset = CTheScripts::Read2BytesFromScript(&m_nIp); CollectParameters(&m_nIp, 1); @@ -177,14 +177,14 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) } case COMMAND_CLEAR_ONSCREEN_TIMER: { - script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); + //script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); m_nIp++; CUserDisplay::OnscnTimer.ClearClock((uint16)CTheScripts::Read2BytesFromScript(&m_nIp)); return 0; } case COMMAND_DISPLAY_ONSCREEN_COUNTER: { - script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); + //script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); m_nIp++; int16 counter = CTheScripts::Read2BytesFromScript(&m_nIp); CollectParameters(&m_nIp, 1); @@ -193,7 +193,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) } case COMMAND_CLEAR_ONSCREEN_COUNTER: { - script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); + //script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR); m_nIp++; CUserDisplay::OnscnTimer.ClearCounter((uint16)CTheScripts::Read2BytesFromScript(&m_nIp)); return 0; @@ -590,7 +590,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) //case COMMAND_MOVE_CAMERA_ALONG_SPLINE: //case COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE: case COMMAND_DECLARE_MISSION_FLAG: - CTheScripts::OnAMissionFlag = (uint16)CTheScripts::Read2BytesFromScript(&++m_nIp); + CTheScripts::OnAMissionFlag = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) - (int32*)CTheScripts::ScriptSpace; return 0; case COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT: return 0; diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp index a8658532..64928e7a 100644 --- a/src/control/Script4.cpp +++ b/src/control/Script4.cpp @@ -1781,7 +1781,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) */ case COMMAND_DISPLAY_ONSCREEN_TIMER_WITH_STRING: { - script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + //script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); uint16 var = CTheScripts::Read2BytesFromScript(&m_nIp); CollectParameters(&m_nIp, 1); wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? @@ -1792,7 +1792,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) } case COMMAND_DISPLAY_ONSCREEN_COUNTER_WITH_STRING: { - script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + //script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); uint16 var = CTheScripts::Read2BytesFromScript(&m_nIp); CollectParameters(&m_nIp, 1); wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp index f970cf89..c594b9c8 100644 --- a/src/control/Script5.cpp +++ b/src/control/Script5.cpp @@ -2556,7 +2556,7 @@ void CTheScripts::SetObjectiveForAllPedsInCollective(int colIndex, eObjective ob } else { pPed->bScriptObjectiveCompleted = false; - pPed->SetObjective(objective, p1, p2); + //pPed->SetObjective(objective, p1, p2); TODO! } } } diff --git a/src/control/Script7.cpp b/src/control/Script7.cpp index 5a70fd28..344ea2c7 100644 --- a/src/control/Script7.cpp +++ b/src/control/Script7.cpp @@ -540,7 +540,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_DISPLAY_NTH_ONSCREEN_COUNTER_WITH_STRING: { char onscreen_str[12]; - script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); + //script_assert(CTheScripts::ScriptSpace[m_nIp++] == ARGUMENT_GLOBALVAR); uint16 var = CTheScripts::Read2BytesFromScript(&m_nIp); CollectParameters(&m_nIp, 2); wchar* text = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); // ??? diff --git a/src/control/ScriptCommands.h b/src/control/ScriptCommands.h index 9863e852..8cf73abd 100644 --- a/src/control/ScriptCommands.h +++ b/src/control/ScriptCommands.h @@ -215,6 +215,11 @@ enum { COMMAND_WHILE, COMMAND_WHILENOT, COMMAND_ENDWHILE, + COMMAND_214, + COMMAND_215, + COMMAND_216, + COMMAND_217, + COMMAND_218, COMMAND_ANDOR, COMMAND_LAUNCH_MISSION, COMMAND_MISSION_HAS_FINISHED, diff --git a/src/core/IniFile.cpp b/src/core/IniFile.cpp index f7e2bfdd..870e9a71 100644 --- a/src/core/IniFile.cpp +++ b/src/core/IniFile.cpp @@ -10,7 +10,7 @@ // --MIAMI: file done float CIniFile::PedNumberMultiplier = 0.6f; -float CIniFile::CarNumberMultiplier = 0.6f; +float CIniFile::CarNumberMultiplier = 0.8f; void CIniFile::LoadIniFile() { @@ -27,5 +27,5 @@ void CIniFile::LoadIniFile() } CPopulation::MaxNumberOfPedsInUse = 25.0f * PedNumberMultiplier; CPopulation::MaxNumberOfPedsInUseInterior = 40.0f * PedNumberMultiplier; - CCarCtrl::MaxNumberOfCarsInUse = 12.0f * CarNumberMultiplier; + CCarCtrl::MaxNumberOfCarsInUse = 30.0f * CarNumberMultiplier; }
\ No newline at end of file diff --git a/src/core/Pad.h b/src/core/Pad.h index 9f9f81b6..3a4f54b3 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -164,6 +164,8 @@ public: int32 LastTimeTouched; int32 AverageWeapon; int32 AverageEntries; + float unk_B4; + float unk_B8; #ifdef DETECT_PAD_INPUT_SWITCH static bool IsAffectedByController; diff --git a/src/core/Streaming.h b/src/core/Streaming.h index a67384f6..f294a7c5 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -123,6 +123,7 @@ public: static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); } static bool HasAnimLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_ANIM); } static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; } + static bool IsScriptOwnedModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_SCRIPTOWNED); } static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); } static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); } static bool CanRemoveAnim(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_ANIM); } diff --git a/src/core/config.h b/src/core/config.h index 4aaeb3c1..d90be214 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -334,7 +334,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually #endif //#define SIMPLIER_MISSIONS // apply simplifications from mobile #define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT -#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log +#define SCRIPT_LOG_FILE_LEVEL 2 // 0 == no log, 1 == overwrite every frame, 2 == full log #ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT #define USE_BASIC_SCRIPT_DEBUG_OUTPUT |