151 lines
4.4 KiB
C++
151 lines
4.4 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <client/gui/TextElement.h>
|
|
|
|
#include "MenuSandbox.h"
|
|
|
|
#include "lua/Mod.h"
|
|
#include "client/Client.h"
|
|
#include "lua/ErrorFormatter.h"
|
|
#include "client/menu/SubgameDef.h"
|
|
|
|
// Modules
|
|
#include "lua/modules/Time.h"
|
|
#include "lua/modules/mSetGui.h"
|
|
#include "lua/modules/mStartGame.h"
|
|
#include "lua/usertype/GuiElement.h"
|
|
|
|
MenuSandbox::MenuSandbox(Client& client, Gui::Root& root, sptr<Gui::Element> sandboxRoot) :
|
|
LuaParser(*client.game),
|
|
client(client),
|
|
root(root),
|
|
sandboxRoot(sandboxRoot) {}
|
|
|
|
void MenuSandbox::reset() {
|
|
sandboxRoot->clear();
|
|
core = {};
|
|
mod = {};
|
|
lua = sol::state {};
|
|
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::debug);
|
|
|
|
loadApi();
|
|
}
|
|
|
|
void MenuSandbox::loadApi() {
|
|
//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));
|
|
|
|
Api::Usertype::GuiElement::bind(lua, core, root);
|
|
MenuApi::set_gui(lua, core, sandboxRoot);
|
|
MenuApi::start_game(client, core);
|
|
|
|
bindModules();
|
|
|
|
lua.set_function("require", &MenuSandbox::require, this);
|
|
lua["dofile"] = lua["loadfile"] = lua["require"];
|
|
}
|
|
|
|
void MenuSandbox::load(const SubgameDef& subgame) {
|
|
reset();
|
|
subgameName = subgame.config.name;
|
|
|
|
try {
|
|
loadMod(subgame.subgamePath + "/../../assets/base");
|
|
loadMod(subgame.subgamePath + "/menu");
|
|
}
|
|
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) {
|
|
if (file.first != fileName) continue;
|
|
|
|
let msg = ErrorFormatter::formatError(fileName,
|
|
std::stoi(line.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1)),
|
|
err, file.first);
|
|
|
|
showError(msg);
|
|
return;
|
|
}
|
|
}
|
|
|
|
showError(err);
|
|
}
|
|
}
|
|
|
|
void MenuSandbox::update(double delta) {
|
|
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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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 };
|
|
|
|
if (std::filesystem::exists(path / "textures"))
|
|
menuAssets = client.game->textures.loadDirectory((path / "textures").string(), false);
|
|
|
|
loadFile("/main");
|
|
}
|
|
|
|
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;
|
|
sandboxRoot->clear();
|
|
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") } }
|
|
}});
|
|
} |