Connect Scene, Error Scene, stability, bugfixes

master
Auri 2021-08-23 23:31:29 -07:00
parent 7285ba71f4
commit 1c58797480
63 changed files with 600 additions and 786 deletions

View File

@ -1,13 +1,12 @@
zepha.player:set_hud(zepha.build_gui(function()
return Gui.Body {
zepha.player:set_hud(zepha.gui(function()
return Gui.Box {
background = "base:viginette",
Gui.Rect {
key = "crosshair",
Gui.Box {
-- id = "crosshair",
position = { pc(50), pc(50) },
position_anchor = { pc(50), pc(50) },
size = { 22 / 3, 22 / 3 },
size = { "22dp", "22dp" },
pos = { "50cw - 50sw", "50ch - 50sh" },
background = "base:crosshair"
}

View File

@ -1,6 +1,6 @@
runfile(_PATH .. "models/init")
runfile(_PATH .. "player_interact")
runfile(_PATH .. "inventory")
runfile(_PATH .. "tools")
require(_PATH .. "models/init")
require(_PATH .. "player_interact")
require(_PATH .. "inventory")
require(_PATH .. "tools")
if zepha.client then runfile(_PATH .. "hud") end
if zepha.client then require(_PATH .. "hud") end

View File

@ -1,8 +1,8 @@
runfile(_PATH .. "none")
runfile(_PATH .. "block")
runfile(_PATH .. "block_foliage")
runfile(_PATH .. "cross_large")
runfile(_PATH .. "block_slab")
runfile(_PATH .. "block_slab_foliage")
runfile(_PATH .. "leaf_like")
runfile(_PATH .. "cross_plant")
require(_PATH .. "none")
require(_PATH .. "block")
require(_PATH .. "block_foliage")
require(_PATH .. "cross_large")
require(_PATH .. "block_slab")
require(_PATH .. "block_slab_foliage")
require(_PATH .. "leaf_like")
require(_PATH .. "cross_plant")

View File

@ -1,17 +1,17 @@
-- Load Libraries
runfile(_PATH .. "modules/fenv")
require(_PATH .. "modules/fenv")
runfile(_PATH .. "modules/math")
runfile(_PATH .. "modules/string")
require(_PATH .. "modules/math")
require(_PATH .. "modules/string")
runfile(_PATH .. "modules/gui")
runfile(_PATH .. "modules/dump")
runfile(_PATH .. "modules/table")
runfile(_PATH .. "modules/after")
runfile(_PATH .. "modules/vector")
runfile(_PATH .. "modules/entity")
runfile(_PATH .. "modules/callbacks")
runfile(_PATH .. "modules/serialization")
require(_PATH .. "modules/gui")
require(_PATH .. "modules/dump")
require(_PATH .. "modules/table")
require(_PATH .. "modules/after")
require(_PATH .. "modules/vector")
require(_PATH .. "modules/entity")
require(_PATH .. "modules/callbacks")
require(_PATH .. "modules/serialization")
-- Register base models (if not on main menu)
if zepha.client or zepha.server then runfile(_PATH .. "game/init") end
if zepha.client or zepha.server then require(_PATH .. "game/init") end

View File

@ -326,6 +326,6 @@ add_library(Zepha_Core
client/gui/compound/GuiCellGraph.cpp
client/gui/compound/GuiCellGraph.h
client/gui/basic/GuiCells.cpp
client/gui/basic/GuiCells.h client/gui/Gui.h client/gui/Root.cpp client/gui/Root.h client/gui/BoxElement.cpp client/gui/BoxElement.h client/gui/Gui.cpp client/gui/Style.h client/gui/TextElement.cpp client/gui/TextElement.h client/gui/Expression.cpp client/gui/Expression.h client/gui/Style.cpp client/CallbackGroup.h)
client/gui/basic/GuiCells.h client/gui/Gui.h client/gui/Root.cpp client/gui/Root.h client/gui/BoxElement.cpp client/gui/BoxElement.h client/gui/Gui.cpp client/gui/Style.h client/gui/TextElement.cpp client/gui/TextElement.h client/gui/Expression.cpp client/gui/Expression.h client/gui/Style.cpp client/Callback.h lua/ModException.h)
target_include_directories(Zepha_Core PUBLIC .)

View File

@ -11,9 +11,7 @@
#pragma clang diagnostic pop
//#include "StartGame.h"
#include <iostream>
#include "client/CallbackGroup.h"
#include "StartGame.h"
/*
* Zepha, designed, developed, and created by Nicole Collings
@ -25,31 +23,13 @@ enum class CB {
A, B, _END
};
template<typename... Args>
void call(std::function<void(vec<any>)> cb, const Args&... args) {
vec<any> vec = { args... };
cb(vec);
}
int main(int argc, char* argv[]) {
// return StartGame(argc, argv);
CallbackGroup<CB, u32> cbs;
u32 cbA1 = cbs.bind(CB::A, [&](u32 i) { std::cout << "a1 " << i << std::endl; });
u32 cbA2 = cbs.bind(CB::A, [&](u32 i) { std::cout << "a2 " << i << std::endl; });
u32 cbA3 = cbs.bind(CB::A, [&](u32 i) { std::cout << "a3 " << i << std::endl; });
cbs.bind(CB::B, [&](u32 i) { std::cout << "b1 " << i << std::endl; });
cbs.bind(CB::B, [&](u32 i) { std::cout << "b2 " << i << std::endl; });
cbs.call(CB::A, "hi!");
cbs.call(CB::A, 1);
cbs.call(CB::A, 2);
cbs.call(CB::B, 2);
cbs.call(CB::B, 1);
cbs.unbind(CB::A, cbA1);
cbs.unbind(CB::A, cbA2);
cbs.call(CB::A, 3);
cbs.unbind(CB::A, cbA3);
cbs.call(CB::A, 4);
return StartGame(argc, argv);
}

View File

@ -1,10 +1,22 @@
#pragma once
#include <list>
#include <iostream>
#include <functional>
#include "util/Types.h"
class CallbackRef {
public:
CallbackRef() = default;
explicit CallbackRef(std::function<void()> unbind): unbind(std::make_shared<std::function<void()>>(unbind)) {};
~CallbackRef() { if (unbind && unbind.unique()) unbind->operator()(); }
private:
sptr<std::function<void()>> unbind = nullptr;
};
template <typename... Args>
class CallbackManager {
public:
@ -17,13 +29,14 @@ public:
}
};
void call(Args&&... args) {
for (const let& cb : callbacks) if (cb.second.valid) cb.second.call(std::forward<Args>(args)...);
void call(const Args&... args) {
for (const let& cb : callbacks) if (cb.second.valid) cb.second.call(args...);
};
usize bind(const CB_TYPE& cb) {
callbacks.emplace(next, InvalidatableCB(cb));
return next++;
CallbackRef bind(const CB_TYPE& cb) {
usize cID = next++;
callbacks.emplace(cID, InvalidatableCB(cb));
return CallbackRef([=]() { unbind(cID); });
};
void unbind(usize ind) {
@ -53,11 +66,11 @@ public:
for (usize i = 0; i < callbacks.size(); i++) callbacks[i].update();
};
void call(CB_IDENTIFIER type, Args&&... args) {
callbacks[static_cast<usize>(type)].call(std::forward<Args>(args)...);
void call(CB_IDENTIFIER type, const Args&... args) {
callbacks[static_cast<usize>(type)].call(args...);
};
usize bind(CB_IDENTIFIER type, const CB_TYPE& cb) {
CallbackRef bind(CB_IDENTIFIER type, const CB_TYPE& cb) {
return callbacks[static_cast<usize>(type)].bind(cb);
};

View File

@ -49,42 +49,6 @@ void Input::setMouseLocked(bool lock) {
glfwSetInputMode(window, GLFW_CURSOR, (mouseLocked ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL));
}
usize Input::bindKeyCallback(i32 key, std::function<void(i32)> cb) {
keyCallbacks[key].emplace(keyCallbacksInd, ICB(cb));
return keyCallbacksInd++;
}
void Input::unbindKeyCallback(i32 key, usize id) {
keyCallbacks[key].at(id).valid = false;
}
usize Input::bindKeyCallback(std::function<void(u32, i32)> cb) {
globalKeyCallbacks.emplace(globalKeyCallbacksInd, ICB(cb));
return globalKeyCallbacksInd++;
}
void Input::unbindKeyCallback(usize id) {
globalKeyCallbacks.at(id).valid = false;
}
usize Input::bindMouseCallback(i32 button, std::function<void(i32)> cb) {
mouseCallbacks[button].emplace(mouseCallbacksInd, ICB(cb));
return mouseCallbacksInd++;
}
void Input::unbindMouseCallback(i32 button, usize id) {
mouseCallbacks[button].at(id).valid = false;
}
usize Input::bindMouseCallback(std::function<void(u32, i32)> cb) {
globalMouseCallbacks.emplace(globalMouseCallbacksInd, ICB(cb));
return globalMouseCallbacksInd++;
}
void Input::unbindMouseCallback(usize id) {
globalMouseCallbacks.at(id).valid = false;
}
ivec2 Input::getMousePos() {
f64 xPos, yPos;
glfwGetCursorPos(window, &xPos, &yPos);
@ -96,15 +60,16 @@ ivec2 Input::getMouseDelta() {
}
void Input::updateKey(u32 key, i32 state) {
if (state == GLFW_REPEAT) return;
keyState[key] = state != GLFW_RELEASE && state != 3;
for (let& cb : keyCallbacks[key]) if (cb.second.valid) cb.second.cb(state);
for (let& cb : globalKeyCallbacks) if (cb.second.valid) cb.second.cb(key, state);
events.call(CBType::KEY, key, state);
events.call(state != GLFW_RELEASE ? CBType::KEY_PRESS : CBType::KEY_RELEASE, key, state);
}
void Input::updateMouse(u32 button, i32 state) {
mouseState[button] = state != GLFW_RELEASE && state != 3;
for (let& cb : mouseCallbacks[button]) if (cb.second.valid) cb.second.cb(state);
for (let& cb : globalMouseCallbacks) if (cb.second.valid) cb.second.cb(button, state);
events.call(CBType::MOUSE, button, state);
events.call(state != GLFW_RELEASE ? CBType::MOUSE_PRESS : CBType::MOUSE_RELEASE, button, state);
}
void Input::scrollCallback(GLFWwindow* window, f64 x, f64 y) {

View File

@ -5,58 +5,13 @@
#include <unordered_map>
#include "util/Types.h"
#include "client/Callback.h"
/**
* Manages callbacks for key and mouse input, allows toggling mouse locking.
*/
class Input {
template <typename C>
struct ICB {
ICB(C cb): cb(cb) {}
bool valid = true;
C cb;
};
enum TestEnum {
A, B,
_END
};
template <typename C>
class CallbackManager {
public:
typedef std::function<C> CB_TYPE;
void update();
usize bind(CB_TYPE cb);
usize unbind(usize ind);
private:
struct InvalidatableCB {
CB_TYPE call;
bool valid = true;
};
usize next = 0;
std::list<usize> invalidInds;
std::unordered_map<usize, InvalidatableCB> callbacks;
};
template <typename C, typename E, std::enable_if_t<std::is_enum_v<E> && E::_END != 0, bool> = true>
class CallbackGroup {
public:
typedef E CB_IDENTIFIER;
typedef std::function<C> CB_TYPE;
usize bind(CB_IDENTIFIER type, CB_TYPE cb);
usize unbind(CB_IDENTIFIER type, usize ind);
private:
std::array<std::unordered_map<usize, CallbackManager<C>>, E::_END - 1> callbacks;
};
public:
/** Activates the input listeners. */
@ -74,18 +29,6 @@ public:
/** Sets whether or not the mouse is locked and hidden for first person camera use. */
void setMouseLocked(bool lock);
usize bindKeyCallback(i32 key, std::function<void(i32)> cb);
void unbindKeyCallback(i32 key, usize id);
usize bindKeyCallback(std::function<void(u32, i32)> cb);
void unbindKeyCallback(usize id);
usize bindMouseCallback(i32 button, std::function<void(i32)> cb);
void unbindMouseCallback(i32 button, usize id);
usize bindMouseCallback(std::function<void(u32, i32)> cb);
void unbindMouseCallback(usize id);
/**
* Gets the position of the mouse relative to the screen.
* Will always report the center of the screen if the mouse is locked.
@ -100,6 +43,18 @@ public:
ivec2 getMouseDelta();
enum class CBType {
KEY,
KEY_PRESS,
KEY_RELEASE,
MOUSE,
MOUSE_PRESS,
MOUSE_RELEASE,
_END
};
CallbackGroup<CBType, u32, i32> events {};
private:
/** Calls the key callbacks and sets the key state of the key provided. */
@ -131,16 +86,4 @@ private:
bool forceMouseUnlocked = false;
GLFWwindow* window = nullptr;
array<std::unordered_map<usize, ICB<std::function<void(i32)>>>, 1024> keyCallbacks {};
usize keyCallbacksInd = 0;
std::unordered_map<usize, ICB<std::function<void(u32, i32)>>> globalKeyCallbacks {};
usize globalKeyCallbacksInd = 0;
array<std::unordered_map<usize, ICB<std::function<void(i32)>>>, 3> mouseCallbacks {};
usize mouseCallbacksInd = 0;
std::unordered_map<usize, ICB<std::function<void(u32, i32)>>> globalMouseCallbacks {};
usize globalMouseCallbacksInd = 0;
};

View File

@ -9,7 +9,7 @@
Window::Window() : Window({ 800, 600 }) {};
Window::Window(ivec2 win) :
win(win), center(win.x / 2, win.y / 2) {
win(win) {
if (!glfwInit()) {
glfwTerminate();
@ -50,7 +50,6 @@ Window::Window(ivec2 win) :
// Setup callbacks
glfwSetWindowUserPointer(mainWindow, this);
glfwSetScrollCallback(mainWindow, scrollCallback);
glfwSetWindowSizeCallback(mainWindow, resizeCallback);
glfwSetInputMode(mainWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@ -61,11 +60,6 @@ Window::Window(ivec2 win) :
void Window::update() {
input.update();
for (let it = resizeCallbacks.begin(); it != resizeCallbacks.end();) {
if (it->first.unique()) it = resizeCallbacks.erase(it);
else it++;
}
}
bool Window::shouldClose() {
@ -76,12 +70,6 @@ void Window::swapBuffers() {
glfwSwapBuffers(mainWindow);
}
Window::RCBLock Window::onResize(std::function<void(ivec2)> cb) {
RCBLock lock = make_shared<bool>(true);
resizeCallbacks.emplace_back(std::pair(lock, cb));
return lock;
}
ivec2 Window::getSize() {
return win;
}
@ -90,18 +78,12 @@ void Window::setCursorHand(bool hand) {
glfwSetCursor(mainWindow, hand ? handCursor : nullptr);
}
void Window::scrollCallback(GLFWwindow* window, f64 xO, f64 yO) {
// auto w = static_cast<Window*>(glfwGetWindowUserPointer(window));
}
void Window::resizeCallback(GLFWwindow* window, i32 width, i32 height) {
let w = static_cast<Window*>(glfwGetWindowUserPointer(window));
glfwGetFramebufferSize(window, &w->win.x, &w->win.y);
glViewport(0, 0, w->win.x, w->win.y);
w->center = glm::ivec2(w->win.x / 2, w->win.y / 2);
for (auto& cb : w->resizeCallbacks) cb.second(w->win);
w->resize.call(ivec2 { width, height });
}
Window::~Window() {

View File

@ -14,8 +14,6 @@
class Window {
public:
using RCBLock = sptr<bool>;
Window();
Window(ivec2 win);
@ -26,8 +24,6 @@ public:
void swapBuffers();
RCBLock onResize(std::function<void(ivec2)> cb);
ivec2 getSize();
void setCursorHand(bool hand);
@ -35,18 +31,16 @@ public:
~Window();
Input input;
GLFWwindow* mainWindow = nullptr;
private:
static void scrollCallback(GLFWwindow* window, f64 xO, f64 yO);
GLFWwindow* mainWindow = nullptr;
CallbackManager<ivec2> resize {};
private:
static void resizeCallback(GLFWwindow* window, i32 width, i32 height);
GLFWcursor* handCursor = nullptr;
ivec2 win;
ivec2 center;
std::list<std::pair<RCBLock, std::function<void(ivec2)>>> resizeCallbacks {};
};

View File

@ -38,7 +38,7 @@ class ServerConnection {
private:
unsigned long timeout = 1000;
unsigned int attempts = 1000;
unsigned int attempts = 10;
ENetHost* host = nullptr;
ENetPeer* peer = nullptr;

View File

@ -39,7 +39,7 @@ Renderer::Renderer(glm::ivec2 win) :
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
lock = window.onResize([&](glm::ivec2 win) {
callbacks.emplace_back(window.resize.bind([&](glm::ivec2 win) {
ssao.windowResized(win);
blur.windowResized(win);
light.windowResized(win);
@ -48,7 +48,7 @@ Renderer::Renderer(glm::ivec2 win) :
camera.changeWindowDimensions(win);
gu.matrix = camera.getOrthographicMatrix();
});
}));
//VSync 1 = On, 0 = Off
glfwSwapInterval(1);

View File

@ -76,6 +76,6 @@ private:
GLint currentModelUniform;
double elapsedTime = 0;
Window::RCBLock lock;
vec<CallbackRef> callbacks {};
};

View File

@ -18,25 +18,22 @@ Gui::Root::Root(Window& window, TextureAtlas& atlas) :
}}
});
lock = window.onResize([&](ivec2 size) {
callbacks.emplace_back(window.resize.bind([&](ivec2 size) {
body->setStyle(StyleRule::SIZE, array<Expression, 2> {
Expression(std::to_string(size.x)), Expression(std::to_string(size.y)) });
Timer t("Resize UI");
body->updateElement();
t.printElapsedMs();
});
}));
mouseCb = window.input.bindMouseCallback([&](u32 button, i32 state) {
std::cout << "input found " << state << std::endl;
callbacks.emplace_back(window.input.events.bind(Input::CBType::MOUSE, [&](u32 button, i32 state) {
let pos = window.input.getMousePos();
body->handleMouseClick(pos, button, state == GLFW_PRESS);
});
}));
}
Gui::Root::~Root() {
window.setCursorHand(false);
window.input.unbindMouseCallback(mouseCb);
std::cout << "unbound callalalalbacks" << std::endl;
}
void Gui::Root::addStylesheet(const std::unordered_map<string, Style>& sheet) {
@ -44,17 +41,13 @@ void Gui::Root::addStylesheet(const std::unordered_map<string, Style>& sheet) {
}
void Gui::Root::update() {
const let pos = window.input.getMousePos();
bool pointer = false;
const let pos = window.input.getMousePos();
body->handleMouseHover(pos, pointer);
setCursorPointer(pointer);
window.setCursorHand(pointer);
}
void Gui::Root::draw(Renderer& renderer) {
if (!body) return;
body->draw(renderer);
}
void Gui::Root::setCursorPointer(bool hand) {
window.setCursorHand(hand);
}

View File

@ -1,14 +1,16 @@
#pragma once
#include <unordered_map>
#include "client/gui/Gui.h"
#include "Element.h"
#include "util/Types.h"
#include "client/Window.h"
#include "game/atlas/TextureAtlas.h"
/**
* Handles rendering and processing events for a Gui tree.
* Holds a `body` Box that is always the screen's size.
*/
namespace Gui {
class Root {
public:
@ -16,7 +18,13 @@ namespace Gui {
~Root();
/**
* Creates an element from the props provided, optionally with children.
* Does not add it to the tree, use body->append() for that.
*/
template<typename E, std::enable_if_t<std::is_base_of_v<Element, E>, bool> = true>
sptr<E> create(const Element::Props& props = {}, const vec<sptr<Element>>& children = {}) {
let elem = make_shared<E>(*this, stylesheets);
elem->setProps(props);
@ -26,23 +34,32 @@ namespace Gui {
return elem;
};
/**
* Adds a stylesheet to the tree, which can provide
* styles for elements with specific classes.
*/
void addStylesheet(const std::unordered_map<string, Style>& sheet);
/** Processes mouse events. */
void update();
/** Renders the Gui tree. */
void draw(Renderer& renderer);
void setCursorPointer(bool hand);
/** The list of stylesheets to apply to the document. */
vec<StyleSheet> stylesheets;
/** The body element, which is the root of the tree. */
const sptr<Element> body;
/** The clients texture atlas. */
TextureAtlas& atlas;
private:
Window& window;
usize mouseCb;
Window::RCBLock lock;
vec<CallbackRef> callbacks {};
};
}

View File

@ -9,9 +9,7 @@
void Gui::TextElement::updateElement() {
const string text = getStyle<string>(StyleRule::CONTENT, "");
if (!font) {
font = std::make_unique<Font>(root.atlas, root.atlas["font"]);
}
if (!font) font = std::make_unique<Font>(root.atlas, root.atlas["font"]);
usize newHash = std::hash<string>{}(text);
if (hash != newHash) {

View File

@ -49,9 +49,8 @@ void MenuSandbox::loadApi() {
bindModules();
// Create sandboxed runfile()
lua["dofile"] = lua["loadfile"] = sol::nil;
lua.set_function("runfile", &MenuSandbox::runFileSandboxed, this);
lua.set_function("require", &MenuSandbox::runFileSandboxed, this);
lua["dofile"] = lua["loadfile"] = lua["require"];
}
void MenuSandbox::load(const SubgameDef& subgame) {
@ -185,14 +184,14 @@ sol::protected_function_result MenuSandbox::errorCallback(sol::protected_functio
fileName.erase(std::remove_if(fileName.begin(), fileName.end(), isspace), fileName.end());
for (const let& file : mod.files) {
if (file.path == fileName) {
let msg = ErrorFormatter::formatError(fileName,
std::stoi(line.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1)),
err, file.file);
showError(msg);
return r;
}
if (file.path != fileName) continue;
let msg = ErrorFormatter::formatError(fileName,
std::stoi(line.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1)),
err, file.file);
showError(msg);
return r;
}
}

View File

@ -1,62 +1,41 @@
//
// Created by aurailus on 11/07/19.
//
#include <thread>
#include <gzip/decompress.hpp>
#include "ConnectScene.h"
//#include "GameScene.h"
#include "GameScene.h"
#include "client/Client.h"
#include "util/net/Packet.h"
#include "util/net/Address.h"
#include "util/net/PacketView.h"
#include "client/graph/Renderer.h"
#include "client/gui/basic/GuiRect.h"
#include "client/gui/basic/GuiText.h"
#include "client/gui/TextElement.h"
#include "game/atlas/asset/AssetType.h"
/**
* Initializes a connection to the remote address,
* sets up the GUI, and attempts to download subgame assets.
*
* @param addr - The server address to init to.
*/
ConnectScene::ConnectScene(Client& client, Address addr) : Scene(client),
root(client.renderer.window, client.game->textures),
connection(client.connection) {
client.renderer.setClearColor(10, 10, 10);
// Font f(client.game->textures, client.game->textures["font"]);
//
// auto statusText = std::make_shared<GuiText>("statusText");
// statusText->create({ 2, 2 }, {}, { 1, 1, 1, 1 }, {}, f);
// statusText->setText("Connecting...");
// statusText->setPos({ 32, 24 });
// components.add(statusText);
//
// auto loadBar = std::make_shared<GuiRect>("loadBar");
// loadBar->create({ 1, 32 }, {}, { 0.17, 0.75, 0.93, 1 });
// loadBar->setPos({ 0, client.renderer.window.getSize().y - 32 });
// components.add(loadBar);
//
using Expr = Gui::Expression;
status = root.body->append<Gui::TextElement>({
.styles = {{
{ Gui::StyleRule::TEXT_SIZE, Expr("2px") },
{ Gui::StyleRule::SIZE, array<Expr, 2> { Expr("100dp"), Expr("-1") } },
{ Gui::StyleRule::CONTENT, string("`c1Connecting to `b`c0" + addr.toString() + "`r`c1...") },
{ Gui::StyleRule::MARGIN, array<Expr, 4> { Expr("4dp"), Expr("4dp"), Expr("4dp"), Expr("4dp") } }
}}
});
connection.attemptConnect(std::move(addr));
//
// client.renderer.window.onResize([&](glm::ivec2 win) {
// components.get<GuiRect>("loadBar")->setPos({ 0, win.y - 32 });
// });
}
void ConnectScene::update() {
client.game->textures.update();
root.update();
switch (connectState) {
default:
throw std::runtime_error("Invalid connection state.");
switch (state) {
case State::DONE:
case State::FAILED_CONNECT:
break;
@ -66,20 +45,18 @@ void ConnectScene::update() {
break;
case State::PROPERTIES: {
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.1, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
if (p.type == Packet::Type::SERVER_INFO) {
// auto statusText = components.get<GuiText>("statusText");
// statusText->setText(statusText->getText() + "Received server properties.\n");
status->setStyle(Gui::StyleRule::CONTENT, status->getStyle<string>(Gui::StyleRule::CONTENT, "")
+ "Received server properties.\n");
const u32 seed = p.d.read<u32>();
// std::cout << seed << std::endl;
std::cout << seed << std::endl;
connectState = State::IDENTIFIER_LIST;
state = State::IDENTIFIER_LIST;
Packet resp(Packet::Type::BLOCK_IDENTIFIER_LIST);
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
}
@ -88,29 +65,22 @@ void ConnectScene::update() {
}
case State::IDENTIFIER_LIST: {
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.2, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
if (p.type == Packet::Type::BLOCK_IDENTIFIER_LIST) {
// auto statusText = components.get<GuiText>("statusText");
// statusText->setText(statusText->getText() + "Received block index-identifier table.\n");
client.game->getDefs().setIdentifiers(p.d.read<vec<string>>());
Packet resp(Packet::Type::BIOME_IDENTIFIER_LIST);
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
}
else if (p.type == Packet::Type::BIOME_IDENTIFIER_LIST) {
// auto statusText = components.get<GuiText>("statusText");
// statusText->setText(
// statusText->getText() + "Received biome index-identifier table.\nDownloading mods...\n");
status->setStyle(Gui::StyleRule::CONTENT, status->getStyle<string>(Gui::StyleRule::CONTENT, "")
+ "Received block & biome index-identifier table.\nDownloading mods... ");
client.game->getBiomes().setIdentifiers(p.d.read<vec<string>>());
connectState = State::MODS;
state = State::MODS;
Packet resp(Packet::Type::MODS);
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
}
@ -119,25 +89,25 @@ void ConnectScene::update() {
}
case State::MODS: {
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.4, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
// auto statusText = components.get<GuiText>("statusText");
if (p.type == Packet::Type::MODS) {
auto luaMod = LuaMod(p);
// statusText->setText(statusText->getText() + "Received mod " + luaMod.config.name + ".\n");
client.game->getParser().getHandler().addLuaMod(std::move(luaMod));
auto mod = LuaMod(p);
status->setStyle(Gui::StyleRule::CONTENT, status->getStyle<string>(Gui::StyleRule::CONTENT, "") +
(modsFound == 0 ? "" : ", ") + ((modsFound) % 8 == 0 && modsFound != 0 ? "\n" : "") +
"`c0`u" + mod.config.name + "`r`c1");
modsFound++;
client.game->getParser().addMod(std::move(mod));
}
else if (p.type == Packet::Type::MOD_ORDER) {
client.game->getParser().getHandler().setModsOrder(p.d.read<vec<string>>());
client.game->getParser().setModLoadOrder(p.d.read<vec<string>>());
// statusText->setText(statusText->getText() +
// "Done downloading mods.\nReceived the mods order.\nReceiving media");
status->setStyle(Gui::StyleRule::CONTENT, status->getStyle<string>(Gui::StyleRule::CONTENT, "")
+ ".\n`c7Done`c1 downloading mods. Received the mods order.\nReceiving media");
connectState = State::MEDIA;
state = State::MEDIA;
Packet resp(Packet::Type::MEDIA);
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
}
@ -146,21 +116,18 @@ void ConnectScene::update() {
}
case State::MEDIA: {
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x * 0.6, 32 });
ENetEvent e;
if (connection.pollEvents(&e) && e.type == ENET_EVENT_TYPE_RECEIVE) {
PacketView p(e.packet);
// auto statusText = components.get<GuiText>("statusText");
if (p.type == Packet::Type::MEDIA) {
AssetType t = p.d.read<AssetType>();
usize count = 0;
while (t != AssetType::END) {
string assetName = p.d.read<string>();
// statusText->setText(statusText->getText() + ".");
status->setStyle(Gui::StyleRule::CONTENT,
status->getStyle<string>(Gui::StyleRule::CONTENT, "") + ".");
if (t == AssetType::TEXTURE) {
u16 width = p.d.read<u16>();
@ -183,24 +150,26 @@ void ConnectScene::update() {
t = p.d.read<AssetType>();
count++;
}
}
else if (p.type == Packet::Type::MEDIA_DONE) {
// statusText->setText(statusText->getText() + " Done.\nDone receiving media.\nJoining world...\n");
// components.get<GuiRect>("loadBar")->setScale({ client.renderer.window.getSize().x, 32 });
status->setStyle(Gui::StyleRule::CONTENT, status->getStyle<string>(Gui::StyleRule::CONTENT, "")
+ " `c7Done.`c1\nLoading complete. `c0`bJoining world...\n");
connectState = State::DONE;
// client.scene.setScene(make_unique<GameScene>(client));
state = State::DONE;
let gameScene = make_unique<GameScene>(client);
// Only set the scene if the GameScene didn't already redirect to an error scene.
if (client.scene.isCurrent(this)) client.scene.setScene(std::move(gameScene));
return;
}
}
break;
}
}
status->updateElement();
}
void ConnectScene::handleConnecting() {
// auto statusText = components.get<GuiText>("statusText");
switch (connection.getConnectionStatus()) {
default:
throw std::runtime_error("Uncaught connection error.");
@ -209,8 +178,9 @@ void ConnectScene::handleConnecting() {
throw std::runtime_error("Enet Initialization error.");
case ServerConnection::State::FAILED_CONNECT:
connectState = State::FAILED_CONNECT;
// statusText->setText(statusText->getText() + "\nFailed to init :(\n");
state = State::FAILED_CONNECT;
status->setStyle(Gui::StyleRule::CONTENT,
status->getStyle<string>(Gui::StyleRule::CONTENT, "") + " `cfFailed to init :(\n");
break;
case ServerConnection::State::ATTEMPTING_CONNECT:
@ -219,14 +189,15 @@ void ConnectScene::handleConnecting() {
dotsTime += client.getDelta();
if (dotsTime > 1) {
dotsTime -= 1;
// statusText->setText(statusText->getText() + ".");
status->setStyle(Gui::StyleRule::CONTENT, status->getStyle<string>(Gui::StyleRule::CONTENT, "") + ".");
}
break;
case ServerConnection::State::CONNECTED: {
connectState = State::PROPERTIES;
// statusText->setText(statusText->getText() + " Connected!~\n");
state = State::PROPERTIES;
status->setStyle(Gui::StyleRule::CONTENT,
status->getStyle<string>(Gui::StyleRule::CONTENT, "") + " `c7Connected!~`c1\n");
Packet resp(Packet::Type::SERVER_INFO);
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
@ -243,5 +214,5 @@ void ConnectScene::draw() {
renderer.beginGUIDrawCalls();
renderer.enableTexture(&client.game->textures.atlasTexture);
// components.draw(renderer);
root.draw(renderer);
}

View File

@ -1,20 +1,18 @@
//
// Created by aurailus on 11/07/19.
//
#pragma once
#include "Scene.h"
#include "client/Window.h"
#include "client/gui/basic/GuiContainer.h"
class ServerConnection;
#include "client/gui/Root.h"
class Address;
class ServerConnection;
namespace Gui { class TextElement; };
class ConnectScene : public Scene {
public:
/** Represents the loading state. */
enum class State {
CONNECTING,
FAILED_CONNECT,
@ -25,21 +23,27 @@ public:
DONE
};
/**
* Initializes a connection to a remote server, displays download progress.
* Starts the GameScene once the assets have been downloaded.
*/
ConnectScene(Client& state, Address addr);
void update() override;
void draw() override;
/** Handles displaying the connection progress. */
void handleConnecting();
private:
State connectState = State::CONNECTING;
ServerConnection& connection;
State state = State::CONNECTING;
// GuiContainer components;
Gui::Root root;
sptr<Gui::TextElement> status;
double dotsTime = 0;
Window::RCBLock lock;
f64 dotsTime = 0;
u32 modsFound = 0;
};

View File

@ -1,10 +1,10 @@
#include "GameScene.h"
#include "util/Util.h"
#include "client/Client.h"
#include "util/PerfTimer.h"
#include "lua/ModException.h"
#include "util/net/PacketView.h"
#include "client/graph/Renderer.h"
#include "client/scene/LuaErrorScene.h"
GameScene::GameScene(Client& client) : Scene(client),
world(make_shared<LocalWorld>(client.game, client.connection, client.renderer, perfSections)) {
@ -13,8 +13,15 @@ GameScene::GameScene(Client& client) : Scene(client),
r.sendTo(client.connection.getPeer(), Packet::Channel::CONNECT);
world.l()->init();
client.game->init(world, world.l()->getPlayer(), client);
world.l()->updatePlayerDimension();
try {
client.game->init(world, world.l()->getPlayer(), client);
world.l()->updatePlayerDimension();
}
catch (ModException e) {
client.scene.setScene(make_unique<LuaErrorScene>(client, e.what()));
return;
}
client.renderer.setClearColor(148, 194, 240);
// client.renderer.setClearColor(16, 24, 32);

View File

@ -1,46 +1,36 @@
//
// Created by aurailus on 2019-12-28.
//
#include "LuaErrorScene.h"
#include "util/Types.h"
#include "client/Client.h"
#include "client/graph/Font.h"
#include "client/graph/Renderer.h"
#include "client/gui/basic/GuiRect.h"
#include "client/gui/basic/GuiText.h"
#include "client/gui/TextElement.h"
#include "client/scene/MainMenuScene.h"
LuaErrorScene::LuaErrorScene(Client& client, const std::string& err) : Scene(client), err(err) {
LuaErrorScene::LuaErrorScene(Client& client, const std::string& err) : Scene(client),
root(client.renderer.window, client.game->textures) {
client.renderer.setClearColor(0, 0, 0);
client.renderer.window.input.setMouseLocked(false);
Font f(client.game->textures, client.game->textures["font"]);
glm::ivec2 win = client.renderer.window.getSize();
using Expr = Gui::Expression;
root.body->append<Gui::TextElement>({
.styles = {{
{ Gui::StyleRule::TEXT_SIZE, Expr("2px") },
{ Gui::StyleRule::SIZE, array<Expr, 2> { Expr("100dp"), Expr("-1") } },
{ Gui::StyleRule::CONTENT, string("`cfEncountered a fatal mod error ;-;\n\n`r") + err },
{ Gui::StyleRule::MARGIN, array<Expr, 4> { Expr("4dp"), Expr("4dp"), Expr("4dp"), Expr("4dp") } }
}}
});
// auto container = std::make_shared<GuiRect>(client.renderer.window, "container");
// container->create({ 800, 500 }, {}, { 0.05, 0.05, 0.05, 1 });
// container->setPos({ win.x / 2 - 800 / 2, win.y / 2 - 500 / 2 });
// components.add(container);
//
// auto titleText = std::make_shared<GuiText>(client.renderer.window, "titleText");
// titleText->create({ 3, 3 }, {}, {}, { 1, 0.4, 0.5, 1 }, f);
// titleText->setText("The Zepha sandbox has encountered an error.");
// titleText->setPos({ 16, 12 });
// container->add(titleText);
//
// auto errorText = std::make_shared<GuiText>(client.renderer.window, "errorText");
// errorText->create({ 2, 2 }, {}, {}, { 0.85, 0.85, 0.85, 1 }, f);
// errorText->setText(err);
// errorText->setPos({ 16, 48 });
// container->add(errorText);
//
// lock = client.renderer.window.onResize([&](glm::ivec2 win) {
// components.get<GuiRect>("container")->setPos({ win.x / 2 - 800 / 2, win.y / 2 - 500 / 2 });
// });
root.body->onClick([&](i32 button, bool down) {
if (button != GLFW_MOUSE_BUTTON_1 || !down) return;
client.scene.setScene(make_unique<MainMenuScene>(client));
});
}
void LuaErrorScene::update() {
client.game->textures.update();
root.update();
}
void LuaErrorScene::draw() {
@ -51,5 +41,5 @@ void LuaErrorScene::draw() {
renderer.beginGUIDrawCalls();
renderer.enableTexture(&client.game->textures.atlasTexture);
// components.draw(renderer);
root.draw(renderer);
}

View File

@ -7,7 +7,9 @@
#include "Scene.h"
#include "client/Window.h"
#include "client/gui/basic/GuiContainer.h"
#include "client/gui/Root.h"
namespace Gui { class TextElement; };
class LuaErrorScene : public Scene {
public:
@ -18,8 +20,6 @@ public:
void draw() override;
private:
// GuiContainer components;
const std::string err;
Window::RCBLock lock;
Gui::Root root;
};

View File

@ -17,7 +17,6 @@ class Client;
class MainMenuScene : public Scene {
public:
explicit MainMenuScene(Client& client);
void update() override;
@ -25,7 +24,6 @@ public:
void draw() override;
private:
/** Find valid subgames in the subgames folder. */
void findSubgames();

View File

@ -5,6 +5,10 @@ void SceneManager::setScene(uptr<Scene> newScene) {
scene = std::move(newScene);
}
bool SceneManager::isCurrent(Scene* self) {
return scene.get() == self;
}
void SceneManager::update() {
if (!scene) return;
scene->update();
@ -18,4 +22,4 @@ void SceneManager::cleanupScene() {
SceneManager::~SceneManager() {
cleanupScene();
}
}

View File

@ -13,6 +13,8 @@ public:
/** Sets the current scene to the one provided. */
void setScene(uptr<Scene> scene);
bool isCurrent(Scene* self);
/** Updates the current scene. */
void update();

View File

@ -6,6 +6,7 @@
#include "client/Client.h"
#include "ErrorFormatter.h"
#include "lua/ModException.h"
#include "register/RegisterItem.h"
#include "register/RegisterBlock.h"
#include "register/RegisterBiome.h"
@ -35,10 +36,57 @@
LocalLuaParser::LocalLuaParser(LocalSubgame& game) : LuaParser(game), keybinds(this) {}
void LocalLuaParser::init(WorldPtr world, PlayerPtr player, Client& client) {
this->client = &client;
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::debug);
loadApi(world, player);
handler.executeMods(Util::bind_this(this, &LocalLuaParser::runFileSandboxed));
try {
runFileSandboxed("base/init");
for (string mod : modLoadOrder) if (mod != "base") runFileSandboxed(mod + "/init");
}
catch (sol::error r) {
string err = r.what();
std::cout << Log::err << err << Log::endl;
vec<string> lines;
{
string line;
std::stringstream textStream(err);
while (std::getline(textStream, line, '\n')) lines.emplace_back(line);
}
for (const let& line : lines) {
usize lineNumStart = line.find(':');
if (lineNumStart == string::npos) continue;
usize lineNumEnd = line.find(':', lineNumStart + 1);
if (lineNumEnd == string::npos) continue;
string fullPath = line.substr(0, lineNumStart);
fullPath.erase(std::remove_if(fullPath.begin(), fullPath.end(), isspace), fullPath.end());
usize slashPos = fullPath.find('/');
if (slashPos == string::npos) continue;
string modName = fullPath.substr(0, slashPos);
if (modName == "base") continue;
let iter = mods.find(modName);
if (iter == mods.end()) continue;
for (const let& file : iter->second.files) {
if (file.path != fullPath) continue;
let msg = ErrorFormatter::formatError(fullPath,
std::stoi(line.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1)),
err, file.file);
throw ModException(msg);
}
}
throw ModException(err);
}
// client.renderer.window.input.setCallback(Util::bind_this(&keybinds, &LuaKeybindHandler::keybindHandler));
}
@ -51,8 +99,12 @@ void LocalLuaParser::update(double delta) {
}
}
LocalModHandler& LocalLuaParser::getHandler() {
return handler;
void LocalLuaParser::addMod(const LuaMod& mod) {
mods.emplace(mod.config.name, mod);
}
void LocalLuaParser::setModLoadOrder(const vec<string> order) {
modLoadOrder = order;
}
void LocalLuaParser::loadApi(WorldPtr world, PlayerPtr player) {
@ -62,8 +114,7 @@ void LocalLuaParser::loadApi(WorldPtr world, PlayerPtr player) {
core["__builtin"] = lua.create_table();
// Types
// ClientApi::gui_element(lua);
Api::Usertype::GuiElement::bind(lua, core, player.l()->getRoot());
Api::Usertype::Target::bind(Api::State::CLIENT, lua, core);
Api::Usertype::Entity::bind(Api::State::CLIENT, lua, core);
Api::Usertype::Inventory::bind(Api::State::CLIENT, lua, core);
@ -111,48 +162,11 @@ void LocalLuaParser::loadApi(WorldPtr world, PlayerPtr player) {
bindModules();
// Create sandboxed runfile()
lua["dofile"] = lua["loadfile"] = sol::nil;
lua.set_function("runfile", &LocalLuaParser::runFileSandboxed, this);
lua.set_function("require", &LocalLuaParser::runFileSandboxed, this);
lua["dofile"] = lua["loadfile"] = lua["require"];
}
sol::protected_function_result LocalLuaParser::errorCallback(sol::protected_function_result r) {
sol::error err = r;
std::string errString = err.what();
try {
std::string::size_type slash = errString.find('/');
if (slash != std::string::npos) throw "npos";
std::string modString = errString.substr(0, slash);
std::string::size_type lineNumStart = errString.find(':', slash);
if (lineNumStart != std::string::npos) throw "lineNumStart";
std::string::size_type lineNumEnd = errString.find(':', lineNumStart + 1);
if (lineNumEnd != std::string::npos) throw "lineNumEnd";
std::string fileName = errString.substr(0, lineNumStart);
int lineNum = std::stoi(errString.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1));
for (const auto& mod : handler.cGetMods()) {
if (mod.config.name == modString) {
for (auto& file : mod.files) {
if (file.path == fileName) {
std::cout << std::endl << ErrorFormatter::formatError(fileName, lineNum, errString, file.file)
<< std::endl;
break;
}
}
break;
}
}
}
catch (...) {
std::cout << Log::err << "Zepha has encountered an error, and ErrorFormatter failed to format it:"
<< std::endl << std::endl << errString << Log::endl;
}
throw std::runtime_error("Exiting.");
}
sol::protected_function_result LocalLuaParser::runFileSandboxed(const std::string& file) {
@ -161,20 +175,22 @@ sol::protected_function_result LocalLuaParser::runFileSandboxed(const std::strin
throw std::runtime_error("Error opening \"" + file + "\", specified file is invalid.");
std::string modname = file.substr(0, modname_length);
for (const LuaMod& mod : handler.cGetMods()) {
if (modname != mod.config.name) continue;
for (const LuaMod::File& f : mod.files) {
if (f.path != file) continue;
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;
return lua.safe_script(f.file, env, std::bind(&LocalLuaParser::errorCallback, this, std::placeholders::_2),
"@" + f.path, sol::load_mode::text);
}
throw std::runtime_error("Error opening \"" + file + "\", file not found.");
let iter = mods.find(modname);
if (iter == mods.end()) throw std::runtime_error("Error opening \"" + file + "\", mod not found.");
for (const LuaMod::File& f : iter->second.files) {
if (f.path != file) continue;
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"] = modname;
using Pfr = sol::protected_function_result;
let res = lua.safe_script(f.file, env,
[](lua_State*, Pfr pfr) -> Pfr { throw static_cast<sol::error>(pfr); },
"@" + f.path, sol::load_mode::text);
return res;
}
throw std::runtime_error("Error opening \"" + file + "\", mod not found.");
}
throw std::runtime_error("Error opening \"" + file + "\", file not found.");
}

View File

@ -4,10 +4,12 @@
#pragma once
#include <unordered_map>
#include "lua/LuaParser.h"
#include "LuaMod.h"
#include "util/CovariantPtr.h"
#include "lua/LocalModHandler.h"
#include "lua/LuaKeybindHandler.h"
class Client;
@ -16,23 +18,28 @@ class LocalPlayer;
class LocalSubgame;
class LocalLuaParser : public LuaParser {
public:
public:
explicit LocalLuaParser(LocalSubgame& game);
void init(WorldPtr world, PlayerPtr player, Client& client);
void update(double delta) override;
LocalModHandler& getHandler();
void addMod(const LuaMod& mod);
private:
void setModLoadOrder(const vec<string> order);
private:
void loadApi(WorldPtr world, PlayerPtr player);
virtual sol::protected_function_result errorCallback(sol::protected_function_result r) override;
sol::protected_function_result runFileSandboxed(const std::string& file);
Client* client;
LuaKeybindHandler keybinds;
LocalModHandler handler;
double accumulatedDelta = 0;
std::unordered_map<string, LuaMod> mods {};
vec<string> modLoadOrder {};
};

View File

@ -1,30 +1,37 @@
////
//// Created by aurailus on 2020-02-19.
////
//
// Created by aurailus on 2020-02-19.
//#include "lua/Lua.h"
//
#include "LocalModHandler.h"
void LocalModHandler::addLuaMod(const LuaMod& mod) {
mods.emplace_back(mod);
}
void LocalModHandler::setModsOrder(const std::vector<std::string>& order) {
modsOrder = order;
}
void LocalModHandler::executeMods(std::function<void(std::string)> run) {
for (std::string& modName : modsOrder) {
if (modName == "base") {
run(modName + "/init");
break;
}
}
for (std::string& modName : modsOrder) {
if (modName != "base") run(modName + "/init");
}
}
const std::vector<LuaMod>& LocalModHandler::cGetMods() const {
return mods;
}
//#include "LocalModHandler.h"
//
//void LocalModHandler::addLuaMod(const LuaMod& mod) {
// mods.emplace_back(mod);
//}
//
//void LocalModHandler::setModsOrder(const std::vector<std::string>& order) {
// modsOrder = order;
//}
//
//void LocalModHandler::executeMods(std::function<void(std::string)> run) {
// try {
// for (std::string& modName : modsOrder) {
// if (modName == "base") {
// run(modName + "/init");
// break;
// }
// }
//
// for (std::string& modName : modsOrder) {
// if (modName != "base") run(modName + "/init");
// }
// }
// catch (sol::error e) {
// std::cout << "CAUGHT B " << e.what() << std::endl;
// }
//}
//
//const std::vector<LuaMod>& LocalModHandler::cGetMods() const {
// return mods;
//}

View File

@ -1,24 +1,24 @@
////
//// Created by aurailus on 2020-02-19.
////
//
// Created by aurailus on 2020-02-19.
//#pragma once
//
#pragma once
#include <functional>
#include "LuaMod.h"
class LocalModHandler {
public:
void addLuaMod(const LuaMod& mod);
void setModsOrder(const std::vector<std::string>& order);
void executeMods(std::function<void(std::string)> run);
const std::vector<LuaMod>& cGetMods() const;
private:
std::vector<LuaMod> mods;
std::vector<std::string> modsOrder;
};
//#include <functional>
//
//#include "LuaMod.h"
//
//class LocalModHandler {
// public:
// void addLuaMod(const LuaMod& mod);
//
// void setModsOrder(const std::vector<std::string>& order);
//
// void executeMods(std::function<void(std::string)> run);
//
// const std::vector<LuaMod>& cGetMods() const;
//
// private:
// std::vector<LuaMod> mods;
// std::vector<std::string> modsOrder;
//};

View File

@ -16,7 +16,7 @@
class Subgame;
class LuaParser {
public:
public:
constexpr static double UPDATE_STEP{ 1 / 60. };
LuaParser(Subgame& game) : game(game) {};
@ -28,7 +28,7 @@ class LuaParser {
template<typename... Args>
sol::protected_function_result safe_function(sol::protected_function f, Args... args) {
auto res = f(args...);
if (!res.valid()) errorCallback(res);
// if (!res.valid()) errorCallback(res);
return res;
}

17
src/lua/ModException.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "util/Types.h"
class ModException : public std::exception {
public:
ModException(const string& message): message(message) {}
const char* what() const throw() {
return message.data();
}
private:
string message;
};

View File

@ -140,9 +140,8 @@ void ServerLuaParser::loadApi(WorldPtr world) {
bindModules();
// Create sandboxed runfile()
lua["dofile"] = lua["loadfile"] = sol::nil;
lua.set_function("runfile", &ServerLuaParser::runFileSandboxed, this);
lua.set_function("require", &ServerLuaParser::runFileSandboxed, this);
lua["dofile"] = lua["loadfile"] = lua["require"];
}
sol::protected_function_result ServerLuaParser::errorCallback(sol::protected_function_result r) {

View File

@ -167,25 +167,21 @@ bool Api::Usertype::LocalPlayer::is_in_menu() {
return player.l()->isInMenu();
}
//void Api::Usertype::LocalPlayer::show_menu(std::shared_ptr<LuaGuiElement> root) {
//// return player.l()->showMenu(root);
// return;
//}
void Api::Usertype::LocalPlayer::close_menu() {
// return player.l()->closeMenu();
return;
void Api::Usertype::LocalPlayer::show_menu(std::shared_ptr<Gui::Element> root) {
return player.l()->showMenu(root);
}
//std::shared_ptr<LuaGuiElement> Api::Usertype::LocalPlayer::get_hud() {
//// return player.l()->getHud();
// return nullptr;
//}
void Api::Usertype::LocalPlayer::close_menu() {
return player.l()->closeMenu();
}
//void Api::Usertype::LocalPlayer::set_hud(std::shared_ptr<LuaGuiElement> hud) {
//// player.l()->setHud(hud);
// return;
//}
std::shared_ptr<Gui::Element> Api::Usertype::LocalPlayer::get_hud() {
return player.l()->getHud();
}
void Api::Usertype::LocalPlayer::set_hud(std::shared_ptr<Gui::Element> hud) {
return player.l()->setHud(hud);
}
void Api::Usertype::LocalPlayer::bind(State, sol::state& lua, sol::table& core) {
lua.new_usertype<LocalPlayer>("Player",
@ -212,10 +208,10 @@ void Api::Usertype::LocalPlayer::bind(State, sol::state& lua, sol::table& core)
"get_dimension", &LocalPlayer::get_dimension,
// "show_menu", &LocalPlayer::show_menu,
"show_menu", &LocalPlayer::show_menu,
"close_menu", &LocalPlayer::close_menu,
// "set_hud", &LocalPlayer::set_hud,
// "get_hud", &LocalPlayer::get_hud,
"set_hud", &LocalPlayer::set_hud,
"get_hud", &LocalPlayer::get_hud,
"pos", sol::property(&LocalPlayer::get_pos, &LocalPlayer::set_pos),
"block_pos", sol::property(&LocalPlayer::get_block_pos, &LocalPlayer::set_pos),

View File

@ -4,16 +4,12 @@
#pragma once
//#include <sol/forward.hpp>
#include <memory>
#include "Inventory.h"
#include "Dimension.h"
#include "world/player/LocalPlayer.h"
//class LuaGuiElement;
namespace Api::Usertype {
class ServerPlayer;
class LocalPlayer;
@ -82,13 +78,13 @@ public:
bool is_in_menu();
// void show_menu(std::shared_ptr<LuaGuiElement> root);
void show_menu(std::shared_ptr<Gui::Element> root);
void close_menu();
// std::shared_ptr<LuaGuiElement> get_hud();
std::shared_ptr<Gui::Element> get_hud();
// void set_hud(std::shared_ptr<LuaGuiElement> hud);
void set_hud(std::shared_ptr<Gui::Element> hud);
static void bind(State state, sol::state& lua, sol::table& core);
};

View File

@ -19,3 +19,7 @@ Address Address::fromString(const std::string& addressString) {
return Address{ address, port };
}
string Address::toString() {
return host + ":" + std::to_string(port);
}

View File

@ -22,6 +22,8 @@ public:
static Address fromString(const string& addressString);
string toString();
string host;
u16 port = Address::DEFAULT_PORT;

View File

@ -40,7 +40,7 @@ void LocalWorld::update(f64 delta, vec<usize>& perfTimings, PerfTimer& perf) {
// Update children
perf.start("update:player");
if (*player) player.l()->update(renderer.window.input, delta, renderer.window.input.getMouseDelta());
if (*player) player.l()->update(delta, renderer.window.input.getMouseDelta());
refs->update(delta, net);
// Update the network

View File

@ -104,7 +104,7 @@ private:
/** A pointer to the active dimension. */
sptr<LocalDimension> activeDimension = nullptr;
Window::RCBLock lock;
// Window::RCBLock lock;
/** A reference to the world gen stream. */
// sptr<WorldInterpolationStream> worldGenStream;

View File

@ -1,7 +1,3 @@
//
// Created by aurailus on 28/12/18.
//
#include "LocalPlayer.h"
#include "util/Ray.h"
@ -9,6 +5,7 @@
#include "game/def/BlockDef.h"
#include "util/net/NetField.h"
#include "lua/usertype/Target.h"
#include "client/gui/BoxElement.h"
#include "client/graph/Renderer.h"
#include "world/dim/chunk/Chunk.h"
#include "util/net/Deserializer.h"
@ -19,33 +16,40 @@
LocalPlayer::LocalPlayer(SubgamePtr game, LocalWorld& world, DimensionPtr dim, Renderer& renderer) :
Player(game, world, dim), DrawableEntity(game, dim), Entity(game, dim),
renderer(renderer),
wireframe(game, dim, { 1, 1, 1 }) {
// gameGui(world.getRefs().l(), renderer.window.getSize(), game.l(), renderer) {
root(renderer.window, game.l()->textures),
wireframe(game, dim, { 1, 1, 1 }),
renderer(renderer) {
handItemModel.parent = &handModel;
// lock = renderer.window.onResize([&](glm::ivec2 win) { gameGui.winResized(win); });
hud = root.body->append<Gui::BoxElement>({ .styles {{
{ Gui::StyleRule::POS, array<Gui::Expression, 2> { Gui::Expression("0"), Gui::Expression("0") }},
{ Gui::StyleRule::SIZE, array<Gui::Expression, 2> { Gui::Expression("100cw"), Gui::Expression("100ch") }}
}}});
menu = root.body->append<Gui::BoxElement>({ .styles {{
{ Gui::StyleRule::POS, array<Gui::Expression, 2> { Gui::Expression("0"), Gui::Expression("0") }},
{ Gui::StyleRule::SIZE, array<Gui::Expression, 2> { Gui::Expression("100cw"), Gui::Expression("100ch") }}
}}});
}
void LocalPlayer::update(Input& input, f64 delta, vec2 mouseDelta) {
// gameGui.update(delta);
void LocalPlayer::update(f64 delta, vec2 mouseDelta) {
root.update();
// handItemModel.setVisible(gameGui.isVisible());
updatePhysics(input, delta, mouseDelta);
updatePhysics(delta, mouseDelta);
vec3 newPos, newVel;
std::tie(newPos, newVel) =
Collision::applyVel(game, dim, *collisionBox, pos, vel, delta);
std::tie(newPos, newVel) = Collision::applyVel(game, dim, *collisionBox, pos, vel, delta);
setPos(newPos);
setVel(newVel);
updateCamera();
findTarget(input);
findTarget();
updateWireframe();
// if (!gameGui.isInMenu()) updateInteract(input, delta);
// if (!gameGui.isInMenu())
updateInteract(delta);
}
string LocalPlayer::getUsername() {
@ -62,7 +66,6 @@ void LocalPlayer::setLookOffset(vec3 eyeOffset, bool assert) {
renderer.camera.setPos(pos + getLookOffset());
}
void LocalPlayer::setHandList(const string& list, bool assert) {
Player::setHandList(list, assert);
world.getRefs().l()->setHandList(list);
@ -100,25 +103,31 @@ bool LocalPlayer::isInMenu() {
// return gameGui.isInMenu();
}
//void LocalPlayer::showMenu(sptr<LuaGuiElement> root) {
//// gameGui.showMenu(root);
// renderer.window.input.setMouseLocked(false);
//}
void LocalPlayer::showMenu(sptr<Gui::Element> newMenu) {
menu->clear();
menu->append(newMenu);
renderer.window.input.setMouseLocked(false);
}
void LocalPlayer::closeMenu() {
// gameGui.closeMenu();
menu->clear();
renderer.window.input.setMouseLocked(true);
}
//sptr<LuaGuiElement> LocalPlayer::getHud() {
//// return gameGui.getHud();
//}
Gui::Root& LocalPlayer::getRoot() {
return root;
}
//void LocalPlayer::setHud(sptr<LuaGuiElement> hud) {
//// gameGui.setHud(hud);
//}
sptr<Gui::Element> LocalPlayer::getHud() {
return hud->get(0);
}
void LocalPlayer::setHudVisible(bool hudVisible) {
void LocalPlayer::setHud(sptr<Gui::Element> newHud) {
hud->clear();
hud->append(newHud);
}
void LocalPlayer::setHudVisible(bool visible) {
// gameGui.setVisible(hudVisible);
}
@ -128,11 +137,11 @@ void LocalPlayer::draw(Renderer&) {
}
void LocalPlayer::drawHud(Renderer&) {
// gameGui.drawHud(renderer);
hud->draw(renderer);
}
void LocalPlayer::drawMenu(Renderer&) {
// gameGui.drawMenu(renderer);
menu->draw(renderer);
}
void LocalPlayer::assertField(Packet packet) {
@ -203,19 +212,18 @@ void LocalPlayer::handleAssertion(Deserializer& d) {
}
}
bool LocalPlayer::getKey(Input& input, LocalPlayer::PlayerControl control) {
// if (gameGui.isInMenu()) return false;
return input.isKeyDown(
bool LocalPlayer::getKey(LocalPlayer::PlayerControl control) {
return renderer.window.input.isKeyDown(
control == PlayerControl::FORWARD ? GLFW_KEY_COMMA :
control == PlayerControl::BACKWARD ? GLFW_KEY_O :
control == PlayerControl::LEFT ? GLFW_KEY_A :
control == PlayerControl::RIGHT ? GLFW_KEY_E :
control == PlayerControl::JUMP ? GLFW_KEY_SPACE :
control == PlayerControl::MOD1 ? GLFW_KEY_LEFT_SHIFT :
GLFW_KEY_LEFT_CONTROL);
control == PlayerControl::BACKWARD ? GLFW_KEY_O :
control == PlayerControl::LEFT ? GLFW_KEY_A :
control == PlayerControl::RIGHT ? GLFW_KEY_E :
control == PlayerControl::JUMP ? GLFW_KEY_SPACE :
control == PlayerControl::MOD1 ? GLFW_KEY_LEFT_SHIFT :
GLFW_KEY_LEFT_CONTROL);
}
void LocalPlayer::updatePhysics(Input& input, f64 delta, vec2 mouseDelta) {
void LocalPlayer::updatePhysics(f64 delta, vec2 mouseDelta) {
static constexpr float JUMP_VEL = 10.0f;
static constexpr float MOVE_VEL = 5.5f;
static constexpr float GRAVITY_ACCELERATION = 40.0f;
@ -224,7 +232,7 @@ void LocalPlayer::updatePhysics(Input& input, f64 delta, vec2 mouseDelta) {
static constexpr float MOUSE_SENSITIVITY = 0.1f;
// Position movement
bool sprinting = getKey(input, PlayerControl::MOD2);
bool sprinting = getKey(PlayerControl::MOD2);
double moveSpeed = MOVE_VEL * (sprinting ? 1.6 : 1);
float friction = 0.3f;
@ -233,7 +241,7 @@ void LocalPlayer::updatePhysics(Input& input, f64 delta, vec2 mouseDelta) {
moveSpeed *= 4;
friction = 0.15f;
}
else if (getKey(input, PlayerControl::JUMP) &&
else if (getKey(PlayerControl::JUMP) &&
Collision::isOnGround(game, dim, *collisionBox, pos, vel))
vel.y = JUMP_VEL;
@ -244,14 +252,14 @@ void LocalPlayer::updatePhysics(Input& input, f64 delta, vec2 mouseDelta) {
glm::vec3 mod{ 0, 0, 0 };
if (getKey(input, PlayerControl::FORWARD)) mod += frontFlat;
if (getKey(input, PlayerControl::BACKWARD)) mod -= frontFlat;
if (getKey(input, PlayerControl::RIGHT)) mod += rightFlat;
if (getKey(input, PlayerControl::LEFT)) mod -= rightFlat;
if (getKey(PlayerControl::FORWARD)) mod += frontFlat;
if (getKey(PlayerControl::BACKWARD)) mod -= frontFlat;
if (getKey(PlayerControl::RIGHT)) mod += rightFlat;
if (getKey(PlayerControl::LEFT)) mod -= rightFlat;
if (flying) {
if (getKey(input, PlayerControl::JUMP)) mod.y += 1;
if (getKey(input, PlayerControl::MOD1)) mod.y -= 1;
if (getKey(PlayerControl::JUMP)) mod.y += 1;
if (getKey(PlayerControl::MOD1)) mod.y -= 1;
}
else {
if (!Collision::isOnGround(game, dim, *collisionBox, pos, vel))
@ -364,7 +372,7 @@ void LocalPlayer::updateWieldAndHandItems() {
handItemModel.setModel(model);
}
void LocalPlayer::findTarget(Input& input) {
void LocalPlayer::findTarget() {
static constexpr float LOOK_DISTANCE = 6.5f;
static constexpr float LOOK_PRECISION = 0.01f;
@ -418,18 +426,18 @@ void LocalPlayer::findTarget(Input& input) {
target = newTarget;
}
void LocalPlayer::updateInteract(Input& input, f64 delta) {
void LocalPlayer::updateInteract(f64 delta) {
if (breakTime > 0) breakTime += delta;
if (breakTime > breakInterval) breakTime = 0;
if (input.isMouseDown(GLFW_MOUSE_BUTTON_LEFT)) {
if (renderer.window.input.isMouseDown(GLFW_MOUSE_BUTTON_LEFT)) {
if (target.type == Target::Type::BLOCK && breakTime == 0) {
auto& targetedBlock = game->getDefs().blockFromId(dim->getBlock(target.data.block.pos));
breakInterval = dim->blockHit(target, static_cast<LocalWorld&>(dim->getWorld()).getPlayer());
breakTime += delta;
}
}
else if (input.isMouseDown(GLFW_MOUSE_BUTTON_RIGHT)) {
else if (renderer.window.input.isMouseDown(GLFW_MOUSE_BUTTON_RIGHT)) {
if (target.type == Target::Type::BLOCK) {
auto& wieldItem = game->getDefs().fromId(this->wieldItem);
auto& targetedBlock = game->getDefs().blockFromId(dim->getBlock(target.data.block.pos));
@ -452,4 +460,4 @@ void LocalPlayer::updateInteract(Input& input, f64 delta) {
dim->wieldItemUse(target, static_cast<LocalWorld&>(dim->getWorld()).getPlayer());
}
}
}
}

View File

@ -5,7 +5,7 @@
#include "util/Target.h"
#include "client/Window.h"
#include "client/gui/GameGui.h"
#include "client/gui/Root.h"
#include "world/dim/LocalDimension.h"
#include "client/entity/WireframeEntity.h"
@ -14,6 +14,7 @@ class Deserializer;
class LocalInventory;
class LocalInventoryRefs;
enum class NetPlayerField;
namespace Gui { class BoxElement; }
/**
* The client-side local player. Manages the camera, and renders UI elements.
@ -24,31 +25,15 @@ public:
/** Enum class for identifying player controls in a keyboard-agnostic manner. */
enum class PlayerControl { FORWARD, LEFT, BACKWARD, RIGHT, JUMP, MOD1, MOD2 };
/**
* Creates the local player, and initializes player UI.
*
* @param game - A reference to the subgame.
* @param world - A reference to the world.
* @param dim - A reference to player's current dimension.
* @param renderer - A reference to the renderer.
*/
/** Creates the local player, and initializes the game Gui. */
LocalPlayer(SubgamePtr game, LocalWorld& world, DimensionPtr dim, Renderer& renderer);
/**
* Updates the player, processing inputs, physics,
* updating the camera, and finding / interacting with the target.
*
* @param input - The input manager, to pull keyboard events from.
* @param delta - The delta time since the last frame.
* @param mouseDelta - The mouse offset from the center of the screen.
*/
void update(Input& input, f64 delta, vec2 mouseDelta);
/** Updates the player, processing inputs, and physics. */
void update(f64 delta, vec2 mouseDelta);
virtual string getUsername() override;
/** The following setters call Player setters, but updates some rendering-related information. */
/* The following call Player setters, but updates some rendering-related information. */
virtual void setPos(vec3 pos, bool assert = false) override;
@ -62,157 +47,78 @@ public:
virtual void setDim(DimensionPtr dim) override;
/**
* Gets the player's target.
* @returns the player's active target.
*/
/** Gets the player's current target. */
Target& getTarget();
/**
* Gets the player's inventory.
* @returns a reference to the player's inventory.
*/
/** Gets the player's inventory. */
virtual InventoryPtr getInventory() override;
/**
* Checks if a player is currently in a menu.
* @returns if a player is currently in a menu.
*/
/** Checks if a player is currently in a menu. */
bool isInMenu();
/**
* Displays a GUI tree to the player, making it the actively open menu.
* @param root - The root GUI element to display.
*/
// void showMenu(sptr<LuaGuiElement> root);
/**
* Closes the currently open menu.
*/
/** Displays a menu to the player, replacing any other menu. */
void showMenu(sptr<Gui::Element> menu);
/** Closes the currently open menu. */
void closeMenu();
/**
* Gets the player's HUD element.
* @returns the root GUI element of the hud.
*/
/** Returns the Gui root. */
Gui::Root& getRoot();
// sptr<LuaGuiElement> getHud();
/** Gets the hud element. */
sptr<Gui::Element> getHud();
/**
* Sets the HUD to the specified GUI tree. The hud does not constitute
* a menu and is always displayed unless the hud is hidden.
*
* @param hud - The root GUI element to display.
*/
/** Sets the hud to the specified element. */
void setHud(sptr<Gui::Element> hud);
// void setHud(sptr<LuaGuiElement> hud);
/**
* Sets the visibility state of the HUD.
* @param hudVisible - Whether or not the HUD should be visible.
*/
void setHudVisible(bool hudVisible);
/**
* Draws the player's target wireframe and held item.
* @param renderer - A reference to the renderer.
*/
/** Sets whether or not the hud should be visible. */
void setHudVisible(bool visible);
/** Draws the player's target wireframe and held item. */
void draw(Renderer& renderer) override;
/**
* Draws the player's HUD tree.
* @param renderer - A reference to the renderer.
*/
/** Draws the player's hud. */
void drawHud(Renderer& renderer);
/**
* Draws the player's menu if they have one open.
* @param renderer - A reference to the renderer.
*/
/** Draws the currently open menu, if there is one. */
void drawMenu(Renderer& renderer);
/**
* Asserts a player field by sending the specified player packet to the server.
* @param packet - The packet to send to the server.
*/
/** Asserts a player field by sending the specified player packet to the server. */
virtual void assertField(Packet packet) override;
/**
* Accepts an assertion packet from the server, updating local properties.
* @param d - A deserializer for the assertion packet.
*/
/** Accepts an assertion packet from the server, updating local properties. */
virtual void handleAssertion(Deserializer& d) override;
private:
/**
* Checks if a specified player-control was pressed.
*
* @param input - The input handler to pull key states from.
* @param control - The control to check the state of.
* @returns a boolean indicating if a specified player control was pressed.
*/
bool getKey(Input& input, PlayerControl control);
/** Checks if a specified player-control was pressed. */
bool getKey(PlayerControl control);
/**
* Moves the player in accordance to the inputs provided.
*
* @param input - The input handler to pull key states from.
* @param delta - The previous frame's delta time.
* @param mouseDelta - The offset of the mouse from the center of the screen.
*/
void updatePhysics(Input& input, f64 delta, vec2 mouseDelta);
/**
* Moves the camera to the player's position, and updates the wield model.
*/
/** Moves the player in accordance to the inputs provided. */
void updatePhysics(f64 delta, vec2 mouseDelta);
/** Moves the camera to the player's position, and updates the wield model. */
void updateCamera();
/**
* Updates the player's wireframe to point at the target.
*/
/** Updates the player's wireframe to point at the target. */
void updateWireframe();
/**
* Updates the hand and wield item definitions
* when their respective lists are changed.
*/
/** Updates the hand and wield item definitions when their respective lists are changed. */
void updateWieldAndHandItems();
/**
* Finds the target under the player's pointer.
* @param input - The input handler.
*/
/** Finds the target under the player's pointer. */
void findTarget();
void findTarget(Input& input);
/** Checks if the player is trying to interact with a block or item, and does so if they are. */
void updateInteract(f64 delta);
/**
* Checks if the player is trying to interact with a
* block or item, and does so if they are.
*
* @param input - The input handler.
* @param delta - The delta time elapsed in the last frame.
*/
/** The Gui root. */
Gui::Root root;
void updateInteract(Input& input, f64 delta);
/** Element roots for the hud and menu, respectively. */
sptr<Gui::BoxElement> hud, menu;
// GameGui gameGui;
/** A reference to the renderer. */
Renderer& renderer;
/** The player's current target. */
@ -232,7 +138,5 @@ private:
/** The actual wield-item model, set to the currently held item. */
DrawableEntity handItemModel;
Window::RCBLock lock;
};

View File

@ -61,7 +61,7 @@ end)
local sizes = {}
local positions = {}
for _ = 1, 100 do
table.insert(sizes, 6 + math.random() * 4)
table.insert(sizes, 3 + math.random() * 8)
table.insert(positions, { math.floor(math.random() * 640), math.floor(math.random() * 320) })
end

View File

@ -4,5 +4,5 @@ _G['chat'] = {
channel_order = {},
}
if zepha.server then runfile(_PATH .. 'api_server')
else runfile(_PATH .. 'api_client') end
if zepha.server then require(_PATH .. 'api_server')
else require(_PATH .. 'api_client') end

View File

@ -1,8 +1,8 @@
runfile(_PATH .. 'api')
require(_PATH .. 'api')
if zepha.client then runfile(_PATH .. 'gui') end
if zepha.server then
chat.create_channel('chat', { name = 'Chat', icon = '@auri:chat:chat_icon' })
end
runfile(_PATH .. 'test')
require(_PATH .. 'test')

View File

@ -1,4 +1,4 @@
runfile(_PATH .. "chest")
require(_PATH .. "chest")
local function stacker_action(dim, pos)
local v = V(0, 1, 0)

View File

@ -1,6 +1,6 @@
_G['health'] = {}
health.internal = {}
runfile(_PATH .. 'api')
runfile(_PATH .. 'interface')
runfile(_PATH .. 'hooks')
require(_PATH .. 'api')
require(_PATH .. 'interface')
require(_PATH .. 'hooks')

View File

@ -2,9 +2,9 @@ if not zepha.client then return end
local hud = zepha.player:get_hud()
health.internal._wrapper = zepha.build_gui(function()
return Gui.Rect {
key = 'health_wrapper'
health.internal._wrapper = zepha.gui(function()
return Gui.Box {
id = 'health_wrapper'
}
end)
@ -15,13 +15,13 @@ function health.internal.update()
health.internal._wrapper:remove('@health:component')
health.internal._wrapper:append(function()
local elem = Gui.Rect {
key = '@health:component',
id = '@health:component',
size = { health.internal._width, 9 },
}
-- Background
for i = 1, hp.max do
elem:append(Gui.Rect {
elem:append(Gui.Box {
size = { 9, 9 },
position = { 8 * (i - 1), 0 },
background = 'crop(0, 0, 9, 9, @auri:health:hearts)'
@ -35,14 +35,14 @@ function health.internal.update()
local start = i % 2
if i > red_start and i <= red_end then
local segment = start ~= 0 and 9 or 18
elem:append(Gui.Rect {
elem:append(Gui.Box {
size = { 9, 9 },
position = { 8 * math.floor((i - 1) / 2), 0 },
background = 'crop(9, ' .. segment .. ', 9, 9, @auri:health:hearts)'
})
elseif i > blue_start and i <= blue_end then
local segment = start ~= 0 and 9 or 18
elem:append(Gui.Rect {
elem:append(Gui.Box {
size = { 9, 9 },
position = { 8 * math.floor((i - 1) / 2), 0 },
background = 'crop(18, ' .. segment .. ', 9, 9, @auri:health:hearts)'
@ -59,11 +59,10 @@ function health.render_default(render)
if render then
hud:append(function()
return Gui.Rect {
key = '@health:default',
id = '@health:default',
size = { health.internal._width, 9 },
position = { '50%', '100%' },
position_anchor = { '50%', '200%' },
position = { '50cw - 50sw', '100cw - 30px' },
health.internal._wrapper
}

View File

@ -1,10 +1,10 @@
_G["hot_wheel"] = {}
if zepha.server then
runfile(_PATH .. "register")
require(_PATH .. "register")
end
if zepha.client then
runfile(_PATH .. "interface")
runfile(_PATH .. "keys")
require(_PATH .. "interface")
require(_PATH .. "keys")
end

View File

@ -1,6 +1,6 @@
runfile("@auri:yield/dropped_item")
require("@auri:yield/dropped_item")
local DROP_ENTITY = true
if DROP_ENTITY then runfile("@auri:yield/mode/entity")
else runfile("@auri:yield/mode/direct") end
if DROP_ENTITY then require("@auri:yield/mode/entity")
else require("@auri:yield/mode/direct") end

View File

@ -1,4 +1,4 @@
local get_yield = runfile("@auri:yield/get_yield")
local get_yield = require("@auri:yield/get_yield")
if zepha.server then
zepha.bind("on_break", function(pos, player)

View File

@ -1,4 +1,4 @@
local get_yield = runfile("@auri:yield/get_yield")
local get_yield = require("@auri:yield/get_yield")
if zepha.server then
zepha.bind("on_break", function(dim, pos)

View File

@ -1,13 +0,0 @@
runfile(_PATH .. "bush_stem")
runfile(_PATH .. "cobblestone")
runfile(_PATH .. "podzol")
runfile(_PATH .. "dirt")
runfile(_PATH .. "grass")
runfile(_PATH .. "leaves")
runfile(_PATH .. "cactus")
runfile(_PATH .. "sand")
runfile(_PATH .. "sandstone")
runfile(_PATH .. "stone")
runfile(_PATH .. "tallgrass")
runfile(_PATH .. "wood")
runfile(_PATH .. "light")

View File

@ -0,0 +1,13 @@
require(_PATH .. "bush_stem")
require(_PATH .. "cobblestone")
require(_PATH .. "podzol")
require(_PATH .. "dirt")
require(_PATH .. "grass")
require(_PATH .. "leaves")
require(_PATH .. "cactus")
require(_PATH .. "sand")
require(_PATH .. "sandstone")
require(_PATH .. "stone")
require(_PATH .. "tallgrass")
require(_PATH .. "wood")
require(_PATH .. "light")

View File

@ -1,4 +0,0 @@
runfile(_PATH .. "rabbit")
runfile(_PATH .. "raven")
runfile(_PATH .. "bee")
runfile(_PATH .. "test")

View File

@ -0,0 +1,4 @@
require(_PATH .. "rabbit")
require(_PATH .. "raven")
require(_PATH .. "bee")
require(_PATH .. "test")

View File

@ -1,5 +1,5 @@
runfile(_PATH .. "blocks/_index")
runfile(_PATH .. "entity/_index")
require(_PATH .. "blocks/index")
require(_PATH .. "entity/index")
local chat_down = false
zepha.register_keybind("zeus:default:open_chat", {

View File

@ -1 +1 @@
runfile("zeus:flowers/flowers")
require(_PATH .. "flowers")

View File

@ -1,7 +1,7 @@
_G["inventory"] = {}
if zepha.server then runfile(_PATH .. "register") end
if zepha.server then require(_PATH .. "register") end
if zepha.client then
runfile(_PATH .. "menu")
runfile(_PATH .. "chest")
require(_PATH .. "menu")
require(_PATH .. "chest")
end

View File

@ -1,2 +1,2 @@
runfile("zeus:kinetic/models/axle")
runfile("zeus:kinetic/blocks/axle")
require("zeus:kinetic/models/axle")
require("zeus:kinetic/blocks/axle")

View File

@ -1,9 +1,9 @@
runfile("zeus:materials/items/stick")
runfile("zeus:materials/items/rock")
runfile("zeus:materials/items/flint")
runfile("zeus:materials/items/flint_heads")
runfile("zeus:materials/items/plant_fibre")
runfile("zeus:materials/items/plant_twine")
require("zeus:materials/items/stick")
require("zeus:materials/items/rock")
require("zeus:materials/items/flint")
require("zeus:materials/items/flint_heads")
require("zeus:materials/items/plant_fibre")
require("zeus:materials/items/plant_twine")
if zepha.server then
zepha.bind("new_player", function(player)

View File

@ -1,5 +1,5 @@
runfile(_PATH .. 'keys')
runfile(_PATH .. 'register_biomes')
require(_PATH .. 'keys')
require(_PATH .. 'register_biomes')
zepha.create_dimension('zeus:world:default', {
biomes = { '#natural', '#default' }

View File

@ -1,6 +1,6 @@
return {
runfile(_PATH .. "biomes/plains"),
runfile(_PATH .. "biomes/highlands"),
runfile(_PATH .. "biomes/desert"),
runfile(_PATH .. "biomes/forest")
require(_PATH .. "biomes/plains"),
require(_PATH .. "biomes/highlands"),
require(_PATH .. "biomes/desert"),
require(_PATH .. "biomes/forest")
}