2012-09-23 22:11:08 +04:00
|
|
|
#ifndef OPENMW_ESM_LAND_H
|
|
|
|
#define OPENMW_ESM_LAND_H
|
2010-02-25 14:03:03 +01:00
|
|
|
|
2023-08-12 13:29:15 +02:00
|
|
|
#include <array>
|
2023-08-12 13:12:05 +02:00
|
|
|
#include <cstdint>
|
2023-08-12 13:26:04 +02:00
|
|
|
#include <memory>
|
2012-09-17 11:37:50 +04:00
|
|
|
|
2018-09-17 14:52:43 +04:00
|
|
|
#include <components/misc/constants.hpp>
|
|
|
|
|
2022-06-04 16:07:59 +02:00
|
|
|
#include "components/esm/defs.hpp"
|
2022-01-22 15:58:41 +01:00
|
|
|
#include "components/esm/esmcommon.hpp"
|
2010-02-25 14:03:03 +01:00
|
|
|
|
2023-08-12 15:45:44 +02:00
|
|
|
#include "landrecorddata.hpp"
|
|
|
|
|
2011-04-06 20:11:08 +04:00
|
|
|
namespace ESM
|
|
|
|
{
|
2012-10-01 00:51:54 +04:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
class ESMReader;
|
|
|
|
class ESMWriter;
|
2012-10-01 00:51:54 +04:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
/*
|
|
|
|
* Landscape data.
|
|
|
|
*/
|
2010-02-25 14:03:03 +01:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
struct Land
|
|
|
|
{
|
|
|
|
constexpr static RecNameInts sRecordId = REC_LAND;
|
2022-06-04 16:07:59 +02:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
|
|
|
static std::string_view getRecordType() { return "Land"; }
|
2013-09-24 13:17:28 +02:00
|
|
|
|
2023-08-12 13:16:58 +02:00
|
|
|
Land() = default;
|
2012-04-01 21:29:49 +02:00
|
|
|
|
2023-08-12 13:27:52 +02:00
|
|
|
Land(const Land& land);
|
|
|
|
|
|
|
|
Land(Land&& other) = default;
|
|
|
|
|
|
|
|
Land& operator=(const Land& land);
|
|
|
|
|
|
|
|
Land& operator=(Land&& land) = default;
|
|
|
|
|
2023-08-12 13:12:05 +02:00
|
|
|
// Only first four bits seem to be used, don't know what they mean.
|
2023-08-12 13:16:58 +02:00
|
|
|
std::uint32_t mFlags = 0;
|
2023-08-12 13:12:05 +02:00
|
|
|
// Map coordinates.
|
2023-08-12 13:16:58 +02:00
|
|
|
std::int32_t mX = 0;
|
|
|
|
std::int32_t mY = 0;
|
2010-02-25 14:03:03 +01:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// Plugin index, used to reference the correct material palette.
|
|
|
|
int getPlugin() const { return mContext.index; }
|
|
|
|
void setPlugin(int index) { mContext.index = index; }
|
2010-02-25 14:03:03 +01:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// File context. This allows the ESM reader to be 'reset' to this
|
|
|
|
// location later when we are ready to load the full data set.
|
|
|
|
// In the editor, there may not be a file associated with the Land,
|
|
|
|
// in which case the filename will be empty.
|
|
|
|
ESM_Context mContext;
|
2010-02-25 14:03:03 +01:00
|
|
|
|
2023-08-12 13:16:58 +02:00
|
|
|
int mDataTypes = 0;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
DATA_VNML = 1,
|
|
|
|
DATA_VHGT = 2,
|
|
|
|
DATA_WNAM = 4,
|
|
|
|
DATA_VCLR = 8,
|
|
|
|
DATA_VTEX = 16
|
|
|
|
};
|
2016-02-28 16:49:18 +01:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// default height to use in case there is no Land record
|
|
|
|
static constexpr int DEFAULT_HEIGHT = -2048;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// number of vertices per side
|
2023-08-12 15:45:44 +02:00
|
|
|
static constexpr int LAND_SIZE = LandRecordData::sLandSize;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// cell terrain size in world coords
|
|
|
|
static constexpr int REAL_SIZE = Constants::CellSizeInUnits;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// total number of vertices
|
2023-08-12 15:45:44 +02:00
|
|
|
static constexpr int LAND_NUM_VERTS = LandRecordData::sLandNumVerts;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
static constexpr int HEIGHT_SCALE = 8;
|
2012-01-21 17:59:12 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// number of textures per side of land
|
2023-08-12 15:45:44 +02:00
|
|
|
static constexpr int LAND_TEXTURE_SIZE = LandRecordData::sLandTextureSize;
|
2012-01-21 17:59:12 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// total number of textures per land
|
2023-08-12 15:45:44 +02:00
|
|
|
static constexpr int LAND_NUM_TEXTURES = LandRecordData::sLandNumTextures;
|
2017-09-03 20:00:19 -04:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
static constexpr int LAND_GLOBAL_MAP_LOD_SIZE = 81;
|
2020-01-10 15:49:57 +03:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
static constexpr int LAND_GLOBAL_MAP_LOD_SIZE_SQRT = 9;
|
|
|
|
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
struct VHGT
|
|
|
|
{
|
|
|
|
float mHeightOffset;
|
2023-08-12 13:12:05 +02:00
|
|
|
std::int8_t mHeightData[LAND_NUM_VERTS];
|
|
|
|
std::uint16_t mUnk1;
|
|
|
|
std::uint8_t mUnk2;
|
2022-09-22 21:26:05 +03:00
|
|
|
};
|
2012-01-21 16:59:08 +00:00
|
|
|
#pragma pack(pop)
|
|
|
|
|
2023-08-12 15:45:44 +02:00
|
|
|
using LandData = ESM::LandRecordData;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
// low-LOD heightmap (used for rendering the global map)
|
2023-08-12 13:29:15 +02:00
|
|
|
std::array<std::int8_t, LAND_GLOBAL_MAP_LOD_SIZE> mWnam;
|
2017-02-14 02:40:41 +01:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
void load(ESMReader& esm, bool& isDeleted);
|
|
|
|
void save(ESMWriter& esm, bool isDeleted = false) const;
|
2012-01-21 16:59:08 +00:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
void blank();
|
2014-10-08 17:17:31 +02:00
|
|
|
|
2023-08-12 15:04:44 +02:00
|
|
|
void loadData(int flags) const;
|
|
|
|
|
|
|
|
void loadData(int flags, LandData& data) const;
|
2012-04-04 21:05:19 +02:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
/**
|
|
|
|
* Frees memory allocated for mLandData
|
|
|
|
*/
|
2023-08-12 15:04:44 +02:00
|
|
|
void unloadData();
|
2012-04-04 21:39:21 +02:00
|
|
|
|
2022-09-22 21:26:05 +03:00
|
|
|
/// Check if given data type is loaded
|
|
|
|
bool isDataLoaded(int flags) const;
|
2012-09-21 12:12:16 +04:00
|
|
|
|
2015-08-31 16:13:26 +02:00
|
|
|
/// Return land data with at least the data types specified in \a flags loaded (if they
|
|
|
|
/// are available). Will return a 0-pointer if there is no data for any of the
|
|
|
|
/// specified types.
|
2022-09-22 21:26:05 +03:00
|
|
|
const LandData* getLandData(int flags) const;
|
2015-08-31 16:13:26 +02:00
|
|
|
|
|
|
|
/// Return land data without loading first anything. Can return a 0-pointer.
|
2023-08-12 13:21:50 +02:00
|
|
|
const LandData* getLandData() const
|
|
|
|
{
|
2023-08-12 13:26:04 +02:00
|
|
|
return mLandData.get();
|
2023-08-12 13:21:50 +02:00
|
|
|
}
|
2015-08-31 16:13:26 +02:00
|
|
|
|
2015-09-03 16:15:00 +02:00
|
|
|
/// Return land data without loading first anything. Can return a 0-pointer.
|
2023-08-12 13:21:50 +02:00
|
|
|
LandData* getLandData()
|
|
|
|
{
|
2023-08-12 13:26:04 +02:00
|
|
|
return mLandData.get();
|
2023-08-12 13:21:50 +02:00
|
|
|
}
|
2015-09-03 16:15:00 +02:00
|
|
|
|
|
|
|
/// \attention Must not be called on objects that aren't fully loaded.
|
|
|
|
///
|
|
|
|
/// \note Added data fields will be uninitialised
|
2022-09-22 21:26:05 +03:00
|
|
|
void add(int flags);
|
2015-09-03 16:15:00 +02:00
|
|
|
|
2012-04-04 21:39:21 +02:00
|
|
|
private:
|
2023-08-12 13:26:04 +02:00
|
|
|
mutable std::unique_ptr<LandData> mLandData;
|
2022-09-22 21:26:05 +03:00
|
|
|
};
|
2012-04-04 21:39:21 +02:00
|
|
|
|
2010-02-25 14:03:03 +01:00
|
|
|
}
|
|
|
|
#endif
|