BIG BOI REFACTOR FOR MULTIDIMENSIONS - Doesn't segfault so i'm commit~

master
Nicole Collings 2020-07-30 22:07:00 -07:00
parent 38b75c212b
commit 6a90bb4875
159 changed files with 3533 additions and 3715 deletions

View File

@ -1,14 +1,16 @@
zepha.player:set_hud(zepha.build_gui(function()
return Gui.Body {
background = "base:viginette",
zepha.after(function()
zepha.player:set_hud(zepha.build_gui(function()
return Gui.Body {
background = "base:viginette",
Gui.Rect {
key = "crosshair",
position = { pc(50), pc(50) },
position_anchor = { pc(50), pc(50) },
size = { 22 / 3, 22 / 3 },
Gui.Rect {
key = "crosshair",
position = { pc(50), pc(50) },
position_anchor = { pc(50), pc(50) },
size = { 22 / 3, 22 / 3 },
background = "base:crosshair"
background = "base:crosshair"
}
}
}
end))
end))
end, 0)

View File

@ -3,4 +3,4 @@ runfile(_PATH .. "player_interact")
runfile(_PATH .. "inventory")
runfile(_PATH .. "tools")
if zepha.player then runfile(_PATH .. "hud") end
if zepha.client then runfile(_PATH .. "hud") end

View File

@ -53,17 +53,13 @@ add_library(Zepha_Core
game/entity/AnimationState.h
game/entity/AnimChannel.cpp
game/entity/AnimChannel.h
game/entity/Collidable.cpp
game/entity/Collidable.h
game/entity/engine/BlockCrackEntity.cpp
game/entity/engine/BlockCrackEntity.h
game/entity/engine/ParticleEntity.cpp
game/entity/engine/ParticleEntity.h
game/entity/engine/PlayerEntity.h
game/entity/engine/WireframeEntity.cpp
game/entity/engine/WireframeEntity.h
game/entity/Entity.cpp
game/entity/Entity.h
game/entity/DrawableEntity.cpp
game/entity/DrawableEntity.h
game/entity/Model.cpp
game/entity/Model.h
game/entity/ModelAnimation.cpp
@ -142,12 +138,12 @@ add_library(Zepha_Core
game/hud/GuiBuilder.cpp
game/hud/GuiBuilder.h
game/hud/SerialGui.h
game/inventory/Inventory.cpp
game/inventory/Inventory.h
game/inventory/ServerInventory.cpp
game/inventory/ServerInventory.h
game/inventory/InventoryList.cpp
game/inventory/InventoryList.h
game/inventory/InventoryRefs.cpp
game/inventory/InventoryRefs.h
game/inventory/ServerInventoryRefs.cpp
game/inventory/ServerInventoryRefs.h
game/inventory/ItemStack.cpp
game/inventory/ItemStack.h
game/inventory/LocalInventory.cpp
@ -178,8 +174,8 @@ add_library(Zepha_Core
game/scene/world/LocalWorld.h
game/scene/world/MeshGenStream.cpp
game/scene/world/MeshGenStream.h
game/scene/world/Player.cpp
game/scene/world/Player.h
game/scene/world/LocalPlayer.cpp
game/scene/world/LocalPlayer.h
game/scene/world/Schematic.cpp
game/scene/world/Schematic.h
game/scene/world/World.cpp
@ -200,12 +196,8 @@ add_library(Zepha_Core
lua/LuaMod.h
lua/LuaParser.cpp
lua/LuaParser.h
lua/modules/BaseModule.h
lua/modules/Block.cpp
lua/modules/Block.h
lua/modules/BaseModule.h
lua/modules/create_structure.h
lua/modules/Entity.cpp
lua/modules/Entity.h
lua/modules/mSetGui.h
lua/modules/mStartGame.h
lua/modules/Register.cpp
@ -225,19 +217,14 @@ add_library(Zepha_Core
lua/ServerModHandler.cpp
lua/ServerModHandler.h
lua/usertype/cAnimationManager.h
lua/usertype/cInventoryRef.h
lua/usertype/cItemStack.h
lua/usertype/cLuaEntity.h
lua/usertype/LocalLuaAnimationManager.cpp
lua/usertype/LocalLuaAnimationManager.h
lua/usertype/LocalLuaEntity.cpp
lua/usertype/LocalLuaEntity.h
lua/usertype/LocalLuaInventory.cpp
lua/usertype/LocalLuaInventory.h
lua/usertype/LocalLuaInventoryList.cpp
lua/usertype/LocalLuaInventoryList.h
lua/usertype/LocalLuaPlayer.cpp
lua/usertype/LocalLuaPlayer.h
lua/usertype/Player.cpp
lua/usertype/Player.h
lua/usertype/LuaGuiElement.cpp
lua/usertype/LuaGuiElement.h
lua/usertype/LuaItemStack.cpp
@ -246,17 +233,14 @@ add_library(Zepha_Core
lua/usertype/ServerLocalLuaEntity.h
lua/usertype/ServerLuaEntity.cpp
lua/usertype/ServerLuaEntity.h
lua/usertype/ServerLuaInventory.cpp
lua/usertype/ServerLuaInventory.h
lua/usertype/ServerLuaInventoryList.cpp
lua/usertype/ServerLuaInventoryList.h
lua/usertype/ServerLuaPlayer.cpp
lua/usertype/ServerLuaPlayer.h
lua/usertype/Inventory.cpp
lua/usertype/Inventory.h
lua/usertype/InventoryList.cpp
lua/usertype/InventoryList.h
lua/usertype/sLuaEntity.h
net/Address.h
net/client/ClientNetworkInterpreter.cpp
net/client/ClientNetworkInterpreter.h
net/client/NetPlayerField.h
net/client/ServerConnection.cpp
net/client/ServerConnection.h
net/Deserializer.h
@ -275,10 +259,10 @@ add_library(Zepha_Core
net/server/asset/ServerTexture.h
net/server/config/ServerConfig.cpp
net/server/config/ServerConfig.h
net/server/conn/ClientList.cpp
net/server/conn/ClientList.h
net/server/conn/ServerClient.cpp
net/server/conn/ServerClient.h
net/server/conn/ServerClients.cpp
net/server/conn/ServerClients.h
net/server/conn/ServerPlayer.cpp
net/server/conn/ServerPlayer.h
net/server/LocalServerInstance.cpp
net/server/LocalServerInstance.h
net/server/Server.cpp
@ -320,7 +304,25 @@ add_library(Zepha_Core
world/fs/FileManipulator.h
world/LocalDimension.cpp
world/LocalDimension.h
world/Target.h
world/Target.h
world/ServerDimension.cpp
world/ServerDimension.h
lua/usertype/Target.cpp lua/usertype/Target.h lua/usertype/BaseUsertype.h lua/usertype/SubgameUsertype.h world/Target.cpp)
lua/usertype/Target.cpp
lua/usertype/Target.h
lua/usertype/BaseUsertype.h
lua/usertype/SubgameUsertype.h
world/Target.cpp
lua/usertype/Dimension.cpp
lua/usertype/Dimension.h
game/scene/world/Player.cpp
game/scene/world/Player.h
game/inventory/InventoryRefs.cpp
game/inventory/InventoryRefs.h
game/inventory/Inventory.cpp
game/inventory/Inventory.h
game/entity/Entity.cpp
game/entity/Entity.h
game/entity/Collision.cpp
game/entity/Collision.h
net/server/conn/ServerClient.cpp
net/server/conn/ServerClient.h lua/modules/Dimension.cpp lua/modules/Dimension.h)

View File

@ -15,8 +15,12 @@ LocalSubgame::LocalSubgame(const std::string& texPath) :
textures.loadDirectory(texPath);
}
void LocalSubgame::init(LocalWorld &world, Player& player, ClientState& state) {
lua->init(world, player, state);
void LocalSubgame::initApi(LocalWorld &world, ClientState& state) {
lua->init(world, state);
}
void LocalSubgame::loadPlayer(std::shared_ptr<LocalPlayer> player) {
lua->loadPlayer(player);
}
void LocalSubgame::update(double delta) {

View File

@ -15,7 +15,7 @@
#include "texture/TextureAtlas.h"
#include "../lua/LocalLuaParser.h"
class Player;
class LocalPlayer;
class LocalWorld;
class ClientState;
@ -24,7 +24,8 @@ public:
explicit LocalSubgame(const std::string& texPath);
~LocalSubgame();
void init(LocalWorld &world, Player& player, ClientState& state);
void initApi(LocalWorld &world, ClientState& state);
void loadPlayer(std::shared_ptr<LocalPlayer> player);
void update(double delta);
std::string texPath;
@ -36,6 +37,7 @@ public:
ModelStore models;
TextureAtlas textures;
private:
std::unique_ptr<LocalLuaParser> lua;
std::unique_ptr<LocalBiomeAtlas> biomes;
std::unique_ptr<LocalDefinitionAtlas> defs;

View File

@ -6,7 +6,7 @@
#include "ServerSubgame.h"
#include "../net/server/conn/ClientList.h"
#include "../net/server/conn/ServerClients.h"
ServerSubgame::ServerSubgame(const std::string& subgame, unsigned int seed) :
subgamePath("subgames/" + subgame + "/"),
@ -23,7 +23,7 @@ void ServerSubgame::init(ServerWorld &world) {
lua->init(world, subgamePath);
}
void ServerSubgame::update(double delta, ClientList& clients) {
void ServerSubgame::update(double delta) {
lua->update(delta);
}

View File

@ -14,7 +14,7 @@
#include "../net/server/asset/AssetStorage.h"
class ServerWorld;
class ClientList;
class ServerClients;
class ServerSubgame : public Subgame {
public:
@ -22,7 +22,7 @@ public:
~ServerSubgame();
void init(ServerWorld& world);
void update(double delta, ClientList& clients);
void update(double delta);
std::string subgamePath;
@ -30,9 +30,10 @@ public:
ServerBiomeAtlas& getBiomes() override { return *biomes; };
ServerLuaParser& getParser() override { return *lua; };
//private:
AssetStorage assets;
private:
std::unique_ptr<ServerLuaParser> lua;
std::unique_ptr<ServerBiomeAtlas> biomes;
std::unique_ptr<ServerDefinitionAtlas> defs;

View File

@ -20,15 +20,15 @@ MapGen::MapGen(DefinitionAtlas& defs, BiomeAtlas& biomes, unsigned int seed) :
biomes(biomes),
props(seed) {}
std::unique_ptr<MapGen::ChunkMap> MapGen::generateChunk(glm::ivec3 pos) {
return generateArea(pos);
std::unique_ptr<MapGen::ChunkMap> MapGen::generateChunk(glm::ivec3 pos, unsigned int dimension) {
return generateArea(pos, dimension, 1);
}
std::unique_ptr<MapGen::ChunkMap> MapGen::generateMapBlock(glm::ivec3 pos) {
return generateArea(Space::Chunk::world::fromMapBlock(pos), 4);
std::unique_ptr<MapGen::ChunkMap> MapGen::generateMapBlock(glm::ivec3 pos, unsigned int dimension) {
return generateArea(Space::Chunk::world::fromMapBlock(glm::vec3(pos)), dimension, 4);
}
std::unique_ptr<MapGen::ChunkMap> MapGen::generateArea(glm::ivec3 origin, unsigned int size) {
std::unique_ptr<MapGen::ChunkMap> MapGen::generateArea(glm::ivec3 origin, unsigned int dimension, unsigned int size) {
Job job(origin, size);
// Build Biome Prop Maps

View File

@ -44,9 +44,9 @@ public:
MapGen(DefinitionAtlas& atlas, BiomeAtlas& biome, unsigned int seed);
std::unique_ptr<ChunkMap> generateChunk(glm::ivec3 pos);
std::unique_ptr<ChunkMap> generateMapBlock(glm::ivec3 pos);
std::unique_ptr<ChunkMap> generateArea(glm::ivec3 origin, unsigned int size = 1);
std::unique_ptr<ChunkMap> generateChunk(glm::ivec3 pos, unsigned int dimension);
std::unique_ptr<ChunkMap> generateMapBlock(glm::ivec3 pos, unsigned int dimension);
std::unique_ptr<ChunkMap> generateArea(glm::ivec3 origin, unsigned int dimension, unsigned int size = 1);
private:
// struct SunlightNode {
// SunlightNode(unsigned short index, Chunk* chunk) : index(index), chunk(chunk) {};

View File

@ -1,29 +0,0 @@
//
// Created by aurailus on 2019-10-28.
//
#pragma once
#include <glm/vec3.hpp>
#include "../../def/item/SelectionBox.h"
class LocalWorld;
class LocalSubgame;
class Collidable {
public:
Collidable(LocalWorld& world, LocalSubgame& defs, const SelectionBox& collisionBox);
void moveCollide(float stepUpAmount = 0);
bool isOnGround();
glm::vec3 pos {};
glm::vec3 vel {};
protected:
LocalWorld& world;
LocalSubgame& game;
SelectionBox collisionBox {};
private:
bool collidesAt(glm::vec3& pos, float stepUpMax = 0);
};

View File

@ -1,87 +1,90 @@
//
// Created by aurailus on 2019-10-28.
// Created by aurailus on 2020-07-30.
//
#include <glm/common.hpp>
#include <algorithm>
#include "Collidable.h"
#include "../../def/LocalSubgame.h"
#include "Collision.h"
#include "../../def/Subgame.h"
#include "../../world/Dimension.h"
#include "../../def/item/BlockDef.h"
#include "../scene/world/LocalWorld.h"
#include "../../def/LocalDefinitionAtlas.h"
#include "../../def/DefinitionAtlas.h"
#include "../../def/item/SelectionBox.h"
Collidable::Collidable(LocalWorld &world, LocalSubgame& defs, const SelectionBox& collisionBox) :
world(world),
game(defs),
collisionBox(collisionBox) {}
bool Collision::isOnGround(Subgame& game, Dimension& dim, SelectionBox& collision, glm::vec3 pos, glm::vec3 vel) {
pos.y -= 0.05f;
return collidesAt(game, dim, collision, pos) && vel.y <= 0;
}
void Collidable::moveCollide(float stepUpAmount) {
void Collision::moveCollide(Subgame& game, Dimension& dim, SelectionBox& collision, glm::vec3& pos, glm::vec3& vel, float stepUpAmount) {
const static double increment = 0.05;
double moved = 0;
for (int i = 0; i < fabs(vel.y) / increment; i++) {
double move = fmax(fmin(increment, fabs(vel.y) - moved), 0);
for (int i = 0; i < std::abs(vel.y) / increment; i++) {
double move = std::max(std::min(increment, std::abs(vel.y) - moved), 0.);
moved += increment;
glm::vec3 newPos = pos;
newPos.y += move * (vel.y < 0 ? -1 : 1);
if (!collidesAt(newPos)) pos = newPos;
if (!collidesAt(game, dim, collision, newPos)) pos = newPos;
else if (vel.y > 0) vel.y = 0;
}
moved = 0;
for (int i = 0; i < fabs(vel.x) / increment; i++) {
double move = fmax(fmin(increment, fabs(vel.x) - moved), 0);
for (int i = 0; i < std::abs(vel.x) / increment; i++) {
double move = std::max(std::min(increment,std::abs(vel.x) - moved), 0.);
moved += increment;
glm::vec3 newPos = pos;
newPos.x += move * (vel.x < 0 ? -1 : 1);
if (!collidesAt(newPos, stepUpAmount)) pos = newPos;
if (!collidesAt(game, dim, collision, newPos, stepUpAmount)) pos = newPos;
else vel.x = 0;
}
moved = 0;
for (int i = 0; i < fabs(vel.z) / increment; i++) {
double move = fmax(fmin(increment, fabs(vel.z) - moved), 0);
for (int i = 0; i < std::abs(vel.z) / increment; i++) {
double move = std::max(std::min(increment, std::abs(vel.z) - moved), 0.);
moved += increment;
glm::vec3 newPos = pos;
newPos.z += move * (vel.z < 0 ? -1 : 1);
if (!collidesAt(newPos, stepUpAmount)) pos = newPos;
if (!collidesAt(game, dim, collision, newPos, stepUpAmount)) pos = newPos;
else vel.z = 0;
}
}
bool Collidable::collidesAt(glm::vec3& pos, float stepUpMax) {
bool Collision::collidesAt(Subgame& game, Dimension& dim, SelectionBox& collision, glm::vec3& pos, float stepUpMax) {
// Find the minimum vertical increase needed to step up
float stepUpAmount = 0;
if (stepUpMax > 0) {
glm::vec3 offset {};
offset.x = collisionBox.a.x;
offset.x = collision.a.x;
while (true) {
offset.y = collisionBox.a.y;
offset.y = collision.a.y;
while (true) {
offset.z = collisionBox.a.z;
offset.z = collision.a.z;
while (true) {
glm::vec3 offsetPos = glm::floor(pos + offset);
auto &def = game.defs->blockFromId(world.getBlock(offsetPos));
auto &def = game.getDefs().blockFromId(dim.getBlock(offsetPos));
if (def.solid)
for (auto &cBox : def.cBoxes)
stepUpAmount = std::fmax(cBox.b.y + offsetPos.y - pos.y, stepUpAmount);
if (offset.z == collisionBox.b.z) break;
offset.z = std::fmin(std::floor(offset.z + 1), collisionBox.b.z);
if (offset.z == collision.b.z) break;
offset.z = std::fmin(std::floor(offset.z + 1), collision.b.z);
}
if (offset.y == collisionBox.a.y + stepUpMax + 0.025f) break; // Hack for precision errors
offset.y = std::fmin(std::floor(offset.y + 1), collisionBox.a.y + stepUpMax + 0.025f);
if (offset.y == collision.a.y + stepUpMax + 0.025f) break; // Hack for precision errors
offset.y = std::fmin(std::floor(offset.y + 1), collision.a.y + stepUpMax + 0.025f);
}
if (offset.x == collisionBox.b.x) break;
offset.x = std::fmin(std::floor(offset.x + 1), collisionBox.b.x);
if (offset.x == collision.b.x) break;
offset.x = std::fmin(std::floor(offset.x + 1), collision.b.x);
}
}
@ -89,18 +92,18 @@ bool Collidable::collidesAt(glm::vec3& pos, float stepUpMax) {
if (stepUpAmount > stepUpMax) return true;
if (stepUpAmount > 0) pos.y += stepUpAmount + 0.025; // Hack for precision errors
SelectionBox collidableBox = {collisionBox.a + pos, collisionBox.b + pos};
SelectionBox collidableBox = {collision.a + pos, collision.b + pos};
glm::vec3 offset {};
// Regular collision check
offset.x = collisionBox.a.x;
offset.x = collision.a.x;
while (true) {
offset.y = collisionBox.a.y;
offset.y = collision.a.y;
while (true) {
offset.z = collisionBox.a.z;
offset.z = collision.a.z;
while (true) {
glm::vec3 offsetPos = glm::floor(pos + offset);
auto& def = game.defs->blockFromId(world.getBlock(offsetPos));
auto& def = game.getDefs().blockFromId(dim.getBlock(offsetPos));
if (def.solid) {
for (auto &cBox : def.cBoxes) {
@ -112,20 +115,15 @@ bool Collidable::collidesAt(glm::vec3& pos, float stepUpMax) {
}
}
if (offset.z == collisionBox.b.z) break;
offset.z = (std::min)(std::floor(offset.z + 1), collisionBox.b.z);
if (offset.z == collision.b.z) break;
offset.z = (std::min)(std::floor(offset.z + 1), collision.b.z);
}
if (offset.y == collisionBox.b.y) break;
offset.y = (std::min)(std::floor(offset.y + 1), collisionBox.b.y);
if (offset.y == collision.b.y) break;
offset.y = (std::min)(std::floor(offset.y + 1), collision.b.y);
}
if (offset.x == collisionBox.b.x) break;
offset.x = (std::min)(std::floor(offset.x + 1), collisionBox.b.x);
if (offset.x == collision.b.x) break;
offset.x = (std::min)(std::floor(offset.x + 1), collision.b.x);
}
return false;
}
bool Collidable::isOnGround() {
glm::vec3 test = {pos.x, pos.y - 0.05f, pos.z};
return collidesAt(test) && vel.y <= 0;
}
}

View File

@ -0,0 +1,18 @@
//
// Created by aurailus on 2020-07-30.
//
#pragma once
#include <glm/vec3.hpp>
class Subgame;
class Dimension;
class SelectionBox;
class Collision {
public:
static bool isOnGround(Subgame& game, Dimension& dim, SelectionBox& collision, glm::vec3 pos, glm::vec3 vel);
static void moveCollide(Subgame& game, Dimension& dimension, SelectionBox& collision, glm::vec3& pos, glm::vec3& vel, float stepUpAmount = 0);
static bool collidesAt(Subgame& game, Dimension& dimension, SelectionBox& collision, glm::vec3& pos, float stepUpMax = 0);
};

View File

@ -0,0 +1,157 @@
//
// Created by aurailus on 25/11/18.
//
#include <utility>
#include <glm/gtc/matrix_transform.hpp>
#include "DrawableEntity.h"
#include "Model.h"
#include "AnimationSegment.h"
#include "../graph/Renderer.h"
#include "../graph/meshtypes/EntityMesh.h"
DrawableEntity::DrawableEntity() : model(std::make_shared<Model>()) {}
DrawableEntity::DrawableEntity(std::shared_ptr<Model> model) :
animState(*model),
model(model) {}
void DrawableEntity::setModel(std::shared_ptr<Model> model) {
animState = AnimationState(*model);
this->model = std::move(model);
animState.setPlaying(true);
}
void DrawableEntity::update(double delta) {
animState.update(delta);
float factor = static_cast<float>(fmin(delta * 8, 1));
visualPosition = visualPosition * (1 - factor) + pos * factor;
visualVisualOffset = visualVisualOffset * (1 - factor) + visualOff * factor;
visualRotation = visualRotation * (1 - factor) + rot * factor;
visualScale = visualScale * (1 - factor) + scale * factor;
}
void DrawableEntity::setPos(glm::vec3 position) {
visualPosition = position;
Entity::setPos(position);
}
void DrawableEntity::interpPos(glm::vec3 position) {
Entity::setPos(position);
}
void DrawableEntity::setVisualOffset(glm::vec3 vs) {
visualVisualOffset = vs;
Entity::setVisualOffset(vs);
}
void DrawableEntity::interpVisualOffset(glm::vec3 vs) {
Entity::setVisualOffset(vs);
}
void DrawableEntity::setRotateX(float rotation) {
visualRotation.x = rotation;
Entity::setRotateX(rotation);
}
void DrawableEntity::interpRotateX(float rotation) {
Entity::setRotateX(rotation);
}
void DrawableEntity::setRotateY(float rotation) {
visualRotation.y = rotation;
Entity::setRotateY(rotation);
}
void DrawableEntity::interpRotateY(float rotation) {
Entity::setRotateY(rotation);
}
void DrawableEntity::setRotateZ(float rotation) {
visualRotation.z = rotation;
Entity::setRotateZ(rotation);
}
void DrawableEntity::interpRotateZ(float rotation) {
Entity::setRotateZ(rotation);
}
void DrawableEntity::setScale(float scale) {
visualScale = glm::vec3(scale);
Entity::setScale(scale);
}
void DrawableEntity::interpScale(float scale) {
Entity::setScale(scale);
}
void DrawableEntity::setScale(glm::vec3 scale) {
visualScale = scale;
Entity::setScale(scale);
}
void DrawableEntity::interpScale(glm::vec3 scale) {
Entity::setScale(scale);
}
void DrawableEntity::setAnimations(const std::vector<AnimationSegment>& anims) {
animState.setAnimations(anims);
}
void DrawableEntity::playAnimation(const std::string &anim, bool loop) {
animState.setAnimNamed(anim, 0, loop);
}
void DrawableEntity::playRange(unsigned int start, unsigned int end, bool loop) {
animState.setAnimRange(start, end, 0, loop);
}
void DrawableEntity::setPlaying(bool playing, unsigned int offset) {
animState.setPlaying(playing);
if (offset != UINT_MAX) animState.setFrame(offset + animState.getFrame());
}
void DrawableEntity::draw(Renderer& renderer) {
if (visible) {
renderer.setModelMatrix(getModelMatrix());
model->getTransformsByFrame(animState.getFrame(), animState.getBounds(), transforms);
renderer.setBones(transforms);
for (const auto& mesh : model->meshes) mesh->draw();
}
}
glm::mat4 DrawableEntity::getModelMatrix() {
glm::mat4 model = glm::mat4(1.0);
model = glm::translate(model, visualPosition + visualVisualOffset);
model = model * getRotationMatrix();
model = glm::scale(model, visualScale);
return model;
}
glm::mat4 DrawableEntity::getRotationMatrix() {
glm::mat4 parentMatrix = (parent != nullptr ? parent->getRotationMatrix() : glm::mat4(1.0f));
glm::mat4 rotMatrix = glm::mat4(1.0f);
rotMatrix = glm::rotate(rotMatrix, glm::radians(visualRotation.x), {1, 0, 0});
rotMatrix = glm::rotate(rotMatrix, glm::radians(visualRotation.y), {0, 1, 0});
rotMatrix = glm::rotate(rotMatrix, glm::radians(visualRotation.z), {0, 0, 1});
return parentMatrix * rotMatrix;
}
void DrawableEntity::cleanup() {
model = nullptr;
}
DrawableEntity::~DrawableEntity() {
cleanup();
}

View File

@ -0,0 +1,71 @@
//
// Created by aurailus on 25/11/18.
//
#pragma once
#include <vector>
#include <memory>
#include <glm/mat4x4.hpp>
#include "Model.h"
#include "Entity.h"
#include "../graph/drawable/Drawable.h"
#include "AnimationState.h"
#include "AnimationSegment.h"
class DrawableEntity : virtual public Entity, public Drawable {
public:
DrawableEntity();
DrawableEntity(const DrawableEntity& o) = delete;
explicit DrawableEntity(std::shared_ptr<Model> model);
void update(double delta) override;
void setModel(std::shared_ptr<Model> model);
virtual void setPos(glm::vec3 position) override;
virtual void interpPos(glm::vec3 position);
virtual void setVisualOffset(glm::vec3 vs) override;
virtual void interpVisualOffset(glm::vec3 vs);
virtual void setRotateX(float rotation) override;
virtual void interpRotateX(float rotation);
virtual void setRotateY(float rotation) override;
virtual void interpRotateY(float rotation);
virtual void setRotateZ(float rotation) override;
virtual void interpRotateZ(float rotation);
virtual void setScale(float scale) override;
virtual void interpScale(float scale);
virtual void setScale(glm::vec3 scale) override;
virtual void interpScale(glm::vec3 scale);
void setAnimations(const std::vector<AnimationSegment>& anims);
void playAnimation(const std::string& anim, bool loop);
void playRange(unsigned int start, unsigned int end, bool loop);
void setPlaying(bool playing, unsigned int offset);
void draw(Renderer& renderer) override;
void cleanup();
~DrawableEntity() override;
AnimationState animState {};
DrawableEntity* parent = nullptr;
protected:
glm::mat4 getModelMatrix();
glm::mat4 getRotationMatrix();
glm::vec3 visualPosition {};
glm::vec3 visualVisualOffset {};
glm::vec3 visualRotation {};
glm::vec3 visualScale {1, 1, 1};
std::shared_ptr<Model> model;
std::vector<glm::mat4> transforms {};
};

View File

@ -1,177 +1,65 @@
//
// Created by aurailus on 25/11/18.
// Created by aurailus on 2020-07-30.
//
#include <utility>
#include <glm/gtc/matrix_transform.hpp>
#include "Entity.h"
#include "Model.h"
#include "AnimationSegment.h"
#include "../graph/Renderer.h"
#include "../graph/meshtypes/EntityMesh.h"
Entity::Entity() : model(std::make_unique<Model>()) {}
Entity::Entity(std::shared_ptr<Model> model) : animState(*model), model(model) {}
void Entity::setModel(std::shared_ptr<Model> model) {
animState = AnimationState(*model);
this->model = std::move(model);
animState.setPlaying(true);
}
void Entity::update(double delta) {
animState.update(delta);
float factor = static_cast<float>(fmin(delta * 8, 1));
visualPosition = visualPosition * (1 - factor) + position * factor;
visualVisualOffset = visualVisualOffset * (1 - factor) + visualOffset * factor;
visualRotation = visualRotation * (1 - factor) + rotation * factor;
visualScale = visualScale * (1 - factor) + scale * factor;
}
void Entity::draw(Renderer& renderer) {
if (visible) {
renderer.setModelMatrix(getModelMatrix());
model->getTransformsByFrame(animState.getFrame(), animState.getBounds(), transforms);
renderer.setBones(transforms);
for (const auto& mesh : model->meshes) mesh->draw();
}
glm::vec3 Entity::getPos() {
return pos;
}
void Entity::setPos(glm::vec3 position) {
this->visualPosition = position;
this->position = position;
this->pos = position;
}
void Entity::interpPos(glm::vec3 position) {
this->position = position;
glm::vec3 Entity::getVel() {
return vel;
}
glm::vec3 Entity::getPos() {
return position;
void Entity::setVel(glm::vec3 velocity) {
this->vel = velocity;
}
glm::vec3 Entity::getVisualOffset() {
return visualOff;
}
void Entity::setVisualOffset(glm::vec3 vs) {
this->visualVisualOffset = vs;
this->visualOffset = vs;
}
void Entity::interpVisualOffset(glm::vec3 vs){
this->visualOffset = vs;
}
glm::vec3 Entity::getVisualOffset(){
return visualOffset;
}
void Entity::setRotateX(float rotation) {
this->visualRotation.x = rotation;
this->rotation.x = rotation;
}
void Entity::interpRotateX(float rotation) {
this->rotation.x = rotation;
this->visualOff = vs;
}
float Entity::getRotateX() {
return rotation.x;
return rot.x;
}
void Entity::setRotateY(float rotation) {
this->visualRotation.y = rotation;
this->rotation.y = rotation;
}
void Entity::interpRotateY(float rotation) {
this->rotation.y = rotation;
void Entity::setRotateX(float rotation) {
this->rot.x = rotation;
}
float Entity::getRotateY() {
return rotation.y;
return rot.y;
}
void Entity::setRotateZ(float rotation) {
this->visualRotation.z = rotation;
this->rotation.z = rotation;
}
void Entity::interpRotateZ(float rotation) {
this->rotation.z = rotation;
void Entity::setRotateY(float rotation) {
this->rot.y = rotation;
}
float Entity::getRotateZ() {
return rotation.z;
return rot.z;
}
void Entity::setScale(float scale) {
this->visualScale = glm::vec3(scale);
this->scale = glm::vec3(scale);
}
void Entity::interpScale(float scale) {
this->scale = glm::vec3(scale);
}
void Entity::setScale(glm::vec3 scale) {
this->visualScale = scale;
this->scale = scale;
}
void Entity::interpScale(glm::vec3 scale) {
this->scale = scale;
void Entity::setRotateZ(float rotation) {
this->rot.z = rotation;
}
glm::vec3 Entity::getScale() {
return scale;
}
glm::mat4 Entity::getModelMatrix() {
glm::mat4 model = glm::mat4(1.0);
model = glm::translate(model, visualPosition + visualVisualOffset);
model = model * getRotationMatrix();
model = glm::scale(model, visualScale);
return model;
void Entity::setScale(float scale) {
this->scale = glm::vec3(scale);
}
glm::mat4 Entity::getRotationMatrix() {
glm::mat4 parentMatrix = (parent != nullptr ? parent->getRotationMatrix() : glm::mat4(1.0f));
glm::mat4 rotMatrix = glm::mat4(1.0f);
rotMatrix = glm::rotate(rotMatrix, glm::radians(visualRotation.x), {1, 0, 0});
rotMatrix = glm::rotate(rotMatrix, glm::radians(visualRotation.y), {0, 1, 0});
rotMatrix = glm::rotate(rotMatrix, glm::radians(visualRotation.z), {0, 0, 1});
return parentMatrix * rotMatrix;
}
void Entity::cleanup() {
model = nullptr;
}
Entity::~Entity() {
cleanup();
}
void Entity::setAnimations(const std::vector<AnimationSegment>& anims) {
animState.setAnimations(anims);
}
void Entity::playAnimation(const std::string &anim, bool loop) {
animState.setAnimNamed(anim, 0, loop);
}
void Entity::playRange(unsigned int start, unsigned int end, bool loop) {
animState.setAnimRange(start, end, 0, loop);
}
void Entity::setPlaying(bool playing, unsigned int offset) {
animState.setPlaying(playing);
if (offset != UINT_MAX) animState.setFrame(offset + animState.getFrame());
void Entity::setScale(glm::vec3 scale) {
this->scale = scale;
}

View File

@ -1,83 +1,43 @@
//
// Created by aurailus on 25/11/18.
// Created by aurailus on 2020-07-30.
//
#pragma once
#include <vector>
#include <memory>
#include <glm/vec3.hpp>
#include <glm/mat4x4.hpp>
#include "AnimationState.h"
#include "AnimationSegment.h"
#include "../graph/drawable/Drawable.h"
#include "../../def/item/SelectionBox.h"
class Model;
class Entity : public Drawable {
class Entity {
public:
Entity();
explicit Entity(std::shared_ptr<Model> model);
void setModel(std::shared_ptr<Model> model);
virtual glm::vec3 getPos();
virtual void setPos(glm::vec3 position);
void update(double delta) override;
void draw(Renderer& renderer) override;
virtual glm::vec3 getVel();
virtual void setVel(glm::vec3 velocity);
void interpPos(glm::vec3 position);
void setPos(glm::vec3 position);
glm::vec3 getPos();
virtual glm::vec3 getVisualOffset();
virtual void setVisualOffset(glm::vec3 vs);
void interpVisualOffset(glm::vec3 vs);
void setVisualOffset(glm::vec3 vs);
glm::vec3 getVisualOffset();
virtual float getRotateX();
virtual void setRotateX(float rotation);
void setRotateX(float rotation);
void interpRotateX(float rotation);
float getRotateX();
virtual float getRotateY();
virtual void setRotateY(float rotation);
void setRotateY(float rotation);
void interpRotateY(float rotation);
float getRotateY();
virtual float getRotateZ();
virtual void setRotateZ(float rotation);
void setRotateZ(float rotation);
void interpRotateZ(float rotation);
float getRotateZ();
virtual glm::vec3 getScale();
virtual void setScale(float scale);
virtual void setScale(glm::vec3 scale);
void interpScale(float scale);
void setScale(float scale);
void interpScale(glm::vec3 scale);
void setScale(glm::vec3 scale);
glm::vec3 getScale();
void setAnimations(const std::vector<AnimationSegment>& anims);
void playAnimation(const std::string& anim, bool loop);
void playRange(unsigned int start, unsigned int end, bool loop);
void setPlaying(bool playing, unsigned int offset);
void cleanup();
~Entity() override;
AnimationState animState {};
Entity* parent = nullptr;
protected:
glm::mat4 getModelMatrix();
glm::mat4 getRotationMatrix();
glm::vec3 position {};
glm::vec3 visualPosition {};
glm::vec3 visualOffset {};
glm::vec3 visualVisualOffset {};
glm::vec3 rotation {};
glm::vec3 visualRotation {};
glm::vec3 pos {};
glm::vec3 vel {};
glm::vec3 rot {};
glm::vec3 visualOff {};
glm::vec3 scale {1, 1, 1};
glm::vec3 visualScale {1, 1, 1};
std::shared_ptr<Model> model = nullptr;
std::vector<glm::mat4> transforms {};
SelectionBox collision;
};

View File

@ -1,90 +0,0 @@
//
// Created by aurailus on 14/04/19.
//
#include <glm/glm.hpp>
#include "BlockCrackEntity.h"
#include "../../../def/LocalSubgame.h"
#include "../../../def/item/MeshPart.h"
#include "../../../def/item/BlockDef.h"
#include "../../../def/texture/AtlasRef.h"
#include "../../../def/item/BlockModelVertex.h"
BlockCrackEntity::BlockCrackEntity(BlockDef &def, TextureAtlas& textureAtlas, glm::ivec3 pos) :
def(def),
textureAtlas(textureAtlas) {
maxHealth = def.health;
setPos(pos);
update();
}
void BlockCrackEntity::update() {
// 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 / static_cast<float>(maxHealth)) * 8)), 7), 0));
if (crackLevel != this->crackLevel) {
this->crackLevel = crackLevel;
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, def.model.parts[i]);
std::unique_ptr<EntityMesh> mesh = std::make_unique<EntityMesh>();
mesh->create(vertices, indices);
this->model->fromMesh(std::move(mesh));
}
}
void BlockCrackEntity::addDamage(double damage) {
damagePending += damage;
update();
}
void BlockCrackEntity::setDamage(double damage) {
double diff = damage - (this->damage + damagePending);
std::cout << diff << ", " << this->damage << ", " << damagePending << std::endl;
addDamage(diff);
}
void BlockCrackEntity::addFaces(unsigned int &indOffset, std::vector<EntityVertex> &vertices, std::vector<unsigned int> &indices, std::vector<MeshPart> &meshParts) {
for (const MeshPart& mp : meshParts) {
glm::vec4 uv;
auto ref = textureAtlas.generateCrackImage(mp.texture->name, static_cast<unsigned short>(crackLevel));
if (ref == nullptr) {
uv = textureAtlas["_missing"]->uv;
}
else uv = ref->uv;
crackedFaces.push_back(ref);
for (const BlockModelVertex &vertex : mp.vertices) {
glm::vec3 pushed_pos = vertex.pos;
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, {}, {} });
}
for (unsigned int index : mp.indices) indices.push_back(indOffset + index);
indOffset += mp.vertices.size();
}
}

View File

@ -1,36 +0,0 @@
//
// Created by aurailus on 14/04/19.
//
#pragma once
#include "../Entity.h"
class BlockDef;
class AtlasRef;
class MeshPart;
class EntityVertex;
class TextureAtlas;
class BlockCrackEntity : public Entity {
public:
BlockCrackEntity(BlockDef &def, TextureAtlas& textureAtlas, glm::ivec3 pos);
void update();
void addDamage(double damage);
void setDamage(double damage);
int maxHealth = 0;
double damage = 0;
double damagePending = 0;
double time = 0;
BlockDef& def;
private:
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;
};

View File

@ -9,7 +9,7 @@
#include "../../../def/item/BlockDef.h"
#include "../../../def/texture/AtlasRef.h"
ParticleEntity::ParticleEntity(glm::vec3 pos, BlockDef &block) {
ParticleEntity::ParticleEntity(glm::vec3 pos, BlockDef &block) : DrawableEntity(std::make_shared<Model>()) {
setPos(pos + glm::vec3(.5,.3,.5));
std::set<std::shared_ptr<AtlasRef>>& textureRefs = block.model.textureRefs;
@ -61,12 +61,12 @@ void ParticleEntity::update(double delta, glm::vec3 player) {
setPos(getPos() + velocity * glm::vec3(static_cast<float>(delta)));
double angle = -glm::degrees(std::atan2(player.z - position.z, player.x - position.x)) + 90.f;
double angle = -glm::degrees(std::atan2(player.z - pos.z, player.x - pos.x)) + 90.f;
setRotateY(static_cast<float>(angle));
velocity.y -= 32.f * delta;
}
void ParticleEntity::draw(Renderer &renderer) {
Entity::draw(renderer);
}
DrawableEntity::draw(renderer);
}

View File

@ -4,11 +4,11 @@
#pragma once
#include "../Entity.h"
#include "../DrawableEntity.h"
class BlockDef;
class ParticleEntity : public Entity {
class ParticleEntity : public DrawableEntity {
public:
ParticleEntity(glm::vec3 pos, BlockDef& block);

View File

@ -4,19 +4,19 @@
#pragma once
#include "../Entity.h"
#include "../DrawableEntity.h"
class PlayerEntity : public Entity {
class PlayerEntity : public DrawableEntity {
public:
PlayerEntity(glm::vec3 pos, unsigned int cid, const std::shared_ptr<Model>& playerModel) : cid(cid) {
setModel(playerModel);
PlayerEntity(Subgame& game, Dimension* dim, glm::vec3 pos, unsigned int id, const std::shared_ptr<Model>& model) :
DrawableEntity(model), id(id) {
setPos(pos);
}
unsigned int getCid() {
return cid;
unsigned int getId() {
return id;
}
private:
unsigned int cid;
unsigned int id;
};

View File

@ -5,20 +5,11 @@
#include "WireframeEntity.h"
#include "../Model.h"
#include "../Entity.h"
#include "../DrawableEntity.h"
#include "../../graph/meshtypes/EntityMesh.h"
WireframeEntity::WireframeEntity(const std::vector<SelectionBox>& boxes, float width, glm::vec3 color) :
width(width),
color(color) {
model = std::make_shared<Model>();
buildMesh(boxes);
}
void WireframeEntity::updateMesh(const std::vector<SelectionBox>& boxes, float width) {
this->width = width;
buildMesh(boxes);
}

View File

@ -4,15 +4,14 @@
#pragma once
#include "../Entity.h"
#include "../DrawableEntity.h"
#include "../../../def/item/SelectionBox.h"
#include "../../graph/meshtypes/EntityVertex.h"
class WireframeEntity : public Entity {
class WireframeEntity : public DrawableEntity {
public:
WireframeEntity() = default;
WireframeEntity(const std::vector<SelectionBox>& boxes, float width, glm::vec3 color);
WireframeEntity(glm::vec3 color) : DrawableEntity(std::make_shared<Model>()), color(color) {};
void updateMesh(const std::vector<SelectionBox>& boxes, float width);
private:

View File

@ -4,26 +4,23 @@
#include "DebugGui.h"
#include "../../def/LocalSubgame.h"
#include "../scene/world/Player.h"
#include "../scene/world/LocalPlayer.h"
#include "../../def/texture/Font.h"
#include "../../def/gen/BiomeDef.h"
#include "../../def/item/BlockDef.h"
#include "components/basic/GuiText.h"
#include "../scene/world/LocalWorld.h"
#include "../../def/gen/LocalBiomeAtlas.h"
#include "../../def/LocalDefinitionAtlas.h"
#include "components/compound/GuiLabelledGraph.h"
DebugGui::DebugGui(glm::vec2 bufferSize, LocalSubgame& defs) :
displayMode(0) {
DebugGui::DebugGui(glm::vec2 bufferSize, LocalSubgame& game, LocalWorld& world) :
game(game),
world(world) {
auto fpsHistogramRef = defs.textures["histogram"];
auto genericHistogramRef = defs.textures["histogram_white"];
auto fontRef = defs.textures["font"];
auto fpsHistogramRef = game.textures["histogram"];
auto genericHistogramRef = game.textures["histogram_white"];
auto fontRef = game.textures["font"];
Font f(defs.textures, fontRef);
Font f(game.textures, fontRef);
auto crosshairText = std::make_shared<GuiText>("crosshairText");
crosshairText->create({2, 2}, {}, {0.2, 0.2, 0.2, 0.5}, {1, 1, 1, 1}, f);
@ -81,7 +78,7 @@ void DebugGui::positionElements(glm::vec2 bufferSize) {
get<GuiLabelledGraph>("gpuGraph")->setPos({bufferWidth - 254, 90 + 80});
}
void DebugGui::update(Player& player, LocalWorld& world, LocalSubgame& game, double fps, int /*chunks*/, int drawCalls, int ssGen, int ssPack) {
void DebugGui::update(LocalPlayer& player, double fps, int /*chunks*/, int drawCalls, int ssGen, int ssPack) {
{ //Top Right Graphs
get<GuiLabelledGraph>("fpsGraph")->pushValue(static_cast<float>(fps));
@ -105,8 +102,8 @@ void DebugGui::update(Player& player, LocalWorld& world, LocalSubgame& game, dou
}
{ //Top-left Data
unsigned int biomeID = world.getBiome(glm::floor(player.getPos()));
std::string biome = game.biomes->biomeFromId(biomeID).identifier;
unsigned int biomeID = world.getActiveDimension().getBiome(glm::floor(player.getPos()));
std::string biome = game.getBiomes().biomeFromId(biomeID).identifier;
glm::vec3 playerPos = glm::floor(player.getPos());
glm::vec3 chunkPos = Space::Chunk::world::fromBlock(playerPos);
@ -149,7 +146,7 @@ void DebugGui::update(Player& player, LocalWorld& world, LocalSubgame& game, dou
thing.face == EVec::BACK ? "BACK" :
"NONE" ;
str << "Pointing At: " << game.defs->blockFromId(world.getBlock(thing.pos)).identifier << std::endl;
str << "Pointing At: " << game.getDefs().blockFromId(world.getActiveDimension().getBlock(thing.pos)).identifier << std::endl;
str << "Pointed Position: " << vecToString(thing.pos) << std::endl;
str << "Pointed Face: " << face << std::endl;
}
@ -165,8 +162,8 @@ void DebugGui::update(Player& player, LocalWorld& world, LocalSubgame& game, dou
std::ostringstream crossText;
if (target.type == Target::Type::BLOCK) {
crossText << game.defs->blockFromId(world.getBlock(target.pos)).name
<< " (" << game.defs->blockFromId(world.getBlock(target.pos)).identifier << ")" << std::endl;
crossText << game.getDefs().blockFromId(world.getActiveDimension().getBlock(target.pos)).name
<< " (" << game.getDefs().blockFromId(world.getActiveDimension().getBlock(target.pos)).identifier << ")" << std::endl;
}
get<GuiText>("crosshairText")->setText(crossText.str());
}

View File

@ -6,19 +6,22 @@
#include "components/basic/GuiContainer.h"
class Player;
class LocalPlayer;
class LocalSubgame;
class LocalWorld;
class DebugGui : public GuiContainer {
public:
DebugGui(glm::vec2 bufferSize, LocalSubgame& atlas);
DebugGui(glm::vec2 bufferSize, LocalSubgame& game, LocalWorld& world);
void bufferResized(glm::vec2 bufferSize);
void changeVisibilityState(int state);
void positionElements(glm::vec2 bufferSize);
void update(Player& player, LocalWorld& world, LocalSubgame& game, double fps, int chunks, int drawCalls, int ssGen, int ssPack);
void update(LocalPlayer& player, double fps, int chunks, int drawCalls, int ssGen, int ssPack);
private:
int displayMode;
LocalWorld& world;
LocalSubgame& game;
};

View File

@ -6,7 +6,7 @@
#include "GuiBuilder.h"
#include "../inventory/Inventory.h"
#include "../inventory/ServerInventory.h"
#include "../inventory/LocalInventoryRefs.h"
class GameGuiBuilder : public GuiBuilder {

View File

@ -9,7 +9,7 @@
#include <memory>
#include <functional>
#include "../../entity/Entity.h"
#include "../../entity/DrawableEntity.h"
class Window;
@ -72,7 +72,7 @@ protected:
bool hovered = false;
bool overflows = false;
Entity entity;
DrawableEntity entity;
std::array<callback, 3> callbacks;
private:

View File

@ -29,11 +29,11 @@ std::shared_ptr<GuiInventoryList> GuiInventoryList::fromSerialized(const LuaGuiE
unsigned short start = static_cast<unsigned short>(elem.get_or<float>("start", 1) - 1);
unsigned short length = static_cast<unsigned short>(elem.get_or<float>("length", 0));
auto invList = refs.getList(source, list);
auto invList = refs.getInventory(source).getListPtr(list);
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.getCursorList(), game, start, length);
slotspc * SerialGui::SCALE_MODIFIER, invList, refs.getCursorList(), game, start, length);
inv->setPos(pos);
return inv;
@ -72,9 +72,8 @@ void GuiInventoryList::setCallback(CallbackType type, const callback& cb) {
GuiComponent::setCallback(type, [&, cb, type](bool down, glm::ivec2 pos) {
if (cb) cb(down, pos);
if (type == GuiComponent::CallbackType::PRIMARY ) this->leftClick (down, pos);
else if (type == GuiComponent::CallbackType::SECONDARY) this->rightClick(down, pos);
else if (type == GuiComponent::CallbackType::HOVER ) this->hoverEvent(down, pos);
if (type == GuiComponent::CallbackType::HOVER) this->hoverEvent(down, pos);
else this->interactEvent(pos, type == GuiComponent::CallbackType::PRIMARY);
});
}
@ -94,8 +93,8 @@ void GuiInventoryList::hoverEvent(bool hovered, glm::ivec2 pos) {
else if (this->hovered) hoverRect->setScale({});
}
void GuiInventoryList::leftClick(bool down, glm::ivec2 pos) {
if (!down || list->getWidth() == 0) return;
void GuiInventoryList::interactEvent(glm::ivec2 pos, bool primary) {
if (list->getWidth() == 0) return;
pos += glm::ivec2(glm::vec2(this->padding.x, this->padding.y) * this->scale);
@ -107,22 +106,7 @@ void GuiInventoryList::leftClick(bool down, glm::ivec2 pos) {
if (index >= list->getLength()) return;
list->primaryInteract(*cursor, index);
}
void GuiInventoryList::rightClick(bool down, glm::ivec2 pos) {
if (!down || list->getWidth() == 0) return;
pos += glm::ivec2(glm::vec2(this->padding.x, this->padding.y) * this->scale);
glm::ivec2 slot = pos / (glm::ivec2(this->scale) * this->innerPadding);
slot.x = std::min(slot.x, static_cast<int>(list->getWidth() - 1));
slot.y = std::min(slot.y, list->getLength() / list->getWidth() - 1);
unsigned short index = slot.x + slot.y * list->getWidth();
if (index >= list->getLength()) return;
list->secondaryInteract(*cursor, index);
list->interact(*cursor, primary, index);
}
void GuiInventoryList::drawContents() {
@ -152,7 +136,7 @@ void GuiInventoryList::drawContents() {
if (stack.id == 0) continue;
auto item = std::make_shared<GuiInventoryItem>("item_" + std::to_string(i) + "_" + std::to_string(j));
item->create(scale, stack.count, defs->defs->fromId(stack.id), f);
item->create(scale, stack.count, defs->getDefs().fromId(stack.id), f);
add(item);
item->setPos({padding.x + j * (16*scale.x+innerPadding.x/scale.x), padding.y + i * (16*scale.y+innerPadding.y/scale.y)});
}

View File

@ -28,15 +28,19 @@ public:
void setCallback(CallbackType type, const callback& cb) override;
void hoverEvent(bool hovered, glm::ivec2 pos);
void leftClick(bool down, glm::ivec2 pos);
void rightClick(bool down, glm::ivec2 pos);
void interactEvent(glm::ivec2 pos, bool primary);
void drawContents();
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, cursor;
unsigned short start, length;
std::shared_ptr<LocalInventoryList> list;
std::shared_ptr<LocalInventoryList> cursor;
unsigned short start;
unsigned short length;
glm::ivec2 innerPadding;
LocalSubgame* defs = nullptr;
};

View File

@ -4,7 +4,7 @@
#pragma once
#include "../../../entity/Entity.h"
#include "../../../entity/DrawableEntity.h"
#include "../../../../util/Util.h"
#include "../basic/GuiRect.h"
#include "../basic/GuiGraph.h"

View File

@ -1,35 +1,28 @@
//
// Created by aurailus on 2019-12-17.
// Created by aurailus on 2020-07-29.
//
#include "Inventory.h"
void Inventory::sendDirtyLists() {
for (auto& list : lists) {
if (list.second->dirty) {
list.second->sendAll();
list.second->dirty = false;
}
}
#include "InventoryList.h"
Inventory::Inventory(Subgame &game, const std::string& name) : game(game), name(name) {}
bool Inventory::hasList(const std::string &name) {
return lists.count(name);
}
void Inventory::createList(std::string name, unsigned short length, unsigned short width) {
lists.emplace(name, std::make_shared<ServerInventoryList>(defs, clients, this->name, name, length, width));
}
std::shared_ptr<ServerInventoryList> Inventory::operator[](std::string name) {
if (lists.count(name)) return lists[name];
else return nullptr;
}
void Inventory::removeList(std::string name) {
void Inventory::removeList(const std::string &name) {
lists.erase(name);
}
void Inventory::setDefaultList(const std::string &name) {
defaultList = name;
InventoryList& Inventory::getList(const std::string &name) {
if (lists.count(name)) return *lists[name];
throw std::runtime_error("List " + name + " doesn't exist in Inventory " + this->name + ".");
}
std::string Inventory::getDefaultList() {
return defaultList;
}
std::shared_ptr<InventoryList> Inventory::getListPtr(const std::string &name) {
// A dirty hack to cause LocalInventory to create a temp list.
try { getList(name); } catch (...) {}
return lists[name];
}

View File

@ -1,5 +1,5 @@
//
// Created by aurailus on 2019-12-17.
// Created by aurailus on 2020-07-29.
//
#pragma once
@ -7,27 +7,26 @@
#include <map>
#include <string>
#include <memory>
#include "ServerInventoryList.h"
class ClientList;
class Subgame;
class InventoryList;
class Inventory {
public:
Inventory(DefinitionAtlas& defs, ClientList* clients, const std::string& name) : defs(defs), clients(clients), name(name) {};
Inventory(const Inventory& o) = delete;
explicit Inventory(Subgame& game, const std::string& name);
void sendDirtyLists();
virtual bool hasList(const std::string& name);
virtual InventoryList& getList(const std::string& name);
std::shared_ptr<InventoryList> getListPtr(const std::string& name);
void createList(std::string name, unsigned short length, unsigned short width);
std::shared_ptr<ServerInventoryList> operator[](std::string name);
void removeList(std::string name);
virtual void createList(const std::string& name, unsigned short length, unsigned short width) = 0;
virtual void removeList(const std::string& name);
void setDefaultList(const std::string& name);
std::string getDefaultList();
DefinitionAtlas& defs;
protected:
Subgame& game;
std::string name;
private:
ClientList* clients;
std::map<std::string, std::shared_ptr<ServerInventoryList>> lists;
std::string defaultList = "";
std::map<std::string, std::shared_ptr<InventoryList>> lists;
};

View File

@ -5,33 +5,20 @@
#include "InventoryList.h"
#include "../../def/ItemDef.h"
#include "../../net/Serializer.h"
#include "../../def/DefinitionAtlas.h"
#include "../../lua/usertype/LuaItemStack.h"
InventoryList::InventoryList(DefinitionAtlas &defs) : defs(defs) {
initialize();
}
InventoryList::InventoryList(DefinitionAtlas &defs, const std::string &invName, const std::string &listName,
unsigned short size, unsigned short width) :
listName(listName),
itemstacks(size),
invName(invName),
InventoryList::InventoryList(Subgame& game, const std::string& name, const std::string& invName, unsigned short size, unsigned short width) :
game(game),
name(name),
items(size),
width(width),
defs(defs) {
initialize();
}
invName(invName) {}
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();
std::string InventoryList::getName() const {
return name;
}
void InventoryList::setWidth(unsigned short width) {
@ -42,8 +29,12 @@ unsigned short InventoryList::getWidth() const {
return width;
}
std::string InventoryList::getName() const {
return listName;
void InventoryList::setLength(unsigned short length) {
items.resize(length);
}
unsigned short InventoryList::getLength() const {
return items.size();
}
// List Manipulation Functions
@ -52,52 +43,52 @@ ItemStack InventoryList::placeStack(unsigned short i, const ItemStack &stack, bo
auto otherStack = getStack(i);
unsigned short allowedTake = otherStack.count;
if (playerInitiated) {
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i+1, LuaItemStack(otherStack, defs))), allowedTake);
}
// if (playerInitiated) {
// auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
// if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i+1, LuaItemStack(otherStack, defs))), allowedTake);
// }
unsigned short allowedPut = stack.count;
if (playerInitiated) {
auto allowPut = luaCallbacks[static_cast<int>(Callback::ALLOW_PUT)];
if (allowPut) allowedPut = std::min(static_cast<unsigned short>(allowPut(i+1, LuaItemStack(stack, defs))), allowedPut);
}
// if (playerInitiated) {
// auto allowPut = luaCallbacks[static_cast<int>(Callback::ALLOW_PUT)];
// if (allowPut) allowedPut = std::min(static_cast<unsigned short>(allowPut(i+1, LuaItemStack(stack, defs))), allowedPut);
// }
sol::function on_put = luaCallbacks[static_cast<int>(Callback::ON_PUT)];
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
// sol::function on_put = luaCallbacks[static_cast<int>(Callback::ON_PUT)];
// sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
if (stack.count == 0) {
if (allowedTake == otherStack.count) setStack(i, {DefinitionAtlas::AIR, 0});
else setStack(i, {otherStack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
// if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
return {otherStack.id, allowedTake};
}
else {
if (otherStack.count) {
if (otherStack.id == stack.id) {
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
unsigned short maxStack = game.getDefs().fromId(stack.id).maxStackSize;
if (allowedPut >= stack.count && allowedPut + otherStack.count < maxStack) {
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
if (on_put) on_put(i+1, LuaItemStack(otherStack, defs));
// if (on_put) on_put(i+1, LuaItemStack(otherStack, defs));
return {};
}
else if (allowedPut > 0) {
allowedPut = std::min(allowedPut, static_cast<unsigned short>(maxStack - otherStack.count));
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
// if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
}
else {
allowedTake = std::min(allowedTake, static_cast<unsigned short>(maxStack - stack.count));
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count - allowedTake)});
if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
// if (allowedTake > 0 && on_take) on_take(i+1, LuaItemStack(otherStack, defs));
return {stack.id, static_cast<unsigned short>(stack.count + allowedTake)};
}
}
else {
if (stack.count <= allowedPut && otherStack.count <= allowedTake) {
setStack(i, stack);
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
if (on_take) on_take(i+1, LuaItemStack(otherStack, defs));
// if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
// if (on_take) on_take(i+1, LuaItemStack(otherStack, defs));
return otherStack;
}
else {
@ -107,7 +98,7 @@ ItemStack InventoryList::placeStack(unsigned short i, const ItemStack &stack, bo
}
else {
setStack(i, {stack.id, static_cast<unsigned short>(otherStack.count + allowedPut)});
if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
// if (allowedPut > 0 && on_put) on_put(i+1, LuaItemStack(otherStack, defs));
return {stack.id, static_cast<unsigned short>(stack.count - allowedPut)};
}
}
@ -117,47 +108,47 @@ ItemStack InventoryList::splitStack(unsigned short i, bool playerInitiated) {
auto stack = getStack(i);
unsigned short allowedTake = stack.count;
if (playerInitiated) {
auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i + 1, LuaItemStack(stack, defs))), allowedTake);
}
// if (playerInitiated) {
// auto allowTake = luaCallbacks[static_cast<int>(Callback::ALLOW_TAKE)];
// if (allowTake) allowedTake = std::min(static_cast<unsigned short>(allowTake(i + 1, LuaItemStack(stack, defs))), allowedTake);
// }
unsigned short initialCount = stack.count;
unsigned short takeCount = std::min(static_cast<unsigned short>(ceil(initialCount / 2.f)), allowedTake);
setStack(i, {stack.id, static_cast<unsigned short>(initialCount - takeCount)});
sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
if (on_take) on_take(i+1, stack);
// sol::function on_take = luaCallbacks[static_cast<int>(Callback::ON_TAKE)];
// if (on_take) on_take(i+1, stack);
return {stack.id, takeCount};
}
ItemStack InventoryList::addStack(ItemStack stack, bool playerInitiated) {
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
unsigned short maxStack = game.getDefs().fromId(stack.id).maxStackSize;
unsigned short i = 0;
while (i < itemstacks.size() && stack.count > 0) {
if (itemstacks[i].count == 0) {
while (i < items.size() && stack.count > 0) {
if (items[i].count == 0) {
if (stack.count <= maxStack) {
itemstacks[i] = stack;
items[i] = stack;
manipulated();
return ItemStack{};
}
else {
itemstacks[i] = stack;
itemstacks[i].count = maxStack;
items[i] = stack;
items[i].count = maxStack;
stack.count -= maxStack;
}
}
else if (itemstacks[i].id == stack.id) {
unsigned int fits = maxStack - itemstacks[i].count;
else if (items[i].id == stack.id) {
unsigned int fits = maxStack - items[i].count;
if (fits >= stack.count) {
itemstacks[i].count += stack.count;
items[i].count += stack.count;
manipulated();
return ItemStack {};
}
else {
stack.count -= fits;
itemstacks[i].count += fits;
items[i].count += fits;
}
}
i++;
@ -168,23 +159,19 @@ ItemStack InventoryList::addStack(ItemStack stack, bool playerInitiated) {
}
unsigned short InventoryList::stackFits(const ItemStack &stack) {
unsigned short maxStack = defs.fromId(stack.id).maxStackSize;
unsigned short maxStack = game.getDefs().fromId(stack.id).maxStackSize;
unsigned short i = 0;
unsigned short fits = 0;
while (i < itemstacks.size() && fits < stack.count) {
if (itemstacks[i].count == 0) {
while (i < items.size() && fits < stack.count) {
if (items[i].count == 0) {
fits += std::min(static_cast<unsigned short>(maxStack), stack.count);
}
else if (itemstacks[i].id == stack.id) {
unsigned int canfit = maxStack - itemstacks[i].count;
if (canfit >= stack.count - fits) {
fits += stack.count - fits;
}
else {
fits = stack.count;
}
else if (items[i].id == stack.id) {
unsigned int canfit = maxStack - items[i].count;
if (canfit >= stack.count - fits) fits += stack.count - fits;
else fits = stack.count;
}
i++;
}
@ -196,17 +183,17 @@ ItemStack InventoryList::takeStack(ItemStack request, bool playerInitiated) {
unsigned short i = 0;
unsigned short to_remove = request.count;
while (i < itemstacks.size() && request.count > 0) {
if (itemstacks[i].id == request.id) {
unsigned int can_take = itemstacks[i].count;
while (i < items.size() && request.count > 0) {
if (items[i].id == request.id) {
unsigned int can_take = items[i].count;
if (can_take >= to_remove) {
itemstacks[i].count -= to_remove;
items[i].count -= to_remove;
manipulated();
return request;
}
else {
to_remove -= can_take;
itemstacks[i] = ItemStack {};
items[i] = ItemStack {};
}
}
i++;
@ -231,45 +218,65 @@ ItemStack InventoryList::removeStack(unsigned short ind, unsigned short count) {
}
}
void InventoryList::primaryInteract(InventoryList& cursor, unsigned short ind) {
cursor.setStack(0, placeStack(ind, cursor.getStack(0), true));
}
void InventoryList::secondaryInteract(InventoryList &cursor, unsigned short ind) {
auto handStack = cursor.getStack(0);
if (handStack.count == 0) {
cursor.setStack(0, splitStack(ind, true));
void InventoryList::interact(InventoryList& cursor, bool primary, unsigned short ind) {
if (primary) {
cursor.setStack(0, placeStack(ind, cursor.getStack(0), true));
}
else {
auto listStack = getStack(ind);
if (listStack.id == 0 || listStack.id == handStack.id) {
auto overflow = placeStack(ind, {handStack.id, 1}, true);
handStack.count -= 1;
if (handStack.count == 0) handStack.id = 0;
if (overflow.count != 0) handStack.count += overflow.count;
cursor.setStack(0, handStack);
auto handStack = cursor.getStack(0);
if (handStack.count == 0) {
cursor.setStack(0, splitStack(ind, true));
}
else {
cursor.setStack(0, placeStack(ind, cursor.getStack(0), true));
auto listStack = getStack(ind);
if (listStack.id == 0 || listStack.id == handStack.id) {
auto overflow = placeStack(ind, {handStack.id, 1}, true);
handStack.count -= 1;
if (handStack.count == 0) handStack.id = 0;
if (overflow.count != 0) handStack.count += overflow.count;
cursor.setStack(0, handStack);
}
else {
cursor.setStack(0, placeStack(ind, cursor.getStack(0), true));
}
}
}
}
ItemStack InventoryList::getStack(unsigned short i) const {
return itemstacks[i];
return items[i];
}
void InventoryList::setStack(unsigned short i, const ItemStack &stack) {
if (stack != getStack(i)) {
itemstacks[i] = stack;
manipulated();
if (stack == getStack(i)) return;
items[i] = stack;
manipulated();
}
Packet InventoryList::createPacket() {
Serializer s {};
s.append<std::string>(invName)
.append<std::string>(name)
.append<unsigned int>(items.size())
.append<unsigned int>(width);
for (auto& stack : items) {
s.append<unsigned short>(stack.count);
s.append<unsigned int>(stack.id);
}
return s.packet(PacketType::INV_DATA, false);
}
void InventoryList::setLuaCallback(InventoryList::Callback type, sol::protected_function cb) {
luaCallbacks[static_cast<size_t>(type)] = cb;
}
//void InventoryList::setLuaCallback(InventoryList::Callback type, sol::protected_function cb) {
// luaCallbacks[static_cast<size_t>(type)] = cb;
//}
//
//sol::protected_function InventoryList::getLuaCallback(InventoryList::Callback type) {
// return luaCallbacks[static_cast<size_t>(type)];
//}
sol::protected_function InventoryList::getLuaCallback(InventoryList::Callback type) {
return luaCallbacks[static_cast<size_t>(type)];
Subgame &InventoryList::getGame() {
return game;
}

View File

@ -6,30 +6,30 @@
#include <string>
#include "../../lua/Lua.h"
#include "ItemStack.h"
#include "../../lua/Lua.h"
#include "../../net/Packet.h"
#include "../../def/Subgame.h"
class DefinitionAtlas;
class InventoryList {
public:
enum class Callback {
ALLOW_TAKE,
ALLOW_PUT,
ON_TAKE,
ON_PUT
};
enum class Callback { ALLOW_TAKE, ALLOW_PUT, ON_TAKE, ON_PUT };
InventoryList(DefinitionAtlas& defs);
InventoryList(DefinitionAtlas& defs, const std::string& invName, const std::string& listName, unsigned short size, unsigned short width);
InventoryList(const InventoryList& o) = delete;
InventoryList(Subgame& game, const std::string& name, const std::string& invName, unsigned short size, unsigned short width);
void setLength(unsigned short length);
unsigned short getLength() const;
std::string getName() const;
void setWidth(unsigned short width);
unsigned short getWidth() const;
std::string getName() const;
void setLength(unsigned short length);
unsigned short getLength() const;
ItemStack getStack(unsigned short i) const;
void setStack(unsigned short i, const ItemStack& stack);
// Place the stack at i into the existing stack, returning overflow or other stack.
virtual ItemStack placeStack(unsigned short i, const ItemStack& stack, bool playerInitiated = false);
@ -44,27 +44,20 @@ public:
// Removes up to count items from ind, returns the items removed
virtual ItemStack removeStack(unsigned short ind, unsigned short count);
// Primary interaction - The action performed when left clicking an inventory slot.
virtual void primaryInteract(InventoryList& cursor, unsigned short ind);
// Secondary interaction - The action performed when right clicking an inventory slot.
virtual void secondaryInteract(InventoryList& cursor, unsigned short ind);
virtual void interact(InventoryList& cursor, bool primary, unsigned short ind);
ItemStack getStack(unsigned short i) const;
void setStack(unsigned short i, const ItemStack& stack);
// sol::protected_function getLuaCallback(Callback type);
// void setLuaCallback(Callback type, sol::protected_function cb);
sol::protected_function getLuaCallback(Callback type);
void setLuaCallback(Callback type, sol::protected_function cb);
DefinitionAtlas& defs;
Subgame& getGame();
protected:
virtual void manipulated() = 0;
void initialize();
Subgame& game;
std::string invName {}, listName {};
std::string name, invName;
unsigned short width = 0;
std::vector<ItemStack> items {};
std::vector<ItemStack> itemstacks {};
std::array<sol::function, 4> luaCallbacks = {};
Packet createPacket();
virtual void manipulated() = 0;
};

View File

@ -1,55 +1,18 @@
//
// Created by aurailus on 2020-02-26.
// Created by aurailus on 2020-07-29.
//
#include "InventoryRefs.h"
#include "ServerInventoryList.h"
#include "../../def/ServerDefinitionAtlas.h"
#include "../../def/Subgame.h"
InventoryRefs::InventoryRefs(ServerDefinitionAtlas &defs, ClientList* clients) :
defs(defs), clients(clients) {}
InventoryRefs::InventoryRefs(Subgame& game) : game(game) {}
void InventoryRefs::update() {
for (auto& inv : inventories) {
inv.second->sendDirtyLists();
}
bool InventoryRefs::hasInventory(const std::string &inv) {
return inventories.count(inv);
}
std::shared_ptr<Inventory> InventoryRefs::createInv(const std::string &inv) {
if (!inventories.count(inv)) inventories.emplace(inv, std::make_shared<Inventory>(defs, clients, inv));
return inventories[inv];
}
std::shared_ptr<Inventory> InventoryRefs::getInv(const std::string &inv) {
return inventories[inv];
}
std::shared_ptr<ServerInventoryList> InventoryRefs::getList(const std::string &inv, const std::string &list) {
if (!inventories.count(inv)) return nullptr;
return inventories[inv]->operator[](list);
}
bool InventoryRefs::addWatcher(const std::string &inv, const std::string &list, unsigned int cid) {
if (!inventories.count(inv)) return false;
if (!inventories[inv]->operator[](list)) return false;
inventories[inv]->operator[](list)->addWatcher(cid);
return true;
}
bool InventoryRefs::removeWatcher(const std::string &inv, const std::string &list, unsigned int cid) {
if (!inventories.count(inv)) return false;
if (!inventories[inv]->operator[](list)) return false;
inventories[inv]->operator[](list)->removeWatcher(cid);
return true;
}
void InventoryRefs::primaryInteract(const std::string &inv, const std::string &list, unsigned short ind, unsigned int cid) {
(*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])[list]->secondaryInteract(*(*inventories["player:" + std::to_string(cid)])["cursor"], ind);
Inventory& InventoryRefs::getInventory(const std::string &inv) {
if (!inventories.count(inv)) throw std::runtime_error("Inventory " + inv + " doesn't exist~!");
return *inventories.at(inv);
}

View File

@ -1,33 +1,27 @@
//
// Created by aurailus on 2020-02-26.
// Created by aurailus on 2020-07-29.
//
#pragma once
#include "Inventory.h"
#include <string>
#include <memory>
#include <unordered_map>
class ServerInventoryList;
class ServerDefinitionAtlas;
class Subgame;
class Inventory;
class InventoryRefs {
public:
InventoryRefs(ServerDefinitionAtlas& defs, ClientList* clients);
InventoryRefs(const InventoryRefs& o) = delete;
explicit InventoryRefs(Subgame& game);
void update();
virtual bool hasInventory(const std::string& inv);
virtual Inventory& createInventory(const std::string& inv) = 0;
virtual Inventory& getInventory(const std::string& inv);
std::shared_ptr<Inventory> createInv(const std::string& inv);
std::shared_ptr<Inventory> getInv(const std::string& inv);
std::shared_ptr<ServerInventoryList> getList(const std::string& inv, const std::string& list);
protected:
Subgame& game;
bool addWatcher(const std::string& inv, const std::string& list, unsigned int cid);
bool removeWatcher(const std::string& inv, const std::string& list, unsigned int cid);
void primaryInteract(const std::string& inv, const std::string& list, unsigned short ind, unsigned int cid);
void secondaryInteract(const std::string& inv, const std::string& list, unsigned short ind, unsigned int cid);
private:
std::unordered_map<std::string, std::shared_ptr<Inventory>> inventories {};
ClientList* clients;
ServerDefinitionAtlas& defs;
double time = 0;
};

View File

@ -5,11 +5,12 @@
#include "ItemStack.h"
#include "../../def/ItemDef.h"
#include "../../def/Subgame.h"
#include "../../def/DefinitionAtlas.h"
#include "../../lua/usertype/LuaItemStack.h"
ItemStack::ItemStack(LuaItemStack &stack, const DefinitionAtlas &atlas) :
id((stack.get_count() == 0) ? DefinitionAtlas::AIR : atlas.fromStr(stack.get_name()).index),
ItemStack::ItemStack(LuaItemStack &stack, Subgame& game) :
id((stack.get_count() == 0) ? DefinitionAtlas::AIR : game.getDefs().fromStr(stack.get_name()).index),
count((this->id == DefinitionAtlas::AIR) ? 0 : stack.get_count()) {}
ItemStack::ItemStack(unsigned int id, unsigned short count) :

View File

@ -6,14 +6,14 @@
#include <string>
class DefinitionAtlas;
class Subgame;
class LuaItemStack;
class ItemStack {
public:
ItemStack() = default;
ItemStack(unsigned int id, unsigned short count);
ItemStack(LuaItemStack& stack, const DefinitionAtlas& atlas);
ItemStack(LuaItemStack& stack, Subgame& game);
bool operator!=(const ItemStack& b) const;
bool operator==(const ItemStack& b) const;

View File

@ -7,37 +7,36 @@
#include "LocalInventoryList.cpp"
#include "../../net/client/ClientNetworkInterpreter.h"
void LocalInventory::createList(const std::string& name, unsigned short length, unsigned short width, bool persistant) {
namespace ph = std::placeholders;
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))}});
LocalInventoryList& LocalInventory::getList(const std::string &name) {
if (hasList(name)) createList(name, 0, 0);
return static_cast<LocalInventoryList&>(Inventory::getList(name));
}
void LocalInventory::removeList(const std::string &name) {
if (lists.count(name)) lists[name].first = 1;
void LocalInventory::createList(const std::string &name, unsigned short length, unsigned short width) {
lists.emplace(name, std::make_shared<LocalInventoryList>(game, name, this->name, length, width, net));
net.invWatch(this->name, name);
}
std::shared_ptr<LocalInventoryList> LocalInventory::operator[](std::string name) {
if (lists.count(name)) return lists[name].second;
else return nullptr;
std::shared_ptr<LocalInventoryList> LocalInventory::getListPtr(const std::string &name) {
if (!hasList(name)) createList(name, 0, 0);
return std::static_pointer_cast<LocalInventoryList>(lists[name]);
}
void LocalInventory::setPersistant(const std::string &list, bool persistant) {
if (!lists.count(name)) return;
lists[name].first = (persistant ? -1 : 0);
std::static_pointer_cast<LocalInventoryList>(lists[list])->persistant = persistant;
}
bool LocalInventory::pruneLists(ClientNetworkInterpreter &net, double time) {
bool LocalInventory::pruneLists(double time) {
for (auto lIt = lists.begin(); lIt != lists.end();) {
if (lIt->second.first != -1) {
auto list = std::static_pointer_cast<LocalInventoryList>(lIt->second);
if (!list->persistant) {
// Start the timeout for Inventories that aren't being used.
if (lIt->second.first == 0 && lIt->second.second.use_count() == 1) lIt->second.first = time + 15;
if (list->decayTime == 0 && list.use_count() == 2) list->decayTime = time + 15;
// Remove the timeout for Inventories that are being used.
else if (lIt->second.first != 0 && lIt->second.second.use_count() > 1) lIt->second.first = 0;
else if (list->decayTime != 0 && list.use_count() > 2) list->decayTime = 0;
// Delete InventoryLists that have passed their timeout.
else if (lIt->second.first != 0 && lIt->second.first <= time) {
else if (list->decayTime != 0 && list->decayTime <= time) {
net.invUnwatch(name, lIt->first);
lIt = lists.erase(lIt);
}
@ -47,4 +46,4 @@ bool LocalInventory::pruneLists(ClientNetworkInterpreter &net, double time) {
}
return lists.size() == 0;
}
}

View File

@ -4,34 +4,33 @@
#pragma once
#include <set>
#include <memory>
#include <functional>
#include <unordered_map>
#include "Inventory.h"
#include "LocalInventoryList.h"
#include "../../def/LocalSubgame.h"
class DefinitionAtlas;
class LocalInventoryList;
class ClientNetworkInterpreter;
class LocalInventory {
class LocalInventory : public Inventory {
public:
typedef std::function<void(const std::string& inv, const std::string& list, unsigned short)> inv_callback_fn;
LocalInventory(LocalSubgame& game, const std::string& name, ClientNetworkInterpreter& net) :
Inventory(game, name), net(net) {}
LocalInventory(DefinitionAtlas& defs, const std::string& name,
inv_callback_fn primaryCallback, inv_callback_fn secondaryCallback) :
defs(defs), name(name), primaryCallback(primaryCallback), secondaryCallback(secondaryCallback) {};
virtual LocalInventoryList& getList(const std::string& name) override;
std::shared_ptr<LocalInventoryList> getListPtr(const std::string& name);
virtual void createList(const std::string& name, unsigned short length, unsigned short width) override;
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);
bool pruneLists(double time);
DefinitionAtlas& defs;
private:
std::string name;
std::unordered_map<std::string, std::pair<double, std::shared_ptr<LocalInventoryList>>> lists;
inv_callback_fn primaryCallback;
inv_callback_fn secondaryCallback;
ClientNetworkInterpreter& net;
};

View File

@ -4,27 +4,22 @@
#include "LocalInventoryList.h"
LocalInventoryList::LocalInventoryList(DefinitionAtlas& defs, const std::string& invName,
const std::string& listName, unsigned short size, unsigned short width,
std::function<void(unsigned short)> primaryCallback, std::function<void(unsigned short)> secondaryCallback) :
InventoryList(defs, invName, listName, size, width),
#include "../../net/client/ClientNetworkInterpreter.h"
primaryCallback(primaryCallback),
secondaryCallback(secondaryCallback) {}
LocalInventoryList::LocalInventoryList(Subgame& game, const std::string& name,
const std::string& invName, unsigned short size, unsigned short width,
ClientNetworkInterpreter& net) :
InventoryList(game, name, invName, size, width),
net(net) {}
void LocalInventoryList::primaryInteract(InventoryList &hand, unsigned short ind) {
InventoryList::primaryInteract(hand, ind);
primaryCallback(ind);
void LocalInventoryList::interact(InventoryList &hand, bool primary, unsigned short ind) {
InventoryList::interact(hand, primary, ind);
net.invInteract(invName, name, primary, ind);
}
void LocalInventoryList::secondaryInteract(InventoryList &hand, unsigned short ind) {
InventoryList::secondaryInteract(hand, ind);
secondaryCallback(ind);
}
void LocalInventoryList::setData(unsigned int size, unsigned int width, std::vector<ItemStack> stacks) {
void LocalInventoryList::setData(unsigned int size, unsigned int width, std::vector<ItemStack> items) {
this->width = width;
this->itemstacks = stacks;
this->items = items;
manipulated();
}

View File

@ -8,23 +8,26 @@
#include "InventoryList.h"
class ClientNetworkInterpreter;
class LocalInventoryList : public InventoryList {
public:
LocalInventoryList(DefinitionAtlas& defs, const std::string& invName,
const std::string& listName, unsigned short size, unsigned short width,
std::function<void(unsigned short)> primaryCallback, std::function<void(unsigned short)> secondaryCallback);
LocalInventoryList(Subgame& game, const std::string& name,
const std::string& invName, unsigned short size, unsigned short width,
ClientNetworkInterpreter& net);
void primaryInteract(InventoryList& hand, unsigned short ind) override;
void secondaryInteract(InventoryList& hand, unsigned short ind) override;
void interact(InventoryList& hand, bool primary, unsigned short ind) override;
void setData(unsigned int size, unsigned int width, std::vector<ItemStack> stacks);
void setData(unsigned int size, unsigned int width, std::vector<ItemStack> items);
void addGuiCallback(std::shared_ptr<std::function<void()>> cb);
void removeGuiCallback(std::shared_ptr<std::function<void()>> cb);
bool persistant = false;
double decayTime = 0;
private:
void manipulated() override;
std::function<void(unsigned short)> primaryCallback = nullptr;
std::function<void(unsigned short)> secondaryCallback = nullptr;
ClientNetworkInterpreter& net;
std::list<std::shared_ptr<std::function<void()>>> guiCallbacks {};
};

View File

@ -6,25 +6,16 @@
#include "LocalInventoryRefs.h"
#include "LocalInventory.h"
#include "LocalInventoryList.h"
#include "../../net/PacketView.h"
#include "../../def/LocalDefinitionAtlas.h"
#include "../../net/client/ClientNetworkInterpreter.h"
LocalInventoryRefs::LocalInventoryRefs(LocalDefinitionAtlas& defs, ClientNetworkInterpreter& net) : defs(defs) {
namespace ph = std::placeholders;
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("cursor", 1, 1, true);
}
LocalInventoryRefs::LocalInventoryRefs(Subgame& game, ClientNetworkInterpreter& net) : InventoryRefs(game), net(net) {}
void LocalInventoryRefs::init() {
createInventory("current_player");
getInventory("current_player").createList("cursor", 1, 1);
watch("current_player", "cursor");
}
@ -32,18 +23,27 @@ void LocalInventoryRefs::update(double delta, ClientNetworkInterpreter& net) {
time += delta;
for (auto mIt = inventories.begin(); mIt != inventories.end();) {
if (mIt->second->pruneLists(net, time)) mIt = inventories.erase(mIt);
if (std::static_pointer_cast<LocalInventory>(mIt->second)->pruneLists(time)) mIt = inventories.erase(mIt);
else mIt++;
}
}
LocalInventory& LocalInventoryRefs::createInventory(const std::string &inv) {
if (!inventories.count(inv)) inventories.emplace(inv, std::make_shared<LocalInventory>(static_cast<LocalSubgame&>(game), inv, net));
return static_cast<LocalInventory&>(*inventories[inv]);
}
LocalInventory& LocalInventoryRefs::getInventory(const std::string &inv) {
return static_cast<LocalInventory&>(InventoryRefs::getInventory(inv));
}
void LocalInventoryRefs::packetReceived(std::unique_ptr<PacketView> p) {
std::string source = p->d.read<std::string>();
std::string list = p->d.read<std::string>();
if (strncmp(source.data(), "player:", 7) == 0) source = "current_player";
if (!inventories.count(source)) return;
if (!inventories[source]->operator[](list)) return;
if (!inventories[source]->hasList(list)) return;
unsigned int size = p->d.read<unsigned int>();
unsigned int width = p->d.read<unsigned int>();
@ -57,53 +57,47 @@ void LocalInventoryRefs::packetReceived(std::unique_ptr<PacketView> p) {
stacks.push_back({id, count});
}
inventories[source]->operator[](list)->setData(size, width, stacks);
static_cast<LocalInventoryList&>(inventories[source]->getList(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);
if (!inventories[inv]->hasList(list)) {
inventories[inv]->createList(list, 0, 0);
net.invWatch(inv, list);
}
else (*inventories[inv]).setPersistant(list, persistant);
std::static_pointer_cast<LocalInventory>(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);
if (inventories.count(inv) && inventories[inv]->hasList(list)) inventories[inv]->removeList(list);
net.invUnwatch(inv, list);
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getHandList() {
return handList == "" ? nullptr : (*inventories["current_player"])[handList];
return 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);
if (handList && list == handList->getName()) return;
if (handList) unWatch("current_player", handList->getName());
handList = getInventory("current_player").getListPtr(list);
getInventory("current_player").setPersistant(list, true);
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getWieldList() {
return wieldList == "" ? nullptr : (*inventories["current_player"])[wieldList];
return 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);
void LocalInventoryRefs::setWieldList(const std::string &list) {
if (wieldList && list == wieldList->getName()) return;
if (wieldList) unWatch("current_player", wieldList->getName());
wieldList = getInventory("current_player").getListPtr(list);
getInventory("current_player").setPersistant(list, true);
}
std::shared_ptr<LocalInventoryList> LocalInventoryRefs::getCursorList() {
return inventories["current_player"]->operator[]("cursor");
}
return std::static_pointer_cast<LocalInventoryList>(
std::static_pointer_cast<LocalInventory>(inventories["current_player"])
->getListPtr("cursor"));
}

View File

@ -8,45 +8,40 @@
#include <functional>
#include <unordered_map>
#include "InventoryRefs.h"
#include "LocalInventory.h"
#include "../../net/PacketChannel.h"
class Packet;
class PacketView;
class LocalInventory;
class LocalInventoryList;
class LocalDefinitionAtlas;
class ClientNetworkInterpreter;
class LocalInventoryRefs {
class LocalInventoryRefs : public InventoryRefs {
public:
typedef std::function<void(const std::string& inv, const std::string& list, unsigned short)> inv_callback_fn;
LocalInventoryRefs(LocalDefinitionAtlas& defs, ClientNetworkInterpreter& net);
LocalInventoryRefs(Subgame& game, ClientNetworkInterpreter& net);
void packetReceived(std::unique_ptr<PacketView> p);
void init();
void update(double delta, ClientNetworkInterpreter& net);
void packetReceived(std::unique_ptr<PacketView> p);
virtual LocalInventory& createInventory(const std::string &inv) override;
virtual LocalInventory& getInventory(const std::string &inv) override;
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> 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 {};
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;
std::shared_ptr<LocalInventoryList> handList = nullptr;
std::shared_ptr<LocalInventoryList> wieldList = nullptr;
ClientNetworkInterpreter& net;
double time = 0;
};

View File

@ -0,0 +1,24 @@
//
// Created by aurailus on 2019-12-17.
//
#include "ServerInventory.h"
#include "ServerInventoryList.h"
void ServerInventory::createList(const std::string &name, unsigned short length, unsigned short width) {
lists.emplace(name, std::make_shared<ServerInventoryList>(game, clients, name, this->name, length, width));
}
ServerInventoryList& ServerInventory::getList(const std::string &name) {
return static_cast<ServerInventoryList&>(Inventory::getList(name));
}
//void ServerInventory::sendDirtyLists() {
// for (auto& list : lists) {
// if (list.second->dirty) {
// list.second->sendAll();
// list.second->dirty = false;
// }
// }
//}

View File

@ -0,0 +1,29 @@
//
// Created by aurailus on 2019-12-17.
//
#pragma once
#include <map>
#include <string>
#include <memory>
#include "Inventory.h"
#include "ServerInventoryList.h"
#include "../../def/ServerSubgame.h"
class ServerClients;
class ServerInventory : public Inventory {
public:
ServerInventory(ServerSubgame& game, const std::string& name, ServerClients& clients) :
Inventory(game, name), clients(clients) {};
virtual void createList(const std::string& name, unsigned short length, unsigned short width) override;
virtual ServerInventoryList& getList(const std::string& name) override;
// void sendDirtyLists();
private:
ServerClients& clients;
};

View File

@ -7,72 +7,46 @@
#include "ServerInventoryList.h"
#include "../../net/Packet.h"
#include "../../net/Serializer.h"
#include "../../lua/usertype/LuaItemStack.h"
#include "../../net/server/conn/ClientList.h"
#include "../../net/server/conn/ServerPlayer.h"
#include "../../net/server/conn/ServerClients.h"
ServerInventoryList::ServerInventoryList(DefinitionAtlas& defs, ClientList* list,
const std::string& invName, const std::string& listName, unsigned short size, unsigned short width) :
InventoryList(defs, invName, listName, size, width),
ServerInventoryList::ServerInventoryList(Subgame& game, ServerClients& list,
const std::string& name, const std::string& invName, unsigned short size, unsigned short width) :
InventoryList(game, name, invName, size, width),
clients(list) {}
void ServerInventoryList::manipulated() {
dirty = true;
}
bool ServerInventoryList::addWatcher(unsigned int cid) {
auto& client = clients->getClient(cid);
if (!client) return false;
for (const auto& i : watchers) if (i == cid) return false;
watchers.push_back(cid);
bool ServerInventoryList::addWatcher(unsigned int id) {
auto& client = clients.getPlayer(id);
if (!client || watchers.count(id)) return false;
watchers.insert(id);
sendTo(client);
return true;
}
bool ServerInventoryList::removeWatcher(unsigned int cid) {
for (auto it = watchers.cbegin(); it != watchers.cend();) {
if (*it == cid) {
watchers.erase(it);
return true;
}
it++;
}
return false;
bool ServerInventoryList::removeWatcher(unsigned int id) {
if (!watchers.count(id)) return false;
watchers.erase(id);
return true;
}
Packet ServerInventoryList::createPacket() {
Serializer s{};
s.append<std::string>(invName)
.append<std::string>(listName)
.append<unsigned int>(itemstacks.size())
.append<unsigned int>(width);
for (auto& stack : itemstacks) {
s.append<unsigned short>(stack.count);
s.append<unsigned int>(stack.id);
}
return s.packet(PacketType::INV_DATA, false);
void ServerInventoryList::sendTo(std::shared_ptr<ServerPlayer> player) {
if (!player) return;
createPacket().sendTo(player->getPeer(), PacketChannel::INVENTORY);
}
void ServerInventoryList::sendTo(std::shared_ptr<ServerClient> client) {
if (!client) return;
createPacket().sendTo(client->peer, PacketChannel::INVENTORY);
}
void ServerInventoryList::sendAll() {
void ServerInventoryList::sendToAll() {
auto p = createPacket();
for (auto it = watchers.cbegin(); it != watchers.cend();) {
auto& client = clients->getClient(*it);
if (!client) {
it = watchers.erase(it);
}
auto& player = clients.getPlayer(*it);
if (!player) it = watchers.erase(it);
else {
p.sendTo(client->peer, PacketChannel::INVENTORY);
p.sendTo(player->getPeer(), PacketChannel::INVENTORY);
it++;
}
}

View File

@ -4,32 +4,30 @@
#pragma once
#include <list>
#include <set>
#include "InventoryList.h"
class ClientList;
class ServerClient;
class ServerClients;
class ServerPlayer;
class Packet;
class ServerInventoryList : public InventoryList {
public:
ServerInventoryList(DefinitionAtlas& defs, ClientList* list, const std::string& invName,
const std::string& listName, unsigned short size, unsigned short width);
ServerInventoryList(Subgame& defs, ServerClients& list, const std::string& name,
const std::string& invName, unsigned short size, unsigned short width);
bool addWatcher(unsigned int cid);
bool removeWatcher(unsigned int cid);
bool addWatcher(unsigned int id);
bool removeWatcher(unsigned int id);
void sendAll();
void sendTo(std::shared_ptr<ServerClient> client);
void sendToAll();
void sendTo(std::shared_ptr<ServerPlayer> player);
bool dirty = false;
private:
void manipulated() override;
Packet createPacket();
ClientList* clients;
std::list<unsigned int> watchers;
ServerClients& clients;
std::set<unsigned int> watchers {};
};

View File

@ -0,0 +1,60 @@
//
// Created by aurailus on 2020-02-26.
//
#include "ServerInventoryRefs.h"
#include "ServerInventory.h"
#include "ServerInventoryList.h"
ServerInventoryRefs::ServerInventoryRefs(Subgame& game, ServerClients& clients) :
InventoryRefs(game), clients(clients) {}
void ServerInventoryRefs::update() {
// for (auto& inv : inventories)
// std::static_pointer_cast<ServerInventory>(inv.second)->sendDirtyLists();
}
ServerInventory& ServerInventoryRefs::createInventory(const std::string &inv) {
if (!inventories.count(inv)) inventories.emplace(inv, std::make_shared<ServerInventory>(static_cast<ServerSubgame&>(game), inv, clients));
return static_cast<ServerInventory&>(*inventories[inv]);
}
ServerInventory& ServerInventoryRefs::getInventory(const std::string &inv) {
return static_cast<ServerInventory&>(InventoryRefs::getInventory(inv));
}
bool ServerInventoryRefs::addWatcher(const std::string &inv, const std::string &list, unsigned int id) {
std::string invReal = inv == "current_player" ? "player:" + std::to_string(id) : inv;
if (!hasInventory(invReal)) return false;
auto& inventory = getInventory(invReal);
if (!inventory.hasList(list)) return false;
inventory.getList(list).addWatcher(id);
return true;
}
bool ServerInventoryRefs::removeWatcher(const std::string &inv, const std::string &list, unsigned int id) {
std::string invReal = inv == "current_player" ? "player:" + std::to_string(id) : inv;
if (!hasInventory(invReal)) return false;
auto& inventory = getInventory(invReal);
if (!inventory.hasList(list)) return false;
inventory.getList(list).removeWatcher(id);
return true;
}
bool ServerInventoryRefs::interact(bool primary, const std::string &inv, const std::string &list, unsigned short ind, unsigned int id) {
std::string playerInv = "player:" + std::to_string(id);
if (!hasInventory(playerInv)) return false;
auto& playerInventory = getInventory(playerInv);
if (!hasInventory(inv)) return false;
auto& inventory = getInventory(inv);
if (!inventory.hasList(list)) return false;
inventory.getList(list).interact(playerInventory.getList("cursor"), primary, ind);
return true;
}

View File

@ -0,0 +1,29 @@
//
// Created by aurailus on 2020-02-26.
//
#pragma once
#include "InventoryRefs.h"
#include "ServerInventory.h"
class ServerClients;
class ServerInventoryList;
class ServerInventoryRefs : public InventoryRefs {
public:
ServerInventoryRefs(Subgame& game, ServerClients& clients);
void update();
virtual ServerInventory& createInventory(const std::string &inv) override;
virtual ServerInventory& getInventory(const std::string &inv) override;
bool addWatcher(const std::string& inv, const std::string& list, unsigned int id);
bool removeWatcher(const std::string& inv, const std::string& list, unsigned int id);
bool interact(bool primary, const std::string& inv, const std::string& list, unsigned short ind, unsigned int id);
private:
ServerClients& clients;
};

View File

@ -92,7 +92,7 @@ void ConnectScene::update() {
auto statusText = components.get<GuiText>("statusText");
statusText->setText(statusText->getText() + "Received block index-identifier table.\n");
state.defs.defs->setIdentifiers(p.d.read<std::vector<std::string>>());
state.defs.getDefs().setIdentifiers(p.d.read<std::vector<std::string>>());
Packet resp(PacketType::BIOME_IDENTIFIER_LIST);
resp.sendTo(connection.getPeer(), PacketChannel::CONNECT);
@ -101,7 +101,7 @@ void ConnectScene::update() {
auto statusText = components.get<GuiText>("statusText");
statusText->setText(statusText->getText() + "Received biome index-identifier table.\nDownloading mods...\n");
state.defs.biomes->setIdentifiers(p.d.read<std::vector<std::string>>());
state.defs.getBiomes().setIdentifiers(p.d.read<std::vector<std::string>>());
connectState = State::MODS;
Packet resp(PacketType::MODS);
@ -122,10 +122,10 @@ void ConnectScene::update() {
if (p.type == PacketType::MODS) {
auto luaMod = LuaMod::fromPacket(p);
statusText->setText(statusText->getText() + "Received mod " + luaMod.config.name + ".\n");
state.defs.lua->getHandler().addLuaMod(std::move(luaMod));
state.defs.getParser().getHandler().addLuaMod(std::move(luaMod));
}
else if (p.type == PacketType::MOD_ORDER) {
state.defs.lua->getHandler().setModsOrder(p.d.read<std::vector<std::string>>());
state.defs.getParser().getHandler().setModsOrder(p.d.read<std::vector<std::string>>());
statusText->setText(statusText->getText() + "Done downloading mods.\nReceived the mods order.\nDownloading media...\n");

View File

@ -10,24 +10,18 @@
#include "../../net/PacketView.h"
GameScene::GameScene(ClientState& state) : Scene(state),
refs(*game.defs, net),
game(state.defs),
world(game, &net),
net(state.connection, game, player),
player(game, world, state.renderer, refs, net),
debugGui(state.renderer.window.getSize(), game) {
namespace ph = std::placeholders;
world(game, state.connection, state.renderer),
debugGui(state.renderer.window.getSize(), game, world) {
Packet r(PacketType::CONNECT_DATA_RECVD);
r.sendTo(state.connection.getPeer(), PacketChannel::CONNECT);
world.init(&player);
net .init(&world, Util::bind_this(&refs, &LocalInventoryRefs::packetReceived));
game .init(world, player, state);
refs .init();
world.connect();
game.initApi(world, state);
if (world.initPlayer()) game.loadPlayer(world.getPlayer());
state.renderer.window.addResizeCallback("gamescene", std::bind(&DebugGui::bufferResized, debugGui, ph::_1));
state.renderer.window.addResizeCallback("gamescene", Util::bind_this(&debugGui, &DebugGui::bufferResized));
state.renderer.setClearColor(148, 194, 240);
state.renderer.window.input.lockMouse(true);
}
@ -35,22 +29,21 @@ GameScene::GameScene(ClientState& state) : Scene(state),
void GameScene::update() {
Window& window = state.renderer.window;
player.update(window.input, state.delta, window.input.mouseDelta());
game.update(state.delta);
refs.update(state.delta, net);
net.update();
world.update(state.delta);
for (auto entity : entities) entity->update(state.delta);
debugGui.update(player, world, game, state.fps, world.getMeshChunkCount(), drawCalls, net.serverSideChunkGens, net.recvPackets);
world.update(state.delta);
net.serverSideChunkGens = 0;
net.recvPackets = 0;
debugGui.update(*world.getPlayer(), state.fps, world.getActiveDimension().getMeshChunkCount(),
drawCalls, world.getNet().serverSideChunkGens, world.getNet().recvPackets);
world.getNet().serverSideChunkGens = 0;
world.getNet().recvPackets = 0;
if (window.input.keyPressed(GLFW_KEY_F1)) {
hudVisible = !hudVisible;
debugGui.changeVisibilityState(hudVisible ? debugVisible ? 0 : 2 : 1);
player.setHudVisible(hudVisible);
world.getPlayer()->setHudVisible(hudVisible);
}
if (window.input.keyPressed(GLFW_KEY_F3)) {
@ -72,15 +65,14 @@ void GameScene::draw() {
for (auto entity : entities) entity->draw(renderer);
world.renderEntities(renderer);
player.draw(renderer);
renderer.endDeferredCalls();
renderer.beginGUIDrawCalls();
renderer.enableTexture(&game.textures.atlasTexture);
player.drawHud(renderer);
world.getPlayer()->drawHud(renderer);
debugGui.draw(renderer);
player.drawMenu(renderer);
world.getPlayer()->drawMenu(renderer);
renderer.swapBuffers();
}

View File

@ -6,7 +6,7 @@
#include "../graph/scene/Scene.h"
#include "world/Player.h"
#include "world/LocalPlayer.h"
#include "world/LocalWorld.h"
#include "../../net/client/ClientNetworkInterpreter.h"
#include "../inventory/LocalInventoryRefs.h"
@ -25,11 +25,7 @@ public:
void cleanup() override;
public:
LocalSubgame& game;
ClientNetworkInterpreter net;
LocalInventoryRefs refs;
LocalWorld world;
Player player;
DebugGui debugGui;
std::vector<Drawable*> entities;

View File

@ -176,8 +176,8 @@ void MenuSandbox::showError(const std::string& what, const std::string& subgame)
errWrap->add(errMsg);
}
sol::protected_function_result MenuSandbox::errorCallback(sol::protected_function_result errPfr) {
sol::error err = errPfr;
sol::protected_function_result MenuSandbox::errorCallback(sol::protected_function_result r) const {
sol::error err = r;
std::string errString = err.what();
try {
@ -189,9 +189,8 @@ sol::protected_function_result MenuSandbox::errorCallback(sol::protected_functio
std::string fileName = errString.substr(0, lineNumStart);
int lineNum = std::stoi(errString.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1));
for (LuaMod::File& f : mod.files)
if (f.path == fileName)
throw std::runtime_error(ErrorFormatter::formatError(fileName, lineNum, errString, f.file));
for (const LuaMod::File& file : mod.files) if (file.path == fileName)
throw std::runtime_error(ErrorFormatter::formatError(fileName, lineNum, errString, file.file));
throw std::out_of_range("Error thrown outside of handled files. [2]");
}

View File

@ -32,7 +32,7 @@ private:
void showError(const std::string& what, const std::string& subgame);
sol::protected_function_result runFileSandboxed(const std::string& file);
sol::protected_function_result errorCallback(sol::protected_function_result errPfr);
virtual sol::protected_function_result errorCallback(sol::protected_function_result r) const override;
LuaMod mod {};
std::vector<std::shared_ptr<AtlasRef>> modAssets {};

View File

@ -0,0 +1,373 @@
//
// Created by aurailus on 28/12/18.
//
#include "LocalPlayer.h"
#include "LocalWorld.h"
#include "../../../util/Ray.h"
#include "../../graph/Renderer.h"
#include "../../entity/Collision.h"
#include "../../../net/Deserializer.h"
#include "../../../def/item/BlockDef.h"
#include "../../../world/chunk/Chunk.h"
#include "../../inventory/LocalInventoryList.h"
#include "../../../net/client/ClientNetworkInterpreter.h"
LocalPlayer::LocalPlayer(LocalSubgame& game, LocalDimension& dim, Renderer &renderer) :
Player(game, dim),
renderer(renderer),
wireframe({1, 1, 1}),
gameGui(*static_cast<LocalWorld&>(dim.getWorld()).getRefs(), renderer.window.getSize(), game, renderer) {
handItemModel.parent = &handModel;
renderer.window.addResizeCallback("player", [&](glm::ivec2 win) { gameGui.winResized(win); });
}
void LocalPlayer::update(Input &input, double delta, glm::vec2 mouseDelta) {
gameGui.update(delta);
handItemModel.setVisible(gameGui.isVisible());
updatePhysics(input, delta, mouseDelta);
Collision::moveCollide(game, dim, collision, pos, vel,
Collision::isOnGround(game, dim, collision, pos, vel) ? 0.6 : vel.y <= 0 ? 0.1 : 0);
updateCamera();
findPointedThing(input);
updateWireframe();
if (!gameGui.isInMenu()) interact(input, delta);
}
void LocalPlayer::assertField(Packet packet) {
packet.type = PacketType::THIS_PLAYER_INFO;
static_cast<LocalWorld&>(dim.getWorld()).getNet().sendPacket(packet, PacketChannel::INTERACT);
}
void LocalPlayer::handleAssertion(Deserializer &d) {
while (!d.atEnd()) {
switch (static_cast<NetField>(d.read<unsigned int>())) {
case NetField::ID: id = d.read<unsigned int>(); break;
case NetField::POS: setPos(d.read<glm::vec3>()); break;
case NetField::VEL: setVel(d.read<glm::vec3>()); break;
case NetField::PITCH: setPitch(d.read<float>()); break;
case NetField::YAW: setYaw(d.read<float>()); break;
case NetField::FLYING: setFlying(d.read<bool>()); break;
case NetField::HAND_INV: setHandList(d.read<std::string>()); break;
case NetField::WIELD_INV: setWieldList(d.read<std::string>()); break;
case NetField::WIELD_INDEX: setWieldIndex(d.read<unsigned short>()); break;
}
}
}
//
// Overridden Setters
//
void LocalPlayer::setPos(glm::vec3 pos, bool assert) {
Player::setPos(pos, assert);
this->renderer.camera.setPos(pos + getLookOffset());
}
void LocalPlayer::setLookOffset(glm::vec3 eyeOffset, bool assert) {
Player::setLookOffset(eyeOffset, assert);
this->renderer.camera.setPos(pos + getLookOffset());
}
void LocalPlayer::setHandList(const std::string &list, bool assert) {
Player::setHandList(list, assert);
static_cast<LocalWorld&>(dim.getWorld()).getRefs()->setHandList(list);
updateWieldAndHandItems();
}
void LocalPlayer::setWieldList(const std::string& list, bool assert) {
Player::setWieldList(list, false);
static_cast<LocalWorld&>(dim.getWorld()).getRefs()->setWieldList(list);
setWieldIndex(wieldIndex);
updateWieldAndHandItems();
if (assert) assertField(Serializer().append(
static_cast<unsigned int>(NetField::WIELD_INV)).append(list).packet());
}
void LocalPlayer::setWieldIndex(unsigned short index, bool assert) {
auto wieldList = static_cast<LocalWorld&>(dim.getWorld()).getRefs()->getWieldList();
wieldIndex = index % std::max((wieldList ? wieldList->getLength() : 1), 1);
updateWieldAndHandItems();
if (assert) assertField(Serializer().append(
static_cast<unsigned int>(NetField::WIELD_INDEX)).append(index).packet());
}
//
// UI Related
//
bool LocalPlayer::isInMenu() {
return gameGui.isInMenu();
}
void LocalPlayer::showMenu(std::shared_ptr<LuaGuiElement> root) {
gameGui.showMenu(root);
renderer.window.input.lockMouse(false);
}
void LocalPlayer::closeMenu() {
gameGui.closeMenu();
renderer.window.input.lockMouse(true);
}
void LocalPlayer::setHud(std::shared_ptr<LuaGuiElement> hud) {
gameGui.setHud(hud);
}
std::shared_ptr<LuaGuiElement> LocalPlayer::getHud() {
return gameGui.getHud();
}
void LocalPlayer::setHudVisible(bool hudVisible) {
gameGui.setVisible(hudVisible);
}
//
// Misc Getters
//
LocalInventory& LocalPlayer::getInventory() {
return static_cast<LocalWorld&>(dim.getWorld()).getRefs()->getInventory("current_player");
}
Target& LocalPlayer::getPointedThing() {
return target;
}
//
// Draw Functions
//
void LocalPlayer::draw(Renderer &renderer) {
wireframe.draw(renderer);
handItemModel.draw(renderer);
}
void LocalPlayer::drawHud(Renderer &renderer) {
gameGui.drawHud(renderer);
}
void LocalPlayer::drawMenu(Renderer &renderer) {
gameGui.drawMenu(renderer);
}
//
// Private uncategorized.
// TODO: Categorize and optimize.
//
bool LocalPlayer::getKey(Input& input, LocalPlayer::PlayerControl control) {
if (gameGui.isInMenu()) return false;
return input.keyDown(
control == PlayerControl::FORWARD ? GLFW_KEY_W :
control == PlayerControl::BACKWARD ? GLFW_KEY_S :
control == PlayerControl::LEFT ? GLFW_KEY_A :
control == PlayerControl::RIGHT ? GLFW_KEY_D :
control == PlayerControl::JUMP ? GLFW_KEY_SPACE :
control == PlayerControl::MOD1 ? GLFW_KEY_LEFT_SHIFT :
GLFW_KEY_LEFT_CONTROL);
}
void LocalPlayer::updatePhysics(Input &input, double delta, glm::vec2 mouseDelta) {
static constexpr float JUMP_VEL = 0.14f;
static constexpr float BASE_MOVE_SPEED = 4.3f;
static constexpr float MOUSE_SENSITIVITY = 0.1f;
//Position movement
bool sprinting = getKey(input, PlayerControl::MOD2);
double moveSpeed = BASE_MOVE_SPEED * delta * (sprinting ? 1.6 : 1);
float friction = 0.3f;
if (flying) {
moveSpeed *= 4;
friction = 0.15f;
}
else if (getKey(input, PlayerControl::JUMP) &&
Collision::isOnGround(game, dim, collision, pos, vel)) vel.y = JUMP_VEL;
//Calculate movement vector from camera angle.
auto& camera = renderer.camera;
glm::vec3 frontFlat = glm::normalize(glm::vec3(camera.getFront().x, 0, camera.getFront().z));
glm::vec3 rightFlat = glm::normalize(glm::vec3(camera.getRight().x, 0, camera.getRight().z));
glm::vec3 mod {0, 0, 0};
if (getKey(input, PlayerControl::FORWARD)) mod += frontFlat;
if (getKey(input, PlayerControl::BACKWARD)) mod -= frontFlat;
if (getKey(input, PlayerControl::RIGHT)) mod += rightFlat;
if (getKey(input, PlayerControl::LEFT)) mod -= rightFlat;
if (flying) {
if (getKey(input, PlayerControl::JUMP)) mod.y += 1;
if (getKey(input, PlayerControl::MOD1)) mod.y -= 1;
}
else {
if (!Collision::isOnGround(game, dim, collision, pos, vel)) vel.y = std::fmax(vel.y - 0.0085, -3);
else if (vel.y < 0) vel.y = 0;
}
if (glm::length(mod) != 0) mod = glm::normalize(mod);
mod = mod * static_cast<float>(moveSpeed);
if (!flying) {
glm::vec3 velFlat = {vel.x, 0, vel.z};
//Add movement vector with friction.
velFlat = velFlat * (1.0f-friction) + mod * friction;
vel.x = velFlat.x;
vel.z = velFlat.z;
}
else {
//If flying factor in vertical mod values.
vel = vel * (1.0f-friction) + mod * friction;
}
//View movement
mouseDelta.x *= MOUSE_SENSITIVITY;
mouseDelta.y *= MOUSE_SENSITIVITY;
yaw += mouseDelta.x;
pitch += mouseDelta.y;
while (yaw > 360.f) yaw -= 360.f;
while (yaw < 0.f) yaw += 360.f;
pitch = std::fmin(std::fmax(pitch, -90), 90);
}
void LocalPlayer::updateCamera() {
renderer.camera.setYaw(yaw);
renderer.camera.setPitch(pitch);
auto type = game.getDefs().fromId(wieldItem).type;
glm::vec3 eyesPos = pos + getLookOffset();
renderer.camera.setPos(eyesPos);
float pitch = std::min(std::max(this->pitch, -89.9f), 89.9f);
glm::vec3 front = glm::normalize(glm::vec3 {
cos(glm::radians(yaw)) * cos(glm::radians(pitch)),
sin(glm::radians(pitch)),
sin(glm::radians(yaw)) * cos(glm::radians(pitch))});
glm::vec3 right = glm::normalize(glm::cross(front, {0, 1, 0}));
glm::vec3 up = glm::normalize(glm::cross(right, front));
glm::vec3 handPos = eyesPos + front * 0.25f + right * 0.25f + up * (type == ItemDef::Type::CRAFTITEM ? -0.15f : -0.2f);
handModel.setRotateY(-yaw);
handModel.setRotateZ(pitch);
if (type == ItemDef::Type::CRAFTITEM) {
handItemModel.setRotateX(45);
handItemModel.setRotateY(110);
handItemModel.setRotateZ(-25);
}
else {
handItemModel.setRotateX(0);
handItemModel.setRotateY(0);
handItemModel.setRotateZ(0);
}
handItemModel.setPos(handPos + vel * 0.1f);
handItemModel.setScale((type == ItemDef::Type::CRAFTITEM ? 0.2f : 0.12f));
}
void LocalPlayer::findPointedThing(Input &input) {
static constexpr float LOOK_DISTANCE = 6.5f;
static constexpr float LOOK_PRECISION = 0.01f;
glm::ivec3 chunkPos = {};
std::unique_lock<std::mutex> lock {};
std::shared_ptr<Chunk> blockChunk = nullptr;
for (Ray ray(*this); ray.getLength() < LOOK_DISTANCE; ray.step(LOOK_PRECISION)) {
glm::vec3 rayEnd = ray.getEnd();
glm::ivec3 roundedPos = glm::floor(rayEnd);
glm::ivec3 currChunkPos = Space::Chunk::world::fromBlock(roundedPos);
if (currChunkPos != chunkPos || blockChunk == nullptr) {
chunkPos = currChunkPos;
blockChunk = dim.getChunk(chunkPos);
if (blockChunk == nullptr) continue;
lock = blockChunk->aquireLock();
}
unsigned int blockID = blockChunk->getBlock(Space::Block::relative::toChunk(roundedPos));
auto& boxes = game.getDefs().blockFromId(blockID).sBoxes;
for (auto& sBox : boxes) {
auto face = sBox.intersects(rayEnd, roundedPos);
if (face != EVec::NONE) {
target = Target(roundedPos, face);
return;
}
}
}
target = Target {};
}
void LocalPlayer::updateWireframe() {
if (!gameGui.isVisible()) {
wireframe.setVisible(false);
}
else if (target.type == Target::Type::BLOCK) {
auto& boxes = game.getDefs().blockFromId(dim.getBlock(target.pos)).sBoxes;
float distance = glm::distance(pos, target.pos + glm::vec3(0.5));
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
wireframe.setPos(target.pos);
wireframe.setVisible(true);
}
else {
wireframe.setVisible(false);
}
}
void LocalPlayer::interact(Input& input, double delta) {
if (target.type == Target::Type::BLOCK) {
if (input.mouseDown(GLFW_MOUSE_BUTTON_LEFT) && breakTime == 0) {
breakInterval = dim.blockHit(target, static_cast<LocalWorld&>(dim.getWorld()).getPlayer());
breakTime += delta;
}
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT))
dim.blockPlaceOrInteract(target, static_cast<LocalWorld&>(dim.getWorld()).getPlayer());
}
if (breakTime > 0) breakTime += delta;
if (breakTime > breakInterval) breakTime = 0;
}
void LocalPlayer::updateWieldAndHandItems() {
auto handList = static_cast<LocalWorld&>(dim.getWorld()).getRefs()->getHandList();
auto wieldList = static_cast<LocalWorld&>(dim.getWorld()).getRefs()->getWieldList();
handItem = handList && handList->getLength() > 0 ? handList->getStack(0).id : 0;
wieldItem = wieldList && wieldList->getLength() > wieldIndex ? wieldList->getStack(wieldIndex).id : 0;
auto& model = game.getDefs().fromId(wieldItem <= DefinitionAtlas::AIR ? handItem : wieldItem).entityModel;
handItemModel.setModel(model);
}
LocalPlayer::~LocalPlayer() {
renderer.window.removeResizeCallback("player");
}
LocalDimension& LocalPlayer::getDimension() {
return static_cast<LocalDimension&>(dim);
}

View File

@ -0,0 +1,81 @@
//
// Created by aurailus on 28/12/18.
//
#pragma once
#include "Player.h"
#include "../../graph/drawable/Drawable.h"
#include "../../hud/GameGui.h"
#include "../../../world/Target.h"
#include "../../../world/LocalDimension.h"
#include "../../entity/engine/WireframeEntity.h"
class Input;
class Deserializer;
class LuaGuiElement;
class LocalInventory;
class LocalInventoryRefs;
enum class NetPlayerField;
class LocalPlayer : public virtual DrawableEntity, public Player {
public:
enum class PlayerControl { FORWARD, LEFT, BACKWARD, RIGHT, JUMP, MOD1, MOD2 };
LocalPlayer(LocalSubgame &game, LocalDimension& dim, Renderer &renderer);
void update(Input &input, double delta, glm::vec2 mouseDelta);
virtual void assertField(Packet packet) override;
virtual void handleAssertion(Deserializer& d) override;
virtual LocalInventory& getInventory() override;
virtual LocalDimension& getDimension() override;
virtual void setPos(glm::vec3 pos, bool assert = false) override;
virtual void setLookOffset(glm::vec3 eyeOffset, bool assert = false) override;
virtual void setHandList(const std::string& list, bool assert = false) override;
virtual void setWieldList(const std::string& list, bool assert = false) override;
virtual void setWieldIndex(unsigned short index, bool assert = false) override;
bool isInMenu();
void showMenu(std::shared_ptr<LuaGuiElement> root);
void closeMenu();
void setHud(std::shared_ptr<LuaGuiElement> hud);
std::shared_ptr<LuaGuiElement> getHud();
void setHudVisible(bool hudVisible);
Target& getPointedThing();
void draw(Renderer& renderer) override;
void drawHud(Renderer& renderer);
void drawMenu(Renderer& renderer);
~LocalPlayer();
private:
bool getKey(Input& input, PlayerControl control);
void updatePhysics(Input &input, double delta, glm::vec2 mouseDelta);
void updateCamera();
void findPointedThing(Input &input);
void updateWireframe();
void interact(Input& input, double delta);
void updateWieldAndHandItems();
GameGui gameGui;
DrawableEntity handModel;
DrawableEntity handItemModel;
WireframeEntity wireframe;
Renderer& renderer;
double breakTime = 0;
double breakInterval = 0;
Target target;
};

View File

@ -4,178 +4,166 @@
#include "LocalWorld.h"
#include "Player.h"
#include "LocalPlayer.h"
#include "../../graph/Renderer.h"
#include "../../../net/PacketView.h"
#include "WorldInterpolationStream.h"
#include "../../../world/chunk/Chunk.h"
#include "../../../def/item/BlockDef.h"
#include "../../../lua/usertype/Target.h"
#include "../../../lua/usertype/LuaItemStack.h"
#include "../../inventory/LocalInventoryList.h"
#include "../../entity/engine/ParticleEntity.h"
#include "../../entity/engine/BlockCrackEntity.h"
#include "../../../lua/usertype/LocalLuaPlayer.h"
#include "../../../net/client/ClientNetworkInterpreter.h"
LocalWorld::LocalWorld(LocalSubgame& defs, ClientNetworkInterpreter* server) :
World(defs),
game(defs),
net(server),
dimension(defs) {}
LocalWorld::LocalWorld(LocalSubgame& game, ServerConnection& conn, Renderer& renderer) :
World(game),
renderer(renderer),
net(conn, game, *this),
refs(std::make_shared<LocalInventoryRefs>(game, net)),
worldGenStream(std::make_shared<WorldInterpolationStream>(55, game)) {}
void LocalWorld::init(Player* player) {
this->player = player;
delete worldGenStream;
worldGenStream = new WorldInterpolationStream(55, game);
void LocalWorld::connect() {
net.init(Util::bind_this(&(*refs), &LocalInventoryRefs::packetReceived));
refs->init();
}
bool LocalWorld::initPlayer() {
if (defaultDimension.empty()) return false;
player = std::make_shared<LocalPlayer>(static_cast<LocalSubgame&>(game), getDefaultDimension(), renderer);
activeDimension = getDefaultDimensionPtr();
return true;
}
void LocalWorld::update(double delta) {
finishChunks();
updateBlockDamages(delta);
dimension.update(delta, player->getPos());
lastMeshUpdates = dimension.lastMeshUpdates;
World::update(delta);
auto end = particles.begin();
for (auto i = particles.begin(); i < particles.end(); i++) {
(*i)->update(delta, player->getPos());
if ((*i)->time > 1) {
end = i;
delete (*i);
}
}
if (end != particles.begin()) particles.erase(particles.begin(), end + 1);
if (player) player->update(renderer.window.input, delta, renderer.window.input.mouseDelta());
refs->update(delta, net);
net.update();
auto finishedChunks = worldGenStream->update();
mapBlocksInterpolated = finishedChunks->size() / 64;
for (const auto &chunk : *finishedChunks) commitChunk(chunk);
}
void LocalWorld::loadWorldPacket(std::unique_ptr<PacketView> p) {
void LocalWorld::handleWorldPacket(std::unique_ptr<PacketView> p) {
worldGenStream->queuePacket(std::move(p));
}
void LocalWorld::handlePlayerEntPacket(std::unique_ptr<PacketView> p) {
if (!player) throw std::runtime_error("Received playerEnt info *before* the player was created.");
unsigned int id = p->d.read<unsigned int>();
if (player->getId() == id) return;
bool found = false;
for (auto& entity : getActiveDimension().playerEntities) {
if (entity.getId() == id) {
entity.interpPos(p->d.read<glm::vec3>());
entity.interpRotateZ(-p->d.read<float>() + 90);
entity.interpRotateY(-p->d.read<float>() + 90);
found = true;
break;
}
}
if (found) return;
//TODO: Reimplement player models.
// auto playerModel = std::make_shared<Model>();
// playerModel->fromSerialized(static_cast<LocalSubgame&>(game).models.models["zeus:default:player"],
// { static_cast<LocalSubgame&>(game).textures["zeus:default:player"] });
// getActiveDimension().playerEntities.emplace_back(p->d.read<glm::vec3>(), id, playerModel);
}
void LocalWorld::commitChunk(std::shared_ptr<Chunk> c) {
dimension.setChunk(std::move(c));
activeDimension->setChunk(std::move(c));
}
unsigned int LocalWorld::getBlock(glm::ivec3 pos) {
return dimension.getBlock(pos);
LocalDimension& LocalWorld::createDimension(const std::string &identifier) {
this->dimensions.emplace_back(std::make_shared<LocalDimension>(static_cast<LocalSubgame&>(game), *this, identifier, this->dimensions.size()));
return static_cast<LocalDimension&>(*dimensions[dimensions.size() - 1]);
}
void LocalWorld::setBlock(glm::ivec3 pos, unsigned int block) {
dimension.setBlock(pos, block);
LocalDimension& LocalWorld::getDefaultDimension() {
return static_cast<LocalDimension&>(World::getDefaultDimension());
}
double LocalWorld::setBlockDamage(glm::ivec3 pos, double damage) {
double totalDamage = World::setBlockDamage(pos, damage);
BlockCrackEntity* block = nullptr;
if (crackEntities.count(pos)) block = crackEntities[pos];
else block = new BlockCrackEntity(game.defs->blockFromId(getBlock(pos)), game.textures, pos);
block->setDamage(damage);
block->time = 0;
return totalDamage;
LocalDimension& LocalWorld::getDimension(unsigned int index) {
return static_cast<LocalDimension&>(*dimensions[index]);
}
void LocalWorld::blockPlace(Target& target) {
std::tuple<sol::optional<LuaItemStack>, sol::optional<glm::vec3>> res = game.lua->safe_function(
game.lua->core["block_place"], LocalLuaPlayer(*player), Api::Usertype::Target(target));
auto stack = std::get<sol::optional<LuaItemStack>>(res);
if (stack) player->getWieldList()->setStack(player->getWieldIndex(), ItemStack(*stack, game.getDefs()));
net->blockPlace(target);
LocalDimension& LocalWorld::getDimension(const std::string &identifier) {
for (auto& dimension : dimensions)
if (dimension->getIdentifier() == identifier)
return static_cast<LocalDimension&>(*dimension);
throw std::runtime_error("No dimension named " + identifier + " found.");
}
void LocalWorld::blockInteract(Target &target) {
game.lua->safe_function(game.lua->core["block_interact"],
LocalLuaPlayer(*player), Api::Usertype::Target(target));
net->blockInteract(target);
std::shared_ptr<LocalDimension> LocalWorld::getDefaultDimensionPtr() {
for (auto& dimension : dimensions)
if (dimension->getIdentifier() == defaultDimension)
return std::static_pointer_cast<LocalDimension>(dimension);
throw std::runtime_error("No default dimension set.");
}
void LocalWorld::blockPlaceOrInteract(Target &target) {
std::tuple<sol::optional<LuaItemStack>, sol::optional<glm::vec3>> res = game.lua->safe_function(
game.lua->core["block_interact_or_place"], LocalLuaPlayer(*player), Api::Usertype::Target(target));
auto stack = std::get<sol::optional<LuaItemStack>>(res);
if (stack) player->getWieldList()->setStack(player->getWieldIndex(), ItemStack(*stack, game.getDefs()));
net->blockPlaceOrInteract(target);
std::shared_ptr<LocalDimension> LocalWorld::getDimensionPtr(const std::string &identifier) {
for (auto& dimension : dimensions)
if (dimension->getIdentifier() == identifier)
return std::static_pointer_cast<LocalDimension>(dimension);
throw std::runtime_error("No dimension named " + identifier + " found.");
}
double LocalWorld::blockHit(Target& target) {
double timeout = 0, damage = 0;
sol::tie(damage, timeout) = game.lua->safe_function(game.lua->core["block_hit"],
LocalLuaPlayer(*player), Api::Usertype::Target(target));
// net->blockHit(target);
return timeout;
ClientNetworkInterpreter& LocalWorld::getNet() {
return net;
}
unsigned short LocalWorld::getBiome(glm::vec3 pos) {
auto chunkPos = Space::Chunk::world::fromBlock(pos);
auto local = Space::Block::relative::toChunk(pos);
auto chunk = getChunk(chunkPos);
auto l = chunk->aquireLock();
if (chunk != nullptr) return chunk->getBiome(local);
return BiomeAtlas::INVALID;
LocalDimension& LocalWorld::getActiveDimension() {
return *activeDimension;
}
std::shared_ptr<Chunk> LocalWorld::getChunk(glm::ivec3 pos) {
return dimension.getChunk(pos);
std::shared_ptr<LocalPlayer> LocalWorld::getPlayer() {
return player;
}
int LocalWorld::getMeshChunkCount() {
return dimension.getMeshChunkCount();
std::shared_ptr<LocalInventoryRefs> LocalWorld::getRefs() {
return refs;
}
int LocalWorld::renderChunks(Renderer &renderer) {
return dimension.renderChunks(renderer);
return activeDimension->renderChunks(renderer);
}
void LocalWorld::renderEntities(Renderer &renderer) {
for (auto& block : crackEntities) block.second->draw(renderer);
for (auto& particle : particles) particle->draw(renderer);
dimension.renderEntities(renderer);
activeDimension->renderEntities(renderer);
player->draw(renderer);
}
void LocalWorld::updateBlockDamages(double delta) {
auto it = crackEntities.cbegin();
while (it != crackEntities.cend()) {
bool deleteMe = false;
auto curr = it++;
auto block = curr->second;
block->time += delta;
if (block->damage >= block->maxHealth) {
//Todo: Lua callback~
setBlock(block->getPos(), DefinitionAtlas::AIR);
setBlockDamage(block->getPos(), 0);
deleteMe = true;
}
if (block->time > 2) {
block->update();
block->addDamage(-1);
block->time = 0;
}
if (block->damage < 0 || block->def.index != getBlock(block->getPos())) {
deleteMe = true;
}
if (deleteMe) {
delete block;
it = crackEntities.erase(curr);
}
else block->update();
}
}
void LocalWorld::finishChunks() {
auto finishedChunks = worldGenStream->update();
mapBlocksInterpolated = finishedChunks->size() / 64;
for (const auto &chunk : *finishedChunks) commitChunk(chunk);
}
//void LocalWorld::updateBlockDamages(double delta) {
// auto it = crackEntities.cbegin();
// while (it != crackEntities.cend()) {
// bool deleteMe = false;
//
// auto curr = it++;
// auto block = curr->second;
//
// block->time += delta;
//
// if (block->damage >= block->maxHealth) {
// //Todo: Lua callback~
// setBlock(block->getPos(), DefinitionAtlas::AIR);
// setBlockDamage(block->getPos(), 0);
// deleteMe = true;
// }
//
// if (block->time > 2) {
// block->update();
// block->addDamage(-1);
// block->time = 0;
// }
//
// if (block->damage < 0 || block->def.index != getBlock(block->getPos())) {
// deleteMe = true;
// }
//
// if (deleteMe) {
// delete block;
// it = crackEntities.erase(curr);
// }
// else block->update();
// }
//}

View File

@ -7,59 +7,55 @@
#include "World.h"
#include "../../../world/LocalDimension.h"
#include "../../../net/client/ClientNetworkInterpreter.h"
class Target;
class Player;
class Window;
class Renderer;
class ItemStack;
class LocalPlayer;
class LocalSubgame;
class ParticleEntity;
class BlockCrackEntity;
class ClientNetworkInterpreter;
class LocalInventoryRefs;
class WorldInterpolationStream;
class LocalWorld : public World {
public:
LocalWorld(LocalSubgame& defs, ClientNetworkInterpreter* net);
LocalWorld(LocalSubgame& game, ServerConnection& conn, Renderer& window);
void init(Player* player);
void connect();
bool initPlayer();
void update(double delta) override;
void createDimension(std::string identifier);
void loadWorldPacket(std::unique_ptr<PacketView> p);
void handleWorldPacket(std::unique_ptr<PacketView> p);
void handlePlayerEntPacket(std::unique_ptr<PacketView> p);
void commitChunk(std::shared_ptr<Chunk> chunk);
unsigned int getBlock(glm::ivec3 pos) override;
void setBlock(glm::ivec3 pos, unsigned int block) override;
virtual LocalDimension& createDimension(const std::string& identifier) override;
double setBlockDamage(glm::ivec3 pos, double damage) override;
virtual LocalDimension& getDefaultDimension() override;
void blockPlace(Target& target);
void blockPlaceOrInteract(Target& target);
void blockInteract(Target& target);
double blockHit(Target& target);
virtual LocalDimension& getDimension(unsigned int index) override;
virtual LocalDimension& getDimension(const std::string& identifier) override;
unsigned short getBiome(glm::vec3 pos);
std::shared_ptr<Chunk> getChunk(glm::ivec3 pos);
std::shared_ptr<LocalDimension> getDefaultDimensionPtr();
std::shared_ptr<LocalDimension> getDimensionPtr(const std::string& identifier);
ClientNetworkInterpreter& getNet();
LocalDimension& getActiveDimension();
std::shared_ptr<LocalPlayer> getPlayer();
std::shared_ptr<LocalInventoryRefs> getRefs();
int getMeshChunkCount();
int renderChunks(Renderer &render);
void renderEntities(Renderer &renderer);
LocalSubgame& game;
LocalDimension dimension;
int mapBlocksInterpolated = 0;
int lastMeshUpdates = 0;
private:
void finishChunks();
void updateBlockDamages(double delta);
Renderer& renderer;
std::unordered_map<glm::ivec3, BlockCrackEntity*, Vec::ivec3> crackEntities;
std::vector<ParticleEntity*> particles;
ClientNetworkInterpreter net;
std::shared_ptr<LocalInventoryRefs> refs;
std::shared_ptr<LocalPlayer> player = nullptr;
Player* player = nullptr;
ClientNetworkInterpreter* net = nullptr;
WorldInterpolationStream* worldGenStream = nullptr;
std::shared_ptr<LocalDimension> activeDimension = nullptr;
std::shared_ptr<WorldInterpolationStream> worldGenStream = nullptr;
};

View File

@ -88,7 +88,7 @@ void MeshGenStream::Thread::exec() {
auto& u = jobs[i];
if (!u.busy) continue;
ChunkMeshGenerator m(u.meshDetails, *game.defs, *game.biomes, u.thisChunk, u.adjacentChunks, offsetSamplers);
ChunkMeshGenerator m(u.meshDetails, game.getDefs(), game.getBiomes(), u.thisChunk, u.adjacentChunks, offsetSamplers);
empty = false;
u.busy = false;
}

View File

@ -1,251 +1,27 @@
//
// Created by aurailus on 28/12/18.
// Created by aurailus on 2020-07-28.
//
#include "Player.h"
#include "LocalWorld.h"
#include "../../../util/Ray.h"
#include "../../graph/Renderer.h"
#include "../../../def/ItemDef.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"
#include "../../../net/client/ClientNetworkInterpreter.h"
#include "../../../net/Serializer.h"
Player::Player(LocalSubgame &game, LocalWorld &world, Renderer &renderer, LocalInventoryRefs &refs, ClientNetworkInterpreter& net) :
Collidable(world, game, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
net(net),
refs(refs),
game(game),
renderer(renderer),
wireframe({}, 0.01, {1, 1, 1}),
gameGui(refs, renderer.window.getSize(), game, renderer) {
handItemModel.parent = &handModel;
renderer.window.addResizeCallback("player", [&](glm::ivec2 win) {
gameGui.winResized(win);
});
unsigned int Player::getId() {
return id;
}
void Player::update(Input &input, double delta, glm::vec2 mouseDelta) {
gameGui.update(delta);
handItemModel.setVisible(gameGui.isVisible());
updatePhysics(input, delta, mouseDelta);
moveCollide(isOnGround() ? 0.6 : vel.y <= 0 ? 0.1 : 0);
updateCamera();
findPointedThing(input);
updateWireframe();
if (!gameGui.isInMenu()) interact(input, delta);
}
bool Player::getKey(Input& input, Player::PlayerControl control) {
if (gameGui.isInMenu()) return false;
return input.keyDown(
control == PlayerControl::FORWARD ? GLFW_KEY_W :
control == PlayerControl::BACKWARD ? GLFW_KEY_S :
control == PlayerControl::LEFT ? GLFW_KEY_A :
control == PlayerControl::RIGHT ? GLFW_KEY_D :
control == PlayerControl::JUMP ? GLFW_KEY_SPACE :
control == PlayerControl::MOD1 ? GLFW_KEY_LEFT_SHIFT :
GLFW_KEY_LEFT_CONTROL);
}
void Player::updatePhysics(Input &input, double delta, glm::vec2 mouseDelta) {
//Position movement
bool sprinting = getKey(input, PlayerControl::MOD2);
double moveSpeed = BASE_MOVE_SPEED * delta * (sprinting ? 1.6 : 1);
float friction = 0.3f;
if (flying) {
moveSpeed *= 4;
friction = 0.15f;
}
else if (getKey(input, PlayerControl::JUMP) && isOnGround()) vel.y = JUMP_VEL;
//Calculate movement vector from camera angle.
auto& camera = renderer.camera;
glm::vec3 frontFlat = glm::normalize(glm::vec3(camera.getFront().x, 0, camera.getFront().z));
glm::vec3 rightFlat = glm::normalize(glm::vec3(camera.getRight().x, 0, camera.getRight().z));
glm::vec3 mod {0, 0, 0};
if (getKey(input, PlayerControl::FORWARD)) mod += frontFlat;
if (getKey(input, PlayerControl::BACKWARD)) mod -= frontFlat;
if (getKey(input, PlayerControl::RIGHT)) mod += rightFlat;
if (getKey(input, PlayerControl::LEFT)) mod -= rightFlat;
if (flying) {
if (getKey(input, PlayerControl::JUMP)) mod.y += 1;
if (getKey(input, PlayerControl::MOD1)) mod.y -= 1;
}
else {
if (!isOnGround()) vel.y = std::fmax(vel.y - 0.0085, -3);
else if (vel.y < 0) vel.y = 0;
}
if (glm::length(mod) != 0) mod = glm::normalize(mod);
mod = mod * static_cast<float>(moveSpeed);
if (!flying) {
glm::vec3 velFlat = {vel.x, 0, vel.z};
//Add movement vector with friction.
velFlat = velFlat * (1.0f-friction) + mod * friction;
vel.x = velFlat.x;
vel.z = velFlat.z;
}
else {
//If flying factor in vertical mod values.
vel = vel * (1.0f-friction) + mod * friction;
}
//View movement
mouseDelta.x *= MOUSE_SENSITIVITY;
mouseDelta.y *= MOUSE_SENSITIVITY;
yaw += mouseDelta.x;
pitch += mouseDelta.y;
while (yaw > 360.f) yaw -= 360.f;
while (yaw < 0.f) yaw += 360.f;
pitch = std::fmin(std::fmax(pitch, -90), 90);
}
void Player::updateCamera() {
renderer.camera.setYaw(yaw);
renderer.camera.setPitch(pitch);
auto type = game.defs->fromId(wieldItem).type;
glm::vec3 eyesPos = {pos.x, pos.y + EYE_HEIGHT, pos.z};
renderer.camera.setPos(eyesPos);
float pitch = std::min(std::max(this->pitch, -89.9f), 89.9f);
glm::vec3 front = glm::normalize(glm::vec3 {
cos(glm::radians(yaw)) * cos(glm::radians(pitch)),
sin(glm::radians(pitch)),
sin(glm::radians(yaw)) * cos(glm::radians(pitch))});
glm::vec3 right = glm::normalize(glm::cross(front, {0, 1, 0}));
glm::vec3 up = glm::normalize(glm::cross(right, front));
glm::vec3 handPos = eyesPos + front * 0.25f + right * 0.25f + up * (type == ItemDef::Type::CRAFTITEM ? -0.15f : -0.2f);
handModel.setRotateY(-yaw);
handModel.setRotateZ(pitch);
if (type == ItemDef::Type::CRAFTITEM) {
handItemModel.setRotateX(45);
handItemModel.setRotateY(110);
handItemModel.setRotateZ(-25);
}
else {
handItemModel.setRotateX(0);
handItemModel.setRotateY(0);
handItemModel.setRotateZ(0);
}
handItemModel.setPos(handPos + vel * 0.1f);
handItemModel.setScale((type == ItemDef::Type::CRAFTITEM ? 0.2f : 0.12f));
}
void Player::findPointedThing(Input &input) {
glm::ivec3 chunkPos = {};
std::unique_lock<std::mutex> lock {};
std::shared_ptr<Chunk> blockChunk = nullptr;
for (Ray ray(this); ray.getLength() < LOOK_DISTANCE; ray.step(LOOK_PRECISION)) {
glm::vec3 rayEnd = ray.getEnd();
glm::ivec3 roundedPos = glm::floor(rayEnd);
glm::ivec3 currChunkPos = Space::Chunk::world::fromBlock(roundedPos);
if (currChunkPos != chunkPos || blockChunk == nullptr) {
chunkPos = currChunkPos;
blockChunk = world.getChunk(chunkPos);
if (blockChunk == nullptr) continue;
lock = blockChunk->aquireLock();
}
unsigned int blockID = blockChunk->getBlock(Space::Block::relative::toChunk(roundedPos));
auto& boxes = game.defs->blockFromId(blockID).sBoxes;
for (auto& sBox : boxes) {
auto face = sBox.intersects(rayEnd, roundedPos);
if (face != EVec::NONE) {
target = Target(roundedPos, face);
return;
}
}
}
target = Target {};
}
void Player::updateWireframe() {
if (!gameGui.isVisible()) {
wireframe.setVisible(false);
}
else if (target.type == Target::Type::BLOCK) {
auto& boxes = game.defs->blockFromId(world.getBlock(target.pos)).sBoxes;
float distance = glm::distance(pos, target.pos + glm::vec3(0.5));
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
wireframe.setPos(target.pos);
wireframe.setVisible(true);
}
else {
wireframe.setVisible(false);
}
}
void Player::interact(Input& input, double delta) {
if (target.type == Target::Type::BLOCK) {
if (input.mouseDown(GLFW_MOUSE_BUTTON_LEFT) && breakTime == 0) {
breakInterval = world.blockHit(target);
breakTime += delta;
}
else if (input.mousePressed(GLFW_MOUSE_BUTTON_RIGHT)) world.blockPlaceOrInteract(target);
}
if (breakTime > 0) breakTime += delta;
if (breakTime > breakInterval) breakTime = 0;
}
//
// Getters and Setters
//
glm::vec3 Player::getPos() {
return pos;
void Player::setId(unsigned int id) {
this->id = id;
}
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) net.assertPlayerField(NetPlayerField::POSITION, pos);
}
glm::vec3 Player::getVel() {
return vel;
Entity::setPos(pos);
if (assert) assertField(Serializer().appendE(NetField::POS).append(pos).packet());
}
void Player::setVel(glm::vec3 vel, bool assert) {
this->vel = vel;
if (assert) net.assertPlayerField(NetPlayerField::VELOCITY, vel);
Entity::setVel(vel);
if (assert) assertField(Serializer().appendE(NetField::VEL).append(vel).packet());
}
float Player::getYaw() {
@ -254,7 +30,7 @@ float Player::getYaw() {
void Player::setYaw(float yaw, bool assert) {
this->yaw = yaw;
if (assert) net.assertPlayerField(NetPlayerField::YAW, yaw);
if (assert) assertField(Serializer().appendE(NetField::YAW).append(yaw).packet());
}
float Player::getPitch() {
@ -263,44 +39,44 @@ float Player::getPitch() {
void Player::setPitch(float pitch, bool assert) {
this->pitch = pitch;
if (assert) net.assertPlayerField(NetPlayerField::PITCH, pitch);
if (assert) assertField(Serializer().appendE(NetField::PITCH).append(pitch).packet());
}
glm::vec3 Player::getLookOffset() {
return this->lookOffset;
}
void Player::setLookOffset(glm::vec3 lookOffset, bool assert) {
this->lookOffset = lookOffset;
if (assert) assertField(Serializer().appendE(NetField::LOOK_OFF).append(lookOffset).packet());
}
bool Player::isFlying() {
return flying;
}
void Player::setFlying(bool flying, bool assert) {
this->flying = flying;
if (assert) net.assertPlayerField(NetPlayerField::FLYING, flying);
if (assert) assertField(Serializer().appendE(NetField::FLYING).append(flying).packet());
}
Target& Player::getPointedThing() {
return target;
std::string &Player::getHandList() {
return handList;
}
LocalInventory& Player::getInventory() {
return *refs.getInv("current_player");
void Player::setHandList(const std::string &list, bool assert) {
handList = list;
if (assert) assertField(Serializer().appendE(NetField::HAND_INV).append(handList).packet());
}
std::shared_ptr<LocalInventoryList> Player::getHandList() {
return refs.getHandList();
std::string &Player::getWieldList() {
return wieldList;
}
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) net.assertPlayerField(NetPlayerField::WIELD_INV, list);
void Player::setWieldList(const std::string &list, bool assert) {
wieldList = list;
if (assert) assertField(Serializer().appendE(NetField::WIELD_INV).append(wieldList).packet());
}
unsigned short Player::getWieldIndex() {
@ -308,89 +84,6 @@ unsigned short Player::getWieldIndex() {
}
void Player::setWieldIndex(unsigned short index, bool assert) {
auto wieldList = refs.getWieldList();
wieldIndex = index % std::max((wieldList ? wieldList->getLength() : 1), 1);
updateWieldAndHandItems();
if (assert) net.assertPlayerField(NetPlayerField::WIELD_INDEX, static_cast<unsigned short>(index));
}
/*
* GUI Functions
*/
void Player::showMenu(std::shared_ptr<LuaGuiElement> root) {
gameGui.showMenu(root);
renderer.window.input.lockMouse(false);
}
void Player::closeMenu() {
gameGui.closeMenu();
renderer.window.input.lockMouse(true);
}
bool Player::isInMenu() {
return gameGui.isInMenu();
}
void Player::setHud(std::shared_ptr<LuaGuiElement> hud) {
gameGui.setHud(hud);
}
std::shared_ptr<LuaGuiElement> Player::getHud() {
return gameGui.getHud();
}
void Player::setHudVisible(bool hudVisible) {
gameGui.setVisible(hudVisible);
}
/*
* Render functions
*/
void Player::draw(Renderer &renderer) {
wireframe.draw(renderer);
handItemModel.draw(renderer);
}
void Player::drawHud(Renderer &renderer) {
gameGui.drawHud(renderer);
}
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);
}
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");
wieldIndex = index;
if (assert) assertField(Serializer().append(NetField::WIELD_INDEX).append(index).packet());
}

View File

@ -1,117 +1,85 @@
//
// Created by aurailus on 28/12/18.
// Created by aurailus on 2020-07-28.
//
#pragma once
#include "../../entity/Collidable.h"
#include "../../graph/drawable/Drawable.h"
#include <memory>
#include <glm/vec3.hpp>
#include "../../hud/GameGui.h"
#include "../../../world/Target.h"
#include "../../entity/engine/WireframeEntity.h"
#include "../../entity/Entity.h"
#include "../../../def/DefinitionAtlas.h"
class Input;
class LuaGuiElement;
class LocalInventory;
class LocalInventoryRefs;
class World;
class Packet;
class Subgame;
class Inventory;
class Dimension;
class Deserializer;
enum class NetPlayerField;
class InventoryList;
class Player : Collidable, public Drawable {
class Player : public virtual Entity {
public:
enum class PlayerControl {
FORWARD, LEFT, BACKWARD, RIGHT,
JUMP, MOD1, MOD2 };
enum class NetField {
ID, POS, VEL, PITCH, YAW, LOOK_OFF, FLYING,
HAND_INV, WIELD_INV, WIELD_INDEX };
static constexpr float MOUSE_SENSITIVITY = 0.1f;
static constexpr float LOOK_DISTANCE = 6.5f;
static constexpr float LOOK_PRECISION = 0.01f;
static constexpr float EYE_HEIGHT = 1.65f;
static constexpr float BASE_MOVE_SPEED = 4.3f;
static constexpr float JUMP_VEL = 0.14f;
Player(Subgame& game, Dimension& dim, unsigned int id = 0) :
game(game), dim(dim), id(id), lookOffset(0, 1.65, 0) {
collision = {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}};
}
Player(LocalSubgame &game, LocalWorld &world, Renderer &renderer, LocalInventoryRefs &refs, ClientNetworkInterpreter& net);
void update(Input &input, double delta, glm::vec2 mouseDelta);
~Player();
virtual unsigned int getId();
virtual void setId(unsigned int id);
glm::vec3 getPos();
void setPos(glm::vec3 pos, bool assert = false);
virtual void setPos(glm::vec3 pos, bool assert = false);
virtual void setVel(glm::vec3 vel, bool assert = false);
glm::vec3 getVel();
void setVel(glm::vec3 vel, bool assert = false);
virtual float getYaw();
virtual void setYaw(float yaw, bool assert = false);
float getYaw();
void setYaw(float yaw, bool assert = false);
virtual float getPitch();
virtual void setPitch(float pitch, bool assert = false);
float getPitch();
void setPitch(float pitch, bool assert = false);
virtual glm::vec3 getLookOffset();
virtual void setLookOffset(glm::vec3 lookOffset, bool assert = false);
bool isFlying();
void setFlying(bool flying, bool assert = false);
virtual bool isFlying();
virtual void setFlying(bool flying, bool assert = false);
LocalInventory& getInventory();
virtual std::string& getHandList();
virtual void setHandList(const std::string& list, bool assert = false);
std::shared_ptr<LocalInventoryList> getHandList();
void setHandList(const std::string& list);
virtual std::string& getWieldList();
virtual void setWieldList(const std::string& list, bool assert = false);
std::shared_ptr<LocalInventoryList> getWieldList();
void setWieldList(const std::string& list, bool assert = false);
virtual unsigned short getWieldIndex();
virtual void setWieldIndex(unsigned short index, bool assert = false);
unsigned short getWieldIndex();
void setWieldIndex(unsigned short index, bool assert = false);
virtual Inventory& getInventory() = 0;
virtual Dimension& getDimension() = 0;
bool isInMenu();
void showMenu(std::shared_ptr<LuaGuiElement> root);
void closeMenu();
void setHud(std::shared_ptr<LuaGuiElement> hud);
std::shared_ptr<LuaGuiElement> getHud();
Target& getPointedThing();
void setHudVisible(bool hudVisible);
void draw(Renderer& renderer) override;
void drawHud(Renderer& renderer);
void drawMenu(Renderer& renderer);
void handleAssertion(Deserializer& d);
virtual void handleAssertion(Deserializer& d) = 0;
protected:
virtual void assertField(Packet packet) = 0;
unsigned int id = 0;
private:
bool getKey(Input& input, PlayerControl control);
void updatePhysics(Input &input, double delta, glm::vec2 mouseDelta);
void updateCamera();
void findPointedThing(Input &input);
void updateWireframe();
void interact(Input& input, double delta);
void updateWieldAndHandItems();
LocalSubgame& game;
ClientNetworkInterpreter& net;
Renderer& renderer;
GameGui gameGui;
Entity handModel;
Entity handItemModel;
WireframeEntity wireframe;
LocalInventoryRefs& refs;
unsigned int wieldIndex = 0;
unsigned int handItem = 1; // Air
unsigned int wieldItem = 1; // Air
Subgame& game;
Dimension& dim;
float yaw = 0;
float pitch = 0;
glm::vec3 lookOffset {};
bool flying = false;
double breakTime = 0;
double breakInterval = 0;
Target target;
};
std::string handList = "";
std::string wieldList = "";
unsigned int handItem = DefinitionAtlas::AIR;
unsigned int wieldItem = DefinitionAtlas::AIR;
unsigned int wieldIndex = 0;
};

View File

@ -4,28 +4,39 @@
#include "World.h"
#include "../../../def/Subgame.h"
#include "../../../def/item/BlockDef.h"
#include "../../../def/DefinitionAtlas.h"
#include "../../../world/Dimension.h"
World::World(Subgame &game) : game(game) {}
double World::getBlockDamage(glm::ivec3 pos) const {
return blockDamages.count(pos) ? blockDamages.at(pos).curr : 0;
void World::update(double delta) {
for (auto& dimension : dimensions) dimension->update(delta);
}
double World::setBlockDamage(glm::ivec3 pos, double damage) {
if (blockDamages.count(pos)) blockDamages[pos].curr = damage;
else blockDamages.insert({pos, Damage { damage, static_cast<double>(game.getDefs().blockFromId(getBlock(pos)).health)}});
return getBlockDamage(pos);
Dimension& World::getDefaultDimension() {
if (defaultDimension.empty()) throw std::runtime_error("No default dimension was set.");
return getDimension(defaultDimension);
}
void World::updateBlockDamages() {
for (auto it = blockDamages.begin(); it != blockDamages.end(); ) {
if (it->second.curr > it->second.max) {
setBlock(it->first, DefinitionAtlas::AIR);
it = blockDamages.erase(it);
}
else it++;
}
void World::setDefaultDimension(const std::string& defaultDimension) {
this->defaultDimension = defaultDimension;
}
//double World::getBlockDamage(glm::ivec3 pos) const {
// return blockDamages.count(pos) ? blockDamages.at(pos).curr : 0;
//}
//
//double World::setBlockDamage(glm::ivec3 pos, double damage) {
// if (blockDamages.count(pos)) blockDamages[pos].curr = damage;
// else blockDamages.insert({pos, Damage { damage, static_cast<double>(game.getDefs().blockFromId(getBlock(pos)).health)}});
// return getBlockDamage(pos);
//}
//
//void World::updateBlockDamages() {
// for (auto it = blockDamages.begin(); it != blockDamages.end(); ) {
// if (it->second.curr > it->second.max) {
// setBlock(it->first, DefinitionAtlas::AIR);
// it = blockDamages.erase(it);
// }
// else it++;
// }
//}

View File

@ -4,7 +4,6 @@
#pragma once
#include <map>
#include <memory>
#include <glm/vec3.hpp>
#include <unordered_map>
@ -16,22 +15,22 @@ class Dimension;
class World {
public:
World(const World& o) = delete;
explicit World(Subgame& game);
virtual void update(double delta) = 0;
virtual void update(double delta);
// virtual Dimension& getDimension() = 0;
virtual Dimension& createDimension(const std::string& identifier) = 0;
virtual unsigned int getBlock(glm::ivec3 pos) = 0;
virtual void setBlock(glm::ivec3 pos, unsigned int block) = 0;
virtual Dimension& getDefaultDimension();
virtual void setDefaultDimension(const std::string& defaultDimension);
virtual double getBlockDamage(glm::ivec3 pos) const;
virtual double setBlockDamage(glm::ivec3 pos, double damage);
virtual Dimension& getDimension(unsigned int index) = 0;
virtual Dimension& getDimension(const std::string& identifier) = 0;
protected:
void updateBlockDamages();
std::map<std::string, std::shared_ptr<Dimension>> dimensions;
std::string defaultDimension {};
std::vector<std::shared_ptr<Dimension>> dimensions;
struct Damage { double curr, max; };
std::unordered_map<glm::ivec3, Damage, Vec::ivec3> blockDamages;

View File

@ -74,7 +74,7 @@ std::unique_ptr<std::vector<std::shared_ptr<Chunk>>> WorldInterpolationStream::u
}
WorldInterpolationStream::Thread::Thread(LocalSubgame& game, unsigned int seed) :
gen(*game.defs, *game.biomes, seed),
gen(game.getDefs(), game.getBiomes(), seed),
thread(std::bind(&WorldInterpolationStream::Thread::exec, this)) {}
void WorldInterpolationStream::Thread::exec() {

View File

@ -13,33 +13,40 @@
#include "register/RegisterKeybinds.h"
// Usertypes
#include "usertype/Target.h"
#include "usertype/Player.h"
#include "usertype/Inventory.h"
#include "usertype/Dimension.h"
#include "usertype/InventoryList.h"
#include "usertype/LuaGuiElement.h"
#include "usertype/cItemStack.h"
#include "usertype/LocalLuaPlayer.h"
#include "usertype/cLuaEntity.h"
#include "usertype/cInventoryRef.h"
#include "usertype/cAnimationManager.h"
#include "usertype/Target.h"
// Modules
#include "modules/Time.h"
#include "modules/Block.h"
#include "modules/Entity.h"
#include "modules/Register.h"
#include "modules/Dimension.h"
#include "modules/create_structure.h"
LocalLuaParser::LocalLuaParser(LocalSubgame& game): LuaParser(game), game(game), keybinds(this) {}
void LocalLuaParser::init(LocalWorld& world, Player& player, ClientState& state) {
void LocalLuaParser::init(LocalWorld& world, ClientState& state) {
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table);
loadApi(game, world, player);
loadApi(game, world);
handler.executeMods(std::bind(&LocalLuaParser::runFileSandboxed, this, std::placeholders::_1));
state.renderer.window.input.setCallback(std::bind(&LuaKeybindHandler::keybindHandler, &keybinds, std::placeholders::_1, std::placeholders::_2));
registerDefs(game);
}
void LocalLuaParser::loadPlayer(std::shared_ptr<LocalPlayer> player) {
core["player"] = Api::Usertype::LocalPlayer(player);
}
void LocalLuaParser::update(double delta) {
this->delta += delta;
while (this->delta > static_cast<double>(UPDATE_STEP)) {
@ -53,7 +60,7 @@ LocalModHandler& LocalLuaParser::getHandler() {
return handler;
}
void LocalLuaParser::loadApi(LocalSubgame &defs, LocalWorld &world, Player& player) {
void LocalLuaParser::loadApi(LocalSubgame &defs, LocalWorld &world) {
//Create Zepha Table
core = lua.create_table();
lua["zepha"] = core;
@ -62,21 +69,21 @@ void LocalLuaParser::loadApi(LocalSubgame &defs, LocalWorld &world, Player& play
// Types
ClientApi::entity (lua);
ClientApi::animation_manager (lua);
ClientApi::local_player (lua);
ClientApi::inventory (lua);
ClientApi::item_stack (lua);
ClientApi::gui_element (lua);
Api::Usertype::Target::bind(Api::State::CLIENT, lua, core);
Api::Usertype::Dimension::bind(Api::State::CLIENT, lua, core);
Api::Usertype::Inventory::bind(Api::State::CLIENT, lua, core);
Api::Usertype::LocalPlayer::bind(Api::State::CLIENT, lua, core);
Api::Usertype::InventoryList::bind(Api::State::CLIENT, lua, core);
core["client"] = true;
core["player"] = LocalLuaPlayer(player);
// Modules
modules.emplace_back(std::make_unique<Api::Module::Time>(Api::State::CLIENT, lua, core));
modules.emplace_back(std::make_unique<Api::Module::Block>(Api::State::CLIENT, core, game, world));
modules.emplace_back(std::make_unique<Api::Module::Entity>(Api::State::CLIENT, core, game, world));
modules.emplace_back(std::make_unique<Api::Module::Register>(Api::State::CLIENT, core, game, world));
modules.emplace_back(std::make_unique<Api::Module::Dimension>(Api::State::CLIENT, core, game, world));
bindModules();
@ -94,8 +101,8 @@ void LocalLuaParser::registerDefs(LocalSubgame &defs) {
RegisterKeybinds::client(core, keybinds);
}
sol::protected_function_result LocalLuaParser::errorCallback(sol::protected_function_result errPfr) const {
sol::error err = errPfr;
sol::protected_function_result LocalLuaParser::errorCallback(sol::protected_function_result r) const {
sol::error err = r;
std::string errString = err.what();
try {

View File

@ -9,7 +9,7 @@
#include "LocalModHandler.h"
#include "LuaKeybindHandler.h"
class Player;
class LocalPlayer;
class LocalWorld;
class ClientState;
class LocalSubgame;
@ -17,22 +17,17 @@ class LocalSubgame;
class LocalLuaParser : public LuaParser {
public:
explicit LocalLuaParser(LocalSubgame& game);
void init(LocalWorld& world, Player& player, ClientState& state);
void init(LocalWorld& world, ClientState& state);
void loadPlayer(std::shared_ptr<LocalPlayer> player);
void update(double delta);
LocalModHandler& getHandler();
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(LocalSubgame& defs, LocalWorld& world, Player& player);
void loadApi(LocalSubgame &defs, LocalWorld &world);
void registerDefs(LocalSubgame &defs);
sol::protected_function_result errorCallback(sol::protected_function_result errPfr) const;
virtual sol::protected_function_result errorCallback(sol::protected_function_result r) const override;
sol::protected_function_result runFileSandboxed(const std::string& file);
LocalSubgame& game;

View File

@ -24,6 +24,14 @@ public:
void bindModules();
template<typename... Args> sol::protected_function_result safe_function(sol::protected_function f, Args... args) const {
auto res = f(args...);
if (!res.valid()) errorCallback(res);
return res;
}
virtual sol::protected_function_result errorCallback(sol::protected_function_result r) const = 0;
Subgame& game;
sol::state lua;

View File

@ -12,23 +12,25 @@
#include "register/RegisterItems.h"
#include "register/RegisterBiomes.h"
#include "register/RegisterBlocks.h"
#include "../net/server/conn/ServerPlayer.h"
#include "../net/server/world/ServerWorld.h"
// Usertypes
#include "usertype/ServerLuaPlayer.h"
#include "usertype/sLuaEntity.h"
#include "usertype/sInventoryRef.h"
#include "usertype/cItemStack.h"
#include "usertype/Target.h"
#include "usertype/Player.h"
#include "usertype/Inventory.h"
#include "usertype/Dimension.h"
#include "usertype/InventoryList.h"
#include "usertype/sLuaEntity.h"
#include "usertype/cItemStack.h"
// Modules
#include "modules/Time.h"
#include "modules/Block.h"
#include "modules/Entity.h"
#include "modules/Register.h"
#include "modules/Dimension.h"
#include "modules/create_structure.h"
#include "LuaMod.h"
ServerLuaParser::ServerLuaParser(ServerSubgame& game) : LuaParser(game), game(game) {}
@ -64,9 +66,9 @@ void ServerLuaParser::sendModsPacket(ENetPeer* peer) const {
Serializer().append(order).packet(PacketType::MOD_ORDER).sendTo(peer, PacketChannel::CONNECT);
}
void ServerLuaParser::playerConnected(std::shared_ptr<ServerClient> client) {
void ServerLuaParser::playerConnected(std::shared_ptr<ServerPlayer> client) {
auto players = core.get<sol::table>("players");
players.add(ServerLuaPlayer(*client));
players.add(Api::Usertype::ServerPlayer(std::static_pointer_cast<Player>(client)));
sol::object player = players[players.size()];
@ -74,13 +76,12 @@ void ServerLuaParser::playerConnected(std::shared_ptr<ServerClient> client) {
safe_function(core["trigger"], "player_join", player);
}
void ServerLuaParser::playerDisconnected(std::shared_ptr<ServerClient> client) {
void ServerLuaParser::playerDisconnected(std::shared_ptr<ServerPlayer> player) {
for (auto& pair : core.get<sol::table>("players")) {
ServerLuaPlayer& p = pair.second.as<ServerLuaPlayer>();
if (p.get_cid() == client->cid) {
auto& p = pair.second.as<Api::Usertype::ServerPlayer>();
if (p.get_id() == player->getId()) {
safe_function(core["trigger"], "player_disconnect", p);
p.is_player = false;
core.get<sol::table>("players")[pair.first] = sol::nil;
break;
}
@ -95,20 +96,21 @@ void ServerLuaParser::loadApi(ServerSubgame &defs, ServerWorld &world) {
// Types
ServerApi::entity (lua);
ServerApi::server_player (lua);
ServerApi::inventory (lua);
ClientApi::item_stack (lua);
Api::Usertype::Target::bind(Api::State::SERVER, lua, core);
Api::Usertype::Dimension::bind(Api::State::SERVER, lua, core);
Api::Usertype::Inventory::bind(Api::State::SERVER, lua, core);
Api::Usertype::ServerPlayer::bind(Api::State::SERVER, lua, core);
Api::Usertype::InventoryList::bind(Api::State::SERVER, lua, core);
core["server"] = true;
core["players"] = lua.create_table();
// Modules
modules.emplace_back(std::make_unique<Api::Module::Time>(Api::State::SERVER, lua, core));
modules.emplace_back(std::make_unique<Api::Module::Block>(Api::State::SERVER, core, game, world));
modules.emplace_back(std::make_unique<Api::Module::Entity>(Api::State::SERVER, core, game, world));
modules.emplace_back(std::make_unique<Api::Module::Register>(Api::State::SERVER, core, game, world));
modules.emplace_back(std::make_unique<Api::Module::Dimension>(Api::State::SERVER, core, game, world));
Api::create_structure (lua, core);
@ -125,8 +127,8 @@ void ServerLuaParser::registerDefs(ServerSubgame &defs) {
RegisterBiomes::server(core, defs);
}
sol::protected_function_result ServerLuaParser::errorCallback(sol::protected_function_result errPfr) const {
sol::error err = errPfr;
sol::protected_function_result ServerLuaParser::errorCallback(sol::protected_function_result r) const {
sol::error err = r;
std::string errString = err.what();
try {

View File

@ -12,30 +12,25 @@
class ServerSubgame;
class ServerWorld;
class ServerClient;
class ServerPlayer;
class ServerLuaParser : public LuaParser {
public:
explicit ServerLuaParser(ServerSubgame& game);
void init(ServerWorld& world, const std::string& rootPath);
void update(double delta) override;
virtual void update(double delta) override;
void sendModsPacket(ENetPeer* peer) const;
void playerConnected(std::shared_ptr<ServerClient> client);
void playerDisconnected(std::shared_ptr<ServerClient> client);
void playerConnected(std::shared_ptr<ServerPlayer> client);
void playerDisconnected(std::shared_ptr<ServerPlayer> client);
template<typename... Args> sol::safe_function_result safe_function(sol::protected_function f, Args... args) const {
auto res = f(args...);
if (!res.valid()) errorCallback(res);
return res;
}
private:
void loadApi(ServerSubgame& defs, ServerWorld& world);
void registerDefs(ServerSubgame &defs);
sol::protected_function_result errorCallback(sol::protected_function_result errPfr) const;
virtual sol::protected_function_result errorCallback(sol::protected_function_result r) const override;
sol::protected_function_result runFileSandboxed(const std::string& file);
ServerSubgame& game;

View File

@ -1,41 +0,0 @@
//
// Created by aurailus on 2020-07-25.
//
#include "Block.h"
#include "../Lua.h"
#include "../../def/ItemDef.h"
#include "../../def/Subgame.h"
#include "../../def/DefinitionAtlas.h"
#include "../../game/scene/world/World.h"
void Api::Module::Block::bind() {
core.set_function("get_block", Util::bind_this(this, &Block::getBlock));
core.set_function("set_block", Util::bind_this(this, &Block::setBlock));
core.set_function("remove_block", [&](glm::ivec3 pos) { setBlock(pos, "air"); });
core.set_function("block_damage_get", Util::bind_this(this, &Block::damageGet));
core.set_function("block_damage_set", Util::bind_this(this, &Block::damageSet));
core.set_function("block_damage_add", Util::bind_this(this, &Block::damageAdd));
}
std::string Api::Module::Block::getBlock(glm::ivec3 pos) {
return game.getDefs().fromId(world.getBlock(pos)).identifier;
}
void Api::Module::Block::setBlock(glm::ivec3 pos, const std::string &identifier) {
world.setBlock(pos, game.getDefs().fromStr(identifier).index);
}
double Api::Module::Block::damageGet(glm::ivec3 pos) {
return world.getBlockDamage(pos);
}
double Api::Module::Block::damageSet(glm::ivec3 pos, double damage) {
return world.setBlockDamage(pos, damage);
}
double Api::Module::Block::damageAdd(glm::ivec3 pos, double damage) {
return world.setBlockDamage(pos, world.getBlockDamage(pos) + damage);
}

View File

@ -1,25 +0,0 @@
//
// Created by aurailus on 2020-07-25.
//
#pragma once
#include <glm/vec3.hpp>
#include "SubgameModule.h"
namespace Api::Module {
class Block : public Api::Module::SubgameModule {
public:
using SubgameModule::SubgameModule;
void bind() override;
protected:
std::string getBlock(glm::ivec3 pos);
void setBlock(glm::ivec3 pos, const std::string& identifier);
double damageGet(glm::ivec3 pos);
double damageSet(glm::ivec3 pos, double damage);
double damageAdd(glm::ivec3 pos, double damage);
};
}

View File

@ -0,0 +1,39 @@
//
// Created by aurailus on 2020-07-30.
//
#include "Dimension.h"
#include "../Lua.h"
#include "../usertype/Dimension.h"
#include "../../game/scene/world/LocalWorld.h"
#include "../../net/server/world/ServerWorld.h"
void Api::Module::Dimension::bind() {
core.set_function("create_dimension", Util::bind_this(this, &Dimension::createDimension));
core.set_function("get_dimension", Util::bind_this(this, &Dimension::getDimension));
core.set_function("get_default_dimension", Util::bind_this(this, &Dimension::getDefaultDimension));
core.set_function("set_default_dimension", Util::bind_this(this, &Dimension::setDefaultDimension));
}
void Api::Module::Dimension::createDimension(const std::string& identifier) {
world.createDimension(identifier);
}
void Api::Module::Dimension::setDefaultDimension(const std::string& identifier) {
world.setDefaultDimension(identifier);
}
sol::object Api::Module::Dimension::getDefaultDimension(const sol::this_state s) {
std::shared_ptr<::Dimension> dim = state == State::CLIENT ?
std::static_pointer_cast<::Dimension>(static_cast<LocalWorld&>(world).getDefaultDimensionPtr()) :
std::static_pointer_cast<::Dimension>(static_cast<ServerWorld&>(world).getDefaultDimensionPtr());
return sol::make_object(s, Api::Usertype::Dimension(dim));
}
sol::object Api::Module::Dimension::getDimension(sol::this_state s, const std::string& identifier) {
std::shared_ptr<::Dimension> dim = state == State::CLIENT ?
std::static_pointer_cast<::Dimension>(static_cast<LocalWorld&>(world).getDimensionPtr(identifier)) :
std::static_pointer_cast<::Dimension>(static_cast<ServerWorld&>(world).getDimensionPtr(identifier));
return sol::make_object(s, Api::Usertype::Dimension(dim));
}

View File

@ -0,0 +1,22 @@
//
// Created by aurailus on 2020-07-30.
//
#pragma once
#include "SubgameModule.h"
namespace Api::Module {
class Dimension : public Api::Module::SubgameModule {
public:
using SubgameModule::SubgameModule;
void bind() override;
protected:
void createDimension(const std::string& identifier);
sol::object getDimension(sol::this_state s, const std::string& identifier);
sol::object getDefaultDimension(const sol::this_state s);
void setDefaultDimension(const std::string& identifier);
};
}

View File

@ -1,101 +0,0 @@
//
// Created by aurailus on 2020-07-25.
//
#include "Entity.h"
#include "../Lua.h"
#include "../usertype/LocalLuaEntity.h"
#include "../usertype/ServerLuaEntity.h"
#include "../../def/LocalSubgame.h"
#include "../../def/ServerSubgame.h"
#include "../../game/scene/world/LocalWorld.h"
#include "../../net/server/world/ServerWorld.h"
void Api::Module::Entity::bind() {
core["entities"] = lua.create_table();
core.set_function("add_entity", Util::bind_this(this, &Entity::addEntity));
if (state == State::CLIENT) core.set_function("remove_entity", Util::bind_this(this, &Entity::clientRemoveEntity));
else core.set_function("remove_entity", Util::bind_this(this, &Entity::serverRemoveEntity));
}
sol::object Api::Module::Entity::addEntity(glm::vec3 pos, const std::string &identifier, sol::optional<sol::object> staticData) {
if (core["registered_entities"][identifier] == sol::nil) throw std::runtime_error(identifier + " is not a valid entity identifier.");
sol::table def = core["registered_entities"][identifier];
sol::table luaEntity = lua.create_table();
luaEntity[sol::metatable_key] = def;
luaEntity["name"] = identifier;
auto displayType = luaEntity.get<sol::optional<std::string>>("display");
if (!displayType) throw std::runtime_error("entity '" + identifier + "' is missing the display property.");
auto displayObject = luaEntity.get<sol::optional<std::string>>("display_object");
if (!displayObject) throw std::runtime_error("entity '" + identifier + "' is missing the display_object property.");
auto displayTexture = luaEntity.get<sol::optional<std::string>>("display_texture");
if (strncmp(displayType->data(), "model", 5) == 0 && !displayTexture) throw std::runtime_error("entity '" + identifier + "' is missing the display_texture property.");
// Server
if (state == State::SERVER) {
auto entity = std::make_unique<ServerEntity>(ind);
entity->setPos(pos);
auto ref = std::make_shared<ServerLuaEntity>(std::move(entity), ind++, static_cast<ServerSubgame&>(game));
luaEntity["object"] = ref;
ref->set_display_type(*displayType, *displayObject, displayTexture);
core.get<sol::table>("entities")[ref->id] = luaEntity;
auto on_create = def.get<sol::optional<sol::protected_function>>("on_create");
if (on_create) (*on_create)(luaEntity, staticData);
static_cast<ServerWorld&>(world).dimension.addLuaEntity(ref);
}
// Client
else {
auto entity = std::make_unique<::Entity>();
entity->setPos(pos);
auto ref = std::make_shared<LocalLuaEntity>(std::move(entity), ind++, static_cast<LocalSubgame&>(game));
luaEntity["object"] = ref;
ref->set_display_type(*displayType, *displayObject, displayTexture);
core.get<sol::table>("entities")[ref->id] = luaEntity;
auto on_create = def.get<sol::optional<sol::protected_function>>("on_create");
if (on_create) (*on_create)(luaEntity, staticData);
static_cast<LocalWorld&>(world).dimension.addLocalEntity(ref);
}
return luaEntity;
}
void Api::Module::Entity::clientRemoveEntity(sol::table entity) {
auto object = entity.get<sol::optional<std::shared_ptr<LocalLuaEntity>>>("object");
if (!object) throw std::runtime_error("Attempting to rmeove an invalid entity.");
sol::optional<sol::table> entityTable = core["entities"][(*object)->id];
if (!entityTable) return;
sol::optional<sol::protected_function> onDestroy = (*entityTable)["on_destroy"];
if (onDestroy) (*onDestroy)();
core["entities"][(*object)->id] = sol::nil;
static_cast<LocalWorld&>(world).dimension.removeLocalEntity(*object);
}
void Api::Module::Entity::serverRemoveEntity(sol::table entity) {
auto object = entity.get<sol::optional<std::shared_ptr<ServerLuaEntity>>>("object");
if (!object) throw std::runtime_error("Attempting to rmeove an invalid entity.");
sol::optional<sol::table> entityTable = core["entities"][(*object)->id];
if (!entityTable) return;
sol::optional<sol::protected_function> onDestroy = (*entityTable)["on_destroy"];
if (onDestroy) (*onDestroy)();
core["entities"][(*object)->id] = sol::nil;
static_cast<ServerWorld&>(world).dimension.removeLuaEntity(*object);
}

View File

@ -1,24 +0,0 @@
//
// Created by aurailus on 2020-07-25.
//
#pragma once
#include <glm/vec3.hpp>
#include "SubgameModule.h"
namespace Api::Module {
class Entity : public Api::Module::SubgameModule {
public:
using SubgameModule::SubgameModule;
void bind() override;
protected:
sol::object addEntity(glm::vec3 pos, const std::string& identifier, sol::optional<sol::object> staticData);
void clientRemoveEntity(sol::table entity);
void serverRemoveEntity(sol::table entity);
unsigned int ind = 0;
};
}

View File

@ -330,12 +330,12 @@ namespace RegisterBiomes {
}
static void server(sol::table& core, ServerSubgame& game) {
registerBiomes(core.get<sol::table>("registered_biomes"), *game.defs, *game.biomes);
game.biomes->generateVoronoi();
registerBiomes(core.get<sol::table>("registered_biomes"), game.getDefs(), game.getBiomes());
game.getBiomes().generateVoronoi();
}
static void client(sol::table& core, LocalSubgame& game) {
registerBiomes(core.get<sol::table>("registered_biomes"), *game.defs, *game.biomes);
game.biomes->generateVoronoi();
registerBiomes(core.get<sol::table>("registered_biomes"), game.getDefs(), game.getBiomes());
game.getBiomes().generateVoronoi();
}
};

View File

@ -361,11 +361,11 @@ namespace RegisterBlocks {
static void server(sol::table& core, ServerSubgame& game) {
registerBlocks(core.get<sol::table>("registered_blocks"),
core.get<sol::table>("registered_blockmodels"), *game.defs, nullptr);
core.get<sol::table>("registered_blockmodels"), game.getDefs(), nullptr);
}
static void client(sol::table& core, LocalSubgame& game) {
registerBlocks(core.get<sol::table>("registered_blocks"),
core.get<sol::table>("registered_blockmodels"), *game.defs, &game.textures);
core.get<sol::table>("registered_blockmodels"), game.getDefs(), &game.textures);
}
};

View File

@ -61,10 +61,10 @@ namespace RegisterItems {
}
static void server(sol::table& core, ServerSubgame& game) {
registerItems(core.get<sol::table>("registered_items"), *game.defs, nullptr);
registerItems(core.get<sol::table>("registered_items"), game.getDefs(), nullptr);
}
static void client(sol::table& core, LocalSubgame& game) {
registerItems(core.get<sol::table>("registered_items"), *game.defs, &game.textures);
registerItems(core.get<sol::table>("registered_items"), game.getDefs(), &game.textures);
}
};

View File

@ -0,0 +1,173 @@
//
// Created by aurailus on 2020-07-28.
//
#include "Dimension.h"
#include "../Lua.h"
#include "../LuaParser.h"
#include "LocalLuaEntity.h"
#include "../../def/gen/BiomeDef.h"
#include "../../def/item/BlockDef.h"
#include "../../world/LocalDimension.h"
#include "../../net/server/world/ServerEntity.h"
#include "../../def/ServerSubgame.h"
#include "ServerLuaEntity.h"
#include "../../world/ServerDimension.h"
std::string Api::Usertype::Dimension::get_block(glm::ivec3 pos) {
return dimension->getGame().getDefs().fromId(dimension->getBlock(pos)).identifier;
}
void Api::Usertype::Dimension::set_block(glm::ivec3 pos, const std::string &block) {
dimension->setBlock(pos, dimension->getGame().getDefs().fromStr(block).index);
}
void Api::Usertype::Dimension::remove_block(glm::ivec3 pos) {
dimension->setBlock(pos, DefinitionAtlas::AIR);
}
double Api::Usertype::Dimension::get_block_damage(glm::ivec3 pos) {
return dimension->getBlockDamage(pos);
}
double Api::Usertype::Dimension::set_block_damage(glm::ivec3 pos, double damage) {
return dimension->setBlockDamage(pos, damage);
}
double Api::Usertype::Dimension::add_block_damage(glm::ivec3 pos, double damage) {
return dimension->setBlockDamage(pos, dimension->getBlockDamage(pos) + damage);
}
std::string Api::Usertype::Dimension::get_biome(glm::ivec3 pos) {
return dimension->getGame().getBiomes().biomeFromId(dimension->getBiome(pos)).identifier;
}
void Api::Usertype::Dimension::set_biome(glm::ivec3 pos, const std::string &biome) {
dimension->setBiome(pos, dimension->getGame().getBiomes().biomeFromStr(biome).index);
}
sol::table Api::Usertype::Dimension::add_entity_c(sol::this_state s, glm::vec3 pos,
const std::string &identifier, sol::optional<sol::object> staticData) {
sol::state_view lua = sol::state_view(s);
sol::table core = lua.get<sol::table>("zepha");
if (core["registered_entities"][identifier] == sol::nil) throw std::runtime_error(identifier + " is not a valid entity identifier.");
sol::table def = core["registered_entities"][identifier];
sol::table luaEntity = lua.create_table();
luaEntity[sol::metatable_key] = def;
luaEntity["name"] = identifier;
auto displayType = luaEntity.get<sol::optional<std::string>>("display");
if (!displayType) throw std::runtime_error("entity '" + identifier + "' is missing the display property.");
auto displayObject = luaEntity.get<sol::optional<std::string>>("display_object");
if (!displayObject) throw std::runtime_error("entity '" + identifier + "' is missing the display_object property.");
auto displayTexture = luaEntity.get<sol::optional<std::string>>("display_texture");
if (strncmp(displayType->data(), "model", 5) == 0 && !displayTexture) throw std::runtime_error("entity '" + identifier + "' is missing the display_texture property.");
auto entity = std::make_unique<::DrawableEntity>();
entity->setPos(pos);
auto ref = std::make_shared<LocalLuaEntity>(std::move(entity), dimension->nextEntityInd(), static_cast<LocalSubgame&>(dimension->getGame()));
luaEntity["object"] = ref;
ref->set_display_type(*displayType, *displayObject, displayTexture);
core.get<sol::table>("entities")[ref->id] = luaEntity;
auto on_create = def.get<sol::optional<sol::protected_function>>("on_create");
if (on_create) (*on_create)(luaEntity, staticData);
std::static_pointer_cast<LocalDimension>(dimension)->addLocalEntity(ref);
return luaEntity;
}
sol::table Api::Usertype::Dimension::add_entity_s(sol::this_state s, glm::vec3 pos,
const std::string &identifier, sol::optional<sol::object> staticData) {
sol::state_view lua = sol::state_view(s);
sol::table core = lua.get<sol::table>("zepha");
if (core["registered_entities"][identifier] == sol::nil) throw std::runtime_error(identifier + " is not a valid entity identifier.");
sol::table def = core["registered_entities"][identifier];
sol::table luaEntity = lua.create_table();
luaEntity[sol::metatable_key] = def;
luaEntity["name"] = identifier;
auto displayType = luaEntity.get<sol::optional<std::string>>("display");
if (!displayType) throw std::runtime_error("entity '" + identifier + "' is missing the display property.");
auto displayObject = luaEntity.get<sol::optional<std::string>>("display_object");
if (!displayObject) throw std::runtime_error("entity '" + identifier + "' is missing the display_object property.");
auto displayTexture = luaEntity.get<sol::optional<std::string>>("display_texture");
if (strncmp(displayType->data(), "model", 5) == 0 && !displayTexture) throw std::runtime_error("entity '" + identifier + "' is missing the display_texture property.");
unsigned int ind = dimension->nextEntityInd();
auto entity = std::make_unique<ServerEntity>(ind);
entity->setPos(pos);
auto ref = std::make_shared<ServerLuaEntity>(std::move(entity), ind, static_cast<ServerSubgame&>(dimension->getGame()));
luaEntity["object"] = ref;
ref->set_display_type(*displayType, *displayObject, displayTexture);
core.get<sol::table>("entities")[ref->id] = luaEntity;
auto on_create = def.get<sol::optional<sol::protected_function>>("on_create");
if (on_create) (*on_create)(luaEntity, staticData);
std::static_pointer_cast<ServerDimension>(dimension)->addLuaEntity(ref);
return luaEntity;
}
void Api::Usertype::Dimension::remove_entity_c(sol::this_state s, sol::table entity) {
sol::state_view lua = sol::state_view(s);
sol::table core = lua.get<sol::table>("zepha");
auto object = entity.get<sol::optional<std::shared_ptr<LocalLuaEntity>>>("object");
if (!object) throw std::runtime_error("Attempting to remove an invalid entity.");
sol::optional<sol::table> entityTable = core["entities"][(*object)->id];
if (!entityTable) return;
sol::optional<sol::protected_function> onDestroy = (*entityTable)["on_destroy"];
if (onDestroy) (*onDestroy)();
core["entities"][(*object)->id] = sol::nil;
std::static_pointer_cast<LocalDimension>(dimension)->removeLocalEntity(*object);
}
void Api::Usertype::Dimension::remove_entity_s(sol::this_state s, sol::table entity) {
sol::state_view lua = sol::state_view(s);
sol::table core = lua.get<sol::table>("zepha");
auto object = entity.get<sol::optional<std::shared_ptr<ServerLuaEntity>>>("object");
if (!object) throw std::runtime_error("Attempting to rmeove an invalid entity.");
sol::optional<sol::table> entityTable = core["entities"][(*object)->id];
if (!entityTable) return;
sol::optional<sol::protected_function> onDestroy = (*entityTable)["on_destroy"];
if (onDestroy) (*onDestroy)();
core["entities"][(*object)->id] = sol::nil;
std::static_pointer_cast<ServerDimension>(dimension)->removeLuaEntity(*object);
}
void Api::Usertype::Dimension::bind(State state, sol::state &lua, sol::table &core) {
lua.new_usertype<Dimension>("LocalDimension",
"get_block", &Dimension::get_block,
"set_block", &Dimension::set_block,
"remove_block", &Dimension::remove_block,
"get_block_damage", &Dimension::get_block_damage,
"set_block_damage", &Dimension::set_block_damage,
"add_block_damage", &Dimension::add_block_damage,
"get_biome", &Dimension::get_block,
"set_biome", &Dimension::set_block,
"add_entity", (state == State::CLIENT ? &Dimension::add_entity_c : &Dimension::add_entity_s),
"remove_entity", (state == State::CLIENT ? &Dimension::remove_entity_c : &Dimension::remove_entity_s)
);
}

View File

@ -0,0 +1,42 @@
//
// Created by aurailus on 2020-07-28.
//
#pragma once
#include <memory>
#include <glm/vec3.hpp>
#include "SubgameUsertype.h"
class Dimension;
namespace Api::Usertype {
class Dimension : public SubgameUsertype {
public:
Dimension(std::shared_ptr<::Dimension> dimension) : dimension(dimension) {}
std::shared_ptr<::Dimension> dimension;
std::string get_block(glm::ivec3 pos);
void set_block(glm::ivec3 pos, const std::string& block);
void remove_block(glm::ivec3 pos);
double get_block_damage(glm::ivec3 pos);
double set_block_damage(glm::ivec3 pos, double damage);
double add_block_damage(glm::ivec3 pos, double damage);
std::string get_biome(glm::ivec3 pos);
void set_biome(glm::ivec3 pos, const std::string& biome);
sol::table add_entity_c(sol::this_state s, glm::vec3 pos,
const std::string &identifier, sol::optional<sol::object> staticData);
sol::table add_entity_s(sol::this_state s, glm::vec3 pos,
const std::string &identifier, sol::optional<sol::object> staticData);
void remove_entity_c(sol::this_state s, sol::table entity);
void remove_entity_s(sol::this_state s, sol::table entity);
static void bind(State state, sol::state& lua, sol::table& core);
};
}

View File

@ -0,0 +1,49 @@
//
// Created by aurailus on 2019-12-17.
//
#include "Inventory.h"
#include "../Lua.h"
#include "InventoryList.h"
#include "../../game/inventory/Inventory.h"
sol::object Api::Usertype::Inventory::add_list(sol::this_state s, std::string name, int size, int width) {
inventory.createList(name, size, width);
return sol::make_object<InventoryList>(s, InventoryList(inventory.getListPtr(name)));
}
sol::object Api::Usertype::Inventory::get_list(sol::this_state s, std::string name) {
if (!inventory.hasList(name)) return sol::nil;
return sol::make_object<InventoryList>(s, InventoryList(inventory.getListPtr(name)));
}
void Api::Usertype::Inventory::remove_list(std::string name) {
inventory.removeList(name);
}
void Api::Usertype::Inventory::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 Api::Usertype::Inventory::get_default_list(sol::this_state s) {
return sol::nil;
// if (inventory.getDefaultList() == "") return sol::nil;
// else return get_list(s, inventory.getDefaultList());
}
void Api::Usertype::Inventory::bind(State state, sol::state &lua, sol::table &core) {
if (state == State::SERVER) lua.new_usertype<Inventory>("Inventory",
"get_list", &Inventory::get_list,
"add_list", &Inventory::add_list,
"remove_list", &Inventory::remove_list,
"set_default_list", &Inventory::set_default_list,
"get_default_list", &Inventory::get_default_list
);
else lua.new_usertype<Inventory>("Inventory",
"get_list", &Inventory::get_list
);
}

View File

@ -0,0 +1,29 @@
//
// Created by aurailus on 2019-12-17.
//
#pragma once
#include <memory>
#include "SubgameUsertype.h"
class Inventory;
namespace Api::Usertype {
class Inventory : public SubgameUsertype {
public:
Inventory(::Inventory& inventory) : inventory(inventory) {}
::Inventory& inventory;
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);
static void bind(State state, sol::state& lua, sol::table& core);
};
}

View File

@ -0,0 +1,154 @@
//
// Created by aurailus on 2019-12-17.
//
#include "InventoryList.h"
#include "../../def/ItemDef.h"
#include "../../def/DefinitionAtlas.h"
#include "../../game/inventory/InventoryList.h"
void Api::Usertype::InventoryList::set_length(int length) {
list->setLength(length);
}
int Api::Usertype::InventoryList::get_length() {
return list->getLength();
}
void Api::Usertype::InventoryList::set_width(int width) {
list->setWidth(width);
}
int Api::Usertype::InventoryList::get_width() {
return list->getWidth();
}
void Api::Usertype::InventoryList::resize(int length, int width) {
list->setLength(length);
list->setWidth(width);
}
std::string Api::Usertype::InventoryList::get_name() {
return list->getName();
}
LuaItemStack Api::Usertype::InventoryList::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->getGame());
}
void Api::Usertype::InventoryList::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->getGame()));
}
void Api::Usertype::InventoryList::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->getGame().getDefs().fromStr(stack[1]).index, stack[2]));
}
LuaItemStack Api::Usertype::InventoryList::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->getGame())), list->getGame());
}
LuaItemStack Api::Usertype::InventoryList::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->getGame().getDefs().fromStr(stack[1]).index, stack[2])), list->getGame());
}
LuaItemStack Api::Usertype::InventoryList::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->getGame());
}
LuaItemStack Api::Usertype::InventoryList::add_stack(LuaItemStack stack) {
return LuaItemStack(list->addStack(ItemStack(stack, list->getGame())), list->getGame());
}
LuaItemStack Api::Usertype::InventoryList::add_stack(sol::table stack) {
return LuaItemStack(list->addStack(ItemStack(list->getGame().getDefs().fromStr(stack[1]).index, stack[2])), list->getGame());
}
int Api::Usertype::InventoryList::stack_fits(LuaItemStack stack) {
return list->stackFits(ItemStack(stack, list->getGame()));
}
int Api::Usertype::InventoryList::stack_fits(sol::table stack) {
return list->stackFits(ItemStack(list->getGame().getDefs().fromStr(stack[1]).index, stack[2]));
}
LuaItemStack Api::Usertype::InventoryList::take_stack(LuaItemStack request) {
return LuaItemStack(list->takeStack(ItemStack(request, list->getGame())), list->getGame());
}
LuaItemStack Api::Usertype::InventoryList::take_stack(sol::table request) {
return LuaItemStack(list->takeStack(ItemStack(list->getGame().getDefs().fromStr(request[1]).index, request[2])), list->getGame());
}
LuaItemStack Api::Usertype::InventoryList::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->getGame());
}
//void LuaInventoryList::set_callback(ServerInventoryList::Callback t, sol::safe_function fun) {
// list->setLuaCallback(t, fun);
//}
//
//sol::safe_function LuaInventoryList::get_callback(ServerInventoryList::Callback t) {
// return list->getLuaCallback(t);
//}
void Api::Usertype::InventoryList::bind(State state, sol::state &lua, sol::table &core) {
if (state == State::SERVER) lua.new_usertype<InventoryList>("InventoryListRef",
"length", sol::property(&InventoryList::get_length, &InventoryList::set_length),
"width", sol::property(&InventoryList::get_width, &InventoryList::set_width),
"name", sol::property(&InventoryList::get_name),
"resize", &InventoryList::resize,
"get_stack", &InventoryList::get_stack,
"set_stack", sol::overload(
sol::resolve<void(unsigned short, LuaItemStack)>(&InventoryList::set_stack),
sol::resolve<void(unsigned short, sol::table)>(&InventoryList::set_stack)),
"place_stack", sol::overload(
sol::resolve<LuaItemStack(unsigned short, LuaItemStack)>(&InventoryList::place_stack),
sol::resolve<LuaItemStack(unsigned short, sol::table)>(&InventoryList::place_stack)),
"split_stack", &InventoryList::split_stack,
"add_stack", sol::overload(
sol::resolve<LuaItemStack(LuaItemStack)>(&InventoryList::add_stack),
sol::resolve<LuaItemStack(sol::table)>(&InventoryList::add_stack)),
"stack_fits", sol::overload(
sol::resolve<int(LuaItemStack)>(&InventoryList::stack_fits),
sol::resolve<int(sol::table)>(&InventoryList::stack_fits)),
"take_stack", sol::overload(
sol::resolve<LuaItemStack(LuaItemStack)>(&InventoryList::take_stack),
sol::resolve<LuaItemStack(sol::table)>(&InventoryList::take_stack)),
"remove_stack", &InventoryList::remove_stack
);
else lua.new_usertype<InventoryList>("InventoryListRef",
"length", sol::property(&InventoryList::get_length),
"width", sol::property(&InventoryList::get_width),
"name", sol::property(&InventoryList::get_name),
"get_stack", &InventoryList::get_stack,
"set_stack", sol::overload(
sol::resolve<void(unsigned short, LuaItemStack)>(&InventoryList::set_stack),
sol::resolve<void(unsigned short, sol::table)>(&InventoryList::set_stack)),
"place_stack", sol::overload(
sol::resolve<LuaItemStack(unsigned short, LuaItemStack)>(&InventoryList::place_stack),
sol::resolve<LuaItemStack(unsigned short, sol::table)>(&InventoryList::place_stack)),
"split_stack", &InventoryList::split_stack,
"add_stack", sol::overload(
sol::resolve<LuaItemStack(LuaItemStack)>(&InventoryList::add_stack),
sol::resolve<LuaItemStack(sol::table)>(&InventoryList::add_stack)),
"stack_fits", sol::overload(
sol::resolve<int(LuaItemStack)>(&InventoryList::stack_fits),
sol::resolve<int(sol::table)>(&InventoryList::stack_fits)),
"take_stack", sol::overload(
sol::resolve<LuaItemStack(LuaItemStack)>(&InventoryList::take_stack),
sol::resolve<LuaItemStack(sol::table)>(&InventoryList::take_stack)),
"remove_stack", &InventoryList::remove_stack
);
}

View File

@ -0,0 +1,58 @@
//
// Created by aurailus on 2019-12-17.
//
#pragma once
#include <memory>
#include "SubgameUsertype.h"
#include "LuaItemStack.h"
class InventoryList;
namespace Api::Usertype {
class InventoryList : public SubgameUsertype {
public:
InventoryList(std::shared_ptr<::InventoryList> list) : list(list) {}
std::shared_ptr<::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);
void set_stack(unsigned short i, LuaItemStack stack);
void set_stack(unsigned short i, sol::table stack);
LuaItemStack place_stack(unsigned short i, LuaItemStack stack);
LuaItemStack place_stack(unsigned short i, sol::table stack);
LuaItemStack split_stack(unsigned short i);
LuaItemStack add_stack(LuaItemStack stack);
LuaItemStack add_stack(sol::table stack);
int stack_fits(LuaItemStack stack);
int stack_fits(sol::table stack);
LuaItemStack take_stack(LuaItemStack request);
LuaItemStack take_stack(sol::table request);
LuaItemStack remove_stack(unsigned short ind, unsigned short count);
// void set_callback(ServerInventoryList::Callback t, sol::safe_function fun);
// sol::safe_function get_callback(ServerInventoryList::Callback t);
static void bind(State state, sol::state& lua, sol::table& core);
};
}

View File

@ -5,10 +5,10 @@
#include "LocalLuaAnimationManager.h"
#include "../Lua.h"
#include "../../game/entity/Entity.h"
#include "../../game/entity/DrawableEntity.h"
#include "../../game/entity/AnimationSegment.h"
LocalLuaAnimationManager::LocalLuaAnimationManager(Entity &entity) :
LocalLuaAnimationManager::LocalLuaAnimationManager(DrawableEntity &entity) :
entity(entity) {}
void LocalLuaAnimationManager::define(sol::table anims) {

View File

@ -6,16 +6,16 @@
#include "../Lua.h"
class Entity;
class DrawableEntity;
class LocalLuaAnimationManager {
public:
LocalLuaAnimationManager(Entity& entity);
LocalLuaAnimationManager(DrawableEntity& entity);
void define(sol::table anims);
LocalLuaAnimationManager& set_anim(sol::object anim, sol::optional<bool> loop);
LocalLuaAnimationManager& play(sol::optional<unsigned int> offset);
LocalLuaAnimationManager& pause(sol::optional<unsigned int> offset);
private:
Entity& entity;
DrawableEntity& entity;
};

View File

@ -85,7 +85,7 @@ float LocalLuaEntity::get_scale() {
void LocalLuaEntity::set_display_type(const std::string &type, const std::string &arg, sol::optional<std::string> arg2) {
if (strncmp(type.data(), "gameobject", 10) == 0) {
ItemDef& def = defs.defs->fromStr(arg);
ItemDef& def = defs.getDefs().fromStr(arg);
if (def.type == ItemDef::Type::BLOCK)
entity->setModel(static_cast<BlockDef&>(def).entityModel);

View File

@ -6,16 +6,16 @@
#include "../Lua.h"
#include "LocalLuaAnimationManager.h"
#include "../../game/entity/Entity.h"
#include "../../game/entity/DrawableEntity.h"
class LocalSubgame;
class LocalLuaEntity {
public:
LocalLuaEntity(std::unique_ptr<Entity> entity, unsigned int id, LocalSubgame& defs) :
LocalLuaEntity(std::unique_ptr<DrawableEntity> entity, unsigned int id, LocalSubgame& defs) :
entity(std::move(entity)), id(id), defs(defs), manager(*this->entity) {}
std::unique_ptr<Entity> entity = nullptr;
std::unique_ptr<DrawableEntity> entity = nullptr;
unsigned int id;
LocalSubgame& defs;

View File

@ -1,13 +0,0 @@
//
// Created by aurailus on 2020-02-24.
//
#include "LocalLuaInventory.h"
#include "LocalLuaInventoryList.h"
sol::object LocalLuaInventory::get_list(sol::this_state s, std::string name) {
auto list = inventory[name];
if (!list) return sol::nil;
return sol::make_object<LocalLuaInventoryList>(s, LocalLuaInventoryList(*list));
}

View File

@ -1,18 +0,0 @@
//
// Created by aurailus on 2020-02-24.
//
#pragma once
#include "../Lua.h"
#include "../../game/inventory/LocalInventory.h"
class LocalLuaInventory {
public:
LocalLuaInventory(LocalInventory& inventory) : inventory(inventory), defs(inventory.defs) {}
LocalInventory& inventory;
DefinitionAtlas& defs;
sol::object get_list(sol::this_state s, std::string name);
};

View File

@ -1,88 +0,0 @@
//
// Created by aurailus on 2020-02-24.
//
#include "LocalLuaInventoryList.h"
#include "LuaItemStack.h"
#include "../../def/ItemDef.h"
#include "../../def/DefinitionAtlas.h"
int LocalLuaInventoryList::get_length() {
return list.getLength();
}
int LocalLuaInventoryList::get_width() {
return list.getWidth();
}
std::string LocalLuaInventoryList::get_name() {
return list.getName();
}
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);
}
LuaItemStack LocalLuaInventoryList::add_stack(LuaItemStack stack) {
return LuaItemStack(list.addStack(ItemStack(stack, list.defs)), list.defs);
}
LuaItemStack LocalLuaInventoryList::add_stack(sol::table stack) {
return LuaItemStack(list.addStack(ItemStack(list.defs.fromStr(stack[1]).index, stack.get<unsigned short>(2))), list.defs);
}
int LocalLuaInventoryList::stack_fits(LuaItemStack stack) {
return list.stackFits(ItemStack(stack, list.defs));
}
int LocalLuaInventoryList::stack_fits(sol::table stack) {
return list.stackFits(ItemStack(list.defs.fromStr(stack[1]).index, stack.get<unsigned short>(2)));
}
LuaItemStack LocalLuaInventoryList::take_stack(LuaItemStack request) {
return LuaItemStack(list.takeStack(ItemStack(request, list.defs)), list.defs);
}
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 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::protected_function fun) {
list.setLuaCallback(t, fun);
}
sol::protected_function LocalLuaInventoryList::get_callback(LocalInventoryList::Callback t) {
return list.getLuaCallback(t);
}

View File

@ -1,43 +0,0 @@
//
// Created by aurailus on 2020-02-24.
//
#pragma once
#include "../../game/inventory/LocalInventoryList.h"
class LocalLuaInventoryList {
public:
LocalLuaInventoryList(LocalInventoryList& list) :
list(list) {}
LocalInventoryList& list;
int get_length();
int get_width();
std::string get_name();
LuaItemStack get_stack(unsigned short i);
void set_stack(unsigned short i, LuaItemStack stack);
void set_stack(unsigned short i, sol::table stack);
LuaItemStack place_stack(unsigned short i, LuaItemStack stack);
LuaItemStack place_stack(unsigned short i, sol::table stack);
LuaItemStack split_stack(unsigned short i);
LuaItemStack add_stack(LuaItemStack stack);
LuaItemStack add_stack(sol::table stack);
int stack_fits(LuaItemStack stack);
int stack_fits(sol::table stack);
LuaItemStack take_stack(LuaItemStack request);
LuaItemStack take_stack(sol::table request);
LuaItemStack remove_stack(unsigned short ind, unsigned short count);
void set_callback(LocalInventoryList::Callback t, sol::protected_function fun);
sol::protected_function get_callback(LocalInventoryList::Callback t);
};

View File

@ -1,118 +0,0 @@
//
// Created by aurailus on 2019-10-19.
//
#include <glm/glm.hpp>
#include "LocalLuaPlayer.h"
#include "LuaItemStack.h"
#include "LocalLuaInventoryList.h"
#include "../../game/scene/world/Player.h"
glm::vec3 LocalLuaPlayer::get_pos() {
return player.getPos();
}
glm::vec3 LocalLuaPlayer::get_block_pos() {
return glm::floor(player.getPos());
}
void LocalLuaPlayer::set_pos(glm::vec3 pos) {
player.setPos(pos, true);
}
glm::vec3 LocalLuaPlayer::get_vel() {
return player.getVel();
}
void LocalLuaPlayer::set_vel(glm::vec3 vel) {
player.setVel(vel, true);
}
float LocalLuaPlayer::get_look_yaw() {
return player.getYaw();
}
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();
}
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();
}
void LocalLuaPlayer::set_hud(std::shared_ptr<LuaGuiElement> hud) {
player.setHud(hud);
}
LocalLuaInventory LocalLuaPlayer::get_inventory() {
return LocalLuaInventory(player.getInventory());
}
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("", true);
else if (list->is<std::string>()) player.setWieldList(list->as<std::string>(), true);
else if (list->is<LocalLuaInventoryList>()) player.setWieldList(list->as<LocalLuaInventoryList>().get_name(), true);
else throw "Attempted to set wield list to nil.";
}
unsigned int LocalLuaPlayer::get_wield_index() {
return player.getWieldIndex() + 1;
}
void LocalLuaPlayer::set_wield_index(unsigned int index) {
player.setWieldIndex(index - 1, true);
}
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) {
player.setFlying(shouldFly, true);
}
bool LocalLuaPlayer::get_flying() {
return player.isFlying();
}

View File

@ -1,96 +0,0 @@
//
// Created by aurailus on 2019-10-19.
//
#pragma once
//#include <sol/forward.hpp>
#include "LocalLuaInventory.h"
class LuaGuiElement;
class Player;
class LocalLuaPlayer {
public:
LocalLuaPlayer(Player& player) : player(player) {}
Player& player;
glm::vec3 get_pos();
glm::vec3 get_block_pos();
void set_pos(glm::vec3 pos);
glm::vec3 get_vel();
void set_vel(glm::vec3 vel);
float get_look_yaw();
void set_look_yaw(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();
std::shared_ptr<LuaGuiElement> get_hud();
void set_hud(std::shared_ptr<LuaGuiElement> hud);
LocalLuaInventory get_inventory();
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();
};
namespace ClientApi {
static void local_player(sol::state& lua) {
lua.new_usertype<LocalLuaPlayer>("LocalPlayer",
"is_player", sol::property([]() { return true; }),
"get_pos", &LocalLuaPlayer::get_pos,
"get_block_pos", &LocalLuaPlayer::get_block_pos,
"set_pos", &LocalLuaPlayer::set_pos,
"get_vel", &LocalLuaPlayer::get_vel,
"set_vel", &LocalLuaPlayer::set_vel,
"get_look_yaw", &LocalLuaPlayer::get_look_yaw,
"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,
"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,
"set_hud", &LocalLuaPlayer::set_hud,
"get_hud", &LocalLuaPlayer::get_hud,
"pos", sol::property(&LocalLuaPlayer::get_pos, &LocalLuaPlayer::set_pos),
"block_pos", sol::property(&LocalLuaPlayer::get_block_pos, &LocalLuaPlayer::set_pos),
"vel", sol::property(&LocalLuaPlayer::get_vel, &LocalLuaPlayer::set_vel),
"look_yaw", sol::property(&LocalLuaPlayer::get_look_yaw, &LocalLuaPlayer::set_look_yaw),
"look_pitch", sol::property(&LocalLuaPlayer::get_look_pitch, &LocalLuaPlayer::set_look_pitch),
"flying", sol::property(&LocalLuaPlayer::set_flying, &LocalLuaPlayer::get_flying),
"in_menu", sol::property(&LocalLuaPlayer::is_in_menu)
);
}
}

View File

@ -6,11 +6,12 @@
#include "../Lua.h"
#include "../../def/ItemDef.h"
#include "../../def/Subgame.h"
#include "../../def/DefinitionAtlas.h"
#include "../../game/inventory/ItemStack.h"
LuaItemStack::LuaItemStack(const ItemStack &stack, const DefinitionAtlas &defs) :
name((stack.count == 0 ? "" : defs.fromId(stack.id).identifier)),
LuaItemStack::LuaItemStack(const ItemStack &stack, Subgame& game) :
name((stack.count == 0 ? "" : game.getDefs().fromId(stack.id).identifier)),
count(stack.count) {}
LuaItemStack::LuaItemStack(const std::string& name, unsigned short count) :

View File

@ -7,13 +7,13 @@
#include <string>
#include <sol/forward.hpp>
class DefinitionAtlas;
class Subgame;
class ItemStack;
class LuaItemStack {
public:
LuaItemStack() = default;
LuaItemStack(const ItemStack& stack, const DefinitionAtlas& defs);
LuaItemStack(const ItemStack& stack, Subgame& game);
LuaItemStack(const std::string& name, unsigned short count);
LuaItemStack(sol::table tbl);

206
src/lua/usertype/Player.cpp Normal file
View File

@ -0,0 +1,206 @@
//
// Created by aurailus on 2019-10-19.
//
#include <glm/glm.hpp>
#include "Player.h"
#include "LuaItemStack.h"
#include "InventoryList.h"
#include "../../game/scene/world/LocalPlayer.h"
unsigned int Api::Usertype::ServerPlayer::get_id() {
return player->getId();
}
glm::vec3 Api::Usertype::ServerPlayer::get_pos() {
return player->getPos();
}
glm::vec3 Api::Usertype::ServerPlayer::get_block_pos() {
return glm::floor(player->getPos());
}
void Api::Usertype::ServerPlayer::set_pos(glm::vec3 pos) {
player->setPos(pos, true);
}
glm::vec3 Api::Usertype::ServerPlayer::get_vel() {
return player->getVel();
}
void Api::Usertype::ServerPlayer::set_vel(glm::vec3 vel) {
player->setVel(vel, true);
}
float Api::Usertype::ServerPlayer::get_look_yaw() {
return player->getYaw();
}
void Api::Usertype::ServerPlayer::set_look_yaw(float rot) {
player->setYaw(rot, true);
}
float Api::Usertype::ServerPlayer::get_look_pitch() {
return player->getPitch();
}
void Api::Usertype::ServerPlayer::set_look_pitch(float rot) {
player->setPitch(rot, true);
}
Api::Usertype::Inventory Api::Usertype::ServerPlayer::get_inventory() {
return Inventory(player->getInventory());
}
sol::object Api::Usertype::ServerPlayer::get_hand_list(sol::this_state s) {
auto listStr = player->getHandList();
if (listStr.empty()) return sol::nil;
return sol::make_object<InventoryList>(s,
InventoryList(player->getInventory().getListPtr(listStr)));
}
sol::object Api::Usertype::ServerPlayer::get_hand_stack(sol::this_state s) {
auto listStr = player->getHandList();
if (listStr.empty()) return sol::nil;
return sol::make_object<LuaItemStack>(s,
InventoryList(player->getInventory().getListPtr(listStr)).get_stack(1));
}
void Api::Usertype::ServerPlayer::set_hand_list(sol::optional<sol::object> list) {
if (!list) player->setHandList("", true);
else if (list->is<std::string>()) player->setHandList(list->as<std::string>(), true);
else if (list->is<InventoryList>()) player->setHandList(list->as<InventoryList>().get_name(), true);
else throw "Attempted to set hand list to nil.";
}
sol::object Api::Usertype::ServerPlayer::get_wield_list(sol::this_state s) {
auto listStr = player->getWieldList();
if (listStr.empty()) return sol::nil;
return sol::make_object<InventoryList>(s,
InventoryList(player->getInventory().getListPtr(listStr)));
}
void Api::Usertype::ServerPlayer::set_wield_list(sol::optional<sol::object> list) {
if (!list) player->setWieldList("", true);
else if (list->is<std::string>()) player->setWieldList(list->as<std::string>(), true);
else if (list->is<InventoryList>()) player->setWieldList(list->as<InventoryList>().get_name(), true);
else throw "Attempted to set wield list to nil.";
}
unsigned int Api::Usertype::ServerPlayer::get_wield_index() {
return player->getWieldIndex() + 1;
}
void Api::Usertype::ServerPlayer::set_wield_index(unsigned int index) {
player->setWieldIndex(index - 1, true);
}
sol::object Api::Usertype::ServerPlayer::get_wield_stack(sol::this_state s) {
auto listStr = player->getWieldList();
if (listStr.empty()) return sol::nil;
return sol::make_object<LuaItemStack>(s, InventoryList(player->getInventory()
.getListPtr(listStr)).get_stack(player->getWieldIndex() + 1));
}
void Api::Usertype::ServerPlayer::set_flying(bool shouldFly) {
player->setFlying(shouldFly, true);
}
bool Api::Usertype::ServerPlayer::get_flying() {
return player->isFlying();
}
void Api::Usertype::ServerPlayer::bind(State state, sol::state &lua, sol::table &core) {
lua.new_usertype<ServerPlayer>("Player",
"get_id", &ServerPlayer::get_id,
"get_pos", &ServerPlayer::get_pos,
"get_block_pos", &ServerPlayer::get_block_pos,
"set_pos", &ServerPlayer::set_pos,
"get_vel", &ServerPlayer::get_vel,
"set_vel", &ServerPlayer::set_vel,
"get_look_yaw", &ServerPlayer::get_look_yaw,
"set_look_yaw", &ServerPlayer::set_look_yaw,
"get_look_pitch", &ServerPlayer::get_look_pitch,
"set_look_pitch", &ServerPlayer::set_look_pitch,
"get_inventory", &ServerPlayer::get_inventory,
"get_hand_list", &ServerPlayer::get_hand_list,
"set_hand_list", &ServerPlayer::set_hand_list,
"get_hand_stack", &ServerPlayer::get_hand_stack,
"get_wield_list", &ServerPlayer::get_wield_list,
"set_wield_list", &ServerPlayer::set_wield_list,
"get_wield_index", &ServerPlayer::get_wield_index,
"set_wield_index", &ServerPlayer::set_wield_index,
"get_wield_stack", &ServerPlayer::get_wield_stack,
"pos", sol::property(&ServerPlayer::get_pos, &ServerPlayer::set_pos),
"block_pos", sol::property(&ServerPlayer::get_block_pos, &ServerPlayer::set_pos),
"vel", sol::property(&ServerPlayer::get_vel, &ServerPlayer::set_vel),
"look_yaw", sol::property(&ServerPlayer::get_look_yaw, &ServerPlayer::set_look_yaw),
"look_pitch", sol::property(&ServerPlayer::get_look_pitch, &ServerPlayer::set_look_pitch),
"flying", sol::property(&ServerPlayer::set_flying, &ServerPlayer::get_flying)
);
}
bool Api::Usertype::LocalPlayer::is_in_menu() {
return std::static_pointer_cast<::LocalPlayer>(player)->isInMenu();
}
void Api::Usertype::LocalPlayer::show_menu(std::shared_ptr<LuaGuiElement> root) {
return std::static_pointer_cast<::LocalPlayer>(player)->showMenu(root);
}
void Api::Usertype::LocalPlayer::close_menu() {
return std::static_pointer_cast<::LocalPlayer>(player)->closeMenu();
}
std::shared_ptr<LuaGuiElement> Api::Usertype::LocalPlayer::get_hud() {
std::cout << "Getting hud " << std::endl;
return std::static_pointer_cast<::LocalPlayer>(player)->getHud();
}
void Api::Usertype::LocalPlayer::set_hud(std::shared_ptr<LuaGuiElement> hud) {
std::static_pointer_cast<::LocalPlayer>(player)->setHud(hud);
}
void Api::Usertype::LocalPlayer::bind(State state, sol::state &lua, sol::table &core) {
lua.new_usertype<LocalPlayer>("Player",
"get_id", &LocalPlayer::get_id,
"get_pos", &LocalPlayer::get_pos,
"get_block_pos", &LocalPlayer::get_block_pos,
"set_pos", &LocalPlayer::set_pos,
"get_vel", &LocalPlayer::get_vel,
"set_vel", &LocalPlayer::set_vel,
"get_look_yaw", &LocalPlayer::get_look_yaw,
"set_look_yaw", &LocalPlayer::set_look_yaw,
"get_look_pitch", &LocalPlayer::get_look_pitch,
"set_look_pitch", &LocalPlayer::set_look_pitch,
"get_inventory", &LocalPlayer::get_inventory,
"get_hand_list", &LocalPlayer::get_hand_list,
"get_hand_stack", &LocalPlayer::get_hand_stack,
"get_wield_list", &LocalPlayer::get_wield_list,
"set_wield_list", &LocalPlayer::set_wield_list,
"get_wield_index", &LocalPlayer::get_wield_index,
"set_wield_index", &LocalPlayer::set_wield_index,
"get_wield_stack", &LocalPlayer::get_wield_stack,
"show_menu", &LocalPlayer::show_menu,
"close_menu", &LocalPlayer::close_menu,
"set_hud", &LocalPlayer::set_hud,
"get_hud", &LocalPlayer::get_hud,
"pos", sol::property(&LocalPlayer::get_pos, &LocalPlayer::set_pos),
"block_pos", sol::property(&LocalPlayer::get_block_pos, &LocalPlayer::set_pos),
"vel", sol::property(&LocalPlayer::get_vel, &LocalPlayer::set_vel),
"look_yaw", sol::property(&LocalPlayer::get_look_yaw, &LocalPlayer::set_look_yaw),
"look_pitch", sol::property(&LocalPlayer::get_look_pitch, &LocalPlayer::set_look_pitch),
"flying", sol::property(&LocalPlayer::set_flying, &LocalPlayer::get_flying),
"in_menu", sol::property(&LocalPlayer::is_in_menu)
);
}

71
src/lua/usertype/Player.h Normal file
View File

@ -0,0 +1,71 @@
//
// Created by aurailus on 2019-10-19.
//
#pragma once
//#include <sol/forward.hpp>
#include <memory>
#include "Inventory.h"
#include "../../game/scene/world/LocalPlayer.h"
class LuaGuiElement;
namespace Api::Usertype {
class ServerPlayer : public SubgameUsertype {
public:
ServerPlayer(std::shared_ptr<::Player> player) : player(player) {}
std::shared_ptr<::Player> player;
unsigned int get_id();
glm::vec3 get_pos();
glm::vec3 get_block_pos();
void set_pos(glm::vec3 pos);
glm::vec3 get_vel();
void set_vel(glm::vec3 vel);
float get_look_yaw();
void set_look_yaw(float rot);
float get_look_pitch();
void set_look_pitch(float rot);
sol::object get_hand_list(sol::this_state s);
sol::object get_hand_stack(sol::this_state s);
void set_hand_list(sol::optional<sol::object> list);
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);
Inventory get_inventory();
unsigned int get_wield_index();
void set_wield_index(unsigned int index);
void set_flying(bool shouldFly);
bool get_flying();
static void bind(State state, sol::state& lua, sol::table& core);
};
class LocalPlayer : public ServerPlayer {
public:
LocalPlayer(std::shared_ptr<::LocalPlayer> player) :
ServerPlayer(std::static_pointer_cast<::Player>(player)) {}
bool is_in_menu();
void show_menu(std::shared_ptr<LuaGuiElement> root);
void close_menu();
std::shared_ptr<LuaGuiElement> get_hud();
void set_hud(std::shared_ptr<LuaGuiElement> hud);
static void bind(State state, sol::state& lua, sol::table& core);
};
}

View File

@ -25,7 +25,7 @@ void ServerLocalLuaEntity::setDisplayType(const std::string &type, const std::st
if (strncmp(type.data(), "gameobject", 10) == 0 &&
(strncmp(displayType.data(), "gameobject", 10) || arg2 != displayArg2)) {
ItemDef& def = defs.defs->fromStr(arg2);
ItemDef& def = defs.getDefs().fromStr(arg2);
if (def.type == ItemDef::Type::BLOCK)
entity->setModel(static_cast<BlockDef&>(def).entityModel);

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