#pragma once #include "render/Renderer.h" #include "Environment.h" #include "render/TextureManager.h" #include "items/GameObjectLoader.h" #include "items/InteractiveObject.h" #include "navigation/PathFinder.h" #include "render/ShadowMap.h" #include "ScriptEngine.h" #include "dialogue/DialogueSystem.h" #include #include namespace ZL { struct NpcCar { enum class Mode { FOLLOW_WAYPOINTS, FOLLOW_PLAYER, NONE, NONE_STAY }; Eigen::Vector3f position = Eigen::Vector3f::Zero(); float rotation = 0.f; float velocity = 0.f; float steeringAngle = 0.f; float acceleration = 20.0f; float friction = 6.0f; float maxSpeed = 24.0f; float maxReverseSpeed = 8.0f; float turnRate = 1.8f; float maxSteerAngle = 0.6f; Mode mode = Mode::FOLLOW_WAYPOINTS; std::vector waypoints; size_t currentWaypoint = 0; float waypointReachRadius = 3.0f; float followMinDistance = 15.0f; float followMaxDistance = 25.0f; std::shared_ptr texture; }; class Location { public: Location(Renderer& iRenderer, Inventory& iInventory, const std::string& locId = "default"); std::string getLocationId() const { return locationId; } std::shared_ptr roomTexture; VertexRenderStruct roomMesh; std::unordered_map gameObjects; std::vector interactiveObjects; VertexRenderStruct tileMesh; std::shared_ptr azsTexture; std::shared_ptr roadTexture; std::shared_ptr grassTexture; std::unique_ptr player; std::unique_ptr girlfriend; std::unique_ptr salesperson; std::unique_ptr police; std::unique_ptr bandit; std::vector> npcs; float cameraAzimuth = 0.0f; float cameraInclination = M_PI * 30.f / 180.f; PathFinder navigation; std::unique_ptr shadowMap; Eigen::Matrix4f cameraViewMatrix = Eigen::Matrix4f::Identity(); InteractiveObject* targetInteractiveObject = nullptr; std::shared_ptr carTexture; VertexRenderStruct carMesh; std::shared_ptr carWheelTexture; VertexRenderStruct carWheelMesh; Vector3f carPosition = Eigen::Vector3f(0.f, 0.f, 0.f); float carRotation = 0.f; float carVelocity = 0.f; float carAcceleration = 20.0f; float carFriction = 6.0f; float carMaxSpeed = 20.0f; float carMaxReverseSpeed = 8.0f; float carTurnRate = 1.8f; float carSteeringAngle = 0.f; float carMaxSteerAngle = 0.6f; NpcCar npcCar; bool keyForward = false; bool keyBackward = false; bool keyLeft = false; bool keyRight = false; bool inCar = false; bool girlfriendInCar = false; Eigen::Vector3f girlfriendLastFollowTarget = Eigen::Vector3f::Zero(); bool girlfriendLastFollowTargetValid = false; bool dialoguePlayedOffroad = false; bool dialoguePlayedCrash = false; bool dialoguePlayedDrivingGas1 = false; bool dialogueDrivingGas1Finished = false; bool dialoguePlayedGas1 = false; bool dialoguePlayedGirlfriend1 = false; bool dialoguePlayedPhone1 = false; bool dialoguePhone1Finished = false; bool npcCarSpawnedAfterPhone = false; bool carOutOfGas = false; bool dialoguePlayedDrivingGasOut = false; float distanceRemaining = 4000.f;//10000.0f; bool dialoguePlayedDistance7000 = false; bool dialoguePlayedDistance5000 = false; bool dialoguePlayedDistance2000 = false; bool dialoguePlayedDistance0 = false; bool policeFollow = false; bool girlfriendRescued = false; enum class PoliceEncounterStage { Idle, Approaching, Returning, Done }; PoliceEncounterStage policeEncounterStage = PoliceEncounterStage::Idle; bool playerFrozen = false; float policeDrivingDialogueTimer = 8.0f; bool banditFollowingPlayer = false; bool dialoguePlayedBanditCaught1 = false; bool dialoguePlayedBanditCaught3 = false; bool banditEncounterFrozePlayer = false; Eigen::Vector3f banditLastFollowTarget = Eigen::Vector3f::Zero(); bool banditLastFollowTargetValid = false; bool dialoguePlayedVillageRescue1 = false; bool dialoguePlayedVillageIntro1 = false; bool dialogueVillageIntro1Finished = false; bool dialoguePlayedVillageIntro2 = false; bool dialoguePlayedVillageFinal1 = false; bool dialoguePlayedVillageFinal2 = false; std::function onLocationChangeRequest; ScriptEngine scriptEngine; Dialogue::DialogueSystem dialogueSystem; //#ifdef SHOW_PATH std::vector debugNavMeshes; void buildDebugNavMeshes(); void drawDebugNavigation(); std::vector debugForbiddenMeshes; void buildDebugForbiddenMeshes(); void drawDebugForbidden(); //#endif bool rightMouseDown = false; int lastMouseX = 0; int lastMouseY = 0; bool mouseInitialized = false; bool wasKeyForward = false; bool invertCameraY = true; void setup(); void setupNavigation(); InteractiveObject* raycastInteractiveObjects(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir); Character* raycastNpcs(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir, float maxDistance = 100.0f); void drawGame(); void drawShadowDepthPass(); void drawGameWithShadows(); bool setNavigationAreaAvailable(const std::string& areaName, bool available); void update(int64_t deltaMs); void updateNpcCar(int64_t deltaMs); void updateGirlfriendFollow(); void updateBanditFollow(); void drawNpcCar(); void handleDown(int64_t fingerId, int eventX, int eventY, int mx, int my); void handleUp(int64_t fingerId, int mx, int my); void handleMotion(int64_t fingerId, int dx, int dy, int mx, int my); void handleKeyDown(int sdlKey); void handleKeyUp(int sdlKey); bool requestDialogueStart(const std::string& dialogueId); void setDialogueFlag(const std::string& flag, int value); int getDialogueFlag(const std::string& flag) const; void cleanup(); void unload(); protected: Renderer& renderer; Inventory& inventory; private: std::string locationId; std::string roofObjectKey; bool roofVisible = true; std::vector> roofHideZones; std::string azsRoofObjectKey; bool azsRoofVisible = true; std::vector> azsRoofHideZones; bool isCarFootprintWalkable(const Eigen::Vector3f& center, float rotation) const; bool isPointInCarFootprint(const Eigen::Vector3f& point, const Eigen::Vector3f& center, float rotation) const; bool doesPlayerCarCollideWithNpcCar(const Eigen::Vector3f& center, float rotation) const; void pushOutOfNpcCarFootprint(Eigen::Vector3f& position) const; // --- FIRST PERSON BUILDING ZONE --- bool firstPersonMode = false; Eigen::AlignedBox buildingFirstPersonZone; // X,Z min/max float savedCameraAzimuth = 0.f; float savedCameraInclination = 0.f; // ----------------------------------- }; } // namespace ZL