233 lines
6.8 KiB
C++
233 lines
6.8 KiB
C++
#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 <string>
|
|
#include <functional>
|
|
|
|
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<Eigen::Vector3f> waypoints;
|
|
size_t currentWaypoint = 0;
|
|
float waypointReachRadius = 3.0f;
|
|
|
|
float followMinDistance = 15.0f;
|
|
float followMaxDistance = 25.0f;
|
|
|
|
std::shared_ptr<Texture> texture;
|
|
};
|
|
|
|
class Location
|
|
{
|
|
public:
|
|
Location(Renderer& iRenderer, Inventory& iInventory, const std::string& locId = "default");
|
|
|
|
std::string getLocationId() const { return locationId; }
|
|
|
|
std::shared_ptr<Texture> roomTexture;
|
|
VertexRenderStruct roomMesh;
|
|
|
|
std::unordered_map<std::string, LoadedGameObject> gameObjects;
|
|
|
|
std::vector<InteractiveObject> interactiveObjects;
|
|
|
|
VertexRenderStruct tileMesh;
|
|
std::shared_ptr<Texture> azsTexture;
|
|
std::shared_ptr<Texture> roadTexture;
|
|
std::shared_ptr<Texture> grassTexture;
|
|
|
|
std::unique_ptr<Character> player;
|
|
std::unique_ptr<Character> girlfriend;
|
|
std::unique_ptr<Character> salesperson;
|
|
std::unique_ptr<Character> police;
|
|
std::unique_ptr<Character> bandit;
|
|
|
|
std::vector<std::unique_ptr<Character>> npcs;
|
|
|
|
float cameraAzimuth = 0.0f;
|
|
float cameraInclination = M_PI * 30.f / 180.f;
|
|
|
|
PathFinder navigation;
|
|
|
|
std::unique_ptr<ShadowMap> shadowMap;
|
|
Eigen::Matrix4f cameraViewMatrix = Eigen::Matrix4f::Identity();
|
|
InteractiveObject* targetInteractiveObject = nullptr;
|
|
|
|
|
|
std::shared_ptr<Texture> carTexture;
|
|
VertexRenderStruct carMesh;
|
|
std::shared_ptr<Texture> 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<void(const std::string&)> onLocationChangeRequest;
|
|
|
|
ScriptEngine scriptEngine;
|
|
Dialogue::DialogueSystem dialogueSystem;
|
|
|
|
//#ifdef SHOW_PATH
|
|
std::vector<VertexRenderStruct> debugNavMeshes;
|
|
void buildDebugNavMeshes();
|
|
void drawDebugNavigation();
|
|
|
|
std::vector<VertexRenderStruct> 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<Eigen::AlignedBox<float, 2>> roofHideZones;
|
|
|
|
std::string azsRoofObjectKey;
|
|
bool azsRoofVisible = true;
|
|
std::vector<Eigen::AlignedBox<float, 2>> 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<float, 2> buildingFirstPersonZone; // X,Z min/max
|
|
float savedCameraAzimuth = 0.f;
|
|
float savedCameraInclination = 0.f;
|
|
// -----------------------------------
|
|
};
|
|
|
|
} // namespace ZL
|