#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" namespace ZL { struct NpcCar { enum class Mode { FOLLOW_WAYPOINTS, FOLLOW_PLAYER }; 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::shared_ptr roomTexture; VertexRenderStruct roomMesh; std::unordered_map gameObjects; std::vector interactiveObjects; VertexRenderStruct tileMesh; 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; 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 = false; 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 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; }; } // namespace ZL