Synchronize block interaction callbacks, wieldlists, etc. Breaking broke
parent
ad029752ef
commit
38b75c212b
|
@ -1,4 +1,5 @@
|
||||||
runfile(_PATH .. "models/init")
|
runfile(_PATH .. "models/init")
|
||||||
|
runfile(_PATH .. "player_interact")
|
||||||
runfile(_PATH .. "inventory")
|
runfile(_PATH .. "inventory")
|
||||||
runfile(_PATH .. "tools")
|
runfile(_PATH .. "tools")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
-- zepha.block_interact_or_place(player: Player , target: Target [, stack: ItemStack]): ItemStack, Vector | nil
|
||||||
|
-- Calls zepha.block_interact if the targeted block can be interacted with, returns the passed in stack or wield stack and nil.
|
||||||
|
-- Otherwise, calls zepha.block_place and returned the function's returned values.
|
||||||
|
function zepha.block_interact_or_place(player, target, stack)
|
||||||
|
local stack = stack or player:get_wield_stack()
|
||||||
|
local target_block = zepha.get_block(target.pos)
|
||||||
|
local target_def = zepha.registered_blocks[target_block]
|
||||||
|
local stack_def = zepha.registered_blocks[stack and stack.name or nil]
|
||||||
|
|
||||||
|
if target_def and (target_def.on_interact or target_def.on_interact_client) then
|
||||||
|
-- Trigger an interaction if the targeted block has one.
|
||||||
|
zepha.block_interact(player, target)
|
||||||
|
return stack, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return if stack isn't a block.
|
||||||
|
if stack == nil or stack_def == nil then return stack, nil end
|
||||||
|
|
||||||
|
-- Place a block using the passed in stack.
|
||||||
|
return zepha.block_place(player, target, stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- zepha.block_interact(player: Player, target: Target): nil
|
||||||
|
-- Interacts with the targeted block. Returns true if the block has an on_interact or
|
||||||
|
-- on_interact_client callback, returns false otherwise.
|
||||||
|
function zepha.block_interact(player, target)
|
||||||
|
local block = zepha.get_block(target.pos)
|
||||||
|
local def = zepha.registered_blocks[block]
|
||||||
|
|
||||||
|
local cb = zepha.server and "on_interact" or "on_interact_client"
|
||||||
|
if type(def[cb]) == "function" then def[cb](target.pos, player) end
|
||||||
|
zepha.trigger(cb, target.pos, player)
|
||||||
|
|
||||||
|
return def.on_interact or def.on_interact_client
|
||||||
|
end
|
||||||
|
|
||||||
|
-- zepha.block_place(player: Player, target: Target [, stack: ItemStack]): ItemStack, Vector | nil
|
||||||
|
-- Attempts to place `stack` or the wield stack in the world, on success returning the
|
||||||
|
-- wield stack with one count removed, and the placed position, or on failure returning the
|
||||||
|
-- original stack and nil.
|
||||||
|
function zepha.block_place(player, target, stack)
|
||||||
|
local stack = stack or player:get_wield_stack()
|
||||||
|
local stack_def = zepha.registered_blocks[stack and stack.name or nil]
|
||||||
|
if stack == nil or stack_def == nil then return stack, nil end
|
||||||
|
|
||||||
|
zepha.set_block(target.pos_above, stack.name)
|
||||||
|
|
||||||
|
stack.count = stack.count - 1
|
||||||
|
return stack, target.pos_above
|
||||||
|
end
|
||||||
|
|
||||||
|
function zepha.block_hit(player, target)
|
||||||
|
local block = zepha.get_block(target.pos)
|
||||||
|
local def = zepha.registered_blocks[block]
|
||||||
|
|
||||||
|
-- Don't do anything, return a small timeout to avoid spamming the function.
|
||||||
|
if not def then return 0, 0.1 end
|
||||||
|
|
||||||
|
local damage, timeout = zepha.get_hit_impact(player, block)
|
||||||
|
zepha.block_damage_add(target.pos, damage)
|
||||||
|
|
||||||
|
return damage, timeout
|
||||||
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
set(ZEPHA_SRC
|
add_library(Zepha_Core
|
||||||
def/DefinitionAtlas.cpp
|
def/DefinitionAtlas.cpp
|
||||||
def/DefinitionAtlas.h
|
def/DefinitionAtlas.h
|
||||||
def/gen/BiomeAtlas.cpp
|
def/gen/BiomeAtlas.cpp
|
||||||
|
@ -200,8 +200,7 @@ set(ZEPHA_SRC
|
||||||
lua/LuaMod.h
|
lua/LuaMod.h
|
||||||
lua/LuaParser.cpp
|
lua/LuaParser.cpp
|
||||||
lua/LuaParser.h
|
lua/LuaParser.h
|
||||||
lua/modules/BaseModule.cpp
|
lua/modules/BaseModule.h
|
||||||
lua/modules/BaseModule.h
|
|
||||||
lua/modules/Block.cpp
|
lua/modules/Block.cpp
|
||||||
lua/modules/Block.h
|
lua/modules/Block.h
|
||||||
lua/modules/create_structure.h
|
lua/modules/create_structure.h
|
||||||
|
@ -321,9 +320,7 @@ set(ZEPHA_SRC
|
||||||
world/fs/FileManipulator.h
|
world/fs/FileManipulator.h
|
||||||
world/LocalDimension.cpp
|
world/LocalDimension.cpp
|
||||||
world/LocalDimension.h
|
world/LocalDimension.h
|
||||||
world/PointedThing.h
|
world/Target.h
|
||||||
world/ServerDimension.cpp
|
world/ServerDimension.cpp
|
||||||
world/ServerDimension.h
|
world/ServerDimension.h
|
||||||
)
|
lua/usertype/Target.cpp lua/usertype/Target.h lua/usertype/BaseUsertype.h lua/usertype/SubgameUsertype.h world/Target.cpp)
|
||||||
|
|
||||||
add_library (Zepha_Core ${ZEPHA_SRC})
|
|
|
@ -58,6 +58,12 @@ void BlockCrackEntity::addDamage(double damage) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlockCrackEntity::setDamage(double damage) {
|
||||||
|
double diff = damage - (this->damage + damagePending);
|
||||||
|
std::cout << diff << ", " << this->damage << ", " << damagePending << std::endl;
|
||||||
|
addDamage(diff);
|
||||||
|
}
|
||||||
|
|
||||||
void BlockCrackEntity::addFaces(unsigned int &indOffset, std::vector<EntityVertex> &vertices, std::vector<unsigned int> &indices, std::vector<MeshPart> &meshParts) {
|
void BlockCrackEntity::addFaces(unsigned int &indOffset, std::vector<EntityVertex> &vertices, std::vector<unsigned int> &indices, std::vector<MeshPart> &meshParts) {
|
||||||
for (const MeshPart& mp : meshParts) {
|
for (const MeshPart& mp : meshParts) {
|
||||||
glm::vec4 uv;
|
glm::vec4 uv;
|
||||||
|
@ -81,4 +87,4 @@ void BlockCrackEntity::addFaces(unsigned int &indOffset, std::vector<EntityVerte
|
||||||
|
|
||||||
indOffset += mp.vertices.size();
|
indOffset += mp.vertices.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ public:
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
void addDamage(double damage);
|
void addDamage(double damage);
|
||||||
|
void setDamage(double damage);
|
||||||
|
|
||||||
int maxHealth = 0;
|
int maxHealth = 0;
|
||||||
double damage = 0;
|
double damage = 0;
|
||||||
|
|
|
@ -138,21 +138,19 @@ void DebugGui::update(Player& player, LocalWorld& world, LocalSubgame& game, dou
|
||||||
str << "Texture Slots: " << game.textures.textureSlotsUsed << " / " << game.textures.maxTextureSlots
|
str << "Texture Slots: " << game.textures.textureSlotsUsed << " / " << game.textures.maxTextureSlots
|
||||||
<< " (" << round(game.textures.textureSlotsUsed / static_cast<float>(game.textures.maxTextureSlots) * 100) << "%)" << std::endl << std::endl;
|
<< " (" << round(game.textures.textureSlotsUsed / static_cast<float>(game.textures.maxTextureSlots) * 100) << "%)" << std::endl << std::endl;
|
||||||
|
|
||||||
PointedThing thing = player.getPointedThing();
|
Target thing = player.getPointedThing();
|
||||||
if (thing.thing == PointedThing::Thing::BLOCK) {
|
if (thing.type == Target::Type::BLOCK) {
|
||||||
EVec faceDir = thing.target.block.face;
|
|
||||||
|
|
||||||
std::string face =
|
std::string face =
|
||||||
faceDir == EVec::TOP ? "TOP" :
|
thing.face == EVec::TOP ? "TOP" :
|
||||||
faceDir == EVec::BOTTOM ? "BOTTOM" :
|
thing.face == EVec::BOTTOM ? "BOTTOM" :
|
||||||
faceDir == EVec::LEFT ? "LEFT" :
|
thing.face == EVec::LEFT ? "LEFT" :
|
||||||
faceDir == EVec::RIGHT ? "RIGHT" :
|
thing.face == EVec::RIGHT ? "RIGHT" :
|
||||||
faceDir == EVec::FRONT ? "FRONT" :
|
thing.face == EVec::FRONT ? "FRONT" :
|
||||||
faceDir == EVec::BACK ? "BACK" :
|
thing.face == EVec::BACK ? "BACK" :
|
||||||
"NONE" ;
|
"NONE" ;
|
||||||
|
|
||||||
str << "Pointing At: " << game.defs->blockFromId(thing.target.block.blockId).identifier << std::endl;
|
str << "Pointing At: " << game.defs->blockFromId(world.getBlock(thing.pos)).identifier << std::endl;
|
||||||
str << "Pointed Position: " << vecToString(thing.target.block.pos) << std::endl;
|
str << "Pointed Position: " << vecToString(thing.pos) << std::endl;
|
||||||
str << "Pointed Face: " << face << std::endl;
|
str << "Pointed Face: " << face << std::endl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -163,12 +161,12 @@ void DebugGui::update(Player& player, LocalWorld& world, LocalSubgame& game, dou
|
||||||
}
|
}
|
||||||
|
|
||||||
{ //Crosshair Text
|
{ //Crosshair Text
|
||||||
PointedThing thing = player.getPointedThing();
|
Target target = player.getPointedThing();
|
||||||
|
|
||||||
std::ostringstream crossText;
|
std::ostringstream crossText;
|
||||||
if (thing.thing == PointedThing::Thing::BLOCK) {
|
if (target.type == Target::Type::BLOCK) {
|
||||||
crossText << game.defs->blockFromId(thing.target.block.blockId).name
|
crossText << game.defs->blockFromId(world.getBlock(target.pos)).name
|
||||||
<< " (" << game.defs->blockFromId(thing.target.block.blockId).identifier << ")" << std::endl;
|
<< " (" << game.defs->blockFromId(world.getBlock(target.pos)).identifier << ")" << std::endl;
|
||||||
}
|
}
|
||||||
get<GuiText>("crosshairText")->setText(crossText.str());
|
get<GuiText>("crosshairText")->setText(crossText.str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ GameScene::GameScene(ClientState& state) : Scene(state),
|
||||||
game(state.defs),
|
game(state.defs),
|
||||||
world(game, &net),
|
world(game, &net),
|
||||||
net(state.connection, game, player),
|
net(state.connection, game, player),
|
||||||
player(world, game, state.renderer, refs),
|
player(game, world, state.renderer, refs, net),
|
||||||
debugGui(state.renderer.window.getSize(), game) {
|
debugGui(state.renderer.window.getSize(), game) {
|
||||||
|
|
||||||
namespace ph = std::placeholders;
|
namespace ph = std::placeholders;
|
||||||
|
@ -23,7 +23,7 @@ GameScene::GameScene(ClientState& state) : Scene(state),
|
||||||
r.sendTo(state.connection.getPeer(), PacketChannel::CONNECT);
|
r.sendTo(state.connection.getPeer(), PacketChannel::CONNECT);
|
||||||
|
|
||||||
world.init(&player);
|
world.init(&player);
|
||||||
net .init(&world, std::bind(&LocalInventoryRefs::packetReceived, refs, ph::_1));
|
net .init(&world, Util::bind_this(&refs, &LocalInventoryRefs::packetReceived));
|
||||||
game .init(world, player, state);
|
game .init(world, player, state);
|
||||||
refs .init();
|
refs .init();
|
||||||
|
|
||||||
|
|
|
@ -9,23 +9,24 @@
|
||||||
#include "WorldInterpolationStream.h"
|
#include "WorldInterpolationStream.h"
|
||||||
#include "../../../world/chunk/Chunk.h"
|
#include "../../../world/chunk/Chunk.h"
|
||||||
#include "../../../def/item/BlockDef.h"
|
#include "../../../def/item/BlockDef.h"
|
||||||
#include "../../../def/gen/LocalBiomeAtlas.h"
|
#include "../../../lua/usertype/Target.h"
|
||||||
#include "../../../def/LocalDefinitionAtlas.h"
|
#include "../../../lua/usertype/LuaItemStack.h"
|
||||||
#include "../../../lua/LocalLuaParser.h"
|
#include "../../inventory/LocalInventoryList.h"
|
||||||
#include "../../entity/engine/ParticleEntity.h"
|
#include "../../entity/engine/ParticleEntity.h"
|
||||||
#include "../../entity/engine/BlockCrackEntity.h"
|
#include "../../entity/engine/BlockCrackEntity.h"
|
||||||
#include "../../../lua/usertype/LocalLuaPlayer.h"
|
#include "../../../lua/usertype/LocalLuaPlayer.h"
|
||||||
#include "../../../net/client/ClientNetworkInterpreter.h"
|
#include "../../../net/client/ClientNetworkInterpreter.h"
|
||||||
|
|
||||||
LocalWorld::LocalWorld(LocalSubgame& defs, ClientNetworkInterpreter* server) :
|
LocalWorld::LocalWorld(LocalSubgame& defs, ClientNetworkInterpreter* server) :
|
||||||
defs(defs),
|
World(defs),
|
||||||
net(server),
|
game(defs),
|
||||||
dimension(defs) {}
|
net(server),
|
||||||
|
dimension(defs) {}
|
||||||
|
|
||||||
void LocalWorld::init(Player* player) {
|
void LocalWorld::init(Player* player) {
|
||||||
this->player = player;
|
this->player = player;
|
||||||
delete worldGenStream;
|
delete worldGenStream;
|
||||||
worldGenStream = new WorldInterpolationStream(55, defs);
|
worldGenStream = new WorldInterpolationStream(55, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalWorld::update(double delta) {
|
void LocalWorld::update(double delta) {
|
||||||
|
@ -61,61 +62,49 @@ void LocalWorld::setBlock(glm::ivec3 pos, unsigned int block) {
|
||||||
dimension.setBlock(pos, block);
|
dimension.setBlock(pos, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalWorld::blockPlace(glm::vec3 pos, unsigned int block) {
|
double LocalWorld::setBlockDamage(glm::ivec3 pos, double damage) {
|
||||||
if (block == LocalDefinitionAtlas::AIR) {
|
double totalDamage = World::setBlockDamage(pos, damage);
|
||||||
auto& def = defs.defs->blockFromId(getBlock(pos));
|
|
||||||
if (def.callbacks.count(Callback::BREAK_CLIENT))
|
|
||||||
defs.lua->safe_function(def.callbacks[Callback::BREAK_CLIENT], pos);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto& def = defs.defs->blockFromId(block);
|
|
||||||
if (def.callbacks.count(Callback::PLACE_CLIENT))
|
|
||||||
defs.lua->safe_function(def.callbacks[Callback::PLACE_CLIENT], pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
net->blockPlace(pos, block);
|
|
||||||
dimension.setBlock(pos, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalWorld::blockBreak(glm::vec3 pos) {
|
|
||||||
blockPlace(pos, DefinitionAtlas::AIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalWorld::blockInteract(PointedThing &thing) {
|
|
||||||
auto& def = defs.defs->blockFromId(getBlock(thing.target.block.pos));
|
|
||||||
|
|
||||||
if (def.callbacks.count(Callback::INTERACT_CLIENT))
|
|
||||||
defs.lua->safe_function(def.callbacks[Callback::INTERACT_CLIENT], thing.target.block.pos);
|
|
||||||
|
|
||||||
net->blockInteract(thing.target.block.pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
double LocalWorld::blockHit(PointedThing& thing) {
|
|
||||||
glm::ivec3 pos = thing.target.block.pos;
|
|
||||||
|
|
||||||
auto& blockDef = defs.defs->blockFromId(getBlock(thing.target.block.pos));
|
|
||||||
|
|
||||||
double damage = 0, timeout = 0;
|
|
||||||
sol::tie(damage, timeout) = defs.lua->safe_function(defs.lua->core["get_hit_impact"],
|
|
||||||
defs.lua->core.get<LocalLuaPlayer>("player"), blockDef.identifier);
|
|
||||||
|
|
||||||
if (damage == 0) return timeout;
|
|
||||||
|
|
||||||
BlockCrackEntity* block = nullptr;
|
BlockCrackEntity* block = nullptr;
|
||||||
for (auto test : crackedBlocks) if (glm::ivec3(test->getPos()) == pos) { block = test; break; }
|
if (crackEntities.count(pos)) block = crackEntities[pos];
|
||||||
if (block == nullptr) {
|
else block = new BlockCrackEntity(game.defs->blockFromId(getBlock(pos)), game.textures, pos);
|
||||||
block = new BlockCrackEntity(blockDef, defs.textures, pos);
|
block->setDamage(damage);
|
||||||
crackedBlocks.push_back(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
block->addDamage(damage);
|
|
||||||
block->time = 0;
|
block->time = 0;
|
||||||
|
|
||||||
// auto def = defs.defs.blockFromId(getBlock(pos));
|
return totalDamage;
|
||||||
// for (int i = 0; i < 40 * damage; i++) {
|
}
|
||||||
// auto p = new ParticleEntity(pos, def);
|
|
||||||
// particles.push_back(p);
|
void LocalWorld::blockPlace(Target& target) {
|
||||||
// }
|
std::tuple<sol::optional<LuaItemStack>, sol::optional<glm::vec3>> res = game.lua->safe_function(
|
||||||
|
game.lua->core["block_place"], LocalLuaPlayer(*player), Api::Usertype::Target(target));
|
||||||
|
|
||||||
|
auto stack = std::get<sol::optional<LuaItemStack>>(res);
|
||||||
|
if (stack) player->getWieldList()->setStack(player->getWieldIndex(), ItemStack(*stack, game.getDefs()));
|
||||||
|
net->blockPlace(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalWorld::blockInteract(Target &target) {
|
||||||
|
game.lua->safe_function(game.lua->core["block_interact"],
|
||||||
|
LocalLuaPlayer(*player), Api::Usertype::Target(target));
|
||||||
|
|
||||||
|
net->blockInteract(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalWorld::blockPlaceOrInteract(Target &target) {
|
||||||
|
std::tuple<sol::optional<LuaItemStack>, sol::optional<glm::vec3>> res = game.lua->safe_function(
|
||||||
|
game.lua->core["block_interact_or_place"], LocalLuaPlayer(*player), Api::Usertype::Target(target));
|
||||||
|
|
||||||
|
auto stack = std::get<sol::optional<LuaItemStack>>(res);
|
||||||
|
if (stack) player->getWieldList()->setStack(player->getWieldIndex(), ItemStack(*stack, game.getDefs()));
|
||||||
|
net->blockPlaceOrInteract(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
double LocalWorld::blockHit(Target& target) {
|
||||||
|
double timeout = 0, damage = 0;
|
||||||
|
sol::tie(damage, timeout) = game.lua->safe_function(game.lua->core["block_hit"],
|
||||||
|
LocalLuaPlayer(*player), Api::Usertype::Target(target));
|
||||||
|
|
||||||
|
// net->blockHit(target);
|
||||||
|
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
@ -143,24 +132,26 @@ int LocalWorld::renderChunks(Renderer &renderer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalWorld::renderEntities(Renderer &renderer) {
|
void LocalWorld::renderEntities(Renderer &renderer) {
|
||||||
for (auto block : crackedBlocks) block->draw(renderer);
|
for (auto& block : crackEntities) block.second->draw(renderer);
|
||||||
for (auto &p : particles) p->draw(renderer);
|
for (auto& particle : particles) particle->draw(renderer);
|
||||||
|
|
||||||
dimension.renderEntities(renderer);
|
dimension.renderEntities(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalWorld::updateBlockDamages(double delta) {
|
void LocalWorld::updateBlockDamages(double delta) {
|
||||||
auto it = crackedBlocks.cbegin();
|
auto it = crackEntities.cbegin();
|
||||||
while (it != crackedBlocks.cend()) {
|
while (it != crackEntities.cend()) {
|
||||||
bool deleteMe = false;
|
bool deleteMe = false;
|
||||||
|
|
||||||
auto curr = it++;
|
auto curr = it++;
|
||||||
auto block = *curr;
|
auto block = curr->second;
|
||||||
|
|
||||||
block->time += delta;
|
block->time += delta;
|
||||||
|
|
||||||
if (block->damage >= block->maxHealth) {
|
if (block->damage >= block->maxHealth) {
|
||||||
blockBreak(block->getPos());
|
//Todo: Lua callback~
|
||||||
|
setBlock(block->getPos(), DefinitionAtlas::AIR);
|
||||||
|
setBlockDamage(block->getPos(), 0);
|
||||||
deleteMe = true;
|
deleteMe = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,8 +166,8 @@ void LocalWorld::updateBlockDamages(double delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteMe) {
|
if (deleteMe) {
|
||||||
delete *curr;
|
delete block;
|
||||||
it = crackedBlocks.erase(curr);
|
it = crackEntities.erase(curr);
|
||||||
}
|
}
|
||||||
else block->update();
|
else block->update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,15 @@
|
||||||
|
|
||||||
#include "../../../world/LocalDimension.h"
|
#include "../../../world/LocalDimension.h"
|
||||||
|
|
||||||
|
class Target;
|
||||||
|
class Player;
|
||||||
|
class Renderer;
|
||||||
|
class ItemStack;
|
||||||
|
class LocalSubgame;
|
||||||
|
class ParticleEntity;
|
||||||
|
class BlockCrackEntity;
|
||||||
class ClientNetworkInterpreter;
|
class ClientNetworkInterpreter;
|
||||||
class WorldInterpolationStream;
|
class WorldInterpolationStream;
|
||||||
class BlockCrackEntity;
|
|
||||||
class ParticleEntity;
|
|
||||||
class PointedThing;
|
|
||||||
class LocalSubgame;
|
|
||||||
class Renderer;
|
|
||||||
class Player;
|
|
||||||
|
|
||||||
class LocalWorld : public World {
|
class LocalWorld : public World {
|
||||||
public:
|
public:
|
||||||
|
@ -24,17 +25,20 @@ public:
|
||||||
void init(Player* player);
|
void init(Player* player);
|
||||||
void update(double delta) override;
|
void update(double delta) override;
|
||||||
|
|
||||||
|
void createDimension(std::string identifier);
|
||||||
|
|
||||||
void loadWorldPacket(std::unique_ptr<PacketView> p);
|
void loadWorldPacket(std::unique_ptr<PacketView> p);
|
||||||
void commitChunk(std::shared_ptr<Chunk> chunk);
|
void commitChunk(std::shared_ptr<Chunk> chunk);
|
||||||
|
|
||||||
unsigned int getBlock(glm::ivec3 pos) override;
|
unsigned int getBlock(glm::ivec3 pos) override;
|
||||||
void setBlock(glm::ivec3 pos, unsigned int block) override;
|
void setBlock(glm::ivec3 pos, unsigned int block) override;
|
||||||
|
|
||||||
void blockPlace(glm::vec3 pos, unsigned int block);
|
double setBlockDamage(glm::ivec3 pos, double damage) override;
|
||||||
void blockBreak(glm::vec3 pos);
|
|
||||||
|
|
||||||
void blockInteract(PointedThing& thing);
|
void blockPlace(Target& target);
|
||||||
double blockHit(PointedThing& thing);
|
void blockPlaceOrInteract(Target& target);
|
||||||
|
void blockInteract(Target& target);
|
||||||
|
double blockHit(Target& target);
|
||||||
|
|
||||||
unsigned short getBiome(glm::vec3 pos);
|
unsigned short getBiome(glm::vec3 pos);
|
||||||
std::shared_ptr<Chunk> getChunk(glm::ivec3 pos);
|
std::shared_ptr<Chunk> getChunk(glm::ivec3 pos);
|
||||||
|
@ -43,7 +47,7 @@ public:
|
||||||
int renderChunks(Renderer &render);
|
int renderChunks(Renderer &render);
|
||||||
void renderEntities(Renderer &renderer);
|
void renderEntities(Renderer &renderer);
|
||||||
|
|
||||||
LocalSubgame& defs;
|
LocalSubgame& game;
|
||||||
LocalDimension dimension;
|
LocalDimension dimension;
|
||||||
|
|
||||||
int mapBlocksInterpolated = 0;
|
int mapBlocksInterpolated = 0;
|
||||||
|
@ -52,7 +56,7 @@ private:
|
||||||
void finishChunks();
|
void finishChunks();
|
||||||
void updateBlockDamages(double delta);
|
void updateBlockDamages(double delta);
|
||||||
|
|
||||||
std::vector<BlockCrackEntity*> crackedBlocks;
|
std::unordered_map<glm::ivec3, BlockCrackEntity*, Vec::ivec3> crackEntities;
|
||||||
std::vector<ParticleEntity*> particles;
|
std::vector<ParticleEntity*> particles;
|
||||||
|
|
||||||
Player* player = nullptr;
|
Player* player = nullptr;
|
||||||
|
|
|
@ -8,23 +8,23 @@
|
||||||
#include "../../../util/Ray.h"
|
#include "../../../util/Ray.h"
|
||||||
#include "../../graph/Renderer.h"
|
#include "../../graph/Renderer.h"
|
||||||
#include "../../../def/ItemDef.h"
|
#include "../../../def/ItemDef.h"
|
||||||
#include "../../../net/Serializer.h"
|
|
||||||
#include "../../../net/Deserializer.h"
|
#include "../../../net/Deserializer.h"
|
||||||
#include "../../../def/item/BlockDef.h"
|
#include "../../../def/item/BlockDef.h"
|
||||||
#include "../../../world/chunk/Chunk.h"
|
#include "../../../world/chunk/Chunk.h"
|
||||||
#include "../../inventory/LocalInventory.h"
|
#include "../../inventory/LocalInventory.h"
|
||||||
#include "../../../def/LocalDefinitionAtlas.h"
|
|
||||||
#include "../../inventory/LocalInventoryList.h"
|
#include "../../inventory/LocalInventoryList.h"
|
||||||
#include "../../../net/client/NetPlayerField.h"
|
#include "../../../net/client/NetPlayerField.h"
|
||||||
|
#include "../../../net/client/ClientNetworkInterpreter.h"
|
||||||
|
|
||||||
Player::Player(LocalWorld& world, LocalSubgame& defs, Renderer& renderer, LocalInventoryRefs& refs) :
|
Player::Player(LocalSubgame &game, LocalWorld &world, Renderer &renderer, LocalInventoryRefs &refs, ClientNetworkInterpreter& net) :
|
||||||
Collidable(world, defs, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
|
Collidable(world, game, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
|
||||||
|
|
||||||
|
net(net),
|
||||||
refs(refs),
|
refs(refs),
|
||||||
game(defs),
|
game(game),
|
||||||
renderer(renderer),
|
renderer(renderer),
|
||||||
wireframe({}, 0.01, {1, 1, 1}),
|
wireframe({}, 0.01, {1, 1, 1}),
|
||||||
gameGui(refs, renderer.window.getSize(), defs, renderer) {
|
gameGui(refs, renderer.window.getSize(), game, renderer) {
|
||||||
handItemModel.parent = &handModel;
|
handItemModel.parent = &handModel;
|
||||||
|
|
||||||
renderer.window.addResizeCallback("player", [&](glm::ivec2 win) {
|
renderer.window.addResizeCallback("player", [&](glm::ivec2 win) {
|
||||||
|
@ -186,27 +186,25 @@ void Player::findPointedThing(Input &input) {
|
||||||
auto face = sBox.intersects(rayEnd, roundedPos);
|
auto face = sBox.intersects(rayEnd, roundedPos);
|
||||||
|
|
||||||
if (face != EVec::NONE) {
|
if (face != EVec::NONE) {
|
||||||
pointedThing.thing = PointedThing::Thing::BLOCK;
|
target = Target(roundedPos, face);
|
||||||
pointedThing.target.block = { blockID, roundedPos, face };
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pointedThing.thing = PointedThing::Thing::NOTHING;
|
target = Target {};
|
||||||
pointedThing.target.nothing = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::updateWireframe() {
|
void Player::updateWireframe() {
|
||||||
if (!gameGui.isVisible()) {
|
if (!gameGui.isVisible()) {
|
||||||
wireframe.setVisible(false);
|
wireframe.setVisible(false);
|
||||||
}
|
}
|
||||||
else if (pointedThing.thing == PointedThing::Thing::BLOCK) {
|
else if (target.type == Target::Type::BLOCK) {
|
||||||
auto& boxes = game.defs->blockFromId(pointedThing.target.block.blockId).sBoxes;
|
auto& boxes = game.defs->blockFromId(world.getBlock(target.pos)).sBoxes;
|
||||||
float distance = glm::distance(pos, glm::vec3(pointedThing.target.block.pos) + glm::vec3(0.5));
|
float distance = glm::distance(pos, target.pos + glm::vec3(0.5));
|
||||||
|
|
||||||
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
|
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
|
||||||
wireframe.setPos(pointedThing.target.block.pos);
|
wireframe.setPos(target.pos);
|
||||||
wireframe.setVisible(true);
|
wireframe.setVisible(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -215,23 +213,12 @@ void Player::updateWireframe() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::interact(Input& input, double delta) {
|
void Player::interact(Input& input, double delta) {
|
||||||
if (pointedThing.thing == PointedThing::Thing::BLOCK) {
|
if (target.type == Target::Type::BLOCK) {
|
||||||
if (input.mouseDown(GLFW_MOUSE_BUTTON_LEFT) && breakTime == 0) {
|
if (input.mouseDown(GLFW_MOUSE_BUTTON_LEFT) && breakTime == 0) {
|
||||||
breakInterval = world.blockHit(pointedThing);
|
breakInterval = world.blockHit(target);
|
||||||
breakTime += delta;
|
breakTime += delta;
|
||||||
}
|
}
|
||||||
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) {
|
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) world.blockPlaceOrInteract(target);
|
||||||
auto& target = game.defs->blockFromId(world.getBlock(pointedThing.target.block.pos));
|
|
||||||
|
|
||||||
if (target.hasInteraction()) world.blockInteract(pointedThing);
|
|
||||||
else if (wieldItem > DefinitionAtlas::AIR && game.defs->fromId(wieldItem).type == ItemDef::Type::BLOCK) {
|
|
||||||
world.blockPlace(pointedThing.target.block.pos + SelectionBox::faceToOffset(pointedThing.target.block.face), wieldItem);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//TODO: Item interactions.
|
|
||||||
// world.itemUse(pointedThing, activeItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (breakTime > 0) breakTime += delta;
|
if (breakTime > 0) breakTime += delta;
|
||||||
|
@ -249,7 +236,7 @@ glm::vec3 Player::getPos() {
|
||||||
void Player::setPos(glm::vec3 pos, bool assert) {
|
void Player::setPos(glm::vec3 pos, bool assert) {
|
||||||
this->pos = pos;
|
this->pos = pos;
|
||||||
this->renderer.camera.setPos({pos.x, pos.y + EYE_HEIGHT, pos.z});
|
this->renderer.camera.setPos({pos.x, pos.y + EYE_HEIGHT, pos.z});
|
||||||
if (assert) assertField(NetPlayerField::POSITION, pos);
|
if (assert) net.assertPlayerField(NetPlayerField::POSITION, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Player::getVel() {
|
glm::vec3 Player::getVel() {
|
||||||
|
@ -258,7 +245,7 @@ glm::vec3 Player::getVel() {
|
||||||
|
|
||||||
void Player::setVel(glm::vec3 vel, bool assert) {
|
void Player::setVel(glm::vec3 vel, bool assert) {
|
||||||
this->vel = vel;
|
this->vel = vel;
|
||||||
if (assert) assertField(NetPlayerField::VELOCITY, vel);
|
if (assert) net.assertPlayerField(NetPlayerField::VELOCITY, vel);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Player::getYaw() {
|
float Player::getYaw() {
|
||||||
|
@ -267,7 +254,7 @@ float Player::getYaw() {
|
||||||
|
|
||||||
void Player::setYaw(float yaw, bool assert) {
|
void Player::setYaw(float yaw, bool assert) {
|
||||||
this->yaw = yaw;
|
this->yaw = yaw;
|
||||||
if (assert) assertField(NetPlayerField::YAW, yaw);
|
if (assert) net.assertPlayerField(NetPlayerField::YAW, yaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Player::getPitch() {
|
float Player::getPitch() {
|
||||||
|
@ -276,7 +263,7 @@ float Player::getPitch() {
|
||||||
|
|
||||||
void Player::setPitch(float pitch, bool assert) {
|
void Player::setPitch(float pitch, bool assert) {
|
||||||
this->pitch = pitch;
|
this->pitch = pitch;
|
||||||
if (assert) assertField(NetPlayerField::PITCH, pitch);
|
if (assert) net.assertPlayerField(NetPlayerField::PITCH, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::isFlying() {
|
bool Player::isFlying() {
|
||||||
|
@ -285,11 +272,11 @@ bool Player::isFlying() {
|
||||||
|
|
||||||
void Player::setFlying(bool flying, bool assert) {
|
void Player::setFlying(bool flying, bool assert) {
|
||||||
this->flying = flying;
|
this->flying = flying;
|
||||||
if (assert) assertField(NetPlayerField::FLYING, flying);
|
if (assert) net.assertPlayerField(NetPlayerField::FLYING, flying);
|
||||||
}
|
}
|
||||||
|
|
||||||
PointedThing& Player::getPointedThing() {
|
Target& Player::getPointedThing() {
|
||||||
return pointedThing;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalInventory& Player::getInventory() {
|
LocalInventory& Player::getInventory() {
|
||||||
|
@ -313,7 +300,7 @@ void Player::setWieldList(const std::string& list, bool assert) {
|
||||||
refs.setWieldList(list);
|
refs.setWieldList(list);
|
||||||
setWieldIndex(wieldIndex);
|
setWieldIndex(wieldIndex);
|
||||||
updateWieldAndHandItems();
|
updateWieldAndHandItems();
|
||||||
if (assert) assertField(NetPlayerField::WIELD_INV, list);
|
if (assert) net.assertPlayerField(NetPlayerField::WIELD_INV, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short Player::getWieldIndex() {
|
unsigned short Player::getWieldIndex() {
|
||||||
|
@ -324,7 +311,7 @@ void Player::setWieldIndex(unsigned short index, bool assert) {
|
||||||
auto wieldList = refs.getWieldList();
|
auto wieldList = refs.getWieldList();
|
||||||
wieldIndex = index % std::max((wieldList ? wieldList->getLength() : 1), 1);
|
wieldIndex = index % std::max((wieldList ? wieldList->getLength() : 1), 1);
|
||||||
updateWieldAndHandItems();
|
updateWieldAndHandItems();
|
||||||
if (assert) assertField(NetPlayerField::WIELD_INV, static_cast<unsigned short>(index));
|
if (assert) net.assertPlayerField(NetPlayerField::WIELD_INDEX, static_cast<unsigned short>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -386,13 +373,6 @@ void Player::updateWieldAndHandItems() {
|
||||||
handItemModel.setModel(model);
|
handItemModel.setModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Player::assertField(NetPlayerField field, T data) {
|
|
||||||
std::cout << "attempt to assert field" << std::endl;
|
|
||||||
// Serializer().append(static_cast<unsigned int>(field)).append<T>(data)
|
|
||||||
// .packet(PacketType::THIS_PLAYER_INFO).sendTo(peer, PacketChannel::PLAYER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::handleAssertion(Deserializer &d) {
|
void Player::handleAssertion(Deserializer &d) {
|
||||||
while (!d.atEnd()) {
|
while (!d.atEnd()) {
|
||||||
switch (static_cast<NetPlayerField>(d.read<unsigned int>())) {
|
switch (static_cast<NetPlayerField>(d.read<unsigned int>())) {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "../../graph/drawable/Drawable.h"
|
#include "../../graph/drawable/Drawable.h"
|
||||||
|
|
||||||
#include "../../hud/GameGui.h"
|
#include "../../hud/GameGui.h"
|
||||||
#include "../../../world/PointedThing.h"
|
#include "../../../world/Target.h"
|
||||||
#include "../../entity/engine/WireframeEntity.h"
|
#include "../../entity/engine/WireframeEntity.h"
|
||||||
|
|
||||||
class Input;
|
class Input;
|
||||||
|
@ -22,8 +22,8 @@ class Player : Collidable, public Drawable {
|
||||||
public:
|
public:
|
||||||
enum class PlayerControl {
|
enum class PlayerControl {
|
||||||
FORWARD, LEFT, BACKWARD, RIGHT,
|
FORWARD, LEFT, BACKWARD, RIGHT,
|
||||||
JUMP, MOD1, MOD2
|
JUMP, MOD1, MOD2 };
|
||||||
};
|
|
||||||
static constexpr float MOUSE_SENSITIVITY = 0.1f;
|
static constexpr float MOUSE_SENSITIVITY = 0.1f;
|
||||||
static constexpr float LOOK_DISTANCE = 6.5f;
|
static constexpr float LOOK_DISTANCE = 6.5f;
|
||||||
static constexpr float LOOK_PRECISION = 0.01f;
|
static constexpr float LOOK_PRECISION = 0.01f;
|
||||||
|
@ -31,7 +31,7 @@ public:
|
||||||
static constexpr float BASE_MOVE_SPEED = 4.3f;
|
static constexpr float BASE_MOVE_SPEED = 4.3f;
|
||||||
static constexpr float JUMP_VEL = 0.14f;
|
static constexpr float JUMP_VEL = 0.14f;
|
||||||
|
|
||||||
Player(LocalWorld& world, LocalSubgame& defs, Renderer& renderer, LocalInventoryRefs& refs);
|
Player(LocalSubgame &game, LocalWorld &world, Renderer &renderer, LocalInventoryRefs &refs, ClientNetworkInterpreter& net);
|
||||||
void update(Input &input, double delta, glm::vec2 mouseDelta);
|
void update(Input &input, double delta, glm::vec2 mouseDelta);
|
||||||
~Player();
|
~Player();
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public:
|
||||||
void setHud(std::shared_ptr<LuaGuiElement> hud);
|
void setHud(std::shared_ptr<LuaGuiElement> hud);
|
||||||
std::shared_ptr<LuaGuiElement> getHud();
|
std::shared_ptr<LuaGuiElement> getHud();
|
||||||
|
|
||||||
PointedThing& getPointedThing();
|
Target& getPointedThing();
|
||||||
void setHudVisible(bool hudVisible);
|
void setHudVisible(bool hudVisible);
|
||||||
|
|
||||||
void draw(Renderer& renderer) override;
|
void draw(Renderer& renderer) override;
|
||||||
|
@ -90,9 +90,9 @@ private:
|
||||||
void interact(Input& input, double delta);
|
void interact(Input& input, double delta);
|
||||||
|
|
||||||
void updateWieldAndHandItems();
|
void updateWieldAndHandItems();
|
||||||
template <typename T> void assertField(NetPlayerField field, T data);
|
|
||||||
|
|
||||||
LocalSubgame& game;
|
LocalSubgame& game;
|
||||||
|
ClientNetworkInterpreter& net;
|
||||||
Renderer& renderer;
|
Renderer& renderer;
|
||||||
|
|
||||||
GameGui gameGui;
|
GameGui gameGui;
|
||||||
|
@ -112,6 +112,6 @@ private:
|
||||||
|
|
||||||
double breakTime = 0;
|
double breakTime = 0;
|
||||||
double breakInterval = 0;
|
double breakInterval = 0;
|
||||||
PointedThing pointedThing;
|
Target target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,30 @@
|
||||||
// Created by aurailus on 2020-01-09.
|
// Created by aurailus on 2020-01-09.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
|
||||||
|
#include "../../../def/Subgame.h"
|
||||||
|
#include "../../../def/item/BlockDef.h"
|
||||||
|
#include "../../../def/DefinitionAtlas.h"
|
||||||
|
|
||||||
|
World::World(Subgame &game) : game(game) {}
|
||||||
|
|
||||||
|
double World::getBlockDamage(glm::ivec3 pos) const {
|
||||||
|
return blockDamages.count(pos) ? blockDamages.at(pos).curr : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double World::setBlockDamage(glm::ivec3 pos, double damage) {
|
||||||
|
if (blockDamages.count(pos)) blockDamages[pos].curr = damage;
|
||||||
|
else blockDamages.insert({pos, Damage { damage, static_cast<double>(game.getDefs().blockFromId(getBlock(pos)).health)}});
|
||||||
|
return getBlockDamage(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::updateBlockDamages() {
|
||||||
|
for (auto it = blockDamages.begin(); it != blockDamages.end(); ) {
|
||||||
|
if (it->second.curr > it->second.max) {
|
||||||
|
setBlock(it->first, DefinitionAtlas::AIR);
|
||||||
|
it = blockDamages.erase(it);
|
||||||
|
}
|
||||||
|
else it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,14 +4,37 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "../../../util/Vec.h"
|
||||||
|
|
||||||
|
class Subgame;
|
||||||
|
class Dimension;
|
||||||
|
|
||||||
class World {
|
class World {
|
||||||
public:
|
public:
|
||||||
explicit World() = default;
|
explicit World(Subgame& game);
|
||||||
|
|
||||||
virtual void update(double delta) = 0;
|
virtual void update(double delta) = 0;
|
||||||
|
|
||||||
|
// virtual Dimension& getDimension() = 0;
|
||||||
|
|
||||||
virtual unsigned int getBlock(glm::ivec3 pos) = 0;
|
virtual unsigned int getBlock(glm::ivec3 pos) = 0;
|
||||||
virtual void setBlock(glm::ivec3 pos, unsigned int block) = 0;
|
virtual void setBlock(glm::ivec3 pos, unsigned int block) = 0;
|
||||||
|
|
||||||
|
virtual double getBlockDamage(glm::ivec3 pos) const;
|
||||||
|
virtual double setBlockDamage(glm::ivec3 pos, double damage);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateBlockDamages();
|
||||||
|
|
||||||
|
std::map<std::string, std::shared_ptr<Dimension>> dimensions;
|
||||||
|
|
||||||
|
struct Damage { double curr, max; };
|
||||||
|
std::unordered_map<glm::ivec3, Damage, Vec::ivec3> blockDamages;
|
||||||
|
|
||||||
|
Subgame& game;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,15 +19,14 @@
|
||||||
#include "usertype/cLuaEntity.h"
|
#include "usertype/cLuaEntity.h"
|
||||||
#include "usertype/cInventoryRef.h"
|
#include "usertype/cInventoryRef.h"
|
||||||
#include "usertype/cAnimationManager.h"
|
#include "usertype/cAnimationManager.h"
|
||||||
|
#include "usertype/Target.h"
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
#include "modules/Time.h"
|
#include "modules/Time.h"
|
||||||
#include "modules/Block.h"
|
#include "modules/Block.h"
|
||||||
#include "modules/Entity.h"
|
#include "modules/Entity.h"
|
||||||
#include "modules/Register.h"
|
#include "modules/Register.h"
|
||||||
|
|
||||||
#include "modules/create_structure.h"
|
#include "modules/create_structure.h"
|
||||||
#include "LuaMod.h"
|
|
||||||
|
|
||||||
LocalLuaParser::LocalLuaParser(LocalSubgame& game): LuaParser(game), game(game), keybinds(this) {}
|
LocalLuaParser::LocalLuaParser(LocalSubgame& game): LuaParser(game), game(game), keybinds(this) {}
|
||||||
|
|
||||||
|
@ -68,6 +67,8 @@ void LocalLuaParser::loadApi(LocalSubgame &defs, LocalWorld &world, Player& play
|
||||||
ClientApi::item_stack (lua);
|
ClientApi::item_stack (lua);
|
||||||
ClientApi::gui_element (lua);
|
ClientApi::gui_element (lua);
|
||||||
|
|
||||||
|
Api::Usertype::Target::bind(Api::State::CLIENT, lua, core);
|
||||||
|
|
||||||
core["client"] = true;
|
core["client"] = true;
|
||||||
core["player"] = LocalLuaPlayer(player);
|
core["player"] = LocalLuaPlayer(player);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "usertype/sLuaEntity.h"
|
#include "usertype/sLuaEntity.h"
|
||||||
#include "usertype/sInventoryRef.h"
|
#include "usertype/sInventoryRef.h"
|
||||||
#include "usertype/cItemStack.h"
|
#include "usertype/cItemStack.h"
|
||||||
|
#include "usertype/Target.h"
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
#include "modules/Time.h"
|
#include "modules/Time.h"
|
||||||
|
@ -98,11 +99,13 @@ void ServerLuaParser::loadApi(ServerSubgame &defs, ServerWorld &world) {
|
||||||
ServerApi::inventory (lua);
|
ServerApi::inventory (lua);
|
||||||
ClientApi::item_stack (lua);
|
ClientApi::item_stack (lua);
|
||||||
|
|
||||||
|
Api::Usertype::Target::bind(Api::State::SERVER, lua, core);
|
||||||
|
|
||||||
core["server"] = true;
|
core["server"] = true;
|
||||||
core["players"] = lua.create_table();
|
core["players"] = lua.create_table();
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
modules.emplace_back(std::make_unique<Api::Module::Time>(Api::State::CLIENT, lua, core));
|
modules.emplace_back(std::make_unique<Api::Module::Time>(Api::State::SERVER, lua, core));
|
||||||
modules.emplace_back(std::make_unique<Api::Module::Block>(Api::State::SERVER, core, game, world));
|
modules.emplace_back(std::make_unique<Api::Module::Block>(Api::State::SERVER, core, game, world));
|
||||||
modules.emplace_back(std::make_unique<Api::Module::Entity>(Api::State::SERVER, core, game, world));
|
modules.emplace_back(std::make_unique<Api::Module::Entity>(Api::State::SERVER, core, game, world));
|
||||||
modules.emplace_back(std::make_unique<Api::Module::Register>(Api::State::SERVER, core, game, world));
|
modules.emplace_back(std::make_unique<Api::Module::Register>(Api::State::SERVER, core, game, world));
|
||||||
|
@ -122,7 +125,7 @@ void ServerLuaParser::registerDefs(ServerSubgame &defs) {
|
||||||
RegisterBiomes::server(core, defs);
|
RegisterBiomes::server(core, defs);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::protected_function_result ServerLuaParser::errorCallback(sol::protected_function_result errPfr) {
|
sol::protected_function_result ServerLuaParser::errorCallback(sol::protected_function_result errPfr) const {
|
||||||
sol::error err = errPfr;
|
sol::error err = errPfr;
|
||||||
std::string errString = err.what();
|
std::string errString = err.what();
|
||||||
|
|
||||||
|
|
|
@ -26,15 +26,16 @@ public:
|
||||||
void playerConnected(std::shared_ptr<ServerClient> client);
|
void playerConnected(std::shared_ptr<ServerClient> client);
|
||||||
void playerDisconnected(std::shared_ptr<ServerClient> client);
|
void playerDisconnected(std::shared_ptr<ServerClient> client);
|
||||||
|
|
||||||
template<typename... Args> void safe_function(sol::protected_function f, Args... args) {
|
template<typename... Args> sol::safe_function_result safe_function(sol::protected_function f, Args... args) const {
|
||||||
auto res = f(args...);
|
auto res = f(args...);
|
||||||
if (!res.valid()) errorCallback(res);
|
if (!res.valid()) errorCallback(res);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void loadApi(ServerSubgame& defs, ServerWorld& world);
|
void loadApi(ServerSubgame& defs, ServerWorld& world);
|
||||||
void registerDefs(ServerSubgame &defs);
|
void registerDefs(ServerSubgame &defs);
|
||||||
|
|
||||||
sol::protected_function_result errorCallback(sol::protected_function_result errPfr);
|
sol::protected_function_result errorCallback(sol::protected_function_result errPfr) const;
|
||||||
sol::protected_function_result runFileSandboxed(const std::string& file);
|
sol::protected_function_result runFileSandboxed(const std::string& file);
|
||||||
|
|
||||||
ServerSubgame& game;
|
ServerSubgame& game;
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
//
|
|
||||||
// Created by aurailus on 2020-07-26.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "BaseModule.h"
|
|
||||||
|
|
||||||
Api::Module::BaseModule::BaseModule(Api::State state, sol::state& lua, sol::table& core) :
|
|
||||||
state(state), lua(lua), core(core) {}
|
|
|
@ -12,7 +12,9 @@ namespace Api {
|
||||||
namespace Module {
|
namespace Module {
|
||||||
class BaseModule {
|
class BaseModule {
|
||||||
public:
|
public:
|
||||||
BaseModule(State state, sol::state& lua, sol::table& core);
|
BaseModule(State state, sol::state& lua, sol::table& core) :
|
||||||
|
state(state), lua(lua), core(core) {}
|
||||||
|
|
||||||
virtual void bind() = 0;
|
virtual void bind() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -14,6 +14,10 @@ void Api::Module::Block::bind() {
|
||||||
core.set_function("get_block", Util::bind_this(this, &Block::getBlock));
|
core.set_function("get_block", Util::bind_this(this, &Block::getBlock));
|
||||||
core.set_function("set_block", Util::bind_this(this, &Block::setBlock));
|
core.set_function("set_block", Util::bind_this(this, &Block::setBlock));
|
||||||
core.set_function("remove_block", [&](glm::ivec3 pos) { setBlock(pos, "air"); });
|
core.set_function("remove_block", [&](glm::ivec3 pos) { setBlock(pos, "air"); });
|
||||||
|
|
||||||
|
core.set_function("block_damage_get", Util::bind_this(this, &Block::damageGet));
|
||||||
|
core.set_function("block_damage_set", Util::bind_this(this, &Block::damageSet));
|
||||||
|
core.set_function("block_damage_add", Util::bind_this(this, &Block::damageAdd));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Api::Module::Block::getBlock(glm::ivec3 pos) {
|
std::string Api::Module::Block::getBlock(glm::ivec3 pos) {
|
||||||
|
@ -23,3 +27,15 @@ std::string Api::Module::Block::getBlock(glm::ivec3 pos) {
|
||||||
void Api::Module::Block::setBlock(glm::ivec3 pos, const std::string &identifier) {
|
void Api::Module::Block::setBlock(glm::ivec3 pos, const std::string &identifier) {
|
||||||
world.setBlock(pos, game.getDefs().fromStr(identifier).index);
|
world.setBlock(pos, game.getDefs().fromStr(identifier).index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Api::Module::Block::damageGet(glm::ivec3 pos) {
|
||||||
|
return world.getBlockDamage(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Api::Module::Block::damageSet(glm::ivec3 pos, double damage) {
|
||||||
|
return world.setBlockDamage(pos, damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Api::Module::Block::damageAdd(glm::ivec3 pos, double damage) {
|
||||||
|
return world.setBlockDamage(pos, world.getBlockDamage(pos) + damage);
|
||||||
|
}
|
||||||
|
|
|
@ -17,5 +17,9 @@ namespace Api::Module {
|
||||||
protected:
|
protected:
|
||||||
std::string getBlock(glm::ivec3 pos);
|
std::string getBlock(glm::ivec3 pos);
|
||||||
void setBlock(glm::ivec3 pos, const std::string& identifier);
|
void setBlock(glm::ivec3 pos, const std::string& identifier);
|
||||||
|
|
||||||
|
double damageGet(glm::ivec3 pos);
|
||||||
|
double damageSet(glm::ivec3 pos, double damage);
|
||||||
|
double damageAdd(glm::ivec3 pos, double damage);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 2020-07-27.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
|
#include "../modules/BaseModule.h"
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
namespace Usertype {
|
||||||
|
class BaseUsertype {
|
||||||
|
public:
|
||||||
|
BaseUsertype() = default;
|
||||||
|
static void bind(State state, sol::state& lua, sol::table& core) {};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -89,9 +89,9 @@ sol::object LocalLuaPlayer::get_wield_list(sol::this_state s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalLuaPlayer::set_wield_list(sol::optional<sol::object> list) {
|
void LocalLuaPlayer::set_wield_list(sol::optional<sol::object> list) {
|
||||||
if (!list) player.setWieldList("");
|
if (!list) player.setWieldList("", true);
|
||||||
else if (list->is<std::string>()) player.setWieldList(list->as<std::string>());
|
else if (list->is<std::string>()) player.setWieldList(list->as<std::string>(), true);
|
||||||
else if (list->is<LocalLuaInventoryList>()) player.setWieldList(list->as<LocalLuaInventoryList>().get_name());
|
else if (list->is<LocalLuaInventoryList>()) player.setWieldList(list->as<LocalLuaInventoryList>().get_name(), true);
|
||||||
else throw "Attempted to set wield list to nil.";
|
else throw "Attempted to set wield list to nil.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ unsigned int LocalLuaPlayer::get_wield_index() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalLuaPlayer::set_wield_index(unsigned int index) {
|
void LocalLuaPlayer::set_wield_index(unsigned int index) {
|
||||||
player.setWieldIndex(index - 1);
|
player.setWieldIndex(index - 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object LocalLuaPlayer::get_wield_stack(sol::this_state s) {
|
sol::object LocalLuaPlayer::get_wield_stack(sol::this_state s) {
|
||||||
|
@ -110,7 +110,7 @@ sol::object LocalLuaPlayer::get_wield_stack(sol::this_state s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalLuaPlayer::set_flying(bool shouldFly) {
|
void LocalLuaPlayer::set_flying(bool shouldFly) {
|
||||||
player.setFlying(shouldFly);
|
player.setFlying(shouldFly, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocalLuaPlayer::get_flying() {
|
bool LocalLuaPlayer::get_flying() {
|
||||||
|
|
|
@ -74,8 +74,8 @@ sol::object ServerLuaPlayer::get_hand_list(sol::this_state s) {
|
||||||
|
|
||||||
void ServerLuaPlayer::set_hand_list(sol::object list) {
|
void ServerLuaPlayer::set_hand_list(sol::object list) {
|
||||||
if (!list) player.setHandList(nullptr);
|
if (!list) player.setHandList(nullptr);
|
||||||
else if (list.is<std::string>()) player.setHandList((*player.getInventory())[list.as<std::string>()], true);
|
else if (list.is<std::string>()) player.setHandList(list.as<std::string>(), true);
|
||||||
else if (list.is<ServerLuaInventoryList>()) player.setHandList((*player.getInventory())[list.as<ServerLuaInventoryList>().get_name()], true);
|
else if (list.is<ServerLuaInventoryList>()) player.setHandList(list.as<ServerLuaInventoryList>().get_name(), true);
|
||||||
else throw "Attempted to set hand list to nil.";
|
else throw "Attempted to set hand list to nil.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,9 +92,9 @@ sol::object ServerLuaPlayer::get_wield_list(sol::this_state s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerLuaPlayer::set_wield_list(sol::object list) {
|
void ServerLuaPlayer::set_wield_list(sol::object list) {
|
||||||
if (!list) player.setWieldList(nullptr);
|
if (!list) player.setWieldList(nullptr, true);
|
||||||
else if (list.is<std::string>()) player.setWieldList((*player.getInventory())[list.as<std::string>()], true);
|
else if (list.is<std::string>()) player.setWieldList(list.as<std::string>(), true);
|
||||||
else if (list.is<ServerLuaInventoryList>()) player.setWieldList((*player.getInventory())[list.as<ServerLuaInventoryList>().get_name()], true);
|
else if (list.is<ServerLuaInventoryList>()) player.setWieldList(list.as<ServerLuaInventoryList>().get_name(), true);
|
||||||
else throw "Attempted to set wield list to nil.";
|
else throw "Attempted to set wield list to nil.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 2020-07-27.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BaseUsertype.h"
|
||||||
|
|
||||||
|
class State;
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
namespace Usertype {
|
||||||
|
class SubgameUsertype : public BaseUsertype {
|
||||||
|
public:
|
||||||
|
SubgameUsertype() = default;
|
||||||
|
static void bind(State state, sol::state& lua, sol::table& core) {};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 2020-07-27.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Target.h"
|
||||||
|
|
||||||
|
#include "../Lua.h"
|
||||||
|
|
||||||
|
Api::Usertype::Target::Target(const ::Target &target) :
|
||||||
|
pos(target.pos),
|
||||||
|
type(target.type),
|
||||||
|
pos_above(target.getAbovePos()) {}
|
||||||
|
|
||||||
|
std::string Api::Usertype::Target::getType() {
|
||||||
|
return type == ::Target::Type::BLOCK ? "block" :
|
||||||
|
type == ::Target::Type::ENTITY ? "entity" :
|
||||||
|
"nothing";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Api::Usertype::Target::bind(State, sol::state &lua, sol::table &core) {
|
||||||
|
lua.new_usertype<Target>("Target",
|
||||||
|
"type", sol::property(&Target::getType),
|
||||||
|
|
||||||
|
"pos", sol::readonly(&Target::pos),
|
||||||
|
"pos_above", sol::readonly(&Target::pos_above)
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 2020-07-27.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
|
|
||||||
|
#include "SubgameUsertype.h"
|
||||||
|
#include "../../world/Target.h"
|
||||||
|
|
||||||
|
namespace Api::Usertype {
|
||||||
|
class Target : public SubgameUsertype {
|
||||||
|
public:
|
||||||
|
Target(const ::Target& target);
|
||||||
|
|
||||||
|
std::string getType();
|
||||||
|
|
||||||
|
::Target::Type type;
|
||||||
|
|
||||||
|
glm::ivec3 pos;
|
||||||
|
glm::ivec3 pos_above;
|
||||||
|
|
||||||
|
static void bind(State state, sol::state& lua, sol::table& core);
|
||||||
|
};
|
||||||
|
}
|
|
@ -28,8 +28,11 @@ enum class PacketType {
|
||||||
MAPBLOCK,
|
MAPBLOCK,
|
||||||
|
|
||||||
// Block
|
// Block
|
||||||
BLOCK_SET,
|
BLOCK_PLACE,
|
||||||
BLOCK_INTERACT,
|
BLOCK_INTERACT,
|
||||||
|
BLOCK_PLACE_OR_INTERACT,
|
||||||
|
|
||||||
|
BLOCK_SET,
|
||||||
|
|
||||||
// Entity
|
// Entity
|
||||||
ENTITY_INFO,
|
ENTITY_INFO,
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include "../NetHandler.h"
|
#include "../NetHandler.h"
|
||||||
#include "../../util/Log.h"
|
#include "../../util/Log.h"
|
||||||
#include "NetPlayerField.h"
|
#include "NetPlayerField.h"
|
||||||
#include "ServerConnection.h"
|
|
||||||
#include "../../game/entity/Model.h"
|
#include "../../game/entity/Model.h"
|
||||||
#include "../../game/scene/world/Player.h"
|
#include "../../game/scene/world/Player.h"
|
||||||
#include "../../game/scene/world/LocalWorld.h"
|
#include "../../game/scene/world/LocalWorld.h"
|
||||||
|
@ -128,14 +127,19 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<PacketView> p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientNetworkInterpreter::blockPlace(glm::ivec3 pos, unsigned int block) {
|
void ClientNetworkInterpreter::blockPlace(Target &target) {
|
||||||
Serializer().append(pos).append(block).packet(PacketType::BLOCK_SET)
|
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
||||||
.sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
.packet(PacketType::BLOCK_PLACE).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientNetworkInterpreter::blockInteract(glm::ivec3 pos) {
|
void ClientNetworkInterpreter::blockInteract(Target &target) {
|
||||||
Serializer().append(pos).packet(PacketType::BLOCK_INTERACT)
|
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
||||||
.sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
.packet(PacketType::BLOCK_INTERACT).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientNetworkInterpreter::blockPlaceOrInteract(Target &target) {
|
||||||
|
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
||||||
|
.packet(PacketType::BLOCK_PLACE_OR_INTERACT).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientNetworkInterpreter::invWatch(const std::string& inv, const std::string& list) {
|
void ClientNetworkInterpreter::invWatch(const std::string& inv, const std::string& list) {
|
||||||
|
|
|
@ -8,12 +8,16 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
|
|
||||||
|
#include "../Serializer.h"
|
||||||
|
#include "ServerConnection.h"
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
class Player;
|
class Player;
|
||||||
|
class Target;
|
||||||
class LocalWorld;
|
class LocalWorld;
|
||||||
class LocalSubgame;
|
|
||||||
class PacketView;
|
class PacketView;
|
||||||
class ServerConnection;
|
class LocalSubgame;
|
||||||
|
enum class NetPlayerField;
|
||||||
|
|
||||||
class ClientNetworkInterpreter {
|
class ClientNetworkInterpreter {
|
||||||
public:
|
public:
|
||||||
|
@ -23,14 +27,20 @@ public:
|
||||||
void init(LocalWorld* world, std::function<void(std::unique_ptr<PacketView>)> invCallback);
|
void init(LocalWorld* world, std::function<void(std::unique_ptr<PacketView>)> invCallback);
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
void blockPlace(glm::ivec3 pos, unsigned int block);
|
void blockPlace(Target& target);
|
||||||
void blockInteract(glm::ivec3 pos);
|
void blockInteract(Target& target);
|
||||||
|
void blockPlaceOrInteract(Target& target);
|
||||||
|
|
||||||
void invWatch(const std::string& inv, const std::string& list);
|
void invWatch(const std::string& inv, const std::string& list);
|
||||||
void invUnwatch(const std::string& inv, const std::string& list);
|
void invUnwatch(const std::string& inv, const std::string& list);
|
||||||
void invInteractPrimary(const std::string& inv, const std::string& list, unsigned short ind);
|
void invInteractPrimary(const std::string& inv, const std::string& list, unsigned short ind);
|
||||||
void invInteractSecondary(const std::string& inv, const std::string& list, unsigned short ind);
|
void invInteractSecondary(const std::string& inv, const std::string& list, unsigned short ind);
|
||||||
|
|
||||||
|
template <typename T> void assertPlayerField(NetPlayerField field, T data) {
|
||||||
|
Serializer().append(static_cast<unsigned int>(field)).append<T>(data)
|
||||||
|
.packet(PacketType::THIS_PLAYER_INFO).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
||||||
|
}
|
||||||
|
|
||||||
int recvPackets = 0;
|
int recvPackets = 0;
|
||||||
int serverSideChunkGens = 0;
|
int serverSideChunkGens = 0;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -8,13 +8,10 @@
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
|
|
||||||
#include "../Serializer.h"
|
#include "../Serializer.h"
|
||||||
#include "../PacketView.h"
|
|
||||||
#include "../../util/Log.h"
|
|
||||||
#include "../../util/Timer.h"
|
#include "../../util/Timer.h"
|
||||||
#include "../PacketChannel.h"
|
#include "../PacketChannel.h"
|
||||||
|
#include "../../world/Target.h"
|
||||||
#include "../../def/item/BlockDef.h"
|
#include "../../def/item/BlockDef.h"
|
||||||
#include "../../def/ServerDefinitionAtlas.h"
|
|
||||||
#include "../../lua/ServerLuaParser.h"
|
|
||||||
#include "../../lua/usertype/ServerLuaPlayer.h"
|
#include "../../lua/usertype/ServerLuaPlayer.h"
|
||||||
|
|
||||||
Server::Server(unsigned short port, const std::string& subgame) :
|
Server::Server(unsigned short port, const std::string& subgame) :
|
||||||
|
@ -114,16 +111,20 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
|
||||||
switch (p.type) {
|
switch (p.type) {
|
||||||
default: {
|
default: {
|
||||||
std::cout << Log::err << "Invalid packet type (" << static_cast<int>(p.type) << ") recieved." << Log::endl;
|
std::cout << Log::err << "Invalid packet type (" << static_cast<int>(p.type) << ") recieved." << Log::endl;
|
||||||
break;
|
break; }
|
||||||
}
|
|
||||||
case PacketType::PLAYER_INFO: {
|
case PacketType::PLAYER_INFO: {
|
||||||
client.setPos(p.d.read<glm::vec3>());
|
client.setPos(p.d.read<glm::vec3>());
|
||||||
client.setPitch(p.d.read<float>());
|
client.setPitch(p.d.read<float>());
|
||||||
client.setYaw(p.d.read<float>());
|
client.setYaw(p.d.read<float>());
|
||||||
|
|
||||||
playersUpdated.emplace(client.cid);
|
playersUpdated.emplace(client.cid);
|
||||||
break;
|
break; }
|
||||||
}
|
|
||||||
|
case PacketType::THIS_PLAYER_INFO: {
|
||||||
|
client.handleAssertion(p.d);
|
||||||
|
break; }
|
||||||
|
|
||||||
case PacketType::BLOCK_SET: {
|
case PacketType::BLOCK_SET: {
|
||||||
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
||||||
unsigned int block = p.d.read<unsigned int>();
|
unsigned int block = p.d.read<unsigned int>();
|
||||||
|
@ -155,14 +156,26 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
|
||||||
defs.lua->safe_function(def.callbacks[Callback::AFTER_PLACE], pos, ServerLuaPlayer(client));
|
defs.lua->safe_function(def.callbacks[Callback::AFTER_PLACE], pos, ServerLuaPlayer(client));
|
||||||
defs.lua->safe_function(defs.lua->core["trigger"], "after_place", pos, ServerLuaPlayer(client));
|
defs.lua->safe_function(defs.lua->core["trigger"], "after_place", pos, ServerLuaPlayer(client));
|
||||||
}
|
}
|
||||||
break;
|
break; }
|
||||||
}
|
|
||||||
|
case PacketType::BLOCK_PLACE: {
|
||||||
|
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
||||||
|
auto face = static_cast<EVec>(p.d.read<unsigned short>());
|
||||||
|
world.blockPlace(Target(pos, face), client);
|
||||||
|
break; }
|
||||||
|
|
||||||
case PacketType::BLOCK_INTERACT: {
|
case PacketType::BLOCK_INTERACT: {
|
||||||
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
||||||
auto& def = defs.defs->blockFromId(world.getBlock(pos));
|
auto face = static_cast<EVec>(p.d.read<unsigned short>());
|
||||||
if (def.callbacks.count(Callback::INTERACT)) defs.lua->safe_function(def.callbacks[Callback::INTERACT], pos, ServerLuaPlayer(client));
|
world.blockInteract(Target(pos, face), client);
|
||||||
break;
|
break; }
|
||||||
}
|
|
||||||
|
case PacketType::BLOCK_PLACE_OR_INTERACT: {
|
||||||
|
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
||||||
|
auto face = static_cast<EVec>(p.d.read<unsigned short>());
|
||||||
|
world.blockPlaceOrInteract(Target(pos, face), client);
|
||||||
|
break; }
|
||||||
|
|
||||||
case PacketType::INV_WATCH: {
|
case PacketType::INV_WATCH: {
|
||||||
std::string source = p.d.read<std::string>();
|
std::string source = p.d.read<std::string>();
|
||||||
std::string list = p.d.read<std::string>();
|
std::string list = p.d.read<std::string>();
|
||||||
|
@ -173,8 +186,8 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
|
||||||
bool exists = refs.addWatcher(source, list, client.cid);
|
bool exists = refs.addWatcher(source, list, client.cid);
|
||||||
if (!exists) Serializer().append(source).append(list)
|
if (!exists) Serializer().append(source).append(list)
|
||||||
.packet(PacketType::INV_INVALID).sendTo(client.peer, PacketChannel::INVENTORY);
|
.packet(PacketType::INV_INVALID).sendTo(client.peer, PacketChannel::INVENTORY);
|
||||||
break;
|
break; }
|
||||||
}
|
|
||||||
case PacketType::INV_UNWATCH: {
|
case PacketType::INV_UNWATCH: {
|
||||||
std::string source = p.d.read<std::string>();
|
std::string source = p.d.read<std::string>();
|
||||||
std::string list = p.d.read<std::string>();
|
std::string list = p.d.read<std::string>();
|
||||||
|
@ -189,10 +202,9 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break; }
|
||||||
}
|
|
||||||
case PacketType::INV_INTERACT: {
|
|
||||||
|
|
||||||
|
case PacketType::INV_INTERACT: {
|
||||||
unsigned short type = p.d.read<unsigned short>();
|
unsigned short type = p.d.read<unsigned short>();
|
||||||
|
|
||||||
std::string source = p.d.read<std::string>();
|
std::string source = p.d.read<std::string>();
|
||||||
|
@ -205,8 +217,7 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
|
||||||
if (type == 0) refs.primaryInteract(source, list, ind, client.cid);
|
if (type == 0) refs.primaryInteract(source, list, ind, client.cid);
|
||||||
else refs.secondaryInteract(source, list, ind, client.cid);
|
else refs.secondaryInteract(source, list, ind, client.cid);
|
||||||
|
|
||||||
break;
|
break; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "../../Packet.h"
|
#include "../../Packet.h"
|
||||||
#include "../../Serializer.h"
|
#include "../../Serializer.h"
|
||||||
|
#include "../../Deserializer.h"
|
||||||
#include "../../client/NetPlayerField.h"
|
#include "../../client/NetPlayerField.h"
|
||||||
#include "../../../game/inventory/InventoryRefs.h"
|
#include "../../../game/inventory/InventoryRefs.h"
|
||||||
|
|
||||||
|
@ -77,21 +78,26 @@ std::shared_ptr<Inventory> ServerClient::getInventory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<InventoryList> ServerClient::getHandList() {
|
std::shared_ptr<InventoryList> ServerClient::getHandList() {
|
||||||
return handList;
|
return (*inventory)[handList];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerClient::setHandList(std::shared_ptr<InventoryList> list, bool assert) {
|
void ServerClient::setHandList(const std::string& list, bool assert) {
|
||||||
handList = list;
|
if (list.empty() || !(*inventory)[list]) this->handList = "";
|
||||||
if (assert) assertField(NetPlayerField::HAND_INV, handList ? handList->getName() : "");
|
else this->handList = list;
|
||||||
|
|
||||||
|
if (assert) assertField(NetPlayerField::HAND_INV, this->handList);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<InventoryList> ServerClient::getWieldList() {
|
std::shared_ptr<InventoryList> ServerClient::getWieldList() {
|
||||||
return wieldList;
|
return (*inventory)[wieldList];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerClient::setWieldList(std::shared_ptr<InventoryList> list, bool assert) {
|
void ServerClient::setWieldList(const std::string& list, bool assert) {
|
||||||
wieldList = list;
|
if (list.empty() || !(*inventory)[list]) this->wieldList = "";
|
||||||
if (assert) assertField(NetPlayerField::WIELD_INV, wieldList ? wieldList->getName() : "");
|
else this->wieldList = list;
|
||||||
|
|
||||||
|
if (assert) assertField(NetPlayerField::WIELD_INV, this->wieldList);
|
||||||
|
setWieldIndex(wieldIndex, assert);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short ServerClient::getWieldIndex() {
|
unsigned short ServerClient::getWieldIndex() {
|
||||||
|
@ -99,10 +105,28 @@ unsigned short ServerClient::getWieldIndex() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerClient::setWieldIndex(unsigned short index, bool assert) {
|
void ServerClient::setWieldIndex(unsigned short index, bool assert) {
|
||||||
|
auto wieldList = (*inventory)[this->wieldList];
|
||||||
wieldIndex = index % (wieldList ? wieldList->getLength() : 1);
|
wieldIndex = index % (wieldList ? wieldList->getLength() : 1);
|
||||||
if (assert) assertField(NetPlayerField::WIELD_INDEX, static_cast<unsigned short>(wieldIndex));
|
if (assert) assertField(NetPlayerField::WIELD_INDEX, static_cast<unsigned short>(wieldIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerClient::handleAssertion(Deserializer &d) {
|
||||||
|
while (!d.atEnd()) {
|
||||||
|
switch (static_cast<NetPlayerField>(d.read<unsigned int>())) {
|
||||||
|
case NetPlayerField::POSITION: setPos(d.read<glm::vec3>()); break;
|
||||||
|
case NetPlayerField::VELOCITY: setVel(d.read<glm::vec3>()); break;
|
||||||
|
case NetPlayerField::PITCH: setPitch(d.read<float>()); break;
|
||||||
|
case NetPlayerField::YAW: setYaw(d.read<float>()); break;
|
||||||
|
|
||||||
|
case NetPlayerField::FLYING: setFlying(d.read<bool>()); break;
|
||||||
|
|
||||||
|
case NetPlayerField::HAND_INV: setHandList(d.read<std::string>()); break;
|
||||||
|
case NetPlayerField::WIELD_INV: setWieldList(d.read<std::string>()); break;
|
||||||
|
case NetPlayerField::WIELD_INDEX: setWieldIndex(d.read<unsigned short>()); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//void ServerClient::setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity) {
|
//void ServerClient::setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity) {
|
||||||
// mapBlockIntegrity[pos] = integrity;
|
// mapBlockIntegrity[pos] = integrity;
|
||||||
//}
|
//}
|
||||||
|
@ -116,4 +140,4 @@ template <typename T>
|
||||||
void ServerClient::assertField(NetPlayerField field, T data) {
|
void ServerClient::assertField(NetPlayerField field, T data) {
|
||||||
Serializer().append(static_cast<unsigned int>(field)).append<T>(data)
|
Serializer().append(static_cast<unsigned int>(field)).append<T>(data)
|
||||||
.packet(PacketType::THIS_PLAYER_INFO).sendTo(peer, PacketChannel::INTERACT);
|
.packet(PacketType::THIS_PLAYER_INFO).sendTo(peer, PacketChannel::INTERACT);
|
||||||
}
|
}
|
|
@ -14,6 +14,7 @@
|
||||||
#include "../../../game/inventory/ServerInventoryList.h"
|
#include "../../../game/inventory/ServerInventoryList.h"
|
||||||
|
|
||||||
enum class NetPlayerField;
|
enum class NetPlayerField;
|
||||||
|
class Deserializer;
|
||||||
class InventoryRefs;
|
class InventoryRefs;
|
||||||
|
|
||||||
class ServerClient {
|
class ServerClient {
|
||||||
|
@ -42,14 +43,16 @@ public:
|
||||||
std::shared_ptr<Inventory> getInventory();
|
std::shared_ptr<Inventory> getInventory();
|
||||||
|
|
||||||
std::shared_ptr<InventoryList> getHandList();
|
std::shared_ptr<InventoryList> getHandList();
|
||||||
void setHandList(std::shared_ptr<InventoryList> list, bool assert = false);
|
void setHandList(const std::string& list, bool assert = false);
|
||||||
|
|
||||||
std::shared_ptr<InventoryList> getWieldList();
|
std::shared_ptr<InventoryList> getWieldList();
|
||||||
void setWieldList(std::shared_ptr<InventoryList> list, bool assert = false);
|
void setWieldList(const std::string& list, bool assert = false);
|
||||||
|
|
||||||
unsigned short getWieldIndex();
|
unsigned short getWieldIndex();
|
||||||
void setWieldIndex(unsigned short index, bool assert = false);
|
void setWieldIndex(unsigned short index, bool assert = false);
|
||||||
|
|
||||||
|
void handleAssertion(Deserializer& d);
|
||||||
|
|
||||||
// void setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity);
|
// void setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity);
|
||||||
// unsigned long long getMapBlockIntegrity(glm::ivec3 pos);
|
// unsigned long long getMapBlockIntegrity(glm::ivec3 pos);
|
||||||
|
|
||||||
|
@ -76,8 +79,9 @@ private:
|
||||||
|
|
||||||
std::shared_ptr<Inventory> inventory;
|
std::shared_ptr<Inventory> inventory;
|
||||||
unsigned int wieldIndex = 0;
|
unsigned int wieldIndex = 0;
|
||||||
std::shared_ptr<InventoryList> handList = nullptr;
|
|
||||||
std::shared_ptr<InventoryList> wieldList = nullptr;
|
std::string handList = "";
|
||||||
|
std::string wieldList = "";
|
||||||
|
|
||||||
unsigned int handItem = DefinitionAtlas::AIR;
|
unsigned int handItem = DefinitionAtlas::AIR;
|
||||||
unsigned int wieldItem = DefinitionAtlas::AIR;
|
unsigned int wieldItem = DefinitionAtlas::AIR;
|
||||||
|
|
|
@ -17,12 +17,15 @@
|
||||||
#include "../../../def/ServerSubgame.h"
|
#include "../../../def/ServerSubgame.h"
|
||||||
#include "../../../def/item/BlockDef.h"
|
#include "../../../def/item/BlockDef.h"
|
||||||
#include "../../../world/chunk/Chunk.h"
|
#include "../../../world/chunk/Chunk.h"
|
||||||
|
#include "../../../lua/usertype/Target.h"
|
||||||
#include "../../../world/chunk/MapBlock.h"
|
#include "../../../world/chunk/MapBlock.h"
|
||||||
#include "../../../world/fs/FileManipulator.h"
|
#include "../../../world/fs/FileManipulator.h"
|
||||||
#include "../../../def/ServerDefinitionAtlas.h"
|
#include "../../../lua/usertype/LuaItemStack.h"
|
||||||
#include "../../../lua/usertype/ServerLuaEntity.h"
|
#include "../../../lua/usertype/ServerLuaEntity.h"
|
||||||
|
#include "../../../lua/usertype/ServerLuaPlayer.h"
|
||||||
|
|
||||||
ServerWorld::ServerWorld(unsigned int seed, ServerSubgame& game, ClientList& clients) :
|
ServerWorld::ServerWorld(unsigned int seed, ServerSubgame& game, ClientList& clients) :
|
||||||
|
World(game),
|
||||||
clientList(clients),
|
clientList(clients),
|
||||||
dimension(game),
|
dimension(game),
|
||||||
seed(seed),
|
seed(seed),
|
||||||
|
@ -68,7 +71,7 @@ void ServerWorld::init(const std::string& worldDir) {
|
||||||
generateMapBlock({0, 0, 0});
|
generateMapBlock({0, 0, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerWorld::update(double delta) {
|
void ServerWorld::update(double) {
|
||||||
dimension.update(clientList.clients, mapBlockGenRange);
|
dimension.update(clientList.clients, mapBlockGenRange);
|
||||||
|
|
||||||
std::unordered_set<glm::ivec3, Vec::ivec3> updatedChunks {};
|
std::unordered_set<glm::ivec3, Vec::ivec3> updatedChunks {};
|
||||||
|
@ -253,6 +256,27 @@ void ServerWorld::setBlock(glm::ivec3 pos, unsigned int block) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerWorld::blockPlace(const Target &target, ServerClient &client) {
|
||||||
|
std::tuple<sol::optional<LuaItemStack>, sol::optional<glm::vec3>> res = game.lua->safe_function(
|
||||||
|
game.lua->core["block_place"], ServerLuaPlayer(client), Api::Usertype::Target(target));
|
||||||
|
|
||||||
|
auto stack = std::get<sol::optional<LuaItemStack>>(res);
|
||||||
|
if (stack) client.getWieldList()->setStack(client.getWieldIndex(), ItemStack(*stack, game.getDefs()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerWorld::blockInteract(const Target &target, ServerClient &client) {
|
||||||
|
game.lua->safe_function(game.lua->core["block_interact"],
|
||||||
|
ServerLuaPlayer(client), Api::Usertype::Target(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerWorld::blockPlaceOrInteract(const Target &target, ServerClient &client) {
|
||||||
|
std::tuple<sol::optional<LuaItemStack>, sol::optional<glm::vec3>> res = game.lua->safe_function(
|
||||||
|
game.lua->core["block_interact_or_place"], ServerLuaPlayer(client), Api::Usertype::Target(target));
|
||||||
|
|
||||||
|
auto stack = std::get<sol::optional<LuaItemStack>>(res);
|
||||||
|
if (stack) client.getWieldList()->setStack(client.getWieldIndex(), ItemStack(*stack, game.getDefs()));
|
||||||
|
}
|
||||||
|
|
||||||
bool ServerWorld::isInBounds(glm::ivec3 cPos, std::pair<glm::ivec3, glm::ivec3> &bounds) {
|
bool ServerWorld::isInBounds(glm::ivec3 cPos, std::pair<glm::ivec3, glm::ivec3> &bounds) {
|
||||||
return (cPos.x >= bounds.first.x && cPos.x <= bounds.second.x
|
return (cPos.x >= bounds.first.x && cPos.x <= bounds.second.x
|
||||||
&& cPos.y >= bounds.first.y && cPos.y <= bounds.second.y
|
&& cPos.y >= bounds.first.y && cPos.y <= bounds.second.y
|
||||||
|
|
|
@ -10,9 +10,11 @@
|
||||||
|
|
||||||
#include "../../../world/ServerDimension.h"
|
#include "../../../world/ServerDimension.h"
|
||||||
|
|
||||||
class ServerSubgame;
|
class Target;
|
||||||
|
class ItemStack;
|
||||||
class ClientList;
|
class ClientList;
|
||||||
class ServerClient;
|
class ServerClient;
|
||||||
|
class ServerSubgame;
|
||||||
class FileManipulator;
|
class FileManipulator;
|
||||||
class ServerGenStream;
|
class ServerGenStream;
|
||||||
class ServerPacketStream;
|
class ServerPacketStream;
|
||||||
|
@ -27,6 +29,10 @@ public:
|
||||||
unsigned int getBlock(glm::ivec3 pos) override;
|
unsigned int getBlock(glm::ivec3 pos) override;
|
||||||
void setBlock(glm::ivec3 pos, unsigned int block) override;
|
void setBlock(glm::ivec3 pos, unsigned int block) override;
|
||||||
|
|
||||||
|
void blockPlace(const Target& target, ServerClient& client);
|
||||||
|
void blockPlaceOrInteract(const Target& target, ServerClient& client);
|
||||||
|
void blockInteract(const Target& target, ServerClient& client);
|
||||||
|
|
||||||
ServerDimension dimension;
|
ServerDimension dimension;
|
||||||
private:
|
private:
|
||||||
void changedMapBlocks(ServerClient& client);
|
void changedMapBlocks(ServerClient& client);
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
//
|
|
||||||
// Created by aurailus on 13/05/19.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../util/Vec.h"
|
|
||||||
|
|
||||||
class PointedThing {
|
|
||||||
public:
|
|
||||||
enum class Thing {
|
|
||||||
ENTITY,
|
|
||||||
BLOCK,
|
|
||||||
NOTHING
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PointedBlock {
|
|
||||||
unsigned int blockId;
|
|
||||||
glm::ivec3 pos;
|
|
||||||
EVec face;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PointedEntity {
|
|
||||||
//TODO;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
PointedBlock block;
|
|
||||||
PointedEntity entity;
|
|
||||||
unsigned short nothing;
|
|
||||||
} PointedThingTarget;
|
|
||||||
|
|
||||||
PointedThing() = default;
|
|
||||||
PointedThing(const PointedThing &o) = default;
|
|
||||||
|
|
||||||
Thing thing = PointedThing::Thing::NOTHING;
|
|
||||||
PointedThingTarget target = PointedThingTarget{0};
|
|
||||||
};
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 2020-07-27.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Target.h"
|
||||||
|
|
||||||
|
#include "../def/item/SelectionBox.h"
|
||||||
|
|
||||||
|
Target::Target(glm::ivec3 pos, EVec face) : type(Type::BLOCK), pos(pos), face(face) {}
|
||||||
|
|
||||||
|
glm::ivec3 Target::getAbovePos() const {
|
||||||
|
return glm::ivec3(pos) + SelectionBox::faceToOffset(face);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// Created by aurailus on 13/05/19.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../util/Vec.h"
|
||||||
|
|
||||||
|
class Target {
|
||||||
|
public:
|
||||||
|
enum class Type { ENTITY, BLOCK, NOTHING };
|
||||||
|
|
||||||
|
Target() = default;
|
||||||
|
Target(const Target &o) = default;
|
||||||
|
Target(glm::ivec3 pos, EVec face);
|
||||||
|
|
||||||
|
glm::ivec3 getAbovePos() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Type type = Target::Type::NOTHING;
|
||||||
|
|
||||||
|
glm::vec3 pos {};
|
||||||
|
EVec face = EVec::NONE;
|
||||||
|
};
|
|
@ -27,6 +27,7 @@ zepha.register_block("@aurailus:crazyblocks:inventory", {
|
||||||
|
|
||||||
if zepha.server then
|
if zepha.server then
|
||||||
zepha.bind("new_player", function(player)
|
zepha.bind("new_player", function(player)
|
||||||
|
player:get_inventory():get_list("hot_wheel_1"):add_stack({"zeus:default:dirt", 32})
|
||||||
player:get_inventory():get_list("hot_wheel_1"):add_stack({"@aurailus:crazyblocks:stacker", 1})
|
player:get_inventory():get_list("hot_wheel_1"):add_stack({"@aurailus:crazyblocks:stacker", 1})
|
||||||
player:get_inventory():get_list("hot_wheel_1"):add_stack({"@aurailus:crazyblocks:inventory", 1})
|
player:get_inventory():get_list("hot_wheel_1"):add_stack({"@aurailus:crazyblocks:inventory", 1})
|
||||||
player:get_inventory():get_list("hot_wheel_1"):add_stack({"@aurailus:crazyblocks:box", 1})
|
player:get_inventory():get_list("hot_wheel_1"):add_stack({"@aurailus:crazyblocks:box", 1})
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
set(ZEPHA_TEST
|
add_library(Zepha_Test
|
||||||
Main.cpp tests/TestSpace.cpp tests/TestBlockChunk.cpp tests/TestSerializer.cpp tests/TestBlockChunkSerialization.cpp)
|
Main.cpp
|
||||||
|
tests/TestSpace.cpp
|
||||||
add_library (Zepha_Test ${ZEPHA_TEST})
|
tests/TestBlockChunk.cpp
|
||||||
|
tests/TestSerializer.cpp
|
||||||
|
tests/TestBlockChunkSerialization.cpp
|
||||||
|
)
|
Loading…
Reference in New Issue