Synchronized Server side entities! Many integer vectors changed to ivecs

master
Nicole Collings 2020-01-08 14:42:14 -08:00
parent 72dbfd9cbf
commit 5d59e013d2
38 changed files with 261 additions and 133 deletions

View File

@ -282,6 +282,32 @@ set(ZEPHA_SRC
game/hud/GuiBuilder.h
game/hud/GameGuiBuilder.cpp
game/hud/GameGuiBuilder.h
lua/api/modules/mStartGame.h lua/api/type/LuaInventoryList.cpp lua/api/type/LuaInventoryList.h lua/api/type/LuaInventory.cpp lua/api/type/LuaInventory.h game/scene/world/Inventory.cpp game/scene/world/Inventory.h lua/api/type/LuaItemStack.cpp lua/api/type/LuaItemStack.h game/scene/world/ItemStack.cpp lua/api/type/cLuaInventory.h lua/api/type/cLuaItemStack.h game/hud/components/basic/GUIModel.cpp game/hud/components/basic/GUIModel.h lua/api/modules/sAddEntity.h server/world/ServerEntity.cpp server/world/ServerEntity.h lua/api/type/ServerLuaEntity.cpp lua/api/type/ServerLuaEntity.h game/scene/LuaErrorScene.cpp game/scene/LuaErrorScene.h lua/api/functions/sUpdateEntities.h lua/api/type/sServerLuaEntity.h util/net/Serializer.h util/net/Deserializer.h)
lua/api/modules/mStartGame.h
lua/api/type/LuaInventoryList.cpp
lua/api/type/LuaInventoryList.h
lua/api/type/LuaInventory.cpp
lua/api/type/LuaInventory.h
game/scene/world/Inventory.cpp
game/scene/world/Inventory.h
lua/api/type/LuaItemStack.cpp
lua/api/type/LuaItemStack.h
game/scene/world/ItemStack.cpp
lua/api/type/cLuaInventory.h
lua/api/type/cLuaItemStack.h
game/hud/components/basic/GUIModel.cpp
game/hud/components/basic/GUIModel.h
lua/api/modules/sAddEntity.h
server/world/ServerEntity.cpp
server/world/ServerEntity.h
lua/api/type/ServerLuaEntity.cpp
lua/api/type/ServerLuaEntity.h
game/scene/LuaErrorScene.cpp
game/scene/LuaErrorScene.h
lua/api/functions/sUpdateEntities.h
lua/api/type/sServerLuaEntity.h
util/net/Serializer.h
util/net/Deserializer.h
lua/api/type/ServerLocalLuaEntity.cpp
lua/api/type/ServerLocalLuaEntity.h)
add_library (Zepha_Core ${ZEPHA_SRC})

View File

@ -13,7 +13,7 @@ ServerDefinitionAtlas::ServerDefinitionAtlas() {
//Air Node
BlockModel nullModel {};
BlockDef* air = new BlockDef("", AIR, "Air", 1, nullModel, false, {}, {});
BlockDef* air = new BlockDef("air", AIR, "Air (you broke the game!)", 1, nullModel, false, {}, {});
registerDef(air);
}

View File

@ -46,8 +46,8 @@ public:
return Dir::NONE;
}
static glm::vec3 faceToOffset(Dir f) {
static const glm::vec3 positionOffsets[6] {
static glm::ivec3 faceToOffset(Dir f) {
static const glm::ivec3 positionOffsets[6] {
{ 1, 0, 0},
{-1, 0, 0},
{ 0, 1, 0},

View File

@ -114,7 +114,7 @@ ClientNetworkInterpreter::~ClientNetworkInterpreter() {
cleanup();
}
void ClientNetworkInterpreter::setBlock(glm::vec3 pos, unsigned int block) {
void ClientNetworkInterpreter::setBlock(glm::ivec3 pos, unsigned int block) {
Packet p(PacketType::BLOCK_SET);
Serializer()
.append(pos)

View File

@ -27,7 +27,7 @@ public:
void update(Player &player);
void cleanup();
void setBlock(glm::vec3 pos, unsigned int block);
void setBlock(glm::ivec3 pos, unsigned int block);
~ClientNetworkInterpreter();

View File

@ -150,7 +150,7 @@ unsigned short LocalWorld::getBiome(glm::vec3 pos) {
return BiomeAtlas::INVALID;
}
void LocalWorld::localSetBlock(glm::vec3 pos, unsigned int block) {
void LocalWorld::localSetBlock(glm::ivec3 pos, unsigned int block) {
if (block == LocalDefinitionAtlas::AIR) {
auto def = defs.defs.blockFromId(getBlock(pos));
if (def.callbacks.count(Callback::BREAK_CLIENT)) {

View File

@ -51,8 +51,8 @@ public:
unsigned short getBiome(glm::vec3 pos);
//Called by the Client
void localSetBlock(glm::vec3 pos, unsigned int block);
//Called form ClientNetworkInterpreter
void localSetBlock(glm::ivec3 pos, unsigned int block);
//Called from ClientNetworkInterpreter
void setBlock(glm::vec3 pos, unsigned int block);
bool solidAt(glm::vec3 pos);

View File

@ -66,6 +66,6 @@ private:
std::array<NoiseSample, 3> noiseSampler;
std::vector<glm::vec3> queuedTasks;
std::unordered_set<glm::vec3, Vec::compareFunc> queuedMap;
std::unordered_set<glm::vec3, Vec::vec3> queuedMap;
};

View File

@ -137,15 +137,15 @@ void Player::updateCamera() {
}
void Player::findPointedThing(Input &input) {
glm::vec3 chunkPos = {};
glm::ivec3 chunkPos = {};
sptr<BlockChunk> blockChunk = nullptr;
for (Ray ray(this); ray.getLength() < LOOK_DISTANCE; ray.step(LOOK_PRECISION)) {
glm::vec3 rayEnd = ray.getEnd();
glm::vec3 roundedPos = glm::floor(rayEnd);
glm::ivec3 roundedPos = glm::floor(rayEnd);
auto currChunkPos = Space::Chunk::world::fromBlock(roundedPos);
if (currChunkPos != chunkPos || blockChunk == nullptr) {
if (glm::ivec3(currChunkPos) != chunkPos || blockChunk == nullptr) {
chunkPos = currChunkPos;
blockChunk = world.getChunk(chunkPos);
}
@ -178,7 +178,7 @@ void Player::updateWireframe() {
}
else if (pointedThing.thing == PointedThing::Thing::BLOCK) {
auto& boxes = defs.defs.blockFromId(pointedThing.target.block.blockId).sBoxes;
float distance = glm::distance(pos, pointedThing.target.block.pos + glm::vec3(0.5));
float distance = glm::distance(pos, glm::vec3(pointedThing.target.block.pos) + glm::vec3(0.5));
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
wireframe.setPos(pointedThing.target.block.pos);

View File

@ -31,7 +31,7 @@ namespace ClientApi {
auto displayObject = luaEntity.get<sol::optional<std::string>>("display_object");
auto displayTexture = luaEntity.get<sol::optional<std::string>>("display_texture");
if (!displayType || !displayObject) throw "Missing display or display_object field.";
if (*displayType == "model" && !displayTexture) throw "Missing model display_texture field.";
if (strncmp(displayType->data(), "model", 5) == 0 && !displayTexture) throw "Missing model display_texture field.";
entityRef->set_display_type(*displayType, *displayObject, displayTexture);

View File

@ -37,7 +37,7 @@ namespace ServerApi {
//TODO: Move these checks to register_entity
if (!displayType) throw "entity '" + *identifier + "' is missing the display property.";
if (!displayObject) throw "entity '" + *identifier + "' is missing the display_object property.";
if (!displayTexture) throw "entity '" + *identifier + "' is missing the display_texture property.";
if (strncmp(displayType->data(), "model", 5) == 0 && !displayTexture) throw "entity '" + *identifier + "' is missing the display_texture property.";
entityRef->set_display_type(*displayType, *displayObject, displayTexture);

View File

@ -0,0 +1,38 @@
//
// Created by aurailus on 2020-01-07.
//
#include "ServerLocalLuaEntity.h"
ServerLocalLuaEntity::ServerLocalLuaEntity(unsigned int id, LocalDefs &defs, const std::string &appearance,
const std::string &arg1, const std::string &arg2) :
id(id),
defs(defs) {
setDisplayType(appearance, arg1, arg2);
}
void ServerLocalLuaEntity::setDisplayType(const std::string &type, const std::string &arg, const std::string &arg2) {
if (strncmp(type.data(), "gameobject", 10) == 0 &&
(strncmp(displayType.data(), "gameobject", 10) || arg2 != displayArg2)) {
ItemDef& def = defs.defs.fromStr(arg2);
if (def.type == ItemDef::Type::BLOCK)
entity->setModel(static_cast<BlockDef&>(def).entityModel);
else if (def.type == ItemDef::Type::CRAFTITEM)
entity->setModel(static_cast<CraftItemDef&>(def).entityModel);
}
else if (strncmp(type.data(), "model", 5) == 0 && !arg2.empty() &&
(strncmp(displayType.data(), "model", 5) || arg != displayArg1 || arg != displayArg2)) {
auto model = std::make_shared<Model>();
model->fromSerialized(defs.models.models[arg], {defs.textures[arg2]});
entity->setModel(model);
}
else return;
displayType = type;
displayArg1 = arg;
displayArg2 = arg2;
}

View File

@ -0,0 +1,24 @@
//
// Created by aurailus on 2020-01-07.
//
#pragma once
#include <string>
#include "../../../def/LocalDefs.h"
#include "../../../game/entity/Entity.h"
class ServerLocalLuaEntity {
public:
ServerLocalLuaEntity(unsigned int id, LocalDefs& defs, const std::string& appearance, const std::string& arg1, const std::string& arg2);
void setDisplayType(const std::string& type, const std::string& arg, const std::string& arg2);
LocalDefs& defs;
std::unique_ptr<Entity> entity = std::make_unique<Entity>();
unsigned int id;
std::string displayType {};
std::string displayArg1 {};
std::string displayArg2 {};
};

View File

@ -110,17 +110,20 @@ void Server::handlePlayerPacket(ServerClient &client, Packet& p) {
case PacketType::BLOCK_SET: {
Deserializer d(p.data);
glm::vec3 pos = d.read<glm::vec3>();
glm::ivec3 pos = d.read<glm::ivec3>();
unsigned int block = d.read<unsigned int>();
unsigned int worldBlock = (block == DefinitionAtlas::AIR ? world.getBlock(pos) : 0);
world.setBlock(pos, block);
if (block == DefinitionAtlas::AIR) {
auto def = defs.defs.blockFromId(world.getBlock(pos));
auto def = defs.defs.blockFromId(worldBlock);
if (def.callbacks.count(Callback::BREAK)) {
def.callbacks[Callback::BREAK](defs.luaApi.vecToTable(pos));
}
} else {
}
else {
auto def = defs.defs.blockFromId(block);
if (def.callbacks.count(Callback::PLACE)) {
def.callbacks[Callback::PLACE](defs.luaApi.vecToTable(pos));

View File

@ -35,6 +35,6 @@ private:
glm::vec3 pos {};
float angle = 0;
std::unordered_map<glm::vec3, unsigned long long, Vec::compareFunc> mapBlockIntegrity {};
std::unordered_map<glm::vec3, unsigned long long, Vec::vec3> mapBlockIntegrity {};
};

View File

@ -53,8 +53,8 @@ bool ServerEntity::checkAndResetDirty() {
return dirty;
}
void ServerEntity::fillPacket(Packet &p) {
p.data = Serializer()
Packet ServerEntity::createPacket(bool reliable) {
return std::move(Serializer()
.append(id)
.append(position)
.append(visualOffset)
@ -63,5 +63,5 @@ void ServerEntity::fillPacket(Packet &p) {
.append(displayMode)
.append(displayArgument1)
.append(displayArgument2)
.data;
.packet(PacketType::ENTITY_INFO, reliable));
}

View File

@ -28,7 +28,7 @@ public:
void setAppearance(std::string displayMode, std::string displayArgument1, std::string displayArgument2);
bool checkAndResetDirty();
void fillPacket(Packet &p);
Packet createPacket(bool reliable = true);
protected:
unsigned int id = 0;
@ -41,6 +41,6 @@ protected:
std::string displayArgument1 = "";
std::string displayArgument2 = "";
bool dirty = false;
bool dirty = true;
};

View File

@ -130,14 +130,9 @@ void ServerWorld::update() {
// TODO: Only send to *nearby clients*.
for (auto& entity : dimension.getLuaEntities()) {
if (entity->entity->checkAndResetDirty()) {
Packet p(PacketType::ENTITY_INFO);
entity->entity->fillPacket(p);
Packet p = entity->entity->createPacket();
for (auto& client : clientList.clients) {
if (client->hasPlayer()) {
p.sendTo(client->getPeer(), PacketChannel::ENTITY);
}
if (client->hasPlayer()) p.sendTo(client->getPeer(), PacketChannel::ENTITY);
}
}
}

View File

@ -40,7 +40,7 @@ private:
WorldGenStream* genStream = nullptr;
std::unordered_set<glm::vec3, Vec::compareFunc> generateQueueMap;
std::unordered_set<glm::vec3, Vec::vec3> generateQueueMap;
std::vector<glm::vec3> generateQueueList;
unsigned int seed;

View File

@ -56,7 +56,7 @@ private:
MapGen gen;
std::vector<glm::vec3> queuedTasks;
std::unordered_set<glm::vec3, Vec::compareFunc> queuedMap;
std::unordered_set<glm::vec3, Vec::vec3> queuedMap;
};
#pragma clang diagnostic pop

View File

@ -23,35 +23,36 @@ namespace Space {
// Private helper methods
namespace {
inline glm::vec3 localFromGlobal(const glm::vec3 &pos, int size) {
auto round = glm::floor(pos);
inline glm::ivec3 localFromGlobal(const glm::ivec3 &pos, int size) {
return glm::vec3 {
(round.x < 0) ? size - 1 + static_cast<int>(round.x + 1) % size : static_cast<int>(round.x) % size,
(round.y < 0) ? size - 1 + static_cast<int>(round.y + 1) % size : static_cast<int>(round.y) % size,
(round.z < 0) ? size - 1 + static_cast<int>(round.z + 1) % size : static_cast<int>(round.z) % size
(pos.x < 0) ? size - 1 + static_cast<int>(pos.x + 1) % size : static_cast<int>(pos.x) % size,
(pos.y < 0) ? size - 1 + static_cast<int>(pos.y + 1) % size : static_cast<int>(pos.y) % size,
(pos.z < 0) ? size - 1 + static_cast<int>(pos.z + 1) % size : static_cast<int>(pos.z) % size
};
}
inline glm::vec3 sectionFromGlobal(glm::vec3 pos, int size) {
auto round = glm::floor(pos);
return {std::floor(round.x / size), std::floor(round.y / size), std::floor(round.z / size)};
inline glm::ivec3 sectionFromGlobal(glm::ivec3 pos, int size) {
return {
std::floor(static_cast<float>(pos.x) / size),
std::floor(static_cast<float>(pos.y) / size),
std::floor(static_cast<float>(pos.z) / size)};
}
}
namespace Region {
namespace world {
// Get a Region world position from a MapBlock's world position.
static inline glm::vec3 fromMapBlock(const glm::vec3& mapBlock) {
static inline glm::ivec3 fromMapBlock(const glm::ivec3& mapBlock) {
return sectionFromGlobal(mapBlock, REGION_SIZE);
}
// Get a Region world position from a Chunk's world position.
static inline glm::vec3 fromChunk(const glm::vec3 &chunk) {
static inline glm::ivec3 fromChunk(const glm::ivec3 &chunk) {
return sectionFromGlobal(chunk, REGION_CHUNK_LENGTH);
}
// Get a Region world position from a Block's world position.
static inline glm::vec3 fromBlock(const glm::vec3 &chunk) {
static inline glm::ivec3 fromBlock(const glm::ivec3 &chunk) {
return sectionFromGlobal(chunk, REGION_BLOCK_LENGTH);
}
}
@ -60,26 +61,26 @@ namespace Space {
namespace MapBlock {
namespace relative {
// Get a MapBlock's relative position in its Region from its world position.
static inline glm::vec3 toRegion(const glm::vec3& pos) {
static inline glm::ivec3 toRegion(const glm::ivec3& pos) {
return localFromGlobal(pos, MAPBLOCK_SIZE);
}
}
namespace world {
// Get a MapBlock world position from a Chunk's world position.
static inline glm::vec3 fromChunk(const glm::vec3 &chunk) {
static inline glm::ivec3 fromChunk(const glm::ivec3 &chunk) {
return sectionFromGlobal(chunk, MAPBLOCK_SIZE);
}
// Get a MapBlock world position from a Block's world position.
static inline glm::vec3 fromBlock(const glm::vec3 &vec) {
static inline glm::ivec3 fromBlock(const glm::ivec3 &vec) {
return sectionFromGlobal(vec, MAPBLOCK_BLOCK_LENGTH);
}
}
// Get the index of a MapBlock within its Region from its local or world position.
static inline unsigned int index(const glm::vec3& vec) {
glm::vec3 local = MapBlock::relative::toRegion(vec);
static inline unsigned int index(const glm::ivec3& vec) {
glm::ivec3 local = MapBlock::relative::toRegion(vec);
unsigned int ind = static_cast<unsigned int>(local.x + REGION_SIZE * (local.y + REGION_SIZE * local.z));
return ind;
}
@ -88,26 +89,26 @@ namespace Space {
namespace Chunk {
namespace relative {
// Get a Chunk's relative position in its MapBlock from its world position.
static inline glm::vec3 toMapBlock(const glm::vec3& pos) {
static inline glm::ivec3 toMapBlock(const glm::ivec3& pos) {
return localFromGlobal(pos, MAPBLOCK_CHUNK_LENGTH);
}
// Get a Chunk's relative position in its Region from its world position.
static inline glm::vec3 toRegion(const glm::vec3& pos) {
static inline glm::ivec3 toRegion(const glm::ivec3& pos) {
return localFromGlobal(pos, REGION_CHUNK_LENGTH);
}
}
namespace world {
// Get a Chunk world position from a Block's world position.
static inline glm::vec3 fromBlock(const glm::vec3& pos) {
static inline glm::ivec3 fromBlock(const glm::ivec3& pos) {
return sectionFromGlobal(pos, CHUNK_BLOCK_LENGTH);
}
}
// Get the index of a Chunk within its MapBlock from its local or world position.
static inline unsigned int index(const glm::vec3& vec) {
glm::vec3 local = Chunk::relative::toMapBlock(vec);
static inline unsigned int index(const glm::ivec3& vec) {
glm::ivec3 local = Chunk::relative::toMapBlock(vec);
return static_cast<unsigned int>(local.x + MAPBLOCK_SIZE * (local.y + MAPBLOCK_SIZE * local.z));
}
}
@ -115,24 +116,24 @@ namespace Space {
namespace Block {
namespace relative {
// Get a Block's relative position to its Chunk from its world position.
static inline glm::vec3 toChunk(const glm::vec3& pos) {
static inline glm::ivec3 toChunk(const glm::ivec3& pos) {
return localFromGlobal(pos, CHUNK_BLOCK_LENGTH);
}
// Get a Block's relative position to its MapBlock from its world position.
static inline glm::vec3 toMapBlock(const glm::vec3& pos) {
static inline glm::ivec3 toMapBlock(const glm::ivec3& pos) {
return localFromGlobal(pos, MAPBLOCK_BLOCK_LENGTH);
}
// Get a Block's relative position in its Region from its world position.
static inline glm::vec3 toRegion(const glm::vec3& pos) {
static inline glm::ivec3 toRegion(const glm::ivec3& pos) {
return localFromGlobal(pos, REGION_BLOCK_LENGTH);
}
}
// Get the index of a Block within its Chunk from its local or world position.
static inline unsigned int index(const glm::vec3& vec) {
glm::vec3 local = Block::relative::toChunk(vec);
static inline unsigned int index(const glm::ivec3& vec) {
glm::ivec3 local = Block::relative::toChunk(vec);
return static_cast<unsigned int>(local.x + CHUNK_SIZE * (local.y + CHUNK_SIZE * local.z));
}
}

View File

@ -11,12 +11,18 @@
#include "Space.h"
namespace Vec {
struct compareFunc {
struct vec3 {
size_t operator()(const glm::vec3& k)const {
return std::hash<float>()(k.x) ^ std::hash<float>()(k.y) ^ std::hash<float>()(k.z);
}
};
struct ivec3 {
size_t operator()(const glm::ivec3& k)const {
return std::hash<int>()(k.x) ^ std::hash<int>()(k.y) ^ std::hash<int>()(k.z);
}
};
const static std::array<glm::ivec3, 6> cardinalVectors = {
glm::ivec3 {1, 0, 0}, glm::ivec3 {-1, 0, 0},
glm::ivec3 {0, 1, 0}, glm::ivec3 {0, -1, 0},

View File

@ -7,7 +7,7 @@
#include "Serializer.h"
#include "Deserializer.h"
Packet::Packet(PacketType type) : type(type) {}
Packet::Packet(PacketType type, bool reliable) : type(type), reliable(reliable) {}
Packet::Packet(ENetPacket *packet) {
std::string packetData(packet->data, packet->data + packet->dataLength);
@ -19,7 +19,7 @@ Packet::Packet(ENetPacket *packet) {
ENetPacket* Packet::toENetPacket() {
std::string serialized = Serializer().append(static_cast<unsigned int>(type)).data + data;
ENetPacket* enet = enet_packet_create(serialized.data(), serialized.length() + 1, ENET_PACKET_FLAG_RELIABLE);
ENetPacket* enet = enet_packet_create(serialized.data(), serialized.length() + 1, (reliable ? ENET_PACKET_FLAG_RELIABLE : 0));
return enet;
}

View File

@ -17,7 +17,7 @@
class Packet {
public:
Packet() = default;
explicit Packet(PacketType type);
explicit Packet(PacketType type, bool reliable = true);
explicit Packet(ENetPacket* packet);
ENetPacket* toENetPacket();
@ -28,5 +28,6 @@ public:
PacketType type = PacketType::UNDEFINED;
std::string data;
bool reliable;
};

View File

@ -17,8 +17,8 @@ public:
template <typename T> inline Serializer& append(const T& elem) {};
Packet packet(PacketType p) {
Packet packet(p);
Packet packet(PacketType p, bool reliable = true) {
Packet packet(p, reliable);
packet.data = data;
return std::move(packet);
};

View File

@ -4,17 +4,17 @@
#include "Dimension.h"
std::shared_ptr<Region> Dimension::getRegion(glm::vec3 regionPosition) {
std::shared_ptr<Region> Dimension::getRegion(glm::ivec3 regionPosition) {
return regions[regionPosition];
}
std::shared_ptr<MapBlock> Dimension::getMapBlock(glm::vec3 mapBlockPosition) {
std::shared_ptr<MapBlock> Dimension::getMapBlock(glm::ivec3 mapBlockPosition) {
auto region = getRegion(Space::Region::world::fromMapBlock(mapBlockPosition));
if (region == nullptr) return nullptr;
return (*region)[Space::MapBlock::index(mapBlockPosition)];
}
std::shared_ptr<BlockChunk> Dimension::getChunk(glm::vec3 chunkPosition) {
std::shared_ptr<BlockChunk> Dimension::getChunk(glm::ivec3 chunkPosition) {
auto mapBlock = getMapBlock(Space::MapBlock::world::fromChunk(chunkPosition));
if (mapBlock == nullptr) return nullptr;
return (*mapBlock)[Space::Chunk::index(chunkPosition)];
@ -25,13 +25,13 @@ void Dimension::setChunk(std::shared_ptr<BlockChunk> chunk) {
(*mapBlock).set(Space::Chunk::index(chunk->pos), chunk);
}
unsigned int Dimension::getBlock(glm::vec3 pos) {
unsigned int Dimension::getBlock(glm::ivec3 pos) {
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
if (chunk != nullptr) return chunk->getBlock(Space::Chunk::relative::toMapBlock(pos));
if (chunk != nullptr) return chunk->getBlock(Space::Block::relative::toChunk(pos));
return 0;
}
bool Dimension::setBlock(glm::vec3 pos, uint block) {
bool Dimension::setBlock(glm::ivec3 pos, uint block) {
auto chunk = getChunk(Space::Chunk::world::fromBlock(pos));
if (chunk == nullptr) return false;
@ -39,13 +39,13 @@ bool Dimension::setBlock(glm::vec3 pos, uint block) {
return true;
}
std::shared_ptr<Region> Dimension::getOrCreateRegion(glm::vec3 pos) {
std::shared_ptr<Region> Dimension::getOrCreateRegion(glm::ivec3 pos) {
if (regions[pos]) return regions[pos];
regions[pos] = std::make_shared<Region>(pos);
return regions[pos];
}
std::shared_ptr<MapBlock> Dimension::getOrCreateMapBlock(glm::vec3 mapBlockPosition) {
std::shared_ptr<MapBlock> Dimension::getOrCreateMapBlock(glm::ivec3 mapBlockPosition) {
auto region = getOrCreateRegion(Space::Region::world::fromMapBlock(mapBlockPosition));
unsigned int index = Space::MapBlock::index(mapBlockPosition);

View File

@ -14,20 +14,20 @@ class Dimension {
public:
Dimension() = default;
std::shared_ptr<Region> getRegion(glm::vec3 regionPosition);
std::shared_ptr<MapBlock> getMapBlock(glm::vec3 mapBlockPosition);
std::shared_ptr<BlockChunk> getChunk(glm::vec3 chunkPosition);
std::shared_ptr<Region> getRegion(glm::ivec3 regionPosition);
std::shared_ptr<MapBlock> getMapBlock(glm::ivec3 mapBlockPosition);
std::shared_ptr<BlockChunk> getChunk(glm::ivec3 chunkPosition);
virtual void setChunk(std::shared_ptr<BlockChunk> chunk);
unsigned int getBlock(glm::vec3 pos);
virtual bool setBlock(glm::vec3 pos, unsigned int block);
unsigned int getBlock(glm::ivec3 pos);
virtual bool setBlock(glm::ivec3 pos, unsigned int block);
protected:
typedef std::unordered_map<glm::vec3, std::shared_ptr<Region>, Vec::compareFunc> block_region_map;
typedef std::unordered_map<glm::ivec3, std::shared_ptr<Region>, Vec::ivec3> block_region_map;
block_region_map regions;
private:
inline std::shared_ptr<Region> getOrCreateRegion(glm::vec3 pos);
inline std::shared_ptr<MapBlock> getOrCreateMapBlock(glm::vec3 mapBlockPosition);
inline std::shared_ptr<Region> getOrCreateRegion(glm::ivec3 pos);
inline std::shared_ptr<MapBlock> getOrCreateMapBlock(glm::ivec3 mapBlockPosition);
};

View File

@ -4,13 +4,14 @@
#include "LocalDimension.h"
LocalDimension::LocalDimension(LocalDefs &defs) : meshGenStream(std::make_unique<MeshGenStream>(defs, *this)) {}
LocalDimension::LocalDimension(LocalDefs &defs) : defs(defs), meshGenStream(std::make_unique<MeshGenStream>(defs, *this)) {}
void LocalDimension::update(double delta, glm::vec3 playerPos) {
finishMeshes();
queueMeshes();
for (auto& entities : luaEntities) entities->entity->update(delta);
for (auto& entities : localEntities) entities->entity->update(delta);
for (auto& entities : serverEntities) entities->entity->update(delta);
for (auto& playerEnt : playerEntities) playerEnt.update(delta);
auto chunkPosOfPlayer = Space::Chunk::world::fromBlock(playerPos);
@ -82,7 +83,8 @@ int LocalDimension::renderChunks(Renderer &renderer) {
}
void LocalDimension::renderEntities(Renderer &renderer) {
for (auto& entity : luaEntities) entity->entity->draw(renderer);
for (auto& entity : localEntities) entity->entity->draw(renderer);
for (auto& entity : serverEntities) entity->entity->draw(renderer);
for (auto& entity : playerEntities) entity.draw(renderer);
}
@ -97,7 +99,7 @@ void LocalDimension::setMeshChunk(std::shared_ptr<MeshChunk> meshChunk) {
renderRefs.emplace(meshChunk->getPos(), --renderElems.end());
}
void LocalDimension::removeMeshChunk(const glm::vec3& pos) {
void LocalDimension::removeMeshChunk(const glm::ivec3& pos) {
if (!renderRefs.count(pos)) return;
auto refIter = renderRefs.at(pos);
@ -108,16 +110,16 @@ void LocalDimension::removeMeshChunk(const glm::vec3& pos) {
}
void LocalDimension::addLocalEntity(std::shared_ptr<LocalLuaEntity> &entity) {
luaEntities.push_back(entity);
luaEntityRefs.emplace(entity->id, --luaEntities.end());
localEntities.push_back(entity);
localEntityRefs.emplace(entity->id, --localEntities.end());
}
void LocalDimension::removeLocalEntity(std::shared_ptr<LocalLuaEntity> &entity) {
if (!luaEntityRefs.count(entity->id)) return;
auto refIter = luaEntityRefs.at(entity->id);
if (!localEntityRefs.count(entity->id)) return;
auto refIter = localEntityRefs.at(entity->id);
luaEntities.erase(refIter);
luaEntityRefs.erase(entity->id);
localEntities.erase(refIter);
localEntityRefs.erase(entity->id);
}
void LocalDimension::handleServerEntity(const Packet& p) {
@ -128,15 +130,37 @@ void LocalDimension::handleServerEntity(const Packet& p) {
auto visualOffset = d.read<glm::vec3>();
auto angle = d.read<float>();
auto scale = d.read<float>();
auto displayMode = d.read<std::string>();
auto displayArg1 = d.read<std::string>();
auto displayArg2 = d.read<std::string>();
//TODO: Finish this function
if (serverEntityRefs.count(id)) {
auto& luaEntity = *serverEntityRefs.at(id)->get();
auto& entity = *luaEntity.entity;
entity.interpPos(position);
entity.interpVisualOffset(visualOffset);
entity.interpAngle(angle);
entity.interpScale(scale);
luaEntity.setDisplayType(displayMode, displayArg1, displayArg2);
}
else {
auto entity = std::make_shared<ServerLocalLuaEntity>(id, defs, displayMode, displayArg1, displayArg2);
entity->entity->setPos(position);
entity->entity->setVisualOffset(visualOffset);
entity->entity->setAngle(angle);
entity->entity->setScale(scale);
serverEntities.push_back(entity);
serverEntityRefs.emplace(id, --serverEntities.end());
}
}
int LocalDimension::getMeshChunkCount() {
return static_cast<int>(renderElems.size());
}
bool LocalDimension::setBlock(glm::vec3 pos, unsigned int block) {
bool LocalDimension::setBlock(glm::ivec3 pos, unsigned int block) {
bool exists = Dimension::setBlock(pos, block);
if (!exists) return false;

View File

@ -6,13 +6,15 @@
#include <unordered_map>
#include <glm/vec3.hpp>
#include "Dimension.h"
#include "region/Region.h"
#include "../util/Vec.h"
#include "../game/scene/world/graph/MeshChunk.h"
#include "../game/scene/world/MeshGenStream.h"
#include "../game/scene/world/graph/MeshChunk.h"
#include "../lua/api/type/LocalLuaEntity.h"
#include "../lua/api/type/ServerLocalLuaEntity.h"
#include "../game/entity/world/PlayerEntity.h"
#include "Dimension.h"
class LocalDimension : public Dimension {
public:
@ -20,10 +22,10 @@ public:
void update(double delta, glm::vec3 playerPos);
void setChunk(std::shared_ptr<BlockChunk> chunk) override;
bool setBlock(glm::vec3 pos, unsigned int block) override;
bool setBlock(glm::ivec3 pos, unsigned int block) override;
void setMeshChunk(std::shared_ptr<MeshChunk> chunk);
void removeMeshChunk(const glm::vec3& pos);
void removeMeshChunk(const glm::ivec3& pos);
void addLocalEntity(std::shared_ptr<LocalLuaEntity>& entity);
void removeLocalEntity(std::shared_ptr<LocalLuaEntity>& entity);
@ -38,7 +40,8 @@ public:
std::vector<PlayerEntity> playerEntities;
private:
typedef std::list<sptr<ChunkRenderElem>>::iterator chunk_ref;
typedef std::list<sptr<LocalLuaEntity>>::iterator luaent_ref;
typedef std::list<sptr<LocalLuaEntity>>::iterator local_ent_ref;
typedef std::list<sptr<ServerLocalLuaEntity>>::iterator server_ent_ref;
void finishMeshes();
void queueMeshes();
@ -46,13 +49,18 @@ private:
void attemptMeshChunk(const sptr<BlockChunk>& chunk, bool updateAdjacents = true);
bool getAdjacentExists(glm::vec3 pos, bool updateAdjacents);
LocalDefs& defs;
uptr<MeshGenStream> meshGenStream = nullptr;
std::vector<glm::vec3> pendingMesh {};
std::unordered_map<uint, luaent_ref> luaEntityRefs {};
std::list<std::shared_ptr<LocalLuaEntity>> luaEntities {};
std::unordered_map<uint, local_ent_ref> localEntityRefs {};
std::list<std::shared_ptr<LocalLuaEntity>> localEntities {};
std::unordered_map<glm::vec3, chunk_ref, Vec::compareFunc> renderRefs {};
std::unordered_map<uint, server_ent_ref> serverEntityRefs {};
std::list<std::shared_ptr<ServerLocalLuaEntity>> serverEntities {};
std::unordered_map<glm::vec3, chunk_ref, Vec::vec3> renderRefs {};
std::list<std::shared_ptr<ChunkRenderElem>> renderElems {};
};

View File

@ -4,7 +4,7 @@
#include "ServerDimension.h"
bool ServerDimension::setBlock(glm::vec3 pos, unsigned int block) {
bool ServerDimension::setBlock(glm::ivec3 pos, unsigned int block) {
bool manip = Dimension::setBlock(pos, block);
if (!manip) return false;
glm::vec3 mb = Space::MapBlock::world::fromBlock(pos);
@ -31,7 +31,7 @@ void ServerDimension::removeLuaEntity(std::shared_ptr<ServerLuaEntity> &entity)
luaEntityRefs.erase(entity->id);
}
unsigned long long ServerDimension::getMapBlockIntegrity(glm::vec3 mapBlock) {
unsigned long long ServerDimension::getMapBlockIntegrity(glm::ivec3 mapBlock) {
if (mapBlockIntegrity.count(mapBlock)) return mapBlockIntegrity[mapBlock];
return 0;
}

View File

@ -12,12 +12,12 @@ public:
ServerDimension() = default;
void setChunk(std::shared_ptr<BlockChunk> chunk) override;
bool setBlock(glm::vec3 pos, unsigned int block) override;
bool setBlock(glm::ivec3 pos, unsigned int block) override;
void addLuaEntity(std::shared_ptr<ServerLuaEntity>& entity);
void removeLuaEntity(std::shared_ptr<ServerLuaEntity>& entity);
unsigned long long getMapBlockIntegrity(glm::vec3 mapBlock);
unsigned long long getMapBlockIntegrity(glm::ivec3 mapBlock);
std::list<std::shared_ptr<ServerLuaEntity>>& getLuaEntities();
private:
typedef std::list<sptr<ServerLuaEntity>>::iterator luaent_ref;
@ -25,6 +25,6 @@ private:
std::unordered_map<uint, luaent_ref> luaEntityRefs {};
std::list<std::shared_ptr<ServerLuaEntity>> luaEntities {};
std::unordered_map<glm::vec3, unsigned long long, Vec::compareFunc> mapBlockIntegrity {};
std::unordered_map<glm::ivec3, unsigned long long, Vec::ivec3> mapBlockIntegrity {};
};

View File

@ -17,7 +17,7 @@ public:
struct PointedBlock {
unsigned int blockId;
glm::vec3 pos;
glm::ivec3 pos;
Dir face;
};

View File

@ -4,7 +4,7 @@
#include "MapBlock.h"
MapBlock::MapBlock(glm::vec3 pos) :
MapBlock::MapBlock(glm::ivec3 pos) :
pos(pos) {
for (int i = 0; i < 64; i++) {

View File

@ -12,11 +12,11 @@
class MapBlock {
public:
MapBlock(glm::vec3 pos);
MapBlock(glm::ivec3 pos);
std::shared_ptr<BlockChunk> operator[](int index);
void set(int index, std::shared_ptr<BlockChunk> chunk);
private:
glm::vec3 pos {};
glm::ivec3 pos {};
std::array<std::shared_ptr<BlockChunk>, 64> blockChunks;
};

View File

@ -4,7 +4,7 @@
#include "Region.h"
Region::Region(glm::vec3 pos) :
Region::Region(glm::ivec3 pos) :
pos(pos) {
for (int i = 0; i < 64; i++) {

View File

@ -11,11 +11,11 @@
class Region {
public:
Region(glm::vec3 pos);
Region(glm::ivec3 pos);
std::shared_ptr<MapBlock> operator[](int index);
void set(int index, std::shared_ptr<MapBlock> block);
private:
glm::vec3 pos {};
glm::ivec3 pos {};
std::array<std::shared_ptr<MapBlock>, 64> mapBlocks {};
};

View File

@ -19,7 +19,7 @@ zepha.register_block("zeus:default:grass", {
pick = 2
},
drop = "zeus:default:dirt",
on_break_client = function(pos)
on_break = function(pos)
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:grass"].drop});
end

View File

@ -33,6 +33,8 @@ zepha.register_entity("zeus:default:dropped_item", {
self.object:int_yaw(self.object.yaw + self.speed)
if self.speed > 4 then self.speed = self.speed * 0.92 end
print(collides(self.object))
if not self.scooping then
if (not collides(self.object)) then
self.velocityY = math.min(self.velocityY + 0.5, 8)
@ -58,7 +60,7 @@ zepha.register_entity("zeus:default:dropped_item", {
self.tick = self.tick + delta
if self.tick > 0.15 then
self:check_collect()
-- self:check_collect()
self.tick = 0
end
end,
@ -69,21 +71,21 @@ zepha.register_entity("zeus:default:dropped_item", {
speed = self.speed
}
end,
check_collect = function(self)
local diff = vector.abs(vector.subtract(zepha.player.pos, self.object.pos))
local distance = math.sqrt(diff.x ^ 2 + diff.y ^ 2 + diff.z ^ 2)
if distance < 2 then
self.object:int_pos(vector.add(zepha.player.pos, v{0, 1.10, 0}))
self.object:int_scale(0.5)
if not self.scooping then
zepha.delay(function()
self.delete = true
zepha.player:get_inventory():get_list("main"):add_stack({self.item, 1})
end, 2/20)
self.scooping = true
end
end
end
-- check_collect = function(self)
-- local diff = vector.abs(vector.subtract(zepha.player.pos, self.object.pos))
-- local distance = math.sqrt(diff.x ^ 2 + diff.y ^ 2 + diff.z ^ 2)
--
-- if distance < 2 then
-- self.object:int_pos(vector.add(zepha.player.pos, v{0, 1.10, 0}))
-- self.object:int_scale(0.5)
--
-- if not self.scooping then
-- zepha.delay(function()
-- self.delete = true
-- zepha.player:get_inventory():get_list("main"):add_stack({self.item, 1})
-- end, 2/20)
-- self.scooping = true
-- end
-- end
-- end
})