Generify RIE parsing, implement setBiome
parent
ee94e691ae
commit
7c87b002d2
|
@ -274,6 +274,6 @@ set(ZEPHA_SRC
|
|||
util/net/Serializer.h
|
||||
util/net/Deserializer.h
|
||||
lua/api/type/ServerLocalLuaEntity.cpp
|
||||
lua/api/type/ServerLocalLuaEntity.h lua/api/modules/register_item.h lua/api/modules/register_biome.h lua/api/modules/delay.h lua/api/modules/register_block.h lua/api/modules/register_blockmodel.h lua/api/modules/register_entity.h game/scene/world/World.cpp game/scene/world/World.h lua/api/modules/set_block.h lua/api/modules/get_block.h lua/api/modules/remove_block.h lua/register/RegisterBiomes.h lua/register/RegisterBlocks.h lua/register/RegisterItems.h lua/register/RegisterKeybinds.h lua/api/type/LocalLuaAnimationManager.cpp lua/api/type/LocalLuaAnimationManager.h lua/api/type/cLocalLuaAnimationManager.h game/scene/world/Schematic.cpp game/scene/world/Schematic.h lua/VenusParser.cpp lua/VenusParser.h lua/ErrorFormatter.cpp lua/ErrorFormatter.h)
|
||||
lua/api/type/ServerLocalLuaEntity.h lua/api/modules/register_item.h lua/api/modules/register_biome.h lua/api/modules/delay.h lua/api/modules/register_block.h lua/api/modules/register_blockmodel.h lua/api/modules/register_entity.h game/scene/world/World.cpp game/scene/world/World.h lua/api/modules/set_block.h lua/api/modules/get_block.h lua/api/modules/remove_block.h lua/register/RegisterBiomes.h lua/register/RegisterBlocks.h lua/register/RegisterItems.h lua/register/RegisterKeybinds.h lua/api/type/LocalLuaAnimationManager.cpp lua/api/type/LocalLuaAnimationManager.h lua/api/type/cLocalLuaAnimationManager.h game/scene/world/Schematic.cpp game/scene/world/Schematic.h lua/VenusParser.cpp lua/VenusParser.h lua/ErrorFormatter.cpp lua/ErrorFormatter.h util/RIE.h)
|
||||
|
||||
add_library (Zepha_Core ${ZEPHA_SRC})
|
|
@ -0,0 +1,116 @@
|
|||
//
|
||||
// Created by aurailus on 2020-02-14.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
|
||||
struct RIE {
|
||||
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> static T read(
|
||||
const unsigned int ind, const std::vector<T>& data, const unsigned int dataLen) {
|
||||
|
||||
if (ind >= dataLen) return 0;
|
||||
for (unsigned int i = 0; i < data.size(); i += 2) {
|
||||
if (data[i] > ind) return data[i - 1];
|
||||
}
|
||||
|
||||
return data[data.size() - 1];
|
||||
}
|
||||
|
||||
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> static bool write(
|
||||
const unsigned int ind, const T val, std::vector<T>& data, const unsigned int dataLen) {
|
||||
|
||||
if (ind >= dataLen) return false;
|
||||
if (read(ind, data, dataLen) == val) return false;
|
||||
|
||||
if (ind == 0) {
|
||||
if (data[2] == ind + 1) {
|
||||
data[1] = val;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
data.insert(data.begin() + 2, 2, ind);
|
||||
data[2] = 1;
|
||||
data[3] = data[1];
|
||||
data[1] = val;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < data.size(); i += 2) {
|
||||
if (data[i] == ind) {
|
||||
// We found an index equating to the block we are going to be setting.
|
||||
if (data[i - 1] == val) {
|
||||
// The last block strip is the same block ID as what we are setting,
|
||||
// So we should extend that strip.
|
||||
if (data.size() > i + 2 && data[i + 2] == ind + 1) {
|
||||
// The next block is one later, meaning we can simply remove this found block
|
||||
// To cause the next strip to cascade over its position.
|
||||
data.erase(data.begin() + i, data.begin() + i + 2);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// The next strip is multiple blocks over, so just add one to our found block index.
|
||||
data[i] += 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The last strip is not the same block.
|
||||
if (data.size() > i + 2 && data[i + 2] == ind + 1) {
|
||||
// There is only one of our block, so we can just update its id.
|
||||
data[i + 1] = val;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// The next strip is multiple blocks over, so we need to copy the previous block to the right
|
||||
// and then set our block into its place
|
||||
data.insert(data.begin() + i, 2, ind);
|
||||
data[i + 1] = val;
|
||||
data[i + 2] = ind + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data[i] > ind) {
|
||||
// We found a strip with an index *larger* than our ind.
|
||||
// We can assume the last strip is not our block, because the getBlock() catch would have caught that.
|
||||
if (data[i] == ind + 1) {
|
||||
if (data[i + 1] == val) {
|
||||
// The next block over is the same, so we can just decrement our index by one.
|
||||
data[i]--;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// There is only one of our block to be placed, directly before our current strip
|
||||
data.insert(data.begin() + i, 2, ind);
|
||||
data[i + 1] = val;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The next strip is multiple blocks over, so we need to insert both our block
|
||||
// *and* the previous strip's block after
|
||||
data.insert(data.begin() + i, 4, ind);
|
||||
data[i + 1] = val;
|
||||
data[i + 2] = ind + 1;
|
||||
data[i + 3] = data[i - 1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Escaped the for loop, meaning there's no index greater than ours.
|
||||
// We will insert our index at the end of the array, and insert the previous block after
|
||||
// if we're not at the end of the chunk.
|
||||
data.push_back(ind);
|
||||
data.push_back(val);
|
||||
|
||||
if (ind >= dataLen - 1) return true; // Don't add the reset if at the end of the chunk.
|
||||
|
||||
data.push_back(ind + 1);
|
||||
data.push_back(data[data.size() - 4]);
|
||||
return true;
|
||||
}
|
||||
};
|
|
@ -20,112 +20,20 @@ BlockChunk::BlockChunk(const std::vector<unsigned int>& blocks, const std::vecto
|
|||
}
|
||||
|
||||
bool BlockChunk::setBlock(unsigned int ind, unsigned int blk) {
|
||||
// Exit early if no manipulation is needed.
|
||||
// Exit if someone is doing something stupid
|
||||
if (ind >= 4096) return false;
|
||||
|
||||
const unsigned int existing = getBlock(ind);
|
||||
if (existing == blk) return false;
|
||||
|
||||
// Deal with shouldHaveMesh
|
||||
if (blk == DefinitionAtlas::AIR) {
|
||||
if ((nonAirBlocks = fmax(nonAirBlocks - 1, 0)) == 0) {
|
||||
empty = true;
|
||||
shouldHaveMesh = false;
|
||||
}
|
||||
// Mesh emptiness manipulation
|
||||
if (blk == DefinitionAtlas::AIR && (nonAirBlocks = fmax(nonAirBlocks - 1, 0)) == 0) {
|
||||
empty = true;
|
||||
shouldHaveMesh = false;
|
||||
}
|
||||
else if (existing == DefinitionAtlas::AIR) {
|
||||
else if (blk != DefinitionAtlas::AIR && getBlock(ind) == DefinitionAtlas::AIR) {
|
||||
if (nonAirBlocks == 0) shouldHaveMesh = true;
|
||||
empty = false;
|
||||
nonAirBlocks++;
|
||||
}
|
||||
|
||||
if (ind == 0) {
|
||||
if (blocks[2] == ind + 1) {
|
||||
blocks[1] = blk;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
blocks.insert(blocks.begin() + 2, 2, ind);
|
||||
blocks[2] = 1;
|
||||
blocks[3] = blocks[1];
|
||||
blocks[1] = blk;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < blocks.size(); i += 2) {
|
||||
if (blocks[i] == ind) {
|
||||
// We found an index equating to the block we are going to be setting.
|
||||
if (blocks[i - 1] == blk) {
|
||||
// The last block strip is the same block ID as what we are setting,
|
||||
// So we should extend that strip.
|
||||
if (blocks.size() > i + 2 && blocks[i + 2] == ind + 1) {
|
||||
// The next block is one later, meaning we can simply remove this found block
|
||||
// To cause the next strip to cascade over its position.
|
||||
blocks.erase(blocks.begin() + i, blocks.begin() + i + 2);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// The next strip is multiple blocks over, so just add one to our found block index.
|
||||
blocks[i] += 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The last strip is not the same block.
|
||||
if (blocks.size() > i + 2 && blocks[i + 2] == ind + 1) {
|
||||
// There is only one of our block, so we can just update its id.
|
||||
blocks[i + 1] = blk;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// The next strip is multiple blocks over, so we need to copy the previous block to the right
|
||||
// and then set our block into its place
|
||||
blocks.insert(blocks.begin() + i, 2, ind);
|
||||
blocks[i + 1] = blk;
|
||||
blocks[i + 2] = ind + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (blocks[i] > ind) {
|
||||
// We found a strip with an index *larger* than our ind.
|
||||
// We can assume the last strip is not our block, because the getBlock() catch would have caught that.
|
||||
if (blocks[i] == ind + 1) {
|
||||
if (blocks[i + 1] == blk) {
|
||||
// The next block over is the same, so we can just decrement our index by one.
|
||||
blocks[i] --;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// There is only one of our block to be placed, directly before our current strip
|
||||
blocks.insert(blocks.begin() + i, 2, ind);
|
||||
blocks[i + 1] = blk;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The next strip is multiple blocks over, so we need to insert both our block
|
||||
// *and* the previous strip's block after
|
||||
blocks.insert(blocks.begin() + i, 4, ind);
|
||||
blocks[i + 1] = blk;
|
||||
blocks[i + 2] = ind + 1;
|
||||
blocks[i + 3] = blocks[i - 1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Escaped the for loop, meaning there's no index greater than ours.
|
||||
// We will insert our index at the end of the array, and insert the previous block after
|
||||
// if we're not at the end of the chunk.
|
||||
blocks.push_back(ind);
|
||||
blocks.push_back(blk);
|
||||
|
||||
if (ind >= 4095) return true; // Don't add the reset if at the end of the chunk.
|
||||
|
||||
blocks.push_back(ind + 1);
|
||||
blocks.push_back(blocks[blocks.size() - 4]);
|
||||
return true;
|
||||
// Return the value
|
||||
RIE::write(ind, blk, blocks, 4096);
|
||||
}
|
||||
|
||||
const std::vector<unsigned int> &BlockChunk::cGetBlocks() const {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <glm/vec3.hpp>
|
||||
#include "../../util/Log.h"
|
||||
#include "../../util/Vec.h"
|
||||
#include "../../util/RIE.h"
|
||||
#include "../../util/Util.h"
|
||||
#include "../../util/net/Packet.h"
|
||||
#include "../../def/gen/BiomeAtlas.h"
|
||||
|
@ -30,7 +31,8 @@ public:
|
|||
inline unsigned int getBlock(unsigned int ind) const;
|
||||
inline unsigned int getBlock(const glm::ivec3& pos) const;
|
||||
|
||||
// bool setBiome(const glm::ivec3& pos, unsigned int ind);
|
||||
inline bool setBiome(unsigned int ind, unsigned short bio);
|
||||
inline bool setBiome(const glm::ivec3& pos, unsigned short bio);
|
||||
|
||||
inline unsigned short getBiome(unsigned int ind) const;
|
||||
inline unsigned short getBiome(const glm::ivec3& pos) const;
|
||||
|
@ -73,10 +75,7 @@ inline bool BlockChunk::setBlock(const glm::ivec3& pos, unsigned int blk) {
|
|||
|
||||
inline unsigned int BlockChunk::getBlock(unsigned int ind) const {
|
||||
if (ind >= 4096) return DefinitionAtlas::INVALID;
|
||||
for (unsigned int i = 0; i < blocks.size(); i += 2) {
|
||||
if (blocks[i] > ind) return blocks[i - 1];
|
||||
}
|
||||
return blocks[blocks.size() - 1];
|
||||
return RIE::read<unsigned int>(ind, blocks, 4096);
|
||||
}
|
||||
|
||||
inline unsigned int BlockChunk::getBlock(const glm::ivec3& pos) const {
|
||||
|
@ -84,12 +83,18 @@ inline unsigned int BlockChunk::getBlock(const glm::ivec3& pos) const {
|
|||
return getBlock(Space::Block::index(pos));
|
||||
}
|
||||
|
||||
inline bool BlockChunk::setBiome(unsigned int ind, unsigned short bio) {
|
||||
RIE::write(ind, bio, biomes, 4096);
|
||||
}
|
||||
|
||||
inline bool BlockChunk::setBiome(const glm::ivec3& pos, unsigned short bio) {
|
||||
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return false;
|
||||
return setBiome(Space::Block::index(pos), bio);
|
||||
}
|
||||
|
||||
inline unsigned short BlockChunk::getBiome(unsigned int ind) const {
|
||||
if (ind >= 4096) return BiomeAtlas::INVALID;
|
||||
for (unsigned int i = 0; i < biomes.size(); i += 2) {
|
||||
if (biomes[i] > ind) return biomes[i - 1];
|
||||
}
|
||||
return biomes[biomes.size() - 1];
|
||||
return RIE::read<unsigned short>(ind, biomes, 4096);
|
||||
}
|
||||
|
||||
inline unsigned short BlockChunk::getBiome(const glm::ivec3& pos) const {
|
||||
|
|
Loading…
Reference in New Issue