Rewrite inventory networking, player networking, tools.

+ Made wield and hand lists.
+ Made tool props & block defenses.
+ Crazyblocks mod to test various API features.
master
Nicole Collings 2020-07-21 19:33:26 -07:00
parent ecaf1fb90c
commit a5e57716ee
103 changed files with 1394 additions and 740 deletions

View File

@ -0,0 +1,5 @@
runfile(_PATH .. "models/init")
runfile(_PATH .. "inventory")
runfile(_PATH .. "tools")
if zepha.player then runfile(_PATH .. "hud") end

View File

@ -0,0 +1,25 @@
-- Register hand item
zepha.register_item("base:hand", {
name = "Hand (you broke the game)",
textures = {"base:hand"},
tool_props = {
interval = 0.25,
damage_groups = { grab = 1, _other = 0 }
}
})
-- Register main and hand inventories
if zepha.server then
zepha.register_on("new_player", function(p)
local inv = p:get_inventory()
local main = inv:add_list("main", 30, 10)
inv:set_default_list(main)
local hand = inv:add_list("hand", 1, 1)
hand:add_stack({"base:hand", 1})
p:set_hand_list(hand)
end)
end

View File

@ -0,0 +1,47 @@
function zepha.get_tool_props(player)
local props = {
interval = 0,
damage_groups = {}
}
if player:get_wield_list() then
local wield_item = player:get_wield_stack()
local wield_props = (zepha.registered_items[wield_item.name] or {}).tool_props or {}
props.interval = wield_props.interval or -1
for group, damage in pairs(wield_props.damage_groups or {}) do props.damage_groups[group] = damage end
end
if props.damage_groups._other == nil and player:get_hand_list() then
local hand_item = player:get_hand_stack()
local hand_props = (zepha.registered_items[hand_item.name] or {}).tool_props or {}
if props.interval == -1 then props.interval = hand_props.interval or -1 end
for group, damage in pairs(hand_props.damage_groups or {}) do
if props.damage_groups[group] == nil then props.damage_groups[group] = damage end
end
end
if props.interval == -1 then props.interval = 1 end
return props
end
function zepha.get_hit_impact(player, block)
local props = zepha.get_tool_props(player)
local def = (zepha.registered_blocks[block] or {}).tool_props or {}
local damage = 0
for group, tool_damage in pairs(props.damage_groups) do
local mul = def.multipliers[group]
if mul == nil then mul = def.multipliers["_other"] end
if mul == nil then mul = 1 end
damage = math.max(damage, tool_damage * mul)
end
damage = math.max(0, damage - (def.defense or 0))
return damage, props.interval
end

View File

@ -1,9 +1,9 @@
-- Load Libraries
runfile(_PATH .. "modules/dump")
runfile(_PATH .. "modules/math")
runfile(_PATH .. "modules/table")
runfile(_PATH .. "modules/vector")
runfile(_PATH .. "modules/gui")
-- Register base models (if not on main menu)
if zepha.register_blockmodel then runfile(_PATH .. "models/_index") end
if zepha.player then runfile(_PATH .. "hud") end
if zepha.client or zepha.server then runfile(_PATH .. "game/init") end

View File

@ -0,0 +1,4 @@
-- Performs a shallow copy of a table.
function table.clone(tbl)
return {table.unpack(tbl)}
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View File

@ -291,9 +291,8 @@ set(ZEPHA_SRC
lua/ErrorFormatter.h
util/RIE.h
lua/api/class/ServerLuaPlayer.cpp
lua/api/class/ServerLuaPlayer.h
lua/api/usertype/sServerPlayer.h
lua/api/modules/register_on.h
lua/api/class/ServerLuaPlayer.h
lua/api/modules/register_on.h
lua/api/functions/trigger_event.h
lua/parser/ServerModHandler.cpp
lua/parser/ServerModHandler.h
@ -320,6 +319,6 @@ set(ZEPHA_SRC
def/gen/MapGenProps.cpp
def/gen/MapGenProps.h
lua/api/class/LuaGuiElement.cpp
lua/api/class/LuaGuiElement.h world/Dimension.cpp world/Dimension.h world/fs/FileManipulator.cpp world/fs/FileManipulator.h def/item/BlockModel.cpp net/server/world/ServerPacketStream.cpp net/server/world/ServerPacketStream.h)
lua/api/class/LuaGuiElement.h world/Dimension.cpp world/Dimension.h world/fs/FileManipulator.cpp world/fs/FileManipulator.h def/item/BlockModel.cpp net/server/world/ServerPacketStream.cpp net/server/world/ServerPacketStream.h lua/register/CreateBlockModel.cpp lua/register/CreateBlockModel.h)
add_library (Zepha_Core ${ZEPHA_SRC})

View File

@ -10,13 +10,27 @@
LocalDefinitionAtlas::LocalDefinitionAtlas(TextureAtlas& atlas) {
//Invalid Node
BlockModel invalidModel = BlockModel::createCube({atlas["_missing"]}, {}, {});
BlockDef* invalid = new BlockDef("invalid", "Invalid (you broke the game!)", 64, invalidModel, invalidModel, true, {}, false, {{}}, {{}});
BlockDef* invalid = new BlockDef();
invalid->identifier = "invalid";
invalid->name = "INVALID";
invalid->maxStackSize = 64;
invalid->model = invalidModel;
invalid->farModel = invalidModel;
invalid->sBoxes = {{{0, 0, 0}, {1, 1, 1}}};
invalid->cBoxes = {{{0, 0, 0}, {1, 1, 1}}};
defs.push_back(invalid);
defTable.insert({"invalid", 0});
//Air Node
BlockModel nullModel {};
BlockDef* air = new BlockDef("air", "Air", 64, nullModel, nullModel, false, {}, true, {}, {}, 1);
BlockDef* air = new BlockDef();
air->identifier = "air";
air->name = "Air";
air->maxStackSize = 64;
air->model = nullModel;
air->farModel = nullModel;
air->solid = false;
air->culls = false;
defs.push_back(air);
defTable.insert({"air", 1});
}

View File

@ -7,15 +7,28 @@
#include "item/BlockDef.h"
ServerDefinitionAtlas::ServerDefinitionAtlas() {
//Invalid Node
BlockModel invalidModel = BlockModel::createCube({}, {}, {});
BlockDef* invalid = new BlockDef("invalid", "Invalid (you broke the game!)", 1, invalidModel, invalidModel, true, {}, false, {{}}, {{}}, INVALID);
BlockDef* invalid = new BlockDef();
invalid->identifier = "invalid";
invalid->name = "INVALID";
invalid->maxStackSize = 64;
invalid->model = invalidModel;
invalid->farModel = invalidModel;
invalid->sBoxes = {{{0, 0, 0}, {1, 1, 1}}};
invalid->cBoxes = {{{0, 0, 0}, {1, 1, 1}}};
registerDef(invalid);
//Air Node
BlockModel nullModel {};
BlockDef* air = new BlockDef("air", "Air (you broke the game!)", 1, nullModel, nullModel, false, {}, true, {}, {}, AIR);
BlockDef* air = new BlockDef();
air->identifier = "air";
air->name = "Air";
air->maxStackSize = 64;
air->model = nullModel;
air->farModel = nullModel;
air->solid = false;
air->culls = false;
registerDef(air);
}

View File

@ -4,30 +4,6 @@
#include "BlockDef.h"
BlockDef::BlockDef(
const std::string& identifier,
const std::string& name,
unsigned short maxStackSize,
const BlockModel& model,
const BlockModel& farModel,
bool solid,
glm::ivec3 lightSource,
bool lightPropagates,
const std::vector<SelectionBox>& sBoxes,
const std::vector<SelectionBox>& cBoxes,
unsigned int index) :
ItemDef {identifier, name, index, maxStackSize, ItemDef::Type::BLOCK},
model(model),
farModel(farModel),
culls(model.culls),
solid(solid),
lightSource(lightSource),
lightPropagates(lightPropagates),
sBoxes(sBoxes),
cBoxes(cBoxes) {}
void BlockDef::createModel() {
std::unique_ptr<EntityMesh> entity = std::make_unique<EntityMesh>();
unsigned int indOffset = 0;
@ -57,3 +33,7 @@ void BlockDef::createModel() {
entityModel = std::make_shared<Model>();
entityModel->fromMesh(std::move(entity));
}
bool BlockDef::hasInteraction() {
return callbacks.count(Callback::INTERACT) || callbacks.count(Callback::INTERACT_CLIENT);
}

View File

@ -16,33 +16,25 @@
class BlockDef : public ItemDef {
public:
BlockDef(
const std::string& identifier,
const std::string& name,
unsigned short maxStackSize,
const BlockModel& model,
const BlockModel& farModel,
bool solid,
glm::ivec3 lightSource,
bool lightPropagates,
const std::vector<SelectionBox>& sBoxes,
const std::vector<SelectionBox>& cBoxes,
unsigned int index = 0
);
BlockDef(): ItemDef {"", "", 0, 0, ItemDef::Type::BLOCK} {};
void createModel();
bool hasInteraction();
BlockModel model;
BlockModel farModel;
bool culls = false;
bool solid = false;
bool culls = true;
bool solid = true;
bool lightPropagates = false;
glm::ivec3 lightSource;
int health = 0;
int defense = 0;
std::vector<SelectionBox> sBoxes;
std::vector<SelectionBox> cBoxes;
glm::ivec3 lightSource {};
std::vector<SelectionBox> sBoxes {};
std::vector<SelectionBox> cBoxes {};
std::unordered_map<Callback, sol::function, Util::EnumClassHash> callbacks {};
};

View File

@ -36,8 +36,8 @@ public:
if (std::abs(vec.y - a.y) < THRESH && vec.x > a.x && vec.x < b.x && vec.z > a.z && vec.z < b.z) return EVec::BOTTOM;
if (std::abs(vec.z - a.z) < THRESH && vec.x > a.x && vec.x < b.x && vec.y > a.y && vec.y < b.y) return EVec::FRONT;
if (std::abs(vec.z - b.z) < THRESH && vec.x > a.x && vec.x < b.x && vec.y > a.y && vec.y < b.y) return EVec::BACK;
if (std::abs(vec.x - b.x) < THRESH && vec.z > a.z && vec.z < b.z && vec.y > a.y && vec.y < b.y) return EVec::LEFT;
if (std::abs(vec.x - a.x) < THRESH && vec.z > a.z && vec.z < b.z && vec.y > a.y && vec.y < b.y) return EVec::RIGHT;
if (std::abs(vec.x - b.x) < THRESH && vec.z > a.z && vec.z < b.z && vec.y > a.y && vec.y < b.y) return EVec::RIGHT;
if (std::abs(vec.x - a.x) < THRESH && vec.z > a.z && vec.z < b.z && vec.y > a.y && vec.y < b.y) return EVec::LEFT;
return EVec::NONE;
}

View File

@ -10,9 +10,9 @@
#include "../scene/world/LocalWorld.h"
Collidable::Collidable(LocalWorld &world, ClientGame& defs, const SelectionBox& collisionBox) :
world(world),
defs(defs),
collisionBox(collisionBox) {}
world(world),
game(defs),
collisionBox(collisionBox) {}
void Collidable::moveCollide(float stepUpAmount) {
const static double increment = 0.05;
@ -67,7 +67,7 @@ bool Collidable::collidesAt(glm::vec3& pos, float stepUpMax) {
offset.z = collisionBox.a.z;
while (true) {
glm::vec3 offsetPos = glm::floor(pos + offset);
auto &def = defs.defs.blockFromId(world.getBlock(offsetPos));
auto &def = game.defs.blockFromId(world.getBlock(offsetPos));
if (def.solid)
for (auto &cBox : def.cBoxes)
@ -99,7 +99,7 @@ bool Collidable::collidesAt(glm::vec3& pos, float stepUpMax) {
offset.z = collisionBox.a.z;
while (true) {
glm::vec3 offsetPos = glm::floor(pos + offset);
auto& def = defs.defs.blockFromId(world.getBlock(offsetPos));
auto& def = game.defs.blockFromId(world.getBlock(offsetPos));
if (def.solid) {
for (auto &cBox : def.cBoxes) {

View File

@ -22,7 +22,7 @@ public:
glm::vec3 vel {};
protected:
LocalWorld& world;
ClientGame& defs;
ClientGame& game;
SelectionBox collisionBox {};
private:
bool collidesAt(glm::vec3& pos, float stepUpMax = 0);

View File

@ -12,36 +12,40 @@
#include "../../../def/texture/AtlasRef.h"
#include "../../../def/item/BlockModelVertex.h"
BlockCrackEntity::BlockCrackEntity(ClientGame &defs, glm::vec3 blockPos, unsigned int blockID) :
defs(defs),
blockPos(blockPos),
blockID(blockID) {
setPos(blockPos);
BlockCrackEntity::BlockCrackEntity(BlockDef &def, TextureAtlas& textureAtlas, glm::ivec3 pos) :
def(def),
textureAtlas(textureAtlas) {
maxHealth = def.health;
setPos(pos);
update();
}
void BlockCrackEntity::update() {
if (targetDamage > damage) damage = static_cast<float>(fmin(targetDamage, damage + 0.2));
else if (targetDamage < damage) damage = static_cast<float>(fmax(targetDamage, damage - 0.2));
// if (damagePending > 0) {
// double amt = std::min(damagePending, 0.2);
// damage += amt;
// damagePending -= amt;
// }
// else if (damagePending < 0) {
// double amt = std::max(damagePending, -0.2);
// damage += amt;
// damagePending -= amt;
// }
damage += damagePending;
damagePending = 0;
auto crackLevel = static_cast<unsigned short>(std::max(std::min(static_cast<int>(std::floor(damage * 8)), 7), 0));
auto crackLevel = static_cast<unsigned short>(std::max(std::min(static_cast<int>(std::floor((damage / static_cast<float>(maxHealth)) * 8)), 7), 0));
if (crackLevel != this->crackLevel) {
this->crackLevel = crackLevel;
auto model = defs.defs.blockFromId(blockID).model;
std::vector<EntityVertex> vertices;
std::vector<unsigned int> indices;
unsigned int indOffset = 0;
crackedFaces.clear();
for (int i = 0; i < 7; i++) {
addFaces(indOffset, vertices, indices, model.parts[i]);
}
for (int i = 0; i < 7; i++) addFaces(indOffset, vertices, indices, def.model.parts[i]);
std::unique_ptr<EntityMesh> mesh = std::make_unique<EntityMesh>();
mesh->create(vertices, indices);
@ -49,16 +53,17 @@ void BlockCrackEntity::update() {
}
}
void BlockCrackEntity::setNewDamage(float damage) {
this->targetDamage = damage;
void BlockCrackEntity::addDamage(double damage) {
damagePending += damage;
update();
}
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;
auto ref = defs.textures.generateCrackImage(mp.texture->name, static_cast<unsigned short>(crackLevel));
auto ref = textureAtlas.generateCrackImage(mp.texture->name, static_cast<unsigned short>(crackLevel));
if (ref == nullptr) {
uv = defs.textures["_missing"]->uv;
uv = textureAtlas["_missing"]->uv;
}
else uv = ref->uv;
@ -69,19 +74,10 @@ void BlockCrackEntity::addFaces(unsigned int &indOffset, std::vector<EntityVerte
pushed_pos += glm::normalize(vertex.nml) * 0.003f;
glm::vec4 tex = {uv.x + (uv.z - uv.x) * vertex.texUVs.x, uv.y + ((uv.w - uv.y) * vertex.texUVs.y), 0, 1};
vertices.push_back({
pushed_pos,
tex,
{1, 1, 1},
true,
vertex.nml,
{}, {}
});
vertices.push_back({ pushed_pos, tex, {1, 1, 1}, true, vertex.nml, {}, {} });
}
for (unsigned int index : mp.indices) {
indices.push_back(indOffset + index);
}
for (unsigned int index : mp.indices) indices.push_back(indOffset + index);
indOffset += mp.vertices.size();
}

View File

@ -6,28 +6,30 @@
#include "../Entity.h"
class ClientGame;
class EntityVertex;
class BlockDef;
class AtlasRef;
class MeshPart;
class EntityVertex;
class TextureAtlas;
class BlockCrackEntity : public Entity {
public:
explicit BlockCrackEntity(ClientGame &defs, glm::vec3 blockPos, unsigned int blockID);
BlockCrackEntity(BlockDef &def, TextureAtlas& textureAtlas, glm::ivec3 pos);
void update();
void setNewDamage(float damage);
void addDamage(double damage);
int maxHealth = 0;
double damage = 0;
double damagePending = 0;
glm::vec3 blockPos;
unsigned int blockID;
float targetDamage = 0;
float damage = 0;
double time = 0;
BlockDef& def;
private:
short crackLevel = -1;
void addFaces(unsigned int &indOffset, std::vector<EntityVertex> &vertices, std::vector<unsigned int> &indices, std::vector<MeshPart> &meshParts);
short crackLevel = -1;
TextureAtlas& textureAtlas;
std::vector<std::shared_ptr<AtlasRef>> crackedFaces;
ClientGame& defs;
};

View File

@ -18,7 +18,7 @@ GameGui::GameGui(LocalInventoryRefs& refs, glm::vec2 bufferSize, ClientGame& def
hudRoot->add(hudLuaRoot);
menuRoot->add(menuLuaRoot);
handList->create({3, 3}, {}, {}, refs.getHand(), refs.getHand(), defs);
handList->create({3, 3}, {}, {}, refs.getCursorList(), refs.getCursorList(), defs);
menuRoot->add(handList);
}

View File

@ -33,18 +33,18 @@ std::shared_ptr<GuiInventoryList> GuiInventoryList::fromSerialized(const LuaGuiE
auto inv = std::make_shared<GuiInventoryList>(elem.key);
inv->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding * SerialGui::SCALE_MODIFIER,
slotspc * SerialGui::SCALE_MODIFIER, invList, refs.getHand(), game, start, length);
slotspc * SerialGui::SCALE_MODIFIER, invList, refs.getCursorList(), game, start, length);
inv->setPos(pos);
return inv;
}
void GuiInventoryList::create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding,
std::shared_ptr<LocalInventoryList> list, std::shared_ptr<LocalInventoryList> hand, ClientGame& defs,
std::shared_ptr<LocalInventoryList> list, std::shared_ptr<LocalInventoryList> cursor, ClientGame& defs,
unsigned short start, unsigned short length) {
this->list = list;
this->hand = hand;
this->cursor = cursor;
this->defs = &defs;
this->start = start;
@ -107,7 +107,7 @@ void GuiInventoryList::leftClick(bool down, glm::ivec2 pos) {
if (index >= list->getLength()) return;
list->primaryInteract(*hand, index);
list->primaryInteract(*cursor, index);
}
void GuiInventoryList::rightClick(bool down, glm::ivec2 pos) {
@ -122,7 +122,7 @@ void GuiInventoryList::rightClick(bool down, glm::ivec2 pos) {
unsigned short index = slot.x + slot.y * list->getWidth();
if (index >= list->getLength()) return;
list->secondaryInteract(*hand, index);
list->secondaryInteract(*cursor, index);
}
void GuiInventoryList::drawContents() {

View File

@ -22,8 +22,8 @@ public:
glm::ivec2 bounds, LocalInventoryRefs& refs);
void create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding,
std::shared_ptr<LocalInventoryList> list, std::shared_ptr<LocalInventoryList> hand, ClientGame& defs,
unsigned short start = 0, unsigned short length = 0);
std::shared_ptr<LocalInventoryList> list, std::shared_ptr<LocalInventoryList> cursor, ClientGame& defs,
unsigned short start = 0, unsigned short length = 0);
void setCallback(CallbackType type, const callback& cb) override;
@ -35,7 +35,7 @@ private:
std::shared_ptr<GuiRect> hoverRect = std::make_shared<GuiRect>("hover_rect");
std::shared_ptr<std::function<void()>> myCallback = nullptr;
std::shared_ptr<LocalInventoryList> list, hand;
std::shared_ptr<LocalInventoryList> list, cursor;
unsigned short start, length;
glm::ivec2 innerPadding;
ClientGame* defs = nullptr;

View File

@ -24,4 +24,12 @@ std::shared_ptr<ServerInventoryList> Inventory::operator[](std::string name) {
void Inventory::removeList(std::string name) {
lists.erase(name);
}
}
void Inventory::setDefaultList(const std::string &name) {
defaultList = name;
}
std::string Inventory::getDefaultList() {
return defaultList;
}

View File

@ -21,9 +21,13 @@ public:
std::shared_ptr<ServerInventoryList> operator[](std::string name);
void removeList(std::string name);
void setDefaultList(const std::string& name);
std::string getDefaultList();
DefinitionAtlas& defs;
std::string name;
private:
ClientList* clients;
std::map<std::string, std::shared_ptr<ServerInventoryList>> lists;
std::string defaultList = "";
};

View File

@ -26,10 +26,18 @@ void InventoryList::initialize() {
for (unsigned int i = 0; i < itemstacks.size(); i++) itemstacks[i] = {};
}
void InventoryList::setLength(unsigned short length) {
itemstacks.resize(length);
}
unsigned short InventoryList::getLength() const {
return itemstacks.size();
}
void InventoryList::setWidth(unsigned short width) {
this->width = width;
}
unsigned short InventoryList::getWidth() const {
return width;
}
@ -223,14 +231,14 @@ ItemStack InventoryList::removeStack(unsigned short ind, unsigned short count) {
}
}
void InventoryList::primaryInteract(InventoryList& hand, unsigned short ind) {
hand.setStack(0, placeStack(ind, hand.getStack(0), true));
void InventoryList::primaryInteract(InventoryList& cursor, unsigned short ind) {
cursor.setStack(0, placeStack(ind, cursor.getStack(0), true));
}
void InventoryList::secondaryInteract(InventoryList &hand, unsigned short ind) {
auto handStack = hand.getStack(0);
void InventoryList::secondaryInteract(InventoryList &cursor, unsigned short ind) {
auto handStack = cursor.getStack(0);
if (handStack.count == 0) {
hand.setStack(0, splitStack(ind, true));
cursor.setStack(0, splitStack(ind, true));
}
else {
auto listStack = getStack(ind);
@ -239,10 +247,10 @@ void InventoryList::secondaryInteract(InventoryList &hand, unsigned short ind) {
handStack.count -= 1;
if (handStack.count == 0) handStack.id = 0;
if (overflow.count != 0) handStack.count += overflow.count;
hand.setStack(0, handStack);
cursor.setStack(0, handStack);
}
else {
hand.setStack(0, placeStack(ind, hand.getStack(0), true));
cursor.setStack(0, placeStack(ind, cursor.getStack(0), true));
}
}
}
@ -264,4 +272,4 @@ void InventoryList::setLuaCallback(InventoryList::Callback type, sol::function c
sol::function InventoryList::getLuaCallback(InventoryList::Callback type) {
return luaCallbacks[static_cast<size_t>(type)];
}
}

View File

@ -23,8 +23,12 @@ public:
InventoryList(DefinitionAtlas& defs);
InventoryList(DefinitionAtlas& defs, const std::string& invName, const std::string& listName, unsigned short size, unsigned short width);
void setLength(unsigned short length);
unsigned short getLength() const;
void setWidth(unsigned short width);
unsigned short getWidth() const;
std::string getName() const;
// Place the stack at i into the existing stack, returning overflow or other stack.
@ -41,9 +45,9 @@ public:
virtual ItemStack removeStack(unsigned short ind, unsigned short count);
// Primary interaction - The action performed when left clicking an inventory slot.
virtual void primaryInteract(InventoryList& hand, unsigned short ind);
virtual void primaryInteract(InventoryList& cursor, unsigned short ind);
// Secondary interaction - The action performed when right clicking an inventory slot.
virtual void secondaryInteract(InventoryList& hand, unsigned short ind);
virtual void secondaryInteract(InventoryList& cursor, unsigned short ind);
ItemStack getStack(unsigned short i) const;
void setStack(unsigned short i, const ItemStack& stack);

View File

@ -47,9 +47,9 @@ bool InventoryRefs::removeWatcher(const std::string &inv, const std::string &lis
}
void InventoryRefs::primaryInteract(const std::string &inv, const std::string &list, unsigned short ind, unsigned int cid) {
inventories[inv]->operator[](list)->primaryInteract(*inventories["player:" + std::to_string(cid)]->operator[]("hand"), ind);
(*inventories[inv])[list]->primaryInteract(*(*inventories["player:" + std::to_string(cid)])["cursor"], ind);
}
void InventoryRefs::secondaryInteract(const std::string &inv, const std::string &list, unsigned short ind, unsigned int cid) {
inventories[inv]->operator[](list)->secondaryInteract(*inventories["player:" + std::to_string(cid)]->operator[]("hand"), ind);
(*inventories[inv])[list]->secondaryInteract(*(*inventories["player:" + std::to_string(cid)])["cursor"], ind);
}

View File

@ -7,19 +7,28 @@
#include "LocalInventoryList.cpp"
#include "../../net/client/ClientNetworkInterpreter.h"
void LocalInventory::createList(std::string name, unsigned short length, unsigned short width, bool maintain) {
void LocalInventory::createList(const std::string& name, unsigned short length, unsigned short width, bool persistant) {
namespace ph = std::placeholders;
lists.insert({name, {(maintain ? -1 : 0),
lists.insert({name, {(persistant ? -1 : 0),
std::make_shared<LocalInventoryList>(defs, this->name, name, length, width,
std::bind(primaryCallback, this->name, name, ph::_1), std::bind(secondaryCallback, this->name, name, ph::_1))}});
}
void LocalInventory::removeList(const std::string &name) {
if (lists.count(name)) lists[name].first = 1;
}
std::shared_ptr<LocalInventoryList> LocalInventory::operator[](std::string name) {
if (lists.count(name)) return lists[name].second;
else return nullptr;
}
void LocalInventory::setPersistant(const std::string &list, bool persistant) {
if (!lists.count(name)) return;
lists[name].first = (persistant ? -1 : 0);
}
bool LocalInventory::pruneLists(ClientNetworkInterpreter &net, double time) {
for (auto lIt = lists.begin(); lIt != lists.end();) {
if (lIt->second.first != -1) {
@ -29,7 +38,7 @@ bool LocalInventory::pruneLists(ClientNetworkInterpreter &net, double time) {
else if (lIt->second.first != 0 && lIt->second.second.use_count() > 1) lIt->second.first = 0;
// Delete InventoryLists that have passed their timeout.
else if (lIt->second.first != 0 && lIt->second.first <= time) {
net.unwatchInv(name, lIt->first);
net.invUnwatch(name, lIt->first);
lIt = lists.erase(lIt);
}
else lIt++;

View File

@ -20,9 +20,11 @@ public:
inv_callback_fn primaryCallback, inv_callback_fn secondaryCallback) :
defs(defs), name(name), primaryCallback(primaryCallback), secondaryCallback(secondaryCallback) {};
void createList(std::string name, unsigned short length, unsigned short width, bool maintain = false);
void createList(const std::string& name, unsigned short length, unsigned short width, bool persistant = false);
void removeList(const std::string& name);
std::shared_ptr<LocalInventoryList> operator[](std::string name);
void setPersistant(const std::string& list, bool persistant);
bool pruneLists(ClientNetworkInterpreter& net, double time);
DefinitionAtlas& defs;

View File

@ -2,6 +2,8 @@
// Created by aurailus on 2020-02-24.
//
#include <iostream>
#include "LocalInventoryRefs.h"
#include "LocalInventory.h"
@ -13,12 +15,17 @@
LocalInventoryRefs::LocalInventoryRefs(LocalDefinitionAtlas& defs, ClientNetworkInterpreter& net) : defs(defs) {
namespace ph = std::placeholders;
this->watchFn = std::bind(&ClientNetworkInterpreter::watchInv, &net, ph::_1, ph::_2);
this->primaryCallback = std::bind(&ClientNetworkInterpreter::primaryInteract, &net, ph::_1, ph::_2, ph::_3);
this->secondaryCallback = std::bind(&ClientNetworkInterpreter::secondaryInteract, &net, ph::_1, ph::_2, ph::_3);
this->watchFn = std::bind(&ClientNetworkInterpreter::invWatch, &net, ph::_1, ph::_2);
this->unWatchFn = std::bind(&ClientNetworkInterpreter::invUnwatch, &net, ph::_1, ph::_2);
this->primaryCallback = std::bind(&ClientNetworkInterpreter::invInteractPrimary, &net, ph::_1, ph::_2, ph::_3);
this->secondaryCallback = std::bind(&ClientNetworkInterpreter::invInteractSecondary, &net, ph::_1, ph::_2, ph::_3);
inventories.insert({"current_player", std::make_shared<LocalInventory>(defs, "current_player", primaryCallback, secondaryCallback)});
inventories["current_player"]->createList("hand", 1, 1, true);
inventories["current_player"]->createList("cursor", 1, 1, true);
}
void LocalInventoryRefs::init() {
watch("current_player", "cursor");
}
void LocalInventoryRefs::update(double delta, ClientNetworkInterpreter& net) {
@ -30,23 +37,6 @@ void LocalInventoryRefs::update(double delta, ClientNetworkInterpreter& net) {
}
}
std::shared_ptr<LocalInventory> LocalInventoryRefs::getInv(const std::string& inv) {
return inventories[inv];
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getList(const std::string& inv, const std::string& list) {
if (!inventories.count(inv)) inventories.insert({inv, {}});
if (inventories[inv]->operator[](list) == nullptr) {
inventories[inv]->createList(list, 0, 0);
watchFn(inv, list);
}
return inventories[inv]->operator[](list);
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getHand() {
return inventories["current_player"]->operator[]("hand");
}
void LocalInventoryRefs::packetReceived(std::unique_ptr<PacketView> p) {
std::string source = p->d.read<std::string>();
std::string list = p->d.read<std::string>();
@ -68,4 +58,52 @@ void LocalInventoryRefs::packetReceived(std::unique_ptr<PacketView> p) {
}
inventories[source]->operator[](list)->setData(size, width, stacks);
}
}
void LocalInventoryRefs::watch(const std::string &inv, const std::string &list, bool persistant) {
if (!inventories.count(inv)) inventories.insert({inv, {}});
if ((*inventories[inv])[list] == nullptr) {
inventories[inv]->createList(list, 0, 0, persistant);
watchFn(inv, list);
}
else (*inventories[inv]).setPersistant(list, persistant);
}
void LocalInventoryRefs::unWatch(const std::string &inv, const std::string &list) {
if (inventories.count(inv) && (*inventories[inv])[list] != nullptr) (*inventories[inv]).removeList(list);
}
std::shared_ptr<LocalInventory> LocalInventoryRefs::getInv(const std::string& inv) {
return inventories[inv];
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getList(const std::string& inv, const std::string& list) {
watch(inv, list);
return inventories[inv]->operator[](list);
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getHandList() {
return handList == "" ? nullptr : (*inventories["current_player"])[handList];
}
void LocalInventoryRefs::setHandList(const std::string &list) {
if (list == handList) return;
if (handList != "") unWatch("current_player", handList);
handList = list;
if (handList != "") watch("current_player", handList, true);
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getWieldList() {
return wieldList == "" ? nullptr : (*inventories["current_player"])[wieldList];
}
void LocalInventoryRefs::setWieldList(const std::string &list){
if (list == wieldList) return;
if (wieldList != "") unWatch("current_player", wieldList);
wieldList = list;
if (wieldList != "") watch("current_player", wieldList, true);
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getCursorList() {
return inventories["current_player"]->operator[]("cursor");
}

View File

@ -19,20 +19,33 @@ public:
typedef std::function<void(const std::string& inv, const std::string& list, unsigned short)> inv_callback_fn;
LocalInventoryRefs(LocalDefinitionAtlas& defs, ClientNetworkInterpreter& net);
void init();
void update(double delta, ClientNetworkInterpreter& net);
void packetReceived(std::unique_ptr<PacketView> p);
void watch(const std::string& inv, const std::string& list, bool persistant = false);
void unWatch(const std::string& inv, const std::string& list);
std::shared_ptr<LocalInventory> getInv(const std::string& inv);
std::shared_ptr<LocalInventoryList> getList(const std::string& inv, const std::string& list);
std::shared_ptr<LocalInventoryList> getHand();
std::shared_ptr<LocalInventoryList> getHandList();
void setHandList(const std::string& list);
std::shared_ptr<LocalInventoryList> getWieldList();
void setWieldList(const std::string& list);
std::shared_ptr<LocalInventoryList> getCursorList();
private:
std::unordered_map<std::string, std::shared_ptr<LocalInventory>> inventories {};
std::function<void(std::string, std::string)> watchFn = nullptr;
inv_callback_fn primaryCallback = nullptr;
inv_callback_fn secondaryCallback = nullptr;
std::function<void(std::string, std::string)> watchFn = nullptr;
std::function<void(std::string, std::string)> unWatchFn = nullptr;
std::string handList = "";
std::string wieldList = "";
LocalDefinitionAtlas& defs;
double time = 0;

View File

@ -2,6 +2,8 @@
// Created by aurailus on 2019-10-29.
//
#include <iostream>
#include "ServerInventoryList.h"
#include "../../net/Packet.h"
@ -57,8 +59,7 @@ Packet ServerInventoryList::createPacket() {
void ServerInventoryList::sendTo(std::shared_ptr<ServerClient> client) {
if (!client) return;
auto p = createPacket();
p.sendTo(client->peer, PacketChannel::INVENTORY);
createPacket().sendTo(client->peer, PacketChannel::INVENTORY);
}
void ServerInventoryList::sendAll() {

View File

@ -23,8 +23,9 @@ 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));
game.init(world, player, state);
net .init(&world, std::bind(&LocalInventoryRefs::packetReceived, refs, ph::_1));
game .init(world, player, state);
refs .init();
state.renderer.window.addResizeCallback("gamescene", std::bind(&DebugGui::bufferResized, debugGui, ph::_1));
state.renderer.setClearColor(148, 194, 240);

View File

@ -12,6 +12,7 @@
#include "../../../net/client/ClientNetworkInterpreter.h"
#include "../../entity/engine/ParticleEntity.h"
#include "../../entity/engine/BlockCrackEntity.h"
#include "../../../lua/api/class/LocalLuaPlayer.h"
LocalWorld::LocalWorld(ClientGame& defs, ClientNetworkInterpreter* server) :
defs(defs),
@ -57,46 +58,63 @@ void LocalWorld::setBlock(glm::ivec3 pos, unsigned int block) {
dimension.setBlock(pos, block);
}
void LocalWorld::localSetBlock(glm::ivec3 pos, unsigned int 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)) {
if (def.callbacks.count(Callback::BREAK_CLIENT))
defs.parser.safe_function(def.callbacks[Callback::BREAK_CLIENT], defs.parser.luaVec(pos));
}
}
else {
auto def = defs.defs.blockFromId(block);
if (def.callbacks.count(Callback::PLACE_CLIENT)) {
if (def.callbacks.count(Callback::PLACE_CLIENT))
defs.parser.safe_function(def.callbacks[Callback::PLACE_CLIENT], defs.parser.luaVec(pos));
}
}
net->setBlock(pos, block);
net->blockPlace(pos, block);
dimension.setBlock(pos, block);
}
void LocalWorld::damageBlock(glm::vec3 pos, float amount) {
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.parser.safe_function(def.callbacks[Callback::INTERACT_CLIENT], defs.parser.luaVec(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.parser.safe_function(defs.parser.core["get_hit_impact"],
defs.parser.core.get<LocalLuaPlayer>("player"), blockDef.identifier);
if (damage == 0) return timeout;
BlockCrackEntity* block = nullptr;
for (auto test : crackedBlocks) {
if (test->blockPos == pos) {
block = test;
break;
}
}
for (auto test : crackedBlocks) if (glm::ivec3(test->getPos()) == pos) { block = test; break; }
if (block == nullptr) {
auto blockID = getBlock(pos);
block = new BlockCrackEntity(defs, pos, blockID);
block = new BlockCrackEntity(blockDef, defs.textures, pos);
crackedBlocks.push_back(block);
}
block->setNewDamage(block->targetDamage + amount);
block->addDamage(damage);
block->time = 0;
auto def = defs.defs.blockFromId(getBlock(pos));
for (int i = 0; i < 40 * amount; i++) {
auto p = new ParticleEntity(pos, def);
particles.push_back(p);
}
// 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 timeout;
}
unsigned short LocalWorld::getBiome(glm::vec3 pos) {
@ -138,18 +156,18 @@ void LocalWorld::updateBlockDamages(double delta) {
block->time += delta;
if (block->damage >= 1) {
localSetBlock(block->blockPos, DefinitionAtlas::AIR);
if (block->damage >= block->maxHealth) {
blockBreak(block->getPos());
deleteMe = true;
}
if (block->time > 2) {
block->update();
block->setNewDamage(block->targetDamage - 0.1f);
block->addDamage(-1);
block->time = 0;
}
if (block->damage < 0 || block->blockID != getBlock(block->blockPos)) {
if (block->damage < 0 || block->def.index != getBlock(block->getPos())) {
deleteMe = true;
}
@ -157,9 +175,7 @@ void LocalWorld::updateBlockDamages(double delta) {
delete *curr;
it = crackedBlocks.erase(curr);
}
else {
block->update();
}
else block->update();
}
}

View File

@ -12,6 +12,7 @@ class ClientNetworkInterpreter;
class WorldInterpolationStream;
class BlockCrackEntity;
class ParticleEntity;
class PointedThing;
class ClientGame;
class Renderer;
class Player;
@ -28,9 +29,12 @@ public:
unsigned int getBlock(glm::ivec3 pos) override;
void setBlock(glm::ivec3 pos, unsigned int block) override;
void localSetBlock(glm::ivec3 pos, unsigned int block);
void damageBlock(glm::vec3 pos, float amount);
void blockPlace(glm::vec3 pos, unsigned int block);
void blockBreak(glm::vec3 pos);
void blockInteract(PointedThing& thing);
double blockHit(PointedThing& thing);
unsigned short getBiome(glm::vec3 pos);
std::shared_ptr<Chunk> getChunk(glm::ivec3 pos);

View File

@ -49,7 +49,7 @@ std::vector<ChunkMeshDetails*> MeshGenStream::update() {
if (!queuedTasks.empty()) {
auto pos = queuedTasks.front();
queuedMap.erase(pos);
queuedTasks.pop();
queuedTasks.pop_front();
std::shared_ptr<Chunk> chunk = dimension.getChunk(pos);
if (chunk == nullptr) goto breakAddTask;
@ -95,9 +95,9 @@ void MeshGenStream::Thread::exec() {
}
}
void MeshGenStream::queue(glm::ivec3 pos) {
void MeshGenStream::queue(glm::ivec3 pos, bool priority) {
if (!queuedMap.count(pos)) {
queuedTasks.push(pos);
priority ? queuedTasks.push_front(pos) : queuedTasks.push_back(pos);
queuedMap.insert(pos);
}
}
@ -107,4 +107,4 @@ MeshGenStream::~MeshGenStream() {
t.keepAlive = false;
t.thread.join();
}
}
}

View File

@ -26,7 +26,7 @@ public:
explicit MeshGenStream(ClientGame& game, LocalDimension& dimension);
~MeshGenStream();
void queue(glm::ivec3 pos);
void queue(glm::ivec3 pos, bool priority = false);
//Will return a vector of MeshDetails pointers containing finished meshes.
//Frees up the threads and starts new tasks.
@ -60,7 +60,7 @@ private:
ClientGame& game;
std::array<NoiseSample, 3> noiseSampler;
std::queue<glm::ivec3> queuedTasks;
std::deque<glm::ivec3> queuedTasks;
std::unordered_set<glm::vec3, Vec::vec3> queuedMap;
};

View File

@ -8,8 +8,13 @@
#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 "../../inventory/LocalInventoryList.h"
#include "../../../net/client/NetPlayerField.h"
Player::Player(LocalWorld& world, ClientGame& defs, Renderer& renderer, LocalInventoryRefs& refs) :
Collidable(world, defs, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
@ -33,7 +38,8 @@ void Player::update(Input &input, double delta, glm::vec2 mouseDelta) {
moveAndLook(input, delta, mouseDelta);
findPointedThing(input);
updateWireframe();
breakBlock(input, delta);
if (!gameGui.isInMenu()) interact(input, delta);
}
void Player::moveAndLook(Input &input, double delta, glm::vec2 mouseDelta) {
@ -109,7 +115,7 @@ void Player::updateCamera() {
renderer.camera.setYaw(yaw);
renderer.camera.setPitch(pitch);
auto type = game.defs.fromId(activeBlock).type;
auto type = game.defs.fromId(wieldItem).type;
glm::vec3 eyesPos = {pos.x, pos.y + EYE_HEIGHT, pos.z};
renderer.camera.setPos(eyesPos);
@ -197,72 +203,80 @@ void Player::updateWireframe() {
}
}
void Player::breakBlock(Input& input, double delta) {
void Player::interact(Input& input, double delta) {
if (pointedThing.thing == PointedThing::Thing::BLOCK) {
if (input.mouseDown(GLFW_MOUSE_BUTTON_LEFT)) {
if (breakInterval == 0) {
world.damageBlock(pointedThing.target.block.pos, BLOCK_DAMAGE);
}
breakInterval += delta;
if (breakInterval > BLOCK_INTERVAL) breakInterval = 0;
}
else {
if (breakInterval > 0) breakInterval += delta;
if (breakInterval > BLOCK_INTERVAL) breakInterval = 0;
if (input.mouseDown(GLFW_MOUSE_BUTTON_LEFT) && breakTime == 0) {
breakInterval = world.blockHit(pointedThing);
breakTime += delta;
}
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) {
auto& target = game.defs.blockFromId(world.getBlock(pointedThing.target.block.pos));
if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT) && activeBlock != DefinitionAtlas::AIR) {
world.localSetBlock(pointedThing.target.block.pos + SelectionBox::faceToOffset(pointedThing.target.block.face), activeBlock);
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 breakInterval = 0;
if (breakTime > 0) breakTime += delta;
if (breakTime > breakInterval) breakTime = 0;
}
/*
* Position, Velocity, Yaw, Pitch Getters & Setters
*/
void Player::setPos(glm::vec3 pos) {
this->pos = pos;
this->renderer.camera.setPos({pos.x, pos.y + EYE_HEIGHT, pos.z});
}
//
// Getters and Setters
//
glm::vec3 Player::getPos() {
return pos;
}
void Player::setVel(glm::vec3 vel) {
this->vel = vel;
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);
}
glm::vec3 Player::getVel() {
return vel;
}
void Player::setYaw(float yaw) {
this->yaw = yaw;
void Player::setVel(glm::vec3 vel, bool assert) {
this->vel = vel;
if (assert) assertField(NetPlayerField::VELOCITY, vel);
}
float Player::getYaw() {
return yaw;
}
void Player::setPitch(float pitch) {
this->pitch = pitch;
void Player::setYaw(float yaw, bool assert) {
this->yaw = yaw;
if (assert) assertField(NetPlayerField::YAW, yaw);
}
float Player::getPitch() {
return pitch;
}
void Player::setFlying(bool flying) {
this->flying = flying;
void Player::setPitch(float pitch, bool assert) {
this->pitch = pitch;
if (assert) assertField(NetPlayerField::PITCH, pitch);
}
bool Player::isFlying() {
return flying;
}
void Player::setFlying(bool flying, bool assert) {
this->flying = flying;
if (assert) assertField(NetPlayerField::FLYING, flying);
}
PointedThing& Player::getPointedThing() {
return pointedThing;
}
@ -271,15 +285,41 @@ LocalInventory& Player::getInventory() {
return *refs.getInv("current_player");
}
std::shared_ptr<LocalInventoryList> Player::getHandList() {
return refs.getHandList();
}
void Player::setHandList(const std::string& list) {
refs.setHandList(list);
updateWieldAndHandItems();
}
std::shared_ptr<LocalInventoryList> Player::getWieldList() {
return refs.getWieldList();
}
void Player::setWieldList(const std::string& list, bool assert) {
refs.setWieldList(list);
setWieldIndex(wieldIndex);
updateWieldAndHandItems();
if (assert) assertField(NetPlayerField::WIELD_INV, list);
}
unsigned short Player::getWieldIndex() {
return wieldIndex;
}
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));
}
/*
* GUI Functions
*/
void Player::setActiveBlock(const std::string& block) {
activeBlock = game.defs.fromStr(block).index;
handItemModel.setModel(game.defs.fromId(activeBlock).entityModel);
}
void Player::showMenu(std::shared_ptr<LuaGuiElement> root) {
gameGui.showMenu(root);
renderer.window.input.lockMouse(false);
@ -324,6 +364,42 @@ void Player::drawMenu(Renderer &renderer) {
gameGui.drawMenu(renderer);
}
void Player::updateWieldAndHandItems() {
auto handList = refs.getHandList();
auto wieldList = refs.getWieldList();
handItem = handList && handList->getLength() > 0 ? handList->getStack(0).id : 0;
wieldItem = wieldList && wieldList->getLength() > wieldIndex ? wieldList->getStack(wieldIndex).id : 0;
auto& model = game.defs.fromId(wieldItem <= DefinitionAtlas::AIR ? handItem : wieldItem).entityModel;
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>())) {
case NetPlayerField::ID: id = d.read<unsigned int>(); break;
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;
}
}
}
Player::~Player() {
renderer.window.removeResizeCallback("player");
}

View File

@ -15,6 +15,8 @@ class Input;
class LuaGuiElement;
class LocalInventory;
class LocalInventoryRefs;
class Deserializer;
enum class NetPlayerField;
class Player : Collidable, public Drawable {
public:
@ -24,67 +26,84 @@ public:
static constexpr float EYE_HEIGHT = 1.65f;
static constexpr float BASE_MOVE_SPEED = 4.3f;
static constexpr float JUMP_VEL = 0.14f;
static constexpr float BLOCK_DAMAGE = 0.36f;
static constexpr float BLOCK_INTERVAL = 0.02f;
Player(LocalWorld& world, ClientGame& defs, Renderer& renderer, LocalInventoryRefs& refs);
void update(Input &input, double delta, glm::vec2 mouseDelta);
~Player();
void setPos(glm::vec3 pos);
glm::vec3 getPos();
void setPos(glm::vec3 pos, bool assert = false);
void setVel(glm::vec3 vel);
glm::vec3 getVel();
void setVel(glm::vec3 vel, bool assert = false);
void setYaw(float yaw);
float getYaw();
void setYaw(float yaw, bool assert = false);
void setPitch(float pitch);
float getPitch();
void setPitch(float pitch, bool assert = false);
void setFlying(bool flying);
bool isFlying();
void setFlying(bool flying, bool assert = false);
void setActiveBlock(const std::string& block);
LocalInventory& getInventory();
std::shared_ptr<LocalInventoryList> getHandList();
void setHandList(const std::string& list);
std::shared_ptr<LocalInventoryList> getWieldList();
void setWieldList(const std::string& list, bool assert = false);
unsigned short getWieldIndex();
void setWieldIndex(unsigned short index, bool assert = false);
bool isInMenu();
void showMenu(std::shared_ptr<LuaGuiElement> root);
void closeMenu();
bool isInMenu();
void setHud(std::shared_ptr<LuaGuiElement> hud);
std::shared_ptr<LuaGuiElement> getHud();
PointedThing& getPointedThing();
void setHudVisible(bool hudVisible);
void draw(Renderer& renderer) override;
void drawHud(Renderer& renderer);
void drawMenu(Renderer& renderer);
LocalInventory& getInventory();
PointedThing& getPointedThing();
void handleAssertion(Deserializer& d);
unsigned int id = 0;
private:
void moveAndLook(Input &input, double delta, glm::vec2 mouseDelta);
void updateCamera();
void findPointedThing(Input &input);
void updateWireframe();
void breakBlock(Input& input, double delta);
void interact(Input& input, double delta);
void updateWieldAndHandItems();
template <typename T> void assertField(NetPlayerField field, T data);
ClientGame& game;
Renderer& renderer;
LocalInventoryRefs& refs;
GameGui gameGui;
Entity handModel;
Entity handItemModel;
WireframeEntity wireframe;
LocalInventoryRefs& refs;
unsigned int wieldIndex = 0;
unsigned int handItem = DefinitionAtlas::AIR;
unsigned int wieldItem = DefinitionAtlas::AIR;
float yaw = 0;
float pitch = 0;
bool flying = false;
unsigned int activeBlock = DefinitionAtlas::AIR;
PointedThing pointedThing;
double breakTime = 0;
double breakInterval = 0;
PointedThing pointedThing;
};

View File

@ -23,9 +23,9 @@ enum class Callback {
AFTER_BREAK,
AFTER_BREAK_CLIENT,
// INTERACT,
// INTERACT_CLIENT,
//
// HIT,
// HIT_CLIENT
INTERACT,
INTERACT_CLIENT,
HIT,
HIT_CLIENT
};

View File

@ -7,7 +7,7 @@
#include "LocalLuaInventoryList.h"
sol::object LocalLuaInventory::get_list(sol::this_state s, std::string name) {
auto inv = inventory[name];
if (!inv) return sol::nil;
return sol::make_object<LocalLuaInventoryList>(s, LocalLuaInventoryList(*inv));
auto list = inventory[name];
if (!list) return sol::nil;
return sol::make_object<LocalLuaInventoryList>(s, LocalLuaInventoryList(*list));
}

View File

@ -21,26 +21,32 @@ std::string LocalLuaInventoryList::get_name() {
}
LuaItemStack LocalLuaInventoryList::get_stack(unsigned short i) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.getStack(i - 1), list.defs);
}
void LocalLuaInventoryList::set_stack(unsigned short i, LuaItemStack stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
list.setStack(i - 1, ItemStack(stack, list.defs));
}
void LocalLuaInventoryList::set_stack(unsigned short i, sol::table stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
list.setStack(i - 1, ItemStack(list.defs.fromStr(stack[1]).index, stack.get<unsigned short>(2)));
}
LuaItemStack LocalLuaInventoryList::place_stack(unsigned short i, LuaItemStack stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.placeStack(i - 1, ItemStack(stack, list.defs)), list.defs);
}
LuaItemStack LocalLuaInventoryList::place_stack(unsigned short i, sol::table stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.placeStack(i - 1, ItemStack(list.defs.fromStr(stack[1]).index, stack.get<unsigned short>(2))), list.defs);
}
LuaItemStack LocalLuaInventoryList::split_stack(unsigned short i) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.splitStack(i - 1), list.defs);
}
@ -68,8 +74,9 @@ LuaItemStack LocalLuaInventoryList::take_stack(sol::table request) {
return LuaItemStack(list.takeStack(ItemStack(list.defs.fromStr(request[1]).index, request.get<unsigned short>(2))), list.defs);
}
LuaItemStack LocalLuaInventoryList::remove_stack(unsigned short ind, unsigned short count) {
return LuaItemStack(list.removeStack(ind - 1, count), list.defs);
LuaItemStack LocalLuaInventoryList::remove_stack(unsigned short i, unsigned short count) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.removeStack(i - 1, count), list.defs);
}
void LocalLuaInventoryList::set_callback(LocalInventoryList::Callback t, sol::function fun) {

View File

@ -6,13 +6,10 @@
#include "LocalLuaPlayer.h"
#include "../../LuaParser.h"
#include "LuaItemStack.h"
#include "LocalLuaInventoryList.h"
#include "../../../game/scene/world/Player.h"
void LocalLuaPlayer::set_pos(const sol::table &pos) {
player.setPos({pos[1], pos[2], pos[3]});
}
sol::table LocalLuaPlayer::get_pos(sol::this_state s) {
glm::vec3 pos = player.getPos();
return LuaParser::luaVec(sol::state_view(s), pos);
@ -23,8 +20,8 @@ sol::table LocalLuaPlayer::get_block_pos(sol::this_state s) {
return LuaParser::luaVec(sol::state_view(s), pos);
}
void LocalLuaPlayer::set_vel(const sol::table &vel) {
player.setVel({vel[1], vel[2], vel[3]});
void LocalLuaPlayer::set_pos(const sol::table &pos) {
player.setPos({pos[1], pos[2], pos[3]}, true);
}
sol::table LocalLuaPlayer::get_vel(sol::this_state s) {
@ -32,22 +29,26 @@ sol::table LocalLuaPlayer::get_vel(sol::this_state s) {
return LuaParser::luaVec(sol::state_view(s), vel);
}
void LocalLuaPlayer::set_look_yaw(float rot) {
player.setYaw(rot);
void LocalLuaPlayer::set_vel(const sol::table &vel) {
player.setVel({vel[1], vel[2], vel[3]}, true);
}
float LocalLuaPlayer::get_look_yaw() {
return player.getYaw();
}
void LocalLuaPlayer::set_look_pitch(float rot) {
player.setPitch(rot);
void LocalLuaPlayer::set_look_yaw(float rot) {
player.setYaw(rot, true);
}
float LocalLuaPlayer::get_look_pitch() {
return player.getPitch();
}
void LocalLuaPlayer::set_look_pitch(float rot) {
player.setPitch(rot, true);
}
bool LocalLuaPlayer::is_in_menu() {
return player.isInMenu();
}
@ -56,6 +57,10 @@ void LocalLuaPlayer::show_menu(std::shared_ptr<LuaGuiElement> root) {
player.showMenu(root);
}
void LocalLuaPlayer::close_menu() {
player.closeMenu();
}
std::shared_ptr<LuaGuiElement> LocalLuaPlayer::get_hud() {
return player.getHud();
}
@ -64,16 +69,47 @@ void LocalLuaPlayer::set_hud(std::shared_ptr<LuaGuiElement> hud) {
player.setHud(hud);
}
void LocalLuaPlayer::close_menu() {
player.closeMenu();
}
LocalLuaInventory LocalLuaPlayer::get_inventory() {
return LocalLuaInventory(player.getInventory());
}
void LocalLuaPlayer::set_selected_block(std::string block) {
player.setActiveBlock(block);
sol::object LocalLuaPlayer::get_hand_list(sol::this_state s) {
auto list = player.getHandList();
if (!list) return sol::nil;
return sol::make_object<LocalLuaInventoryList>(s, LocalLuaInventoryList(*list));
}
sol::object LocalLuaPlayer::get_hand_stack(sol::this_state s) {
auto list = player.getHandList();
if (!list) return sol::nil;
return sol::make_object<LuaItemStack>(s, LocalLuaInventoryList(*list).get_stack(1));
}
sol::object LocalLuaPlayer::get_wield_list(sol::this_state s) {
auto list = player.getWieldList();
if (!list) return sol::nil;
return sol::make_object<LocalLuaInventoryList>(s, LocalLuaInventoryList(*list));
}
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());
else throw "Attempted to set wield list to nil.";
}
unsigned int LocalLuaPlayer::get_wield_index() {
return player.getWieldIndex() + 1;
}
void LocalLuaPlayer::set_wield_index(unsigned int index) {
player.setWieldIndex(index - 1);
}
sol::object LocalLuaPlayer::get_wield_stack(sol::this_state s) {
auto list = player.getWieldList();
if (!list) return sol::nil;
return sol::make_object<LuaItemStack>(s, LocalLuaInventoryList(*list).get_stack(player.getWieldIndex() + 1));
}
void LocalLuaPlayer::set_flying(bool shouldFly) {
@ -82,4 +118,4 @@ void LocalLuaPlayer::set_flying(bool shouldFly) {
bool LocalLuaPlayer::get_flying() {
return player.isFlying();
}
}

View File

@ -17,29 +17,37 @@ public:
Player& player;
void set_pos(const sol::table& pos);
sol::table get_pos(sol::this_state s);
sol::table get_block_pos(sol::this_state s);
void set_pos(const sol::table& pos);
void set_vel(const sol::table& vel);
sol::table get_vel(sol::this_state s);
void set_vel(const sol::table& vel);
void set_look_yaw(float rot);
float get_look_yaw();
void set_look_yaw(float rot);
void set_look_pitch(float rot);
float get_look_pitch();
void set_look_pitch(float rot);
bool is_in_menu();
void show_menu(std::shared_ptr<LuaGuiElement> root);
void close_menu();
bool is_in_menu();
void set_hud(std::shared_ptr<LuaGuiElement> hud);
std::shared_ptr<LuaGuiElement> get_hud();
void set_hud(std::shared_ptr<LuaGuiElement> hud);
LocalLuaInventory get_inventory();
void set_selected_block(std::string block);
sol::object get_hand_list(sol::this_state s);
sol::object get_hand_stack(sol::this_state s);
sol::object get_wield_list(sol::this_state s);
sol::object get_wield_stack(sol::this_state s);
void set_wield_list(sol::optional<sol::object> list);
unsigned int get_wield_index();
void set_wield_index(unsigned int index);
void set_flying(bool shouldFly);
bool get_flying();
@ -48,18 +56,26 @@ public:
namespace ClientApi {
static void local_player(sol::state& lua) {
lua.new_usertype<LocalLuaPlayer>("LocalPlayer",
"set_pos", &LocalLuaPlayer::set_pos,
"is_player", sol::property([]() { return true; }),
"get_pos", &LocalLuaPlayer::get_pos,
"get_block_pos", &LocalLuaPlayer::get_block_pos,
"set_vel", &LocalLuaPlayer::set_vel,
"set_pos", &LocalLuaPlayer::set_pos,
"get_vel", &LocalLuaPlayer::get_vel,
"set_look_yaw", &LocalLuaPlayer::set_look_yaw,
"set_vel", &LocalLuaPlayer::set_vel,
"get_look_yaw", &LocalLuaPlayer::get_look_yaw,
"set_look_pitch", &LocalLuaPlayer::set_look_pitch,
"set_look_yaw", &LocalLuaPlayer::set_look_yaw,
"get_look_pitch", &LocalLuaPlayer::get_look_pitch,
"set_look_pitch", &LocalLuaPlayer::set_look_pitch,
"get_inventory", &LocalLuaPlayer::get_inventory,
"set_selected_block", &LocalLuaPlayer::set_selected_block,
"get_hand_list", &LocalLuaPlayer::get_hand_list,
"get_hand_stack", &LocalLuaPlayer::get_hand_stack,
"get_wield_list", &LocalLuaPlayer::get_wield_list,
"set_wield_list", &LocalLuaPlayer::set_wield_list,
"get_wield_index", &LocalLuaPlayer::get_wield_index,
"set_wield_index", &LocalLuaPlayer::set_wield_index,
"get_wield_stack", &LocalLuaPlayer::get_wield_stack,
"show_menu", &LocalLuaPlayer::show_menu,
"close_menu", &LocalLuaPlayer::close_menu,

View File

@ -12,11 +12,21 @@ sol::object ServerLuaInventory::add_list(sol::this_state s, std::string name, in
}
sol::object ServerLuaInventory::get_list(sol::this_state s, std::string name) {
auto inv = inventory[name];
if (!inv) return sol::nil;
return sol::make_object<ServerLuaInventoryList>(s, ServerLuaInventoryList(*inv));
auto list = inventory[name];
if (!list) return sol::nil;
return sol::make_object<ServerLuaInventoryList>(s, ServerLuaInventoryList(*list));
}
void ServerLuaInventory::remove_list(std::string name) {
inventory.removeList(name);
}
void ServerLuaInventory::set_default_list(sol::object list) {
if (list.is<std::string>()) inventory.setDefaultList(list.as<std::string>());
else inventory.setDefaultList(list.as<sol::table>().get<std::string>("name"));
}
sol::object ServerLuaInventory::get_default_list(sol::this_state s) {
if (inventory.getDefaultList() == "") return sol::nil;
else get_list(s, inventory.getDefaultList());
}

View File

@ -16,4 +16,7 @@ public:
sol::object add_list(sol::this_state s, std::string name, int size, int width);
sol::object get_list(sol::this_state s, std::string name);
void remove_list(std::string name);
void set_default_list(sol::object list);
sol::object get_default_list(sol::this_state s);
};

View File

@ -7,39 +7,58 @@
#include "../../../def/ItemDef.h"
#include "../../../def/DefinitionAtlas.h"
void ServerLuaInventoryList::set_length(int length) {
list.setLength(length);
}
int ServerLuaInventoryList::get_length() {
return list.getLength();
}
void ServerLuaInventoryList::set_width(int width) {
list.setWidth(width);
}
int ServerLuaInventoryList::get_width() {
return list.getWidth();
}
void ServerLuaInventoryList::resize(int length, int width) {
list.setLength(length);
list.setWidth(width);
}
std::string ServerLuaInventoryList::get_name() {
return list.getName();
}
LuaItemStack ServerLuaInventoryList::get_stack(unsigned short i) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.getStack(i - 1), list.defs);
}
void ServerLuaInventoryList::set_stack(unsigned short i, LuaItemStack stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
list.setStack(i - 1, ItemStack(stack, list.defs));
}
void ServerLuaInventoryList::set_stack(unsigned short i, sol::table stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
list.setStack(i - 1, ItemStack(list.defs.fromStr(stack[1]).index, stack.get<unsigned short>(2)));
}
LuaItemStack ServerLuaInventoryList::place_stack(unsigned short i, LuaItemStack stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.placeStack(i - 1, ItemStack(stack, list.defs)), list.defs);
}
LuaItemStack ServerLuaInventoryList::place_stack(unsigned short i, sol::table stack) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.placeStack(i - 1, ItemStack(list.defs.fromStr(stack[1]).index, stack.get<unsigned short>(2))), list.defs);
}
LuaItemStack ServerLuaInventoryList::split_stack(unsigned short i) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.splitStack(i - 1), list.defs);
}
@ -67,8 +86,9 @@ LuaItemStack ServerLuaInventoryList::take_stack(sol::table request) {
return LuaItemStack(list.takeStack(ItemStack(list.defs.fromStr(request[1]).index, request.get<unsigned short>(2))), list.defs);
}
LuaItemStack ServerLuaInventoryList::remove_stack(unsigned short ind, unsigned short count) {
return LuaItemStack(list.removeStack(ind - 1, count), list.defs);
LuaItemStack ServerLuaInventoryList::remove_stack(unsigned short i, unsigned short count) {
if (i < 1 || i > list.getLength()) throw "index is outside of list bounds.";
return LuaItemStack(list.removeStack(i - 1, count), list.defs);
}
void ServerLuaInventoryList::set_callback(ServerInventoryList::Callback t, sol::function fun) {
@ -77,4 +97,4 @@ void ServerLuaInventoryList::set_callback(ServerInventoryList::Callback t, sol::
sol::function ServerLuaInventoryList::get_callback(ServerInventoryList::Callback t) {
return list.getLuaCallback(t);
}
}

View File

@ -9,13 +9,19 @@
class ServerLuaInventoryList {
public:
ServerLuaInventoryList(ServerInventoryList& list) :
ServerLuaInventoryList(InventoryList& list) :
list(list) {}
ServerInventoryList& list;
InventoryList& list;
void set_length(int length);
int get_length();
void set_width(int width);
int get_width();
void resize(int length, int width);
std::string get_name();
LuaItemStack get_stack(unsigned short i);

View File

@ -6,53 +6,7 @@
#include "../../LuaParser.h"
#include "../../../net/NetHandler.h"
void ServerLuaPlayer::set_pos(const sol::table &pos) {
player.assertPos({pos[1], pos[2], pos[3]});
}
sol::table ServerLuaPlayer::get_pos(sol::this_state s) {
glm::vec3 pos = player.getPos();
return LuaParser::luaVec(sol::state_view(s), pos);
}
sol::table ServerLuaPlayer::get_block_pos(sol::this_state s) {
glm::vec3 pos = glm::floor(player.getPos());
return LuaParser::luaVec(sol::state_view(s), pos);
}
//void ServerLuaPlayer::set_vel(const sol::table &vel) {
// player.setVel({vel["x"], vel["y"], vel["z"]});
//}
//sol::table ServerLuaPlayer::get_vel(sol::this_state s) {
// glm::vec3 vel = player.getVel();
// return sol::state_view(s).create_table_with("x", vel.x, "y", vel.y, "z", vel.z);
//}
void ServerLuaPlayer::set_look_yaw(float rot) {
player.assertYaw(rot);
}
float ServerLuaPlayer::get_look_yaw() {
return player.getYaw();
}
void ServerLuaPlayer::set_look_pitch(float rot) {
player.assertPitch(rot);
}
float ServerLuaPlayer::get_look_pitch() {
return player.getPitch();
}
void ServerLuaPlayer::set_flying(bool shouldFly) {
player.setFlying(shouldFly);
}
bool ServerLuaPlayer::get_flying() {
return player.isFlying();
}
#include "ServerLuaInventoryList.h"
std::string ServerLuaPlayer::get_name() {
return player.username;
@ -66,6 +20,97 @@ std::string ServerLuaPlayer::get_address() {
return NetHandler::intToIPString(player.address.host) + ":" + std::to_string(player.address.port);
}
sol::table ServerLuaPlayer::get_pos(sol::this_state s) {
glm::vec3 pos = player.getPos();
return LuaParser::luaVec(sol::state_view(s), pos);
}
sol::table ServerLuaPlayer::get_block_pos(sol::this_state s) {
glm::vec3 pos = glm::floor(player.getPos());
return LuaParser::luaVec(sol::state_view(s), pos);
}
void ServerLuaPlayer::set_pos(const sol::table &pos) {
player.setPos({pos[1], pos[2], pos[3]}, true);
}
sol::table ServerLuaPlayer::get_vel(sol::this_state s) {
glm::vec3 vel = player.getVel();
return LuaParser::luaVec(sol::state_view(s), vel);
}
void ServerLuaPlayer::set_vel(const sol::table &vel) {
player.setVel({vel[1], vel[2], vel[3]}, true);
}
float ServerLuaPlayer::get_look_yaw() {
return player.getYaw();
}
void ServerLuaPlayer::set_look_yaw(float rot) {
player.setYaw(rot, true);
}
float ServerLuaPlayer::get_look_pitch() {
return player.getPitch();
}
void ServerLuaPlayer::set_look_pitch(float rot) {
player.setPitch(rot, true);
}
bool ServerLuaPlayer::get_flying() {
return player.isFlying();
}
void ServerLuaPlayer::set_flying(bool shouldFly) {
player.setFlying(shouldFly, true);
}
ServerLuaInventory ServerLuaPlayer::get_inventory() {
return ServerLuaInventory(*player.getInventory());
}
sol::object ServerLuaPlayer::get_hand_list(sol::this_state s) {
return sol::make_object<ServerLuaInventoryList>(s, ServerLuaInventoryList(*player.getHandList()));
}
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 throw "Attempted to set hand list to nil.";
}
sol::object ServerLuaPlayer::get_hand_stack(sol::this_state s) {
auto list = player.getHandList();
if (!list) return sol::nil;
return sol::make_object<LuaItemStack>(s, ServerLuaInventoryList(*list).get_stack(1));
}
sol::object ServerLuaPlayer::get_wield_list(sol::this_state s) {
auto list = player.getWieldList();
if (!list) return sol::nil;
return sol::make_object<ServerLuaInventoryList>(s, ServerLuaInventoryList(*list));
}
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);
else throw "Attempted to set wield list to nil.";
}
sol::object ServerLuaPlayer::get_wield_stack(sol::this_state s) {
auto list = player.getWieldList();
if (!list) return sol::nil;
return sol::make_object<LuaItemStack>(s, ServerLuaInventoryList(*list).get_stack(player.getWieldIndex() + 1));
}
unsigned int ServerLuaPlayer::get_wield_index() {
return player.getWieldIndex() + 1;
}
void ServerLuaPlayer::set_wield_index(unsigned int index) {
player.setWieldIndex(index - 1, true);
}

View File

@ -14,34 +14,84 @@ public:
ServerLuaPlayer(ServerClient& player) : player(player), cid(player.cid) {}
ServerClient& player;
unsigned int cid;
bool is_player = true;
void set_pos(const sol::table& pos);
sol::table get_pos(sol::this_state s);
sol::table get_block_pos(sol::this_state s);
// void set_vel(const sol::table& vel);
// sol::table get_vel(sol::this_state s);
void set_look_yaw(float rot);
float get_look_yaw();
void set_look_pitch(float rot);
float get_look_pitch();
// std::string get_menu_state();
// void close_menu();
// void open_menu(sol::this_state s, std::string menu, sol::optional<sol::table> callbacks);
ServerLuaInventory get_inventory();
// void set_selected_block(std::string block);
void set_flying(bool shouldFly);
bool get_flying();
bool is_player;
std::string get_name();
unsigned int get_cid();
std::string get_address();
sol::table get_pos(sol::this_state s);
sol::table get_block_pos(sol::this_state s);
void set_pos(const sol::table& pos);
sol::table get_vel(sol::this_state s);
void set_vel(const sol::table& vel);
float get_look_yaw();
void set_look_yaw(float rot);
float get_look_pitch();
void set_look_pitch(float rot);
ServerLuaInventory get_inventory();
sol::object get_hand_list(sol::this_state s);
void set_hand_list(sol::object handList);
sol::object get_hand_stack(sol::this_state s);
sol::object get_wield_list(sol::this_state s);
sol::object get_wield_stack(sol::this_state s);
void set_wield_list(sol::object list);
unsigned int get_wield_index();
void set_wield_index(unsigned int index);
void set_flying(bool shouldFly);
bool get_flying();
private:
unsigned int cid;
};
namespace ServerApi {
static void server_player(sol::state& lua) {
lua.new_usertype<ServerLuaPlayer>("ServerPlayer",
"is_player", sol::readonly(&ServerLuaPlayer::is_player),
"get_pos", &ServerLuaPlayer::get_pos,
"get_block_pos", &ServerLuaPlayer::get_block_pos,
"set_pos", &ServerLuaPlayer::set_pos,
"get_vel", &ServerLuaPlayer::get_vel,
"set_vel", &ServerLuaPlayer::set_vel,
"get_look_yaw", &ServerLuaPlayer::get_look_yaw,
"set_look_yaw", &ServerLuaPlayer::set_look_yaw,
"get_look_pitch", &ServerLuaPlayer::get_look_pitch,
"set_look_pitch", &ServerLuaPlayer::set_look_pitch,
"get_inventory", &ServerLuaPlayer::get_inventory,
"get_hand_list", &ServerLuaPlayer::get_hand_list,
"set_hand_list", &ServerLuaPlayer::set_hand_list,
"get_hand_stack", &ServerLuaPlayer::get_hand_stack,
"get_wield_list", &ServerLuaPlayer::get_wield_list,
"set_wield_list", &ServerLuaPlayer::set_wield_list,
"get_wield_index", &ServerLuaPlayer::get_wield_index,
"set_wield_index", &ServerLuaPlayer::set_wield_index,
"get_wield_stack", &ServerLuaPlayer::get_wield_stack,
// "open_menu", &ServerLuaPlayer::open_menu,
// "close_menu", &ServerLuaPlayer::close_menu,
"pos", sol::property(&ServerLuaPlayer::get_pos, &ServerLuaPlayer::set_pos),
"block_pos", sol::property(&ServerLuaPlayer::get_block_pos, &ServerLuaPlayer::set_pos),
"vel", sol::property(&ServerLuaPlayer::get_vel, &ServerLuaPlayer::set_vel),
"look_yaw", sol::property(&ServerLuaPlayer::get_look_yaw, &ServerLuaPlayer::set_look_yaw),
"look_pitch", sol::property(&ServerLuaPlayer::get_look_pitch, &ServerLuaPlayer::set_look_pitch),
"flying", sol::property(&ServerLuaPlayer::set_flying, &ServerLuaPlayer::get_flying),
"name", sol::property(&ServerLuaPlayer::get_name),
"cid", sol::property(&ServerLuaPlayer::get_cid),
"address", sol::property(&ServerLuaPlayer::get_address)
);
}
}

View File

@ -19,5 +19,14 @@ namespace Api {
end
end
)");
lua.script(R"(
zepha.__builtin.add_player = function(player)
table.insert(zepha.players, player)
zepha.__builtin.trigger_event("new_player", player)
zepha.__builtin.trigger_event("player_join", player)
end
)");
}
}

View File

@ -33,6 +33,8 @@ namespace ClientApi {
"set_scale", &LocalLuaEntity::set_scale,
"get_scale", &LocalLuaEntity::get_scale,
"set_display_type", &LocalLuaEntity::set_display_type,
"pos", sol::property(&LocalLuaEntity::get_pos, &LocalLuaEntity::set_pos),
"visual_offset", sol::property(&LocalLuaEntity::get_visual_offset, &LocalLuaEntity::set_visual_offset),
"pitch", sol::property(&LocalLuaEntity::get_pitch, &LocalLuaEntity::set_pitch),
@ -40,9 +42,7 @@ namespace ClientApi {
"roll", sol::property(&LocalLuaEntity::get_roll, &LocalLuaEntity::set_roll),
"scale", sol::property(&LocalLuaEntity::get_scale, &LocalLuaEntity::set_scale),
"anims", sol::readonly(&LocalLuaEntity::manager),
"set_display_type", &LocalLuaEntity::set_display_type
"anims", sol::readonly(&LocalLuaEntity::manager)
);
}
}

View File

@ -14,14 +14,19 @@ namespace ServerApi {
lua.new_usertype<ServerLuaInventory>("InventoryRef",
"get_list", &ServerLuaInventory::get_list,
"add_list", &ServerLuaInventory::add_list,
"remove_list", &ServerLuaInventory::remove_list
"remove_list", &ServerLuaInventory::remove_list,
"set_default_list", &ServerLuaInventory::set_default_list,
"get_default_list", &ServerLuaInventory::get_default_list
);
lua.new_usertype<ServerLuaInventoryList>("InventoryListRef",
"length", sol::property(&ServerLuaInventoryList::get_length),
"width", sol::property(&ServerLuaInventoryList::get_width),
"length", sol::property(&ServerLuaInventoryList::get_length, &ServerLuaInventoryList::set_length),
"width", sol::property(&ServerLuaInventoryList::get_width, &ServerLuaInventoryList::set_width),
"name", sol::property(&ServerLuaInventoryList::get_name),
"resize", &ServerLuaInventoryList::resize,
"get_stack", &ServerLuaInventoryList::get_stack,
"set_stack", sol::overload(
sol::resolve<void(unsigned short, LuaItemStack)>(&ServerLuaInventoryList::set_stack),

View File

@ -1,46 +0,0 @@
//
// Created by aurailus on 2020-02-17.
//
#pragma once
#include <sol2/sol.hpp>
#include "../class/ServerLuaPlayer.h"
namespace ServerApi {
void server_player(sol::state& lua) {
lua.new_usertype<ServerLuaPlayer>("ServerPlayer",
"is_player", sol::readonly(&ServerLuaPlayer::is_player),
"set_pos", &ServerLuaPlayer::set_pos,
"get_pos", &ServerLuaPlayer::get_pos,
"get_block_pos", &ServerLuaPlayer::get_block_pos,
// "set_vel", &ServerLuaPlayer::set_vel,
// "get_vel", &ServerLuaPlayer::get_vel,
"set_look_yaw", &ServerLuaPlayer::set_look_yaw,
"get_look_yaw", &ServerLuaPlayer::get_look_yaw,
"set_look_pitch", &ServerLuaPlayer::set_look_pitch,
"get_look_pitch", &ServerLuaPlayer::get_look_pitch,
"get_inventory", &ServerLuaPlayer::get_inventory,
// "open_menu", &ServerLuaPlayer::open_menu,
// "close_menu", &ServerLuaPlayer::close_menu,
"pos", sol::property(&ServerLuaPlayer::get_pos, &ServerLuaPlayer::set_pos),
"block_pos", sol::property(&ServerLuaPlayer::get_block_pos, &ServerLuaPlayer::set_pos),
// "vel", sol::property(&ServerLuaPlayer::get_vel, &ServerLuaPlayer::set_vel),
"look_yaw", sol::property(&ServerLuaPlayer::get_look_yaw, &ServerLuaPlayer::set_look_yaw),
"look_pitch", sol::property(&ServerLuaPlayer::get_look_pitch, &ServerLuaPlayer::set_look_pitch),
"flying", sol::property(&ServerLuaPlayer::set_flying, &ServerLuaPlayer::get_flying),
"name", sol::property(&ServerLuaPlayer::get_name),
"cid", sol::property(&ServerLuaPlayer::get_cid),
"address", sol::property(&ServerLuaPlayer::get_address)
// "menu_state", sol::property(&ServerLuaPlayer::get_menu_state)
);
}
}

View File

@ -149,7 +149,7 @@ sol::protected_function_result LocalLuaParser::errorCallback(sol::protected_func
}
std::cout << Log::err << "Zepha has encountered an error, and ErrorFormatter failed to format it:"
<< std::endl << std::endl << errString << Log::endl;
<< std::endl << errString << Log::endl;
exit(1);
return errPfr;

View File

@ -23,9 +23,10 @@ public:
LocalModHandler& getHandler();
template<typename... Args> void safe_function(sol::protected_function f, Args... args) const {
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(ClientGame& defs, LocalWorld& world, Player& player);

View File

@ -14,7 +14,7 @@
#include "../register/RegisterBiomes.h"
// Usertypes
#include "../api/usertype/sServerPlayer.h"
#include "../api/class/ServerLuaPlayer.h"
#include "../api/usertype/sLuaEntity.h"
#include "../api/usertype/sInventoryRef.h"
#include "../api/usertype/cItemStack.h"
@ -76,18 +76,13 @@ void ServerLuaParser::sendModsPacket(ENetPeer* peer) const {
void ServerLuaParser::playerConnected(std::shared_ptr<ServerClient> client) {
auto players = core.get<sol::table>("players");
players.add(ServerLuaPlayer(*client));
ServerLuaPlayer& player = players[players.size()];
safe_function(core["__builtin"]["trigger_event"], "new_player", player);
safe_function(core["__builtin"]["trigger_event"], "player_join", player);
safe_function(core["__builtin"]["add_player"], ServerLuaPlayer(*client));
}
void ServerLuaParser::playerDisconnected(std::shared_ptr<ServerClient> client) {
for (auto& pair : core.get<sol::table>("players")) {
ServerLuaPlayer& p = pair.second.as<ServerLuaPlayer>();
if (p.cid == client->cid) {
if (p.get_cid() == client->cid) {
safe_function(core["__builtin"]["trigger_event"], "player_disconnect", p);
p.is_player = false;

View File

@ -0,0 +1,5 @@
//
// Created by aurailus on 2020-07-19.
//
#include "CreateBlockModel.h"

View File

@ -0,0 +1,9 @@
//
// Created by aurailus on 2020-07-19.
//
#pragma once
class CreateBlockModel {
};

View File

@ -274,6 +274,13 @@ namespace RegisterBlocks {
bool lightPropagates = blockTable.get_or("light_propagates", false);
auto maxStack = blockTable.get_or("stack", 64);
int health = 1, defense = 0;
auto toolOpt = blockTable.get<sol::optional<sol::table>>("tool_props");
if (toolOpt) {
health = toolOpt->get_or<unsigned int>("health", 1);
defense = toolOpt->get_or<unsigned int>("defense", 0);
}
glm::vec3 lightSource {};
if (blockTable.get<sol::optional<sol::table>>("light_source")) {
auto light = blockTable.get<sol::table>("light_source");
@ -301,43 +308,53 @@ namespace RegisterBlocks {
// Create the block model
std::pair<BlockModel, BlockModel> models = createBlockModel(blockTable, blockModels, atlas);
BlockDef *blockDef = new BlockDef(
identifier,
*nameOpt,
maxStack,
models.first, models.second,
solid,
lightSource,
lightPropagates,
std::move(selectionBoxes),
std::move(collisionBoxes),
defs.size() // Index
);
BlockDef* def = new BlockDef();
def->identifier = identifier;
def->name = *nameOpt;
def->index = defs.size();
def->solid = solid;
def->lightSource = lightSource;
def->lightPropagates = lightPropagates;
def->health = health;
def->defense = defense;
def->maxStackSize = maxStack;
def->model = models.first;
def->farModel = models.second;
def->sBoxes = std::move(selectionBoxes);
def->cBoxes = std::move(collisionBoxes);
// Create entity model
if (atlas) blockDef->createModel();
if (atlas) def->createModel();
// Bind Callbacks
addCallback(blockDef, blockTable, "on_construct", Callback::CONSTRUCT);
addCallback(blockDef, blockTable, "after_construct", Callback::AFTER_CONSTRUCT);
addCallback(def, blockTable, "on_construct", Callback::CONSTRUCT);
addCallback(def, blockTable, "after_construct", Callback::AFTER_CONSTRUCT);
addCallback(blockDef, blockTable, "on_destruct", Callback::DESTRUCT);
addCallback(blockDef, blockTable, "after_destruct", Callback::AFTER_DESTRUCT);
addCallback(def, blockTable, "on_destruct", Callback::DESTRUCT);
addCallback(def, blockTable, "after_destruct", Callback::AFTER_DESTRUCT);
addCallback(blockDef, blockTable, "on_place", Callback::PLACE);
addCallback(blockDef, blockTable, "on_place_client", Callback::PLACE_CLIENT);
addCallback(def, blockTable, "on_place", Callback::PLACE);
addCallback(def, blockTable, "on_place_client", Callback::PLACE_CLIENT);
addCallback(blockDef, blockTable, "after_place", Callback::AFTER_PLACE);
addCallback(blockDef, blockTable, "after_place_client", Callback::AFTER_PLACE_CLIENT);
addCallback(def, blockTable, "after_place", Callback::AFTER_PLACE);
addCallback(def, blockTable, "after_place_client", Callback::AFTER_PLACE_CLIENT);
addCallback(blockDef, blockTable, "on_break", Callback::BREAK);
addCallback(blockDef, blockTable, "on_break_client", Callback::BREAK_CLIENT);
addCallback(def, blockTable, "on_break", Callback::BREAK);
addCallback(def, blockTable, "on_break_client", Callback::BREAK_CLIENT);
addCallback(blockDef, blockTable, "after_break", Callback::AFTER_BREAK);
addCallback(blockDef, blockTable, "after_break_client", Callback::AFTER_BREAK_CLIENT);
addCallback(def, blockTable, "after_break", Callback::AFTER_BREAK);
addCallback(def, blockTable, "after_break_client", Callback::AFTER_BREAK_CLIENT);
addCallback(def, blockTable, "on_interact", Callback::INTERACT);
addCallback(def, blockTable, "on_interact_client", Callback::INTERACT_CLIENT);
// Add Block Definition to the AtlasK
defs.registerDef(blockDef);
defs.registerDef(def);
}
}

View File

@ -27,8 +27,8 @@ namespace RegisterItems {
auto texturesOpt = itemTable.get<sol::optional<sol::table>> ("textures");
auto maxStack = itemTable.get_or("stack", 64);
if (!nameOpt) throw identifier + " is missing name property!";
if (!texturesOpt) throw identifier + " is missing textures property!";
if (!nameOpt) throw std::runtime_error(identifier + " is missing name property!");
if (!texturesOpt) throw std::runtime_error(identifier + " is missing textures property!");
//Convert Textures Table to Vector
std::vector<std::string> textures;

View File

@ -14,7 +14,7 @@ public:
Deserializer(const std::string& data) : data(&data[0]), len(data.length()) {};
Deserializer(const char* start, size_t len) : data(start), len(len) {};
template <typename T> inline T read() {};
template <typename T> inline T read() { assert(false); };
template <typename T> inline Deserializer& read(T& ref) {
ref = read<T>();
return *this;

View File

@ -10,19 +10,28 @@ enum class PacketType {
// Information Request Types
BLOCK_IDENTIFIER_LIST,
BIOME_IDENTIFIER_LIST,
MODS,
MOD_ORDER,
MODS,
MEDIA,
MEDIA_DONE,
CONNECT_DATA_RECVD,
// Ingame Data Types
// Miscellaneous
SERVER_INFO,
THIS_PLAYER_INFO,
// Player Info
PLAYER_INFO,
THIS_PLAYER_INFO,
// World
CHUNK,
MAPBLOCK,
// Block
BLOCK_SET,
BLOCK_INTERACT,
// Entity
ENTITY_INFO,
ENTITY_REMOVED,

View File

@ -16,7 +16,7 @@ class Serializer {
public:
std::string data {};
template <typename T> inline Serializer& append(const T& elem) {};
template <typename T> inline Serializer& append(const T& elem) { assert(false); };
Packet packet(PacketType p, bool reliable = true) {
Packet packet(p, reliable);

View File

@ -76,37 +76,16 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<PacketView> p) {
case PacketType::SERVER_INFO:
serverSideChunkGens = p->d.read<unsigned int>(); break;
case PacketType::THIS_PLAYER_INFO: {
while (!p->d.atEnd()) {
switch (p->d.read<unsigned int>()) {
case static_cast<unsigned int>(NetPlayerField::ID): {
cid = p->d.read<unsigned int>();
break;
}
case static_cast<unsigned int>(NetPlayerField::POSITION): {
player.setPos(p->d.read<glm::vec3>());
break;
}
case static_cast<unsigned int>(NetPlayerField::PITCH): {
player.setPitch(p->d.read<float>());
break;
}
case static_cast<unsigned int>(NetPlayerField::YAW): {
player.setYaw(p->d.read<float>());
break;
}
}
}
break; }
case PacketType::THIS_PLAYER_INFO:
player.handleAssertion(p->d); break;
case PacketType::PLAYER_INFO: {
unsigned int cid = p->d.read<unsigned int>();
if (this->cid == cid) break;
if (player.id == cid) break;
bool found = false;
for (auto& entity : world->dimension.playerEntities) {
if (entity.getCid() == cid) {
// Update an existing PlayerEntity
entity.interpPos(p->d.read<glm::vec3>());
entity.interpRotateZ(-p->d.read<float>() + 90);
entity.interpRotateY(-p->d.read<float>() + 90);
@ -149,27 +128,32 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<PacketView> p) {
}
}
void ClientNetworkInterpreter::setBlock(glm::ivec3 pos, unsigned int block) {
Serializer().append(pos).append(block)
.packet(PacketType::BLOCK_SET).sendTo(connection.getPeer(), PacketChannel::BLOCK);
void ClientNetworkInterpreter::blockPlace(glm::ivec3 pos, unsigned int block) {
Serializer().append(pos).append(block).packet(PacketType::BLOCK_SET)
.sendTo(connection.getPeer(), PacketChannel::BLOCK);
}
void ClientNetworkInterpreter::watchInv(const std::string& inv, const std::string& list) {
Serializer().append(inv).append(list)
.packet(PacketType::INV_WATCH).sendTo(connection.getPeer(), PacketChannel::INVENTORY);
void ClientNetworkInterpreter::blockInteract(glm::ivec3 pos) {
Serializer().append(pos).packet(PacketType::BLOCK_INTERACT)
.sendTo(connection.getPeer(), PacketChannel::BLOCK);
}
void ClientNetworkInterpreter::unwatchInv(const std::string& inv, const std::string& list) {
auto packet = Serializer().append(inv).append(list).packet(PacketType::INV_UNWATCH);
packet.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
void ClientNetworkInterpreter::invWatch(const std::string& inv, const std::string& list) {
Serializer().append(inv).append(list).packet(PacketType::INV_WATCH)
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
}
void ClientNetworkInterpreter::primaryInteract(const std::string &inv, const std::string &list, unsigned short ind) {
auto packet = Serializer().append<unsigned short>(0).append(inv).append(list).append<unsigned short>(ind).packet(PacketType::INV_INTERACT);
packet.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
void ClientNetworkInterpreter::invUnwatch(const std::string& inv, const std::string& list) {
Serializer().append(inv).append(list).packet(PacketType::INV_UNWATCH)
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
}
void ClientNetworkInterpreter::secondaryInteract(const std::string &inv, const std::string &list, unsigned short ind) {
auto packet = Serializer().append<unsigned short>(1).append(inv).append(list).append<unsigned short>(ind).packet(PacketType::INV_INTERACT);
packet.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
void ClientNetworkInterpreter::invInteractPrimary(const std::string &inv, const std::string &list, unsigned short ind) {
Serializer().append<unsigned short>(0).append(inv).append(list).append<unsigned short>(ind).packet(PacketType::INV_INTERACT)
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
}
void ClientNetworkInterpreter::invInteractSecondary(const std::string &inv, const std::string &list, unsigned short ind) {
Serializer().append<unsigned short>(1).append(inv).append(list).append<unsigned short>(ind).packet(PacketType::INV_INTERACT)
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
}

View File

@ -23,20 +23,19 @@ public:
void init(LocalWorld* world, std::function<void(std::unique_ptr<PacketView>)> invCallback);
void update();
// Functions to be called by outside of ClientNetworkInterpreter
void setBlock(glm::ivec3 pos, unsigned int block);
void watchInv(const std::string& inv, const std::string& list);
void unwatchInv(const std::string& inv, const std::string& list);
void blockPlace(glm::ivec3 pos, unsigned int block);
void blockInteract(glm::ivec3 pos);
void primaryInteract(const std::string& inv, const std::string& list, unsigned short ind);
void secondaryInteract(const std::string& inv, const std::string& list, unsigned short ind);
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);
int recvPackets = 0;
int serverSideChunkGens = 0;
private:
void receivedPacket(std::unique_ptr<PacketView> ePacket);
int cid = 0;
Player& player;
ServerConnection& connection;

View File

@ -7,6 +7,13 @@
enum class NetPlayerField {
ID,
POSITION,
VELOCITY,
PITCH,
YAW
YAW,
FLYING,
HAND_INV,
WIELD_INV,
WIELD_INDEX
};

View File

@ -169,6 +169,15 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
}
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.parser.safe_function(def.callbacks[Callback::INTERACT],
defs.parser.luaVec(pos), ServerLuaPlayer(client));
}
break;
}
case PacketType::INV_WATCH: {
std::string source = p.d.read<std::string>();
std::string list = p.d.read<std::string>();
@ -177,12 +186,8 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
if (source == "current_player") source = "player:" + std::to_string(client.cid);
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;
}
if (!exists) Serializer().append(source).append(list)
.packet(PacketType::INV_INVALID).sendTo(client.peer, PacketChannel::INVENTORY);
break;
}
case PacketType::INV_UNWATCH: {

View File

@ -45,7 +45,7 @@ void ClientList::createPlayer(std::shared_ptr<ServerClient> c) {
c->hasPlayer = true;
c->setUsername("TEMPORaRY");
c->getInventory()->createList("hand", 1, 1);
c->getInventory()->createList("cursor", 1, 1);
defs.parser.playerConnected(c);

View File

@ -22,79 +22,98 @@ void ServerClient::setUsername(const std::string &name) {
this->username = name;
}
void ServerClient::assertPos(glm::vec3 pos) {
setPos(pos);
Serializer()
.append(static_cast<unsigned int>(NetPlayerField::POSITION))
.append(pos)
.packet(PacketType::THIS_PLAYER_INFO)
.sendTo(peer, PacketChannel::PLAYER);
glm::vec3 ServerClient::getPos() {
return pos;
}
void ServerClient::setPos(glm::vec3 pos) {
void ServerClient::setPos(glm::vec3 pos, bool assert) {
glm::vec3 lastMapBlock = Space::MapBlock::world::fromBlock(this->pos);
glm::vec3 newMapBlock = Space::MapBlock::world::fromBlock(pos);
if (newMapBlock != lastMapBlock && !changedMapBlocks) changedMapBlocks = true;
this->pos = pos;
if (assert) assertField(NetPlayerField::POSITION, pos);
}
glm::vec3 ServerClient::getPos() {
return pos;
glm::vec3 ServerClient::getVel() {
return vel;
}
void ServerClient::assertPitch(float pitch) {
setPitch(pitch);
Serializer()
.append(static_cast<unsigned int>(NetPlayerField::PITCH))
.append(pitch)
.packet(PacketType::THIS_PLAYER_INFO)
.sendTo(peer, PacketChannel::PLAYER);
}
void ServerClient::setPitch(float pitch) {
this->pitch = pitch;
void ServerClient::setVel(glm::vec3 vel, bool assert) {
this->vel = vel;
if (assert) assertField(NetPlayerField::VELOCITY, vel);
}
float ServerClient::getPitch() {
return pitch;
}
void ServerClient::assertYaw(float yaw) {
setYaw(yaw);
Serializer()
.append(static_cast<unsigned int>(NetPlayerField::YAW))
.append(yaw)
.packet(PacketType::THIS_PLAYER_INFO)
.sendTo(peer, PacketChannel::PLAYER);
}
void ServerClient::setYaw(float yaw) {
this->yaw = yaw;
void ServerClient::setPitch(float pitch, bool assert) {
this->pitch = pitch;
if (assert) assertField(NetPlayerField::PITCH, pitch);
}
float ServerClient::getYaw() {
return yaw;
}
void ServerClient::setFlying(bool flying) {
this->flying = flying;
void ServerClient::setYaw(float yaw, bool assert) {
this->yaw = yaw;
if (assert) assertField(NetPlayerField::YAW, yaw);
}
bool ServerClient::isFlying() {
return flying;
}
void ServerClient::setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity) {
mapBlockIntegrity[pos] = integrity;
}
unsigned long long ServerClient::getMapBlockIntegrity(glm::ivec3 pos) {
if (mapBlockIntegrity.count(pos)) return mapBlockIntegrity[pos];
return 0;
void ServerClient::setFlying(bool flying, bool assert) {
this->flying = flying;
if (assert) assertField(NetPlayerField::FLYING, flying);
}
std::shared_ptr<Inventory> ServerClient::getInventory() {
return inventory;
}
}
std::shared_ptr<InventoryList> ServerClient::getHandList() {
return handList;
}
void ServerClient::setHandList(std::shared_ptr<InventoryList> list, bool assert) {
handList = list;
if (assert) assertField(NetPlayerField::HAND_INV, handList ? handList->getName() : "");
}
std::shared_ptr<InventoryList> ServerClient::getWieldList() {
return wieldList;
}
void ServerClient::setWieldList(std::shared_ptr<InventoryList> list, bool assert) {
wieldList = list;
if (assert) assertField(NetPlayerField::WIELD_INV, wieldList ? wieldList->getName() : "");
}
unsigned short ServerClient::getWieldIndex() {
return wieldIndex;
}
void ServerClient::setWieldIndex(unsigned short index, bool assert) {
wieldIndex = index % (wieldList ? wieldList->getLength() : 1);
if (assert) assertField(NetPlayerField::WIELD_INDEX, static_cast<unsigned short>(wieldIndex));
}
//void ServerClient::setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity) {
// mapBlockIntegrity[pos] = integrity;
//}
//
//unsigned long long ServerClient::getMapBlockIntegrity(glm::ivec3 pos) {
// if (mapBlockIntegrity.count(pos)) return mapBlockIntegrity[pos];
// return 0;
//}
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::PLAYER);
}

View File

@ -9,9 +9,11 @@
#include <unordered_map>
#include "../../../util/Vec.h"
#include "../../../def/DefinitionAtlas.h"
#include "../../../game/inventory/Inventory.h"
#include "../../../game/inventory/ServerInventoryList.h"
enum class NetPlayerField;
class InventoryRefs;
class ServerClient {
@ -22,26 +24,35 @@ public:
void setUsername(const std::string& name);
void assertPos(glm::vec3 pos);
void setPos(glm::vec3 pos);
glm::vec3 getPos();
void setPos(glm::vec3 pos, bool assert = false);
glm::vec3 getVel();
void setVel(glm::vec3 vel, bool assert = false);
void assertPitch(float pitch);
void setPitch(float pitch);
float getPitch();
void setPitch(float pitch, bool assert = false);
void assertYaw(float yaw);
void setYaw(float yaw);
float getYaw();
void setYaw(float yaw, bool assert = false);
void setFlying(bool flying);
bool isFlying();
void setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity);
unsigned long long getMapBlockIntegrity(glm::ivec3 pos);
void setFlying(bool flying, bool assert = false);
std::shared_ptr<Inventory> getInventory();
std::shared_ptr<InventoryList> getHandList();
void setHandList(std::shared_ptr<InventoryList> list, bool assert = false);
std::shared_ptr<InventoryList> getWieldList();
void setWieldList(std::shared_ptr<InventoryList> list, bool assert = false);
unsigned short getWieldIndex();
void setWieldIndex(unsigned short index, bool assert = false);
// void setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity);
// unsigned long long getMapBlockIntegrity(glm::ivec3 pos);
bool hasPlayer = false;
unsigned int cid = 0;
@ -54,13 +65,22 @@ public:
glm::vec3 lastPos = glm::vec3(INFINITY);
private:
glm::vec3 pos {};
template <typename T> void assertField(NetPlayerField field, T data);
glm::vec3 pos { 0, -37, 0 };
glm::vec3 vel {};
float pitch = 0;
float yaw = 0;
bool flying = false;
std::shared_ptr<Inventory> inventory;
unsigned int wieldIndex = 0;
std::shared_ptr<InventoryList> handList = nullptr;
std::shared_ptr<InventoryList> wieldList = nullptr;
unsigned int handItem = DefinitionAtlas::AIR;
unsigned int wieldItem = DefinitionAtlas::AIR;
std::unordered_map<glm::ivec3, unsigned long long, Vec::ivec3> mapBlockIntegrity {};
};

View File

@ -195,11 +195,11 @@ bool LocalDimension::setBlock(glm::ivec3 pos, unsigned int block) {
if (lp.z == 15 && getChunk(cp + glm::ivec3 {0, 0, 1})) getChunk(cp + glm::ivec3 {0, 0, 1})->dirty = true;
else if (lp.z == 0 && getChunk(cp + glm::ivec3 {0, 0, -1})) getChunk(cp + glm::ivec3 {0, 0, -1})->dirty = true;
attemptMeshChunk(chunk);
attemptMeshChunk(chunk, true);
return true;
}
void LocalDimension::attemptMeshChunk(const std::shared_ptr<Chunk>& chunk, bool updateAdjacents) {
void LocalDimension::attemptMeshChunk(const std::shared_ptr<Chunk>& chunk, bool priority, bool updateAdjacents) {
static const std::vector<glm::ivec3> dirs {
glm::ivec3 {1, 0, 0}, glm::ivec3 {-1, 0, 0},
glm::ivec3 {0, 1, 0}, glm::ivec3 {0, -1, 0},
@ -213,14 +213,14 @@ void LocalDimension::attemptMeshChunk(const std::shared_ptr<Chunk>& chunk, bool
if (!chunk->shouldRender) removeMeshChunk(chunk->pos);
meshGenStream->queue(chunk->pos);
meshGenStream->queue(chunk->pos, priority);
chunk->dirty = false;
}
bool LocalDimension::getAdjacentExists(glm::vec3 pos, bool updateAdjacents) {
auto chunk = getChunk(pos);
if (chunk == nullptr) return false;
if (updateAdjacents) attemptMeshChunk(chunk, false);
if (updateAdjacents) attemptMeshChunk(chunk, false, false);
return true;
}

View File

@ -56,7 +56,7 @@ private:
void finishMeshes();
void attemptMeshChunk(const std::shared_ptr<Chunk>& chunk, bool updateAdjacents = true);
void attemptMeshChunk(const std::shared_ptr<Chunk>& chunk, bool priority = false, bool updateAdjacents = true);
bool getAdjacentExists(glm::vec3 pos, bool updateAdjacents);
ClientGame& game;

View File

@ -2,5 +2,5 @@
"name": "@aurailus:basictools",
"description": "Basic tools for Zepha.",
"version": "0.0.1",
"depends": ["zeus:materials", "@aurailus:crafting"]
"depends": ["zeus:materials", "@aurailus:crafting", "@aurailus:hot_wheel"]
}

View File

@ -32,6 +32,12 @@ zepha.register_item("@aurailus:basictools:flint_shovel", {
name = "Flint Spade",
textures = {
"@aurailus:basictools:flint_shovel"
},
tool_props = {
interval = 0.4,
damage_groups = {
scoop = 7
}
}
});
@ -61,5 +67,21 @@ zepha.register_item("@aurailus:basictools:wooden_shovel", {
name = "Wooden Shovel",
textures = {
"@aurailus:basictools:wooden_shovel"
},
tool_props = {
interval = 0.45,
damage_groups = {
scoop = 5
}
}
});
});
if zepha.server then
zepha.register_on("new_player", function(player)
local inv = player:get_inventory():get_list("hot_wheel_1");
-- inv:add_stack({"@aurailus:basictools:wooden_pickaxe", 1})
-- inv:add_stack({"@aurailus:basictools:wooden_hatchet", 1})
inv:add_stack({"@aurailus:basictools:wooden_shovel", 1})
inv:add_stack({"@aurailus:basictools:flint_shovel", 1})
end)
end

View File

@ -0,0 +1,6 @@
{
"name": "@aurailus:crazyblocks",
"description": "Various objects for testing block interactions.",
"version": "1.0.0",
"depends": ["zeus:default", "@aurailus:inventory", "@aurailus:hot_wheel"]
}

Binary file not shown.

View File

@ -0,0 +1,10 @@
zepha.register_blockmodel("@aurailus:crazyblocks:box", {
mesh = "@aurailus:crazyblocks:box.b3d"
})
zepha.register_block("@aurailus:crazyblocks:box", {
name = "Box",
model = "base:block",
textures = {"zeus:default:oak_log_side", "zeus:default:oak_planks"},
on_interact_client = function() inventory.open_chest() end
})

View File

@ -0,0 +1,35 @@
runfile(_PATH .. "chest")
local function stacker_action(pos)
local v = V(0, 1, 0)
while zepha.get_block(pos + v) == "@aurailus:crazyblocks:stacker" do v = v + V(0, 1, 0) end
zepha.set_block(pos + v, "@aurailus:crazyblocks:stacker")
end
local function inventory_action()
inventory.open_inventory()
end
zepha.register_block("@aurailus:crazyblocks:stacker", {
name = "Stacker",
model = "base:block",
textures = {"zeus:default:oak_planks"},
on_interact = stacker_action,
on_interact_client = stacker_action
})
zepha.register_block("@aurailus:crazyblocks:inventory", {
name = "Open Inventory",
model = "base:block",
textures = {"zeus:default:cobblestone"},
on_interact_client = inventory_action
})
if zepha.server then
zepha.register_on("new_player", function(player)
player:get_inventory():get_list("hot_wheel_1"):add_stack({"base:hand", 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:box", 1})
end)
end

View File

@ -40,8 +40,7 @@ local function select_slot(n)
for i, list in ipairs(api.lists) do list.visible = i ~= n end
for i, label in ipairs(api.labels) do label.visible = i ~= n end
local inv = zepha.player:get_inventory():get_list("hot_wheel_" .. slot)
if inv then zepha.player:set_selected_block(inv:get_stack(item).name) end
zepha.player:set_wield_list("hot_wheel_" .. slot);
if not rotating then position() end
end
@ -50,8 +49,7 @@ local function select_item(n)
local offset = slot - 1
api.list_expanded_indicator.position = { 2 + 18 * (item - 1), 0 }
local inv = zepha.player:get_inventory():get_list("hot_wheel_" .. slot)
if inv then zepha.player:set_selected_block(inv:get_stack(item).name) end
zepha.player:set_wield_index(item)
end
select_slot(1)

View File

@ -6,4 +6,26 @@ zepha.register_on("new_player", function(p)
inv:add_list("hot_wheel_4", 5, 5)
inv:add_list("hot_wheel_5", 5, 5)
inv:add_list("hot_wheel_6", 5, 5)
-- -- Get hot wheel
-- local invs = {
-- inv:get_list("hot_wheel_1"),
-- inv:get_list("hot_wheel_2"),
-- inv:get_list("hot_wheel_3"),
-- inv:get_list("hot_wheel_4"),
-- inv:get_list("hot_wheel_5"),
-- inv:get_list("hot_wheel_6")
-- }
--
-- for _,inv in pairs(invs) do
-- inv.allow_take = function() return 0 end
--
-- inv.allow_put = function(slot, item)
-- zepha.delay(function()
-- -- This delay is necessary to avoid the engine overwriting it with nothing
-- inv:set_stack(slot, item)
-- end, 0)
-- return 0
-- end
-- end
end)

View File

@ -1,15 +1,19 @@
zepha.register_block("zeus:default:bush_stem", {
visible = true,
culls = false,
name = "Bush Stem",
culls = false,
model = "base:cross_large",
textures = {
"zeus:default:bush_stem"
},
lowdef_render = false,
toughness = {
hand = 0.3,
axe = 0.1
textures = { "zeus:default:bush_stem" },
far_render = false,
tool_props = {
health = 5,
multipliers = {
snap = 1.5,
grab = 1.0,
_other = 0.5
}
},
yields = "zeus:materials:stick"
})

View File

@ -1,10 +1,17 @@
zepha.register_block("zeus:default:cobblestone", {
name = "Cobblestone",
model = "base:block",
textures = {"zeus:default:cobblestone"},
toughness = {
hand = 14,
pick = 3
tool_props = {
health = 25,
multipliers = {
crack = 1.8,
smash = 2.0,
_other = 0.25
}
},
yields = "zeus:default:cobblestone"
})

View File

@ -1,11 +1,16 @@
zepha.register_block("zeus:default:dirt", {
name = "Dirt",
model = "base:block",
textures = {"zeus:default:dirt"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
tool_props = {
health = 25,
multipliers = {
scoop = 2.0,
smash = 0,
}
},
yields = "zeus:default:dirt",
})

View File

@ -1,5 +1,6 @@
zepha.register_block("zeus:default:grass", {
name = "Grass",
model = "base:block_foliage",
textures = {
"tint(0, zeus:default:grass_top)",
@ -7,45 +8,49 @@ zepha.register_block("zeus:default:grass", {
"tint(0, zeus:default:grass_side_under, zeus:default:grass_side_under_mask)",
"tint(0, zeus:default:grass_floating)",
},
lowdef_textures = {
far_textures = {
"tint(0, zeus:default:grass_top)",
"zeus:default:dirt",
"tint(0, zeus:default:grass_side_ld, zeus:default:grass_side_ld_mask)"
},
toughness = {
hand = 3,
shovel = 1,
pick = 2
tool_props = {
health = 25,
multipliers = {
scoop = 2.0,
smash = 0,
}
},
yields = function()
if math.random() >= 0.5 then return "zeus:default:dirt"
else return "zeus:materials:plant_fibre" end
end
})
zepha.register_block("zeus:default:grass_slab", {
name = "Grass Slab",
model = "base:block_slab_foliage",
textures = {
"tint(0, zeus:default:grass_top)",
"zeus:default:dirt",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_floating)",
},
culls = false,
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
selection_box = {
{0, 0, 0, 1, 0.5, 1}
},
collision_box = {
{0, 0, 0, 1, 0.5, 1}
},
yields = "zeus:default:grass_slab"
})
-- zepha.register_block("zeus:default:grass_slab", {
-- name = "Grass Slab",
-- model = "base:block_slab_foliage",
-- textures = {
-- "tint(0, zeus:default:grass_top)",
-- "zeus:default:dirt",
-- "tint(0, zeus:default:grass_top)",
-- "tint(0, zeus:default:grass_top)",
-- "tint(0, zeus:default:grass_top)",
-- "tint(0, zeus:default:grass_top)",
-- "tint(0, zeus:default:grass_floating)",
-- },
-- culls = false,
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- selection_box = {
-- {0, 0, 0, 1, 0.5, 1}
-- },
-- collision_box = {
-- {0, 0, 0, 1, 0.5, 1}
-- },
-- yields = "zeus:default:grass_slab"
-- })

View File

@ -1,19 +1,25 @@
zepha.register_block("zeus:default:leaves", {
visible = true,
culls = false,
light_propagates = true,
name = "Leaves",
culls = false,
model = "base:leaf_like",
textures = {
"tint(0, zeus:default:leaves)",
"tint(0, zeus:default:leaves_puff)"
},
lowdef_textures = {
far_textures = {
"tint(0, zeus:default:leaves_opaque)",
},
toughness = {
hand = 1,
axe = 0.2,
tool_props = {
health = 5,
multipliers = {
snap = 2.0,
cut = 2.0
}
},
light_propagates = true,
yields = "zeus:materials:stick"
})

View File

@ -1,11 +1,16 @@
zepha.register_block("zeus:default:sand", {
name = "Sand",
model = "base:block",
textures = {"zeus:default:sand"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
tool_props = {
health = 8,
multipliers = {
scoop = 2.0,
smash = 0
}
},
yields = "zeus:default:sand"
})

View File

@ -1,14 +1,21 @@
zepha.register_block("zeus:default:sandstone", {
name = "Sandstone",
model = "base:block",
textures = {
"zeus:default:sandstone_top",
"zeus:default:sandstone_top",
"zeus:default:sandstone"
},
toughness = {
hand = 14,
pick = 3
tool_props = {
health = 20,
multipliers = {
crack = 1.8,
smash = 2.0,
_other = 0.25
}
},
yields = "zeus:default:sand"
})

View File

@ -1,11 +1,18 @@
zepha.register_block("zeus:default:stone", {
name = "Stone",
model = "base:block",
textures = {"zeus:default:stone"},
toughness = {
hand = 14,
pick = 3
tool_props = {
health = 35,
multipliers = {
crack = 1.8,
smash = 1.0,
_other = 0
}
},
yields = function()
if math.random() >= 0.5 then return "zeus:default:cobblestone"
else return "zeus:materials:rock" end

View File

@ -1,20 +1,26 @@
for i = 1, 5, 1 do
zepha.register_block("zeus:default:tallgrass_" .. i, {
name = "Tall Grass",
culls = false,
solid = false,
name = "Tall Grass",
model = "base:cross_plant",
textures = { "tint(0, zeus:default:tallgrass_"..i..")" },
far_render = false,
selection_box = {{1/16, 0, 1/16, 15/16, 0.30 + i * 0.1, 15/16}},
tool_props = {
health = 5,
multipliers = {
snap = 1.8,
grab = 1.2,
_other = 0.35
}
},
light_propagates = true,
textures = {
"tint(0, zeus:default:tallgrass_"..i..")"
},
lowdef_render = false,
selection_box = {
{1/16, 0, 1/16, 15/16, 0.30 + i * 0.1, 15/16}
},
toughness = {
hand = 0
},
yields = function(pos)
if math.random() > 0.8 then return "zeus:materials:plant_fibre" end
end

View File

@ -1,14 +1,22 @@
zepha.register_block("zeus:default:wood", {
name = "Log",
model = "base:block",
textures = {
"zeus:default:oak_log_top",
"zeus:default:oak_log_top",
"zeus:default:oak_log_side"
},
toughness = {
hand = 5,
axe = 3,
tool_props = {
health = 30,
multipliers = {
chop = 2.0,
crack = 1.7,
grab = 0,
_other = 0.5
}
},
yields = "zeus:default:wood"
})

View File

@ -28,4 +28,11 @@ zepha.register_keybind("zeus:default:double_jump_fly", {
if press - last_press < 0.25 then toggleFlying() end
last_press = press;
end
})
})
-- if (zepha.client) then
-- zepha.delay(function()
-- zepha.get_hit_impact(zepha.player, "zeus:default:stone")
-- return true
-- end, 1)
-- end

View File

@ -1,48 +1,52 @@
-- Register the inventory menu and keybind
zepha.register_keybind("zeus:inventory:open_inventory", {
description = "Open Inventory",
default = zepha.keys.e,
on_press = function()
if zepha.player.menu_state == "" do
zepha.player:open_menu([[
body[body]
background: #0003
local chest = zepha.build_gui(function()
return Gui.Body {
background = "#0003",
rect[inventory]
position: 50% 50%
position_anchor: 50% 32%
size: 218px 160px
callbacks = {
primary = function() zepha.player:close_menu() end,
},
rect[inv_background]
position: 0px 50px
size: 218px 100px
padding: 20px 10px 8px 10px
background: zeus:inventory:inventory
Gui.Rect {
key = "inventory",
position = { pc(50), pc(50) },
position_anchor = { pc(50), pc(32) },
size = { 218, 160 },
inventory
source: current_player
list: main
position: 1px 1px
slot_spacing: 2px 2px
end
end
Gui.Rect {
key = "inventory_background",
rect[chest_background]
position: 0px -48px
size: 218px 100px
padding: 20px 10px 8px 10px
background: zeus:inventory:chest
position = { 0, 50 },
size = { 218, 100 },
padding = { 20, 10, 8, 10 },
background = "zeus:inventory:inventory",
inventory
source: current_player
list: main
position: 1px 1px
slot_spacing: 2px 2px
end
end
end
end
]])
else zepha.player:close_menu() end
Gui.InventoryList {
position = { 1, 1 },
slot_spacing = { 2, 2 },
source = "current_player",
list = "main",
}
},
Gui.Rect {
key = "chest_background",
position = { 0, -48 },
size = { 218, 100 },
padding = { 20, 10, 8, 10 },
background = "zeus:inventory:chest",
Gui.InventoryList {
position = { 1, 1 },
slot_spacing = { 2, 2 },
source = "current_player",
list = "main",
}
}
}
}
})
end)
inventory.open_chest = function()
zepha.player:show_menu(chest)
end

Some files were not shown because too many files have changed in this diff Show More