DarkflameServer/dZoneManager/Zone.h
David Markowitz bd9b790e1d
feat: Add MovingAI pathing for NPCs without combatAI (#1509)
* remove goto

* Update MovementAIComponent.cpp

* convert to PathWaypoint

Easier for usage with paths

* add path parsing

* ref removal, simplification of work

* it works

* Update MovementAIComponent.cpp

* disable pathing for combat

we just need it for npcs for now, combat ai can be done later

* fixed stuttery enemies

wow

* start at ramped up speed

* add pausing and resuming

* Update MovementAIComponent.cpp

* Update MovementAIComponent.h

* Update CMakeLists.txt
2024-03-26 21:06:22 -05:00

263 lines
5.8 KiB
C++

#pragma once
#include "dZMCommon.h"
#include "LDFFormat.h"
#include "tinyxml2.h"
#include <string>
#include <vector>
#include <map>
namespace LUTriggers {
struct Trigger;
};
class Level;
enum class eWaypointCommandType : uint32_t;
struct WaypointCommand {
eWaypointCommandType command{};
std::string data;
};
struct SceneRef {
std::string filename;
uint32_t id{};
uint32_t sceneType{}; //0 = general, 1 = audio?
std::string name;
NiPoint3 unknown1;
float unknown2{};
uint8_t color_r{};
uint8_t color_g{};
uint8_t color_b{};
Level* level;
std::map<uint32_t, LUTriggers::Trigger*> triggers;
};
struct SceneTransitionInfo {
uint64_t sceneID{}; //id of the scene being transitioned to.
NiPoint3 position;
};
struct SceneTransition {
std::string name;
std::vector<SceneTransitionInfo> points;
float width{};
};
struct MovingPlatformPathWaypoint {
uint8_t lockPlayer{};
float wait{};
std::string departSound;
std::string arriveSound;
};
struct CameraPathWaypoint {
float time{};
float fov{};
float tension{};
float continuity{};
float bias{};
};
struct RacingPathWaypoint {
uint8_t isResetNode{};
uint8_t isNonHorizontalCamera{};
float planeWidth{};
float planeHeight{};
float shortestDistanceToEnd{};
};
struct PathWaypoint {
NiPoint3 position;
NiQuaternion rotation; // not included in all, but it's more convenient here
MovingPlatformPathWaypoint movingPlatform;
CameraPathWaypoint camera;
RacingPathWaypoint racing;
float speed{};
std::vector<LDFBaseData*> config;
std::vector<WaypointCommand> commands;
};
enum class PathType : uint32_t {
Movement = 0,
MovingPlatform = 1,
Property = 2,
Camera = 3,
Spawner = 4,
Showcase = 5,
Race = 6,
Rail = 7
};
enum class PathBehavior : uint32_t {
Loop = 0,
Bounce = 1,
Once = 2
};
enum class PropertyPathType : int32_t {
Path = 0,
EntireZone = 1,
GenetatedRectangle = 2
};
enum class PropertyType : int32_t {
Premiere = 0,
Prize = 1,
LUP = 2,
Headspace = 3
};
enum class PropertyRentalPeriod : uint32_t {
Forever = 0,
Seconds = 1,
Minutes = 2,
Hours = 3,
Days = 4,
Weeks = 5,
Months = 6,
Years = 7
};
enum class PropertyAchievmentRequired : uint32_t {
None = 0,
Builder = 1,
Craftsman = 2,
SeniorBuilder = 3,
JourneyMan = 4,
MasterBuilder = 5,
Architect = 6,
SeniorArchitect = 7,
MasterArchitect = 8,
Visionary = 9,
Exemplar = 10
};
struct MovingPlatformPath {
std::string platformTravelSound;
uint8_t timeBasedMovement{};
};
struct PropertyPath {
PropertyPathType pathType{};
int32_t price{};
uint32_t rentalTime{};
uint64_t associatedZone{};
std::string displayName;
std::string displayDesc;
PropertyType type{};
uint32_t cloneLimit{};
float repMultiplier{};
PropertyRentalPeriod rentalPeriod{};
PropertyAchievmentRequired achievementRequired{};
// Player respawn coordinates in the main zone (not the property zone)
NiPoint3 playerZoneCoords;
float maxBuildHeight{};
};
struct CameraPath {
std::string nextPath;
uint8_t rotatePlayer{};
};
struct SpawnerPath {
LOT spawnedLOT{};
uint32_t respawnTime{};
int32_t maxToSpawn{};
uint32_t amountMaintained{};
LWOOBJID spawnerObjID;
uint8_t spawnerNetActive{};
};
struct Path {
uint32_t pathVersion{};
PathType pathType;
std::string pathName;
uint32_t flags{};
PathBehavior pathBehavior;
uint32_t waypointCount{};
std::vector<PathWaypoint> pathWaypoints;
SpawnerPath spawner;
MovingPlatformPath movingPlatform;
PropertyPath property;
CameraPath camera;
};
class Zone {
public:
enum class FileFormatVersion : uint32_t { //Times are guessed.
PrePreAlpha = 30,
PreAlpha = 32,
LatePreAlpha = 33,
EarlyAlpha = 35,
Alpha = 36,
LateAlpha = 37,
Beta = 38,
Launch = 39,
Auramar = 40,
Latest = 41
};
public:
Zone(const LWOMAPID& mapID, const LWOINSTANCEID& instanceID, const LWOCLONEID& cloneID);
~Zone();
void Initalize();
void LoadZoneIntoMemory();
std::string GetFilePathForZoneID();
uint32_t CalculateChecksum();
void LoadLevelsIntoMemory();
void AddRevision(LWOSCENEID sceneID, uint32_t revision);
const LWOZONEID& GetZoneID() const { return m_ZoneID; }
const uint32_t GetChecksum() const { return m_CheckSum; }
LUTriggers::Trigger* GetTrigger(uint32_t sceneID, uint32_t triggerID);
const Path* GetPath(std::string name) const;
uint32_t GetWorldID() const { return m_WorldID; }
[[nodiscard]] std::string GetZoneName() const { return m_ZoneName; }
std::string GetZoneRawPath() const { return m_ZoneRawPath; }
std::string GetZonePath() const { return m_ZonePath; }
const NiPoint3& GetSpawnPos() const { return m_Spawnpoint; }
const NiQuaternion& GetSpawnRot() const { return m_SpawnpointRotation; }
void SetSpawnPos(const NiPoint3& pos) { m_Spawnpoint = pos; }
void SetSpawnRot(const NiQuaternion& rot) { m_SpawnpointRotation = rot; }
private:
LWOZONEID m_ZoneID;
std::string m_ZoneFilePath;
uint32_t m_NumberOfObjectsLoaded;
uint32_t m_NumberOfSceneTransitionsLoaded;
FileFormatVersion m_FileFormatVersion;
uint32_t m_CheckSum;
uint32_t m_WorldID; //should be equal to the MapID
NiPoint3 m_Spawnpoint;
NiQuaternion m_SpawnpointRotation;
uint32_t m_SceneCount;
std::string m_ZonePath; //Path to the .luz's folder
std::string m_ZoneName; //Name given to the zone by a level designer
std::string m_ZoneDesc; //Description of the zone by a level designer
std::string m_ZoneRawPath; //Path to the .raw file of this zone.
std::map<LWOSCENEID, SceneRef> m_Scenes;
std::vector<SceneTransition> m_SceneTransitions;
uint32_t m_PathDataLength;
uint32_t m_PathChunkVersion;
std::vector<Path> m_Paths;
std::map<LWOSCENEID, uint32_t> m_MapRevisions; //rhs is the revision!
//private ("helper") functions:
void LoadScene(std::istream& file);
void LoadLUTriggers(std::string triggerFile, SceneRef& scene);
void LoadSceneTransition(std::istream& file);
SceneTransitionInfo LoadSceneTransitionInfo(std::istream& file);
void LoadPath(std::istream& file);
};