2021-12-05 17:54:36 +00:00
|
|
|
#pragma once
|
2023-01-07 05:17:05 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
#include "dZMCommon.h"
|
|
|
|
#include "LDFFormat.h"
|
2023-01-07 05:17:05 +00:00
|
|
|
#include "tinyxml2.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
|
2023-01-07 05:17:05 +00:00
|
|
|
namespace LUTriggers {
|
|
|
|
struct Trigger;
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
2023-01-07 05:17:05 +00:00
|
|
|
class Level;
|
|
|
|
|
2024-03-09 01:29:01 +00:00
|
|
|
enum class eWaypointCommandType : uint32_t;
|
|
|
|
|
|
|
|
struct WaypointCommand {
|
2024-03-27 02:06:22 +00:00
|
|
|
eWaypointCommandType command{};
|
2024-03-09 01:29:01 +00:00
|
|
|
std::string data;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
struct SceneRef {
|
|
|
|
std::string filename;
|
2024-03-27 02:06:22 +00:00
|
|
|
uint32_t id{};
|
|
|
|
uint32_t sceneType{}; //0 = general, 1 = audio?
|
2021-12-05 17:54:36 +00:00
|
|
|
std::string name;
|
2023-08-10 21:35:12 +00:00
|
|
|
NiPoint3 unknown1;
|
2024-03-27 02:06:22 +00:00
|
|
|
float unknown2{};
|
|
|
|
uint8_t color_r{};
|
|
|
|
uint8_t color_g{};
|
|
|
|
uint8_t color_b{};
|
2021-12-05 17:54:36 +00:00
|
|
|
Level* level;
|
|
|
|
std::map<uint32_t, LUTriggers::Trigger*> triggers;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SceneTransitionInfo {
|
2024-03-27 02:06:22 +00:00
|
|
|
uint64_t sceneID{}; //id of the scene being transitioned to.
|
2021-12-05 17:54:36 +00:00
|
|
|
NiPoint3 position;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SceneTransition {
|
|
|
|
std::string name;
|
|
|
|
std::vector<SceneTransitionInfo> points;
|
2024-03-27 02:06:22 +00:00
|
|
|
float width{};
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct MovingPlatformPathWaypoint {
|
2024-03-27 02:06:22 +00:00
|
|
|
uint8_t lockPlayer{};
|
|
|
|
float wait{};
|
2021-12-05 17:54:36 +00:00
|
|
|
std::string departSound;
|
|
|
|
std::string arriveSound;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CameraPathWaypoint {
|
2024-03-27 02:06:22 +00:00
|
|
|
float time{};
|
|
|
|
float fov{};
|
|
|
|
float tension{};
|
|
|
|
float continuity{};
|
|
|
|
float bias{};
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
2022-11-12 14:44:03 +00:00
|
|
|
struct RacingPathWaypoint {
|
2024-03-27 02:06:22 +00:00
|
|
|
uint8_t isResetNode{};
|
|
|
|
uint8_t isNonHorizontalCamera{};
|
|
|
|
float planeWidth{};
|
|
|
|
float planeHeight{};
|
|
|
|
float shortestDistanceToEnd{};
|
2022-11-12 14:44:03 +00:00
|
|
|
};
|
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
struct PathWaypoint {
|
|
|
|
NiPoint3 position;
|
|
|
|
NiQuaternion rotation; // not included in all, but it's more convenient here
|
|
|
|
MovingPlatformPathWaypoint movingPlatform;
|
|
|
|
CameraPathWaypoint camera;
|
2022-11-12 14:44:03 +00:00
|
|
|
RacingPathWaypoint racing;
|
2024-03-27 02:06:22 +00:00
|
|
|
float speed{};
|
2021-12-05 17:54:36 +00:00
|
|
|
std::vector<LDFBaseData*> config;
|
2024-03-09 01:29:01 +00:00
|
|
|
std::vector<WaypointCommand> commands;
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2022-11-12 14:44:03 +00:00
|
|
|
enum class PropertyPathType : int32_t {
|
|
|
|
Path = 0,
|
|
|
|
EntireZone = 1,
|
|
|
|
GenetatedRectangle = 2
|
|
|
|
};
|
|
|
|
|
2023-01-07 05:17:05 +00:00
|
|
|
enum class PropertyType : int32_t {
|
2022-11-12 14:44:03 +00:00
|
|
|
Premiere = 0,
|
2023-01-07 05:17:05 +00:00
|
|
|
Prize = 1,
|
|
|
|
LUP = 2,
|
|
|
|
Headspace = 3
|
2022-11-12 14:44:03 +00:00
|
|
|
};
|
|
|
|
|
2023-08-10 21:35:12 +00:00
|
|
|
enum class PropertyRentalPeriod : uint32_t {
|
2021-12-05 17:54:36 +00:00
|
|
|
Forever = 0,
|
|
|
|
Seconds = 1,
|
|
|
|
Minutes = 2,
|
|
|
|
Hours = 3,
|
|
|
|
Days = 4,
|
|
|
|
Weeks = 5,
|
|
|
|
Months = 6,
|
|
|
|
Years = 7
|
|
|
|
};
|
|
|
|
|
2023-08-10 21:35:12 +00:00
|
|
|
enum class PropertyAchievmentRequired : uint32_t {
|
2021-12-05 17:54:36 +00:00
|
|
|
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;
|
2024-03-27 02:06:22 +00:00
|
|
|
uint8_t timeBasedMovement{};
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct PropertyPath {
|
2024-03-27 02:06:22 +00:00
|
|
|
PropertyPathType pathType{};
|
|
|
|
int32_t price{};
|
|
|
|
uint32_t rentalTime{};
|
|
|
|
uint64_t associatedZone{};
|
2021-12-05 17:54:36 +00:00
|
|
|
std::string displayName;
|
|
|
|
std::string displayDesc;
|
2024-03-27 02:06:22 +00:00
|
|
|
PropertyType type{};
|
|
|
|
uint32_t cloneLimit{};
|
|
|
|
float repMultiplier{};
|
|
|
|
PropertyRentalPeriod rentalPeriod{};
|
|
|
|
PropertyAchievmentRequired achievementRequired{};
|
2023-11-22 02:04:23 +00:00
|
|
|
|
|
|
|
// Player respawn coordinates in the main zone (not the property zone)
|
2021-12-05 17:54:36 +00:00
|
|
|
NiPoint3 playerZoneCoords;
|
2024-03-27 02:06:22 +00:00
|
|
|
float maxBuildHeight{};
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CameraPath {
|
|
|
|
std::string nextPath;
|
2024-03-27 02:06:22 +00:00
|
|
|
uint8_t rotatePlayer{};
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SpawnerPath {
|
2024-03-27 02:06:22 +00:00
|
|
|
LOT spawnedLOT{};
|
|
|
|
uint32_t respawnTime{};
|
|
|
|
int32_t maxToSpawn{};
|
|
|
|
uint32_t amountMaintained{};
|
2021-12-05 17:54:36 +00:00
|
|
|
LWOOBJID spawnerObjID;
|
2024-03-27 02:06:22 +00:00
|
|
|
uint8_t spawnerNetActive{};
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct Path {
|
2024-03-27 02:06:22 +00:00
|
|
|
uint32_t pathVersion{};
|
2021-12-05 17:54:36 +00:00
|
|
|
PathType pathType;
|
|
|
|
std::string pathName;
|
2024-03-27 02:06:22 +00:00
|
|
|
uint32_t flags{};
|
2021-12-05 17:54:36 +00:00
|
|
|
PathBehavior pathBehavior;
|
2024-03-27 02:06:22 +00:00
|
|
|
uint32_t waypointCount{};
|
2021-12-05 17:54:36 +00:00
|
|
|
std::vector<PathWaypoint> pathWaypoints;
|
|
|
|
SpawnerPath spawner;
|
|
|
|
MovingPlatformPath movingPlatform;
|
|
|
|
PropertyPath property;
|
|
|
|
CameraPath camera;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Zone {
|
|
|
|
public:
|
2023-08-10 21:35:12 +00:00
|
|
|
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
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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; }
|
2023-01-07 05:17:05 +00:00
|
|
|
std::string GetZoneRawPath() const { return m_ZoneRawPath; }
|
2022-08-04 00:59:47 +00:00
|
|
|
std::string GetZonePath() const { return m_ZonePath; }
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
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;
|
2023-08-10 21:35:12 +00:00
|
|
|
FileFormatVersion m_FileFormatVersion;
|
2021-12-05 17:54:36 +00:00
|
|
|
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.
|
|
|
|
|
2023-12-23 17:24:16 +00:00
|
|
|
std::map<LWOSCENEID, SceneRef> m_Scenes;
|
2021-12-05 17:54:36 +00:00
|
|
|
std::vector<SceneTransition> m_SceneTransitions;
|
2022-11-12 14:44:03 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
uint32_t m_PathDataLength;
|
2022-11-12 14:44:03 +00:00
|
|
|
uint32_t m_PathChunkVersion;
|
2023-01-07 05:17:05 +00:00
|
|
|
std::vector<Path> m_Paths;
|
2022-11-12 14:44:03 +00:00
|
|
|
|
2023-12-23 17:24:16 +00:00
|
|
|
std::map<LWOSCENEID, uint32_t> m_MapRevisions; //rhs is the revision!
|
2021-12-05 17:54:36 +00:00
|
|
|
//private ("helper") functions:
|
2022-11-01 18:21:26 +00:00
|
|
|
void LoadScene(std::istream& file);
|
2023-12-23 17:24:16 +00:00
|
|
|
void LoadLUTriggers(std::string triggerFile, SceneRef& scene);
|
2022-11-01 18:21:26 +00:00
|
|
|
void LoadSceneTransition(std::istream& file);
|
|
|
|
SceneTransitionInfo LoadSceneTransitionInfo(std::istream& file);
|
|
|
|
void LoadPath(std::istream& file);
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|