From b26361239fd549666404f01022d254f97de1f2ea Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Mon, 5 Aug 2019 18:10:41 +0200 Subject: [PATCH 1/8] Basic Console stuff. Seperate PRs for more advanced console features. --- src/CMakeLists.txt | 10 + src/RTTI/RTTI_Console.hpp | 20 ++ src/RTTI/RTTI_TypeIDs.hpp | 2 + src/RTTI/RTTI_UIConsole.hpp | 20 ++ src/components/Console.cpp | 432 +++++++++++++++++++++++++++++++++ src/components/Console.hpp | 380 +++++++++++++++++++++++++++++ src/components/GameplayUI.cpp | 6 + src/components/GameplayUI.hpp | 9 + src/components/UIConsole.cpp | 108 +++++++++ src/components/UIConsole.hpp | 75 ++++++ src/components/UIInventory.cpp | 2 +- src/core/Engine.cpp | 1 + src/gui/skin_gothic.cpp | 12 +- src/main_WorldViewer.cpp | 3 + 14 files changed, 1077 insertions(+), 3 deletions(-) create mode 100644 src/RTTI/RTTI_Console.hpp create mode 100644 src/RTTI/RTTI_UIConsole.hpp create mode 100644 src/components/Console.cpp create mode 100644 src/components/Console.hpp create mode 100644 src/components/UIConsole.cpp create mode 100644 src/components/UIConsole.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3dbf2d5b..1bfbdea6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(REGothEngine STATIC RTTI/RTTI_Character.hpp RTTI/RTTI_CharacterAI.hpp RTTI/RTTI_CharacterKeyboardInput.hpp + RTTI/RTTI_Console.hpp RTTI/RTTI_GameClock.hpp RTTI/RTTI_Inventory.hpp RTTI/RTTI_NodeVisuals.hpp @@ -31,8 +32,13 @@ add_library(REGothEngine STATIC RTTI/RTTI_ScriptObjectStorage.hpp RTTI/RTTI_StoryInformation.hpp RTTI/RTTI_TypeIDs.hpp + RTTI/RTTI_Console.hpp + RTTI/RTTI_UIConsole.hpp + RTTI/RTTI_UIDialogueChoice.hpp RTTI/RTTI_UIElement.hpp RTTI/RTTI_UIFocusText.hpp + RTTI/RTTI_UIInventory.hpp + RTTI/RTTI_UISubtitleBox.hpp RTTI/RTTI_VisualCharacter.hpp RTTI/RTTI_VisualInteractiveObject.hpp RTTI/RTTI_VisualSkeletalAnimation.hpp @@ -55,6 +61,8 @@ add_library(REGothEngine STATIC components/CharacterKeyboardInput.hpp components/CharacterState.cpp components/CharacterState.hpp + components/Console.cpp + components/Console.hpp components/EventQueue.cpp components/EventQueue.hpp components/Focusable.cpp @@ -85,6 +93,8 @@ add_library(REGothEngine STATIC components/StoryInformation.hpp components/ThirdPersonCamera.cpp components/ThirdPersonCamera.hpp + components/UIConsole.cpp + components/UIConsole.hpp components/UIDialogueChoice.cpp components/UIDialogueChoice.hpp components/UIElement.cpp diff --git a/src/RTTI/RTTI_Console.hpp b/src/RTTI/RTTI_Console.hpp new file mode 100644 index 00000000..42dfe7fa --- /dev/null +++ b/src/RTTI/RTTI_Console.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "RTTIUtil.hpp" +#include + +namespace REGoth +{ + class RTTI_Console : public bs::RTTIType + { + BS_BEGIN_RTTI_MEMBERS + // This class should not be serialized + BS_END_RTTI_MEMBERS + + public: + RTTI_Console() + { + } + + REGOTH_IMPLEMENT_RTTI_CLASS_FOR_COMPONENT(Console) + }; +} // namespace REGoth \ No newline at end of file diff --git a/src/RTTI/RTTI_TypeIDs.hpp b/src/RTTI/RTTI_TypeIDs.hpp index 29472d56..8fc48a7b 100644 --- a/src/RTTI/RTTI_TypeIDs.hpp +++ b/src/RTTI/RTTI_TypeIDs.hpp @@ -73,5 +73,7 @@ namespace REGoth TID_REGOTH_StoryInformation = 600065, TID_REGOTH_Inventory = 600066, TID_REGOTH_UIInventory = 600067, + TID_REGOTH_Console = 600068, + TID_REGOTH_UIConsole = 600069, }; } // namespace REGoth diff --git a/src/RTTI/RTTI_UIConsole.hpp b/src/RTTI/RTTI_UIConsole.hpp new file mode 100644 index 00000000..68f644f3 --- /dev/null +++ b/src/RTTI/RTTI_UIConsole.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "RTTIUtil.hpp" +#include + +namespace REGoth +{ + class RTTI_UIConsole : public bs::RTTIType + { + BS_BEGIN_RTTI_MEMBERS + // This class should not be serialized + BS_END_RTTI_MEMBERS + + public: + RTTI_UIConsole() + { + } + + REGOTH_IMPLEMENT_RTTI_CLASS_FOR_COMPONENT(UIConsole) + }; +} // namespace REGoth \ No newline at end of file diff --git a/src/components/Console.cpp b/src/components/Console.cpp new file mode 100644 index 00000000..00a7de8a --- /dev/null +++ b/src/components/Console.cpp @@ -0,0 +1,432 @@ +#include "Console.hpp" +#include "components/GameplayUI.hpp" +#include +#include +#include + +namespace REGoth +{ + Console::Console(const bs::HSceneObject& parent) + : bs::Component(parent) + { + setName("Console"); + + mConsoleUI = gGameplayUI()->consoleUI(); + + registerAllCommand(); + } + + Console::~Console() + { + } + + bs::Vector Console::onInputChanged(const bs::String& input) + { + bs::Vector outputs; + return outputs; + } + + bs::Vector Console::onCommandConfirmed(bs::String input) + { + bs::Vector outputs; + return outputs; + } + + bs::Vector Console::command_List(bs::Vector args) + { + REGOTH_LOG(Info, Uncategorized, "[Console] Command 'list' executed!"); + bs::Vector outputs; + + outputs.push_back("List of all commands:"); + for (auto it = mCommands.begin(); it != mCommands.end(); it++) + { + bs::String command = it->first; + + outputs.push_back(command); + } + + return outputs; + } + + bs::Vector Console::command_Help(bs::Vector args) + { + REGOTH_LOG(Info, Uncategorized, "[Console] Command 'help' executed!"); + bs::Vector outputs; + + bs::String& command = args.front(); + auto it = mCommands.find(command); + if (it == mCommands.end()) + { + outputs.push_back("Unkown command: " + command); + } + else + { + bs::String usage = it->second.usage; + outputs.push_back(usage); + bs::String help = it->second.help; + outputs.push_back(help); + } + + return outputs; + } + + bs::Vector Console::command_CheatFull(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat full' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_CheatGod(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat god' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_Insert(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'insert' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_Spawnmass(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'spawnmass' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_Kill(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'kill' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_EditAbilities(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit abilities' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_EditFocus(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit focus' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_SetTime(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'set time' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_GotoWaypoint(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto waypoint' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_GotoCamera(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto camera' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_GotoPos(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto pos' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_AIGoto(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'aigoto' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_SetClippingfactor(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, + "[Console] Command 'set clippingfactor' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_ZFogZone(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'zfogzone' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_ToggleConsole(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle console' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_ToggleFrame(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle frame' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_ToggleWaynet(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle waynet' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_Firstperson(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'firstperson' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_HeroExport(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero export' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + bs::Vector Console::command_HeroImport(bs::Vector args) + { + // TODO: implement + REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero import' is not implemented yet!"); + bs::Vector outputs; + + return outputs; + } + + void Console::registerCommand(const bs::String& name, Command command) + { + mCommands[name] = command; + } + + void Console::registerAllCommand() + { + using This = Console; + Command command; + + command = CommandBuilder() + .callback((commandCallback)&This::command_List) + .usage("Usage: list") + .help("Lists all commands.") + .build(); + registerCommand("list", command); + + command = CommandBuilder() + .callback(&This::command_Help) + .arg(TokenType::Command) + .usage("Usage: help [command]") + .help("Prints out helpful information about the given command.") + .build(); + registerCommand("help", command); + + command = CommandBuilder() + .callback(&This::command_CheatFull) + .usage("Usage: cheat full") + .help("") + .build(); + registerCommand("cheat full", command); + + command = CommandBuilder() + .callback(&This::command_CheatGod) + .usage("Usage: cheat god") + .help("") + .build(); + registerCommand("cheat god", command); + + command = CommandBuilder() + .callback(&This::command_Insert) + .arg(TokenType::Instance) + .usage("Usage: insert [name]") + .help("") + .build(); + registerCommand("insert", command); + + command = CommandBuilder() + .callback(&This::command_Spawnmass) + .arg(TokenType::Literal) + .usage("Usage: spawnmass {giga} [amount]") + .help("") + .build(); + registerCommand("spawnmass", command); + + command = CommandBuilder() + .callback(&This::command_Kill) + .usage("Usage: kill") + .help("Kill the NPC you have currently in focus") + .build(); + registerCommand("kill", command); + + command = CommandBuilder() + .callback(&This::command_EditAbilities) + .usage("Usage: edit abilities") + .help("") + .build(); + registerCommand("edit abilities", command); + + command = CommandBuilder() + .callback(&This::command_EditFocus) + .usage("Usage: edit focus") + .help("") + .build(); + registerCommand("edit focus", command); + + command = CommandBuilder() + .callback(&This::command_SetTime) + .arg(TokenType::Literal) + .arg(TokenType::Literal) + .usage("Usage: set time [hh] [mm]") + .help("") + .build(); + registerCommand("set time", command); + + command = CommandBuilder() + .callback(&This::command_GotoWaypoint) + .arg(TokenType::Waypoint) + .usage("Usage: goto waypoint [waypoint]") + .help("") + .build(); + registerCommand("goto waypoint", command); + + command = CommandBuilder() + .callback(&This::command_GotoCamera) + .usage("Usage: goto camera") + .help("") + .build(); + registerCommand("goto camera", command); + + command = CommandBuilder() + .callback(&This::command_GotoPos) + .arg(TokenType::Literal) + .arg(TokenType::Literal) + .arg(TokenType::Literal) + .usage("Usage: goto pos [x] [y] [z]") + .help("") + .build(); + registerCommand("goto pos", command); + + command = CommandBuilder() + .callback(&This::command_AIGoto) + .arg(TokenType::Waypoint) + .usage("Usage: aigoto [waypoint]") + .help("") + .build(); + registerCommand("aigoto", command); + + command = CommandBuilder() + .callback(&This::command_SetClippingfactor) + .usage("Usage: set clippingfactor [f]") + .help("") + .build(); + registerCommand("set clippingfactor", command); + + command = CommandBuilder() + .callback(&This::command_ZFogZone) + .usage("Usage: zfogzone") + .help("Some Fogzone stuff") + .build(); + registerCommand("zfogzone", command); + + command = CommandBuilder() + .callback(&This::command_ToggleConsole) + .usage("Usage: toggle console") + .help("") + .build(); + registerCommand("toggle console", command); + + command = CommandBuilder() + .callback(&This::command_ToggleFrame) + .usage("Usage: toggle frame") + .help("") + .build(); + registerCommand("toggle frame", command); + + command = CommandBuilder() + .callback(&This::command_ToggleWaynet) + .usage("Usage: toggle waynet") + .help("") + .build(); + registerCommand("toggle waynet", command); + + command = CommandBuilder() + .callback(&This::command_Firstperson) + .usage("Usage: firstperson") + .help("") + .build(); + registerCommand("firstperson", command); + + command = CommandBuilder() + .callback(&This::command_HeroExport) + .arg(TokenType::Literal) + .usage("Usage: hero export [filename]") + .help("") + .build(); + registerCommand("hero export", command); + + command = CommandBuilder() + .callback(&This::command_HeroImport) + .arg(TokenType::Literal) + .usage("Usage: hero import [filename]") + .help("") + .build(); + registerCommand("hero import", command); + } + + REGOTH_DEFINE_RTTI(Console) +} // namespace REGoth diff --git a/src/components/Console.hpp b/src/components/Console.hpp new file mode 100644 index 00000000..0c7742a9 --- /dev/null +++ b/src/components/Console.hpp @@ -0,0 +1,380 @@ +#pragma once +#include + +namespace REGoth +{ + class Console; + using HConsole = bs::GameObjectHandle; + + class UIConsole; + using HUIConsole = bs::GameObjectHandle; + + /** + * This class handles the logical side of the in-game Console. + * This is where the command functions are defined and are registered to the corresponding command. + * Handles history of executed command (TODO) and tries for autocomplete suggestions of the current + * input supplied by the ConsoleUI component. + * Executes correct command based on textual input. + */ + class Console : public bs::Component + { + struct Command; // forward declaration + + public: + Console(const bs::HSceneObject& parent); + virtual ~Console(); + + /** + * Keeps track of where we are in the current command to offer 'content-aware' autocomplete + * suggestions. + * + * @return A vector of auto-complete suggestions to be displayed by the ConsoleUI component. + * + * @note To be used in the callback of the inputChanged event of the inputBox of the ConsoleUI + * component. + * + * @param input + * Current input - usually provided by the inputChanged event of the inputBox of the + * ConsoleUI component. + */ + bs::Vector onInputChanged(const bs::String& input); + + /** + * Identifies the correct command based on the input string and executes its callback. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @note To be used in the callback of the onInputConfirmed event of the inputBox of the + * ConsoleUI component. + * + * @param input + * Current input - Needs to be provided manually by the ConsoleUI component. + */ + bs::Vector onCommandConfirmed(bs::String input); + + private: + /** + * Lists all commands that are registered to this Console. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_List(bs::Vector args); + + /** + * Prints a 'helpful' help message (aka a short description) of the given command. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Name of the command. + */ + bs::Vector command_Help(bs::Vector args); + + /** + * Restores health and mana of the currently controlled(?) character. + * TODO: currently controlled or PC_HERO only? + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_CheatFull(bs::Vector args); + + /** + * Turns on god mode for the currently controlled(?) character. + * TODO: currently controlled or PC_HERO only? + * TODO: Is god mode only invulnerability? + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_CheatGod(bs::Vector args); + + /** + * Insert the given Item/NPC infront of the currently controlled character. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Name of an item or NPC. + * TODO: Anything else you can insert with this? + */ + bs::Vector command_Insert(bs::Vector args); + + /** + * Spawns (???) around(?) the currently controlled character- + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Amount of entities to spawn. + */ + bs::Vector command_Spawnmass(bs::Vector args); + + /** + * Kills target currently in focus. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_Kill(bs::Vector args); + + /** + * Allows editing various attributes and abilities of the currently controlled character. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_EditAbilities(bs::Vector args); + + /** + * Allows editing various attributes and abilities of the character currently in focus. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_EditFocus(bs::Vector args); + + /** + * Sets the current time. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Two literal arguments in the form of [hh] [mm]. + */ + bs::Vector command_SetTime(bs::Vector args); + + /** + * Teleport the currently controlled character to the given waypoint. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Waypoint to teleport to. + */ + bs::Vector command_GotoWaypoint(bs::Vector args); + + /** + * Teleports PC_HERO(?) to the free floating camera. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_GotoCamera(bs::Vector args); + + /** + * Teleport the currently controlled character to the given position in the world. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Three literal arguments in the form of [x] [y] [z] to repesent a position. + */ + bs::Vector command_GotoPos(bs::Vector args); + + /** + * ??? + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Waypoint. + */ + bs::Vector command_AIGoto(bs::Vector args); + + /** + * ??? + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Literal float argument. + */ + bs::Vector command_SetClippingfactor(bs::Vector args); + + /** + * ??? + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_ZFogZone(bs::Vector args); + + /** + * Toggles the visuals of the console. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_ToggleConsole(bs::Vector args); + + /** + * Toggles the visuals of the frame (whole gameui). + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_ToggleFrame(bs::Vector args); + + /** + * Toggles the visuals of the waynet (debug). + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_ToggleWaynet(bs::Vector args); + + /** + * Toggles firstperson mode. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Does not use any arguments. + */ + bs::Vector command_Firstperson(bs::Vector args); + + /** + * Exports attributes and abilities of currently controlled characters to a file with the given + * name in the save folder. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Name of the file. + */ + bs::Vector command_HeroExport(bs::Vector args); + + /** + * Import attributes and abilities from the file with the given name in the save folder and apply + * them to the currently controlled character. + * + * @return A vector of output messages to be displayed by the ConsoleUI component. + * + * @param args + * Name of the file. + */ + bs::Vector command_HeroImport(bs::Vector args); + + /** + * Register a command by + * + * @param name + * Name of the command to identify it in the ingame console. + * + * @param command + * The command itself with its reference to the callback and other useful information. + */ + void registerCommand(const bs::String& name, Command command); + + /** + * Registers all commands. + */ + void registerAllCommand(); + + private: + HUIConsole mConsoleUI; + bs::Map mCommands; + using commandCallback = bs::Vector (Console::*)(bs::Vector); + + /** + * A collection of all types of tokesn that can appear in a command like the command itself and + * various types of arguments. Used to describe the arguments for a command and to have + * 'context-aware' autocomplete suggestions. + */ + enum class TokenType + { + Literal, + Command, + Instance, // FIXME: Yeah I am not so sure about this in relation to the original commands + Waypoint, + Freepoint, + }; + + /** + * @struct Command + * + * @var Command::callback + * Member 'callback' holds the function pointer to a method of Component Console. + * @var Command::args + * Member 'args' is a Vector of TokenTypes that specifies how many arguments and of which + * type the corresponding function in 'callback' takes + * @var Command::usage + * Member 'usage' describes how this command is supposed to be used + * @var Command::help + * Member 'help' gives a short description of what this command does + */ + struct Command + { + commandCallback callback; + bs::Vector args = {}; + bs::String usage; // TODO: Maybe I can generate this from the args? + bs::String help; + }; + + /** + * This class is a simple buildern pattern implementation for the Command struct. + * Makes the instantiation a lot more readable, since designated initializers are not available. + */ + class CommandBuilder + { + public: + CommandBuilder& callback(commandCallback callback) + { + cmd.callback = callback; + return *this; + } + CommandBuilder& arg(TokenType arg) + { + cmd.args.push_back(arg); + return *this; + } + CommandBuilder& usage(bs::String usage) + { + cmd.usage = usage; + return *this; + } + CommandBuilder& help(bs::String help) + { + cmd.help = help; + return *this; + } + Command build() + { + return cmd; + } + + private: + Command cmd = {}; + }; + + public: + REGOTH_DECLARE_RTTI(Console) + + protected: + Console() = default; // For RTTI + }; +} // namespace REGoth diff --git a/src/components/GameplayUI.cpp b/src/components/GameplayUI.cpp index 378195f4..0b2cfeaf 100644 --- a/src/components/GameplayUI.cpp +++ b/src/components/GameplayUI.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,11 @@ namespace REGoth { mInventoryUI = addChildElement("UIInventory"); } + + if (!mConsoleUI) + { + mConsoleUI = addChildElement("UIConsole"); + } } void GameplayUI::createGlobal(bs::HCamera camera) diff --git a/src/components/GameplayUI.hpp b/src/components/GameplayUI.hpp index cdd05795..72ad4761 100644 --- a/src/components/GameplayUI.hpp +++ b/src/components/GameplayUI.hpp @@ -16,6 +16,9 @@ namespace REGoth class UIInventory; using HUIInventory = bs::GameObjectHandle; + class UIConsole; + using HUIConsole = bs::GameObjectHandle; + class GameplayUI; using HGameplayUI = bs::GameObjectHandle; @@ -104,6 +107,11 @@ namespace REGoth return mInventoryUI; } + HUIConsole consoleUI() const + { + return mConsoleUI; + } + protected: void onInitialized() override; @@ -111,6 +119,7 @@ namespace REGoth HUISubtitleBox mSubtitleBox; HUIFocusText mFocusText; HUIInventory mInventoryUI; + HUIConsole mConsoleUI; private: public: diff --git a/src/components/UIConsole.cpp b/src/components/UIConsole.cpp new file mode 100644 index 00000000..7c6850f2 --- /dev/null +++ b/src/components/UIConsole.cpp @@ -0,0 +1,108 @@ +#include "UIConsole.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace REGoth +{ + UIConsole::UIConsole(const bs::HSceneObject& parent, HUIElement parentUIElement) + : UIElement(parent, parentUIElement, new bs::GUIPanel()) + { + setName("UIConsole"); + + bs::GUILayoutY* layoutY = layout().addNewElement(); + + bs::GUIPanel* topPanel = layoutY->addNewElement(); + bs::GUIPanel* backgroundPanel = topPanel->addNewElement(1); + mBackground = backgroundPanel->addNewElement("GothicConsoleBackground"); + + bs::GUIPanel* foregroundPanel = topPanel->addNewElement(0); + mScrollArea = foregroundPanel->addNewElement(); + setOutput("Welcome to the REGoth Console :)"); + + // FIXME: Input box does not appear properly ontop of the texture so i moved it below everything + mInputBox = layoutY->addNewElement(false, "GothicConsoleInputBox"); + mInputBox->setText("I am a console!"); + } + + UIConsole::~UIConsole() + { + } + + void UIConsole::onInitialized() + { + mToggleConsole = bs::VirtualButton("ToggleConsole"); + } + + void UIConsole::update() + { + UIElement::update(); + + bs::Rect2I parentBounds = parentLayout().getBounds(); + + layout().setPosition(0, 0); + // TODO: Consider whole screen for this layout because of suggestion box and edit box + layout().setWidth(parentBounds.width); + layout().setHeight(parentBounds.height * 0.2); + + // Activation Input Handling + if (bs::gVirtualInput().isButtonDown(mToggleConsole)) + { + mState = (mState == State::Closed) ? State::Open : State::Closed; + } + + // State handling + switch (mState) + { + case State::Closed: + mBackground->setVisible(false); + mScrollArea->setVisible(false); + mInputBox->setVisible(false); + mInputBox->setFocus(false); + break; + + case State::Open: + mBackground->setVisible(true); + mScrollArea->setVisible(true); + mInputBox->setVisible(true); + mInputBox->setFocus(true); + break; + } + + if (mState == State::Open) + { + // Input Handling + } + } + + void UIConsole::clearInput() + { + mInputBox->setText(""); + } + + void UIConsole::setOutput(bs::Vector outputs) + { + for (auto output : outputs) + { + setOutput(output); + } + } + + void UIConsole::setOutput(bs::String output) + { + auto element = mScrollArea->getLayout().addNewElement(bs::HString(output)); + element->setHeight(20); + mScrollArea->scrollDownPct(1.0); // Move scrollbar to the very bottom ; FIXME: Does not work + // correctly + } + + REGOTH_DEFINE_RTTI(UIConsole) +} // namespace REGoth diff --git a/src/components/UIConsole.hpp b/src/components/UIConsole.hpp new file mode 100644 index 00000000..d15de818 --- /dev/null +++ b/src/components/UIConsole.hpp @@ -0,0 +1,75 @@ +#pragma once +#include "components/UIElement.hpp" +#include +#include +#include + +namespace REGoth +{ + class UIConsole; + using HUIConsole = bs::GameObjectHandle; + + /** + * This class handles the visual side of the in-game Console. It consists of + * scrollable output windows and an input box to enter the console commands. Additionally there are + * UIElements for autocomplete suggestions and extra functionality such as a UI for editing npc + * properties (TODO). + * + * The component is largely autonomous and works solely on the input of the user by delegated it to + * the actual Console component. + */ + class UIConsole : public UIElement + { + public: + UIConsole(const bs::HSceneObject& parent, HUIElement parentUiElement); + virtual ~UIConsole(); + + /** + * Resets the input of the internal InputBox UIElement to the empty String "", + * Used to clear the input after a command has been entered. + */ + void clearInput(); + + /** + * Creates UI Labels for each of the Strings in \p outputs to be put into the Scrollable Area. + * + * @param outputs A Vector of Strings with the ouputs to be added to the Scrollable Area. + */ + void setOutput(bs::Vector outputs); + + /** + * Creates a UI Label for \p output to be put into the Scrollable Area. + * + * @param output a String with the output to be added to the Scrollable Area. + */ + void setOutput(bs::String output); + + protected: + enum class State + { + Closed, + Open, + }; + + /** + * Sets internal variables for VirtualButtons + */ + void onInitialized() override; + + /** Triggered once per frame. Allows the component to handle input and move. */ + void update() override; + + private: + State mState = State::Closed; + bs::GUITexture* mBackground = nullptr; + bs::GUIScrollArea* mScrollArea = nullptr; + bs::GUIInputBox* mInputBox = nullptr; + bs::VirtualButton mToggleConsole; + + public: + REGOTH_DECLARE_RTTI(UIConsole) + + protected: + UIConsole() = default; // For RTTI + }; +} // namespace REGoth diff --git a/src/components/UIInventory.cpp b/src/components/UIInventory.cpp index 794612d9..3a5e79bb 100644 --- a/src/components/UIInventory.cpp +++ b/src/components/UIInventory.cpp @@ -70,8 +70,8 @@ namespace REGoth bs::Rect2I bounds = parentLayout().getBounds(); - bounds.y = 0; bounds.height = parentLayout().getBounds().height; + bounds.y = bounds.height / 2; bounds.width = 180; layout().setBounds(bounds); diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 9c9f9104..c5171f03 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -141,6 +141,7 @@ void Engine::setupInput() inputConfig->registerButton("ToggleMeleeWeapon", BC_1); inputConfig->registerButton("Action", BC_LCONTROL); inputConfig->registerButton("QuickSave", BC_F5); + inputConfig->registerButton("ToggleConsole", BC_F2); // Camera controls for axes (analog input, e.g. mouse or gamepad thumbstick) // These return values in [-1.0, 1.0] range. diff --git a/src/gui/skin_gothic.cpp b/src/gui/skin_gothic.cpp index c41d45b1..5627887a 100644 --- a/src/gui/skin_gothic.cpp +++ b/src/gui/skin_gothic.cpp @@ -101,13 +101,21 @@ namespace REGoth skin->setStyle("GothicSubtitleBoxCharacterName", labelDefaultHighlighted); skin->setStyle("GothicSubtitleBoxText", labelDefault); - auto button = *skin->getStyle("Button"); - + auto button = *skin->getStyle("Button"); // Commented out: That font is hard to read // button.font = fontGothicOld10WhiteHi; // button.fontSize = 17; skin->setStyle("Button", button); + bs::GUIElementStyle consoleBackground = baseStyle; + consoleBackground.normal.texture = gOriginalGameResources().sprite("CONSOLE.TGA"); + skin->setStyle("GothicConsoleBackground", consoleBackground); + + auto consoleInputBox = *skin->getStyle("InputBox"); + // consoleInputBox.font = fontGothicOld10WhiteHi; + // consoleInputBox.fontSize = 17; + skin->setStyle("GothicConsoleInputBox", consoleInputBox); + // Cache the skin for later use s_SkinGothic = skin; diff --git a/src/main_WorldViewer.cpp b/src/main_WorldViewer.cpp index 33836750..777a8d3f 100644 --- a/src/main_WorldViewer.cpp +++ b/src/main_WorldViewer.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -130,6 +131,8 @@ class REGothWorldViewer : public REGoth::Engine REGoth::GameplayUI::createGlobal(mMainCamera); + world->SO()->addComponent(); + auto inventory = hero->SO()->getComponent(); inventory->giveItem("ITFOAPPLE"); From 4152b6a63efadc33f41a8f5214f7fd67dd5bf731 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Mon, 5 Aug 2019 18:36:20 +0200 Subject: [PATCH 2/8] Is this better? --- src/components/Console.cpp | 18 ++++++++++++++++++ src/components/Console.hpp | 3 +++ src/components/UIConsole.cpp | 14 +++++++++++++- src/components/UIConsole.hpp | 17 ++++++++++++++++- 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/components/Console.cpp b/src/components/Console.cpp index 00a7de8a..f598131a 100644 --- a/src/components/Console.cpp +++ b/src/components/Console.cpp @@ -1,5 +1,6 @@ #include "Console.hpp" #include "components/GameplayUI.hpp" +#include "components/UIConsole.hpp" #include #include #include @@ -20,6 +21,23 @@ namespace REGoth { } + void Console::onInitialized() + { + auto valueChangedCallback = [&](const bs::String& input) { + REGOTH_LOG(Info, Uncategorized, "[Console] Input changed to: {0}!", input); + bs::Vector suggestions = onInputChanged(input); + }; + mConsoleUI->mOnInputChanged.connect(valueChangedCallback); + + auto confirmCallback = [&]() { + const bs::String& input = mConsoleUI->getInput(); + REGOTH_LOG(Info, Uncategorized, "[Console] Command confirmed: {0}!", input); + bs::Vector outputs = onCommandConfirmed(input); + mConsoleUI->clearInput(); + }; + mConsoleUI->mOnConfirm.connect(confirmCallback); + } + bs::Vector Console::onInputChanged(const bs::String& input) { bs::Vector outputs; diff --git a/src/components/Console.hpp b/src/components/Console.hpp index 0c7742a9..b9670030 100644 --- a/src/components/Console.hpp +++ b/src/components/Console.hpp @@ -52,6 +52,9 @@ namespace REGoth */ bs::Vector onCommandConfirmed(bs::String input); + protected: + void onInitialized() override; + private: /** * Lists all commands that are registered to this Console. diff --git a/src/components/UIConsole.cpp b/src/components/UIConsole.cpp index 7c6850f2..69781e04 100644 --- a/src/components/UIConsole.cpp +++ b/src/components/UIConsole.cpp @@ -39,7 +39,9 @@ namespace REGoth void UIConsole::onInitialized() { - mToggleConsole = bs::VirtualButton("ToggleConsole"); + mOnConfirm = mInputBox->onConfirm; + mOnInputChanged = mInputBox->onValueChanged; + mToggleConsole = bs::VirtualButton("ToggleConsole"); } void UIConsole::update() @@ -83,6 +85,11 @@ namespace REGoth } } + const bs::String& UIConsole::getInput() + { + return mInputBox->getText(); + } + void UIConsole::clearInput() { mInputBox->setText(""); @@ -104,5 +111,10 @@ namespace REGoth // correctly } + void UIConsole::clearOutput() + { + // TODO + } + REGOTH_DEFINE_RTTI(UIConsole) } // namespace REGoth diff --git a/src/components/UIConsole.hpp b/src/components/UIConsole.hpp index d15de818..36173814 100644 --- a/src/components/UIConsole.hpp +++ b/src/components/UIConsole.hpp @@ -25,7 +25,12 @@ namespace REGoth virtual ~UIConsole(); /** - * Resets the input of the internal InputBox UIElement to the empty String "", + * Get the current Input. + */ + const bs::String& getInput(); + + /** + * Resets the input of the internal InputBox UIElement to the empty String "". * Used to clear the input after a command has been entered. */ void clearInput(); @@ -44,6 +49,12 @@ namespace REGoth */ void setOutput(bs::String output); + /** + * Resets the input of the internal ScrollArea UIElement. + * Used to clear the output. + */ + void clearOutput(); + protected: enum class State { @@ -59,6 +70,10 @@ namespace REGoth /** Triggered once per frame. Allows the component to handle input and move. */ void update() override; + public: + bs::Event mOnConfirm; + bs::Event mOnInputChanged; + private: State mState = State::Closed; bs::GUITexture* mBackground = nullptr; From 5f8845915658cbcfb383f5fa3eb3291266ebe50c Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Mon, 5 Aug 2019 18:45:35 +0200 Subject: [PATCH 3/8] Certainly looks a lot cleaner --- src/components/Console.cpp | 106 +++++++++++-------------------------- src/components/Console.hpp | 76 +++++++++----------------- 2 files changed, 55 insertions(+), 127 deletions(-) diff --git a/src/components/Console.cpp b/src/components/Console.cpp index f598131a..32182169 100644 --- a/src/components/Console.cpp +++ b/src/components/Console.cpp @@ -24,33 +24,31 @@ namespace REGoth void Console::onInitialized() { auto valueChangedCallback = [&](const bs::String& input) { - REGOTH_LOG(Info, Uncategorized, "[Console] Input changed to: {0}!", input); - bs::Vector suggestions = onInputChanged(input); + REGOTH_LOG(Info, Uncategorized, "[Console] !EVENT! Input changed to: {0}!", input); + onInputChanged(input); }; mConsoleUI->mOnInputChanged.connect(valueChangedCallback); auto confirmCallback = [&]() { const bs::String& input = mConsoleUI->getInput(); - REGOTH_LOG(Info, Uncategorized, "[Console] Command confirmed: {0}!", input); - bs::Vector outputs = onCommandConfirmed(input); + REGOTH_LOG(Info, Uncategorized, "[Console] !EVENT! Command confirmed: {0}!", input); + onCommandConfirmed(input); mConsoleUI->clearInput(); }; mConsoleUI->mOnConfirm.connect(confirmCallback); } - bs::Vector Console::onInputChanged(const bs::String& input) + void Console::onInputChanged(const bs::String& input) { - bs::Vector outputs; - return outputs; + // TODO + rename } - bs::Vector Console::onCommandConfirmed(bs::String input) + void Console::onCommandConfirmed(const bs::String& input) { - bs::Vector outputs; - return outputs; + // TODO + rename } - bs::Vector Console::command_List(bs::Vector args) + void Console::command_List(bs::Vector args) { REGOTH_LOG(Info, Uncategorized, "[Console] Command 'list' executed!"); bs::Vector outputs; @@ -62,11 +60,9 @@ namespace REGoth outputs.push_back(command); } - - return outputs; } - bs::Vector Console::command_Help(bs::Vector args) + void Console::command_Help(bs::Vector args) { REGOTH_LOG(Info, Uncategorized, "[Console] Command 'help' executed!"); bs::Vector outputs; @@ -84,189 +80,147 @@ namespace REGoth bs::String help = it->second.help; outputs.push_back(help); } - - return outputs; } - bs::Vector Console::command_CheatFull(bs::Vector args) + void Console::command_CheatFull(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat full' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_CheatGod(bs::Vector args) + void Console::command_CheatGod(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat god' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_Insert(bs::Vector args) + void Console::command_Insert(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'insert' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_Spawnmass(bs::Vector args) + void Console::command_Spawnmass(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'spawnmass' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_Kill(bs::Vector args) + void Console::command_Kill(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'kill' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_EditAbilities(bs::Vector args) + void Console::command_EditAbilities(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit abilities' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_EditFocus(bs::Vector args) + void Console::command_EditFocus(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit focus' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_SetTime(bs::Vector args) + void Console::command_SetTime(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'set time' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_GotoWaypoint(bs::Vector args) + void Console::command_GotoWaypoint(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto waypoint' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_GotoCamera(bs::Vector args) + void Console::command_GotoCamera(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto camera' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_GotoPos(bs::Vector args) + void Console::command_GotoPos(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto pos' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_AIGoto(bs::Vector args) + void Console::command_AIGoto(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'aigoto' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_SetClippingfactor(bs::Vector args) + void Console::command_SetClippingfactor(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'set clippingfactor' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_ZFogZone(bs::Vector args) + void Console::command_ZFogZone(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'zfogzone' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_ToggleConsole(bs::Vector args) + void Console::command_ToggleConsole(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle console' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_ToggleFrame(bs::Vector args) + void Console::command_ToggleFrame(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle frame' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_ToggleWaynet(bs::Vector args) + void Console::command_ToggleWaynet(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle waynet' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_Firstperson(bs::Vector args) + void Console::command_Firstperson(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'firstperson' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_HeroExport(bs::Vector args) + void Console::command_HeroExport(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero export' is not implemented yet!"); bs::Vector outputs; - - return outputs; } - bs::Vector Console::command_HeroImport(bs::Vector args) + void Console::command_HeroImport(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero import' is not implemented yet!"); bs::Vector outputs; - - return outputs; } void Console::registerCommand(const bs::String& name, Command command) diff --git a/src/components/Console.hpp b/src/components/Console.hpp index b9670030..58e4c9f0 100644 --- a/src/components/Console.hpp +++ b/src/components/Console.hpp @@ -28,8 +28,6 @@ namespace REGoth * Keeps track of where we are in the current command to offer 'content-aware' autocomplete * suggestions. * - * @return A vector of auto-complete suggestions to be displayed by the ConsoleUI component. - * * @note To be used in the callback of the inputChanged event of the inputBox of the ConsoleUI * component. * @@ -37,20 +35,18 @@ namespace REGoth * Current input - usually provided by the inputChanged event of the inputBox of the * ConsoleUI component. */ - bs::Vector onInputChanged(const bs::String& input); + void onInputChanged(const bs::String& input); /** * Identifies the correct command based on the input string and executes its callback. * - * @return A vector of output messages to be displayed by the ConsoleUI component. - * * @note To be used in the callback of the onInputConfirmed event of the inputBox of the * ConsoleUI component. * * @param input * Current input - Needs to be provided manually by the ConsoleUI component. */ - bs::Vector onCommandConfirmed(bs::String input); + void onCommandConfirmed(const bs::String& input); protected: void onInitialized() override; @@ -59,228 +55,206 @@ namespace REGoth /** * Lists all commands that are registered to this Console. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_List(bs::Vector args); + void command_List(bs::Vector args); /** * Prints a 'helpful' help message (aka a short description) of the given command. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Name of the command. */ - bs::Vector command_Help(bs::Vector args); + void command_Help(bs::Vector args); /** * Restores health and mana of the currently controlled(?) character. * TODO: currently controlled or PC_HERO only? * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_CheatFull(bs::Vector args); + void command_CheatFull(bs::Vector args); /** * Turns on god mode for the currently controlled(?) character. * TODO: currently controlled or PC_HERO only? * TODO: Is god mode only invulnerability? * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_CheatGod(bs::Vector args); + void command_CheatGod(bs::Vector args); /** * Insert the given Item/NPC infront of the currently controlled character. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Name of an item or NPC. * TODO: Anything else you can insert with this? */ - bs::Vector command_Insert(bs::Vector args); + void command_Insert(bs::Vector args); /** * Spawns (???) around(?) the currently controlled character- * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Amount of entities to spawn. */ - bs::Vector command_Spawnmass(bs::Vector args); + void command_Spawnmass(bs::Vector args); /** * Kills target currently in focus. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_Kill(bs::Vector args); + void command_Kill(bs::Vector args); /** * Allows editing various attributes and abilities of the currently controlled character. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_EditAbilities(bs::Vector args); + void command_EditAbilities(bs::Vector args); /** * Allows editing various attributes and abilities of the character currently in focus. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_EditFocus(bs::Vector args); + void command_EditFocus(bs::Vector args); /** * Sets the current time. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Two literal arguments in the form of [hh] [mm]. */ - bs::Vector command_SetTime(bs::Vector args); + void command_SetTime(bs::Vector args); /** * Teleport the currently controlled character to the given waypoint. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Waypoint to teleport to. */ - bs::Vector command_GotoWaypoint(bs::Vector args); + void command_GotoWaypoint(bs::Vector args); /** * Teleports PC_HERO(?) to the free floating camera. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_GotoCamera(bs::Vector args); + void command_GotoCamera(bs::Vector args); /** * Teleport the currently controlled character to the given position in the world. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Three literal arguments in the form of [x] [y] [z] to repesent a position. */ - bs::Vector command_GotoPos(bs::Vector args); + void command_GotoPos(bs::Vector args); /** * ??? * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Waypoint. */ - bs::Vector command_AIGoto(bs::Vector args); + void command_AIGoto(bs::Vector args); /** * ??? * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Literal float argument. */ - bs::Vector command_SetClippingfactor(bs::Vector args); + void command_SetClippingfactor(bs::Vector args); /** * ??? * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_ZFogZone(bs::Vector args); + void command_ZFogZone(bs::Vector args); /** * Toggles the visuals of the console. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_ToggleConsole(bs::Vector args); + void command_ToggleConsole(bs::Vector args); /** * Toggles the visuals of the frame (whole gameui). * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_ToggleFrame(bs::Vector args); + void command_ToggleFrame(bs::Vector args); /** * Toggles the visuals of the waynet (debug). * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_ToggleWaynet(bs::Vector args); + void command_ToggleWaynet(bs::Vector args); /** * Toggles firstperson mode. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Does not use any arguments. */ - bs::Vector command_Firstperson(bs::Vector args); + void command_Firstperson(bs::Vector args); /** * Exports attributes and abilities of currently controlled characters to a file with the given * name in the save folder. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Name of the file. */ - bs::Vector command_HeroExport(bs::Vector args); + void command_HeroExport(bs::Vector args); /** * Import attributes and abilities from the file with the given name in the save folder and apply * them to the currently controlled character. * - * @return A vector of output messages to be displayed by the ConsoleUI component. * * @param args * Name of the file. */ - bs::Vector command_HeroImport(bs::Vector args); + void command_HeroImport(bs::Vector args); /** * Register a command by @@ -301,7 +275,7 @@ namespace REGoth private: HUIConsole mConsoleUI; bs::Map mCommands; - using commandCallback = bs::Vector (Console::*)(bs::Vector); + using commandCallback = void (Console::*)(bs::Vector); /** * A collection of all types of tokesn that can appear in a command like the command itself and From 1b53dae1da30eb5d2de2dafee3e5452cace73fb5 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Mon, 5 Aug 2019 21:34:23 +0200 Subject: [PATCH 4/8] Parse and Execute works, clearOutput does not really work, added clear command --- src/components/Console.cpp | 208 ++++++++++++++++++++++++++--------- src/components/Console.hpp | 28 ++++- src/components/UIConsole.cpp | 25 +++-- src/components/UIConsole.hpp | 7 +- 4 files changed, 203 insertions(+), 65 deletions(-) diff --git a/src/components/Console.cpp b/src/components/Console.cpp index 32182169..6369f0b0 100644 --- a/src/components/Console.cpp +++ b/src/components/Console.cpp @@ -32,7 +32,7 @@ namespace REGoth auto confirmCallback = [&]() { const bs::String& input = mConsoleUI->getInput(); REGOTH_LOG(Info, Uncategorized, "[Console] !EVENT! Command confirmed: {0}!", input); - onCommandConfirmed(input); + parseAndExecuteCommand(input); mConsoleUI->clearInput(); }; mConsoleUI->mOnConfirm.connect(confirmCallback); @@ -43,9 +43,58 @@ namespace REGoth // TODO + rename } - void Console::onCommandConfirmed(const bs::String& input) + void Console::parseAndExecuteCommand(const bs::String& input) { - // TODO + rename + bs::String sanitized_input = input; + bs::StringUtil::trim(sanitized_input); + bs::Vector tokenized_input = bs::StringUtil::split(sanitized_input, " "); + + for (const auto& token : tokenized_input) + REGOTH_LOG(Info, Uncategorized, "[Console] Token in tokenized input: {0}!", token); + + // detect command + auto it = mCommands.begin(); + for (; it != mCommands.end(); it++) + { + // construct command based on number of tokens + bs::UINT32 num_of_tokens = it->num_of_tokens; + if (tokenized_input.size() < num_of_tokens) continue; + bs::String command; + for (bs::UINT32 i = 0; i < num_of_tokens; i++) + { + if (!command.empty()) + { + command = command + " "; + } + command = command + tokenized_input[i]; + } + + // if the command matches the input we just break and it will contain the correct command + if (bs::StringUtil::compare(command, it->name) == 0) break; + } + + // Command not found + if (it == mCommands.end()) return; + REGOTH_LOG(Info, Uncategorized, "[Console] Command was found and is: {0}!", it->name); + + // call callback and pass arguments + tokenized_input.erase(tokenized_input.begin(), tokenized_input.begin() + it->num_of_tokens); + if (tokenized_input.size() != it->args.size()) + { + REGOTH_LOG(Info, Uncategorized, + "[Console] Wrong number of arguments: Should be {0}, but is {1}!", it->args.size(), + tokenized_input.size()); + mConsoleUI->setOutput(it->usage); + return; + } + (this->*it->callback)(tokenized_input); + } + + void Console::command_Clear(bs::Vector args) + { + REGOTH_LOG(Info, Uncategorized, "[Console] Command 'clear' executed!"); + + mConsoleUI->clearOutput(); } void Console::command_List(bs::Vector args) @@ -56,10 +105,12 @@ namespace REGoth outputs.push_back("List of all commands:"); for (auto it = mCommands.begin(); it != mCommands.end(); it++) { - bs::String command = it->first; + bs::String command = it->name; outputs.push_back(command); } + + mConsoleUI->setOutput(outputs); } void Console::command_Help(bs::Vector args) @@ -68,102 +119,118 @@ namespace REGoth bs::Vector outputs; bs::String& command = args.front(); - auto it = mCommands.find(command); + auto it = std::find_if(mCommands.begin(), mCommands.end(), [&command](const Command& cmd) { + return (bs::StringUtil::compare(cmd.name, command) == 0); + }); if (it == mCommands.end()) { outputs.push_back("Unkown command: " + command); } else { - bs::String usage = it->second.usage; + bs::String usage = it->usage; outputs.push_back(usage); - bs::String help = it->second.help; + bs::String help = it->help; outputs.push_back(help); } + + mConsoleUI->setOutput(outputs); } void Console::command_CheatFull(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat full' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'cheat full' is not implemented yet!"); } void Console::command_CheatGod(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat god' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'cheat god' is not implemented yet!"); } void Console::command_Insert(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'insert' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'insert' is not implemented yet!"); } void Console::command_Spawnmass(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'spawnmass' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'spawnmass' is not implemented yet!"); } void Console::command_Kill(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'kill' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'kill' is not implemented yet!"); } void Console::command_EditAbilities(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit abilities' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'edit abilities' is not implemented yet!"); } void Console::command_EditFocus(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit focus' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'edit focus' is not implemented yet!"); } void Console::command_SetTime(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'set time' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'set time' is not implemented yet!"); } void Console::command_GotoWaypoint(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto waypoint' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'goto waypoint' is not implemented yet!"); } void Console::command_GotoCamera(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto camera' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'goto camera' is not implemented yet!"); } void Console::command_GotoPos(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto pos' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'goto pos' is not implemented yet!"); } void Console::command_AIGoto(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'aigoto' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'aigoto' is not implemented yet!"); } void Console::command_SetClippingfactor(bs::Vector args) @@ -171,61 +238,70 @@ namespace REGoth // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'set clippingfactor' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'set clippingfactor' is not implemented yet!"); } void Console::command_ZFogZone(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'zfogzone' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'zfogzone' is not implemented yet!"); } void Console::command_ToggleConsole(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle console' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'toggle console' is not implemented yet!"); } void Console::command_ToggleFrame(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle frame' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'toggle frame' is not implemented yet!"); } void Console::command_ToggleWaynet(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle waynet' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'toggle waynet' is not implemented yet!"); } void Console::command_Firstperson(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'firstperson' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'firstperson' is not implemented yet!"); } void Console::command_HeroExport(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero export' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'hero export' is not implemented yet!"); } void Console::command_HeroImport(bs::Vector args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero import' is not implemented yet!"); - bs::Vector outputs; + + mConsoleUI->setOutput("Command 'hero import' is not implemented yet!"); } - void Console::registerCommand(const bs::String& name, Command command) + void Console::registerCommand(const Command& command) { - mCommands[name] = command; + // TODO: Some auto suggestion stuff can happen here + mCommands.push_back(command); } void Console::registerAllCommand() @@ -234,96 +310,117 @@ namespace REGoth Command command; command = CommandBuilder() + .name("clear") + .callback((commandCallback)&This::command_Clear) + .usage("Usage: clear") + .help("Clears console output.") + .build(); + registerCommand(command); + + command = CommandBuilder() + .name("list") .callback((commandCallback)&This::command_List) .usage("Usage: list") .help("Lists all commands.") .build(); - registerCommand("list", command); + registerCommand(command); command = CommandBuilder() + .name("help") .callback(&This::command_Help) .arg(TokenType::Command) .usage("Usage: help [command]") .help("Prints out helpful information about the given command.") .build(); - registerCommand("help", command); + registerCommand(command); command = CommandBuilder() + .name("cheat full") .callback(&This::command_CheatFull) .usage("Usage: cheat full") .help("") .build(); - registerCommand("cheat full", command); + registerCommand(command); command = CommandBuilder() + .name("cheat god") .callback(&This::command_CheatGod) .usage("Usage: cheat god") .help("") .build(); - registerCommand("cheat god", command); + registerCommand(command); command = CommandBuilder() + .name("insert") .callback(&This::command_Insert) .arg(TokenType::Instance) .usage("Usage: insert [name]") .help("") .build(); - registerCommand("insert", command); + registerCommand(command); command = CommandBuilder() + .name("spawnmass") .callback(&This::command_Spawnmass) .arg(TokenType::Literal) .usage("Usage: spawnmass {giga} [amount]") .help("") .build(); - registerCommand("spawnmass", command); + registerCommand(command); command = CommandBuilder() + .name("kill") .callback(&This::command_Kill) .usage("Usage: kill") .help("Kill the NPC you have currently in focus") .build(); - registerCommand("kill", command); + registerCommand(command); command = CommandBuilder() + .name("edit abilities") .callback(&This::command_EditAbilities) .usage("Usage: edit abilities") .help("") .build(); - registerCommand("edit abilities", command); + registerCommand(command); command = CommandBuilder() + .name("edit focus") .callback(&This::command_EditFocus) .usage("Usage: edit focus") .help("") .build(); - registerCommand("edit focus", command); + registerCommand(command); command = CommandBuilder() + .name("set time") .callback(&This::command_SetTime) .arg(TokenType::Literal) .arg(TokenType::Literal) .usage("Usage: set time [hh] [mm]") .help("") .build(); - registerCommand("set time", command); + registerCommand(command); command = CommandBuilder() + .name("goto waypoint") .callback(&This::command_GotoWaypoint) .arg(TokenType::Waypoint) .usage("Usage: goto waypoint [waypoint]") .help("") .build(); - registerCommand("goto waypoint", command); + registerCommand(command); command = CommandBuilder() + .name("goto camera") .callback(&This::command_GotoCamera) .usage("Usage: goto camera") .help("") .build(); - registerCommand("goto camera", command); + registerCommand(command); command = CommandBuilder() + .name("goto pos") .callback(&This::command_GotoPos) .arg(TokenType::Literal) .arg(TokenType::Literal) @@ -331,73 +428,82 @@ namespace REGoth .usage("Usage: goto pos [x] [y] [z]") .help("") .build(); - registerCommand("goto pos", command); + registerCommand(command); command = CommandBuilder() + .name("aigoto") .callback(&This::command_AIGoto) .arg(TokenType::Waypoint) .usage("Usage: aigoto [waypoint]") .help("") .build(); - registerCommand("aigoto", command); + registerCommand(command); command = CommandBuilder() + .name("set clippingfactor") .callback(&This::command_SetClippingfactor) .usage("Usage: set clippingfactor [f]") .help("") .build(); - registerCommand("set clippingfactor", command); + registerCommand(command); command = CommandBuilder() + .name("zgofzone") .callback(&This::command_ZFogZone) .usage("Usage: zfogzone") .help("Some Fogzone stuff") .build(); - registerCommand("zfogzone", command); + registerCommand(command); command = CommandBuilder() + .name("toggle console") .callback(&This::command_ToggleConsole) .usage("Usage: toggle console") .help("") .build(); - registerCommand("toggle console", command); + registerCommand(command); command = CommandBuilder() + .name("toggle frame") .callback(&This::command_ToggleFrame) .usage("Usage: toggle frame") .help("") .build(); - registerCommand("toggle frame", command); + registerCommand(command); command = CommandBuilder() + .name("toggle waynet") .callback(&This::command_ToggleWaynet) .usage("Usage: toggle waynet") .help("") .build(); - registerCommand("toggle waynet", command); + registerCommand(command); command = CommandBuilder() + .name("firstperson") .callback(&This::command_Firstperson) .usage("Usage: firstperson") .help("") .build(); - registerCommand("firstperson", command); + registerCommand(command); command = CommandBuilder() + .name("hero export") .callback(&This::command_HeroExport) .arg(TokenType::Literal) .usage("Usage: hero export [filename]") .help("") .build(); - registerCommand("hero export", command); + registerCommand(command); command = CommandBuilder() + .name("hero import") .callback(&This::command_HeroImport) .arg(TokenType::Literal) .usage("Usage: hero import [filename]") .help("") .build(); - registerCommand("hero import", command); + registerCommand(command); } REGOTH_DEFINE_RTTI(Console) diff --git a/src/components/Console.hpp b/src/components/Console.hpp index 58e4c9f0..fca95940 100644 --- a/src/components/Console.hpp +++ b/src/components/Console.hpp @@ -46,12 +46,21 @@ namespace REGoth * @param input * Current input - Needs to be provided manually by the ConsoleUI component. */ - void onCommandConfirmed(const bs::String& input); + void parseAndExecuteCommand(const bs::String& input); protected: void onInitialized() override; private: + /** + * Clears console output + * + * + * @param args + * Does not use any arguments. + */ + void command_Clear(bs::Vector args); + /** * Lists all commands that are registered to this Console. * @@ -265,7 +274,7 @@ namespace REGoth * @param command * The command itself with its reference to the callback and other useful information. */ - void registerCommand(const bs::String& name, Command command); + void registerCommand(const Command& command); /** * Registers all commands. @@ -274,7 +283,7 @@ namespace REGoth private: HUIConsole mConsoleUI; - bs::Map mCommands; + bs::Vector mCommands; using commandCallback = void (Console::*)(bs::Vector); /** @@ -306,6 +315,8 @@ namespace REGoth */ struct Command { + bs::String name; + bs::UINT32 num_of_tokens; commandCallback callback; bs::Vector args = {}; bs::String usage; // TODO: Maybe I can generate this from the args? @@ -319,6 +330,17 @@ namespace REGoth class CommandBuilder { public: + CommandBuilder& name(const bs::String& name) + { + // sanitize name and determine num of tokens aka how many words in the command + bs::String sanitized_name = name; + bs::StringUtil::trim(sanitized_name); + bs::UINT32 num_of_tokens = bs::StringUtil::split(sanitized_name, " ").size(); + + cmd.name = sanitized_name; + cmd.num_of_tokens = num_of_tokens; + return *this; + } CommandBuilder& callback(commandCallback callback) { cmd.callback = callback; diff --git a/src/components/UIConsole.cpp b/src/components/UIConsole.cpp index 69781e04..e68d8c56 100644 --- a/src/components/UIConsole.cpp +++ b/src/components/UIConsole.cpp @@ -26,11 +26,9 @@ namespace REGoth bs::GUIPanel* foregroundPanel = topPanel->addNewElement(0); mScrollArea = foregroundPanel->addNewElement(); - setOutput("Welcome to the REGoth Console :)"); // FIXME: Input box does not appear properly ontop of the texture so i moved it below everything mInputBox = layoutY->addNewElement(false, "GothicConsoleInputBox"); - mInputBox->setText("I am a console!"); } UIConsole::~UIConsole() @@ -42,6 +40,8 @@ namespace REGoth mOnConfirm = mInputBox->onConfirm; mOnInputChanged = mInputBox->onValueChanged; mToggleConsole = bs::VirtualButton("ToggleConsole"); + + setOutput("Welcome to the REGoth Console :)"); } void UIConsole::update() @@ -95,7 +95,7 @@ namespace REGoth mInputBox->setText(""); } - void UIConsole::setOutput(bs::Vector outputs) + void UIConsole::setOutput(const bs::Vector& outputs) { for (auto output : outputs) { @@ -103,17 +103,26 @@ namespace REGoth } } - void UIConsole::setOutput(bs::String output) + void UIConsole::setOutput(const bs::String& output) { - auto element = mScrollArea->getLayout().addNewElement(bs::HString(output)); - element->setHeight(20); + auto label = mScrollArea->getLayout().addNewElement(bs::HString(output)); + label->setHeight(20); + mOutputLabels.push_back(label); + + mScrollArea->_updateLayout(mScrollArea->_getLayoutData()); mScrollArea->scrollDownPct(1.0); // Move scrollbar to the very bottom ; FIXME: Does not work - // correctly + // correctly, call above is workaround } void UIConsole::clearOutput() { - // TODO + // TODO: does not work correctly + for (bs::GUILabel* pLabel : mOutputLabels) + { + mScrollArea->getLayout().removeElement(pLabel); + } + + mOutputLabels.clear(); } REGOTH_DEFINE_RTTI(UIConsole) diff --git a/src/components/UIConsole.hpp b/src/components/UIConsole.hpp index 36173814..f2bed37d 100644 --- a/src/components/UIConsole.hpp +++ b/src/components/UIConsole.hpp @@ -40,14 +40,14 @@ namespace REGoth * * @param outputs A Vector of Strings with the ouputs to be added to the Scrollable Area. */ - void setOutput(bs::Vector outputs); + void setOutput(const bs::Vector& outputs); /** * Creates a UI Label for \p output to be put into the Scrollable Area. * * @param output a String with the output to be added to the Scrollable Area. */ - void setOutput(bs::String output); + void setOutput(const bs::String& output); /** * Resets the input of the internal ScrollArea UIElement. @@ -78,7 +78,8 @@ namespace REGoth State mState = State::Closed; bs::GUITexture* mBackground = nullptr; bs::GUIScrollArea* mScrollArea = nullptr; - bs::GUIInputBox* mInputBox = nullptr; + bs::Vector mOutputLabels; + bs::GUIInputBox* mInputBox = nullptr; bs::VirtualButton mToggleConsole; public: From 9a450d37bec08bac78b95039c46531b216bf047b Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Tue, 6 Aug 2019 17:21:02 +0200 Subject: [PATCH 5/8] Minor fixes in repsonse to the review --- src/CMakeLists.txt | 1 - src/RTTI/RTTI_Console.hpp | 2 +- src/RTTI/RTTI_UIConsole.hpp | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1bfbdea6..876f28b5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,7 +32,6 @@ add_library(REGothEngine STATIC RTTI/RTTI_ScriptObjectStorage.hpp RTTI/RTTI_StoryInformation.hpp RTTI/RTTI_TypeIDs.hpp - RTTI/RTTI_Console.hpp RTTI/RTTI_UIConsole.hpp RTTI/RTTI_UIDialogueChoice.hpp RTTI/RTTI_UIElement.hpp diff --git a/src/RTTI/RTTI_Console.hpp b/src/RTTI/RTTI_Console.hpp index 42dfe7fa..79bc17af 100644 --- a/src/RTTI/RTTI_Console.hpp +++ b/src/RTTI/RTTI_Console.hpp @@ -17,4 +17,4 @@ namespace REGoth REGOTH_IMPLEMENT_RTTI_CLASS_FOR_COMPONENT(Console) }; -} // namespace REGoth \ No newline at end of file +} // namespace REGoth diff --git a/src/RTTI/RTTI_UIConsole.hpp b/src/RTTI/RTTI_UIConsole.hpp index 68f644f3..7b336deb 100644 --- a/src/RTTI/RTTI_UIConsole.hpp +++ b/src/RTTI/RTTI_UIConsole.hpp @@ -17,4 +17,4 @@ namespace REGoth REGOTH_IMPLEMENT_RTTI_CLASS_FOR_COMPONENT(UIConsole) }; -} // namespace REGoth \ No newline at end of file +} // namespace REGoth From b32818eaeeda0b669e207ae2f5f3ed3fc4eae90e Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Tue, 6 Aug 2019 17:37:26 +0200 Subject: [PATCH 6/8] Take reference for arguments Allow extra trailing arguments for now changed Spawnmass to SpawnMass "Fix" help command for multi-word commands --- src/components/Console.cpp | 78 ++++++++++++++++++++++-------------- src/components/Console.hpp | 76 ++++++++++++----------------------- src/components/UIConsole.hpp | 2 +- 3 files changed, 74 insertions(+), 82 deletions(-) diff --git a/src/components/Console.cpp b/src/components/Console.cpp index 6369f0b0..932c78d9 100644 --- a/src/components/Console.cpp +++ b/src/components/Console.cpp @@ -79,7 +79,8 @@ namespace REGoth // call callback and pass arguments tokenized_input.erase(tokenized_input.begin(), tokenized_input.begin() + it->num_of_tokens); - if (tokenized_input.size() != it->args.size()) + // FIXME: allow trailing arguments that are ignored for now + if (tokenized_input.size() < it->args.size()) { REGOTH_LOG(Info, Uncategorized, "[Console] Wrong number of arguments: Should be {0}, but is {1}!", it->args.size(), @@ -90,14 +91,14 @@ namespace REGoth (this->*it->callback)(tokenized_input); } - void Console::command_Clear(bs::Vector args) + void Console::command_Clear(bs::Vector& args) { REGOTH_LOG(Info, Uncategorized, "[Console] Command 'clear' executed!"); mConsoleUI->clearOutput(); } - void Console::command_List(bs::Vector args) + void Console::command_List(bs::Vector& args) { REGOTH_LOG(Info, Uncategorized, "[Console] Command 'list' executed!"); bs::Vector outputs; @@ -113,18 +114,35 @@ namespace REGoth mConsoleUI->setOutput(outputs); } - void Console::command_Help(bs::Vector args) + void Console::command_Help(bs::Vector& args) { REGOTH_LOG(Info, Uncategorized, "[Console] Command 'help' executed!"); bs::Vector outputs; - bs::String& command = args.front(); - auto it = std::find_if(mCommands.begin(), mCommands.end(), [&command](const Command& cmd) { - return (bs::StringUtil::compare(cmd.name, command) == 0); - }); + // detect command + auto it = mCommands.begin(); + for (; it != mCommands.end(); it++) + { + // construct command based on number of tokens + bs::UINT32 num_of_tokens = it->num_of_tokens; + if (args.size() < num_of_tokens) continue; + bs::String command; + for (bs::UINT32 i = 0; i < num_of_tokens; i++) + { + if (!command.empty()) + { + command = command + " "; + } + command = command + args[i]; + } + + // if the command matches the input we just break and it will contain the correct command + if (bs::StringUtil::compare(command, it->name) == 0) break; + } + if (it == mCommands.end()) { - outputs.push_back("Unkown command: " + command); + outputs.push_back("Unkown command!"); } else { @@ -137,7 +155,7 @@ namespace REGoth mConsoleUI->setOutput(outputs); } - void Console::command_CheatFull(bs::Vector args) + void Console::command_CheatFull(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat full' is not implemented yet!"); @@ -145,7 +163,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'cheat full' is not implemented yet!"); } - void Console::command_CheatGod(bs::Vector args) + void Console::command_CheatGod(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'cheat god' is not implemented yet!"); @@ -153,7 +171,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'cheat god' is not implemented yet!"); } - void Console::command_Insert(bs::Vector args) + void Console::command_Insert(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'insert' is not implemented yet!"); @@ -161,7 +179,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'insert' is not implemented yet!"); } - void Console::command_Spawnmass(bs::Vector args) + void Console::command_SpawnMass(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'spawnmass' is not implemented yet!"); @@ -169,7 +187,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'spawnmass' is not implemented yet!"); } - void Console::command_Kill(bs::Vector args) + void Console::command_Kill(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'kill' is not implemented yet!"); @@ -177,7 +195,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'kill' is not implemented yet!"); } - void Console::command_EditAbilities(bs::Vector args) + void Console::command_EditAbilities(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit abilities' is not implemented yet!"); @@ -185,7 +203,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'edit abilities' is not implemented yet!"); } - void Console::command_EditFocus(bs::Vector args) + void Console::command_EditFocus(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'edit focus' is not implemented yet!"); @@ -193,7 +211,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'edit focus' is not implemented yet!"); } - void Console::command_SetTime(bs::Vector args) + void Console::command_SetTime(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'set time' is not implemented yet!"); @@ -201,7 +219,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'set time' is not implemented yet!"); } - void Console::command_GotoWaypoint(bs::Vector args) + void Console::command_GotoWaypoint(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto waypoint' is not implemented yet!"); @@ -209,7 +227,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'goto waypoint' is not implemented yet!"); } - void Console::command_GotoCamera(bs::Vector args) + void Console::command_GotoCamera(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto camera' is not implemented yet!"); @@ -217,7 +235,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'goto camera' is not implemented yet!"); } - void Console::command_GotoPos(bs::Vector args) + void Console::command_GotoPos(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'goto pos' is not implemented yet!"); @@ -225,7 +243,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'goto pos' is not implemented yet!"); } - void Console::command_AIGoto(bs::Vector args) + void Console::command_AIGoto(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'aigoto' is not implemented yet!"); @@ -233,7 +251,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'aigoto' is not implemented yet!"); } - void Console::command_SetClippingfactor(bs::Vector args) + void Console::command_SetClippingfactor(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, @@ -242,7 +260,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'set clippingfactor' is not implemented yet!"); } - void Console::command_ZFogZone(bs::Vector args) + void Console::command_ZFogZone(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'zfogzone' is not implemented yet!"); @@ -250,7 +268,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'zfogzone' is not implemented yet!"); } - void Console::command_ToggleConsole(bs::Vector args) + void Console::command_ToggleConsole(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle console' is not implemented yet!"); @@ -258,7 +276,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'toggle console' is not implemented yet!"); } - void Console::command_ToggleFrame(bs::Vector args) + void Console::command_ToggleFrame(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle frame' is not implemented yet!"); @@ -266,7 +284,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'toggle frame' is not implemented yet!"); } - void Console::command_ToggleWaynet(bs::Vector args) + void Console::command_ToggleWaynet(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'toggle waynet' is not implemented yet!"); @@ -274,7 +292,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'toggle waynet' is not implemented yet!"); } - void Console::command_Firstperson(bs::Vector args) + void Console::command_Firstperson(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'firstperson' is not implemented yet!"); @@ -282,7 +300,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'firstperson' is not implemented yet!"); } - void Console::command_HeroExport(bs::Vector args) + void Console::command_HeroExport(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero export' is not implemented yet!"); @@ -290,7 +308,7 @@ namespace REGoth mConsoleUI->setOutput("Command 'hero export' is not implemented yet!"); } - void Console::command_HeroImport(bs::Vector args) + void Console::command_HeroImport(bs::Vector& args) { // TODO: implement REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'hero import' is not implemented yet!"); @@ -361,7 +379,7 @@ namespace REGoth command = CommandBuilder() .name("spawnmass") - .callback(&This::command_Spawnmass) + .callback(&This::command_SpawnMass) .arg(TokenType::Literal) .usage("Usage: spawnmass {giga} [amount]") .help("") diff --git a/src/components/Console.hpp b/src/components/Console.hpp index fca95940..d67cbe5e 100644 --- a/src/components/Console.hpp +++ b/src/components/Console.hpp @@ -12,14 +12,10 @@ namespace REGoth /** * This class handles the logical side of the in-game Console. * This is where the command functions are defined and are registered to the corresponding command. - * Handles history of executed command (TODO) and tries for autocomplete suggestions of the current - * input supplied by the ConsoleUI component. * Executes correct command based on textual input. */ class Console : public bs::Component { - struct Command; // forward declaration - public: Console(const bs::HSceneObject& parent); virtual ~Console(); @@ -55,216 +51,194 @@ namespace REGoth /** * Clears console output * - * * @param args * Does not use any arguments. */ - void command_Clear(bs::Vector args); + void command_Clear(bs::Vector& args); /** * Lists all commands that are registered to this Console. * - * * @param args * Does not use any arguments. */ - void command_List(bs::Vector args); + void command_List(bs::Vector& args); /** * Prints a 'helpful' help message (aka a short description) of the given command. * - * * @param args * Name of the command. */ - void command_Help(bs::Vector args); + void command_Help(bs::Vector& args); /** * Restores health and mana of the currently controlled(?) character. * TODO: currently controlled or PC_HERO only? * - * * @param args * Does not use any arguments. */ - void command_CheatFull(bs::Vector args); + void command_CheatFull(bs::Vector& args); /** * Turns on god mode for the currently controlled(?) character. * TODO: currently controlled or PC_HERO only? * TODO: Is god mode only invulnerability? * - * * @param args * Does not use any arguments. */ - void command_CheatGod(bs::Vector args); + void command_CheatGod(bs::Vector& args); /** * Insert the given Item/NPC infront of the currently controlled character. * - * * @param args * Name of an item or NPC. * TODO: Anything else you can insert with this? */ - void command_Insert(bs::Vector args); + void command_Insert(bs::Vector& args); /** * Spawns (???) around(?) the currently controlled character- * - * * @param args * Amount of entities to spawn. */ - void command_Spawnmass(bs::Vector args); + void command_SpawnMass(bs::Vector& args); /** * Kills target currently in focus. * - * * @param args * Does not use any arguments. */ - void command_Kill(bs::Vector args); + void command_Kill(bs::Vector& args); /** * Allows editing various attributes and abilities of the currently controlled character. * - * * @param args * Does not use any arguments. */ - void command_EditAbilities(bs::Vector args); + void command_EditAbilities(bs::Vector& args); /** * Allows editing various attributes and abilities of the character currently in focus. * - * * @param args * Does not use any arguments. */ - void command_EditFocus(bs::Vector args); + void command_EditFocus(bs::Vector& args); /** * Sets the current time. * - * * @param args * Two literal arguments in the form of [hh] [mm]. */ - void command_SetTime(bs::Vector args); + void command_SetTime(bs::Vector& args); /** * Teleport the currently controlled character to the given waypoint. * - * * @param args * Waypoint to teleport to. */ - void command_GotoWaypoint(bs::Vector args); + void command_GotoWaypoint(bs::Vector& args); /** * Teleports PC_HERO(?) to the free floating camera. * - * * @param args * Does not use any arguments. */ - void command_GotoCamera(bs::Vector args); + void command_GotoCamera(bs::Vector& args); /** * Teleport the currently controlled character to the given position in the world. * - * * @param args * Three literal arguments in the form of [x] [y] [z] to repesent a position. */ - void command_GotoPos(bs::Vector args); + void command_GotoPos(bs::Vector& args); /** * ??? * - * * @param args * Waypoint. */ - void command_AIGoto(bs::Vector args); + void command_AIGoto(bs::Vector& args); /** * ??? * - * * @param args * Literal float argument. */ - void command_SetClippingfactor(bs::Vector args); + void command_SetClippingfactor(bs::Vector& args); /** * ??? * - * * @param args * Does not use any arguments. */ - void command_ZFogZone(bs::Vector args); + void command_ZFogZone(bs::Vector& args); /** * Toggles the visuals of the console. * - * * @param args * Does not use any arguments. */ - void command_ToggleConsole(bs::Vector args); + void command_ToggleConsole(bs::Vector& args); /** * Toggles the visuals of the frame (whole gameui). * - * * @param args * Does not use any arguments. */ - void command_ToggleFrame(bs::Vector args); + void command_ToggleFrame(bs::Vector& args); /** * Toggles the visuals of the waynet (debug). * - * * @param args * Does not use any arguments. */ - void command_ToggleWaynet(bs::Vector args); + void command_ToggleWaynet(bs::Vector& args); /** * Toggles firstperson mode. * - * * @param args * Does not use any arguments. */ - void command_Firstperson(bs::Vector args); + void command_Firstperson(bs::Vector& args); /** * Exports attributes and abilities of currently controlled characters to a file with the given * name in the save folder. * - * * @param args * Name of the file. */ - void command_HeroExport(bs::Vector args); + void command_HeroExport(bs::Vector& args); /** * Import attributes and abilities from the file with the given name in the save folder and apply * them to the currently controlled character. * - * * @param args * Name of the file. */ - void command_HeroImport(bs::Vector args); + void command_HeroImport(bs::Vector& args); + struct Command; // forward declaration /** * Register a command by * @@ -284,7 +258,7 @@ namespace REGoth private: HUIConsole mConsoleUI; bs::Vector mCommands; - using commandCallback = void (Console::*)(bs::Vector); + using commandCallback = void (Console::*)(bs::Vector&); /** * A collection of all types of tokesn that can appear in a command like the command itself and diff --git a/src/components/UIConsole.hpp b/src/components/UIConsole.hpp index f2bed37d..8553ed3a 100644 --- a/src/components/UIConsole.hpp +++ b/src/components/UIConsole.hpp @@ -16,7 +16,7 @@ namespace REGoth * properties (TODO). * * The component is largely autonomous and works solely on the input of the user by delegated it to - * the actual Console component. + * the actual Console component via events. */ class UIConsole : public UIElement { From 063a7991b19f0339ea9c38799e910633a476e062 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Wed, 7 Aug 2019 18:15:39 +0200 Subject: [PATCH 7/8] Implement get/set time --- src/components/Console.cpp | 36 ++++++++++++++++++++++++++++++++---- src/components/Console.hpp | 14 +++++++++++++- src/main_WorldViewer.cpp | 2 +- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/components/Console.cpp b/src/components/Console.cpp index 932c78d9..b21d97b1 100644 --- a/src/components/Console.cpp +++ b/src/components/Console.cpp @@ -1,4 +1,6 @@ #include "Console.hpp" +#include "components/GameClock.hpp" +#include "components/GameWorld.hpp" #include "components/GameplayUI.hpp" #include "components/UIConsole.hpp" #include @@ -7,8 +9,9 @@ namespace REGoth { - Console::Console(const bs::HSceneObject& parent) + Console::Console(const bs::HSceneObject& parent, HGameWorld gameWorld) : bs::Component(parent) + , mGameWorld(gameWorld) { setName("Console"); @@ -211,12 +214,29 @@ namespace REGoth mConsoleUI->setOutput("Command 'edit focus' is not implemented yet!"); } + void Console::command_GetTime(bs::Vector& args) + { + auto clock = mGameWorld->gameclock(); + bs::INT32 day = clock->getDay(); + bs::INT32 hour = clock->getHour(); + bs::INT32 minute = clock->getMinute(); + + // FIXME: proper formatting for hour and day, maybe move to GameClock + bs::String output = bs::StringUtil::format("Time: Day {0} {1}:{2}", day, hour, minute); + + mConsoleUI->setOutput(output); + REGOTH_LOG(Info, Uncategorized, output); + } + void Console::command_SetTime(bs::Vector& args) { - // TODO: implement - REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'set time' is not implemented yet!"); + auto clock = mGameWorld->gameclock(); + bs::INT32 hh = bs::parseINT32(args[0]); + bs::INT32 mm = bs::parseINT32(args[1]); - mConsoleUI->setOutput("Command 'set time' is not implemented yet!"); + clock->setTime(hh, mm); + + mConsoleUI->setOutput("Set time called!"); } void Console::command_GotoWaypoint(bs::Vector& args) @@ -410,6 +430,14 @@ namespace REGoth .build(); registerCommand(command); + command = CommandBuilder() + .name("get time") + .callback(&This::command_GetTime) + .usage("Usage: get time") + .help("") + .build(); + registerCommand(command); + command = CommandBuilder() .name("set time") .callback(&This::command_SetTime) diff --git a/src/components/Console.hpp b/src/components/Console.hpp index d67cbe5e..215e3d94 100644 --- a/src/components/Console.hpp +++ b/src/components/Console.hpp @@ -9,6 +9,9 @@ namespace REGoth class UIConsole; using HUIConsole = bs::GameObjectHandle; + class GameWorld; + using HGameWorld = bs::GameObjectHandle; + /** * This class handles the logical side of the in-game Console. * This is where the command functions are defined and are registered to the corresponding command. @@ -17,7 +20,7 @@ namespace REGoth class Console : public bs::Component { public: - Console(const bs::HSceneObject& parent); + Console(const bs::HSceneObject& parent, HGameWorld gameWorld); virtual ~Console(); /** @@ -132,6 +135,14 @@ namespace REGoth */ void command_EditFocus(bs::Vector& args); + /** + * Gets the current time. + * + * @param args + * Does not use any arguments. + */ + void command_GetTime(bs::Vector& args); + /** * Sets the current time. * @@ -256,6 +267,7 @@ namespace REGoth void registerAllCommand(); private: + HGameWorld mGameWorld; HUIConsole mConsoleUI; bs::Vector mCommands; using commandCallback = void (Console::*)(bs::Vector&); diff --git a/src/main_WorldViewer.cpp b/src/main_WorldViewer.cpp index 777a8d3f..4f667a40 100644 --- a/src/main_WorldViewer.cpp +++ b/src/main_WorldViewer.cpp @@ -131,7 +131,7 @@ class REGothWorldViewer : public REGoth::Engine REGoth::GameplayUI::createGlobal(mMainCamera); - world->SO()->addComponent(); + world->SO()->addComponent(world); auto inventory = hero->SO()->getComponent(); From 2a20336582349a6db32e993a37a3a33babd11a37 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Thu, 8 Aug 2019 19:41:13 +0200 Subject: [PATCH 8/8] Unchecked insert and give --- src/components/Console.cpp | 63 ++++++++++++++++++++++++++++++------ src/components/Console.hpp | 9 ++++++ src/components/Inventory.cpp | 2 +- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/components/Console.cpp b/src/components/Console.cpp index b21d97b1..71fe2b9f 100644 --- a/src/components/Console.cpp +++ b/src/components/Console.cpp @@ -1,7 +1,9 @@ #include "Console.hpp" +#include "components/Character.hpp" #include "components/GameClock.hpp" #include "components/GameWorld.hpp" #include "components/GameplayUI.hpp" +#include "components/Inventory.hpp" #include "components/UIConsole.hpp" #include #include @@ -174,12 +176,43 @@ namespace REGoth mConsoleUI->setOutput("Command 'cheat god' is not implemented yet!"); } + void Console::command_Give(bs::Vector& args) + { + bs::String& instance = args[0]; + bs::StringUtil::replaceAll(instance, "_", ""); + bs::StringUtil::toUpperCase(instance); + const bs::UINT32 amount = bs::parseINT32(args[1]); + + auto inventory = mGameWorld->hero()->SO()->getComponent(); + inventory->giveItem(instance, amount); + + bs::String output = bs::StringUtil::format("Gave {0} {1} to hero.", instance, amount); + mConsoleUI->setOutput(output); + } + void Console::command_Insert(bs::Vector& args) { - // TODO: implement - REGOTH_LOG(Warning, Uncategorized, "[Console] Command 'insert' is not implemented yet!"); + bs::String& instance = args[0]; + bs::StringUtil::replaceAll(instance, "_", ""); + bs::StringUtil::toUpperCase(instance); + const bs::Transform& transform = mGameWorld->hero()->SO()->getTransform(); + REGOTH_LOG(Info, Uncategorized, "Insert called with {0}.", instance); + + // determine if it is an item or a "creature" + if (bs::StringUtil::startsWith(instance, "it")) // this is not entirely correct :) + { + REGOTH_LOG(Info, Uncategorized, "Is am item!", instance); + mGameWorld->insertItem(instance, transform); + } + else + { + REGOTH_LOG(Info, Uncategorized, "Is a character!", instance); + mGameWorld->insertCharacter(instance, transform); + } - mConsoleUI->setOutput("Command 'insert' is not implemented yet!"); + bs::String output = + bs::StringUtil::format("Inserted {0} at some place.", instance /*, transform*/); + mConsoleUI->setOutput(output); } void Console::command_SpawnMass(bs::Vector& args) @@ -216,10 +249,10 @@ namespace REGoth void Console::command_GetTime(bs::Vector& args) { - auto clock = mGameWorld->gameclock(); - bs::INT32 day = clock->getDay(); - bs::INT32 hour = clock->getHour(); - bs::INT32 minute = clock->getMinute(); + auto clock = mGameWorld->gameclock(); + const bs::INT32 day = clock->getDay(); + const bs::INT32 hour = clock->getHour(); + const bs::INT32 minute = clock->getMinute(); // FIXME: proper formatting for hour and day, maybe move to GameClock bs::String output = bs::StringUtil::format("Time: Day {0} {1}:{2}", day, hour, minute); @@ -230,9 +263,9 @@ namespace REGoth void Console::command_SetTime(bs::Vector& args) { - auto clock = mGameWorld->gameclock(); - bs::INT32 hh = bs::parseINT32(args[0]); - bs::INT32 mm = bs::parseINT32(args[1]); + auto clock = mGameWorld->gameclock(); + const bs::INT32 hh = bs::parseINT32(args[0]); + const bs::INT32 mm = bs::parseINT32(args[1]); clock->setTime(hh, mm); @@ -388,6 +421,16 @@ namespace REGoth .build(); registerCommand(command); + command = CommandBuilder() + .name("give") + .callback(&This::command_Give) + .arg(TokenType::Instance) + .arg(TokenType::Literal) + .usage("Usage: give [name] [amount]") + .help("") + .build(); + registerCommand(command); + command = CommandBuilder() .name("insert") .callback(&This::command_Insert) diff --git a/src/components/Console.hpp b/src/components/Console.hpp index 215e3d94..5eeaa907 100644 --- a/src/components/Console.hpp +++ b/src/components/Console.hpp @@ -94,6 +94,15 @@ namespace REGoth */ void command_CheatGod(bs::Vector& args); + /** + * Give the given item to pc_hero + * + * @param args + * Name of an item. + * Amount. + */ + void command_Give(bs::Vector& args); + /** * Insert the given Item/NPC infront of the currently controlled character. * diff --git a/src/components/Inventory.cpp b/src/components/Inventory.cpp index ee637661..aa0cc136 100644 --- a/src/components/Inventory.cpp +++ b/src/components/Inventory.cpp @@ -44,7 +44,7 @@ namespace REGoth REGOTH_THROW(InvalidParametersException, "Count cannot be 0"); } - mItemCountByInstance[instance] += 1; + mItemCountByInstance[instance] += count; OnItemChanged(instance); }