commit
57a9a26c23
@ -9,7 +9,10 @@
|
|||||||
#include "data/dv.hpp"
|
#include "data/dv.hpp"
|
||||||
#include "io/engine_paths.hpp"
|
#include "io/engine_paths.hpp"
|
||||||
#include "io/io.hpp"
|
#include "io/io.hpp"
|
||||||
|
#include "coders/commons.hpp"
|
||||||
|
#include "debug/Logger.hpp"
|
||||||
|
|
||||||
|
static debug::Logger logger("content-pack");
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
@ -47,6 +50,24 @@ bool ContentPack::is_pack(const io::path& folder) {
|
|||||||
return io::is_regular_file(folder / PACKAGE_FILENAME);
|
return io::is_regular_file(folder / PACKAGE_FILENAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<ContentPackStats> ContentPack::loadStats() const {
|
||||||
|
auto contentFile = getContentFile();
|
||||||
|
if (!io::exists(contentFile)) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
dv::value object;
|
||||||
|
try {
|
||||||
|
object = io::read_object(contentFile);
|
||||||
|
} catch (const parsing_error& err) {
|
||||||
|
logger.error() << err.errorLog();
|
||||||
|
}
|
||||||
|
ContentPackStats stats {};
|
||||||
|
stats.totalBlocks = object.has("blocks") ? object["blocks"].size() : 0;
|
||||||
|
stats.totalItems = object.has("items") ? object["items"].size() : 0;
|
||||||
|
stats.totalEntities = object.has("entities") ? object["entities"].size() : 0;
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
static void checkContentPackId(const std::string& id, const io::path& folder) {
|
static void checkContentPackId(const std::string& id, const io::path& folder) {
|
||||||
if (id.length() < 2 || id.length() > 24)
|
if (id.length() < 2 || id.length() > 24)
|
||||||
throw contentpack_error(
|
throw contentpack_error(
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
#include "content_fwd.hpp"
|
#include "content_fwd.hpp"
|
||||||
@ -36,6 +37,16 @@ struct DependencyPack {
|
|||||||
std::string id;
|
std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ContentPackStats {
|
||||||
|
size_t totalBlocks;
|
||||||
|
size_t totalItems;
|
||||||
|
size_t totalEntities;
|
||||||
|
|
||||||
|
inline bool hasSavingContent() const {
|
||||||
|
return totalBlocks + totalItems + totalEntities > 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ContentPack {
|
struct ContentPack {
|
||||||
std::string id = "none";
|
std::string id = "none";
|
||||||
std::string title = "untitled";
|
std::string title = "untitled";
|
||||||
@ -48,6 +59,8 @@ struct ContentPack {
|
|||||||
|
|
||||||
io::path getContentFile() const;
|
io::path getContentFile() const;
|
||||||
|
|
||||||
|
std::optional<ContentPackStats> loadStats() const;
|
||||||
|
|
||||||
static inline const std::string PACKAGE_FILENAME = "package.json";
|
static inline const std::string PACKAGE_FILENAME = "package.json";
|
||||||
static inline const std::string CONTENT_FILENAME = "content.json";
|
static inline const std::string CONTENT_FILENAME = "content.json";
|
||||||
static inline const io::path BLOCKS_FOLDER = "blocks";
|
static inline const io::path BLOCKS_FOLDER = "blocks";
|
||||||
@ -87,16 +100,6 @@ struct ContentPack {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ContentPackStats {
|
|
||||||
size_t totalBlocks;
|
|
||||||
size_t totalItems;
|
|
||||||
size_t totalEntities;
|
|
||||||
|
|
||||||
inline bool hasSavingContent() const {
|
|
||||||
return totalBlocks + totalItems + totalEntities > 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WorldFuncsSet {
|
struct WorldFuncsSet {
|
||||||
bool onblockplaced;
|
bool onblockplaced;
|
||||||
bool onblockreplaced;
|
bool onblockreplaced;
|
||||||
|
|||||||
@ -270,6 +270,7 @@ void Hud::updateHotbarControl() {
|
|||||||
void Hud::updateWorldGenDebug() {
|
void Hud::updateWorldGenDebug() {
|
||||||
auto& level = frontend.getLevel();
|
auto& level = frontend.getLevel();
|
||||||
const auto& chunks = *player.chunks;
|
const auto& chunks = *player.chunks;
|
||||||
|
uint padding = engine.getSettings().chunks.padding.get();
|
||||||
auto generator =
|
auto generator =
|
||||||
frontend.getController()->getChunksController()->getGenerator();
|
frontend.getController()->getChunksController()->getGenerator();
|
||||||
auto debugInfo = generator->createDebugInfo();
|
auto debugInfo = generator->createDebugInfo();
|
||||||
@ -291,8 +292,15 @@ void Hud::updateWorldGenDebug() {
|
|||||||
int ax = x - (width - areaWidth) / 2;
|
int ax = x - (width - areaWidth) / 2;
|
||||||
int az = z - (height - areaHeight) / 2;
|
int az = z - (height - areaHeight) / 2;
|
||||||
|
|
||||||
data[(flippedZ * width + x) * 4 + 1] =
|
bool isInLoadingZone =
|
||||||
chunks.getChunk(ax + ox, az + oz) ? 255 : 0;
|
frontend.getController()
|
||||||
|
->getChunksController()
|
||||||
|
->isInLoadingZone(player, padding, ax + ox, az + oz);
|
||||||
|
|
||||||
|
data[(flippedZ * width + x) * 4 + 1] =
|
||||||
|
chunks.getChunk(ax + ox, az + oz)
|
||||||
|
? (isInLoadingZone ? 255 : 128)
|
||||||
|
: 0;
|
||||||
data[(flippedZ * width + x) * 4 + 0] =
|
data[(flippedZ * width + x) * 4 + 0] =
|
||||||
level.chunks->fetch(ax + ox, az + oz) ? 255 : 0;
|
level.chunks->fetch(ax + ox, az + oz) ? 255 : 0;
|
||||||
|
|
||||||
|
|||||||
@ -60,18 +60,55 @@ void ChunksController::update(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChunksController::loadVisible(const Player& player, uint padding) const {
|
bool ChunksController::isInLoadingZone(
|
||||||
|
const Player& player, uint padding, int x, int z
|
||||||
|
) const {
|
||||||
const auto& chunks = *player.chunks;
|
const auto& chunks = *player.chunks;
|
||||||
int sizeX = chunks.getWidth();
|
int sizeX = chunks.getWidth();
|
||||||
int sizeY = chunks.getHeight();
|
int sizeY = chunks.getHeight();
|
||||||
|
|
||||||
|
int minDistance = ((sizeX - padding * 2) / 2) * ((sizeY - padding * 2) / 2);
|
||||||
|
|
||||||
|
int lx = (x - chunks.getOffsetX()) - sizeX / 2;
|
||||||
|
int lz = (z - chunks.getOffsetY()) - sizeY / 2;
|
||||||
|
int distance = (lx * lx + lz * lz);
|
||||||
|
|
||||||
|
return distance < minDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChunksController::loadVisible(const Player& player, uint padding) const {
|
||||||
|
auto& chunks = *player.chunks;
|
||||||
|
int sizeX = chunks.getWidth();
|
||||||
|
int sizeY = chunks.getHeight();
|
||||||
|
|
||||||
int nearX = 0;
|
int nearX = 0;
|
||||||
int nearZ = 0;
|
int nearZ = 0;
|
||||||
bool assigned = false;
|
bool assigned = false;
|
||||||
int minDistance = ((sizeX - padding * 2) / 2) * ((sizeY - padding * 2) / 2);
|
int minDistance = ((sizeX - padding * 2) / 2) * ((sizeY - padding * 2) / 2);
|
||||||
|
int maxDistance = ((sizeX) / 2) * ((sizeY) / 2);
|
||||||
|
for (uint z = 0; z < sizeY; z++) {
|
||||||
|
for (uint x = 0; x < sizeX; x++) {
|
||||||
|
int index = z * sizeX + x;
|
||||||
|
int lx = x - sizeX / 2;
|
||||||
|
int lz = z - sizeY / 2;
|
||||||
|
int distance = (lx * lx + lz * lz);
|
||||||
|
auto& chunk = chunks.getChunks()[index];
|
||||||
|
if (chunk != nullptr) {
|
||||||
|
if (distance >= maxDistance) {
|
||||||
|
chunks.remove(
|
||||||
|
x + chunks.getOffsetX(), z + chunks.getOffsetY()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (uint z = padding; z < sizeY - padding; z++) {
|
for (uint z = padding; z < sizeY - padding; z++) {
|
||||||
for (uint x = padding; x < sizeX - padding; x++) {
|
for (uint x = padding; x < sizeX - padding; x++) {
|
||||||
int index = z * sizeX + x;
|
int index = z * sizeX + x;
|
||||||
|
int lx = x - sizeX / 2;
|
||||||
|
int lz = z - sizeY / 2;
|
||||||
|
int distance = (lx * lx + lz * lz);
|
||||||
auto& chunk = chunks.getChunks()[index];
|
auto& chunk = chunks.getChunks()[index];
|
||||||
if (chunk != nullptr) {
|
if (chunk != nullptr) {
|
||||||
if (chunk->flags.loaded && !chunk->flags.lighted) {
|
if (chunk->flags.loaded && !chunk->flags.lighted) {
|
||||||
@ -81,9 +118,7 @@ bool ChunksController::loadVisible(const Player& player, uint padding) const {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int lx = x - sizeX / 2;
|
|
||||||
int lz = z - sizeY / 2;
|
|
||||||
int distance = (lx * lx + lz * lz);
|
|
||||||
if (distance < minDistance) {
|
if (distance < minDistance) {
|
||||||
minDistance = distance;
|
minDistance = distance;
|
||||||
nearX = x;
|
nearX = x;
|
||||||
|
|||||||
@ -32,6 +32,8 @@ public:
|
|||||||
int64_t maxDuration, int loadDistance, uint padding, Player& player
|
int64_t maxDuration, int loadDistance, uint padding, Player& player
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
bool isInLoadingZone(const Player& player, uint padding, int x, int z) const;
|
||||||
|
|
||||||
const WorldGenerator* getGenerator() const {
|
const WorldGenerator* getGenerator() const {
|
||||||
return generator.get();
|
return generator.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -123,8 +123,13 @@ static int l_pack_get_info(
|
|||||||
auto runtime = content ? content->getPackRuntime(pack.id) : nullptr;
|
auto runtime = content ? content->getPackRuntime(pack.id) : nullptr;
|
||||||
if (runtime) {
|
if (runtime) {
|
||||||
lua::pushboolean(L, runtime->getStats().hasSavingContent());
|
lua::pushboolean(L, runtime->getStats().hasSavingContent());
|
||||||
lua::setfield(L, "has_indices");
|
} else {
|
||||||
|
auto stats = pack.loadStats();
|
||||||
|
lua::pushboolean(
|
||||||
|
L, stats.has_value() ? stats->hasSavingContent() : false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
lua::setfield(L, "has_indices");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -114,6 +114,17 @@ namespace util {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void remove(TCoord x, TCoord y) {
|
||||||
|
auto lx = x - offsetX;
|
||||||
|
auto ly = y - offsetY;
|
||||||
|
if (lx < 0 || ly < 0 || lx >= sizeX || ly >= sizeY) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (outCallback)
|
||||||
|
outCallback(x, y, firstBuffer[ly * sizeX + lx]);
|
||||||
|
firstBuffer[ly * sizeX + lx] = T{};
|
||||||
|
}
|
||||||
|
|
||||||
void setOutCallback(const OutCallback& callback) {
|
void setOutCallback(const OutCallback& callback) {
|
||||||
outCallback = callback;
|
outCallback = callback;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -419,3 +419,7 @@ void Chunks::getVoxels(VoxelsVolume& volume, bool backlight) const {
|
|||||||
void Chunks::saveAndClear() {
|
void Chunks::saveAndClear() {
|
||||||
areaMap.clear();
|
areaMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Chunks::remove(int32_t x, int32_t z) {
|
||||||
|
areaMap.remove(x, z);
|
||||||
|
}
|
||||||
|
|||||||
@ -133,6 +133,8 @@ public:
|
|||||||
|
|
||||||
void saveAndClear();
|
void saveAndClear();
|
||||||
|
|
||||||
|
void remove(int32_t x, int32_t z);
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<Chunk>>& getChunks() const {
|
const std::vector<std::shared_ptr<Chunk>>& getChunks() const {
|
||||||
return areaMap.getBuffer();
|
return areaMap.getBuffer();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user