Lua Defined structures - WIP, New UI Library, move Base from mods~
Refactor GUIBuilder and MenuSandbox Added outlined texturesmaster
parent
6579255b70
commit
4febca7ef8
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "base",
|
||||
"description": "Base definitions for Zepha.",
|
||||
"description": "Base definitions for the Zepha Engine.",
|
||||
"version": "1.0.0",
|
||||
"depends": []
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
local env = {}
|
||||
setmetatable(env, {__index = _G})
|
||||
|
||||
env.Gui = {}
|
||||
|
||||
local function create_gui_table(elem_type, data)
|
||||
local element = {}
|
||||
element.type = elem_type
|
||||
element.children = {}
|
||||
element.callbacks = {}
|
||||
element.traits = {}
|
||||
element.key = ""
|
||||
|
||||
for k, v in pairs(data) do
|
||||
if type(k) == "number" then
|
||||
table.insert(element.children, v)
|
||||
elseif k == "key" then
|
||||
element.key = v
|
||||
elseif k == "callbacks" then
|
||||
element.callbacks = v
|
||||
else
|
||||
element.traits[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return element
|
||||
end
|
||||
|
||||
env.Gui.Body = function(data) return create_gui_table("body", data) end
|
||||
env.Gui.Rect = function(data) return create_gui_table("rect", data) end
|
||||
env.Gui.Text = function(data) return create_gui_table("text", data) end
|
||||
env.Gui.Model = function(data) return create_gui_table("model", data) end
|
||||
env.Gui.Button = function(data) return create_gui_table("button", data) end
|
||||
env.Gui.InventoryList = function(data) return create_gui_table("inventory_list", data) end
|
||||
|
||||
env.pc = function(num)
|
||||
return tostring(num) .. "%"
|
||||
end
|
||||
|
||||
zepha.create_menu = function(fn)
|
||||
setfenv(fn, env)
|
||||
return fn()
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
-- Register base models (if not on main menu)
|
||||
if zepha.register_blockmodel then runfile(_PATH .. "models/_index") end
|
||||
|
||||
-- Load Libraries
|
||||
runfile(_PATH .. "dump")
|
||||
runfile(_PATH .. "math")
|
||||
runfile(_PATH .. "vector")
|
||||
runfile(_PATH .. "gui")
|
|
@ -320,6 +320,6 @@ set(ZEPHA_SRC
|
|||
game/inventory/InventoryList.h
|
||||
lua/api/modules/time.h
|
||||
util/net/PacketView.cpp
|
||||
util/net/PacketView.h)
|
||||
util/net/PacketView.h lua/api/modules/create_structure.h util/Any.h)
|
||||
|
||||
add_library (Zepha_Core ${ZEPHA_SRC})
|
|
@ -17,4 +17,5 @@
|
|||
|
||||
int main(int argc, char* argv[]) {
|
||||
return StartGame(argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,23 +5,26 @@
|
|||
#include "BiomeDef.h"
|
||||
|
||||
BiomeDef::BiomeDef(
|
||||
const std::string& identifier, unsigned int index, float temperature, float humidity, float roughness,
|
||||
unsigned int topBlock, unsigned int soilBlock, unsigned int rockBlock,
|
||||
const std::vector<noise::module::Module*>& heightmap, const std::vector<noise::module::Module*>& volume,
|
||||
glm::vec3 biomeTint) :
|
||||
const std::string& identifier, unsigned int index, float temperature, float humidity, float roughness,
|
||||
unsigned int topBlock, unsigned int soilBlock, unsigned int rockBlock,
|
||||
const std::vector<noise::module::Module*>& heightmap, const std::vector<noise::module::Module*>& volume,
|
||||
const std::vector<std::shared_ptr<Schematic>> schematics,
|
||||
glm::vec3 biomeTint) :
|
||||
|
||||
identifier(identifier),
|
||||
index(index),
|
||||
identifier(identifier),
|
||||
index(index),
|
||||
|
||||
temperature(temperature),
|
||||
humidity(humidity),
|
||||
roughness(roughness),
|
||||
temperature(temperature),
|
||||
humidity(humidity),
|
||||
roughness(roughness),
|
||||
|
||||
topBlock(topBlock),
|
||||
soilBlock(soilBlock),
|
||||
rockBlock(rockBlock),
|
||||
topBlock(topBlock),
|
||||
soilBlock(soilBlock),
|
||||
rockBlock(rockBlock),
|
||||
|
||||
heightmap(heightmap),
|
||||
volume(volume),
|
||||
heightmap(heightmap),
|
||||
volume(volume),
|
||||
|
||||
biomeTint(biomeTint) {}
|
||||
schematics(schematics),
|
||||
|
||||
biomeTint(biomeTint) {}
|
||||
|
|
|
@ -6,14 +6,18 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <glm/glm.hpp>
|
||||
#include <noise/module/modulebase.h>
|
||||
|
||||
#include "../../game/scene/world/Schematic.h"
|
||||
|
||||
struct BiomeDef {
|
||||
BiomeDef() = default;
|
||||
BiomeDef(const std::string& identifier, unsigned int index, float temperature, float humidity, float roughness,
|
||||
unsigned int topBlock, unsigned int soilBlock, unsigned int rockBlock,
|
||||
const std::vector<noise::module::Module*>& heightmap, const std::vector<noise::module::Module*>& volume,
|
||||
const std::vector<std::shared_ptr<Schematic>> schematics,
|
||||
glm::vec3 biomeTint);
|
||||
|
||||
std::string identifier = "";
|
||||
|
@ -30,5 +34,7 @@ struct BiomeDef {
|
|||
std::vector<noise::module::Module*> heightmap;
|
||||
std::vector<noise::module::Module*> volume;
|
||||
|
||||
std::vector<std::shared_ptr<Schematic>> schematics;
|
||||
|
||||
glm::vec3 biomeTint {};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
LocalBiomeAtlas::LocalBiomeAtlas() {
|
||||
//Invalid Biome
|
||||
BiomeDef* invalid = new BiomeDef("invalid", 0, -1, -1, -1, 0, 0, 0, {}, {}, {});
|
||||
BiomeDef* invalid = new BiomeDef("invalid", 0, -1, -1, -1, 0, 0, 0, {}, {}, {}, {});
|
||||
defs.push_back(invalid);
|
||||
defTable.insert({"invalid", 0});
|
||||
}
|
||||
|
|
|
@ -206,16 +206,16 @@ void MapGen::generateStructures(chunk_partials_map& chunks, chunk_partial& chunk
|
|||
std::default_random_engine generator(chunk.second->pos.x + chunk.second->pos.y * 30 + chunk.second->pos.z * 3.5);
|
||||
std::uniform_real_distribution<float> distribution(0, 1);
|
||||
|
||||
unsigned int cWood = defs.blockFromStr("zeus:default:wood").index;
|
||||
unsigned int cLeaves = defs.blockFromStr("zeus:default:leaves").index;
|
||||
unsigned int cAir = DefinitionAtlas::INVALID;
|
||||
// unsigned int cWood = defs.blockFromStr("zeus:default:wood").index;
|
||||
// unsigned int cLeaves = defs.blockFromStr("zeus:default:leaves").index;
|
||||
// unsigned int cAir = DefinitionAtlas::INVALID;
|
||||
|
||||
Schematic c {};
|
||||
c.dimensions = {3, 3, 3};
|
||||
c.origin = {1, 0, 1};
|
||||
c.blocks = { cAir, cAir, cAir, cAir, cLeaves, cAir, cAir, cAir, cAir,
|
||||
cAir, cWood, cAir, cLeaves, cWood, cLeaves, cAir, cLeaves, cAir,
|
||||
cAir, cAir, cAir, cAir, cLeaves, cAir, cAir, cAir, cAir };
|
||||
// Schematic c {};
|
||||
// c.dimensions = {3, 3, 3};
|
||||
// c.origin = {1, 0, 1};
|
||||
// c.blocks = { cAir, cAir, cAir, cAir, cLeaves, cAir, cAir, cAir, cAir,
|
||||
// cAir, cWood, cAir, cLeaves, cWood, cLeaves, cAir, cLeaves, cAir,
|
||||
// cAir, cAir, cAir, cAir, cLeaves, cAir, cAir, cAir, cAir };
|
||||
|
||||
glm::ivec3 wp = chunk.second->pos;
|
||||
glm::ivec3 lp;
|
||||
|
@ -234,9 +234,15 @@ void MapGen::generateStructures(chunk_partials_map& chunks, chunk_partial& chunk
|
|||
glm::ivec3 off = {};
|
||||
glm::ivec3 p = wp * 16 + lp;
|
||||
|
||||
for (unsigned int j = 0; j < c.length(); j++) {
|
||||
c.assignOffset(j, off);
|
||||
setBlock(p + off - c.origin, c.blocks[j], chunks);
|
||||
auto biome = biomes.biomeFromId(chunk.second->getBiome(ind));
|
||||
auto schematic = biome.schematics.size() > 0 ? biome.schematics[0] : nullptr;
|
||||
|
||||
if (schematic != nullptr) {
|
||||
if (!schematic->processed) schematic->process(defs);
|
||||
for (unsigned int j = 0; j < schematic->length(); j++) {
|
||||
schematic->assignOffset(j, off);
|
||||
setBlock(p + off - schematic->origin, schematic->blocks[j], chunks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
ServerBiomeAtlas::ServerBiomeAtlas() {
|
||||
//Invalid Biome
|
||||
BiomeDef* invalid = new BiomeDef("invalid", INVALID, -1, -1, -1, 0, 0, 0, {}, {}, {});
|
||||
BiomeDef* invalid = new BiomeDef("invalid", INVALID, -1, -1, -1, 0, 0, 0, {}, {}, {}, {});
|
||||
registerBiome(invalid);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,19 +44,19 @@ void GameGui::winResized(glm::ivec2 win) {
|
|||
menuBuilder.build(win);
|
||||
}
|
||||
|
||||
void GameGui::setMenu(const std::string& menu, const std::map<std::string, GuiBuilder::ComponentCallbacks>& callbacks) {
|
||||
menuState = "menu"; //TODO: Implement the menu state properly
|
||||
menuBuilder.setGui(menu, callbacks);
|
||||
void GameGui::buildMenu(sol::state_view state, sol::table menu) {
|
||||
menuBuilder.setGuiTable(state, menu);
|
||||
menuBuilder.build(win);
|
||||
inMenu = true;
|
||||
}
|
||||
|
||||
void GameGui::closeMenu() {
|
||||
menuBuilder.clear();
|
||||
menuState = "";
|
||||
inMenu = false;
|
||||
}
|
||||
|
||||
const std::string &GameGui::getMenuState() {
|
||||
return menuState;
|
||||
const bool GameGui::isInMenu() const {
|
||||
return inMenu;
|
||||
}
|
||||
|
||||
void GameGui::setVisible(bool visible) {
|
||||
|
|
|
@ -25,9 +25,9 @@ public:
|
|||
void setVisible(bool visible);
|
||||
bool isVisible();
|
||||
|
||||
void setMenu(const std::string& menu, const std::map<std::string, GuiBuilder::ComponentCallbacks>& callbacks);
|
||||
void buildMenu(sol::state_view state, sol::table menu);
|
||||
const bool isInMenu() const;
|
||||
void closeMenu();
|
||||
const std::string& getMenuState();
|
||||
|
||||
void drawHud(Renderer& renderer);
|
||||
void drawMenu(Renderer& renderer);
|
||||
|
@ -36,7 +36,7 @@ private:
|
|||
Renderer& renderer;
|
||||
|
||||
glm::ivec2 win {};
|
||||
std::string menuState = "";
|
||||
bool inMenu = false;
|
||||
|
||||
std::shared_ptr<GuiContainer> menuRoot = std::make_shared<GuiInventoryList>("menuRoot");
|
||||
std::shared_ptr<GuiContainer> menuLuaRoot = std::make_shared<GuiInventoryList>("menuLuaRoot");
|
||||
|
|
|
@ -2,36 +2,34 @@
|
|||
// Created by aurailus on 2019-12-12.
|
||||
//
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "GameGuiBuilder.h"
|
||||
|
||||
#include "components/compound/GuiInventoryList.h"
|
||||
|
||||
std::shared_ptr<GuiComponent> GameGuiBuilder::createComponent(SerialGui::Elem &data, glm::ivec2 bounds) {
|
||||
auto c = GuiBuilder::createComponent(data, bounds);
|
||||
std::shared_ptr<GuiComponent> GameGuiBuilder::createComponent(const SerialGui::Element& elem, glm::ivec2 bounds) {
|
||||
auto c = GuiBuilder::createComponent(elem, bounds);
|
||||
if (c != nullptr) return c;
|
||||
|
||||
GuiComponent::callback cbLeftClick = nullptr;
|
||||
GuiComponent::callback cbRightClick = nullptr;
|
||||
GuiComponent::callback cbHover = nullptr;
|
||||
|
||||
if (callbacks.count(data.key)) {
|
||||
cbLeftClick = callbacks[data.key].left;
|
||||
cbRightClick = callbacks[data.key].right;
|
||||
cbHover = callbacks[data.key].hover;
|
||||
}
|
||||
|
||||
switch (Util::hash(data.type.c_str())) {
|
||||
switch (Util::hash(elem.type.c_str())) {
|
||||
default: break;
|
||||
case Util::hash("inventory"): {
|
||||
c = GuiInventoryList::fromSerialized(data, game, bounds, refs);
|
||||
case Util::hash("inventory_list"): {
|
||||
c = GuiInventoryList::fromSerialized(elem, defs, bounds, refs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (c != nullptr) {
|
||||
c->setCallback(GuiComponent::CallbackType::PRIMARY, cbLeftClick);
|
||||
c->setCallback(GuiComponent::CallbackType::SECONDARY, cbRightClick);
|
||||
c->setCallback(GuiComponent::CallbackType::HOVER, cbHover);
|
||||
}
|
||||
if (!c) return nullptr;
|
||||
|
||||
if (elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::PRIMARY)])
|
||||
c->setCallback(GuiComponent::CallbackType::PRIMARY, elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::PRIMARY)]);
|
||||
|
||||
if (elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::SECONDARY)])
|
||||
c->setCallback(GuiComponent::CallbackType::SECONDARY, elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::SECONDARY)]);
|
||||
|
||||
if (elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::HOVER)])
|
||||
c->setCallback(GuiComponent::CallbackType::HOVER, elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::HOVER)]);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
class GameGuiBuilder : public GuiBuilder {
|
||||
public:
|
||||
GameGuiBuilder(LocalInventoryRefs& refs, ClientGame& defs, std::shared_ptr<GuiContainer> root) :
|
||||
refs(refs), GuiBuilder(defs, root) {};
|
||||
defs(defs), refs(refs), GuiBuilder(defs.textures, defs.models, root) {};
|
||||
|
||||
std::shared_ptr<GuiComponent> createComponent(SerialGui::Elem& data, glm::ivec2 bounds) override;
|
||||
std::shared_ptr<GuiComponent> createComponent(const SerialGui::Element& elem, glm::ivec2 bounds) override;
|
||||
private:
|
||||
LocalInventoryRefs& refs;
|
||||
ClientGame& defs;
|
||||
};
|
||||
|
|
|
@ -10,160 +10,150 @@
|
|||
#include "components/basic/GuiContainer.h"
|
||||
#include "components/compound/GuiImageButton.h"
|
||||
|
||||
GuiBuilder::GuiBuilder(ClientGame& defs, std::shared_ptr<GuiContainer> root) :
|
||||
game(defs), root(root) {}
|
||||
GuiBuilder::GuiBuilder(TextureAtlas& textures, ModelStore& models, std::shared_ptr<GuiContainer> root) :
|
||||
textures(textures), models(models), root(root) {}
|
||||
|
||||
void GuiBuilder::setGui(const std::string& menu, const std::map<std::string, ComponentCallbacks>& callbacks) {
|
||||
this->callbacks = callbacks;
|
||||
deserialize(menu);
|
||||
void GuiBuilder::setGuiTable(sol::state_view state, sol::table menu) {
|
||||
keyInd = 0;
|
||||
serialized = rDeserialize(state, menu);
|
||||
}
|
||||
|
||||
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;
|
||||
std::string::size_type prev = 0;
|
||||
SerialGui::Element GuiBuilder::rDeserialize(sol::state_view state, sol::table menu) {
|
||||
std::string type = menu.get<std::string>("type");
|
||||
std::string key = (menu.get<sol::optional<std::string>>("key") ? menu.get<std::string>("key") : "__UNKEYED_COMPONENT_" + std::to_string(keyInd++));
|
||||
|
||||
while ((pos = menu.find('\n', prev)) != std::string::npos) {
|
||||
std::string sub = menu.substr(prev, pos - prev);
|
||||
std::string::size_type start = sub.find_first_not_of("\t\v\r ");
|
||||
if (start == std::string::npos) start = 0;
|
||||
std::string::size_type end = sub.find_last_not_of("\t\v\r ");
|
||||
SerialGui::Element element(type, key);
|
||||
|
||||
sub = sub.substr(start, end - start + 1);
|
||||
if (sub.substr(0, 2) != "--" && !sub.empty()) lines.push_back(sub);
|
||||
prev = pos + 1;
|
||||
for (auto trait : menu.get<sol::table>("traits")) {
|
||||
auto key = trait.first.as<std::string>();
|
||||
if (trait.second.is<std::string>()) {
|
||||
element.addTrait(key, Any::from<std::string>(trait.second.as<std::string>()));
|
||||
}
|
||||
else if (trait.second.is<sol::table>()) {
|
||||
if (trait.second.as<sol::table>().size() == 2) {
|
||||
auto x = trait.second.as<sol::table>().get<sol::object>(1);
|
||||
auto y = trait.second.as<sol::table>().get<sol::object>(2);
|
||||
|
||||
glm::vec2 values = {};
|
||||
if (x.is<float>()) values.x = x.as<float>();
|
||||
else if (x.is<std::string>()) values.x = SerialGui::toDouble(x.as<std::string>());
|
||||
if (y.is<float>()) values.y = y.as<float>();
|
||||
else if (y.is<std::string>()) values.y = SerialGui::toDouble(y.as<std::string>());
|
||||
|
||||
element.addTrait(key, Any::from<glm::vec2>(values));
|
||||
}
|
||||
else if (trait.second.as<sol::table>().size() == 4) {
|
||||
auto x = trait.second.as<sol::table>().get<sol::object>(1);
|
||||
auto y = trait.second.as<sol::table>().get<sol::object>(2);
|
||||
auto z = trait.second.as<sol::table>().get<sol::object>(3);
|
||||
auto w = trait.second.as<sol::table>().get<sol::object>(4);
|
||||
|
||||
glm::vec4 values = {};
|
||||
if (x.is<float>()) values.x = x.as<float>();
|
||||
else if (x.is<std::string>()) values.x = SerialGui::toDouble(x.as<std::string>());
|
||||
if (y.is<float>()) values.y = y.as<float>();
|
||||
else if (y.is<std::string>()) values.y = SerialGui::toDouble(y.as<std::string>());
|
||||
if (z.is<float>()) values.z = z.as<float>();
|
||||
else if (z.is<std::string>()) values.z = SerialGui::toDouble(z.as<std::string>());
|
||||
if (w.is<float>()) values.w = w.as<float>();
|
||||
else if (w.is<std::string>()) values.w = SerialGui::toDouble(w.as<std::string>());
|
||||
|
||||
element.addTrait(key, Any::from<glm::vec4>(values));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
components.clear();
|
||||
unsigned int keyInd = 0;
|
||||
std::vector<SerialGui::Elem*> stack {};
|
||||
SerialGui::Elem* component = nullptr;
|
||||
auto callbacks = menu.get<sol::optional<sol::table>>("callbacks");
|
||||
if (callbacks) {
|
||||
if (callbacks->get<sol::optional<sol::function>>("primary"))
|
||||
element.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::PRIMARY)] = [=](bool down, glm::ivec2 pos) {
|
||||
callbacks->get<sol::function>("primary")(down, LuaParser::luaVec(state, {pos.x, pos.y, 0})); };
|
||||
|
||||
// Parse through the serialized structure and create the Serialized tree
|
||||
for (const std::string& line : lines) {
|
||||
if (line.find(':') != std::string::npos) {
|
||||
// A Property
|
||||
if (component == nullptr) throw "expected a component name before a property";
|
||||
if (callbacks->get<sol::optional<sol::function>>("secondary"))
|
||||
element.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::SECONDARY)] = [=](bool down, glm::ivec2 pos) {
|
||||
callbacks->get<sol::function>("secondary")(down, LuaParser::luaVec(state, {pos.x, pos.y, 0})); };
|
||||
|
||||
std::string::size_type delimiter = line.find(':');
|
||||
|
||||
std::string name = line.substr(0, delimiter);
|
||||
std::string::size_type start = name.find_first_not_of("\t\v\r ");
|
||||
if (start == std::string::npos) start = 0;
|
||||
std::string::size_type end = name.find_last_not_of("\t\v\r ");
|
||||
name = name.substr(start, end - start + 1);
|
||||
|
||||
std::string value = line.substr(delimiter + 1, std::string::npos);
|
||||
start = value.find_first_not_of("\t\v\r ");
|
||||
if (start == std::string::npos) start = 0;
|
||||
end = value.find_last_not_of("\t\v\r ");
|
||||
value = value.substr(start, end - start + 1);
|
||||
|
||||
component->tokens.emplace(name, value);
|
||||
}
|
||||
else if (line != "end") {
|
||||
// Beginning of a component definition
|
||||
std::string key = "";
|
||||
std::string::size_type keyStart;
|
||||
std::string::size_type keyEnd;
|
||||
if ((keyStart = line.find('[')) != std::string::npos &&
|
||||
(keyEnd = line.find_last_of(']')) != std::string::npos && keyEnd > keyStart) {
|
||||
key = line.substr(keyStart + 1, keyEnd - keyStart - 1);
|
||||
}
|
||||
else {
|
||||
// Create an implicit key because one was not specified
|
||||
key = "__" + std::to_string(keyInd++);
|
||||
}
|
||||
|
||||
std::string type = line.substr(0, keyStart);
|
||||
SerialGui::Elem g {type, key, {}, {}};
|
||||
|
||||
if (component == nullptr) {
|
||||
components.push_back(std::move(g));
|
||||
component = &components[components.size() - 1];
|
||||
}
|
||||
else {
|
||||
component->children.push_back(std::move(g));
|
||||
stack.push_back(component);
|
||||
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;
|
||||
}
|
||||
if (callbacks->get<sol::optional<sol::function>>("hover"))
|
||||
element.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::HOVER)] = [=](bool down, glm::ivec2 pos) {
|
||||
callbacks->get<sol::function>("hover")(down, LuaParser::luaVec(state, {pos.x, pos.y, 0})); };
|
||||
}
|
||||
|
||||
|
||||
auto children = menu.get<sol::optional<sol::table>>("children");
|
||||
if (children) for (auto& pair : *children) element.children.push_back(rDeserialize(state, pair.second.as<sol::table>()));
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
void GuiBuilder::build(glm::ivec2 winBounds) {
|
||||
clear(false);
|
||||
recursivelyCreate(components, root, winBounds);
|
||||
if (serialized.type != "")
|
||||
rCreate(serialized, root, winBounds);
|
||||
}
|
||||
|
||||
void GuiBuilder::clear(bool clrCallbacks) {
|
||||
if (clrCallbacks) callbacks.clear();
|
||||
void GuiBuilder::clear(bool deleteRoot) {
|
||||
rClearCallbacks(root);
|
||||
root->empty();
|
||||
if (deleteRoot) serialized = {"", ""};
|
||||
}
|
||||
|
||||
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, bounds);
|
||||
if (component == nullptr) continue;
|
||||
parent->add(component);
|
||||
recursivelyCreate(data.children, component, component->getScale());
|
||||
void GuiBuilder::rCreate(const SerialGui::Element& element, std::shared_ptr<GuiComponent> parent, glm::ivec2 bounds) {
|
||||
auto component = createComponent(element, bounds);
|
||||
if (!component) throw std::runtime_error("GuiBuilder failed to create component: " + element.key);
|
||||
parent->add(component);
|
||||
|
||||
for (auto& child : element.children) rCreate(child, component, component->getScale());
|
||||
}
|
||||
|
||||
void GuiBuilder::rClearCallbacks(std::shared_ptr<GuiComponent> component) {
|
||||
component->setCallback(GuiComponent::CallbackType::PRIMARY, nullptr);
|
||||
component->setCallback(GuiComponent::CallbackType::SECONDARY, nullptr);
|
||||
component->setCallback(GuiComponent::CallbackType::HOVER, nullptr);
|
||||
|
||||
for (auto& child : component->getChildren()) {
|
||||
rClearCallbacks(child);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<GuiComponent> GuiBuilder::createComponent(SerialGui::Elem& data, glm::ivec2 bounds) {
|
||||
std::shared_ptr<GuiComponent> GuiBuilder::createComponent(const SerialGui::Element& elem, glm::ivec2 bounds) {
|
||||
std::shared_ptr<GuiComponent> c = nullptr;
|
||||
|
||||
GuiComponent::callback cbLeftClick = nullptr;
|
||||
GuiComponent::callback cbRightClick = nullptr;
|
||||
GuiComponent::callback cbHover = nullptr;
|
||||
|
||||
if (callbacks.count(data.key)) {
|
||||
cbLeftClick = callbacks[data.key].left;
|
||||
cbRightClick = callbacks[data.key].right;
|
||||
cbHover = callbacks[data.key].hover;
|
||||
}
|
||||
|
||||
switch (Util::hash(data.type.c_str())) {
|
||||
switch (Util::hash(elem.type.c_str())) {
|
||||
default: break;
|
||||
case Util::hash("body"): {
|
||||
auto body = GuiRect::fromSerialized(data, game, bounds);
|
||||
auto body = GuiRect::fromSerialized(elem, textures, bounds);
|
||||
body->setScale(bounds);
|
||||
c = body;
|
||||
break;
|
||||
}
|
||||
case Util::hash("rect"):
|
||||
c = GuiRect::fromSerialized(data, game, bounds);
|
||||
c = GuiRect::fromSerialized(elem, textures, bounds);
|
||||
break;
|
||||
case Util::hash("button"):
|
||||
c = GuiImageButton::fromSerialized(data, game, bounds);
|
||||
c = GuiImageButton::fromSerialized(elem, textures, bounds);
|
||||
break;
|
||||
case Util::hash("text"):
|
||||
c = GuiText::fromSerialized(data, game, bounds);
|
||||
c = GuiText::fromSerialized(elem, textures, bounds);
|
||||
break;
|
||||
case Util::hash("model"):
|
||||
c = GuiModel::fromSerialized(data, game, bounds);
|
||||
c = GuiModel::fromSerialized(elem, textures, models, bounds);
|
||||
break;
|
||||
}
|
||||
|
||||
if (c != nullptr) {
|
||||
c->setCallback(GuiComponent::CallbackType::PRIMARY, cbLeftClick);
|
||||
c->setCallback(GuiComponent::CallbackType::SECONDARY, cbRightClick);
|
||||
c->setCallback(GuiComponent::CallbackType::HOVER, cbHover);
|
||||
}
|
||||
if (!c) return nullptr;
|
||||
|
||||
if (elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::PRIMARY)])
|
||||
c->setCallback(GuiComponent::CallbackType::PRIMARY, elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::PRIMARY)]);
|
||||
|
||||
if (elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::SECONDARY)])
|
||||
c->setCallback(GuiComponent::CallbackType::SECONDARY, elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::SECONDARY)]);
|
||||
|
||||
if (elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::HOVER)])
|
||||
c->setCallback(GuiComponent::CallbackType::HOVER, elem.callbacks[static_cast<unsigned int>(GuiComponent::CallbackType::HOVER)]);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
GuiBuilder::~GuiBuilder() {
|
||||
clear(true);
|
||||
clear();
|
||||
}
|
||||
|
|
|
@ -14,21 +14,23 @@ class GuiBuilder {
|
|||
public:
|
||||
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 clear(bool clrCallbacks = true);
|
||||
GuiBuilder(TextureAtlas& textures, ModelStore& models, std::shared_ptr<GuiContainer> root);
|
||||
void setGuiTable(sol::state_view state, const sol::table menu);
|
||||
void build(glm::ivec2 winBounds);
|
||||
void clear(bool deleteRoot = true);
|
||||
|
||||
~GuiBuilder();
|
||||
|
||||
protected:
|
||||
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);
|
||||
SerialGui::Element rDeserialize(sol::state_view state, sol::table menu);
|
||||
void rCreate(const SerialGui::Element& element, std::shared_ptr<GuiComponent> parent, glm::ivec2 bounds);
|
||||
static void rClearCallbacks(std::shared_ptr<GuiComponent> component);
|
||||
virtual std::shared_ptr<GuiComponent> createComponent(const SerialGui::Element& elem, glm::ivec2 bounds);
|
||||
|
||||
std::map<std::string, ComponentCallbacks> callbacks;
|
||||
TextureAtlas& textures;
|
||||
ModelStore& models;
|
||||
|
||||
ClientGame& game;
|
||||
std::shared_ptr<GuiContainer> root;
|
||||
std::vector<SerialGui::Elem> components {};
|
||||
std::shared_ptr<GuiContainer> root = nullptr;
|
||||
|
||||
SerialGui::Element serialized = {"", ""};
|
||||
unsigned int keyInd = 0;
|
||||
};
|
||||
|
|
|
@ -15,13 +15,42 @@
|
|||
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <sol2/sol.hpp>
|
||||
#include "../../util/Any.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace SerialGui {
|
||||
struct Elem {
|
||||
class Element {
|
||||
public:
|
||||
Element(const std::string& type, const std::string& key) : type(type), key(key) {};
|
||||
|
||||
std::string type;
|
||||
std::string key;
|
||||
std::map<std::string, std::string> tokens;
|
||||
std::vector<SerialGui::Elem> children;
|
||||
|
||||
void addTrait(const std::string& key, const Any& any) {
|
||||
traits.emplace(key, any);
|
||||
}
|
||||
|
||||
template <typename T> const T& get(const std::string& key) const {
|
||||
if (!traits.count(key)) throw std::logic_error("Key missing from table");
|
||||
return traits.at(key).get<T>();
|
||||
}
|
||||
|
||||
template <typename T> const T& get_or(const std::string& key, const T& other) const noexcept {
|
||||
if (!traits.count(key)) return other;
|
||||
return traits.at(key).get_or<T>(other);
|
||||
}
|
||||
|
||||
template <typename T> const bool has(const std::string& key) const noexcept {
|
||||
if (!traits.count(key)) return false;
|
||||
return traits.at(key).is<T>();
|
||||
}
|
||||
|
||||
std::array<std::function<void(bool, glm::ivec2)>, 3> callbacks = {{nullptr, nullptr, nullptr}};
|
||||
std::vector<SerialGui::Element> children {};
|
||||
private:
|
||||
std::map<std::string, Any> traits {};
|
||||
};
|
||||
|
||||
const float SCALE_MODIFIER = 3;
|
||||
|
@ -51,46 +80,43 @@ namespace SerialGui {
|
|||
return std::move(vec);
|
||||
}
|
||||
|
||||
static double toDouble(const std::string& input, unsigned int multiple) {
|
||||
static double toDouble(const std::string& input) {
|
||||
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;
|
||||
return v - 10.f; // Percentages are going to be stored in negatives. Ew.
|
||||
}
|
||||
|
||||
double v = std::strtod(input.c_str(), &e);
|
||||
double v = round(std::strtod(input.c_str(), &e));
|
||||
if (*e != '\0' || errno != 0) throw std::runtime_error("error decoding num from string");
|
||||
return v;
|
||||
}
|
||||
|
||||
static double convertNum(float input, unsigned int multiple) {
|
||||
if (input >= -20 && input < 0) {
|
||||
if (!multiple) return input + 10;
|
||||
else return (((input + 10) * multiple / SCALE_MODIFIER) * SCALE_MODIFIER);
|
||||
}
|
||||
|
||||
return input * SCALE_MODIFIER;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static T deserialize(const std::string& in, glm::ivec2 multiple = {}) {};
|
||||
template <typename T> static T calcNumbers(const T 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 <typename T> static T get(const SerialGui::Element& elem, const std::string& req, glm::ivec2 multiple = {}) {
|
||||
if (!elem.has<T>(req)) return T{};
|
||||
return calcNumbers<T>(elem.get<T>(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::vec2 calcNumbers<glm::vec2>(const glm::vec2 in, glm::ivec2 multiple) {
|
||||
return {convertNum(in.x, multiple.x), convertNum(in.y, 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)};
|
||||
template <> glm::vec4 calcNumbers<glm::vec4>(const glm::vec4 in, glm::ivec2 multiple) {
|
||||
return {convertNum(in.x, multiple.x), convertNum(in.y, multiple.y), convertNum(in.z, multiple.x), convertNum(in.w, multiple.y)};
|
||||
}
|
||||
};
|
|
@ -170,4 +170,8 @@ void GuiComponent::updatePos() {
|
|||
for (const auto& child : children) {
|
||||
child->updatePos();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<GuiComponent>> GuiComponent::getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
std::shared_ptr<GuiComponent> insert(unsigned int index, std::shared_ptr<GuiComponent> component);
|
||||
std::shared_ptr<GuiComponent> add(std::shared_ptr<GuiComponent> component);
|
||||
|
||||
std::list<std::shared_ptr<GuiComponent>> getChildren();
|
||||
|
||||
void remove(const std::string& key);
|
||||
void empty();
|
||||
|
||||
|
|
|
@ -5,23 +5,24 @@
|
|||
#include "GuiModel.h"
|
||||
|
||||
#include "../../../../def/ClientGame.h"
|
||||
#include "../../../../def/model/ModelStore.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");
|
||||
std::shared_ptr<GuiModel> GuiModel::fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, ModelStore& models, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
|
||||
glm::vec2 scale = SerialGui::get<glm::vec2>(elem, "scale");
|
||||
glm::vec2 anim_range = SerialGui::get<glm::vec2>(elem, "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"];
|
||||
std::string type = elem.get_or<std::string>("type", "model");
|
||||
std::string source = elem.get_or<std::string>("source", "");
|
||||
std::string texture = elem.get_or<std::string>("texture", "");
|
||||
|
||||
auto m = std::make_shared<Model>();
|
||||
if (type == "model") m->fromSerialized(game.models.models[source], {game.textures[texture]});
|
||||
if (type == "model") m->fromSerialized(models.models[source], {textures[texture]});
|
||||
|
||||
auto model = std::make_shared<GuiModel>(s.key);
|
||||
auto model = std::make_shared<GuiModel>(elem.key);
|
||||
model->create(scale, m);
|
||||
model->setPos(pos);
|
||||
|
||||
|
|
|
@ -11,13 +11,14 @@
|
|||
#include "../../SerialGui.h"
|
||||
|
||||
class ClientGame;
|
||||
class ModelStore;
|
||||
|
||||
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);
|
||||
static std::shared_ptr<GuiModel> fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, ModelStore& models, glm::ivec2 bounds);
|
||||
|
||||
void create(glm::vec2 scale, std::shared_ptr<Model> model);
|
||||
void update(double delta) override;
|
||||
|
|
|
@ -10,22 +10,21 @@
|
|||
|
||||
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);
|
||||
std::shared_ptr<GuiRect> GuiRect::fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
|
||||
glm::vec2 size = SerialGui::get<glm::vec2>(elem, "size", bounds);
|
||||
glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "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 = elem.get_or<std::string>("background", "");
|
||||
bool hideOverflow = elem.get_or<std::string>("overflow", "visible") == "hidden";
|
||||
|
||||
bool hideOverflow = s.tokens["overflow"] == "hidden";
|
||||
|
||||
auto rect = std::make_shared<GuiRect>(s.key);
|
||||
auto rect = std::make_shared<GuiRect>(elem.key);
|
||||
if (background[0] == '#') rect->create(size, padding, Util::hexToColorVec(background));
|
||||
else if (background.size() > 0) rect->create(size, padding, game.textures[background]);
|
||||
else if (background.size() > 0) rect->create(size, padding, textures[background]);
|
||||
else rect->create(size, padding, glm::vec4 {});
|
||||
rect->setOverflows(!hideOverflow);
|
||||
rect->setPos(pos);
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
GuiRect() = default;
|
||||
GuiRect(const std::string& key);
|
||||
|
||||
static std::shared_ptr<GuiRect> fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds);
|
||||
static std::shared_ptr<GuiRect> fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, 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);
|
||||
|
|
|
@ -23,32 +23,22 @@ 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");
|
||||
std::shared_ptr<GuiText> GuiText::fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
|
||||
glm::vec2 size = SerialGui::get<glm::vec2>(elem, "size", bounds);
|
||||
glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
|
||||
glm::vec2 scale = SerialGui::get<glm::vec2>(elem, "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"]);
|
||||
glm::vec4 background_color = Util::hexToColorVec(elem.get_or<std::string>("background", "#0000"));
|
||||
glm::vec4 color = Util::hexToColorVec(elem.get_or<std::string>("color", "#fff"));
|
||||
std::string content = elem.get_or<std::string>("content", "");
|
||||
|
||||
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"]});
|
||||
auto text = std::make_shared<GuiText>(elem.key);
|
||||
text->create(scale * SerialGui::SCALE_MODIFIER, padding, background_color, color, {textures, textures["font"]});
|
||||
text->setText(content);
|
||||
text->setPos(pos);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ public:
|
|||
GuiText() = default;
|
||||
explicit GuiText(const std::string& key);
|
||||
|
||||
static std::shared_ptr<GuiText> fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds);
|
||||
static std::shared_ptr<GuiText> fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, glm::ivec2 bounds);
|
||||
|
||||
void create(glm::vec2 scale, glm::vec4 padding, glm::vec4 bgcolor, glm::vec4 color, Font font);
|
||||
|
||||
|
|
|
@ -9,37 +9,29 @@
|
|||
|
||||
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);
|
||||
std::shared_ptr<GuiImageButton> GuiImageButton::fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, glm::ivec2 bounds) {
|
||||
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "position_anchor");
|
||||
glm::vec2 size = SerialGui::get<glm::vec2>(elem, "size", bounds);
|
||||
glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "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 background = elem.get_or<std::string>("background", "");
|
||||
std::string background_hover = elem.get_or<std::string>("background_hover", background);
|
||||
|
||||
bool hideOverflow = s.tokens["overflow"] == "hidden";
|
||||
bool hideOverflow = elem.get_or<std::string>("overflow", "visible") == "hidden";
|
||||
std::string content = elem.get_or<std::string>("content", "");
|
||||
|
||||
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]);
|
||||
auto button = std::make_shared<GuiImageButton>(elem.key);
|
||||
button->create(size, padding, textures[background], textures[background_hover]);
|
||||
button->setOverflows(!hideOverflow);
|
||||
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"]});
|
||||
auto text = std::make_shared<GuiText>(elem.key + "__TEXT");
|
||||
text->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding, {}, {1, 1, 1, 1}, {textures, textures["font"]});
|
||||
text->setPos({6 * SerialGui::SCALE_MODIFIER, size.y / 2 - 4.5 * SerialGui::SCALE_MODIFIER});
|
||||
text->setText(content);
|
||||
button->add(text);
|
||||
|
|
|
@ -11,7 +11,7 @@ public:
|
|||
GuiImageButton() = default;
|
||||
GuiImageButton(const std::string& key);
|
||||
|
||||
static std::shared_ptr<GuiImageButton> fromSerialized(SerialGui::Elem s, ClientGame& game, glm::ivec2 bounds);
|
||||
static std::shared_ptr<GuiImageButton> fromSerialized(const SerialGui::Element& elem, TextureAtlas& textures, glm::ivec2 bounds);
|
||||
|
||||
void create(glm::vec2 scale, glm::vec4 padding, std::shared_ptr<AtlasRef> texture, std::shared_ptr<AtlasRef> hoverTexture);
|
||||
|
||||
|
|
|
@ -9,20 +9,20 @@
|
|||
#include "../../../../def/texture/Font.h"
|
||||
GuiInventoryList::GuiInventoryList(const std::string &key) : GuiContainer(key) {}
|
||||
|
||||
std::shared_ptr<GuiInventoryList> GuiInventoryList::fromSerialized(SerialGui::Elem s, ClientGame &game,
|
||||
std::shared_ptr<GuiInventoryList> GuiInventoryList::fromSerialized(SerialGui::Element elem, ClientGame &game,
|
||||
glm::ivec2 bounds, LocalInventoryRefs& refs) {
|
||||
|
||||
glm::vec2 pos = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::deserializeToken<glm::vec2>(s.tokens, "position_anchor");
|
||||
glm::vec2 pos = SerialGui::get<glm::vec2>(elem, "position", bounds);
|
||||
glm::vec2 offset = SerialGui::get<glm::vec2>(elem, "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);
|
||||
glm::vec4 padding = SerialGui::get<glm::vec4>(elem, "padding", bounds);
|
||||
glm::vec2 slotspc = SerialGui::get<glm::vec2>(elem, "slot_spacing", bounds);
|
||||
|
||||
std::string source = s.tokens["source"];
|
||||
std::string list = s.tokens["list"];
|
||||
std::string source = elem.get_or<std::string>("source", "");
|
||||
std::string list = elem.get_or<std::string>("list", "");
|
||||
|
||||
auto invList = refs.getList(source, list);
|
||||
auto inv = std::make_shared<GuiInventoryList>(s.key);
|
||||
auto inv = std::make_shared<GuiInventoryList>(elem.key);
|
||||
|
||||
inv->create(glm::vec2(SerialGui::SCALE_MODIFIER), padding * SerialGui::SCALE_MODIFIER,
|
||||
slotspc * SerialGui::SCALE_MODIFIER, invList, refs.getHand(), game);
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
GuiInventoryList(const std::string& key);
|
||||
~GuiInventoryList() override;
|
||||
|
||||
static std::shared_ptr<GuiInventoryList> fromSerialized(SerialGui::Elem s, ClientGame &game,
|
||||
static std::shared_ptr<GuiInventoryList> fromSerialized(SerialGui::Element elem, ClientGame &game,
|
||||
glm::ivec2 bounds, LocalInventoryRefs& refs);
|
||||
|
||||
void create(glm::vec2 scale, glm::vec4 padding, glm::ivec2 innerPadding,
|
||||
|
|
|
@ -7,44 +7,49 @@
|
|||
#include "../../../lua/api/menu/mDelay.h"
|
||||
#include "../../../lua/api/menu/mSetGui.h"
|
||||
#include "../../../lua/api/menu/mStartGame.h"
|
||||
#include "../../../lua/ErrorFormatter.h"
|
||||
|
||||
MenuSandbox::MenuSandbox(glm::ivec2 &win, ClientState& state, std::shared_ptr<GuiContainer> container) :
|
||||
win(win),
|
||||
state(state),
|
||||
container(container),
|
||||
builder(state.defs, container) {}
|
||||
win(win),
|
||||
state(state),
|
||||
container(container),
|
||||
builder(state.defs.textures, state.defs.models, container) {}
|
||||
|
||||
void MenuSandbox::setup() {
|
||||
void MenuSandbox::reset() {
|
||||
builder.clear(true);
|
||||
delayed_functions.clear();
|
||||
core = {};
|
||||
mod = {};
|
||||
lua = sol::state {};
|
||||
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table);
|
||||
|
||||
loadApi();
|
||||
}
|
||||
|
||||
void MenuSandbox::loadApi() {
|
||||
//Create Zepha Table
|
||||
core = lua.create_table();
|
||||
lua["zepha"] = core;
|
||||
core["__builtin"] = lua.create_table();
|
||||
|
||||
//Sandbox the dofile function
|
||||
MenuApi::delay (core, delayed_functions);
|
||||
MenuApi::set_gui (builder, win, lua, core);
|
||||
MenuApi::start_game (state, core);
|
||||
|
||||
// Create sandboxed runfile()
|
||||
lua["dofile"] = lua["loadfile"] = sol::nil;
|
||||
lua.set_function("runfile", &MenuSandbox::DoFileSandboxed, this);
|
||||
|
||||
MenuApi::delay(core, delayed_functions);
|
||||
MenuApi::set_gui(builder, win, lua, core);
|
||||
MenuApi::start_game(state, core);
|
||||
lua.set_function("runfile", &MenuSandbox::runFileSandboxed, this);
|
||||
}
|
||||
|
||||
void MenuSandbox::load(const Subgame& subgame) {
|
||||
builder.clear();
|
||||
setup();
|
||||
reset();
|
||||
|
||||
try {
|
||||
loadMod(subgame.subgamePath + "/menu");
|
||||
DoFileSandboxed("init");
|
||||
loadAndRunMod(subgame.subgamePath + "/../../assets/base");
|
||||
loadAndRunMod(subgame.subgamePath + "/menu");
|
||||
}
|
||||
catch (const std::string& e) {
|
||||
std::cout << Log::err <<
|
||||
"Encountered an error loading menu mod for subgame '" + subgame.config.name + "':\n\t"
|
||||
<< e << Log::endl;
|
||||
std::cout << Log::err << "Encountered an error loading menu mod for subgame '" + subgame.config.name + "':\n\t" << e << Log::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,32 +57,24 @@ void MenuSandbox::windowResized() {
|
|||
builder.build(win);
|
||||
}
|
||||
|
||||
sol::protected_function_result MenuSandbox::DoFileSandboxed(const std::string& file) {
|
||||
sol::protected_function_result MenuSandbox::runFileSandboxed(const std::string& file) {
|
||||
for (LuaModFile& f : mod.files) {
|
||||
if (f.path == file) {
|
||||
|
||||
sol::environment env(lua, sol::create, lua.globals());
|
||||
env["_PATH"] = f.path.substr(0, f.path.find_last_of('/') + 1);
|
||||
env["_FILE"] = f.path;
|
||||
env["_MODNAME"] = mod.config.name;
|
||||
|
||||
auto pfr = lua.safe_script(f.file, env, [&](lua_State*, sol::protected_function_result errPfr) {
|
||||
sol::error err = errPfr;
|
||||
std::cout << Log::err << file << " returned an error: " << err.what() << Log::endl;
|
||||
return errPfr;
|
||||
}, "@" + f.path, sol::load_mode::text);
|
||||
|
||||
return pfr;
|
||||
return lua.safe_script(f.file, env, std::bind(&MenuSandbox::errorCallback, this,
|
||||
std::placeholders::_2), "@" + f.path, sol::load_mode::text);
|
||||
}
|
||||
}
|
||||
|
||||
throw std::string("Error executing file '" + file + "', file not found.");
|
||||
}
|
||||
|
||||
void MenuSandbox::loadMod(const std::string &modPath) {
|
||||
void MenuSandbox::loadAndRunMod(const std::string &modPath) {
|
||||
if (!cf_file_exists(modPath.data())) throw std::string("Directory not found.");
|
||||
|
||||
mod = LuaMod {};
|
||||
LuaMod mod;
|
||||
std::string root = modPath + "/script";
|
||||
|
||||
std::list<std::string> dirsToScan {root};
|
||||
|
@ -133,4 +130,33 @@ void MenuSandbox::loadMod(const std::string &modPath) {
|
|||
if (cf_file_exists(texPath.data())) {
|
||||
this->modAssets = state.defs.textures.loadDirectory(texPath, false, true);
|
||||
}
|
||||
|
||||
this->mod = mod;
|
||||
runFileSandboxed("main");
|
||||
}
|
||||
|
||||
sol::protected_function_result MenuSandbox::errorCallback(sol::protected_function_result errPfr) {
|
||||
sol::error err = errPfr;
|
||||
std::string errString = err.what();
|
||||
|
||||
try {
|
||||
std::string::size_type lineNumStart = errString.find(':');
|
||||
assert(lineNumStart != std::string::npos);
|
||||
std::string::size_type lineNumEnd = errString.find(':', lineNumStart + 1);
|
||||
assert(lineNumEnd != std::string::npos);
|
||||
|
||||
std::string fileName = errString.substr(0, lineNumStart);
|
||||
int lineNum = std::stoi(errString.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1));
|
||||
|
||||
for (LuaModFile &f : mod.files) {
|
||||
if (f.path == fileName) {
|
||||
std::cout << std::endl << ErrorFormatter::formatError(fileName, lineNum, errString, f.file) << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
std::cout << std::endl << Log::err << errString << Log::endl;
|
||||
}
|
||||
exit(1);
|
||||
}
|
|
@ -23,15 +23,19 @@ public:
|
|||
|
||||
using LuaParser::update;
|
||||
private:
|
||||
void setup();
|
||||
void loadMod(const std::string& modPath);
|
||||
void reset();
|
||||
void loadApi();
|
||||
void executeMods();
|
||||
void loadAndRunMod(const std::string& modPath);
|
||||
|
||||
sol::protected_function_result DoFileSandboxed(const std::string& file);
|
||||
sol::protected_function_result runFileSandboxed(const std::string& file);
|
||||
sol::protected_function_result errorCallback(sol::protected_function_result errPfr);
|
||||
|
||||
LuaMod mod {};
|
||||
std::vector<std::shared_ptr<AtlasRef>> modAssets {};
|
||||
|
||||
std::shared_ptr<GuiContainer> container = nullptr;
|
||||
|
||||
ClientState& state;
|
||||
GuiBuilder builder;
|
||||
glm::ivec2& win;
|
||||
|
|
|
@ -276,8 +276,8 @@ void Player::setActiveBlock(const std::string& block) {
|
|||
handItemModel.setModel(defs.defs.fromId(activeBlock).entityModel);
|
||||
}
|
||||
|
||||
void Player::setMenu(const std::string& menu, const std::map<std::string, GuiBuilder::ComponentCallbacks>& callbacks) {
|
||||
gameGui.setMenu(menu, callbacks);
|
||||
void Player::buildMenu(sol::state_view state, sol::table menu) {
|
||||
gameGui.buildMenu(state, menu);
|
||||
renderer.window.lockMouse(false);
|
||||
}
|
||||
|
||||
|
@ -290,8 +290,8 @@ void Player::setGuiVisible(bool hudVisible) {
|
|||
gameGui.setVisible(hudVisible);
|
||||
}
|
||||
|
||||
std::string Player::getMenuState() {
|
||||
return gameGui.getMenuState();
|
||||
bool Player::isInMenu() {
|
||||
return gameGui.isInMenu();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -43,9 +43,9 @@ public:
|
|||
|
||||
void setActiveBlock(const std::string& block);
|
||||
|
||||
void setMenu(const std::string& menu, const std::map<std::string, GuiBuilder::ComponentCallbacks>& callbacks);
|
||||
std::string getMenuState();
|
||||
void buildMenu(sol::state_view state, sol::table menu);
|
||||
void closeMenu();
|
||||
bool isInMenu();
|
||||
void setGuiVisible(bool hudVisible);
|
||||
|
||||
void draw(Renderer& renderer) override;
|
||||
|
|
|
@ -3,3 +3,29 @@
|
|||
//
|
||||
|
||||
#include "Schematic.h"
|
||||
|
||||
#include "../../../def/DefinitionAtlas.h"
|
||||
|
||||
void Schematic::process(DefinitionAtlas& atlas) {
|
||||
blocks.reserve(stringData.size());
|
||||
|
||||
for (auto& string : stringData) {
|
||||
blocks.push_back(atlas.blockFromStr(string).index);
|
||||
}
|
||||
|
||||
stringData.clear();
|
||||
stringData.shrink_to_fit();
|
||||
|
||||
processed = true;
|
||||
}
|
||||
|
||||
void Schematic::assignOffset(int ind, glm::ivec3& vec) {
|
||||
vec.z = ind / (dimensions.x * dimensions.y);
|
||||
ind -= (vec.z * dimensions.x * dimensions.y);
|
||||
vec.y = ind / dimensions.z;
|
||||
vec.x = ind % dimensions.x;
|
||||
}
|
||||
|
||||
unsigned int Schematic::index(const glm::ivec3& vec) {
|
||||
return static_cast<unsigned int>(vec.x + dimensions.x * (vec.y + dimensions.y * vec.z));
|
||||
}
|
|
@ -5,25 +5,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
class DefinitionAtlas;
|
||||
|
||||
struct Schematic {
|
||||
std::vector<std::string> stringData {};
|
||||
bool processed = false;
|
||||
|
||||
std::vector<unsigned int> blocks {};
|
||||
glm::ivec3 dimensions {};
|
||||
glm::ivec3 origin {};
|
||||
|
||||
// inline unsigned int index(const glm::ivec3& vec) {
|
||||
// return static_cast<unsigned int>(vec.x + dimensions.x * (vec.y + dimensions.y * vec.z));
|
||||
// }
|
||||
void process(DefinitionAtlas& atlas);
|
||||
|
||||
inline unsigned int length() {
|
||||
return blocks.size();
|
||||
}
|
||||
inline unsigned int length() { return blocks.size(); }
|
||||
|
||||
inline void assignOffset(int ind, glm::ivec3& vec) {
|
||||
vec.z = ind / (dimensions.x * dimensions.y);
|
||||
ind -= ((int)vec.z * dimensions.x * dimensions.y);
|
||||
vec.y = ind / dimensions.y;
|
||||
vec.x = ind % dimensions.z;
|
||||
}
|
||||
void assignOffset(int ind, glm::ivec3& vec);
|
||||
unsigned int index(const glm::ivec3& vec);
|
||||
};
|
||||
|
|
|
@ -18,10 +18,10 @@ class LuaParser {
|
|||
public:
|
||||
constexpr static double UPDATE_STEP {1 / 60.0};
|
||||
|
||||
static inline void override_panic(sol::optional<std::string> message) {
|
||||
std::cout << Log::err << "Zepha has panicked! Error:" << Log::endl;
|
||||
if (message) std::cout << Log::err << message.value() << Log::endl;
|
||||
}
|
||||
// static inline void override_panic(sol::optional<std::string> message) {
|
||||
// std::cout << Log::err << "Zepha has panicked! Error:" << Log::endl;
|
||||
// if (message) std::cout << Log::err << message.value() << Log::endl;
|
||||
// }
|
||||
|
||||
struct DelayedFunction {
|
||||
sol::function function;
|
||||
|
|
|
@ -43,39 +43,12 @@ float LocalLuaPlayer::get_look_pitch() {
|
|||
return player.getPitch();
|
||||
}
|
||||
|
||||
std::string LocalLuaPlayer::get_menu_state() {
|
||||
return player.getMenuState();
|
||||
bool LocalLuaPlayer::is_in_menu() {
|
||||
return player.isInMenu();
|
||||
}
|
||||
|
||||
void LocalLuaPlayer::open_menu(sol::this_state s, std::string menu, sol::optional<sol::table> callbacks) {
|
||||
if (callbacks) {
|
||||
std::map<std::string, GuiBuilder::ComponentCallbacks> callbackMap;
|
||||
|
||||
for (auto& pair : *callbacks) {
|
||||
if (!pair.first.is<std::string>() || !pair.second.is<sol::table>()) continue;
|
||||
std::string identifier = pair.first.as<std::string>();
|
||||
sol::table callbacks = pair.second.as<sol::table>();
|
||||
GuiBuilder::ComponentCallbacks componentCallbacks {};
|
||||
|
||||
auto left = callbacks.get<sol::optional<sol::function>>("left");
|
||||
auto right = callbacks.get<sol::optional<sol::function>>("right");
|
||||
auto hover = callbacks.get<sol::optional<sol::function>>("hover");
|
||||
|
||||
if (left) componentCallbacks.left = [=](bool down, glm::ivec2 pos) {
|
||||
(*left)(down, sol::state_view(s).create_table_with("x", pos.x, "y", pos.y)); };
|
||||
|
||||
if (right) componentCallbacks.right = [=](bool down, glm::ivec2 pos) {
|
||||
(*right)(down, sol::state_view(s).create_table_with("x", pos.x, "y", pos.y)); };
|
||||
|
||||
if (hover) componentCallbacks.hover = [=](bool down, glm::ivec2 pos) {
|
||||
(*hover)(down, sol::state_view(s).create_table_with("x", pos.x, "y", pos.y)); };
|
||||
|
||||
callbackMap.emplace(identifier, componentCallbacks);
|
||||
}
|
||||
|
||||
player.setMenu(menu, callbackMap);
|
||||
}
|
||||
else player.setMenu(menu, {});
|
||||
void LocalLuaPlayer::show_menu(sol::this_state s, sol::table menu) {
|
||||
player.buildMenu(s, menu);
|
||||
}
|
||||
|
||||
void LocalLuaPlayer::close_menu() {
|
||||
|
|
|
@ -29,9 +29,9 @@ public:
|
|||
void set_look_pitch(float rot);
|
||||
float get_look_pitch();
|
||||
|
||||
std::string get_menu_state();
|
||||
bool is_in_menu();
|
||||
void close_menu();
|
||||
void open_menu(sol::this_state s, std::string menu, sol::optional<sol::table> callbacks);
|
||||
void show_menu(sol::this_state s, sol::table menu);
|
||||
|
||||
LocalLuaInventory get_inventory();
|
||||
|
||||
|
|
|
@ -9,35 +9,8 @@
|
|||
|
||||
namespace MenuApi {
|
||||
void set_gui(GuiBuilder& builder, glm::ivec2& win, sol::state& lua, sol::table& core) {
|
||||
core.set_function("set_gui", [&](std::string gui, sol::optional<sol::table> callbacks) {
|
||||
if (callbacks) {
|
||||
std::map<std::string, GuiBuilder::ComponentCallbacks> callbackMap;
|
||||
|
||||
for (auto& pair : *callbacks) {
|
||||
if (!pair.first.is<std::string>() || !pair.second.is<sol::table>()) continue;
|
||||
std::string identifier = pair.first.as<std::string>();
|
||||
sol::table callbacks = pair.second.as<sol::table>();
|
||||
GuiBuilder::ComponentCallbacks componentCallbacks {};
|
||||
|
||||
auto left = callbacks.get<sol::optional<sol::function>>("left");
|
||||
auto right = callbacks.get<sol::optional<sol::function>>("right");
|
||||
auto hover = callbacks.get<sol::optional<sol::function>>("hover");
|
||||
|
||||
if (left) componentCallbacks.left = [=, &lua](bool down, glm::ivec2 pos) {
|
||||
(*left)(down, lua.create_table_with("x", pos.x, "y", pos.y)); };
|
||||
|
||||
if (right) componentCallbacks.right = [=, &lua](bool down, glm::ivec2 pos) {
|
||||
(*right)(down, lua.create_table_with("x", pos.x, "y", pos.y)); };
|
||||
|
||||
if (hover) componentCallbacks.hover = [=, &lua](bool down, glm::ivec2 pos) {
|
||||
(*hover)(down, lua.create_table_with("x", pos.x, "y", pos.y)); };
|
||||
|
||||
callbackMap.emplace(identifier, componentCallbacks);
|
||||
}
|
||||
|
||||
builder.setGui(gui, callbackMap);
|
||||
}
|
||||
else builder.setGui(gui);
|
||||
core.set_function("set_gui", [&](sol::this_state s, sol::table gui) {
|
||||
builder.setGuiTable(sol::state_view(s), gui);
|
||||
builder.build(win);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// Created by aurailus on 2020-03-15.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sol2/sol.hpp>
|
||||
#include "../../../game/scene/world/Schematic.h"
|
||||
|
||||
namespace Api {
|
||||
static void create_structure(sol::state& lua, sol::table& core) {
|
||||
core.set_function("create_structure", [&](sol::optional<sol::table> data) {
|
||||
if (!data) throw "expected a table as the first argument.";
|
||||
|
||||
auto origin = data->get<sol::optional<sol::table>>("origin");
|
||||
auto schematic = data->get<sol::optional<sol::table>>("schematic");
|
||||
|
||||
if (!origin) throw "expected a table as the first argument.";
|
||||
if (!schematic) throw "expected a table as the first argument.";
|
||||
|
||||
auto s = std::make_shared<Schematic>();
|
||||
|
||||
unsigned int yWid = schematic->size();
|
||||
unsigned int zWid = (*schematic).get<sol::table>(1).size();
|
||||
unsigned int xWid = (*schematic).get<sol::table>(1).get<sol::table>(1).size();
|
||||
|
||||
s->dimensions = {xWid, yWid, zWid};
|
||||
s->stringData.resize(xWid * yWid * zWid);
|
||||
|
||||
s->origin = {origin->get<unsigned int>(1), origin->get<unsigned int>(2), origin->get<unsigned int>(3)};
|
||||
|
||||
for (unsigned int y = 1; y <= yWid; y++) {
|
||||
for (unsigned int z = 1; z <= zWid; z++) {
|
||||
for (unsigned int x = 1; x <= xWid; x++) {
|
||||
s->stringData[s->index({x - 1, y - 1, z - 1})] =
|
||||
schematic->get<sol::table>(y).get<sol::table>(z).get_or<std::string>(x, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ namespace ClientApi {
|
|||
"get_inventory", &LocalLuaPlayer::get_inventory,
|
||||
"set_selected_block", &LocalLuaPlayer::set_selected_block,
|
||||
|
||||
"open_menu", &LocalLuaPlayer::open_menu,
|
||||
"show_menu", &LocalLuaPlayer::show_menu,
|
||||
"close_menu", &LocalLuaPlayer::close_menu,
|
||||
|
||||
"pos", sol::property(&LocalLuaPlayer::get_pos, &LocalLuaPlayer::set_pos),
|
||||
|
@ -34,7 +34,7 @@ namespace ClientApi {
|
|||
|
||||
"flying", sol::property(&LocalLuaPlayer::set_flying, &LocalLuaPlayer::get_flying),
|
||||
|
||||
"menu_state", sol::property(&LocalLuaPlayer::get_menu_state)
|
||||
"in_menu", sol::property(&LocalLuaPlayer::is_in_menu)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@
|
|||
#include "../api/modules/remove_entity.h"
|
||||
#include "../api/modules/register_keybind.h"
|
||||
#include "../api/modules/time.h"
|
||||
#include "../api/modules/create_structure.h"
|
||||
|
||||
// Functions
|
||||
#include "../api/functions/trigger_event.h"
|
||||
|
@ -97,6 +98,8 @@ void LocalLuaParser::loadApi(ClientGame &defs, LocalWorld &world, Player& player
|
|||
|
||||
Api::time(lua, core);
|
||||
|
||||
Api::create_structure (lua, core);
|
||||
|
||||
// Functions
|
||||
Api::update_entities(lua);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "../api/modules/add_entity.h"
|
||||
#include "../api/modules/remove_entity.h"
|
||||
#include "../api/modules/time.h"
|
||||
#include "../api/modules/create_structure.h"
|
||||
|
||||
// Functions
|
||||
#include "../api/functions/trigger_event.h"
|
||||
|
@ -130,6 +131,8 @@ void ServerLuaParser::loadApi(ServerGame &defs, ServerWorld &world) {
|
|||
|
||||
Api::time(lua, core);
|
||||
|
||||
Api::create_structure (lua, core);
|
||||
|
||||
// Functions
|
||||
Api::trigger_event (lua);
|
||||
Api::update_entities(lua);
|
||||
|
|
|
@ -41,7 +41,7 @@ const std::vector<LuaMod>& ServerModHandler::cGetMods() const {
|
|||
}
|
||||
|
||||
std::list<std::string> ServerModHandler::findModDirectories(const std::string& path) {
|
||||
std::list<std::string> modDirs {};
|
||||
std::list<std::string> modDirs {path + "/../../../assets/base"};
|
||||
std::list<std::string> dirsToScan {path};
|
||||
|
||||
cf_dir_t dir;
|
||||
|
|
|
@ -300,6 +300,11 @@ namespace RegisterBiomes {
|
|||
heightmapModules.push_back(new noise::module::Const);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Schematic>> schematics {};
|
||||
if (biomeTable.get<sol::optional<sol::table>>("structures"))
|
||||
for (auto s : biomeTable.get<sol::table>("structures"))
|
||||
schematics.push_back(s.second.as<std::shared_ptr<Schematic>>());
|
||||
|
||||
// Create biome definition
|
||||
BiomeDef* biomeDef = new BiomeDef(
|
||||
identifier, biomes.size(),
|
||||
|
@ -309,6 +314,7 @@ namespace RegisterBiomes {
|
|||
defs.blockFromStr(*bRock).index,
|
||||
heightmapModules,
|
||||
volumeModules,
|
||||
schematics,
|
||||
glm::vec3(Util::hexToColorVec((*biomeTint)))
|
||||
);
|
||||
|
||||
|
|
|
@ -125,25 +125,31 @@ void Server::handlePlayerPacket(ServerClient& client, PacketView& p) {
|
|||
if (block == DefinitionAtlas::AIR) {
|
||||
auto def = defs.defs.blockFromId(worldBlock);
|
||||
if (def.callbacks.count(Callback::BREAK)) def.callbacks[Callback::BREAK](defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "break", defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "break",
|
||||
defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
}
|
||||
else {
|
||||
auto def = defs.defs.blockFromId(block);
|
||||
if (def.callbacks.count(Callback::PLACE)) def.callbacks[Callback::PLACE](defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "place", defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "place",
|
||||
defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
}
|
||||
|
||||
world.setBlock(pos, block);
|
||||
|
||||
if (block == DefinitionAtlas::AIR) {
|
||||
auto def = defs.defs.blockFromId(worldBlock);
|
||||
if (def.callbacks.count(Callback::AFTER_BREAK)) def.callbacks[Callback::AFTER_BREAK](defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "after_break", defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
if (def.callbacks.count(Callback::AFTER_BREAK)) def.callbacks[Callback::AFTER_BREAK](
|
||||
defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "after_break",
|
||||
defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
}
|
||||
else {
|
||||
auto def = defs.defs.blockFromId(block);
|
||||
if (def.callbacks.count(Callback::AFTER_PLACE)) def.callbacks[Callback::AFTER_PLACE](defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "after_place", defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
if (def.callbacks.count(Callback::AFTER_PLACE)) def.callbacks[Callback::AFTER_PLACE](
|
||||
defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
defs.parser.safe_function(defs.parser.core["__builtin"]["trigger_event"], "after_place",
|
||||
defs.parser.luaVec(pos), ServerLuaPlayer(client));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include "WorldGenStream.h"
|
||||
#include "../conn/ClientList.h"
|
||||
#include "../../def/ServerGame.h"
|
||||
|
|
|
@ -20,24 +20,28 @@ public:
|
|||
}
|
||||
|
||||
template <typename T, typename T_ = T> void set(T_&& val) {
|
||||
type = typeid(T).hash_code();
|
||||
|
||||
if (sizeof(T) <= STACK_SIZE) {
|
||||
new(data.s) T(std::forward<T_>(val));
|
||||
stack_destructor = std::bind(&Any::delete_stack<T_>, this);
|
||||
}
|
||||
else {
|
||||
isEmpty = false;
|
||||
// if (sizeof(T) < STACK_SIZE) {
|
||||
// data.h = nullptr;
|
||||
// new(data.s) T(std::forward<T_>(val));
|
||||
// stack_destructor = std::bind(&Any::delete_stack<T>, this);
|
||||
// type = typeid(T).hash_code();
|
||||
// }
|
||||
// else {
|
||||
if (stack_destructor) stack_destructor();
|
||||
data.h = std::make_shared<T>(std::forward<T_>(val));
|
||||
stack_destructor = nullptr;
|
||||
}
|
||||
type = typeid(T).hash_code();
|
||||
// }
|
||||
}
|
||||
|
||||
template<typename T> const T& get() const {
|
||||
if (empty()) throw std::logic_error("Tried to get empty Any.");
|
||||
if (type != typeid(T).hash_code()) throw std::logic_error("Any is not of type specified.");
|
||||
|
||||
if (sizeof(T) <= STACK_SIZE) return *reinterpret_cast<T*>(const_cast<char*>(data.s));
|
||||
else return *std::static_pointer_cast<T>(data.h);
|
||||
// if (sizeof(T) < STACK_SIZE) return *reinterpret_cast<T*>(const_cast<char*>(data.s));
|
||||
// else
|
||||
return *std::static_pointer_cast<T>(data.h);
|
||||
}
|
||||
|
||||
template<typename T> const T& get_or(const T& other) const noexcept {
|
||||
|
@ -46,16 +50,18 @@ public:
|
|||
}
|
||||
|
||||
template <typename T> const bool is() const noexcept {
|
||||
return typeid(T).hash_code() == type;
|
||||
size_t hash = typeid(T).hash_code();
|
||||
return hash == type;
|
||||
}
|
||||
|
||||
bool const empty() const noexcept {
|
||||
return type == 0;
|
||||
return isEmpty;
|
||||
}
|
||||
|
||||
void reset() noexcept {
|
||||
if (stack_destructor) stack_destructor();
|
||||
data.h = nullptr;
|
||||
stack_destructor = nullptr;
|
||||
isEmpty = true;
|
||||
type = 0;
|
||||
}
|
||||
|
||||
|
@ -66,16 +72,19 @@ public:
|
|||
private:
|
||||
template <typename T> void delete_stack() {
|
||||
reinterpret_cast<T*>(data.s)->~T();
|
||||
stack_destructor = nullptr;
|
||||
type = 0;
|
||||
}
|
||||
|
||||
bool isEmpty = true;
|
||||
std::size_t type = 0;
|
||||
std::function<void()> stack_destructor = nullptr;
|
||||
|
||||
union Data {
|
||||
char s[STACK_SIZE];
|
||||
alignas(16) char s[STACK_SIZE];
|
||||
std::shared_ptr<void> h;
|
||||
|
||||
Data() { this->h = nullptr; }
|
||||
Data() : h(nullptr) {}
|
||||
Data(const Data& o) { memcpy(this->s, o.s, STACK_SIZE); }
|
||||
~Data() {};
|
||||
} data {};
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
zepha.set_gui([[
|
||||
body
|
||||
background: #214a21
|
||||
|
||||
text[name]
|
||||
position: 4px 4px
|
||||
content: "Minimal Subgame Base"
|
||||
end
|
||||
end
|
||||
]])
|
|
@ -0,0 +1,12 @@
|
|||
local menu = zepha.create_menu(function()
|
||||
return Gui.Body {
|
||||
background = "#214a21",
|
||||
|
||||
Gui.Text {
|
||||
position = { 4, 4 },
|
||||
content = "Minimal Subgame"
|
||||
}
|
||||
}
|
||||
end)
|
||||
|
||||
zepha.set_gui(menu)
|
|
@ -1,10 +0,0 @@
|
|||
zepha.set_gui([[
|
||||
body
|
||||
background: #124778
|
||||
|
||||
text[name]
|
||||
position: 4px 4px
|
||||
content: "Parentheses"
|
||||
end
|
||||
end
|
||||
]])
|
|
@ -0,0 +1,10 @@
|
|||
zepha.set_gui(zepha.create_menu(function()
|
||||
return Gui.Body {
|
||||
background = "#124778",
|
||||
|
||||
Gui.Text {
|
||||
position = { 4, 4 },
|
||||
content = "Parentheses"
|
||||
}
|
||||
}
|
||||
end))
|
|
@ -1,46 +0,0 @@
|
|||
zepha.set_gui([[
|
||||
body
|
||||
background: zeus_background
|
||||
|
||||
rect[sidebar]
|
||||
position: 20% 0
|
||||
position_anchor: 50% 0
|
||||
size: 102px 100%
|
||||
background: #0135
|
||||
|
||||
rect[logo]
|
||||
position: 8px 8px
|
||||
size: 86px 30px
|
||||
background: zeus_logo
|
||||
end
|
||||
|
||||
button[buttonPlay]
|
||||
position: 6px 50px
|
||||
size: 90px 20px
|
||||
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: crop(0, 0, 90, 20, zeus_button)
|
||||
background_hover: crop(0, 20, 90, 20, zeus_button)
|
||||
content: "Browse Servers"
|
||||
end
|
||||
end
|
||||
end
|
||||
]], {
|
||||
buttonPlay = {
|
||||
-- TODO: Change left/right notation to primary/secondary.
|
||||
left = function()
|
||||
zepha.start_game_local()
|
||||
end
|
||||
},
|
||||
buttonServers = {
|
||||
left = function()
|
||||
zepha.start_game()
|
||||
end
|
||||
}
|
||||
})
|
|
@ -0,0 +1,52 @@
|
|||
zepha.set_gui(zepha.create_menu(function()
|
||||
return Gui.Body {
|
||||
background = "zeus_background",
|
||||
|
||||
Gui.Rect {
|
||||
key = "sidebar",
|
||||
position = { pc(20), 0 },
|
||||
position_anchor = { pc(50), 0 },
|
||||
size = { 102, pc(100) },
|
||||
background = "#0135",
|
||||
|
||||
Gui.Rect {
|
||||
key = "logo",
|
||||
position = { 8, 8 },
|
||||
size = { 86, 30 },
|
||||
background = "zeus_logo"
|
||||
},
|
||||
|
||||
Gui.Button {
|
||||
key = "buttonPlay",
|
||||
|
||||
callbacks = {
|
||||
primary = function()
|
||||
zepha.start_game_local()
|
||||
end
|
||||
},
|
||||
|
||||
position = { 6, 50 },
|
||||
size = { 90, 20 },
|
||||
background = "crop(0, 0, 90, 20, zeus_button)",
|
||||
background_hover = "crop(0, 20, 90, 20, zeus_button)",
|
||||
content = "Local Play"
|
||||
},
|
||||
|
||||
Gui.Button {
|
||||
key = "buttonServers",
|
||||
|
||||
callbacks = {
|
||||
primary = function()
|
||||
zepha.start_game()
|
||||
end
|
||||
},
|
||||
|
||||
position = { 6, 74 },
|
||||
size = { 90, 20 },
|
||||
background = "crop(0, 0, 90, 20, zeus_button)",
|
||||
background_hover = "crop(0, 20, 90, 20, zeus_button)",
|
||||
content = "Browse Servers"
|
||||
}
|
||||
}
|
||||
}
|
||||
end))
|
|
@ -1,10 +0,0 @@
|
|||
-- Register base models
|
||||
runfile(_PATH .. "models/_index")
|
||||
|
||||
-- Load Libraries
|
||||
runfile(_PATH .. "dump")
|
||||
runfile(_PATH .. "math")
|
||||
runfile(_PATH .. "vector")
|
||||
|
||||
-- Signal completion
|
||||
print("Base definitions loaded.")
|
|
@ -3,7 +3,7 @@ local menu = zepha.create_menu(function()
|
|||
background = "#0003",
|
||||
|
||||
callbacks = {
|
||||
primary = zepha.player:close_menu
|
||||
primary = function() zepha.player:close_menu() end,
|
||||
},
|
||||
|
||||
Gui.Rect {
|
||||
|
@ -70,7 +70,6 @@ local menu = zepha.create_menu(function()
|
|||
size = { 214, 67 },
|
||||
background = "zeus:inventory:inventory_wheel",
|
||||
|
||||
children = {
|
||||
Gui.InventoryList {
|
||||
position = { 9, 1 },
|
||||
slot_spacing = { 2, 2 },
|
||||
|
@ -112,15 +111,14 @@ local menu = zepha.create_menu(function()
|
|||
}
|
||||
end)
|
||||
|
||||
-- Register the inventory menu and keybind
|
||||
zepha.register_keybind("zeus:inventory:open_inventory", {
|
||||
description = "Open Inventory",
|
||||
default = zepha.keys.e,
|
||||
on_press = function()
|
||||
if (zepha.player.menu_state == "") then
|
||||
zepha.player:open_menu(menu)
|
||||
if not zepha.player.in_menu then
|
||||
zepha.player:show_menu(menu)
|
||||
else
|
||||
zepha.player:close_menu()
|
||||
end
|
||||
}
|
||||
})
|
||||
end
|
||||
})
|
|
@ -1,125 +0,0 @@
|
|||
## Register the inventory menu and keybind
|
||||
zepha.register_keybind("zeus:inventory:open_inventory", {
|
||||
description = "Open Inventory",
|
||||
default = zepha.keys.e,
|
||||
on_press = () => {
|
||||
if (zepha.player.menu_state == "") {
|
||||
zepha.player:open_menu([[
|
||||
body[body]
|
||||
background: #0003
|
||||
|
||||
rect[inventory]
|
||||
position: 50% 50%
|
||||
position_anchor: 50% 55%
|
||||
size: 218px 160px
|
||||
|
||||
rect[inv_background]
|
||||
position: 0px 45px
|
||||
size: 218px 100px
|
||||
padding: 20px 10px 8px 10px
|
||||
background: zeus:inventory:inventory
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
list: main
|
||||
position: 1px 1px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
end
|
||||
|
||||
rect[craft_background]
|
||||
size: 218px 72px
|
||||
position: 0px -15px
|
||||
padding: 20px 10px 8px 10px
|
||||
background: zeus:inventory:crafting
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
list: craft
|
||||
position: 111px 1px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
list: craft_result
|
||||
position: 163px 10px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
|
||||
rect[player_clamp]
|
||||
position: 41px -8px
|
||||
size: 34px 52px
|
||||
overflow: hidden
|
||||
|
||||
model
|
||||
scale: 86 86
|
||||
position: 15px 52px
|
||||
type: model
|
||||
source: zeus:default:player
|
||||
texture: zeus:default:player
|
||||
anim_range: 0 300
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
rect[hot_wheel]
|
||||
size: 214px 67px
|
||||
position: 2px 160px
|
||||
background: zeus:inventory:inventory_wheel
|
||||
|
||||
inventory
|
||||
source: current_player
|
||||
list: hot_wheel_1
|
||||
position: 9px 1px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
inventory
|
||||
source: current_player
|
||||
list: hot_wheel_2
|
||||
position: 117px 1px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
inventory
|
||||
source: current_player
|
||||
list: hot_wheel_3
|
||||
position: 125px 25px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
inventory
|
||||
source: current_player
|
||||
list: hot_wheel_4
|
||||
position: 117px 50px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
inventory
|
||||
source: current_player
|
||||
list: hot_wheel_5
|
||||
position: 9px 50px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
inventory
|
||||
source: current_player
|
||||
list: hot_wheel_6
|
||||
position: 1px 25px
|
||||
slot_spacing: 2px 2px
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
]], {
|
||||
body = {
|
||||
left = fn() {
|
||||
zepha.player:close_menu()
|
||||
}
|
||||
},
|
||||
inv_background = {
|
||||
left = fn() {} ## Prevent close menu from triggering.
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
zepha.player:close_menu()
|
||||
}
|
||||
}
|
||||
})
|
|
@ -1,3 +1,4 @@
|
|||
runfile(_PATH .. "plains")
|
||||
runfile(_PATH .. "highlands")
|
||||
runfile(_PATH .. "desert")
|
||||
runfile(_PATH .. "desert")
|
||||
runfile(_PATH .. "forest")
|
|
@ -0,0 +1,127 @@
|
|||
local noise = {
|
||||
heightmap = {
|
||||
module = "add",
|
||||
sources = {{
|
||||
## Elevation
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.002,
|
||||
octaves = 8
|
||||
},
|
||||
scale = 250,
|
||||
bias = -32
|
||||
}, {
|
||||
## Features
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.2,
|
||||
octaves = 3,
|
||||
},
|
||||
scale = 6,
|
||||
bias = 6
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
local woo = "zeus:default:wood"
|
||||
local lea = "zeus:default:leaves"
|
||||
local inv = "invalid"
|
||||
|
||||
local trunk_layer_0 = {
|
||||
{ inv, inv, inv, inv, inv },
|
||||
{ inv, woo, woo, woo, inv },
|
||||
{ inv, woo, woo, woo, inv },
|
||||
{ inv, woo, woo, woo, inv },
|
||||
{ inv, inv, inv, inv, inv }
|
||||
}
|
||||
|
||||
local trunk_layer_1 = {
|
||||
{ inv, inv, inv, inv, inv },
|
||||
{ inv, inv, woo, inv, inv },
|
||||
{ inv, woo, woo, woo, inv },
|
||||
{ inv, inv, woo, inv, inv },
|
||||
{ inv, inv, inv, inv, inv }
|
||||
}
|
||||
|
||||
local trunk_layer_2 = {
|
||||
{ inv, inv, inv, inv, inv },
|
||||
{ inv, inv, inv, inv, inv },
|
||||
{ inv, inv, woo, inv, inv },
|
||||
{ inv, inv, inv, inv, inv },
|
||||
{ inv, inv, inv, inv, inv }
|
||||
}
|
||||
|
||||
local leaf_layer_1 = {
|
||||
{ inv, lea, lea, lea, inv },
|
||||
{ lea, lea, lea, lea, lea },
|
||||
{ lea, lea, woo, lea, lea },
|
||||
{ lea, lea, lea, lea, lea },
|
||||
{ inv, lea, lea, lea, inv }
|
||||
}
|
||||
|
||||
local leaf_layer_2 = {
|
||||
{ inv, inv, inv, inv, inv },
|
||||
{ inv, lea, lea, lea, inv },
|
||||
{ inv, lea, woo, lea, inv },
|
||||
{ inv, lea, lea, lea, inv },
|
||||
{ inv, inv, inv, inv, inv }
|
||||
}
|
||||
|
||||
local leaf_layer_3 = {
|
||||
{ inv, inv, inv, inv, inv },
|
||||
{ inv, lea, lea, inv, inv },
|
||||
{ inv, lea, lea, lea, inv },
|
||||
{ inv, inv, lea, lea, inv },
|
||||
{ inv, inv, inv, inv, inv }
|
||||
}
|
||||
|
||||
local tree = zepha.create_structure({
|
||||
origin = V(2, 2, 2),
|
||||
schematic = {
|
||||
trunk_layer_0,
|
||||
trunk_layer_0,
|
||||
trunk_layer_0,
|
||||
trunk_layer_0,
|
||||
trunk_layer_1,
|
||||
trunk_layer_1,
|
||||
trunk_layer_1,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
trunk_layer_2,
|
||||
leaf_layer_2,
|
||||
leaf_layer_1,
|
||||
leaf_layer_1,
|
||||
leaf_layer_1,
|
||||
leaf_layer_1,
|
||||
leaf_layer_2,
|
||||
leaf_layer_3
|
||||
}
|
||||
})
|
||||
|
||||
zepha.register_biome("zeus:mapgen:forest", {
|
||||
environment = {
|
||||
temperature = 15/100,
|
||||
humidity = 80/100,
|
||||
roughness = 20/100,
|
||||
},
|
||||
blocks = {
|
||||
top = "zeus:default:grass",
|
||||
soil = "zeus:default:dirt",
|
||||
rock = "zeus:default:stone"
|
||||
},
|
||||
biome_tint = "#7beb26",
|
||||
noise = noise,
|
||||
structures = {
|
||||
tree
|
||||
}
|
||||
})
|
|
@ -1,3 +1,61 @@
|
|||
local noise = {
|
||||
heightmap = {
|
||||
module = "add",
|
||||
sources = {{
|
||||
## Elevation
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.002,
|
||||
octaves = 8
|
||||
},
|
||||
scale = 250,
|
||||
bias = -32
|
||||
}, {
|
||||
## Features
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.2,
|
||||
octaves = 3,
|
||||
},
|
||||
scale = 6,
|
||||
bias = 6
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
local woo = "zeus:default:wood"
|
||||
local lea = "zeus:default:leaves"
|
||||
local inv = "invalid"
|
||||
|
||||
local shrub_layer_0 = {
|
||||
{ inv, inv, inv },
|
||||
{ inv, woo, inv },
|
||||
{ inv, inv, inv }
|
||||
}
|
||||
|
||||
local shrub_layer_1 = {
|
||||
{ inv, lea, inv },
|
||||
{ lea, woo, lea },
|
||||
{ inv, lea, inv }
|
||||
}
|
||||
|
||||
local shrub_layer_2 = {
|
||||
{ inv, inv, inv },
|
||||
{ inv, lea, inv },
|
||||
{ inv, inv, inv }
|
||||
}
|
||||
|
||||
local shrub = zepha.create_structure({
|
||||
origin = V(1, 1, 1),
|
||||
schematic = {
|
||||
shrub_layer_0,
|
||||
shrub_layer_1,
|
||||
shrub_layer_2,
|
||||
}
|
||||
})
|
||||
|
||||
local noise = {
|
||||
volume = {
|
||||
module = "add",
|
||||
|
@ -48,5 +106,8 @@ zepha.register_biome("zeus:mapgen:highlands", {
|
|||
rock = "zeus:default:stone"
|
||||
},
|
||||
biome_tint = "#e6fa61",
|
||||
noise = noise
|
||||
noise = noise,
|
||||
structures = {
|
||||
shrub
|
||||
}
|
||||
})
|
|
@ -28,7 +28,7 @@ local noise = {
|
|||
zepha.register_biome("zeus:mapgen:plains", {
|
||||
environment = {
|
||||
temperature = 15/100,
|
||||
humidity = 80/100,
|
||||
humidity = 60/100,
|
||||
roughness = 20/100,
|
||||
},
|
||||
blocks = {
|
||||
|
@ -37,5 +37,8 @@ zepha.register_biome("zeus:mapgen:plains", {
|
|||
rock = "zeus:default:stone"
|
||||
},
|
||||
biome_tint = "#aaed45",
|
||||
noise = noise
|
||||
noise = noise,
|
||||
structures = {
|
||||
tree
|
||||
}
|
||||
})
|
Binary file not shown.
After Width: | Height: | Size: 662 B |
Binary file not shown.
After Width: | Height: | Size: 555 B |
Binary file not shown.
After Width: | Height: | Size: 736 B |
Binary file not shown.
After Width: | Height: | Size: 387 B |
Binary file not shown.
After Width: | Height: | Size: 526 B |
Loading…
Reference in New Issue