diff options
Diffstat (limited to 'src/control/Bridge.cpp')
-rw-r--r-- | src/control/Bridge.cpp | 151 |
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 |