#pragma once #include "Vehicle.h" #include "Door.h" enum eFerryNodes { FERRY_DOOR_FRONT = 1, FERRY_RAMP_FRONT, FERRY_DOOR_BACK, FERRY_RAMP_BACK, NUM_FERRY_NODES }; enum { NUM_FERRY_STATIONS = 2, NUM_FERRIES = NUM_FERRY_PATHS * 2, NUM_WAKE_POINTS = 64 }; enum { FERRY_STOPPED = 0, FERRY_CRUISING, FERRY_SLOWING, FERRY_ACCELERATING }; enum { FERRY_DOOR_CLOSED = 0, FERRY_DOOR_OPENING, FERRY_DOOR_OPEN, FERRY_DOOR_CLOSING }; struct CFerryNode { float x; float y; float z; float t; }; struct CFerryInterpolationLine { uint8 type; float time; // when does this keyframe start // initial values at start of frame float position; float speed; float acceleration; }; struct CFerryPath { float TotalLengthOfTrack; float TotalDurationOfTrack; int16 NumTrackNodes; CFerryNode* aTrackNodes; CFerryInterpolationLine* aLineBits; }; class CFerry; class CFerryInst { public: CFerryPath* pPathData[NUM_FERRY_PATHS]; float m_afPositions[NUM_FERRIES]; float m_afSpeeds[NUM_FERRIES]; CFerry* m_apFerries[NUM_FERRIES]; bool m_bFerriesDisabled; uint16 m_anNumWakePoints[NUM_FERRIES]; CVector2D m_avWakePoints[NUM_FERRIES][NUM_WAKE_POINTS]; float m_afWakePointTimer[NUM_FERRIES][NUM_WAKE_POINTS]; }; class CFerry : public CVehicle { public: int16 m_nFerryId; uint16 m_isFarAway; uint16 m_nCurTrackNode; float m_fSpeed; bool m_bFerryDocked; uint32 m_nDoorTimer; uint32 m_nTimeLeftStation; int16 m_nDoorState; bool m_bApproachingDock; uint8 m_nSkipFerryStatus; uint32 m_nTimeAlongPath; bool m_bUseFrontDoor; CVector m_vecForwardSpeed; CColModel* m_pDefaultColModel; uint8 m_nCollision; CDoor m_doors[4]; RwFrame* m_aFerryNodes[NUM_FERRY_NODES]; bool m_bAlreadyRendered; bool m_bPlayerArrivedHorn; static CFerryInst* mspInst; enum eSpaceUse { FERRY_SPACE_PED = 0, FERRY_SPACE_CAR }; enum eSpaceStyle { FERRY_SPACE_STYLE_0 = 0, FERRY_SPACE_STYLE_1 }; void Render(void); static void EnableFerryPath(int); CFerry(int32, uint8); void SetModelIndex(uint32); static void InitFerrys(void); static void Init(void*); void ProcessControl(void); void PlayArrivedHorn(void); void AddWakePoint(CVector); void PruneWakeTrail(void); void SkipFerryToNextDock(void); static void DissableFerryPath(int); void CompleteDorrMovement(void); bool IsDoorOpen(void); void CloseDoor(void); bool IsDocked(void); static CFerry* GetClosestFerry(float, float); CVector GetBoardingSpace(CFerry::eSpaceUse, CFerry::eSpaceStyle, uint8); CVector GetNearestDoor(CVector); void OpenFerryDoor(float); void FerryHitStuff(CPtrList&); static void RenderAllRemaning(void); static void UpdateFerrys(void); static void SwitchFerryCollision(int); void SetupForMultiplayer(void); void Write(base::cRelocatableChunkWriter&); virtual void OpenDoor(void); void PreRender(void); virtual bool IsDoorClosed(void); static CFerry* GetFerry(int i) { return mspInst ? mspInst->m_apFerries[i] : nil; } static void SetFerriesDisabled(bool disabled) { mspInst->m_bFerriesDisabled = disabled; } };