Synchronize block interaction callbacks, wieldlists, etc. Breaking broke
parent
ad029752ef
commit
38b75c212b
|
@ -1,4 +1,5 @@
|
|||
runfile(_PATH .. "models/init")
|
||||
runfile(_PATH .. "player_interact")
|
||||
runfile(_PATH .. "inventory")
|
||||
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.h
|
||||
def/gen/BiomeAtlas.cpp
|
||||
|
@ -200,8 +200,7 @@ set(ZEPHA_SRC
|
|||
lua/LuaMod.h
|
||||
lua/LuaParser.cpp
|
||||
lua/LuaParser.h
|
||||
lua/modules/BaseModule.cpp
|
||||
lua/modules/BaseModule.h
|
||||
lua/modules/BaseModule.h
|
||||
lua/modules/Block.cpp
|
||||
lua/modules/Block.h
|
||||
lua/modules/create_structure.h
|
||||
|
@ -321,9 +320,7 @@ set(ZEPHA_SRC
|
|||
world/fs/FileManipulator.h
|
||||
world/LocalDimension.cpp
|
||||
world/LocalDimension.h
|
||||
world/PointedThing.h
|
||||
world/Target.h
|
||||
world/ServerDimension.cpp
|
||||
world/ServerDimension.h
|
||||
)
|
||||
|
||||
add_library (Zepha_Core ${ZEPHA_SRC})
|
||||
lua/usertype/Target.cpp lua/usertype/Target.h lua/usertype/BaseUsertype.h lua/usertype/SubgameUsertype.h world/Target.cpp)
|
|
@ -58,6 +58,12 @@ void BlockCrackEntity::addDamage(double damage) {
|
|||
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) {
|
||||
for (const MeshPart& mp : meshParts) {
|
||||
glm::vec4 uv;
|
||||
|
@ -81,4 +87,4 @@ void BlockCrackEntity::addFaces(unsigned int &indOffset, std::vector<EntityVerte
|
|||
|
||||
indOffset += mp.vertices.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
|
||||
void update();
|
||||
void addDamage(double damage);
|
||||
void setDamage(double damage);
|
||||
|
||||
int maxHealth = 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
|
||||
<< " (" << round(game.textures.textureSlotsUsed / static_cast<float>(game.textures.maxTextureSlots) * 100) << "%)" << std::endl << std::endl;
|
||||
|
||||
PointedThing thing = player.getPointedThing();
|
||||
if (thing.thing == PointedThing::Thing::BLOCK) {
|
||||
EVec faceDir = thing.target.block.face;
|
||||
|
||||
Target thing = player.getPointedThing();
|
||||
if (thing.type == Target::Type::BLOCK) {
|
||||
std::string face =
|
||||
faceDir == EVec::TOP ? "TOP" :
|
||||
faceDir == EVec::BOTTOM ? "BOTTOM" :
|
||||
faceDir == EVec::LEFT ? "LEFT" :
|
||||
faceDir == EVec::RIGHT ? "RIGHT" :
|
||||
faceDir == EVec::FRONT ? "FRONT" :
|
||||
faceDir == EVec::BACK ? "BACK" :
|
||||
"NONE" ;
|
||||
thing.face == EVec::TOP ? "TOP" :
|
||||
thing.face == EVec::BOTTOM ? "BOTTOM" :
|
||||
thing.face == EVec::LEFT ? "LEFT" :
|
||||
thing.face == EVec::RIGHT ? "RIGHT" :
|
||||
thing.face == EVec::FRONT ? "FRONT" :
|
||||
thing.face == EVec::BACK ? "BACK" :
|
||||
"NONE" ;
|
||||
|
||||
str << "Pointing At: " << game.defs->blockFromId(thing.target.block.blockId).identifier << std::endl;
|
||||
str << "Pointed Position: " << vecToString(thing.target.block.pos) << std::endl;
|
||||
str << "Pointing At: " << game.defs->blockFromId(world.getBlock(thing.pos)).identifier << std::endl;
|
||||
str << "Pointed Position: " << vecToString(thing.pos) << std::endl;
|
||||
str << "Pointed Face: " << face << std::endl;
|
||||
}
|
||||
else {
|
||||
|
@ -163,12 +161,12 @@ void DebugGui::update(Player& player, LocalWorld& world, LocalSubgame& game, dou
|
|||
}
|
||||
|
||||
{ //Crosshair Text
|
||||
PointedThing thing = player.getPointedThing();
|
||||
Target target = player.getPointedThing();
|
||||
|
||||
std::ostringstream crossText;
|
||||
if (thing.thing == PointedThing::Thing::BLOCK) {
|
||||
crossText << game.defs->blockFromId(thing.target.block.blockId).name
|
||||
<< " (" << game.defs->blockFromId(thing.target.block.blockId).identifier << ")" << std::endl;
|
||||
if (target.type == Target::Type::BLOCK) {
|
||||
crossText << game.defs->blockFromId(world.getBlock(target.pos)).name
|
||||
<< " (" << game.defs->blockFromId(world.getBlock(target.pos)).identifier << ")" << std::endl;
|
||||
}
|
||||
get<GuiText>("crosshairText")->setText(crossText.str());
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ GameScene::GameScene(ClientState& state) : Scene(state),
|
|||
game(state.defs),
|
||||
world(game, &net),
|
||||
net(state.connection, game, player),
|
||||
player(world, game, state.renderer, refs),
|
||||
player(game, world, state.renderer, refs, net),
|
||||
debugGui(state.renderer.window.getSize(), game) {
|
||||
|
||||
namespace ph = std::placeholders;
|
||||
|
@ -23,7 +23,7 @@ GameScene::GameScene(ClientState& state) : Scene(state),
|
|||
r.sendTo(state.connection.getPeer(), PacketChannel::CONNECT);
|
||||
|
||||
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);
|
||||
refs .init();
|
||||
|
||||
|
|
|
@ -9,23 +9,24 @@
|
|||
#include "WorldInterpolationStream.h"
|
||||
#include "../../../world/chunk/Chunk.h"
|
||||
#include "../../../def/item/BlockDef.h"
|
||||
#include "../../../def/gen/LocalBiomeAtlas.h"
|
||||
#include "../../../def/LocalDefinitionAtlas.h"
|
||||
#include "../../../lua/LocalLuaParser.h"
|
||||
#include "../../../lua/usertype/Target.h"
|
||||
#include "../../../lua/usertype/LuaItemStack.h"
|
||||
#include "../../inventory/LocalInventoryList.h"
|
||||
#include "../../entity/engine/ParticleEntity.h"
|
||||
#include "../../entity/engine/BlockCrackEntity.h"
|
||||
#include "../../../lua/usertype/LocalLuaPlayer.h"
|
||||
#include "../../../net/client/ClientNetworkInterpreter.h"
|
||||
|
||||
LocalWorld::LocalWorld(LocalSubgame& defs, ClientNetworkInterpreter* server) :
|
||||
defs(defs),
|
||||
net(server),
|
||||
dimension(defs) {}
|
||||
World(defs),
|
||||
game(defs),
|
||||
net(server),
|
||||
dimension(defs) {}
|
||||
|
||||
void LocalWorld::init(Player* player) {
|
||||
this->player = player;
|
||||
delete worldGenStream;
|
||||
worldGenStream = new WorldInterpolationStream(55, defs);
|
||||
worldGenStream = new WorldInterpolationStream(55, game);
|
||||
}
|
||||
|
||||
void LocalWorld::update(double delta) {
|
||||
|
@ -61,61 +62,49 @@ void LocalWorld::setBlock(glm::ivec3 pos, unsigned int block) {
|
|||
dimension.setBlock(pos, block);
|
||||
}
|
||||
|
||||
void LocalWorld::blockPlace(glm::vec3 pos, unsigned int block) {
|
||||
if (block == LocalDefinitionAtlas::AIR) {
|
||||
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;
|
||||
double LocalWorld::setBlockDamage(glm::ivec3 pos, double damage) {
|
||||
double totalDamage = World::setBlockDamage(pos, damage);
|
||||
|
||||
BlockCrackEntity* block = nullptr;
|
||||
for (auto test : crackedBlocks) if (glm::ivec3(test->getPos()) == pos) { block = test; break; }
|
||||
if (block == nullptr) {
|
||||
block = new BlockCrackEntity(blockDef, defs.textures, pos);
|
||||
crackedBlocks.push_back(block);
|
||||
}
|
||||
|
||||
block->addDamage(damage);
|
||||
if (crackEntities.count(pos)) block = crackEntities[pos];
|
||||
else block = new BlockCrackEntity(game.defs->blockFromId(getBlock(pos)), game.textures, pos);
|
||||
block->setDamage(damage);
|
||||
block->time = 0;
|
||||
|
||||
// auto def = defs.defs.blockFromId(getBlock(pos));
|
||||
// for (int i = 0; i < 40 * damage; i++) {
|
||||
// auto p = new ParticleEntity(pos, def);
|
||||
// particles.push_back(p);
|
||||
// }
|
||||
return totalDamage;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -143,24 +132,26 @@ int LocalWorld::renderChunks(Renderer &renderer) {
|
|||
}
|
||||
|
||||
void LocalWorld::renderEntities(Renderer &renderer) {
|
||||
for (auto block : crackedBlocks) block->draw(renderer);
|
||||
for (auto &p : particles) p->draw(renderer);
|
||||
for (auto& block : crackEntities) block.second->draw(renderer);
|
||||
for (auto& particle : particles) particle->draw(renderer);
|
||||
|
||||
dimension.renderEntities(renderer);
|
||||
}
|
||||
|
||||
void LocalWorld::updateBlockDamages(double delta) {
|
||||
auto it = crackedBlocks.cbegin();
|
||||
while (it != crackedBlocks.cend()) {
|
||||
auto it = crackEntities.cbegin();
|
||||
while (it != crackEntities.cend()) {
|
||||
bool deleteMe = false;
|
||||
|
||||
auto curr = it++;
|
||||
auto block = *curr;
|
||||
auto block = curr->second;
|
||||
|
||||
block->time += delta;
|
||||
|
||||
if (block->damage >= block->maxHealth) {
|
||||
blockBreak(block->getPos());
|
||||
//Todo: Lua callback~
|
||||
setBlock(block->getPos(), DefinitionAtlas::AIR);
|
||||
setBlockDamage(block->getPos(), 0);
|
||||
deleteMe = true;
|
||||
}
|
||||
|
||||
|
@ -175,8 +166,8 @@ void LocalWorld::updateBlockDamages(double delta) {
|
|||
}
|
||||
|
||||
if (deleteMe) {
|
||||
delete *curr;
|
||||
it = crackedBlocks.erase(curr);
|
||||
delete block;
|
||||
it = crackEntities.erase(curr);
|
||||
}
|
||||
else block->update();
|
||||
}
|
||||
|
|
|
@ -8,14 +8,15 @@
|
|||
|
||||
#include "../../../world/LocalDimension.h"
|
||||
|
||||
class Target;
|
||||
class Player;
|
||||
class Renderer;
|
||||
class ItemStack;
|
||||
class LocalSubgame;
|
||||
class ParticleEntity;
|
||||
class BlockCrackEntity;
|
||||
class ClientNetworkInterpreter;
|
||||
class WorldInterpolationStream;
|
||||
class BlockCrackEntity;
|
||||
class ParticleEntity;
|
||||
class PointedThing;
|
||||
class LocalSubgame;
|
||||
class Renderer;
|
||||
class Player;
|
||||
|
||||
class LocalWorld : public World {
|
||||
public:
|
||||
|
@ -24,17 +25,20 @@ public:
|
|||
void init(Player* player);
|
||||
void update(double delta) override;
|
||||
|
||||
void createDimension(std::string identifier);
|
||||
|
||||
void loadWorldPacket(std::unique_ptr<PacketView> p);
|
||||
void commitChunk(std::shared_ptr<Chunk> chunk);
|
||||
|
||||
unsigned int getBlock(glm::ivec3 pos) override;
|
||||
void setBlock(glm::ivec3 pos, unsigned int block) override;
|
||||
|
||||
void blockPlace(glm::vec3 pos, unsigned int block);
|
||||
void blockBreak(glm::vec3 pos);
|
||||
double setBlockDamage(glm::ivec3 pos, double damage) override;
|
||||
|
||||
void blockInteract(PointedThing& thing);
|
||||
double blockHit(PointedThing& thing);
|
||||
void blockPlace(Target& target);
|
||||
void blockPlaceOrInteract(Target& target);
|
||||
void blockInteract(Target& target);
|
||||
double blockHit(Target& target);
|
||||
|
||||
unsigned short getBiome(glm::vec3 pos);
|
||||
std::shared_ptr<Chunk> getChunk(glm::ivec3 pos);
|
||||
|
@ -43,7 +47,7 @@ public:
|
|||
int renderChunks(Renderer &render);
|
||||
void renderEntities(Renderer &renderer);
|
||||
|
||||
LocalSubgame& defs;
|
||||
LocalSubgame& game;
|
||||
LocalDimension dimension;
|
||||
|
||||
int mapBlocksInterpolated = 0;
|
||||
|
@ -52,7 +56,7 @@ private:
|
|||
void finishChunks();
|
||||
void updateBlockDamages(double delta);
|
||||
|
||||
std::vector<BlockCrackEntity*> crackedBlocks;
|
||||
std::unordered_map<glm::ivec3, BlockCrackEntity*, Vec::ivec3> crackEntities;
|
||||
std::vector<ParticleEntity*> particles;
|
||||
|
||||
Player* player = nullptr;
|
||||
|
|
|
@ -8,23 +8,23 @@
|
|||
#include "../../../util/Ray.h"
|
||||
#include "../../graph/Renderer.h"
|
||||
#include "../../../def/ItemDef.h"
|
||||
#include "../../../net/Serializer.h"
|
||||
#include "../../../net/Deserializer.h"
|
||||
#include "../../../def/item/BlockDef.h"
|
||||
#include "../../../world/chunk/Chunk.h"
|
||||
#include "../../inventory/LocalInventory.h"
|
||||
#include "../../../def/LocalDefinitionAtlas.h"
|
||||
#include "../../inventory/LocalInventoryList.h"
|
||||
#include "../../../net/client/NetPlayerField.h"
|
||||
#include "../../../net/client/ClientNetworkInterpreter.h"
|
||||
|
||||
Player::Player(LocalWorld& world, LocalSubgame& defs, Renderer& renderer, LocalInventoryRefs& refs) :
|
||||
Collidable(world, defs, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
|
||||
Player::Player(LocalSubgame &game, LocalWorld &world, Renderer &renderer, LocalInventoryRefs &refs, ClientNetworkInterpreter& net) :
|
||||
Collidable(world, game, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
|
||||
|
||||
net(net),
|
||||
refs(refs),
|
||||
game(defs),
|
||||
game(game),
|
||||
renderer(renderer),
|
||||
wireframe({}, 0.01, {1, 1, 1}),
|
||||
gameGui(refs, renderer.window.getSize(), defs, renderer) {
|
||||
gameGui(refs, renderer.window.getSize(), game, renderer) {
|
||||
handItemModel.parent = &handModel;
|
||||
|
||||
renderer.window.addResizeCallback("player", [&](glm::ivec2 win) {
|
||||
|
@ -186,27 +186,25 @@ void Player::findPointedThing(Input &input) {
|
|||
auto face = sBox.intersects(rayEnd, roundedPos);
|
||||
|
||||
if (face != EVec::NONE) {
|
||||
pointedThing.thing = PointedThing::Thing::BLOCK;
|
||||
pointedThing.target.block = { blockID, roundedPos, face };
|
||||
target = Target(roundedPos, face);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pointedThing.thing = PointedThing::Thing::NOTHING;
|
||||
pointedThing.target.nothing = 0;
|
||||
target = Target {};
|
||||
}
|
||||
|
||||
void Player::updateWireframe() {
|
||||
if (!gameGui.isVisible()) {
|
||||
wireframe.setVisible(false);
|
||||
}
|
||||
else if (pointedThing.thing == PointedThing::Thing::BLOCK) {
|
||||
auto& boxes = game.defs->blockFromId(pointedThing.target.block.blockId).sBoxes;
|
||||
float distance = glm::distance(pos, glm::vec3(pointedThing.target.block.pos) + glm::vec3(0.5));
|
||||
else if (target.type == Target::Type::BLOCK) {
|
||||
auto& boxes = game.defs->blockFromId(world.getBlock(target.pos)).sBoxes;
|
||||
float distance = glm::distance(pos, target.pos + glm::vec3(0.5));
|
||||
|
||||
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
|
||||
wireframe.setPos(pointedThing.target.block.pos);
|
||||
wireframe.setPos(target.pos);
|
||||
wireframe.setVisible(true);
|
||||
}
|
||||
else {
|
||||
|
@ -215,23 +213,12 @@ void Player::updateWireframe() {
|
|||
}
|
||||
|
||||
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) {
|
||||
breakInterval = world.blockHit(pointedThing);
|
||||
breakInterval = world.blockHit(target);
|
||||
breakTime += delta;
|
||||
}
|
||||
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) world.blockPlaceOrInteract(target);
|
||||
}
|
||||
|
||||
if (breakTime > 0) breakTime += delta;
|
||||
|
@ -249,7 +236,7 @@ glm::vec3 Player::getPos() {
|
|||
void Player::setPos(glm::vec3 pos, bool assert) {
|
||||
this->pos = pos;
|
||||
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() {
|
||||
|
@ -258,7 +245,7 @@ glm::vec3 Player::getVel() {
|
|||
|
||||
void Player::setVel(glm::vec3 vel, bool assert) {
|
||||
this->vel = vel;
|
||||
if (assert) assertField(NetPlayerField::VELOCITY, vel);
|
||||
if (assert) net.assertPlayerField(NetPlayerField::VELOCITY, vel);
|
||||
}
|
||||
|
||||
float Player::getYaw() {
|
||||
|
@ -267,7 +254,7 @@ float Player::getYaw() {
|
|||
|
||||
void Player::setYaw(float yaw, bool assert) {
|
||||
this->yaw = yaw;
|
||||
if (assert) assertField(NetPlayerField::YAW, yaw);
|
||||
if (assert) net.assertPlayerField(NetPlayerField::YAW, yaw);
|
||||
}
|
||||
|
||||
float Player::getPitch() {
|
||||
|
@ -276,7 +263,7 @@ float Player::getPitch() {
|
|||
|
||||
void Player::setPitch(float pitch, bool assert) {
|
||||
this->pitch = pitch;
|
||||
if (assert) assertField(NetPlayerField::PITCH, pitch);
|
||||
if (assert) net.assertPlayerField(NetPlayerField::PITCH, pitch);
|
||||
}
|
||||
|
||||
bool Player::isFlying() {
|
||||
|
@ -285,11 +272,11 @@ bool Player::isFlying() {
|
|||
|
||||
void Player::setFlying(bool flying, bool assert) {
|
||||
this->flying = flying;
|
||||
if (assert) assertField(NetPlayerField::FLYING, flying);
|
||||
if (assert) net.assertPlayerField(NetPlayerField::FLYING, flying);
|
||||
}
|
||||
|
||||
PointedThing& Player::getPointedThing() {
|
||||
return pointedThing;
|
||||
Target& Player::getPointedThing() {
|
||||
return target;
|
||||
}
|
||||
|
||||
LocalInventory& Player::getInventory() {
|
||||
|
@ -313,7 +300,7 @@ void Player::setWieldList(const std::string& list, bool assert) {
|
|||
refs.setWieldList(list);
|
||||
setWieldIndex(wieldIndex);
|
||||
updateWieldAndHandItems();
|
||||
if (assert) assertField(NetPlayerField::WIELD_INV, list);
|
||||
if (assert) net.assertPlayerField(NetPlayerField::WIELD_INV, list);
|
||||
}
|
||||
|
||||
unsigned short Player::getWieldIndex() {
|
||||
|
@ -324,7 +311,7 @@ void Player::setWieldIndex(unsigned short index, bool assert) {
|
|||
auto wieldList = refs.getWieldList();
|
||||
wieldIndex = index % std::max((wieldList ? wieldList->getLength() : 1), 1);
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
while (!d.atEnd()) {
|
||||
switch (static_cast<NetPlayerField>(d.read<unsigned int>())) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "../../graph/drawable/Drawable.h"
|
||||
|
||||
#include "../../hud/GameGui.h"
|
||||
#include "../../../world/PointedThing.h"
|
||||
#include "../../../world/Target.h"
|
||||
#include "../../entity/engine/WireframeEntity.h"
|
||||
|
||||
class Input;
|
||||
|
@ -22,8 +22,8 @@ class Player : Collidable, public Drawable {
|
|||
public:
|
||||
enum class PlayerControl {
|
||||
FORWARD, LEFT, BACKWARD, RIGHT,
|
||||
JUMP, MOD1, MOD2
|
||||
};
|
||||
JUMP, MOD1, MOD2 };
|
||||
|
||||
static constexpr float MOUSE_SENSITIVITY = 0.1f;
|
||||
static constexpr float LOOK_DISTANCE = 6.5f;
|
||||
static constexpr float LOOK_PRECISION = 0.01f;
|
||||
|
@ -31,7 +31,7 @@ public:
|
|||
static constexpr float BASE_MOVE_SPEED = 4.3f;
|
||||
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);
|
||||
~Player();
|
||||
|
||||
|
@ -68,7 +68,7 @@ public:
|
|||
void setHud(std::shared_ptr<LuaGuiElement> hud);
|
||||
std::shared_ptr<LuaGuiElement> getHud();
|
||||
|
||||
PointedThing& getPointedThing();
|
||||
Target& getPointedThing();
|
||||
void setHudVisible(bool hudVisible);
|
||||
|
||||
void draw(Renderer& renderer) override;
|
||||
|
@ -90,9 +90,9 @@ private:
|
|||
void interact(Input& input, double delta);
|
||||
|
||||
void updateWieldAndHandItems();
|
||||
template <typename T> void assertField(NetPlayerField field, T data);
|
||||
|
||||
LocalSubgame& game;
|
||||
ClientNetworkInterpreter& net;
|
||||
Renderer& renderer;
|
||||
|
||||
GameGui gameGui;
|
||||
|
@ -112,6 +112,6 @@ private:
|
|||
|
||||
double breakTime = 0;
|
||||
double breakInterval = 0;
|
||||
PointedThing pointedThing;
|
||||
Target target;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,4 +2,30 @@
|
|||
// 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
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../../../util/Vec.h"
|
||||
|
||||
class Subgame;
|
||||
class Dimension;
|
||||
|
||||
class World {
|
||||
public:
|
||||
explicit World() = default;
|
||||
explicit World(Subgame& game);
|
||||
|
||||
virtual void update(double delta) = 0;
|
||||
|
||||
// virtual Dimension& getDimension() = 0;
|
||||
|
||||
virtual unsigned int getBlock(glm::ivec3 pos) = 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/cInventoryRef.h"
|
||||
#include "usertype/cAnimationManager.h"
|
||||
#include "usertype/Target.h"
|
||||
|
||||
// Modules
|
||||
#include "modules/Time.h"
|
||||
#include "modules/Block.h"
|
||||
#include "modules/Entity.h"
|
||||
#include "modules/Register.h"
|
||||
|
||||
#include "modules/create_structure.h"
|
||||
#include "LuaMod.h"
|
||||
|
||||
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::gui_element (lua);
|
||||
|
||||
Api::Usertype::Target::bind(Api::State::CLIENT, lua, core);
|
||||
|
||||
core["client"] = true;
|
||||
core["player"] = LocalLuaPlayer(player);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "usertype/sLuaEntity.h"
|
||||
#include "usertype/sInventoryRef.h"
|
||||
#include "usertype/cItemStack.h"
|
||||
#include "usertype/Target.h"
|
||||
|
||||
// Modules
|
||||
#include "modules/Time.h"
|
||||
|
@ -98,11 +99,13 @@ void ServerLuaParser::loadApi(ServerSubgame &defs, ServerWorld &world) {
|
|||
ServerApi::inventory (lua);
|
||||
ClientApi::item_stack (lua);
|
||||
|
||||
Api::Usertype::Target::bind(Api::State::SERVER, lua, core);
|
||||
|
||||
core["server"] = true;
|
||||
core["players"] = lua.create_table();
|
||||
|
||||
// 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::Entity>(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);
|
||||
}
|
||||
|
||||
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;
|
||||
std::string errString = err.what();
|
||||
|
||||
|
|
|
@ -26,15 +26,16 @@ public:
|
|||
void playerConnected(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...);
|
||||
if (!res.valid()) errorCallback(res);
|
||||
return res;
|
||||
}
|
||||
private:
|
||||
void loadApi(ServerSubgame& defs, ServerWorld& world);
|
||||
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);
|
||||
|
||||
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 {
|
||||
class BaseModule {
|
||||
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;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -14,6 +14,10 @@ void Api::Module::Block::bind() {
|
|||
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("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) {
|
||||
|
@ -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) {
|
||||
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:
|
||||
std::string getBlock(glm::ivec3 pos);
|
||||
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) {
|
||||
if (!list) player.setWieldList("");
|
||||
else if (list->is<std::string>()) player.setWieldList(list->as<std::string>());
|
||||
else if (list->is<LocalLuaInventoryList>()) player.setWieldList(list->as<LocalLuaInventoryList>().get_name());
|
||||
if (!list) player.setWieldList("", true);
|
||||
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(), true);
|
||||
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) {
|
||||
player.setWieldIndex(index - 1);
|
||||
player.setWieldIndex(index - 1, true);
|
||||
}
|
||||
|
||||
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) {
|
||||
player.setFlying(shouldFly);
|
||||
player.setFlying(shouldFly, true);
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!list) player.setHandList(nullptr);
|
||||
else if (list.is<std::string>()) player.setHandList((*player.getInventory())[list.as<std::string>()], true);
|
||||
else if (list.is<ServerLuaInventoryList>()) player.setHandList((*player.getInventory())[list.as<ServerLuaInventoryList>().get_name()], true);
|
||||
else if (list.is<std::string>()) player.setHandList(list.as<std::string>(), true);
|
||||
else if (list.is<ServerLuaInventoryList>()) player.setHandList(list.as<ServerLuaInventoryList>().get_name(), true);
|
||||
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) {
|
||||
if (!list) player.setWieldList(nullptr);
|
||||
else if (list.is<std::string>()) player.setWieldList((*player.getInventory())[list.as<std::string>()], true);
|
||||
else if (list.is<ServerLuaInventoryList>()) player.setWieldList((*player.getInventory())[list.as<ServerLuaInventoryList>().get_name()], true);
|
||||
if (!list) player.setWieldList(nullptr, true);
|
||||
else if (list.is<std::string>()) player.setWieldList(list.as<std::string>(), true);
|
||||
else if (list.is<ServerLuaInventoryList>()) player.setWieldList(list.as<ServerLuaInventoryList>().get_name(), true);
|
||||
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,
|
||||
|
||||
// Block
|
||||
BLOCK_SET,
|
||||
BLOCK_PLACE,
|
||||
BLOCK_INTERACT,
|
||||
BLOCK_PLACE_OR_INTERACT,
|
||||
|
||||
BLOCK_SET,
|
||||
|
||||
// Entity
|
||||
ENTITY_INFO,
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "../NetHandler.h"
|
||||
#include "../../util/Log.h"
|
||||
#include "NetPlayerField.h"
|
||||
#include "ServerConnection.h"
|
||||
#include "../../game/entity/Model.h"
|
||||
#include "../../game/scene/world/Player.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) {
|
||||
Serializer().append(pos).append(block).packet(PacketType::BLOCK_SET)
|
||||
.sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
||||
void ClientNetworkInterpreter::blockPlace(Target &target) {
|
||||
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
||||
.packet(PacketType::BLOCK_PLACE).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
||||
}
|
||||
|
||||
void ClientNetworkInterpreter::blockInteract(glm::ivec3 pos) {
|
||||
Serializer().append(pos).packet(PacketType::BLOCK_INTERACT)
|
||||
.sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
||||
void ClientNetworkInterpreter::blockInteract(Target &target) {
|
||||
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
||||
.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) {
|
||||
|
|
|
@ -8,12 +8,16 @@
|
|||
#include <functional>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include "../Serializer.h"
|
||||
#include "ServerConnection.h"
|
||||
|
||||
class Model;
|
||||
class Player;
|
||||
class Target;
|
||||
class LocalWorld;
|
||||
class LocalSubgame;
|
||||
class PacketView;
|
||||
class ServerConnection;
|
||||
class LocalSubgame;
|
||||
enum class NetPlayerField;
|
||||
|
||||
class ClientNetworkInterpreter {
|
||||
public:
|
||||
|
@ -23,14 +27,20 @@ public:
|
|||
void init(LocalWorld* world, std::function<void(std::unique_ptr<PacketView>)> invCallback);
|
||||
void update();
|
||||
|
||||
void blockPlace(glm::ivec3 pos, unsigned int block);
|
||||
void blockInteract(glm::ivec3 pos);
|
||||
void blockPlace(Target& target);
|
||||
void blockInteract(Target& target);
|
||||
void blockPlaceOrInteract(Target& target);
|
||||
|
||||
void invWatch(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 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 serverSideChunkGens = 0;
|
||||
private:
|
||||
|
|
|
@ -8,13 +8,10 @@
|
|||
#include "Server.h"
|
||||
|
||||
#include "../Serializer.h"
|
||||
#include "../PacketView.h"
|
||||
#include "../../util/Log.h"
|
||||
#include "../../util/Timer.h"
|
||||
#include "../PacketChannel.h"
|
||||
#include "../../world/Target.h"
|
||||
#include "../../def/item/BlockDef.h"
|
||||
#include "../../def/ServerDefinitionAtlas.h"
|
||||
#include "../../lua/ServerLuaParser.h"
|
||||
#include "../../lua/usertype/ServerLuaPlayer.h"
|
||||
|
||||
Server::Server(unsigned short port, const std::string& subgame) :
|
||||
|
@ -114,16 +111,20 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
|
|||
switch (p.type) {
|
||||
default: {
|
||||
std::cout << Log::err << "Invalid packet type (" << static_cast<int>(p.type) << ") recieved." << Log::endl;
|
||||
break;
|
||||
}
|
||||
break; }
|
||||
|
||||
case PacketType::PLAYER_INFO: {
|
||||
client.setPos(p.d.read<glm::vec3>());
|
||||
client.setPitch(p.d.read<float>());
|
||||
client.setYaw(p.d.read<float>());
|
||||
|
||||
playersUpdated.emplace(client.cid);
|
||||
break;
|
||||
}
|
||||
break; }
|
||||
|
||||
case PacketType::THIS_PLAYER_INFO: {
|
||||
client.handleAssertion(p.d);
|
||||
break; }
|
||||
|
||||
case PacketType::BLOCK_SET: {
|
||||
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
||||
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(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: {
|
||||
glm::ivec3 pos = p.d.read<glm::ivec3>();
|
||||
auto& def = defs.defs->blockFromId(world.getBlock(pos));
|
||||
if (def.callbacks.count(Callback::INTERACT)) defs.lua->safe_function(def.callbacks[Callback::INTERACT], pos, ServerLuaPlayer(client));
|
||||
break;
|
||||
}
|
||||
auto face = static_cast<EVec>(p.d.read<unsigned short>());
|
||||
world.blockInteract(Target(pos, face), client);
|
||||
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: {
|
||||
std::string source = 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);
|
||||
if (!exists) Serializer().append(source).append(list)
|
||||
.packet(PacketType::INV_INVALID).sendTo(client.peer, PacketChannel::INVENTORY);
|
||||
break;
|
||||
}
|
||||
break; }
|
||||
|
||||
case PacketType::INV_UNWATCH: {
|
||||
std::string source = 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;
|
||||
}
|
||||
case PacketType::INV_INTERACT: {
|
||||
break; }
|
||||
|
||||
case PacketType::INV_INTERACT: {
|
||||
unsigned short type = p.d.read<unsigned short>();
|
||||
|
||||
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);
|
||||
else refs.secondaryInteract(source, list, ind, client.cid);
|
||||
|
||||
break;
|
||||
}
|
||||
break; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "../../Packet.h"
|
||||
#include "../../Serializer.h"
|
||||
#include "../../Deserializer.h"
|
||||
#include "../../client/NetPlayerField.h"
|
||||
#include "../../../game/inventory/InventoryRefs.h"
|
||||
|
||||
|
@ -77,21 +78,26 @@ std::shared_ptr<Inventory> ServerClient::getInventory() {
|
|||
}
|
||||
|
||||
std::shared_ptr<InventoryList> ServerClient::getHandList() {
|
||||
return handList;
|
||||
return (*inventory)[handList];
|
||||
}
|
||||
|
||||
void ServerClient::setHandList(std::shared_ptr<InventoryList> list, bool assert) {
|
||||
handList = list;
|
||||
if (assert) assertField(NetPlayerField::HAND_INV, handList ? handList->getName() : "");
|
||||
void ServerClient::setHandList(const std::string& list, bool assert) {
|
||||
if (list.empty() || !(*inventory)[list]) this->handList = "";
|
||||
else this->handList = list;
|
||||
|
||||
if (assert) assertField(NetPlayerField::HAND_INV, this->handList);
|
||||
}
|
||||
|
||||
std::shared_ptr<InventoryList> ServerClient::getWieldList() {
|
||||
return wieldList;
|
||||
return (*inventory)[wieldList];
|
||||
}
|
||||
|
||||
void ServerClient::setWieldList(std::shared_ptr<InventoryList> list, bool assert) {
|
||||
wieldList = list;
|
||||
if (assert) assertField(NetPlayerField::WIELD_INV, wieldList ? wieldList->getName() : "");
|
||||
void ServerClient::setWieldList(const std::string& list, bool assert) {
|
||||
if (list.empty() || !(*inventory)[list]) this->wieldList = "";
|
||||
else this->wieldList = list;
|
||||
|
||||
if (assert) assertField(NetPlayerField::WIELD_INV, this->wieldList);
|
||||
setWieldIndex(wieldIndex, assert);
|
||||
}
|
||||
|
||||
unsigned short ServerClient::getWieldIndex() {
|
||||
|
@ -99,10 +105,28 @@ unsigned short ServerClient::getWieldIndex() {
|
|||
}
|
||||
|
||||
void ServerClient::setWieldIndex(unsigned short index, bool assert) {
|
||||
auto wieldList = (*inventory)[this->wieldList];
|
||||
wieldIndex = index % (wieldList ? wieldList->getLength() : 1);
|
||||
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) {
|
||||
// mapBlockIntegrity[pos] = integrity;
|
||||
//}
|
||||
|
@ -116,4 +140,4 @@ template <typename T>
|
|||
void ServerClient::assertField(NetPlayerField field, T data) {
|
||||
Serializer().append(static_cast<unsigned int>(field)).append<T>(data)
|
||||
.packet(PacketType::THIS_PLAYER_INFO).sendTo(peer, PacketChannel::INTERACT);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
#include "../../../game/inventory/ServerInventoryList.h"
|
||||
|
||||
enum class NetPlayerField;
|
||||
class Deserializer;
|
||||
class InventoryRefs;
|
||||
|
||||
class ServerClient {
|
||||
|
@ -42,14 +43,16 @@ public:
|
|||
std::shared_ptr<Inventory> getInventory();
|
||||
|
||||
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();
|
||||
void setWieldList(std::shared_ptr<InventoryList> list, bool assert = false);
|
||||
void setWieldList(const std::string& list, bool assert = false);
|
||||
|
||||
unsigned short getWieldIndex();
|
||||
void setWieldIndex(unsigned short index, bool assert = false);
|
||||
|
||||
void handleAssertion(Deserializer& d);
|
||||
|
||||
// void setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity);
|
||||
// unsigned long long getMapBlockIntegrity(glm::ivec3 pos);
|
||||
|
||||
|
@ -76,8 +79,9 @@ private:
|
|||
|
||||
std::shared_ptr<Inventory> inventory;
|
||||
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 wieldItem = DefinitionAtlas::AIR;
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
#include "../../../def/ServerSubgame.h"
|
||||
#include "../../../def/item/BlockDef.h"
|
||||
#include "../../../world/chunk/Chunk.h"
|
||||
#include "../../../lua/usertype/Target.h"
|
||||
#include "../../../world/chunk/MapBlock.h"
|
||||
#include "../../../world/fs/FileManipulator.h"
|
||||
#include "../../../def/ServerDefinitionAtlas.h"
|
||||
#include "../../../lua/usertype/LuaItemStack.h"
|
||||
#include "../../../lua/usertype/ServerLuaEntity.h"
|
||||
#include "../../../lua/usertype/ServerLuaPlayer.h"
|
||||
|
||||
ServerWorld::ServerWorld(unsigned int seed, ServerSubgame& game, ClientList& clients) :
|
||||
World(game),
|
||||
clientList(clients),
|
||||
dimension(game),
|
||||
seed(seed),
|
||||
|
@ -68,7 +71,7 @@ void ServerWorld::init(const std::string& worldDir) {
|
|||
generateMapBlock({0, 0, 0});
|
||||
}
|
||||
|
||||
void ServerWorld::update(double delta) {
|
||||
void ServerWorld::update(double) {
|
||||
dimension.update(clientList.clients, mapBlockGenRange);
|
||||
|
||||
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) {
|
||||
return (cPos.x >= bounds.first.x && cPos.x <= bounds.second.x
|
||||
&& cPos.y >= bounds.first.y && cPos.y <= bounds.second.y
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
|
||||
#include "../../../world/ServerDimension.h"
|
||||
|
||||
class ServerSubgame;
|
||||
class Target;
|
||||
class ItemStack;
|
||||
class ClientList;
|
||||
class ServerClient;
|
||||
class ServerSubgame;
|
||||
class FileManipulator;
|
||||
class ServerGenStream;
|
||||
class ServerPacketStream;
|
||||
|
@ -27,6 +29,10 @@ public:
|
|||
unsigned int getBlock(glm::ivec3 pos) 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;
|
||||
private:
|
||||
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
|
||||
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:inventory", 1})
|
||||
player:get_inventory():get_list("hot_wheel_1"):add_stack({"@aurailus:crazyblocks:box", 1})
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
set(ZEPHA_TEST
|
||||
Main.cpp tests/TestSpace.cpp tests/TestBlockChunk.cpp tests/TestSerializer.cpp tests/TestBlockChunkSerialization.cpp)
|
||||
|
||||
add_library (Zepha_Test ${ZEPHA_TEST})
|
||||
add_library(Zepha_Test
|
||||
Main.cpp
|
||||
tests/TestSpace.cpp
|
||||
tests/TestBlockChunk.cpp
|
||||
tests/TestSerializer.cpp
|
||||
tests/TestBlockChunkSerialization.cpp
|
||||
)
|
Loading…
Reference in New Issue