feat: Implement clear and playanim console commands

This commit is contained in:
Vsevolod Kremianskii 2020-12-13 13:07:07 +07:00
parent 472f2a8c57
commit ced99add00
4 changed files with 85 additions and 13 deletions

View file

@ -29,8 +29,9 @@ Specify a game path to run the game, e.g. `reone --game C:\swkotor`
Controls:
* Use WASD and ZC keys to move around
* Left click to interact with an object
* Use V key to switch the camera type
* Press V to switch the camera type
* Use "-" and "+" keys to adjust the game speed
* Press "~" to toggle the debug console
## Configuration

View file

@ -17,19 +17,26 @@
#include "console.h"
#include <boost/algorithm/string.hpp>
#include "glm/ext.hpp"
#include "../common/log.h"
#include "../render/font.h"
#include "../render/fonts.h"
#include "../render/mesh/quad.h"
#include "../render/shaders.h"
#include "../resource/resources.h"
#include "game.h"
using namespace std;
using namespace std::placeholders;
using namespace reone::gui;
using namespace reone::render;
using namespace reone::scene;
namespace reone {
@ -38,7 +45,51 @@ namespace game {
constexpr int kMaxOutputLineCount = 50;
constexpr int kVisibleLineCount = 15;
Console::Console(const GraphicsOptions &opts) : _opts(opts), _input(kTextInputConsole) {
Console::Console(Game *game) :
_game(game),
_opts(game->options().graphics),
_input(kTextInputConsole) {
initCommands();
}
void Console::initCommands() {
addCommand("clear", bind(&Console::cmdClear, this, _1));
addCommand("playanim", bind(&Console::cmdPlayAnim, this, _1));
}
void Console::addCommand(const std::string &name, const CommandHandler &handler) {
_commands.insert(make_pair(name, handler));
}
void Console::cmdClear(vector<string> tokens) {
_output.clear();
_outputOffset = 0;
}
void Console::cmdPlayAnim(vector<string> tokens) {
if (tokens.size() < 2) {
print("Usage: playanim anim_name");
return;
}
ObjectSelector &selector = _game->module()->area()->objectSelector();
auto selectedObject = selector.selectedObject();
if (!selectedObject) {
print("playanim: no object selected");
return;
}
selectedObject->model()->playAnimation(tokens[1], kAnimationLoop);
}
void Console::print(const string &text) {
_output.push_front(text);
trimOutput();
}
void Console::trimOutput() {
for (int i = static_cast<int>(_output.size()) - kMaxOutputLineCount; i > 0; --i) {
_output.pop_back();
}
}
void Console::load() {
@ -103,14 +154,16 @@ bool Console::handleKeyUp(const SDL_KeyboardEvent &event) {
}
void Console::executeInputText() {
debug(boost::format("Console: execute \"%s\"") % _input.text());
_output.push_front(_input.text());
trimOutput();
}
vector<string> tokens;
boost::split(tokens, _input.text(), boost::is_space(), boost::token_compress_on);
void Console::trimOutput() {
for (int i = static_cast<int>(_output.size()) - kMaxOutputLineCount; i > 0; --i) {
_output.pop_back();
if (tokens.empty()) return;
auto maybeCommand = _commands.find(tokens[0]);
if (maybeCommand != _commands.end()) {
maybeCommand->second(move(tokens));
} else {
print("Unsupported command: " + tokens[0]);
}
}
@ -149,7 +202,7 @@ void Console::drawLines() const {
// Output
for (int i = 0; i < kVisibleLineCount - 1 && i < static_cast<int>(_output.size()) - _outputOffset; ++i) {
const string &line = _output[i + _outputOffset];
const string &line = _output[static_cast<size_t>(i) + _outputOffset];
transform = glm::translate(transform, glm::vec3(0.0f, -_font->height(), 0.0f));
_font->render(line, transform, glm::vec3(1.0f), TextGravity::Right);
}

View file

@ -21,6 +21,7 @@
#include <memory>
#include <string>
#include <queue>
#include <unordered_map>
#include "SDL2/SDL_events.h"
@ -32,9 +33,11 @@ namespace reone {
namespace game {
class Game;
class Console {
public:
Console(const render::GraphicsOptions &opts);
Console(Game *game);
void load();
bool handle(const SDL_Event &event);
@ -43,12 +46,16 @@ public:
bool isOpen() const;
private:
std::shared_ptr<render::Font> _font;
typedef std::function<void(std::vector<std::string>)> CommandHandler;
Game *_game;
render::GraphicsOptions _opts;
std::shared_ptr<render::Font> _font;
bool _open { false };
gui::TextInput _input;
std::deque<std::string> _output;
int _outputOffset { 0 };
std::unordered_map<std::string, CommandHandler> _commands;
Console(const Console &) = delete;
Console &operator=(const Console &) = delete;
@ -57,10 +64,21 @@ private:
bool handleKeyUp(const SDL_KeyboardEvent &event);
void executeInputText();
void print(const std::string &text);
void trimOutput();
void drawBackground() const;
void drawLines() const;
// Commands
void initCommands();
void addCommand(const std::string &name, const CommandHandler &handler);
void cmdClear(std::vector<std::string> tokens);
void cmdPlayAnim(std::vector<std::string> tokens);
// END Commands
};
} // namespace game

View file

@ -60,7 +60,7 @@ Game::Game(const fs::path &path, const Options &opts) :
_window(opts.graphics, this),
_sceneGraph(opts.graphics),
_worldPipeline(&_sceneGraph, opts.graphics),
_console(opts.graphics),
_console(this),
_party(this) {
initGameVersion();