Removed ClientState entirely and restructured client data passing.
* Updated the fenv polyfill. * Added a fromString helper to Address. * Added documentation comments to some classes. More to come! * Configured CLion code style settings.master
parent
8d6e19500a
commit
a9a12a89d9
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
|
@ -7,8 +7,9 @@
|
|||
<inspection_tool class="ClangTidyInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="clangTidyChecks" value="*,-android-*,-bugprone-bool-pointer-implicit-conversion,-cert-env33-c,-cert-dcl50-cpp,-cert-dcl59-cpp,-cppcoreguidelines-no-malloc,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-fuchsia-*,-google-*,google-default-arguments,google-explicit-constructor,google-runtime-member-string-references,google-runtime-operator,-hicpp-braces-around-statements,-hicpp-named-parameter,-hicpp-no-array-decay,-hicpp-no-assembler,-hicpp-no-malloc,-hicpp-function-size,-hicpp-special-member-functions,-hicpp-vararg,-llvm-*,-objc-*,-readability-else-after-return,-readability-implicit-bool-conversion,-readability-named-parameter,-readability-simplify-boolean-expr,-readability-braces-around-statements,-readability-identifier-naming,-readability-function-size,-readability-redundant-member-init,-misc-bool-pointer-implicit-conversion,-misc-definitions-in-headers,-misc-unused-alias-decls,-misc-unused-parameters,-misc-unused-using-decls,-modernize-use-using,-modernize-use-default-member-init,-clang-diagnostic-*,-clang-analyzer-*,-cert-msc30-c,-cert-msc50-cpp,-bugprone-integer-division,-modernize-use-auto" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LongLine" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="OCDFAInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="OCUnusedMacro" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="OCInconsistentNaming" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
local debug = _G['debug']
|
||||
_G['debug'] = nil
|
||||
|
||||
if not setfenv then
|
||||
_G['setfenv'] = function(fn, env)
|
||||
local i = 1
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
add_library(Zepha_Core
|
||||
client/Client.cpp
|
||||
client/Client.h
|
||||
client/ClientState.cpp
|
||||
client/ClientState.h
|
||||
client/conn/ClientNetworkInterpreter.cpp
|
||||
client/conn/ClientNetworkInterpreter.h
|
||||
client/conn/ServerConnection.cpp
|
||||
|
@ -323,6 +321,6 @@ add_library(Zepha_Core
|
|||
world/ServerWorld.h
|
||||
world/World.cpp
|
||||
world/World.h
|
||||
)
|
||||
util/net/Address.cpp)
|
||||
|
||||
target_include_directories(Zepha_Core PUBLIC .)
|
|
@ -19,7 +19,14 @@
|
|||
|
||||
#include "StartGame.h"
|
||||
|
||||
/**
|
||||
* Main entrance point to the program. (Am I really describing what the main function is?)
|
||||
* Intentionally kept minimal to allow for testing. Real startup logic is done in StartGame. *
|
||||
* @param argc - Argument array length
|
||||
* @param argv - Argument array
|
||||
* @returns - A numerical value indicating exit status.
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
return StartGame(argc, argv);
|
||||
}
|
||||
|
||||
|
|
128
src/StartGame.h
128
src/StartGame.h
|
@ -11,9 +11,18 @@
|
|||
#include "client/Client.h"
|
||||
#include "server/Server.h"
|
||||
|
||||
enum class Mode { INVALID, CLIENT, SERVER };
|
||||
enum class Mode { CLIENT, SERVER };
|
||||
|
||||
std::map<std::string, std::string> parseArgs(int argc, char* argv[]) {
|
||||
|
||||
/**
|
||||
* Parses the arg list provided by the operating system into a map of key-value strings.
|
||||
* @throws invalid_argument if it encounters a duplicate or improperly formatted argument.
|
||||
* @param argc - Argument array length
|
||||
* @param argv - Argument array
|
||||
* @returns - A map of parsed arguments.
|
||||
*/
|
||||
|
||||
std::map<std::string, std::string> ParseArgs(int argc, char* argv[]) {
|
||||
//Collect arguments into `args` map
|
||||
std::map<std::string, std::string> args;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
@ -32,76 +41,83 @@ std::map<std::string, std::string> parseArgs(int argc, char* argv[]) {
|
|||
return args;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a Client or Server instance, depending on the arguments provided.
|
||||
* @param argc - Argument array length
|
||||
* @param argv - Argument array
|
||||
* @returns - A numerical value indicating exit status.
|
||||
*/
|
||||
|
||||
int StartGame(int argc, char* argv[]) {
|
||||
std::string path = argv[0];
|
||||
|
||||
Address addr {"127.0.0.1", 32000};
|
||||
Mode mode = Mode::CLIENT;
|
||||
std::string subgame = "";
|
||||
bool ascii = true;
|
||||
|
||||
//Parse the arguments map
|
||||
for (auto arg : parseArgs(argc, argv)) {
|
||||
switch (Util::hash(arg.first.c_str())) {
|
||||
default: {
|
||||
std::cout << Log::err << "Invalid argument " << arg.first << "." << Log::endl;
|
||||
return -1;
|
||||
}
|
||||
case Util::hash("--mode"): {
|
||||
try {
|
||||
unsigned short port = Address::DEFAULT_PORT;
|
||||
std::string subgame = "";
|
||||
bool ascii = true;
|
||||
|
||||
/**
|
||||
* Handle command line arguments.
|
||||
* @arg mode ("client" | "server") - Whether to initialize a client instance, or a server. Defaults to "client".
|
||||
* @arg port (unsigned short) - The port that the server should listen on. Defaults to Address::DEFAULT_PORT.
|
||||
* @arg subgame (std::string) - The subgame that the server should load.
|
||||
* @arg noascii - Switch to disable ASCII from the console output.
|
||||
*/
|
||||
|
||||
for (auto arg : ParseArgs(argc, argv)) {
|
||||
switch (Util::hash(arg.first.c_str())) {
|
||||
default:
|
||||
throw std::runtime_error("Invalid argument '" + arg.first + "'.");
|
||||
|
||||
case Util::hash("--mode"):
|
||||
if (arg.second == "client") mode = Mode::CLIENT;
|
||||
else if (arg.second == "server") mode = Mode::SERVER;
|
||||
else std::cout << Log::err << "Invalid mode argument." << Log::endl;
|
||||
else throw std::runtime_error("Invalid mode specified.");
|
||||
break;
|
||||
}
|
||||
case Util::hash("--port"): {
|
||||
addr.port = static_cast<unsigned short>(stoi(arg.second));
|
||||
|
||||
// case Util::hash("--address"):
|
||||
// addr.host = arg.second;
|
||||
// break;
|
||||
|
||||
case Util::hash("--port"):
|
||||
port = static_cast<unsigned short>(stoi(arg.second));
|
||||
break;
|
||||
}
|
||||
case Util::hash("--address"): {
|
||||
addr.host = arg.second;
|
||||
break;
|
||||
}
|
||||
case Util::hash("--subgame"): {
|
||||
|
||||
case Util::hash("--subgame"):
|
||||
subgame = arg.second;
|
||||
break;
|
||||
}
|
||||
case Util::hash("--noascii"): {
|
||||
|
||||
case Util::hash("--noascii"):
|
||||
ascii = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Obligatory ASCII Art is obligatory.
|
||||
if (ascii) {
|
||||
Log::clear();
|
||||
std::cout << "\n"
|
||||
"\t\t▒███████▒▓█████ ██▓███ ██░ ██ ▄▄▄ \n"
|
||||
"\t\t▒ ▒ ▒ ▄▀░▓█ ▀ ▓██░ ██▒▓██░ ██▒▒████▄ \n"
|
||||
"\t\t░ ▒ ▄▀▒░ ▒███ ▓██░ ██▓▒▒██▀▀██░▒██ ▀█▄ \n"
|
||||
"\t\t ▄▀▒ ░▒▓█ ▄ ▒██▄█▓▒ ▒░▓█ ░██ ░██▄▄▄▄██ \n"
|
||||
"\t\t▒███████▒░▒████▒▒██▒ ░ ░░▓█▒░██▓ ▓█ ▓██▒\n"
|
||||
"\t\t░▒▒ ▓░▒░▒░░ ▒░ ░▒▓▒░ ░ ░ ▒ ░░▒░▒ ▒▒ ▓▒█░\n"
|
||||
"\t\t░ ▒ ▒ ░ ▒ ░ ░ ░░▒ ░ ▒ ░▒░ ░ ▒ ▒▒ ░\n"
|
||||
"\t\t ░ ░ ░ ░ ░░ ░ ░ ░ ▒ \n" << std::endl;
|
||||
}
|
||||
|
||||
//Start the game
|
||||
switch (mode) {
|
||||
default: {
|
||||
std::cout << Log::err << "Mode not set." << Log::endl;
|
||||
return -1;
|
||||
if (ascii) {
|
||||
Log::clear();
|
||||
std::cout <<
|
||||
"\n"
|
||||
"\t\t ____ ____ ____ _ _ __ \n"
|
||||
"\t\t(__ )( __)( _ \\/ )( \\ / _\\ \n"
|
||||
"\t\t / _/ ) _) ) __/) __ (/ \\\n"
|
||||
"\t\t(____)(____)(__) \\_)(_/\\_/\\_/\n" << std::endl;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case Mode::CLIENT: {
|
||||
Client c(path, addr, {1366, 768});
|
||||
break;
|
||||
}
|
||||
Client c({1366, 768});
|
||||
break; }
|
||||
|
||||
case Mode::SERVER: {
|
||||
Server s(addr.port, subgame);
|
||||
break;
|
||||
Server s(port, subgame);
|
||||
break; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
catch (const std::exception& e) {
|
||||
std::cout << Log::err << "Zepha failed to start.\n" << e.what() << Log::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
//
|
||||
// Created by aurailus on 06/01/19.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Client.h"
|
||||
|
||||
#include "../util/Log.h"
|
||||
#include "../util/Timer.h"
|
||||
#include "LocalServerInstance.h"
|
||||
|
||||
|
@ -14,55 +10,60 @@
|
|||
#include "scene/ConnectScene.h"
|
||||
#include "scene/MainMenuScene.h"
|
||||
|
||||
Client::Client(const std::string& path, const Address &addr, glm::ivec2 dims) :
|
||||
state(path.substr(0, path.find_last_of('/') + 1), renderer),
|
||||
renderer(dims),
|
||||
addr(addr),
|
||||
executablePath(path) {
|
||||
|
||||
/**
|
||||
* Creates a client window and starts the main event loop.
|
||||
* Initially opens to the main menu.
|
||||
* @param window - The dimensions for the created window.
|
||||
*/
|
||||
|
||||
Client::Client(glm::ivec2 window) :
|
||||
renderer(window) {
|
||||
|
||||
std::cout << Log::info << "Starting Zepha Client." << Log::endl;
|
||||
|
||||
std::unique_ptr<Scene> scene = std::make_unique<MainMenuScene>(state);
|
||||
// std::unique_ptr<Scene> scene = std::make_unique<LuaErrorScene>(state, "whoopsie poopsie did a fucky wucky");
|
||||
sceneManager.setScene(std::move(scene));
|
||||
|
||||
scene.setScene(std::make_unique<MainMenuScene>(*this));
|
||||
while (!renderer.window.shouldClose()) loop();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the last frame's delta time.
|
||||
* @returns the delta time.
|
||||
*/
|
||||
|
||||
double Client::getDelta() {
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts a local server and connects to it.
|
||||
* @throws runtime_error if a local server is already running.
|
||||
* @param subgame - The subgame for the local server to run.
|
||||
*/
|
||||
|
||||
void Client::startLocalServer(const std::string& subgame) {
|
||||
//TODO: Implement Local Server
|
||||
// localServer = std::make_shared<LocalServerInstance>(executablePath, addr.port, state.subgame);
|
||||
// localServer->start();
|
||||
|
||||
scene.setScene(std::make_unique<ConnectScene>(*this, Address { "127.0.0.1", Address::DEFAULT_PORT }));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The main event loop. Polls GLFW, and updates the scene and the renderer.
|
||||
* Will be called by the Client constructor until render.window.shouldClose() returns true.
|
||||
*/
|
||||
|
||||
void Client::loop() {
|
||||
Timer t("Client Loop");
|
||||
|
||||
if (state.desiredState == "local") {
|
||||
state.desiredState = "connect";
|
||||
localServer = std::make_shared<LocalServerInstance>(executablePath, addr.port, state.subgame);
|
||||
localServer->start();
|
||||
}
|
||||
|
||||
if (state.desiredState == "connect") {
|
||||
state.desiredState = "this";
|
||||
std::unique_ptr<Scene> scene = std::make_unique<ConnectScene>(state, addr);
|
||||
sceneManager.setScene(std::move(scene));
|
||||
}
|
||||
|
||||
if (state.desiredState == "game") {
|
||||
state.desiredState = "this";
|
||||
std::unique_ptr<Scene> scene = std::make_unique<GameScene>(state);
|
||||
sceneManager.setScene(std::move(scene));
|
||||
}
|
||||
|
||||
double now = glfwGetTime();
|
||||
state.delta = now - timeElapsed;
|
||||
delta = now - timeElapsed;
|
||||
timeElapsed = now;
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
sceneManager.update();
|
||||
renderer.update(state.delta);
|
||||
|
||||
state.fps = 1000.0 / (t.elapsedNs() / 1000000.0);
|
||||
}
|
||||
|
||||
Client::~Client() {
|
||||
sceneManager.cleanupScene();
|
||||
if (localServer) localServer->stop();
|
||||
scene.update();
|
||||
renderer.update(delta);
|
||||
}
|
|
@ -1,31 +1,41 @@
|
|||
//
|
||||
// Created by aurailus on 06/01/19.
|
||||
//
|
||||
/*
|
||||
* Main Client object. Contains important properties, such as the renderer and scene manager.
|
||||
* Also manages the local server, if there is one.
|
||||
*
|
||||
* - Auri, 03/11/20
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/net/Address.h"
|
||||
#include "client/ClientState.h"
|
||||
#include "game/LocalSubgame.h"
|
||||
#include "client/graph/Renderer.h"
|
||||
#include "client/scene/SceneManager.h"
|
||||
#include "client/conn/ServerConnection.h"
|
||||
|
||||
class LocalServerInstance;
|
||||
|
||||
class Client {
|
||||
public:
|
||||
Client(const std::string& path, const Address& addr, glm::ivec2 dims);
|
||||
~Client();
|
||||
Client(const Client& o) = delete;
|
||||
explicit Client(glm::ivec2 window);
|
||||
|
||||
double getDelta();
|
||||
|
||||
void startLocalServer(const std::string& subgame);
|
||||
|
||||
Renderer renderer;
|
||||
SceneManager scene;
|
||||
ServerConnection connection {};
|
||||
|
||||
std::shared_ptr<LocalSubgame> game = std::make_shared<LocalSubgame>("../assets/textures");
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
std::string executablePath;
|
||||
Address addr {};
|
||||
Renderer renderer;
|
||||
ClientState state;
|
||||
SceneManager sceneManager;
|
||||
|
||||
std::shared_ptr<LocalServerInstance> localServer = nullptr;
|
||||
|
||||
double timeElapsed = 0.0f;
|
||||
double delta = 0;
|
||||
double timeElapsed = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
//
|
||||
// Created by aurailus on 2019-12-11.
|
||||
//
|
||||
|
||||
#include "ClientState.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
ClientState::ClientState(const std::string& path, Renderer& renderer) :
|
||||
path(path),
|
||||
renderer(renderer),
|
||||
defs(path + "assets\\textures") {}
|
||||
#else
|
||||
ClientState::ClientState(const std::string &path, Renderer &renderer) :
|
||||
path(path),
|
||||
renderer(renderer),
|
||||
game(path + "../assets/textures") {}
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
//
|
||||
// Created by aurailus on 06/01/19.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "game/LocalSubgame.h"
|
||||
#include "client/conn/ServerConnection.h"
|
||||
|
||||
class Renderer;
|
||||
|
||||
class ClientState {
|
||||
public:
|
||||
ClientState(const std::string& path, Renderer& renderer);
|
||||
|
||||
std::string path;
|
||||
std::string subgame;
|
||||
|
||||
Renderer& renderer;
|
||||
ServerConnection connection {};
|
||||
LocalSubgame game;
|
||||
|
||||
unsigned int seed = 0;
|
||||
|
||||
std::string desiredState = "this";
|
||||
|
||||
double fps = 0;
|
||||
double delta = 0;
|
||||
};
|
|
@ -44,3 +44,7 @@ void LocalServerInstance::stop() {
|
|||
std::cout << Log::err << "Local Server destructor not implemented on Windows!" << Log::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
LocalServerInstance::~LocalServerInstance() {
|
||||
stop();
|
||||
}
|
|
@ -18,6 +18,8 @@ public:
|
|||
|
||||
bool start();
|
||||
void stop();
|
||||
|
||||
~LocalServerInstance();
|
||||
private:
|
||||
std::string path;
|
||||
std::string subgame;
|
||||
|
|
|
@ -43,7 +43,7 @@ DebugGui::DebugGui(glm::vec2 bufferSize, SubgamePtr game, WorldPtr world) :
|
|||
add(genGraph);
|
||||
|
||||
auto packetGraph = std::make_shared<GuiLabelledGraph>("packetGraph");
|
||||
packetGraph->create({244, 64}, {}, "Packets", 120, 512, genericHistogramRef, f);
|
||||
packetGraph->create({244, 64}, {}, "Packets", 120, 32, genericHistogramRef, f);
|
||||
add(packetGraph);
|
||||
|
||||
auto fpsGraph = std::make_shared<GuiLabelledGraph>("fpsGraph");
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
//
|
||||
// Created by aurailus on 2019-12-12.
|
||||
//
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cute_files/cute_files.h>
|
||||
|
@ -8,6 +6,7 @@
|
|||
#include "MenuSandbox.h"
|
||||
|
||||
#include "lua/LuaMod.h"
|
||||
#include "client/Client.h"
|
||||
#include "lua/ErrorFormatter.h"
|
||||
#include "client/menu/SubgameDef.h"
|
||||
#include "client/gui/basic/GuiText.h"
|
||||
|
@ -18,12 +17,13 @@
|
|||
#include "lua/modules/mSetGui.h"
|
||||
#include "lua/modules/mStartGame.h"
|
||||
|
||||
MenuSandbox::MenuSandbox(glm::ivec2 &win, ClientState& state, std::shared_ptr<GuiContainer> container) : LuaParser(state.game),
|
||||
MenuSandbox::MenuSandbox(glm::ivec2 &win, Client& client, std::shared_ptr<GuiContainer> container) :
|
||||
LuaParser(*client.game),
|
||||
win(win),
|
||||
state(state),
|
||||
client(client),
|
||||
container(container),
|
||||
luaContainer(std::dynamic_pointer_cast<GuiContainer>(container->add(std::make_shared<GuiContainer>("__lua")))),
|
||||
builder(state.game.textures, state.game.models, luaContainer) {}
|
||||
builder(client.game->textures, client.game->models, luaContainer) {}
|
||||
|
||||
void MenuSandbox::reset() {
|
||||
container->remove("error");
|
||||
|
@ -48,7 +48,7 @@ void MenuSandbox::loadApi() {
|
|||
ClientApi::gui_element(lua);
|
||||
|
||||
MenuApi::set_gui (builder, win, lua, core);
|
||||
MenuApi::start_game (state, core);
|
||||
MenuApi::start_game (client, core);
|
||||
|
||||
bindModules();
|
||||
|
||||
|
@ -87,9 +87,10 @@ sol::protected_function_result MenuSandbox::runFileSandboxed(const std::string&
|
|||
env["_FILE"] = f.path;
|
||||
env["_MODNAME"] = mod.config.name;
|
||||
|
||||
return lua.safe_script(f.file, env, std::bind(&MenuSandbox::errorCallback, this, std::placeholders::_2), "@" + f.path, sol::load_mode::text);
|
||||
return lua.safe_script(f.file, env, std::bind(&MenuSandbox::errorCallback,
|
||||
this, std::placeholders::_2), "@" + f.path, sol::load_mode::text);
|
||||
}
|
||||
throw std::runtime_error("Error opening \"" + file + "\", file not found.");
|
||||
throw std::runtime_error("Error opening '" + file + "', file not found.");
|
||||
}
|
||||
|
||||
void MenuSandbox::loadAndRunMod(const std::string &modPath) {
|
||||
|
@ -149,7 +150,7 @@ void MenuSandbox::loadAndRunMod(const std::string &modPath) {
|
|||
|
||||
std::string texPath = modPath + "/textures";
|
||||
if (cf_file_exists(texPath.data())) {
|
||||
this->modAssets = state.game.textures.loadDirectory(texPath, false, true);
|
||||
this->modAssets = client.game->textures.loadDirectory(texPath, false, true);
|
||||
}
|
||||
|
||||
this->mod = mod;
|
||||
|
@ -158,7 +159,7 @@ void MenuSandbox::loadAndRunMod(const std::string &modPath) {
|
|||
|
||||
void MenuSandbox::showError(const std::string& what, const std::string& subgame) {
|
||||
const std::string errPrefixText = "Encountered an error while loading the menu for " + subgame + " ;-;";
|
||||
Font f(state.game.textures, state.game.textures["font"]);
|
||||
Font f(client.game->textures, client.game->textures["font"]);
|
||||
|
||||
auto errWrap = std::make_shared<GuiContainer>("error");
|
||||
container->add(errWrap);
|
||||
|
|
|
@ -9,15 +9,15 @@
|
|||
#include "lua/LuaMod.h"
|
||||
#include "client/gui/GuiBuilder.h"
|
||||
|
||||
class Client;
|
||||
class Subgame;
|
||||
class AtlasRef;
|
||||
class SubgameDef;
|
||||
class ClientState;
|
||||
class GuiContainer;
|
||||
|
||||
class MenuSandbox : LuaParser {
|
||||
public:
|
||||
MenuSandbox(glm::ivec2& win, ClientState& state, std::shared_ptr<GuiContainer> container);
|
||||
MenuSandbox(glm::ivec2& window, Client& client, std::shared_ptr<GuiContainer> container);
|
||||
void load(const SubgameDef& subgame);
|
||||
|
||||
void update(double delta) override;
|
||||
|
@ -41,6 +41,6 @@ private:
|
|||
std::shared_ptr<GuiContainer> luaContainer = nullptr;
|
||||
GuiBuilder builder;
|
||||
|
||||
ClientState& state;
|
||||
Client& client;
|
||||
glm::ivec2& win;
|
||||
};
|
||||
|
|
|
@ -6,22 +6,31 @@
|
|||
|
||||
#include "ConnectScene.h"
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "util/net/Packet.h"
|
||||
#include "util/net/Address.h"
|
||||
#include "client/ClientState.h"
|
||||
#include "util/net/PacketView.h"
|
||||
#include "client/graph/Renderer.h"
|
||||
#include "client/gui/basic/GuiRect.h"
|
||||
#include "client/gui/basic/GuiText.h"
|
||||
#include "game/atlas/asset/AssetType.h"
|
||||
#include "game/atlas/LocalDefinitionAtlas.h"
|
||||
#include "GameScene.h"
|
||||
|
||||
ConnectScene::ConnectScene(ClientState &state, Address addr) : Scene(state),
|
||||
connection(state.connection) {
|
||||
|
||||
state.renderer.setClearColor(10, 10, 10);
|
||||
/**
|
||||
* Initializes a connection to the remote address,
|
||||
* sets up the GUI, and attempts to download subgame assets.
|
||||
*
|
||||
* @param addr - The server address to connect to.
|
||||
*/
|
||||
|
||||
Font f(state.game.textures, state.game.textures["font"]);
|
||||
ConnectScene::ConnectScene(Client &client, Address addr) : Scene(client),
|
||||
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);
|
||||
|
@ -31,18 +40,18 @@ ConnectScene::ConnectScene(ClientState &state, Address addr) : Scene(state),
|
|||
|
||||
auto loadBar = std::make_shared<GuiRect>("loadBar");
|
||||
loadBar->create({1, 32}, {}, {0.17, 0.75, 0.93, 1});
|
||||
loadBar->setPos({0, state.renderer.window.getSize().y - 32});
|
||||
loadBar->setPos({0, client.renderer.window.getSize().y - 32});
|
||||
components.add(loadBar);
|
||||
|
||||
connection.attemptConnect(std::move(addr));
|
||||
|
||||
state.renderer.window.addResizeCallback("scene", [&](glm::ivec2 win) {
|
||||
client.renderer.window.addResizeCallback("scene", [&](glm::ivec2 win) {
|
||||
components.get<GuiRect>("loadBar")->setPos({0, win.y - 32});
|
||||
});
|
||||
}
|
||||
|
||||
void ConnectScene::update() {
|
||||
state.game.textures.update();
|
||||
client.game->textures.update();
|
||||
|
||||
switch (connectState) {
|
||||
default:
|
||||
|
@ -57,7 +66,7 @@ void ConnectScene::update() {
|
|||
break;
|
||||
|
||||
case State::PROPERTIES: {
|
||||
components.get<GuiRect>("loadBar")->setScale({state.renderer.window.getSize().x * 0.1, 32});
|
||||
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) {
|
||||
|
@ -67,7 +76,8 @@ void ConnectScene::update() {
|
|||
auto statusText = components.get<GuiText>("statusText");
|
||||
statusText->setText(statusText->getText() + "Received server properties.\n");
|
||||
|
||||
state.seed = p.d.read<unsigned int>();
|
||||
// TODO: Reimplement this somewhere or something.
|
||||
// state.seed = p.d.read<unsigned int>();
|
||||
|
||||
connectState = State::IDENTIFIER_LIST;
|
||||
Packet resp(Packet::Type::BLOCK_IDENTIFIER_LIST);
|
||||
|
@ -78,7 +88,7 @@ void ConnectScene::update() {
|
|||
}
|
||||
|
||||
case State::IDENTIFIER_LIST: {
|
||||
components.get<GuiRect>("loadBar")->setScale({state.renderer.window.getSize().x * 0.2, 32});
|
||||
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) {
|
||||
|
@ -88,7 +98,7 @@ void ConnectScene::update() {
|
|||
auto statusText = components.get<GuiText>("statusText");
|
||||
statusText->setText(statusText->getText() + "Received block index-identifier table.\n");
|
||||
|
||||
state.game.getDefs().setIdentifiers(p.d.read<std::vector<std::string>>());
|
||||
client.game->getDefs().setIdentifiers(p.d.read<std::vector<std::string>>());
|
||||
|
||||
Packet resp(Packet::Type::BIOME_IDENTIFIER_LIST);
|
||||
resp.sendTo(connection.getPeer(), Packet::Channel::CONNECT);
|
||||
|
@ -97,7 +107,7 @@ void ConnectScene::update() {
|
|||
auto statusText = components.get<GuiText>("statusText");
|
||||
statusText->setText(statusText->getText() + "Received biome index-identifier table.\nDownloading mods...\n");
|
||||
|
||||
state.game.getBiomes().setIdentifiers(p.d.read<std::vector<std::string>>());
|
||||
client.game->getBiomes().setIdentifiers(p.d.read<std::vector<std::string>>());
|
||||
|
||||
connectState = State::MODS;
|
||||
Packet resp(Packet::Type::MODS);
|
||||
|
@ -108,7 +118,7 @@ void ConnectScene::update() {
|
|||
}
|
||||
|
||||
case State::MODS: {
|
||||
components.get<GuiRect>("loadBar")->setScale({state.renderer.window.getSize().x * 0.4, 32});
|
||||
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);
|
||||
|
@ -118,10 +128,10 @@ void ConnectScene::update() {
|
|||
if (p.type == Packet::Type::MODS) {
|
||||
auto luaMod = LuaMod::fromPacket(p);
|
||||
statusText->setText(statusText->getText() + "Received mod " + luaMod.config.name + ".\n");
|
||||
state.game.getParser().getHandler().addLuaMod(std::move(luaMod));
|
||||
client.game->getParser().getHandler().addLuaMod(std::move(luaMod));
|
||||
}
|
||||
else if (p.type == Packet::Type::MOD_ORDER) {
|
||||
state.game.getParser().getHandler().setModsOrder(p.d.read<std::vector<std::string>>());
|
||||
client.game->getParser().getHandler().setModsOrder(p.d.read<std::vector<std::string>>());
|
||||
|
||||
statusText->setText(statusText->getText() + "Done downloading mods.\nReceived the mods order.\nDownloading media...\n");
|
||||
|
||||
|
@ -134,7 +144,7 @@ void ConnectScene::update() {
|
|||
}
|
||||
|
||||
case State::MEDIA: {
|
||||
components.get<GuiRect>("loadBar")->setScale({state.renderer.window.getSize().x * 0.6, 32});
|
||||
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) {
|
||||
|
@ -156,15 +166,15 @@ void ConnectScene::update() {
|
|||
std::string data = p.d.read<std::string>();
|
||||
std::string uncompressed = gzip::decompress(data.data(), data.length());
|
||||
|
||||
state.game.textures.addImage(
|
||||
reinterpret_cast<unsigned char *>(const_cast<char *>(uncompressed.data())),
|
||||
assetName, true, width, height);
|
||||
client.game->textures.addImage(
|
||||
reinterpret_cast<unsigned char *>(const_cast<char *>(uncompressed.data())),
|
||||
assetName, true, width, height);
|
||||
}
|
||||
else if (t == AssetType::MODEL) {
|
||||
std::string format = p.d.read<std::string>();
|
||||
std::string data = p.d.read<std::string>();
|
||||
|
||||
state.game.models.models.insert({assetName, SerializedModel{assetName, data, format}});
|
||||
client.game->models.models.insert({assetName, SerializedModel{assetName, data, format}});
|
||||
}
|
||||
|
||||
t = static_cast<AssetType>(p.d.read<int>());
|
||||
|
@ -174,11 +184,11 @@ void ConnectScene::update() {
|
|||
statusText->setText(statusText->getText() + "Received " + std::to_string(count) + "x media files.\n");
|
||||
}
|
||||
else if (p.type == Packet::Type::MEDIA_DONE) {
|
||||
components.get<GuiRect>("loadBar")->setScale({state.renderer.window.getSize().x, 32});
|
||||
components.get<GuiRect>("loadBar")->setScale({client.renderer.window.getSize().x, 32});
|
||||
statusText->setText(statusText->getText() + "Done downloading media.\nJoining world...\n");
|
||||
|
||||
connectState = State::DONE;
|
||||
state.desiredState = "game";
|
||||
client.scene.setScene(std::make_unique<GameScene>(client));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -206,7 +216,7 @@ void ConnectScene::handleConnecting() {
|
|||
case ServerConnection::State::ATTEMPTING_CONNECT:
|
||||
connection.processConnecting();
|
||||
|
||||
dotsTime += state.delta;
|
||||
dotsTime += client.getDelta();
|
||||
if (dotsTime > 1) {
|
||||
dotsTime -= 1;
|
||||
statusText->setText(statusText->getText() + ".");
|
||||
|
@ -225,12 +235,12 @@ void ConnectScene::handleConnecting() {
|
|||
}
|
||||
|
||||
void ConnectScene::draw() {
|
||||
Renderer& renderer = state.renderer;
|
||||
Renderer& renderer = client.renderer;
|
||||
|
||||
renderer.beginChunkDeferredCalls();
|
||||
renderer.endDeferredCalls();
|
||||
renderer.beginGUIDrawCalls();
|
||||
renderer.enableTexture(&state.game.textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
|
||||
components.draw(renderer);
|
||||
|
||||
|
@ -238,5 +248,5 @@ void ConnectScene::draw() {
|
|||
}
|
||||
|
||||
void ConnectScene::cleanup() {
|
||||
state.renderer.window.removeResizeCallback("scene");
|
||||
client.renderer.window.removeResizeCallback("scene");
|
||||
}
|
|
@ -23,15 +23,14 @@ public:
|
|||
DONE
|
||||
};
|
||||
|
||||
ConnectScene(ClientState& state, Address addr);
|
||||
ConnectScene(Client& state, Address addr);
|
||||
|
||||
void update() override;
|
||||
void draw() override;
|
||||
void cleanup() override;
|
||||
|
||||
void handleConnecting();
|
||||
|
||||
void draw() override;
|
||||
|
||||
void cleanup() override;
|
||||
private:
|
||||
State connectState = State::CONNECTING;
|
||||
ServerConnection& connection;
|
||||
|
|
|
@ -4,36 +4,36 @@
|
|||
|
||||
#include "GameScene.h"
|
||||
|
||||
#include "client/ClientState.h"
|
||||
#include "client/Client.h"
|
||||
#include "util/net/PacketView.h"
|
||||
#include "client/graph/Renderer.h"
|
||||
|
||||
GameScene::GameScene(ClientState& state) : Scene(state),
|
||||
game(std::make_shared<LocalSubgame>(state.game)),
|
||||
world(std::make_shared<LocalWorld>(game, state.connection, state.renderer)),
|
||||
debugGui(state.renderer.window.getSize(), game, world) {
|
||||
GameScene::GameScene(Client& client) : Scene(client),
|
||||
world(std::make_shared<LocalWorld>(client.game, client.connection, client.renderer)),
|
||||
debugGui(client.renderer.window.getSize(), client.game, world) {
|
||||
|
||||
Packet r(Packet::Type::CONNECT_DATA_RECVD);
|
||||
r.sendTo(state.connection.getPeer(), Packet::Channel::CONNECT);
|
||||
r.sendTo(client.connection.getPeer(), Packet::Channel::CONNECT);
|
||||
|
||||
world.l()->connect();
|
||||
game .l()->init(world, world.l()->getPlayer(), state);
|
||||
client.game->init(world, world.l()->getPlayer(), client);
|
||||
world.l()->updatePlayerDimension();
|
||||
|
||||
state.renderer.window.addResizeCallback("gamescene", Util::bind_this(&debugGui, &DebugGui::bufferResized));
|
||||
state.renderer.setClearColor(148, 194, 240);
|
||||
state.renderer.window.input.lockMouse(true);
|
||||
client.renderer.window.addResizeCallback("gamescene", Util::bind_this(&debugGui, &DebugGui::bufferResized));
|
||||
client.renderer.setClearColor(148, 194, 240);
|
||||
client.renderer.window.input.lockMouse(true);
|
||||
}
|
||||
|
||||
void GameScene::update() {
|
||||
Window& window = state.renderer.window;
|
||||
Window& window = client.renderer.window;
|
||||
|
||||
game.l()->update(state.delta);
|
||||
world->update(state.delta);
|
||||
client.game->update(client.getDelta());
|
||||
world->update(client.getDelta());
|
||||
|
||||
for (auto entity : entities) entity->update(state.delta);
|
||||
for (auto entity : entities) entity->update(client.getDelta());
|
||||
|
||||
debugGui.update(world.l()->getPlayer().l(), state.fps, world.l()->getActiveDimension().l()->getMeshChunkCount(),
|
||||
double lastFps = 1 / client.getDelta();
|
||||
debugGui.update(world.l()->getPlayer().l(), lastFps, world.l()->getActiveDimension().l()->getMeshChunkCount(),
|
||||
drawCalls, world.l()->getNet().serverSideChunkGens, world.l()->getNet().recvPackets);
|
||||
|
||||
world.l()->getNet().serverSideChunkGens = 0;
|
||||
|
@ -52,11 +52,11 @@ void GameScene::update() {
|
|||
}
|
||||
|
||||
void GameScene::draw() {
|
||||
Renderer& renderer = state.renderer;
|
||||
Renderer& renderer = client.renderer;
|
||||
Camera& camera = renderer.camera;
|
||||
|
||||
renderer.beginChunkDeferredCalls();
|
||||
renderer.enableTexture(&game.l()->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
|
||||
drawCalls = world.l()->renderChunks(renderer);
|
||||
|
||||
|
@ -67,7 +67,7 @@ void GameScene::draw() {
|
|||
|
||||
renderer.endDeferredCalls();
|
||||
renderer.beginGUIDrawCalls();
|
||||
renderer.enableTexture(&game.l()->textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
|
||||
world.l()->getPlayer().l()->drawHud(renderer);
|
||||
debugGui.draw(renderer);
|
||||
|
@ -77,5 +77,5 @@ void GameScene::draw() {
|
|||
}
|
||||
|
||||
void GameScene::cleanup() {
|
||||
state.renderer.window.removeResizeCallback("gamescene");
|
||||
client.renderer.window.removeResizeCallback("gamescene");
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@ class Drawable;
|
|||
|
||||
class GameScene : public Scene {
|
||||
public:
|
||||
explicit GameScene(ClientState& state);
|
||||
GameScene(Client& client);
|
||||
|
||||
void update() override;
|
||||
void draw() override;
|
||||
|
||||
void cleanup() override;
|
||||
|
||||
public:
|
||||
SubgamePtr game;
|
||||
WorldPtr world;
|
||||
|
||||
DebugGui debugGui;
|
||||
|
|
|
@ -4,18 +4,18 @@
|
|||
|
||||
#include "LuaErrorScene.h"
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "client/graph/Font.h"
|
||||
#include "client/ClientState.h"
|
||||
#include "client/graph/Renderer.h"
|
||||
#include "client/gui/basic/GuiRect.h"
|
||||
#include "client/gui/basic/GuiText.h"
|
||||
|
||||
LuaErrorScene::LuaErrorScene(ClientState &state, const std::string &err) : Scene(state), err(err) {
|
||||
state.renderer.setClearColor(0, 0, 0);
|
||||
state.renderer.window.input.lockMouse(false);
|
||||
LuaErrorScene::LuaErrorScene(Client& client, const std::string &err) : Scene(client), err(err) {
|
||||
client.renderer.setClearColor(0, 0, 0);
|
||||
client.renderer.window.input.lockMouse(false);
|
||||
|
||||
Font f(state.game.textures, state.game.textures["font"]);
|
||||
glm::ivec2 win = state.renderer.window.getSize();
|
||||
Font f(client.game->textures, client.game->textures["font"]);
|
||||
glm::ivec2 win = client.renderer.window.getSize();
|
||||
|
||||
auto container = std::make_shared<GuiRect>("container");
|
||||
container->create({800, 500}, {}, {0.05, 0.05, 0.05, 1});
|
||||
|
@ -34,22 +34,22 @@ LuaErrorScene::LuaErrorScene(ClientState &state, const std::string &err) : Scene
|
|||
errorText->setPos({16, 48});
|
||||
container->add(errorText);
|
||||
|
||||
state.renderer.window.addResizeCallback("scene", [&](glm::ivec2 win) {
|
||||
client.renderer.window.addResizeCallback("scene", [&](glm::ivec2 win) {
|
||||
components.get<GuiRect>("container")->setPos({win.x / 2 - 800 / 2, win.y / 2 - 500 / 2});
|
||||
});
|
||||
}
|
||||
|
||||
void LuaErrorScene::update() {
|
||||
state.game.textures.update();
|
||||
client.game->textures.update();
|
||||
}
|
||||
|
||||
void LuaErrorScene::draw() {
|
||||
Renderer& renderer = state.renderer;
|
||||
Renderer& renderer = client.renderer;
|
||||
|
||||
renderer.beginChunkDeferredCalls();
|
||||
renderer.endDeferredCalls();
|
||||
renderer.beginGUIDrawCalls();
|
||||
renderer.enableTexture(&state.game.textures.atlasTexture);
|
||||
renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
|
||||
components.draw(renderer);
|
||||
|
||||
|
@ -57,5 +57,5 @@ void LuaErrorScene::draw() {
|
|||
}
|
||||
|
||||
void LuaErrorScene::cleanup() {
|
||||
state.renderer.window.removeResizeCallback("scene");
|
||||
client.renderer.window.removeResizeCallback("scene");
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
class LuaErrorScene : public Scene {
|
||||
public:
|
||||
LuaErrorScene(ClientState& state, const std::string& err);
|
||||
LuaErrorScene(Client& client, const std::string& err);
|
||||
|
||||
void update() override;
|
||||
void draw() override;
|
||||
|
|
|
@ -10,28 +10,32 @@
|
|||
#include "MainMenuScene.h"
|
||||
|
||||
#include "util/Log.h"
|
||||
#include "client/ClientState.h"
|
||||
#include "client/Client.h"
|
||||
#include "client/graph/Renderer.h"
|
||||
#include "client/menu/SubgameDef.h"
|
||||
#include "client/gui/basic/GuiText.h"
|
||||
#include "game/atlas/asset/AtlasRef.h"
|
||||
#include "client/gui/basic/GuiContainer.h"
|
||||
#include "client/gui/compound/GuiImageButton.h"
|
||||
#include "ConnectScene.h"
|
||||
|
||||
MainMenuScene::MainMenuScene(ClientState& state) :
|
||||
Scene(state),
|
||||
sandbox(sandboxArea, state, menuContainer) {
|
||||
MainMenuScene::MainMenuScene(Client& client) :
|
||||
Scene(client),
|
||||
components(std::make_unique<GuiContainer>()),
|
||||
menuContainer(std::make_shared<GuiContainer>("__menu")),
|
||||
sandbox(sandboxArea, client, menuContainer) {
|
||||
|
||||
state.renderer.setClearColor(0, 0, 0);
|
||||
state.renderer.window.input.lockMouse(false);
|
||||
client.renderer.setClearColor(0, 0, 0);
|
||||
client.renderer.window.input.lockMouse(false);
|
||||
|
||||
Font f(state.game.textures, state.game.textures["font"]);
|
||||
win = state.renderer.window.getSize();
|
||||
Font f(client.game->textures, client.game->textures["font"]);
|
||||
win = client.renderer.window.getSize();
|
||||
sandboxArea = win - glm::ivec2(0, 18 * GS);
|
||||
|
||||
components.add(menuContainer);
|
||||
components->add(menuContainer);
|
||||
|
||||
branding = std::make_shared<GuiContainer>("zephaBranding");
|
||||
components.add(branding);
|
||||
components->add(branding);
|
||||
{
|
||||
auto zephaText = std::make_shared<GuiText>("zephaText");
|
||||
zephaText->create({GS, GS}, {}, {}, {1, 1, 1, 1}, f);
|
||||
|
@ -51,34 +55,42 @@ MainMenuScene::MainMenuScene(ClientState& state) :
|
|||
|
||||
auto navigationBarIcons = navigationBar->get<GuiContainer>("navigationBarIcons");
|
||||
|
||||
components.add(navigationBar);
|
||||
components->add(navigationBar);
|
||||
{
|
||||
auto settingsButton = std::make_shared<GuiImageButton>("settingsButton");
|
||||
settingsButton->create({16 * GS, 16 * GS}, {},
|
||||
state.game.textures["crop(0, 0, 16, 16, menu_flag_settings)"],
|
||||
state.game.textures["crop(16, 0, 16, 16, menu_flag_settings)"]);
|
||||
client.game->textures["crop(0, 0, 16, 16, menu_flag_settings)"],
|
||||
client.game->textures["crop(16, 0, 16, 16, menu_flag_settings)"]);
|
||||
|
||||
navigationBar->get<GuiContainer>("navigationBarIcons")->add(settingsButton);
|
||||
|
||||
auto closeButton = std::make_shared<GuiImageButton>("closeButton");
|
||||
closeButton->create({16 * GS, 16 * GS}, {},
|
||||
state.game.textures["crop(0, 0, 16, 16, menu_flag_quit)"],
|
||||
state.game.textures["crop(16, 0, 16, 16, menu_flag_quit)"]);
|
||||
client.game->textures["crop(0, 0, 16, 16, menu_flag_quit)"],
|
||||
client.game->textures["crop(16, 0, 16, 16, menu_flag_quit)"]);
|
||||
|
||||
closeButton->setCallback(GuiComponent::CallbackType::PRIMARY, [](bool down, glm::ivec2) { if (down) exit(0); });
|
||||
navigationBar->get<GuiContainer>("navigationBarIcons")->add(closeButton);
|
||||
|
||||
auto serversButton = std::make_shared<GuiImageButton>("serversButton");
|
||||
serversButton->create({16 * GS, 16 * GS}, {},
|
||||
state.game.textures["crop(0, 0, 16, 16, menu_flag_multiplayer)"],
|
||||
state.game.textures["crop(16, 0, 16, 16, menu_flag_multiplayer)"]);
|
||||
client.game->textures["crop(0, 0, 16, 16, menu_flag_multiplayer)"],
|
||||
client.game->textures["crop(16, 0, 16, 16, menu_flag_multiplayer)"]);
|
||||
|
||||
serversButton->setPos({GS, GS});
|
||||
navigationBarIcons->add(serversButton);
|
||||
|
||||
auto contentButton = std::make_shared<GuiImageButton>("contentButton");
|
||||
contentButton->create({16 * GS, 16 * GS}, {},
|
||||
state.game.textures["crop(0, 0, 16, 16, menu_flag_content)"],
|
||||
state.game.textures["crop(16, 0, 16, 16, menu_flag_content)"]);
|
||||
client.game->textures["crop(0, 0, 16, 16, menu_flag_content)"],
|
||||
client.game->textures["crop(16, 0, 16, 16, menu_flag_content)"]);
|
||||
|
||||
contentButton->setPos({GS + GS * 18, GS});
|
||||
contentButton->setCallback(GuiComponent::CallbackType::PRIMARY, [&](bool down, glm::ivec2) { if (down) state.desiredState = "connect"; });
|
||||
contentButton->setCallback(GuiComponent::CallbackType::PRIMARY, [&](bool down, glm::ivec2) {
|
||||
if (!down) return;
|
||||
client.scene.setScene(std::make_unique<ConnectScene>(client, Address { "127.0.0.1" }));
|
||||
});
|
||||
|
||||
navigationBarIcons->add(contentButton);
|
||||
|
||||
auto divider = std::make_shared<GuiRect>("divider");
|
||||
|
@ -91,16 +103,18 @@ MainMenuScene::MainMenuScene(ClientState& state) :
|
|||
for (unsigned int i = 0; i < subgames.size(); i++) {
|
||||
auto &subgame = subgames[i];
|
||||
auto button = std::make_shared<GuiImageButton>(subgame.config.name);
|
||||
|
||||
button->create({16 * GS, 16 * GS}, {},
|
||||
state.game.textures["crop(0, 0, 16, 16, " + subgame.iconRef->name + ")"],
|
||||
state.game.textures["crop(16, 0, 16, 16, " + subgame.iconRef->name + ")"]);
|
||||
client.game->textures["crop(0, 0, 16, 16, " + subgame.iconRef->name + ")"],
|
||||
client.game->textures["crop(16, 0, 16, 16, " + subgame.iconRef->name + ")"]);
|
||||
|
||||
button->setPos({GS * 7 + GS * 18 * (i + 2), GS});
|
||||
button->setCallback(GuiComponent::CallbackType::PRIMARY, [&, i](bool down, glm::ivec2) {
|
||||
if (down) {
|
||||
selectedSubgame = &subgame;
|
||||
sandbox.load(*selectedSubgame);
|
||||
}
|
||||
button->setCallback(GuiComponent::CallbackType::PRIMARY, [&](bool down, glm::ivec2) {
|
||||
if (!down) return;
|
||||
selectedSubgame = &subgame;
|
||||
sandbox.load(*selectedSubgame);
|
||||
});
|
||||
|
||||
navigationBarIcons->add(button);
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +126,7 @@ MainMenuScene::MainMenuScene(ClientState& state) :
|
|||
|
||||
positionElements();
|
||||
|
||||
state.renderer.window.addResizeCallback("mainmenu", [&](glm::ivec2 win) {
|
||||
client.renderer.window.addResizeCallback("mainmenu", [&](glm::ivec2 win) {
|
||||
this->win = win;
|
||||
sandboxArea = win - glm::ivec2(0, 18 * GS);
|
||||
positionElements();
|
||||
|
@ -120,7 +134,7 @@ MainMenuScene::MainMenuScene(ClientState& state) :
|
|||
}
|
||||
|
||||
void MainMenuScene::findSubgames() {
|
||||
std::string subgamesPath = state.path + "../subgames";
|
||||
std::string subgamesPath = "../subgames";
|
||||
|
||||
cf_dir_t subgamesDir;
|
||||
cf_dir_open(&subgamesDir, subgamesPath.data());
|
||||
|
@ -165,8 +179,8 @@ void MainMenuScene::findSubgames() {
|
|||
std::string description = (j["description"].is_string() ? j["description"] : "");
|
||||
std::string version = j["version"];
|
||||
|
||||
std::shared_ptr<AtlasRef> icon = state.game.textures["menu_flag_missing"];
|
||||
if (hasIcon) icon = state.game.textures.loadImage(std::string(subgameFolder.path) + "/icon.png", name);
|
||||
std::shared_ptr<AtlasRef> icon = client.game->textures["menu_flag_missing"];
|
||||
if (hasIcon) icon = client.game->textures.loadImage(std::string(subgameFolder.path) + "/icon.png", name);
|
||||
|
||||
subgames.push_back({icon, {name, description, version}, subgameFolder.path});
|
||||
}
|
||||
|
@ -191,7 +205,7 @@ void MainMenuScene::positionElements() {
|
|||
auto navigationBarBg = navigationBar->get<GuiContainer>("navigationBarBg");
|
||||
for (unsigned int i = 0; i < static_cast<float>(win.x) / 64.f / GS; i++) {
|
||||
auto segment = std::make_shared<GuiRect>("segment_" + std::to_string(i));
|
||||
segment->create({64 * GS, 18 * GS}, {}, state.game.textures["menu_bar_bg"]);
|
||||
segment->create({64 * GS, 18 * GS}, {}, client.game->textures["menu_bar_bg"]);
|
||||
segment->setPos({i * 64 * GS, 0});
|
||||
navigationBarBg->add(segment);
|
||||
}
|
||||
|
@ -202,23 +216,23 @@ void MainMenuScene::positionElements() {
|
|||
}
|
||||
|
||||
void MainMenuScene::update() {
|
||||
state.game.textures.update();
|
||||
sandbox.update(state.delta);
|
||||
client.game->textures.update();
|
||||
sandbox.update(client.getDelta());
|
||||
|
||||
components.handleMouseInput(state.renderer.window);
|
||||
components->handleMouseInput(client.renderer.window);
|
||||
}
|
||||
|
||||
void MainMenuScene::draw() {
|
||||
state.renderer.beginChunkDeferredCalls();
|
||||
state.renderer.endDeferredCalls();
|
||||
client.renderer.beginChunkDeferredCalls();
|
||||
client.renderer.endDeferredCalls();
|
||||
|
||||
state.renderer.beginGUIDrawCalls();
|
||||
state.renderer.enableTexture(&state.game.textures.atlasTexture);
|
||||
components.draw(state.renderer);
|
||||
state.renderer.swapBuffers();
|
||||
client.renderer.beginGUIDrawCalls();
|
||||
client.renderer.enableTexture(&client.game->textures.atlasTexture);
|
||||
components->draw(client.renderer);
|
||||
client.renderer.swapBuffers();
|
||||
}
|
||||
|
||||
void MainMenuScene::cleanup() {
|
||||
state.renderer.window.setCursorHand(false);
|
||||
state.renderer.window.removeResizeCallback("mainmenu");
|
||||
}
|
||||
client.renderer.window.setCursorHand(false);
|
||||
client.renderer.window.removeResizeCallback("mainmenu");
|
||||
}
|
|
@ -8,13 +8,12 @@
|
|||
|
||||
#include "client/menu/SubgameDef.h"
|
||||
#include "client/menu/MenuSandbox.h"
|
||||
#include "client/gui/basic/GuiContainer.h"
|
||||
|
||||
class ClientState;
|
||||
class Client;
|
||||
|
||||
class MainMenuScene : public Scene {
|
||||
public:
|
||||
explicit MainMenuScene(ClientState& state);
|
||||
explicit MainMenuScene(Client& client);
|
||||
|
||||
void update() override;
|
||||
void draw() override;
|
||||
|
@ -24,15 +23,15 @@ private:
|
|||
void positionElements();
|
||||
void findSubgames();
|
||||
|
||||
const float GS = 3;
|
||||
static constexpr float GS = 3;
|
||||
|
||||
glm::ivec2 win {};
|
||||
glm::ivec2 sandboxArea {};
|
||||
|
||||
GuiContainer components;
|
||||
std::shared_ptr<GuiContainer> branding = nullptr;
|
||||
std::shared_ptr<GuiContainer> navigationBar = nullptr;
|
||||
std::shared_ptr<GuiContainer> menuContainer = std::make_shared<GuiContainer>("__menu");
|
||||
std::unique_ptr<GuiContainer> components;
|
||||
std::shared_ptr<GuiContainer> branding;
|
||||
std::shared_ptr<GuiContainer> navigationBar;
|
||||
std::shared_ptr<GuiContainer> menuContainer;
|
||||
|
||||
MenuSandbox sandbox;
|
||||
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
//
|
||||
// Created by aurailus on 06/01/19.
|
||||
//
|
||||
/*
|
||||
* Scene abstract superclass, provides base scene methods for use by SceneManager.
|
||||
* Stores a reference to the client, for children.
|
||||
*
|
||||
* - Auri, 03/11/20
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class ClientState;
|
||||
class Client;
|
||||
|
||||
class Scene {
|
||||
public:
|
||||
explicit Scene(ClientState& state) : state(state) {}
|
||||
explicit Scene(Client& client) : client(client) {}
|
||||
|
||||
virtual void update() = 0;
|
||||
virtual void draw() = 0;
|
||||
|
@ -16,6 +19,6 @@ public:
|
|||
|
||||
virtual ~Scene() = default;
|
||||
|
||||
ClientState& state;
|
||||
Client& client;
|
||||
};
|
||||
|
||||
|
|
|
@ -4,27 +4,55 @@
|
|||
|
||||
#include "SceneManager.h"
|
||||
|
||||
|
||||
/**
|
||||
* Sets a new scene as the current scene.
|
||||
* Cleans up the old scene.
|
||||
* @param newScene - The new current scene.
|
||||
*/
|
||||
|
||||
void SceneManager::setScene(std::unique_ptr<Scene> newScene) {
|
||||
cleanupScene();
|
||||
scene = std::move(newScene);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a reference to the current scene.
|
||||
* @returns The current scene as a const reference.
|
||||
*/
|
||||
|
||||
const Scene& SceneManager::getScene() {
|
||||
return *scene;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates and renders the current scene, if there is one.
|
||||
*/
|
||||
|
||||
void SceneManager::update() {
|
||||
if (!scene) return;
|
||||
scene->update();
|
||||
scene->draw();
|
||||
}
|
||||
|
||||
void SceneManager::setScene(std::unique_ptr<Scene> scene) {
|
||||
if (this->scene != nullptr) cleanupScene();
|
||||
this->scene = std::move(scene);
|
||||
}
|
||||
|
||||
Scene& SceneManager::getScene() {
|
||||
return *scene;
|
||||
}
|
||||
/**
|
||||
* Cleans up the current scene and removes it.
|
||||
* There will be no current scene after this method executes.
|
||||
*/
|
||||
|
||||
void SceneManager::cleanupScene() {
|
||||
if (scene != nullptr) {
|
||||
scene->cleanup();
|
||||
scene = nullptr;
|
||||
}
|
||||
if (scene) scene->cleanup();
|
||||
scene = nullptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clean up the scene on destruction.
|
||||
*/
|
||||
|
||||
SceneManager::~SceneManager() {
|
||||
cleanupScene();
|
||||
}
|
|
@ -10,15 +10,14 @@
|
|||
|
||||
class SceneManager {
|
||||
public:
|
||||
SceneManager() = default;
|
||||
|
||||
void setScene(std::unique_ptr<Scene> scene);
|
||||
Scene& getScene();
|
||||
const Scene& getScene();
|
||||
|
||||
void update();
|
||||
void cleanupScene();
|
||||
|
||||
~SceneManager();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Scene> scene = nullptr;
|
||||
};
|
||||
|
|
|
@ -4,24 +4,42 @@
|
|||
|
||||
#include "LocalSubgame.h"
|
||||
|
||||
LocalSubgame::LocalSubgame(const std::string& texPath) :
|
||||
texPath(texPath),
|
||||
|
||||
/**
|
||||
* Creates subgame instances, including the lua parser, and biome and block atlases.
|
||||
* Also loads base assets into the texture atlas.
|
||||
* @param baseAssets - The relative path to the base texture assets.
|
||||
*/
|
||||
|
||||
LocalSubgame::LocalSubgame(const std::string& baseAssets) :
|
||||
textures(2048),
|
||||
|
||||
lua(std::make_unique<LocalLuaParser>(*this)),
|
||||
biomes(std::make_unique<LocalBiomeAtlas>()),
|
||||
defs(std::make_unique<LocalDefinitionAtlas>(textures)) {
|
||||
|
||||
textures.loadDirectory(texPath);
|
||||
textures.loadDirectory(baseAssets);
|
||||
}
|
||||
|
||||
void LocalSubgame::init(WorldPtr world, PlayerPtr player, ClientState& state) {
|
||||
lua->init(world, player, state);
|
||||
|
||||
/**
|
||||
* Initializes the Lua Parser.
|
||||
* @param world - Passed in to the Lua Parser.
|
||||
* @param player - Passed in to the Lua Parser.
|
||||
* @param client - Passed in to the Lua Parser.
|
||||
*/
|
||||
|
||||
void LocalSubgame::init(WorldPtr world, PlayerPtr player, Client& client) {
|
||||
lua->init(world, player, client);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the lua parser and the texture atlas.
|
||||
* @param delta - The last frame's delta time.
|
||||
*/
|
||||
|
||||
void LocalSubgame::update(double delta) {
|
||||
lua->update(delta);
|
||||
textures.update();
|
||||
}
|
||||
|
||||
LocalSubgame::~LocalSubgame() {}
|
||||
|
|
|
@ -1,35 +1,32 @@
|
|||
//
|
||||
// The ClientGame class stores all of the subgame data for the client.
|
||||
// This data is used when in the GameScene. It is initialized when the client joins a game and cleared when they exit it.
|
||||
// The data within is in an undefined state until the init method is called.
|
||||
// Created by aurailus on 18/04/19.
|
||||
//
|
||||
/*
|
||||
* The Local Subgame stores all local subgame data.
|
||||
* Includes Block / Item definitions, biome definitions, the lua parser, models, and textures.
|
||||
*
|
||||
* - Auri, 03/11/20
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Subgame.h"
|
||||
|
||||
#include "game/atlas/asset/ModelStore.h"
|
||||
#include "game/atlas/LocalBiomeAtlas.h"
|
||||
#include "game/atlas/LocalDefinitionAtlas.h"
|
||||
#include "game/atlas/TextureAtlas.h"
|
||||
#include "util/CovariantPtr.h"
|
||||
#include "lua/LocalLuaParser.h"
|
||||
#include "game/atlas/TextureAtlas.h"
|
||||
#include "game/atlas/LocalBiomeAtlas.h"
|
||||
#include "game/atlas/asset/ModelStore.h"
|
||||
#include "game/atlas/LocalDefinitionAtlas.h"
|
||||
|
||||
class LocalPlayer;
|
||||
class Client;
|
||||
class LocalWorld;
|
||||
class ClientState;
|
||||
class LocalPlayer;
|
||||
|
||||
class LocalSubgame : public Subgame {
|
||||
public:
|
||||
explicit LocalSubgame(const std::string& texPath);
|
||||
~LocalSubgame();
|
||||
explicit LocalSubgame(const std::string& baseAssets);
|
||||
|
||||
void init(WorldPtr world, PlayerPtr player, ClientState& state);
|
||||
void init(WorldPtr world, PlayerPtr player, Client& client);
|
||||
void update(double delta);
|
||||
|
||||
std::string texPath;
|
||||
|
||||
LocalDefinitionAtlas& getDefs() override { return *defs; };
|
||||
LocalBiomeAtlas& getBiomes() override { return *biomes; };
|
||||
LocalLuaParser& getParser() override { return *lua; };
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include "LocalLuaParser.h"
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "ErrorFormatter.h"
|
||||
#include "client/ClientState.h"
|
||||
#include "client/graph/Renderer.h"
|
||||
#include "register/RegisterItems.h"
|
||||
#include "register/RegisterBlocks.h"
|
||||
|
@ -33,12 +33,12 @@
|
|||
|
||||
LocalLuaParser::LocalLuaParser(LocalSubgame& game): LuaParser(game), keybinds(this) {}
|
||||
|
||||
void LocalLuaParser::init(WorldPtr world, PlayerPtr player, ClientState& state) {
|
||||
void LocalLuaParser::init(WorldPtr world, PlayerPtr player, 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));
|
||||
state.renderer.window.input.setCallback(Util::bind_this(&keybinds, &LuaKeybindHandler::keybindHandler));
|
||||
client.renderer.window.input.setCallback(Util::bind_this(&keybinds, &LuaKeybindHandler::keybindHandler));
|
||||
|
||||
registerDefs();
|
||||
}
|
||||
|
|
|
@ -4,21 +4,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "LuaParser.h"
|
||||
#include "lua/LuaParser.h"
|
||||
|
||||
#include "LocalModHandler.h"
|
||||
#include "LuaKeybindHandler.h"
|
||||
#include "../util/CovariantPtr.h"
|
||||
#include "util/CovariantPtr.h"
|
||||
#include "lua/LocalModHandler.h"
|
||||
#include "lua/LuaKeybindHandler.h"
|
||||
|
||||
class LocalPlayer;
|
||||
class Client;
|
||||
class LocalWorld;
|
||||
class ClientState;
|
||||
class LocalPlayer;
|
||||
class LocalSubgame;
|
||||
|
||||
class LocalLuaParser : public LuaParser {
|
||||
public:
|
||||
explicit LocalLuaParser(LocalSubgame& game);
|
||||
void init(WorldPtr world, PlayerPtr player, ClientState& state);
|
||||
void init(WorldPtr world, PlayerPtr player, Client& client);
|
||||
|
||||
void update(double delta) override;
|
||||
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
#include <list>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include "lua/Lua.h"
|
||||
#include "util/CovariantPtr.h"
|
||||
#include "modules/SubgameModule.h"
|
||||
|
||||
#include "Lua.h"
|
||||
#include "../util/CovariantPtr.h"
|
||||
|
||||
class Subgame;
|
||||
|
||||
class LuaParser {
|
||||
|
|
|
@ -4,21 +4,23 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../Lua.h"
|
||||
#include "client/ClientState.h"
|
||||
#include "lua/Lua.h"
|
||||
#include "client/Client.h"
|
||||
#include "util/net/Address.h"
|
||||
#include "client/scene/ConnectScene.h"
|
||||
|
||||
namespace MenuApi {
|
||||
void start_game(ClientState& state, sol::table& core) {
|
||||
void start_game(Client& client, sol::table& core) {
|
||||
//TODO: Don't hardcode the subgame
|
||||
|
||||
core.set_function("start_game", [&]() {
|
||||
state.subgame = "zeus";
|
||||
state.desiredState = "connect";
|
||||
core.set_function("game_connect", [&](std::string address) {
|
||||
client.scene.setScene(std::make_unique<ConnectScene>(client, Address::fromString(address)));
|
||||
});
|
||||
|
||||
core.set_function("start_game_local", [&]() {
|
||||
state.subgame = "zeus";
|
||||
state.desiredState = "local";
|
||||
core.set_function("game_host", [&](sol::this_state s) {
|
||||
sol::state_view state(s);
|
||||
const auto subgame = state.get<std::string>("zepha.__builtin.subgame");
|
||||
client.startLocalServer(subgame);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@ class ServerInventoryRefs;
|
|||
template <typename B, typename L, typename S>
|
||||
class CovariantPtr {
|
||||
std::shared_ptr<B> b = nullptr;
|
||||
|
||||
public:
|
||||
CovariantPtr() = default;
|
||||
CovariantPtr(std::nullptr_t) {};
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Created by auri on 2020-11-03.
|
||||
//
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Address.h"
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Address object from the provided address string.
|
||||
* Address string should be in standard dot + optional colon notation, e.g: 192.168.0.1:8000, 127.0.0.1.
|
||||
* @throws std::invalid_argument - There is a value after a colon that cannot be converted into a valid numeric value.
|
||||
* @throws std::out_of_range - There is a numeric port specified, but it is greater than the maximum unsigned short.
|
||||
* @param addressString - The string to parse.
|
||||
* @returns - An Address object with the specified address.
|
||||
*/
|
||||
|
||||
Address Address::fromString(const std::string &addressString) {
|
||||
std::string address;
|
||||
unsigned short port;
|
||||
|
||||
size_t sep = addressString.find(':');
|
||||
if (sep == std::string::npos) {
|
||||
address = address;
|
||||
port = Address::DEFAULT_PORT;
|
||||
}
|
||||
else {
|
||||
address = addressString.substr(0, sep++); // Increment sep for next substr call.
|
||||
unsigned int p = stoi(addressString.substr(sep, addressString.length() - sep));
|
||||
if (p > 65535) throw std::out_of_range("Port value is greater than 65535.");
|
||||
port = static_cast<unsigned short>(p);
|
||||
}
|
||||
|
||||
return Address { address, port };
|
||||
}
|
|
@ -8,5 +8,9 @@
|
|||
|
||||
struct Address {
|
||||
std::string host;
|
||||
unsigned short port;
|
||||
unsigned short port = Address::DEFAULT_PORT;
|
||||
|
||||
static Address fromString(const std::string& addressString);
|
||||
|
||||
constexpr static unsigned short DEFAULT_PORT = 13110;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue