summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Stats.cpp5
-rw-r--r--src/Stats.h7
-rw-r--r--src/control/Bridge.cpp151
-rw-r--r--src/control/Bridge.h25
-rw-r--r--src/control/PathFind.cpp2
-rw-r--r--src/control/PathFind.h2
6 files changed, 185 insertions, 7 deletions
diff --git a/src/Stats.cpp b/src/Stats.cpp
index 5256b0cf..3c5b55e4 100644
--- a/src/Stats.cpp
+++ b/src/Stats.cpp
@@ -1,5 +1,6 @@
#include "common.h"
#include "Stats.h"
-int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
-int32 &CStats::HeadShots = *(int32*)0x8F647C; \ No newline at end of file
+int32& CStats::DaysPassed = *(int32*)0x8F2BB8;
+int32& CStats::HeadShots = *(int32*)0x8F647C;
+bool& CStats::CommercialPassed = *(bool*)0x8F4334; \ No newline at end of file
diff --git a/src/Stats.h b/src/Stats.h
index e7cc3dc5..39b0e184 100644
--- a/src/Stats.h
+++ b/src/Stats.h
@@ -3,6 +3,7 @@
class CStats
{
public:
- static int32 &DaysPassed;
- static int32 &HeadShots;
-};
+ static int32& DaysPassed;
+ static int32& HeadShots;
+ static bool& CommercialPassed;
+}; \ No newline at end of file
diff --git a/src/control/Bridge.cpp b/src/control/Bridge.cpp
index 91f3c788..3215ea2d 100644
--- a/src/control/Bridge.cpp
+++ b/src/control/Bridge.cpp
@@ -1,5 +1,154 @@
#include "common.h"
#include "patcher.h"
#include "Bridge.h"
+#include "Pools.h"
+#include "ModelIndices.h"
+#include "PathFind.h"
+#include "Stats.h"
-WRAPPER bool CBridge::ShouldLightsBeFlashing(void) { EAXJMP(0x413D10); }
+CEntity*& CBridge::pLiftRoad = *(CEntity**)0x8E2C8C;
+CEntity*& CBridge::pLiftPart = *(CEntity**)0x8E2C94;
+CEntity*& CBridge::pWeight = *(CEntity**)0x8E28BC;
+
+int& CBridge::State = *(int*)0x8F2A1C;
+int& CBridge::OldState = *(int*)0x8F2A20;
+
+float& CBridge::DefaultZLiftPart = *(float*)0x941430;
+float& CBridge::DefaultZLiftRoad = *(float*)0x941438;
+float& CBridge::DefaultZLiftWeight = *(float*)0x8F1A44;
+
+float& CBridge::OldLift = *(float*)0x8F6254;
+
+uint32& CBridge::TimeOfBridgeBecomingOperational = *(uint32*)0x8F2BC0;
+
+void CBridge::Init()
+{
+ FindBridgeEntities();
+ OldLift = -1.0;
+ if (pLiftPart && pWeight)
+ {
+ DefaultZLiftPart = pLiftPart->GetPosition().z;
+ DefaultZLiftWeight = pWeight->GetPosition().z;
+
+ if (pLiftRoad)
+ DefaultZLiftRoad = pLiftRoad->GetPosition().z;
+
+ ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, true);
+ }
+}
+
+void CBridge::Update()
+{
+ if (!pLiftPart || !pWeight)
+ return;
+
+ OldState = State;
+
+ float liftHeight;
+
+ if (CStats::CommercialPassed)
+ {
+ if (TimeOfBridgeBecomingOperational == 0)
+ TimeOfBridgeBecomingOperational = CTimer::GetTimeInMilliseconds();
+
+ // Time remaining for bridge to become operational
+ // uint16, so after about a minute it overflows to 0 and the cycle repeats
+ uint16 timeElapsed = CTimer::GetTimeInMilliseconds() - TimeOfBridgeBecomingOperational;
+
+ // Calculate lift part height and bridge state
+ if (timeElapsed < 10000)
+ {
+ State = STATE_LIFT_PART_MOVING_DOWN;
+ liftHeight = 25.0 - timeElapsed / 10000.0 * 25.0;
+ }
+ else if (timeElapsed < 40000)
+ {
+ liftHeight = 0.0;
+ State = STATE_LIFT_PART_IS_DOWN;
+ }
+ else if (timeElapsed < 50000)
+ {
+ liftHeight = 0.0;
+ State = STATE_LIFT_PART_ABOUT_TO_MOVE_UP;
+ }
+ else if (timeElapsed < 60000)
+ {
+ State = STATE_LIFT_PART_MOVING_UP;
+ liftHeight = (timeElapsed - 50000) / 10000.0 * 25.0;
+ }
+ else
+ {
+ liftHeight = 25.0;
+ State = STATE_LIFT_PART_IS_UP;
+ }
+
+ // Move bridge part
+ if (liftHeight != OldLift)
+ {
+ pLiftPart->GetPosition().z = DefaultZLiftPart + liftHeight;
+ pLiftPart->GetMatrix().UpdateRW();
+ pLiftPart->UpdateRwFrame();
+ if (pLiftRoad)
+ {
+ pLiftRoad->GetPosition().z = DefaultZLiftRoad + liftHeight;
+ pLiftRoad->GetMatrix().UpdateRW();
+ pLiftRoad->UpdateRwFrame();
+ }
+ pWeight->GetPosition().z = DefaultZLiftWeight - liftHeight;
+ pWeight->GetMatrix().UpdateRW();
+ pWeight->UpdateRwFrame();
+
+ OldLift = liftHeight;
+ }
+
+ if (State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP && OldState == STATE_LIFT_PART_IS_DOWN)
+ ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, true);
+ else if (State == STATE_LIFT_PART_IS_DOWN && OldState == STATE_LIFT_PART_MOVING_DOWN)
+ ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, false);
+ }
+ else
+ {
+ liftHeight = 25.0;
+ TimeOfBridgeBecomingOperational = 0;
+ State = STATE_BRIDGE_LOCKED;
+ }
+}
+
+bool CBridge::ShouldLightsBeFlashing() { return State != STATE_LIFT_PART_IS_DOWN; }
+
+void CBridge::FindBridgeEntities()
+{
+ pWeight = nil;
+ pLiftRoad = nil;
+ pLiftPart = nil;
+
+ for (int i = 1; i < CPools::GetBuildingPool()->GetSize(); ++i)
+ {
+ CBuilding* entry = CPools::GetBuildingPool()->GetSlot(i);
+ if (entry)
+ {
+ if (entry->GetModelIndex() == MI_BRIDGELIFT)
+ pLiftPart = entry;
+ else if (entry->GetModelIndex() == MI_BRIDGEROADSEGMENT)
+ pLiftRoad = entry;
+ else if (entry->GetModelIndex() == MI_BRIDGEWEIGHT)
+ pWeight = entry;
+ }
+ }
+}
+
+bool CBridge::ThisIsABridgeObjectMovingUp(int index)
+{
+ if (index != MI_BRIDGEROADSEGMENT && index != MI_BRIDGELIFT)
+ return false;
+
+ return State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP || State == STATE_LIFT_PART_MOVING_UP;
+}
+
+STARTPATCHES
+ InjectHook(0x413A30, &CBridge::Init, PATCH_JUMP);
+ InjectHook(0x413AC0, &CBridge::Update, PATCH_JUMP);
+ InjectHook(0x413D10, &CBridge::ShouldLightsBeFlashing, PATCH_JUMP);
+ InjectHook(0x413D20, &CBridge::FindBridgeEntities, PATCH_JUMP);
+ InjectHook(0x413DE0, &CBridge::ThisIsABridgeObjectMovingUp, PATCH_JUMP);
+ENDPATCHES \ No newline at end of file
diff --git a/src/control/Bridge.h b/src/control/Bridge.h
index 64b85c1d..52c85322 100644
--- a/src/control/Bridge.h
+++ b/src/control/Bridge.h
@@ -1,7 +1,30 @@
#pragma once
+#include "Entity.h"
class CBridge
{
+private:
+ enum bridgeStates
+ {
+ STATE_BRIDGE_LOCKED,
+ STATE_LIFT_PART_IS_UP,
+ STATE_LIFT_PART_MOVING_DOWN,
+ STATE_LIFT_PART_IS_DOWN,
+ STATE_LIFT_PART_ABOUT_TO_MOVE_UP,
+ STATE_LIFT_PART_MOVING_UP
+ };
+
+
+ static CEntity *&pLiftRoad, *&pLiftPart, *&pWeight;
+ static int &State, &OldState;
+ static float &DefaultZLiftPart, &DefaultZLiftRoad, &DefaultZLiftWeight;
+ static float& OldLift;
+ static uint32& TimeOfBridgeBecomingOperational;
+
public:
- static bool ShouldLightsBeFlashing(void);
+ static void Init();
+ static void Update();
+ static bool ShouldLightsBeFlashing();
+ static void FindBridgeEntities();
+ static bool ThisIsABridgeObjectMovingUp(int);
};
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index f511b5dc..f9ce7f35 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -626,6 +626,8 @@ CPathFind::CalcNodeCoors(int16 x, int16 y, int16 z, int id, CVector *out)
*out = m_mapObjects[id]->GetMatrix() * pos;
}
+WRAPPER void CPathFind::SetLinksBridgeLights(float, float, float, float, bool) { EAXJMP(0x42E3B0); }
+
STARTPATCHES
InjectHook(0x429610, &CPathFind::PreparePathData, PATCH_JUMP);
InjectHook(0x429C20, &CPathFind::PreparePathDataForType, PATCH_JUMP);
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index cc0b0a2f..9b6be573 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -131,6 +131,8 @@ public:
int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool disabled, bool betweenLevels);
bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); }
+
+ void SetLinksBridgeLights(float, float, float, float, bool);
};
static_assert(sizeof(CPathFind) == 0x4c8f4, "CPathFind: error");