summaryrefslogtreecommitdiffstats
path: root/src/control/Bridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/control/Bridge.cpp')
-rw-r--r--src/control/Bridge.cpp151
1 files changed, 150 insertions, 1 deletions
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