#pragma once #include "render/Renderer.h" #include "Environment.h" #include "render/TextureManager.h" #include "render/TextRenderer.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 LocationSetup { std::string roomMeshPath; std::string roomTexturePath; std::string gameObjectsJsonPath; std::string npcsJsonPath; std::string dialoguesJsonPath; std::string navigationJsonPath; std::string scriptPath; Eigen::Vector3f playerPosition = Eigen::Vector3f::Zero(); Eigen::Vector3f ghostPosition = Eigen::Vector3f::Zero(); }; class Location { public: Location(Renderer& iRenderer, Inventory& iInventory); std::shared_ptr roomTexture; VertexRenderStruct roomMesh; std::unordered_map gameObjects; std::vector interactiveObjects; std::unique_ptr player; 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; // "Walk to NPC, then fire on_npc_interact" — mirrors targetInteractiveObject // so a click from outside interactionRadius still leads to a Lua callback // once the player gets close enough. Character* targetInteractNpc = nullptr; int targetInteractNpcIndex = -1; std::unique_ptr npcNameText; ScriptEngine scriptEngine; Dialogue::DialogueSystem dialogueSystem; #ifdef SHOW_PATH std::vector debugNavMeshes; void buildDebugNavMeshes(); void drawDebugNavigation(); #endif // Set by Game when the user's primary pointer (left mouse / single touch) // has crossed the tap-vs-drag threshold and is now rotating the camera. bool cameraDragging = false; int lastMouseX = 0; int lastMouseY = 0; void setup(const LocationSetup& params); void setupNavigation(const std::string& navigationJsonPath); 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 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 eventX, int eventY, int mx, int my); bool requestDialogueStart(const std::string& dialogueId); void setDialogueFlag(const std::string& flag, int value); int getDialogueFlag(const std::string& flag) const; protected: Renderer& renderer; Inventory& inventory; }; } // namespace ZL