Zepha/src/client/menu/MenuSandbox.cpp

151 lines
4.4 KiB
C++
Raw Normal View History

#include <fstream>
#include <iostream>
2021-08-20 22:48:38 -07:00
#include <client/gui/TextElement.h>
2019-12-12 02:13:28 -08:00
#include "MenuSandbox.h"
2021-09-06 18:33:01 -07:00
#include "lua/Mod.h"
#include "client/Client.h"
2020-08-13 00:55:18 -07:00
#include "lua/ErrorFormatter.h"
#include "client/menu/SubgameDef.h"
2019-12-12 02:13:28 -08:00
// Modules
2020-08-13 00:55:18 -07:00
#include "lua/modules/Time.h"
#include "lua/modules/mSetGui.h"
#include "lua/modules/mStartGame.h"
2021-08-24 01:48:53 -07:00
#include "lua/usertype/GuiElement.h"
2020-04-13 16:33:15 -07:00
2021-08-20 22:48:38 -07:00
MenuSandbox::MenuSandbox(Client& client, Gui::Root& root, sptr<Gui::Element> sandboxRoot) :
2020-11-08 22:57:34 -08:00
LuaParser(*client.game),
2021-08-20 22:48:38 -07:00
client(client),
root(root),
sandboxRoot(sandboxRoot) {}
2019-12-12 02:13:28 -08:00
void MenuSandbox::reset() {
2021-08-20 22:48:38 -07:00
sandboxRoot->clear();
2020-11-08 22:57:34 -08:00
core = {};
mod = {};
2021-08-20 22:48:38 -07:00
lua = sol::state {};
2020-11-08 22:57:34 -08:00
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::debug);
loadApi();
}
void MenuSandbox::loadApi() {
2020-11-08 22:57:34 -08:00
//Create Zepha Table
core = lua.create_table();
lua["zepha"] = core;
core["__builtin"] = lua.create_table();
modules.emplace_back(std::make_unique<Api::Module::Time>(Api::State::CLIENT, lua, core));
2021-08-20 22:48:38 -07:00
Api::Usertype::GuiElement::bind(lua, core, root);
MenuApi::set_gui(lua, core, sandboxRoot);
2020-11-08 22:57:34 -08:00
MenuApi::start_game(client, core);
bindModules();
2021-09-06 18:33:01 -07:00
lua.set_function("require", &MenuSandbox::require, this);
lua["dofile"] = lua["loadfile"] = lua["require"];
2019-12-12 02:13:28 -08:00
}
void MenuSandbox::load(const SubgameDef& subgame) {
2020-11-08 22:57:34 -08:00
reset();
2021-08-20 22:48:38 -07:00
subgameName = subgame.config.name;
2021-08-24 13:51:41 -07:00
try {
2021-09-06 18:33:01 -07:00
loadMod(subgame.subgamePath + "/../../assets/base");
loadMod(subgame.subgamePath + "/menu");
2021-08-24 13:51:41 -07:00
}
catch (sol::error e) {
string err = static_cast<sol::error>(e).what();
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 fileName = line.substr(0, lineNumStart);
fileName.erase(std::remove_if(fileName.begin(), fileName.end(), isspace), fileName.end());
for (const let& file : mod.files) {
2021-09-06 18:33:01 -07:00
if (file.first != fileName) continue;
2021-08-24 13:51:41 -07:00
let msg = ErrorFormatter::formatError(fileName,
std::stoi(line.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1)),
2021-09-06 18:33:01 -07:00
err, file.first);
2021-08-24 13:51:41 -07:00
showError(msg);
return;
}
}
showError(err);
}
2019-12-12 02:13:28 -08:00
}
void MenuSandbox::update(double delta) {
2021-08-22 11:58:52 -07:00
accumulatedDelta += delta;
while (accumulatedDelta > static_cast<double>(UPDATE_STEP)) {
safe_function(core["__builtin"]["update_entities"], static_cast<double>(UPDATE_STEP));
safe_function(core["__builtin"]["update_delayed_functions"]);
accumulatedDelta -= static_cast<double>(UPDATE_STEP);
}
}
2021-09-06 18:33:01 -07:00
sol::protected_function_result MenuSandbox::require(sol::this_environment thisEnv, const string& path) {
sol::environment env = static_cast<sol::environment>(thisEnv);
string currentPath = env.get<string>("__PATH");
std::cout << "CURRENT: " << currentPath << "\nPATH: " << path << std::endl;
return loadFile(path);
// auto modName = env.get<std::string>("_MODNAME");
// std::string iden = identifier[0] == ':' ? modName + identifier : identifier;
2019-12-12 02:13:28 -08:00
}
2021-09-06 18:33:01 -07:00
sol::protected_function_result MenuSandbox::loadFile(const string& path) {
let it = mod.files.find(path);
if (it == mod.files.end()) throw sol::error("Error opening '" + path + "', file not found.");
let& file = it->second;
sol::environment env(lua, sol::create, lua.globals());
env["_PATH"] = path.substr(0, path.find_last_of('/') + 1);
env["_FILE"] = path;
env["_MODNAME"] = mod.name;
using Pfr = sol::protected_function_result;
return lua.safe_script(file, env,
[](lua_State*, Pfr pfr) -> Pfr { throw static_cast<sol::error>(pfr); },
"@" + path, sol::load_mode::text);
}
void MenuSandbox::loadMod(const std::filesystem::path& path) {
mod = { path, true };
2020-11-08 22:57:34 -08:00
2021-09-06 18:33:01 -07:00
if (std::filesystem::exists(path / "textures"))
2021-09-23 23:16:23 -07:00
menuAssets = client.game->textures.loadDirectory((path / "textures").string(), false);
2020-11-08 22:57:34 -08:00
2021-09-06 18:33:01 -07:00
loadFile("/main");
}
2021-08-20 22:48:38 -07:00
void MenuSandbox::showError(const string& err) {
const string errPrefixText = "`cfEncountered an error while loading the menu for '" + subgameName + "' ;-;\n\n`r";
using Expr = Gui::Expression;
2021-08-22 11:58:52 -07:00
sandboxRoot->clear();
2021-08-24 01:48:53 -07:00
sandboxRoot->append<Gui::TextElement>({{
{ Gui::Prop::CONTENT, errPrefixText + err },
{ Gui::Prop::TEXT_SIZE, Expr("2px") },
{ Gui::Prop::SIZE, array<Expr, 2> { Expr("100dp"), Expr("-1") } },
{ Gui::Prop::MARGIN, array<Expr, 4> { Expr("4dp"), Expr("4dp"), Expr("4dp"), Expr("4dp") } }
}});
2021-08-24 13:51:41 -07:00
}