Refactor GUI Library
parent
1f3acbcce6
commit
707ccb6a51
|
@ -218,7 +218,7 @@ set(ZEPHA_SRC
|
|||
game/scene/world/ItemStack.h
|
||||
server/LocalServerInstance.cpp
|
||||
server/LocalServerInstance.h
|
||||
game/hud/SerializedGuiElem.h
|
||||
game/hud/SerialGui.h
|
||||
util/Voronoi3D.cpp
|
||||
util/Voronoi3D.h
|
||||
def/gen/BiomeDef.cpp
|
||||
|
|
|
@ -10,14 +10,6 @@
|
|||
|
||||
enum class Mode { INVALID, CLIENT, SERVER };
|
||||
|
||||
uint64_t constexpr mix(char m, uint64_t s) {
|
||||
return ((s<<7) + ~(s>>3)) + ~m;
|
||||
}
|
||||
|
||||
uint64_t constexpr hashStr(const char * m) {
|
||||
return (*m) ? mix(*m, hashStr(m+1)) : 0;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> parseArgs(int argc, char* argv[]) {
|
||||
//Collect arguments into `args` map
|
||||
std::map<std::string, std::string> args;
|
||||
|
@ -54,30 +46,30 @@ int StartGame(int argc, char* argv[]) {
|
|||
|
||||
//Parse the arguments map
|
||||
for (auto arg : parseArgs(argc, argv)) {
|
||||
switch (hashStr(arg.first.c_str())) {
|
||||
switch (Util::hash(arg.first.c_str())) {
|
||||
default: {
|
||||
std::cout << Log::err << "Invalid argument " << arg.first << "." << Log::endl;
|
||||
return -1;
|
||||
}
|
||||
case hashStr("--mode"): {
|
||||
case Util::hash("--mode"): {
|
||||
if (arg.second == "client") mode = Mode::CLIENT;
|
||||
else if (arg.second == "server") mode = Mode::SERVER;
|
||||
else std::cout << Log::err << "Invalid mode argument." << Log::endl;
|
||||
break;
|
||||
}
|
||||
case hashStr("--port"): {
|
||||
case Util::hash("--port"): {
|
||||
addr.port = static_cast<unsigned short>(stoi(arg.second));
|
||||
break;
|
||||
}
|
||||
case hashStr("--address"): {
|
||||
case Util::hash("--address"): {
|
||||
addr.host = arg.second;
|
||||
break;
|
||||
}
|
||||
case hashStr("--subgame"): {
|
||||
case Util::hash("--subgame"): {
|
||||
subgame = arg.second;
|
||||
break;
|
||||
}
|
||||
case hashStr("--noascii"): {
|
||||
case Util::hash("--noascii"): {
|
||||
ascii = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "GameGuiBuilder.h"
|
||||
#include "SerializedGuiElem.h"
|
||||
#include "SerialGui.h"
|
||||
#include "components/basic/GUIText.h"
|
||||
#include "components/basic/GUIRect.h"
|
||||
#include "components/basic/GUIContainer.h"
|
||||
|
|
|
@ -3,93 +3,31 @@
|
|||
//
|
||||
|
||||
#include "GameGuiBuilder.h"
|
||||
|
||||
#include "components/compound/GUIInventoryList.h"
|
||||
|
||||
std::shared_ptr<GUIComponent> GameGuiBuilder::createComponent(SerializedGuiElem &data) {
|
||||
auto comp = GuiBuilder::createComponent(data);
|
||||
if (comp) return comp;
|
||||
std::shared_ptr<GUIComponent> GameGuiBuilder::createComponent(SerialGui::Elem &data, glm::ivec2 bounds) {
|
||||
auto c = GuiBuilder::createComponent(data, bounds);
|
||||
if (c != nullptr) return c;
|
||||
|
||||
// Extra definitions
|
||||
GUIComponent::callback cbLeftClick = nullptr;
|
||||
GUIComponent::callback cbRightClick = nullptr;
|
||||
GUIComponent::callback cbHover = nullptr;
|
||||
|
||||
glm::vec2 pos {};
|
||||
|
||||
std::function<void(bool, glm::ivec2)> cbLeftClick = nullptr, cbRightClick = nullptr, cbHover = nullptr;
|
||||
if (callbacks.count(data.key)) {
|
||||
cbLeftClick = callbacks[data.key].left;
|
||||
cbRightClick = callbacks[data.key].right;
|
||||
cbHover = callbacks[data.key].hover;
|
||||
}
|
||||
|
||||
if (data.tokens.count("position")) {
|
||||
auto tokens = splitValue(data.tokens["position"], 2);
|
||||
pos = {stringToNum(tokens[0], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_HEIGHT)};
|
||||
}
|
||||
|
||||
glm::vec2 offset {};
|
||||
if (data.tokens.count("position_anchor")) {
|
||||
auto tokens = splitValue(data.tokens["position_anchor"], 2);
|
||||
offset = {stringToNum(tokens[0], PercentBehavior::DECIMAL),
|
||||
stringToNum(tokens[1], PercentBehavior::DECIMAL)};
|
||||
}
|
||||
|
||||
glm::vec2 size {};
|
||||
if (data.tokens.count("size")) {
|
||||
auto tokens = splitValue(data.tokens["size"], 2);
|
||||
size = {stringToNum(tokens[0], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_HEIGHT)};
|
||||
}
|
||||
|
||||
pos -= offset * size;
|
||||
|
||||
glm::vec4 padding {};
|
||||
if (data.tokens.count("padding")) {
|
||||
auto tokens = splitValue(data.tokens["padding"], 4);
|
||||
padding = {stringToNum(tokens[0], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[2], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[3], PercentBehavior::BUFF_WIDTH)};
|
||||
}
|
||||
|
||||
else if (data.type == "inventory") {
|
||||
|
||||
std::string source = (data.tokens.count("source") ? data.tokens["source"] : "");
|
||||
std::string list = (data.tokens.count("list") ? data.tokens["list"] : "");
|
||||
|
||||
if (source != "current_player") {
|
||||
std::cerr << "Invalid source specified, " << source << std::endl;
|
||||
return nullptr;
|
||||
switch (Util::hash(data.type.c_str())) {
|
||||
default: break;
|
||||
case Util::hash("inventory"): {
|
||||
c = GUIInventoryList::fromSerialized(data, game, bounds, inventory, hand);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!inventory[list]) {
|
||||
std::cerr << "Invalid list specified, " << list << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto invList = inventory[list];
|
||||
|
||||
glm::vec4 padding {};
|
||||
if (data.tokens.count("padding")) {
|
||||
auto tokens = splitValue(data.tokens["padding"], 4);
|
||||
padding = {stringToNum(tokens[0], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[2], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[3], PercentBehavior::BUFF_WIDTH)};
|
||||
}
|
||||
|
||||
glm::vec2 innerPadding {};
|
||||
if (data.tokens.count("slot_spacing")) {
|
||||
auto tokens = splitValue(data.tokens["slot_spacing"], 2);
|
||||
innerPadding = {stringToNum(tokens[0], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_WIDTH)};
|
||||
}
|
||||
|
||||
auto inv = std::make_shared<GUIInventoryList>(data.key);
|
||||
|
||||
inv->create(glm::vec2(SCALE_MODIFIER), padding * SCALE_MODIFIER, innerPadding * SCALE_MODIFIER, *invList, hand, defs);
|
||||
inv->setPos(pos);
|
||||
inv->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
|
||||
return inv;
|
||||
}
|
||||
|
||||
if (c != nullptr) c->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ public:
|
|||
GameGuiBuilder(Inventory& inventory, InventoryList& hand, ClientGame& defs, std::shared_ptr<GUIContainer> root) :
|
||||
inventory(inventory), hand(hand), GuiBuilder(defs, root) {};
|
||||
|
||||
std::shared_ptr<GUIComponent> createComponent(SerializedGuiElem& data) override;
|
||||
std::shared_ptr<GUIComponent> createComponent(SerialGui::Elem& data, glm::ivec2 bounds) override;
|
||||
|
||||
private:
|
||||
Inventory& inventory;
|
||||
|
|
|
@ -4,17 +4,22 @@
|
|||
|
||||
#include "GuiBuilder.h"
|
||||
|
||||
#include "components/basic/GUIRect.h"
|
||||
#include "components/basic/GUIText.h"
|
||||
#include "components/basic/GUIModel.h"
|
||||
#include "components/basic/GUIContainer.h"
|
||||
#include "components/compound/GUIImageButton.h"
|
||||
|
||||
GuiBuilder::GuiBuilder(ClientGame& defs, std::shared_ptr<GUIContainer> root) :
|
||||
defs(defs), root(root) {}
|
||||
game(defs), root(root) {}
|
||||
|
||||
void GuiBuilder::setGui(const std::string& menu, const std::map<std::string, ComponentCallbacks>& callbacks) {
|
||||
this->menu = menu;
|
||||
this->callbacks = callbacks;
|
||||
|
||||
deserialize();
|
||||
deserialize(menu);
|
||||
}
|
||||
|
||||
void GuiBuilder::deserialize() {
|
||||
void GuiBuilder::deserialize(const std::string& menu) {
|
||||
// Split the lines by the newline delimiter
|
||||
std::vector<std::string> lines;
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
|
@ -33,14 +38,15 @@ void GuiBuilder::deserialize() {
|
|||
}
|
||||
|
||||
components.clear();
|
||||
std::vector<SerializedGuiElem*> stack {};
|
||||
unsigned int missingKey = 0;
|
||||
SerializedGuiElem* component = nullptr;
|
||||
unsigned int keyInd = 0;
|
||||
std::vector<SerialGui::Elem*> stack {};
|
||||
SerialGui::Elem* component = nullptr;
|
||||
|
||||
// Parse through the serialized structure and create the Serialized tree
|
||||
for (const std::string& line : lines) {
|
||||
if (line.find(':') != std::string::npos) {
|
||||
//Token
|
||||
if (component == nullptr) throw "Property before component.";
|
||||
// A Property
|
||||
if (component == nullptr) throw "expected a component name before a property";
|
||||
|
||||
std::string::size_type delimiter = line.find(':');
|
||||
|
||||
|
@ -58,19 +64,8 @@ void GuiBuilder::deserialize() {
|
|||
|
||||
component->tokens.emplace(name, value);
|
||||
}
|
||||
else if (line == "end") {
|
||||
//End Component Def
|
||||
if (stack.size() > 0) {
|
||||
component = stack[stack.size() - 1];
|
||||
stack.pop_back();
|
||||
}
|
||||
else {
|
||||
stack.pop_back();
|
||||
component = nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Component
|
||||
else if (line != "end") {
|
||||
// Beginning of a component definition
|
||||
std::string key = "";
|
||||
std::string::size_type keyStart;
|
||||
std::string::size_type keyEnd;
|
||||
|
@ -79,15 +74,12 @@ void GuiBuilder::deserialize() {
|
|||
key = line.substr(keyStart + 1, keyEnd - keyStart - 1);
|
||||
}
|
||||
else {
|
||||
key = "__" + std::to_string(missingKey++);
|
||||
// Create an implicit key because one was not specified
|
||||
key = "__" + std::to_string(keyInd++);
|
||||
}
|
||||
std::string type = line.substr(0, keyStart);
|
||||
|
||||
SerializedGuiElem g;
|
||||
g.key = key;
|
||||
g.type = type;
|
||||
g.tokens = {};
|
||||
g.children = {};
|
||||
std::string type = line.substr(0, keyStart);
|
||||
SerialGui::Elem g {type, key, {}, {}};
|
||||
|
||||
if (component == nullptr) {
|
||||
components.push_back(std::move(g));
|
||||
|
@ -99,14 +91,20 @@ void GuiBuilder::deserialize() {
|
|||
component = &component->children[component->children.size() - 1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// End of a component definition -- pop the stack up
|
||||
if (stack.size() > 0) {
|
||||
component = stack[stack.size() - 1];
|
||||
stack.pop_back();
|
||||
}
|
||||
else component = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiBuilder::build(glm::ivec2 win) {
|
||||
this->win = win;
|
||||
|
||||
void GuiBuilder::build(glm::ivec2 winBounds) {
|
||||
clear(false);
|
||||
recursivelyCreate(components, root);
|
||||
recursivelyCreate(components, root, winBounds);
|
||||
}
|
||||
|
||||
void GuiBuilder::clear(bool clrCallbacks) {
|
||||
|
@ -114,248 +112,52 @@ void GuiBuilder::clear(bool clrCallbacks) {
|
|||
root->empty();
|
||||
}
|
||||
|
||||
void GuiBuilder::recursivelyCreate(std::vector<SerializedGuiElem> components, std::shared_ptr<GUIComponent> parent) {
|
||||
void GuiBuilder::recursivelyCreate(std::vector<SerialGui::Elem> components, std::shared_ptr<GUIComponent> parent, glm::ivec2 bounds) {
|
||||
for (auto& data : components) {
|
||||
std::shared_ptr<GUIComponent> component = createComponent(data);
|
||||
if (component != nullptr) {
|
||||
parent->add(component);
|
||||
recursivelyCreate(data.children, component);
|
||||
}
|
||||
std::shared_ptr<GUIComponent> component = createComponent(data, bounds);
|
||||
if (component == nullptr) continue;
|
||||
parent->add(component);
|
||||
recursivelyCreate(data.children, component, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<GUIComponent> GuiBuilder::createComponent(SerializedGuiElem& data) {
|
||||
glm::vec2 pos {};
|
||||
std::shared_ptr<GUIComponent> GuiBuilder::createComponent(SerialGui::Elem& data, glm::ivec2 bounds) {
|
||||
std::shared_ptr<GUIComponent> c = nullptr;
|
||||
|
||||
GUIComponent::callback cbLeftClick = nullptr;
|
||||
GUIComponent::callback cbRightClick = nullptr;
|
||||
GUIComponent::callback cbHover = nullptr;
|
||||
|
||||
std::function<void(bool, glm::ivec2)> cbLeftClick = nullptr, cbRightClick = nullptr, cbHover = nullptr;
|
||||
if (callbacks.count(data.key)) {
|
||||
cbLeftClick = callbacks[data.key].left;
|
||||
cbRightClick = callbacks[data.key].right;
|
||||
cbHover = callbacks[data.key].hover;
|
||||
}
|
||||
|
||||
if (data.tokens.count("position")) {
|
||||
auto tokens = splitValue(data.tokens["position"], 2);
|
||||
pos = {stringToNum(tokens[0], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_HEIGHT)};
|
||||
}
|
||||
|
||||
glm::vec2 offset {};
|
||||
if (data.tokens.count("position_anchor")) {
|
||||
auto tokens = splitValue(data.tokens["position_anchor"], 2);
|
||||
offset = {stringToNum(tokens[0], PercentBehavior::DECIMAL),
|
||||
stringToNum(tokens[1], PercentBehavior::DECIMAL)};
|
||||
}
|
||||
|
||||
glm::vec2 size {};
|
||||
if (data.tokens.count("size")) {
|
||||
auto tokens = splitValue(data.tokens["size"], 2);
|
||||
size = {stringToNum(tokens[0], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_HEIGHT)};
|
||||
}
|
||||
|
||||
pos -= offset * size;
|
||||
|
||||
glm::vec4 padding {};
|
||||
if (data.tokens.count("padding")) {
|
||||
auto tokens = splitValue(data.tokens["padding"], 4);
|
||||
padding = {stringToNum(tokens[0], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[2], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[3], PercentBehavior::BUFF_WIDTH)};
|
||||
}
|
||||
|
||||
if (data.type == "body") {
|
||||
auto rect = std::make_shared<GUIRect>(data.key);
|
||||
|
||||
std::string background = "";
|
||||
if (data.tokens.count("background")) background = data.tokens["background"];
|
||||
|
||||
if (background[0] == '#') rect->create(win, {}, Util::hexToColorVec(background));
|
||||
else if (background.substr(0, 6) == "asset(") rect->create(win, {}, defs.textures[background.substr(6, background.length() - 7)]);
|
||||
else rect->create(win, {}, glm::vec4 {});
|
||||
|
||||
rect->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
return rect;
|
||||
}
|
||||
|
||||
else if (data.type == "rect") {
|
||||
size.x -= padding.y + padding.w;
|
||||
size.y -= padding.x + padding.z;
|
||||
|
||||
std::string background = "";
|
||||
if (data.tokens.count("background")) background = data.tokens["background"];
|
||||
|
||||
auto rect = std::make_shared<GUIRect>(data.key);
|
||||
if (background[0] == '#') rect->create(size, padding, Util::hexToColorVec(background));
|
||||
else if (background.substr(0, 6) == "asset(") rect->create(size, padding, defs.textures[background.substr(6, background.length() - 7)]);
|
||||
else rect->create(size, padding, glm::vec4 {});
|
||||
|
||||
rect->setPos(pos);
|
||||
rect->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
return rect;
|
||||
}
|
||||
|
||||
else if (data.type == "button") {
|
||||
size.x -= padding.y + padding.w;
|
||||
size.y -= padding.x + padding.z;
|
||||
|
||||
std::string background = "";
|
||||
if (data.tokens.count("background")) background = data.tokens["background"];
|
||||
std::string background_hover = background;
|
||||
if (data.tokens.count("background_hover")) background_hover = data.tokens["background_hover"];
|
||||
|
||||
auto button = std::make_shared<GUIImageButton>(data.key);
|
||||
button->create(size, padding, defs.textures[background.substr(6, background.length() - 7)], defs.textures[background_hover.substr(6, background_hover.length() - 7)]);
|
||||
|
||||
std::string content = "";
|
||||
if (data.tokens.count("content")) content = data.tokens["content"].substr(1, data.tokens["content"].size() - 2);
|
||||
|
||||
if (content != "") {
|
||||
std::string::size_type off = 0;
|
||||
while ((off = content.find("\\n", off)) != std::string::npos) {
|
||||
content.replace(off, 2, "\n");
|
||||
off += 1;
|
||||
}
|
||||
|
||||
auto text = std::make_shared<GUIText>(data.key + "__TEXT");
|
||||
text->create(glm::vec2(SCALE_MODIFIER), padding, {}, {1, 1, 1, 1},
|
||||
{defs.textures, defs.textures["font"]});
|
||||
text->setText(content);
|
||||
text->setPos({6*SCALE_MODIFIER, size.y / 2 - 4.5*SCALE_MODIFIER});
|
||||
button->add(text);
|
||||
switch (Util::hash(data.type.c_str())) {
|
||||
default: break;
|
||||
case Util::hash("body"): {
|
||||
auto body = GUIRect::fromSerialized(data, game, bounds);
|
||||
body->setScale(bounds);
|
||||
c = body;
|
||||
break;
|
||||
}
|
||||
|
||||
button->setPos(pos);
|
||||
button->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
return button;
|
||||
case Util::hash("rect"):
|
||||
c = GUIRect::fromSerialized(data, game, bounds);
|
||||
break;
|
||||
case Util::hash("button"):
|
||||
c = GUIImageButton::fromSerialized(data, game, bounds);
|
||||
break;
|
||||
case Util::hash("text"):
|
||||
c = GUIText::fromSerialized(data, game, bounds);
|
||||
break;
|
||||
case Util::hash("model"):
|
||||
c = GUIModel::fromSerialized(data, game, bounds);
|
||||
break;
|
||||
}
|
||||
|
||||
else if (data.type == "text") {
|
||||
glm::vec2 scale = {1, 1};
|
||||
if (data.tokens.count("scale")) {
|
||||
auto tokens = splitValue(data.tokens["scale"], 2);
|
||||
scale = {stringToNum(tokens[0], PercentBehavior::DECIMAL),
|
||||
stringToNum(tokens[1], PercentBehavior::DECIMAL)};
|
||||
}
|
||||
|
||||
glm::vec4 padding {};
|
||||
if (data.tokens.count("padding")) {
|
||||
auto tokens = splitValue(data.tokens["padding"], 4);
|
||||
padding = {stringToNum(tokens[0], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[1], PercentBehavior::BUFF_WIDTH),
|
||||
stringToNum(tokens[2], PercentBehavior::BUFF_HEIGHT),
|
||||
stringToNum(tokens[3], PercentBehavior::BUFF_WIDTH)};
|
||||
}
|
||||
|
||||
glm::vec4 background_color = Util::hexToColorVec("#0000");
|
||||
if (data.tokens.count("background")) background_color = Util::hexToColorVec(data.tokens["background"]);
|
||||
glm::vec4 color = Util::hexToColorVec("#fff");
|
||||
if (data.tokens.count("color")) color = Util::hexToColorVec(data.tokens["color"]);
|
||||
|
||||
std::string content = "Missing content string";
|
||||
if (data.tokens.count("content")) content = data.tokens["content"].substr(1, data.tokens["content"].size() - 2);
|
||||
|
||||
std::string::size_type off = 0;
|
||||
while ((off = content.find("\\n", off)) != std::string::npos) {
|
||||
content.replace(off, 2, "\n");
|
||||
off += 1;
|
||||
}
|
||||
|
||||
auto text = std::make_shared<GUIText>(data.key);
|
||||
text->create(scale * SCALE_MODIFIER, padding, background_color, color, {defs.textures, defs.textures["font"]});
|
||||
text->setText(content);
|
||||
text->setPos(pos);
|
||||
text->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
return text;
|
||||
}
|
||||
|
||||
else if (data.type == "model") {
|
||||
glm::vec2 scale = {1, 1};
|
||||
if (data.tokens.count("scale")) {
|
||||
auto tokens = splitValue(data.tokens["scale"], 2);
|
||||
scale = {stringToNum(tokens[0], PercentBehavior::DECIMAL),
|
||||
stringToNum(tokens[1], PercentBehavior::DECIMAL)};
|
||||
}
|
||||
std::string type = (data.tokens.count("type") ? data.tokens["type"] : "model");
|
||||
std::string source = (data.tokens.count("source") ? data.tokens["source"] : "");
|
||||
std::string texture = (data.tokens.count("texture") ? data.tokens["texture"] : "");
|
||||
|
||||
glm::vec2 anim_range = {0, 0};
|
||||
if (data.tokens.count("anim_range")) {
|
||||
auto tokens = splitValue(data.tokens["anim_range"], 2);
|
||||
anim_range = {stringToNum(tokens[0], PercentBehavior::DECIMAL),
|
||||
stringToNum(tokens[1], PercentBehavior::DECIMAL)};
|
||||
}
|
||||
|
||||
auto m = std::make_shared<Model>();
|
||||
|
||||
if (type == "model") {
|
||||
m->fromSerialized(defs.models.models[source], {defs.textures[texture]});
|
||||
}
|
||||
|
||||
auto model = std::make_shared<GUIModel>(data.key);
|
||||
model->create(scale, m);
|
||||
|
||||
if (anim_range.y != 0) {
|
||||
model->animate(anim_range);
|
||||
}
|
||||
|
||||
model->setPos(pos);
|
||||
model->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
return model;
|
||||
}
|
||||
|
||||
// An unknown type was specified.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
float GuiBuilder::stringToNum(const std::string& input, PercentBehavior behavior = PercentBehavior::BUFF_WIDTH) {
|
||||
if (input.find("px") != std::string::npos) {
|
||||
return atof(input.substr(0, input.find("px")).c_str()) * SCALE_MODIFIER;
|
||||
}
|
||||
|
||||
if (input.find('%') != std::string::npos) {
|
||||
float decimal = atof(input.substr(0, input.find('%')).c_str()) / 100;
|
||||
switch (behavior) {
|
||||
case PercentBehavior::DECIMAL:
|
||||
return decimal;
|
||||
case PercentBehavior::BUFF_WIDTH:
|
||||
return round(decimal * win.x / SCALE_MODIFIER) * SCALE_MODIFIER;
|
||||
case PercentBehavior::BUFF_HEIGHT:
|
||||
return round(decimal * win.y / SCALE_MODIFIER) * SCALE_MODIFIER;
|
||||
}
|
||||
}
|
||||
|
||||
return atof(input.c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> GuiBuilder::splitValue(const std::string &value, unsigned int targetVals) {
|
||||
std::vector<std::string> vec {};
|
||||
|
||||
if (value == "") throw "No values for splitValue.";
|
||||
|
||||
size_t count = std::count(value.begin(), value.end(), ' ');
|
||||
if (count + 1 > targetVals) throw "Too many values for splitValue.";
|
||||
|
||||
size_t begin = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
size_t end = value.find(' ', begin);
|
||||
vec.push_back(value.substr(begin, end - begin));
|
||||
begin = end + 1;
|
||||
}
|
||||
vec.push_back(value.substr(begin));
|
||||
|
||||
while (vec.size() < targetVals) {
|
||||
for (auto& v: vec) {
|
||||
vec.push_back(v);
|
||||
if (vec.size() >= targetVals) break;
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(vec);
|
||||
if (c != nullptr) c->setCallbacks(cbLeftClick, cbRightClick, cbHover);
|
||||
return c;
|
||||
}
|
||||
|
||||
GuiBuilder::~GuiBuilder() {
|
||||
|
|
|
@ -4,51 +4,31 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include "SerializedGuiElem.h"
|
||||
#include "SerialGui.h"
|
||||
#include "../../def/ClientGame.h"
|
||||
#include "components/basic/GUIRect.h"
|
||||
#include "components/basic/GUIText.h"
|
||||
#include "components/basic/GUIModel.h"
|
||||
#include "components/basic/GUIContainer.h"
|
||||
#include "components/compound/GUIImageButton.h"
|
||||
#include "components/GUIComponent.h"
|
||||
|
||||
class GUIContainer;
|
||||
|
||||
class GuiBuilder {
|
||||
public:
|
||||
struct ComponentCallbacks {
|
||||
GUIComponent::callback left {}, right {}, hover {};
|
||||
};
|
||||
struct ComponentCallbacks { GUIComponent::callback left {}, right {}, hover {}; };
|
||||
|
||||
GuiBuilder(ClientGame& defs, std::shared_ptr<GUIContainer> root);
|
||||
void setGui(const std::string& menu, const std::map<std::string, ComponentCallbacks>& callbacks = {});
|
||||
void build(glm::ivec2 win);
|
||||
void clear(bool clrCallbacks = true);
|
||||
void build(glm::ivec2 winBounds);
|
||||
|
||||
~GuiBuilder();
|
||||
|
||||
protected:
|
||||
const float SCALE_MODIFIER = 3;
|
||||
void deserialize(const std::string& menu);
|
||||
void recursivelyCreate(std::vector<SerialGui::Elem> components, std::shared_ptr<GUIComponent> parent, glm::ivec2 bounds);
|
||||
virtual std::shared_ptr<GUIComponent> createComponent(SerialGui::Elem& component, glm::ivec2 bounds);
|
||||
|
||||
enum PercentBehavior {
|
||||
BUFF_WIDTH,
|
||||
BUFF_HEIGHT,
|
||||
DECIMAL
|
||||
};
|
||||
|
||||
void deserialize();
|
||||
void recursivelyCreate(std::vector<SerializedGuiElem> components, std::shared_ptr<GUIComponent> parent);
|
||||
virtual std::shared_ptr<GUIComponent> createComponent(SerializedGuiElem& component);
|
||||
|
||||
static std::vector<std::string> splitValue(const std::string& value, unsigned int targetVals = 0);
|
||||
float stringToNum(const std::string& input, PercentBehavior behavior);
|
||||
|
||||
glm::ivec2 win;
|
||||
|
||||
std::string menu;
|
||||
std::map<std::string, ComponentCallbacks> callbacks;
|
||||
|
||||
ClientGame& game;
|
||||
std::shared_ptr<GUIContainer> root;
|
||||
std::vector<SerializedGuiElem> components {};
|
||||
ClientGame& defs;
|
||||
std::vector<SerialGui::Elem> components {};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// Created by aurailus on 2019-11-03.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
namespace SerialGui {
|
||||
struct Elem {
|
||||
std::string type;
|
||||
std::string key;
|
||||
std::map<std::string, std::string> tokens;
|
||||
std::vector<SerialGui::Elem> children;
|
||||
};
|
||||
|
||||
const float SCALE_MODIFIER = 3;
|
||||
|
||||
namespace {
|
||||
static std::vector<std::string> split(const std::string& value, unsigned int targetCount = 0) {
|
||||
std::vector<std::string> vec {};
|
||||
|
||||
if (value == "") throw std::runtime_error("expected one or more values to split");
|
||||
|
||||
size_t count = std::count(value.begin(), value.end(), ' ');
|
||||
if (count + 1 > targetCount) throw std::runtime_error("expected less values");
|
||||
|
||||
// Split the values into the vector.
|
||||
size_t begin = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
size_t end = value.find(' ', begin);
|
||||
vec.push_back(value.substr(begin, end - begin));
|
||||
begin = end + 1;
|
||||
}
|
||||
vec.push_back(value.substr(begin));
|
||||
|
||||
// Duplicate values until we meet or surpass the expected values.
|
||||
while (vec.size() < targetCount) for (auto& v: vec) vec.push_back(v);
|
||||
if (vec.size() > targetCount) throw std::runtime_error("values are not a division of expectation");
|
||||
|
||||
return std::move(vec);
|
||||
}
|
||||
|
||||
static double toDouble(const std::string& input, unsigned int multiple) {
|
||||
char* e;
|
||||
errno = 0;
|
||||
|
||||
if (input.find("px") == input.length() - 2) {
|
||||
double v = round(std::strtod(input.substr(0, input.find("px")).c_str(), &e));
|
||||
if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
|
||||
return v * SCALE_MODIFIER;
|
||||
}
|
||||
|
||||
if (input.find('%') == input.length() - 1) {
|
||||
double v = std::strtod(input.substr(0, input.find("%")).c_str(), &e) / 100;
|
||||
if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
|
||||
|
||||
if (!multiple) return v;
|
||||
return round(v * multiple / SCALE_MODIFIER) * SCALE_MODIFIER;
|
||||
}
|
||||
|
||||
double v = std::strtod(input.c_str(), &e);
|
||||
if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static T deserialize(const std::string& in, glm::ivec2 multiple = {}) {};
|
||||
|
||||
template <typename T> static T deserializeToken(const std::map<std::string, std::string>& tokens,
|
||||
const std::string& req, glm::ivec2 multiple = {}) {
|
||||
if (!tokens.count(req)) return T{};
|
||||
return deserialize<T>(tokens.at(req), multiple);
|
||||
}
|
||||
|
||||
template <> glm::vec2 deserialize<glm::vec2>(const std::string& in, glm::ivec2 multiple) {
|
||||
auto tokens = split(in, 2);
|
||||
return {toDouble(tokens[0], multiple.x), toDouble(tokens[1], multiple.y)};
|
||||
}
|
||||
|
||||
template <> glm::vec4 deserialize<glm::vec4>(const std::string& in, glm::ivec2 multiple) {
|
||||
auto tokens = split(in, 4);
|
||||
return {toDouble(tokens[0], multiple.x), toDouble(tokens[1], multiple.y),
|
||||
toDouble(tokens[2], multiple.x), toDouble(tokens[3], multiple.y)};
|
||||
}
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// Created by aurailus on 2019-11-03.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
struct SerializedGuiElem {
|
||||
std::string type;
|
||||
std::string key;
|
||||
std::map<std::string, std::string> tokens;
|
||||
std::vector<SerializedGuiElem> children;
|
||||
};
|
|
@ -3,8 +3,11 @@
|
|||
//
|
||||
|
||||
#include "GUIInventoryItem.h"
|
||||
|
||||
#include "GUIText.h"
|
||||
#include "GUIRect.h"
|
||||
#include "GUIModel.h"
|
||||
#include "../../../../def/texture/Font.h"
|
||||
|
||||
GUIInventoryItem::GUIInventoryItem(const std::string &key) : GUIContainer(key) {}
|
||||
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GUIRect.h"
|
||||
#include "../../../../def/texture/Font.h"
|
||||
#include "GUIContainer.h"
|
||||
|
||||
class ItemDef;
|
||||
class Font;
|
||||
|
||||
class GUIInventoryItem : public GUIContainer {
|
||||
public:
|
||||
GUIInventoryItem() = default;
|
||||
|
|
|
@ -4,8 +4,32 @@
|
|||
|
||||
#include "GUIModel.h"
|
||||
|
||||
#include "../../../../def/ClientGame.h"
|
||||
|
||||
GUIModel::GUIModel(const std::string &key) : GUIComponent(key) {}
|
||||
|
||||
std::shared_ptr<GUIModel> GUIModel::fromSerialized(SerialGui::Elem s, ClientGame &game, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position", bounds);
|
||||
glm::vec2 scale = SerialGui::deserializeToken<glm::vec2>(s.tokens, "scale");
|
||||
glm::vec2 anim_range = SerialGui::deserializeToken<glm::vec2>(s.tokens, "anim_range");
|
||||
if (scale == glm::vec2{0, 0}) scale = {1, 1};
|
||||
|
||||
std::string type = s.tokens.count("type") ? s.tokens["type"] : "model";
|
||||
std::string source = s.tokens["source"];
|
||||
std::string texture = s.tokens["texture"];
|
||||
|
||||
auto m = std::make_shared<Model>();
|
||||
if (type == "model") m->fromSerialized(game.models.models[source], {game.textures[texture]});
|
||||
|
||||
auto model = std::make_shared<GUIModel>(s.key);
|
||||
model->create(scale, m);
|
||||
model->setPos(pos);
|
||||
|
||||
if (anim_range.y != 0) model->animate(anim_range);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
void GUIModel::create(glm::vec2 scale, std::shared_ptr<Model> model) {
|
||||
entity.setModel(model);
|
||||
setScale({scale.x + padding.w + padding.y, scale.y + padding.x + padding.z});
|
||||
|
@ -39,4 +63,4 @@ void GUIModel::draw(Renderer &renderer) {
|
|||
renderer.clearDepthBuffer();
|
||||
GUIComponent::draw(renderer);
|
||||
renderer.toggleDepthTest(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,20 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "GUIContainer.h"
|
||||
#include "../../../../def/ItemDef.h"
|
||||
#include "../../SerialGui.h"
|
||||
|
||||
class ClientGame;
|
||||
|
||||
class GUIModel : public GUIComponent {
|
||||
public:
|
||||
GUIModel() = default;
|
||||
GUIModel(const std::string& key);
|
||||
|
||||
static std::shared_ptr<GUIModel> fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds);
|
||||
|
||||
void create(glm::vec2 scale, std::shared_ptr<Model> model);
|
||||
void update(double delta) override;
|
||||
|
||||
|
|
|
@ -4,8 +4,31 @@
|
|||
|
||||
#include "GUIRect.h"
|
||||
|
||||
#include "../../SerialGui.h"
|
||||
#include "../../../../util/Util.h"
|
||||
#include "../../../../def/ClientGame.h"
|
||||
|
||||
GUIRect::GUIRect(const std::string &key) : GUIComponent(key) {}
|
||||
|
||||
std::shared_ptr<GUIRect> GUIRect::fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position_anchor");
|
||||
glm::vec2 size = SerialGui::deserializeToken<glm::vec2>(s.tokens, "size", bounds);
|
||||
glm::vec4 padding = SerialGui::deserializeToken<glm::vec4>(s.tokens, "padding", bounds);
|
||||
|
||||
pos -= offset * size;
|
||||
size -= glm::vec2 {padding.y + padding.w, padding.x + padding.z};
|
||||
|
||||
std::string background = s.tokens["background"];
|
||||
|
||||
auto rect = std::make_shared<GUIRect>(s.key);
|
||||
if (background[0] == '#') rect->create(size, padding, Util::hexToColorVec(background));
|
||||
else if (background.size() > 0) rect->create(size, padding, game.textures[background]);
|
||||
else rect->create(size, padding, glm::vec4 {});
|
||||
rect->setPos(pos);
|
||||
return rect;
|
||||
}
|
||||
|
||||
// Single Color Constructor
|
||||
// Creates a GUIRect object whose background
|
||||
// is a flat color defined by 'color'.
|
||||
|
|
|
@ -6,14 +6,20 @@
|
|||
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../GUIComponent.h"
|
||||
#include "../../SerialGui.h"
|
||||
#include "../../../../def/texture/AtlasRef.h"
|
||||
|
||||
class ClientGame;
|
||||
|
||||
class GUIRect : public GUIComponent {
|
||||
public:
|
||||
GUIRect() = default;
|
||||
GUIRect(const std::string& key);
|
||||
|
||||
static std::shared_ptr<GUIRect> fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds);
|
||||
|
||||
void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 color);
|
||||
void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 tl, glm::vec4 tr, glm::vec4 bl, glm::vec4 br);
|
||||
void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture);
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
// Created by aurailus on 25/12/18.
|
||||
//
|
||||
|
||||
#include "GUIText.h"
|
||||
#include <utility>
|
||||
|
||||
#include "GUIText.h"
|
||||
|
||||
GUIText::GUIText(const std::string &key) : GUIComponent(key) {}
|
||||
|
||||
void GUIText::create(glm::vec2 scale, glm::vec4 padding, glm::vec4 bgcolor, glm::vec4 color, Font font) {
|
||||
|
@ -22,6 +23,38 @@ void GUIText::create(glm::vec2 scale, glm::vec4 padding, glm::vec4 bgcolor, glm:
|
|||
setText("");
|
||||
}
|
||||
|
||||
std::shared_ptr<GUIText> GUIText::fromSerialized(SerialGui::Elem s, ClientGame &game, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position_anchor");
|
||||
glm::vec2 size = SerialGui::deserializeToken<glm::vec2>(s.tokens, "size", bounds);
|
||||
glm::vec4 padding = SerialGui::deserializeToken<glm::vec4>(s.tokens, "padding", bounds);
|
||||
glm::vec2 scale = SerialGui::deserializeToken<glm::vec2>(s.tokens, "scale");
|
||||
if (scale == glm::vec2{0, 0}) scale = {1, 1};
|
||||
|
||||
pos -= offset * size;
|
||||
size -= glm::vec2 {padding.y + padding.w, padding.x + padding.z};
|
||||
|
||||
glm::vec4 background_color = Util::hexToColorVec("#0000");
|
||||
if (s.tokens.count("background")) background_color = Util::hexToColorVec(s.tokens["background"]);
|
||||
glm::vec4 color = Util::hexToColorVec("#fff");
|
||||
if (s.tokens.count("color")) color = Util::hexToColorVec(s.tokens["color"]);
|
||||
|
||||
std::string content = "";
|
||||
if (s.tokens.count("content") && s.tokens["content"].length() >= 2) content = s.tokens["content"].substr(1, s.tokens["content"].size() - 2);
|
||||
std::string::size_type off = 0;
|
||||
while ((off = content.find("\\n", off)) != std::string::npos) {
|
||||
content.replace(off, 2, "\n");
|
||||
off += 1;
|
||||
}
|
||||
|
||||
auto text = std::make_shared<GUIText>(s.key);
|
||||
text->create(scale * SerialGui::SCALE_MODIFIER, padding, background_color, color, {game.textures, game.textures["font"]});
|
||||
text->setText(content);
|
||||
text->setPos(pos);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
void GUIText::setText(std::string text) {
|
||||
this->text = std::move(text);
|
||||
unsigned int indOffset = 0;
|
||||
|
|
|
@ -4,17 +4,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "../GUIComponent.h"
|
||||
#include "../../../../def/texture/AtlasRef.h"
|
||||
|
||||
#include "../../SerialGui.h"
|
||||
#include "../../../../def/texture/Font.h"
|
||||
#include <utility>
|
||||
#include "../../../../def/texture/AtlasRef.h"
|
||||
|
||||
class GUIText : public GUIComponent {
|
||||
public:
|
||||
GUIText() = default;
|
||||
explicit GUIText(const std::string& key);
|
||||
|
||||
static std::shared_ptr<GUIText> fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds);
|
||||
|
||||
void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 bgcolor, glm::vec4 color, Font font);
|
||||
|
||||
unsigned int getWidth();
|
||||
|
|
|
@ -4,8 +4,47 @@
|
|||
|
||||
#include "GUIImageButton.h"
|
||||
|
||||
#include "../../../../def/ClientGame.h"
|
||||
#include "../basic/GUIText.h"
|
||||
|
||||
GUIImageButton::GUIImageButton(const std::string &key) : GUIRect(key) {}
|
||||
|
||||
std::shared_ptr<GUIImageButton> GUIImageButton::fromSerialized(SerialGui::Elem s, ClientGame &game, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position_anchor");
|
||||
glm::vec2 size = SerialGui::deserializeToken<glm::vec2>(s.tokens, "size", bounds);
|
||||
glm::vec4 padding = SerialGui::deserializeToken<glm::vec4>(s.tokens, "padding", bounds);
|
||||
|
||||
pos -= offset * size;
|
||||
size -= glm::vec2 {padding.y + padding.w, padding.x + padding.z};
|
||||
|
||||
std::string background = s.tokens["background"];
|
||||
std::string background_hover = s.tokens["background_hover"];
|
||||
if (background_hover.length() == 0) background_hover = background;
|
||||
|
||||
std::string content = "";
|
||||
if (s.tokens.count("content") && s.tokens["content"].length() >= 2) content = s.tokens["content"].substr(1, s.tokens["content"].size() - 2);
|
||||
std::string::size_type off = 0;
|
||||
while ((off = content.find("\\n", off)) != std::string::npos) {
|
||||
content.replace(off, 2, "\n");
|
||||
off += 1;
|
||||
}
|
||||
|
||||
auto button = std::make_shared<GUIImageButton>(s.key);
|
||||
button->create(size, padding, game.textures[background], game.textures[background_hover]);
|
||||
button->setPos(pos);
|
||||
|
||||
if (content != "") {
|
||||
auto text = std::make_shared<GUIText>(s.key + "__TEXT");
|
||||
text->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding, {}, {1, 1, 1, 1}, {game.textures, game.textures["font"]});
|
||||
text->setPos({6 * SerialGui::SCALE_MODIFIER, size.y / 2 - 4.5 * SerialGui::SCALE_MODIFIER});
|
||||
text->setText(content);
|
||||
button->add(text);
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
// Texture Constructor
|
||||
// Creates a GUIImageButton object with two textures
|
||||
// defined by the 'texture' & 'hoverTexture' reference.
|
||||
|
@ -39,4 +78,4 @@ void GUIImageButton::rebuild(bool hover) {
|
|||
|
||||
entity.setModel(model);
|
||||
setScale({scale.x + padding.w + padding.y, scale.y + padding.x + padding.z});
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ public:
|
|||
GUIImageButton() = default;
|
||||
GUIImageButton(const std::string& key);
|
||||
|
||||
static std::shared_ptr<GUIImageButton> fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds);
|
||||
|
||||
void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture, std::shared_ptr<AtlasRef> hoverTexture);
|
||||
|
||||
void setHoverCallback(const callback& hoverCallback) override;
|
||||
|
|
|
@ -4,8 +4,43 @@
|
|||
|
||||
#include "GUIInventoryList.h"
|
||||
|
||||
#include "../basic/GUIInventoryItem.h"
|
||||
#include "../../../../def/texture/Font.h"
|
||||
|
||||
GUIInventoryList::GUIInventoryList(const std::string &key) : GUIContainer(key) {}
|
||||
|
||||
std::shared_ptr<GUIInventoryList> GUIInventoryList::fromSerialized(SerialGui::Elem s, ClientGame &game,
|
||||
glm::ivec2 bounds, Inventory& inventory, InventoryList& hand) {
|
||||
|
||||
glm::vec2 pos = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position_anchor");
|
||||
glm::vec2 size = SerialGui::deserializeToken<glm::vec2>(s.tokens, "size", bounds);
|
||||
glm::vec4 padding = SerialGui::deserializeToken<glm::vec4>(s.tokens, "padding", bounds);
|
||||
glm::vec2 slotspc = SerialGui::deserializeToken<glm::vec2>(s.tokens, "slot_spacing", bounds);
|
||||
|
||||
std::string source = s.tokens["source"];
|
||||
std::string list = s.tokens["list"];
|
||||
|
||||
if (source != "current_player") {
|
||||
std::cerr << "Invalid source specified, " << source << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!inventory[list]) {
|
||||
std::cerr << "Invalid list specified, " << list << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto invList = inventory[list];
|
||||
auto inv = std::make_shared<GUIInventoryList>(s.key);
|
||||
|
||||
inv->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding * SerialGui::SCALE_MODIFIER,
|
||||
slotspc * SerialGui::SCALE_MODIFIER, *invList, hand, game);
|
||||
inv->setPos(pos);
|
||||
|
||||
return inv;
|
||||
}
|
||||
|
||||
void GUIInventoryList::create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding, InventoryList &list, InventoryList& hand, ClientGame &defs) {
|
||||
this->list = &list;
|
||||
this->hand = &hand;
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "../basic/GUIContainer.h"
|
||||
#include "../../../../def/ClientGame.h"
|
||||
|
||||
#include "../basic/GUIRect.h"
|
||||
#include "../basic/GUIInventoryItem.h"
|
||||
#include "../../../../def/texture/Font.h"
|
||||
#include "../../SerialGui.h"
|
||||
#include "../../../../def/ClientGame.h"
|
||||
#include "../../../scene/world/Inventory.h"
|
||||
#include "../../../scene/world/InventoryList.h"
|
||||
|
||||
class GUIInventoryList : public GUIContainer {
|
||||
|
@ -17,6 +18,9 @@ public:
|
|||
GUIInventoryList(const std::string& key);
|
||||
~GUIInventoryList() override;
|
||||
|
||||
static std::shared_ptr<GUIInventoryList> fromSerialized(SerialGui::Elem s, ClientGame &game,
|
||||
glm::ivec2 bounds, Inventory& inventory, InventoryList& hand);
|
||||
|
||||
void create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding, InventoryList& list, InventoryList& hand, ClientGame& defs);
|
||||
|
||||
void setHoverCallback(const callback& hoverCallback) override;
|
||||
|
|
|
@ -221,5 +221,15 @@ namespace Util {
|
|||
case 348: return "menu";
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
constexpr static uint64_t mix(char m, uint64_t s) {
|
||||
return ((s << 7) + ~(s >> 3)) + ~m;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr static uint64_t hash(const char * m) {
|
||||
return (*m) ? mix(*m, hash(m + 1)) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ BlockChunk::BlockChunk(const std::vector<unsigned int>& blocks, const std::vecto
|
|||
}
|
||||
|
||||
bool BlockChunk::setBlock(unsigned int ind, unsigned int blk) {
|
||||
// Exit if someone is doing something stupid
|
||||
if (ind >= 4096) return false;
|
||||
if (!RIE::write(ind, blk, blocks, 4096)) return false;
|
||||
|
||||
// Mesh emptiness manipulation
|
||||
if (blk == DefinitionAtlas::AIR) {
|
||||
if ((nonAirBlocks = fmax(nonAirBlocks - 1, 0)) == 0) {
|
||||
|
@ -35,8 +35,7 @@ bool BlockChunk::setBlock(unsigned int ind, unsigned int blk) {
|
|||
nonAirBlocks++;
|
||||
}
|
||||
|
||||
// Actually set the block
|
||||
return RIE::write(ind, blk, blocks, 4096);
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::vector<unsigned int> &BlockChunk::cGetBlocks() const {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
zepha.set_gui([[
|
||||
body
|
||||
background: asset(zeus_background)
|
||||
background: zeus_background
|
||||
|
||||
rect[sidebar]
|
||||
position: 20% 0
|
||||
|
@ -11,22 +11,22 @@ zepha.set_gui([[
|
|||
rect[logo]
|
||||
position: 8px 8px
|
||||
size: 86px 30px
|
||||
background: asset(zeus_logo)
|
||||
background: zeus_logo
|
||||
end
|
||||
|
||||
button[buttonPlay]
|
||||
position: 6px 50px
|
||||
size: 90px 20px
|
||||
background: asset(crop(0, 0, 90, 20, zeus_button))
|
||||
background_hover: asset(crop(0, 20, 90, 20, zeus_button))
|
||||
background: crop(0, 0, 90, 20, zeus_button)
|
||||
background_hover: crop(0, 20, 90, 20, zeus_button)
|
||||
content: "Local Play"
|
||||
end
|
||||
|
||||
button[buttonServers]
|
||||
position: 6px 74px
|
||||
size: 90px 20px
|
||||
background: asset(crop(0, 0, 90, 20, zeus_button))
|
||||
background_hover: asset(crop(0, 20, 90, 20, zeus_button))
|
||||
background: crop(0, 0, 90, 20, zeus_button)
|
||||
background_hover: crop(0, 20, 90, 20, zeus_button)
|
||||
content: "Browse Servers"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ zepha.register_keybind("zeus:inventory:open_inventory", {
|
|||
position: 0px 45px
|
||||
size: 218px 100px
|
||||
padding: 20px 10px 8px 10px
|
||||
background: asset(zeus:inventory:inventory)
|
||||
background: zeus:inventory:inventory
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
|
@ -31,7 +31,7 @@ zepha.register_keybind("zeus:inventory:open_inventory", {
|
|||
size: 218px 72px
|
||||
position: 0px -15px
|
||||
padding: 20px 10px 8px 10px
|
||||
background: asset(zeus:inventory:crafting)
|
||||
background: zeus:inventory:crafting
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
|
@ -51,7 +51,7 @@ zepha.register_keybind("zeus:inventory:open_inventory", {
|
|||
rect[hot_wheel]
|
||||
size: 214px 67px
|
||||
position: 2px 160px
|
||||
background: asset(zeus:inventory:inventory_wheel)
|
||||
background: zeus:inventory:inventory_wheel
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
|
|
Loading…
Reference in New Issue