refactor: Prefer dependency injection to callbacks in concrete GUIs
This commit is contained in:
parent
fce658500b
commit
fe1ab7a424
20 changed files with 286 additions and 361 deletions
|
@ -250,28 +250,13 @@ void Game::drawCursor() {
|
|||
}
|
||||
|
||||
void Game::loadHUD() {
|
||||
_hud.reset(new HUD(_version, _options.graphics));
|
||||
_hud.reset(new HUD(this, _version, _options.graphics));
|
||||
_hud->load();
|
||||
_hud->setOnEquipmentClick(bind(&Game::onEquipmentClick, this));
|
||||
}
|
||||
|
||||
void Game::onEquipmentClick() {
|
||||
_hud->resetFocus();
|
||||
|
||||
shared_ptr<SpatialObject> player(_module->area()->player());
|
||||
_equipment->open(player.get());
|
||||
|
||||
_screen = GameScreen::Equipment;
|
||||
}
|
||||
|
||||
void Game::loadDialogGui() {
|
||||
_dialog.reset(new Dialog(_version, this, _options.graphics));
|
||||
_dialog.reset(new Dialog(this, _version, _options.graphics));
|
||||
_dialog->load();
|
||||
_dialog->setOnDialogFinished(bind(&Game::onDialogFinished, this));
|
||||
}
|
||||
|
||||
void Game::onDialogFinished() {
|
||||
_screen = GameScreen::InGame;
|
||||
}
|
||||
|
||||
void Game::loadContainerGui() {
|
||||
|
@ -280,12 +265,8 @@ void Game::loadContainerGui() {
|
|||
}
|
||||
|
||||
void Game::loadEquipmentGui() {
|
||||
_equipment.reset(new Equipment(_version, _options.graphics));
|
||||
_equipment.reset(new Equipment(this, _version, _options.graphics));
|
||||
_equipment->load();
|
||||
_equipment->setOnClose([this]() {
|
||||
_equipment->resetFocus();
|
||||
_screen = GameScreen::InGame;
|
||||
});
|
||||
}
|
||||
|
||||
GUI *Game::getScreenGUI() const {
|
||||
|
@ -430,6 +411,12 @@ void Game::onCameraChanged(CameraType camera) {
|
|||
_window.setRelativeMouseMode(camera == CameraType::FirstPerson);
|
||||
}
|
||||
|
||||
void Game::openEquipment() {
|
||||
shared_ptr<SpatialObject> player(_module->area()->player());
|
||||
_equipment->open(player.get());
|
||||
_screen = GameScreen::Equipment;
|
||||
}
|
||||
|
||||
bool Game::handle(const SDL_Event &event) {
|
||||
GUI *gui = getScreenGUI();
|
||||
if (gui && gui->handle(event)) {
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
void openContainer(SpatialObject *container);
|
||||
void scheduleModuleTransition(const std::string &moduleName, const std::string &entry);
|
||||
void onCameraChanged(CameraType camera);
|
||||
void openEquipment();
|
||||
|
||||
bool handle(const SDL_Event &event) override;
|
||||
|
||||
|
@ -206,7 +207,6 @@ private:
|
|||
// Event handlers
|
||||
|
||||
void onDialogFinished();
|
||||
void onEquipmentClick();
|
||||
|
||||
// END Event handlers
|
||||
};
|
||||
|
|
|
@ -70,157 +70,34 @@ void CharacterGeneration::load() {
|
|||
|
||||
loadClassSelection();
|
||||
loadQuickOrCustom();
|
||||
loadQuickCharacterGeneration();
|
||||
loadQuick();
|
||||
loadPortraitSelection();
|
||||
loadNameEntry();
|
||||
}
|
||||
|
||||
void CharacterGeneration::loadClassSelection() {
|
||||
_classSelection = make_unique<ClassSelection>(_game, _version, _gfxOpts);
|
||||
_classSelection = make_unique<ClassSelection>(_game, this, _version, _gfxOpts);
|
||||
_classSelection->load();
|
||||
_classSelection->setOnClassSelected([this](const CreatureConfiguration &config) {
|
||||
_classSelection->resetFocus();
|
||||
_portraitSelection->loadPortraits(config);
|
||||
loadCharacter(config);
|
||||
showControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::QuickOrCustom;
|
||||
});
|
||||
_classSelection->setOnCancel([this]() {
|
||||
_classSelection->resetFocus();
|
||||
_game->openMainMenu();
|
||||
});
|
||||
}
|
||||
|
||||
void CharacterGeneration::loadCharacter(const CreatureConfiguration &config) {
|
||||
_character = config;
|
||||
|
||||
Control &lblModel = getControl("MODEL_LBL");
|
||||
const Control::Extent &extent = lblModel.extent();
|
||||
float aspect = extent.width / static_cast<float>(extent.height);
|
||||
|
||||
glm::mat4 cameraTransform(1.0f);
|
||||
cameraTransform = glm::translate(cameraTransform, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
cameraTransform = glm::rotate(cameraTransform, glm::half_pi<float>(), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
cameraTransform = glm::rotate(cameraTransform, glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
unique_ptr<Control::Scene3D> scene(SceneBuilder(_gfxOpts)
|
||||
.aspect(aspect)
|
||||
.depth(0.1f, 10.0f)
|
||||
.modelSupplier(bind(&CharacterGeneration::getCharacterModel, this, config, _1))
|
||||
.modelScale(kModelScale)
|
||||
.modelOffset(glm::vec2(0.0f, kModelOffsetY))
|
||||
.cameraTransform(cameraTransform)
|
||||
.ambientLightColor(glm::vec3(1.0f))
|
||||
.build());
|
||||
|
||||
lblModel.setScene3D(move(scene));
|
||||
|
||||
string portrait(findPortrait(config.appearance));
|
||||
Control &lblPortrait = getControl("PORTRAIT_LBL");
|
||||
|
||||
if (!portrait.empty()) {
|
||||
lblPortrait.setBorderFill(portrait);
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<ModelSceneNode> CharacterGeneration::getCharacterModel(const CreatureConfiguration &config, SceneGraph &sceneGraph) {
|
||||
unique_ptr<ObjectFactory> objectFactory(new ObjectFactory(_version, _game, &sceneGraph, _gfxOpts));
|
||||
|
||||
unique_ptr<Creature> creature(objectFactory->newCreature());
|
||||
creature->load(config);
|
||||
|
||||
return creature->model();
|
||||
}
|
||||
|
||||
void CharacterGeneration::loadQuickOrCustom() {
|
||||
_quickOrCustom = make_unique<QuickOrCustom>(_version, _gfxOpts);
|
||||
_quickOrCustom = make_unique<QuickOrCustom>(this, _version, _gfxOpts);
|
||||
_quickOrCustom->load();
|
||||
_quickOrCustom->setOnQuickCharacter([this]() {
|
||||
_quickOrCustom->resetFocus();
|
||||
_screen = CharGenScreen::Quick;
|
||||
});
|
||||
_quickOrCustom->setOnBack([this]() {
|
||||
_quickOrCustom->resetFocus();
|
||||
hideControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::ClassSelection;
|
||||
});
|
||||
}
|
||||
|
||||
void CharacterGeneration::loadQuickCharacterGeneration() {
|
||||
_quick = make_unique<QuickCharacterGeneration>(_version, _gfxOpts);
|
||||
void CharacterGeneration::loadQuick() {
|
||||
_quick = make_unique<QuickCharacterGeneration>(this, _version, _gfxOpts);
|
||||
_quick->load();
|
||||
|
||||
if (_version == GameVersion::KotOR) {
|
||||
_quick->configureControl("LBL_DECORATION", [](Control &ctrl) { ctrl.setDiscardColor(glm::vec3(0.0f, 0.0f, 0.082353f)); });
|
||||
}
|
||||
_quick->setOnStepSelected([this](int step) {
|
||||
_quick->resetFocus();
|
||||
|
||||
switch (step) {
|
||||
case 1:
|
||||
hideControl("MODEL_LBL");
|
||||
_portraitSelection->loadPortraits(_character);
|
||||
_screen = CharGenScreen::PortraitSelection;
|
||||
break;
|
||||
case 2:
|
||||
hideControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::Name;
|
||||
break;
|
||||
default:
|
||||
finishCharacterGeneration();
|
||||
break;
|
||||
}
|
||||
});
|
||||
_quick->setOnCancel([this]() {
|
||||
_quick->resetFocus();
|
||||
_screen = CharGenScreen::QuickOrCustom;
|
||||
});
|
||||
}
|
||||
|
||||
void CharacterGeneration::finishCharacterGeneration() {
|
||||
string moduleName(_version == GameVersion::KotOR ? "end_m01aa" : "001ebo");
|
||||
|
||||
CreatureConfiguration config(_character);
|
||||
config.equipment.clear();
|
||||
|
||||
PartyConfiguration party;
|
||||
party.memberCount = 1;
|
||||
party.leader = config;
|
||||
|
||||
_game->loadModule(moduleName, party);
|
||||
}
|
||||
|
||||
void CharacterGeneration::loadPortraitSelection() {
|
||||
_portraitSelection = make_unique<PortraitSelection>(_version, _gfxOpts);
|
||||
_portraitSelection = make_unique<PortraitSelection>(this, _version, _gfxOpts);
|
||||
_portraitSelection->load();
|
||||
_portraitSelection->setOnPortraitSelected([this](const CreatureConfiguration &config) {
|
||||
_portraitSelection->resetFocus();
|
||||
loadCharacter(config);
|
||||
showControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::Quick;
|
||||
_quick->setStep(1);
|
||||
});
|
||||
_portraitSelection->setOnCancel([this]() {
|
||||
_portraitSelection->resetFocus();
|
||||
showControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::Quick;
|
||||
});
|
||||
}
|
||||
|
||||
void CharacterGeneration::loadNameEntry() {
|
||||
_nameEntry = make_unique<NameEntry>(_version, _gfxOpts);
|
||||
_nameEntry = make_unique<NameEntry>(this, _version, _gfxOpts);
|
||||
_nameEntry->load();
|
||||
_nameEntry->setOnEnd([this]() {
|
||||
_nameEntry->resetFocus();
|
||||
showControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::Quick;
|
||||
_quick->setStep(2);
|
||||
});
|
||||
_nameEntry->setOnBack([this]() {
|
||||
_nameEntry->resetFocus();
|
||||
showControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::Quick;
|
||||
});
|
||||
}
|
||||
|
||||
bool CharacterGeneration::handle(const SDL_Event &event) {
|
||||
|
@ -262,6 +139,100 @@ void CharacterGeneration::render3D() const {
|
|||
getSubGUI()->render3D();
|
||||
}
|
||||
|
||||
void CharacterGeneration::finish() {
|
||||
string moduleName(_version == GameVersion::KotOR ? "end_m01aa" : "001ebo");
|
||||
|
||||
CreatureConfiguration config(_character);
|
||||
config.equipment.clear();
|
||||
|
||||
PartyConfiguration party;
|
||||
party.memberCount = 1;
|
||||
party.leader = config;
|
||||
|
||||
_game->loadModule(moduleName, party);
|
||||
}
|
||||
|
||||
void CharacterGeneration::cancel() {
|
||||
_game->openMainMenu();
|
||||
}
|
||||
|
||||
void CharacterGeneration::openClassSelection() {
|
||||
hideControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::ClassSelection;
|
||||
}
|
||||
|
||||
void CharacterGeneration::openNameEntry() {
|
||||
hideControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::Name;
|
||||
}
|
||||
|
||||
void CharacterGeneration::openPortraitSelection() {
|
||||
hideControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::PortraitSelection;
|
||||
}
|
||||
|
||||
void CharacterGeneration::openQuick() {
|
||||
showControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::Quick;
|
||||
}
|
||||
|
||||
void CharacterGeneration::openQuickOrCustom() {
|
||||
showControl("MODEL_LBL");
|
||||
_screen = CharGenScreen::QuickOrCustom;
|
||||
}
|
||||
|
||||
void CharacterGeneration::loadCharacterModel() {
|
||||
Control &lblModel = getControl("MODEL_LBL");
|
||||
const Control::Extent &extent = lblModel.extent();
|
||||
float aspect = extent.width / static_cast<float>(extent.height);
|
||||
|
||||
glm::mat4 cameraTransform(1.0f);
|
||||
cameraTransform = glm::translate(cameraTransform, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
cameraTransform = glm::rotate(cameraTransform, glm::half_pi<float>(), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
cameraTransform = glm::rotate(cameraTransform, glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
unique_ptr<Control::Scene3D> scene(SceneBuilder(_gfxOpts)
|
||||
.aspect(aspect)
|
||||
.depth(0.1f, 10.0f)
|
||||
.modelSupplier(bind(&CharacterGeneration::getCharacterModel, this, _1))
|
||||
.modelScale(kModelScale)
|
||||
.modelOffset(glm::vec2(0.0f, kModelOffsetY))
|
||||
.cameraTransform(cameraTransform)
|
||||
.ambientLightColor(glm::vec3(1.0f))
|
||||
.build());
|
||||
|
||||
lblModel.setScene3D(move(scene));
|
||||
|
||||
string portrait(findPortrait(_character.appearance));
|
||||
if (!portrait.empty()) {
|
||||
Control &lblPortrait = getControl("PORTRAIT_LBL");
|
||||
lblPortrait.setBorderFill(portrait);
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<ModelSceneNode> CharacterGeneration::getCharacterModel(SceneGraph &sceneGraph) {
|
||||
unique_ptr<ObjectFactory> objectFactory(new ObjectFactory(_version, _game, &sceneGraph, _gfxOpts));
|
||||
|
||||
unique_ptr<Creature> creature(objectFactory->newCreature());
|
||||
creature->load(_character);
|
||||
|
||||
return creature->model();
|
||||
}
|
||||
|
||||
const CreatureConfiguration &CharacterGeneration::character() const {
|
||||
return _character;
|
||||
}
|
||||
|
||||
void CharacterGeneration::setCharacter(const CreatureConfiguration &config) {
|
||||
_character = config;
|
||||
loadCharacterModel();
|
||||
_portraitSelection->updatePortraits();
|
||||
}
|
||||
|
||||
void CharacterGeneration::setQuickStep(int step) {
|
||||
_quick->setStep(step);
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -48,12 +48,24 @@ public:
|
|||
CharacterGeneration(Game *game, resource::GameVersion, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
|
||||
bool handle(const SDL_Event &event) override;
|
||||
void update(float dt) override;
|
||||
void render() const override;
|
||||
void render3D() const override;
|
||||
|
||||
void finish();
|
||||
void cancel();
|
||||
void openClassSelection();
|
||||
void openNameEntry();
|
||||
void openPortraitSelection();
|
||||
void openQuick();
|
||||
void openQuickOrCustom();
|
||||
|
||||
const CreatureConfiguration &character() const;
|
||||
|
||||
void setCharacter(const CreatureConfiguration &config);
|
||||
void setQuickStep(int step);
|
||||
|
||||
private:
|
||||
Game *_game { nullptr };
|
||||
CharGenScreen _screen { CharGenScreen::ClassSelection };
|
||||
|
@ -70,26 +82,20 @@ private:
|
|||
|
||||
// END Sub GUI
|
||||
|
||||
void loadCharacterModel();
|
||||
|
||||
gui::GUI *getSubGUI() const;
|
||||
std::shared_ptr<scene::ModelSceneNode> getCharacterModel(const CreatureConfiguration &config, scene::SceneGraph &sceneGraph);
|
||||
std::shared_ptr<scene::ModelSceneNode> getCharacterModel(scene::SceneGraph &sceneGraph);
|
||||
|
||||
// Loading
|
||||
|
||||
void loadClassSelection();
|
||||
void loadQuickOrCustom();
|
||||
void loadQuickCharacterGeneration();
|
||||
void loadQuick();
|
||||
void loadPortraitSelection();
|
||||
void loadNameEntry();
|
||||
|
||||
void loadCharacter(const CreatureConfiguration &config);
|
||||
|
||||
// END Loading
|
||||
|
||||
// Event handling
|
||||
|
||||
void finishCharacterGeneration();
|
||||
|
||||
// END Event handling
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "../colors.h"
|
||||
|
||||
#include "chargen.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::gui;
|
||||
|
@ -62,8 +64,10 @@ static map<ClassType, int> g_classDescStrRefs {
|
|||
{ ClassType::JediGuardian, 48033 }
|
||||
};
|
||||
|
||||
ClassSelection::ClassSelection(Game *game, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts), _game(game) {
|
||||
ClassSelection::ClassSelection(Game *game, CharacterGeneration *charGen, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_game(game),
|
||||
_charGen(charGen) {
|
||||
|
||||
_resRef = getResRef("classsel");
|
||||
|
||||
|
@ -240,27 +244,19 @@ int ClassSelection::getClassButtonIndexByTag(const string &tag) const {
|
|||
}
|
||||
|
||||
void ClassSelection::onClick(const string &control) {
|
||||
resetFocus();
|
||||
|
||||
int idx = getClassButtonIndexByTag(control);
|
||||
if (idx != -1) {
|
||||
ClassButton &button = _classButtons[idx];
|
||||
if (_onClassSelected) {
|
||||
_onClassSelected(button.config);
|
||||
}
|
||||
_charGen->setCharacter(_classButtons[idx].config);
|
||||
_charGen->openQuickOrCustom();
|
||||
return;
|
||||
}
|
||||
if (control == "BTN_BACK") {
|
||||
if (_onCancel) _onCancel();
|
||||
_charGen->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void ClassSelection::setOnClassSelected(const function<void(const CreatureConfiguration &)> &fn) {
|
||||
_onClassSelected = fn;
|
||||
}
|
||||
|
||||
void ClassSelection::setOnCancel(const function<void()> &fn) {
|
||||
_onCancel = fn;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -28,17 +28,15 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class CharacterGeneration;
|
||||
class Game;
|
||||
|
||||
class ClassSelection : public gui::GUI {
|
||||
public:
|
||||
ClassSelection(Game *game, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
ClassSelection(Game *game, CharacterGeneration *charGen, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
|
||||
void setOnClassSelected(const std::function<void(const CreatureConfiguration &)> &fn);
|
||||
void setOnCancel(const std::function<void()> &fn);
|
||||
|
||||
private:
|
||||
struct ClassButton {
|
||||
gui::Control *control { nullptr };
|
||||
|
@ -47,12 +45,11 @@ private:
|
|||
};
|
||||
|
||||
Game *_game { nullptr };
|
||||
CharacterGeneration *_charGen { nullptr };
|
||||
resource::GameVersion _version { resource::GameVersion::KotOR };
|
||||
glm::ivec2 _defaultButtonSize { 0 };
|
||||
glm::ivec2 _enlargedButtonSize { 0 };
|
||||
std::vector<ClassButton> _classButtons;
|
||||
std::function<void(const CreatureConfiguration &)> _onClassSelected;
|
||||
std::function<void()> _onCancel;
|
||||
|
||||
void configureClassButtons();
|
||||
void configureClassModels();
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "../colors.h"
|
||||
|
||||
#include "chargen.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::gui;
|
||||
|
@ -29,8 +31,9 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
NameEntry::NameEntry(GameVersion version, const GraphicsOptions &opts) :
|
||||
NameEntry::NameEntry(CharacterGeneration *charGen, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_charGen(charGen),
|
||||
_input(kTextInputLetters | kTextInputWhitespace) {
|
||||
|
||||
_resRef = getResRef("name");
|
||||
|
@ -62,25 +65,17 @@ bool NameEntry::handle(const SDL_Event &event) {
|
|||
}
|
||||
|
||||
void NameEntry::onClick(const string &control) {
|
||||
resetFocus();
|
||||
|
||||
if (control == "END_BTN") {
|
||||
if (_onEnd) {
|
||||
_onEnd();
|
||||
}
|
||||
_charGen->setQuickStep(2);
|
||||
_charGen->openQuick();
|
||||
|
||||
} else if (control == "BTN_BACK") {
|
||||
if (_onBack) {
|
||||
_onBack();
|
||||
}
|
||||
_charGen->openQuick();
|
||||
}
|
||||
}
|
||||
|
||||
void NameEntry::setOnEnd(const function<void()> &fn) {
|
||||
_onEnd = fn;
|
||||
}
|
||||
|
||||
void NameEntry::setOnBack(const function<void()> &fn) {
|
||||
_onBack = fn;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -24,20 +24,18 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class CharacterGeneration;
|
||||
|
||||
class NameEntry : public gui::GUI {
|
||||
public:
|
||||
NameEntry(resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
NameEntry(CharacterGeneration *charGen, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
bool handle(const SDL_Event &event) override;
|
||||
|
||||
void setOnEnd(const std::function<void()> &fn);
|
||||
void setOnBack(const std::function<void()> &fn);
|
||||
|
||||
private:
|
||||
CharacterGeneration *_charGen { nullptr };
|
||||
gui::TextInput _input;
|
||||
std::function<void()> _onEnd;
|
||||
std::function<void()> _onBack;
|
||||
|
||||
void onClick(const std::string &control) override;
|
||||
};
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "../colors.h"
|
||||
|
||||
#include "chargen.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::gui;
|
||||
|
@ -32,7 +34,10 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
PortraitSelection::PortraitSelection(GameVersion version, const GraphicsOptions &opts) : GUI(version, opts) {
|
||||
PortraitSelection::PortraitSelection(CharacterGeneration *charGen, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_charGen(charGen) {
|
||||
|
||||
_resRef = getResRef("portcust");
|
||||
|
||||
switch (version) {
|
||||
|
@ -65,15 +70,12 @@ void PortraitSelection::setButtonColors(const string &tag) {
|
|||
control.setHilight(move(hilight));
|
||||
}
|
||||
|
||||
void PortraitSelection::loadPortraits(const CreatureConfiguration &config) {
|
||||
if (!_portraits.empty() && _character == config) return;
|
||||
|
||||
_character = config;
|
||||
void PortraitSelection::updatePortraits() {
|
||||
_portraits.clear();
|
||||
|
||||
shared_ptr<TwoDaTable> portraits(Resources.find2DA("portraits"));
|
||||
int sex = _character.gender == Gender::Female ? 1 : 0;
|
||||
|
||||
_portraits.clear();
|
||||
const CreatureConfiguration &character = _charGen->character();
|
||||
int sex = character.gender == Gender::Female ? 1 : 0;
|
||||
|
||||
for (auto &row : portraits->rows()) {
|
||||
if (row.getInt("forpc") == 1 && row.getInt("sex") == sex) {
|
||||
|
@ -94,14 +96,18 @@ void PortraitSelection::loadPortraits(const CreatureConfiguration &config) {
|
|||
_portraits.push_back(move(portrait));
|
||||
}
|
||||
}
|
||||
auto maybePortrait = find_if(_portraits.begin(), _portraits.end(), [&config](const Portrait &portrait) {
|
||||
resetCurrentPortrait();
|
||||
}
|
||||
|
||||
void PortraitSelection::resetCurrentPortrait() {
|
||||
const CreatureConfiguration &character = _charGen->character();
|
||||
auto maybePortrait = find_if(_portraits.begin(), _portraits.end(), [&character](const Portrait &portrait) {
|
||||
return
|
||||
portrait.appearanceNumber == config.appearance ||
|
||||
portrait.appearanceS == config.appearance ||
|
||||
portrait.appearanceL == config.appearance;
|
||||
portrait.appearanceNumber == character.appearance ||
|
||||
portrait.appearanceS == character.appearance ||
|
||||
portrait.appearanceL == character.appearance;
|
||||
});
|
||||
_currentPortrait = static_cast<int>(distance(_portraits.begin(), maybePortrait));
|
||||
|
||||
loadCurrentPortrait();
|
||||
}
|
||||
|
||||
|
@ -115,6 +121,8 @@ void PortraitSelection::loadCurrentPortrait() {
|
|||
}
|
||||
|
||||
void PortraitSelection::onClick(const string &control) {
|
||||
resetFocus();
|
||||
|
||||
int portraitCount = static_cast<int>(_portraits.size());
|
||||
|
||||
if (control == "BTN_ARRL") {
|
||||
|
@ -129,37 +137,30 @@ void PortraitSelection::onClick(const string &control) {
|
|||
loadCurrentPortrait();
|
||||
|
||||
} else if (control == "BTN_ACCEPT") {
|
||||
if (_onPortraitSelected) {
|
||||
int appearance;
|
||||
switch (_character.clazz) {
|
||||
case ClassType::Scoundrel:
|
||||
appearance = _portraits[_currentPortrait].appearanceS;
|
||||
break;
|
||||
case ClassType::Soldier:
|
||||
appearance = _portraits[_currentPortrait].appearanceL;
|
||||
break;
|
||||
default:
|
||||
appearance = _portraits[_currentPortrait].appearanceNumber;
|
||||
break;
|
||||
}
|
||||
CreatureConfiguration charGenInfo(_character);
|
||||
charGenInfo.appearance = appearance;
|
||||
_onPortraitSelected(charGenInfo);
|
||||
CreatureConfiguration character(_charGen->character());
|
||||
int appearance;
|
||||
switch (character.clazz) {
|
||||
case ClassType::Scoundrel:
|
||||
appearance = _portraits[_currentPortrait].appearanceS;
|
||||
break;
|
||||
case ClassType::Soldier:
|
||||
appearance = _portraits[_currentPortrait].appearanceL;
|
||||
break;
|
||||
default:
|
||||
appearance = _portraits[_currentPortrait].appearanceNumber;
|
||||
break;
|
||||
}
|
||||
character.appearance = appearance;
|
||||
_charGen->setQuickStep(1);
|
||||
_charGen->setCharacter(character);
|
||||
_charGen->openQuick();
|
||||
|
||||
} else if (control == "BTN_BACK") {
|
||||
if (_onCancel) _onCancel();
|
||||
resetCurrentPortrait();
|
||||
_charGen->openQuick();
|
||||
}
|
||||
}
|
||||
|
||||
void PortraitSelection::setOnPortraitSelected(const function<void(const CreatureConfiguration &)> &fn) {
|
||||
_onPortraitSelected = fn;
|
||||
}
|
||||
|
||||
void PortraitSelection::setOnCancel(const function<void()> &fn) {
|
||||
_onCancel = fn;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -26,26 +26,26 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class CharacterGeneration;
|
||||
|
||||
class PortraitSelection : public gui::GUI {
|
||||
public:
|
||||
PortraitSelection(resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
PortraitSelection(CharacterGeneration *charGen, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
void loadPortraits(const CreatureConfiguration &config);
|
||||
|
||||
void setOnPortraitSelected(const std::function<void(const CreatureConfiguration &)> &fn);
|
||||
void setOnCancel(const std::function<void()> &fn);
|
||||
void updatePortraits();
|
||||
void resetCurrentPortrait();
|
||||
|
||||
private:
|
||||
CreatureConfiguration _character;
|
||||
CharacterGeneration *_charGen { nullptr };
|
||||
std::vector<Portrait> _portraits;
|
||||
int _currentPortrait { 0 };
|
||||
std::function<void(const CreatureConfiguration &)> _onPortraitSelected;
|
||||
std::function<void()> _onCancel;
|
||||
|
||||
void setButtonColors(const std::string &tag);
|
||||
void loadCurrentPortrait();
|
||||
void onClick(const std::string &control) override;
|
||||
|
||||
void loadCurrentPortrait();
|
||||
void setButtonColors(const std::string &tag);
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "../colors.h"
|
||||
|
||||
#include "chargen.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::gui;
|
||||
|
@ -31,7 +33,10 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
QuickCharacterGeneration::QuickCharacterGeneration(GameVersion version, const GraphicsOptions &opts) : GUI(version, opts) {
|
||||
QuickCharacterGeneration::QuickCharacterGeneration(CharacterGeneration *charGen, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_charGen(charGen) {
|
||||
|
||||
_resRef = getResRef("quickpnl");
|
||||
|
||||
if (_version == GameVersion::TheSithLords) {
|
||||
|
@ -42,10 +47,20 @@ QuickCharacterGeneration::QuickCharacterGeneration(GameVersion version, const Gr
|
|||
|
||||
void QuickCharacterGeneration::load() {
|
||||
GUI::load();
|
||||
setStep(0);
|
||||
doSetStep(0);
|
||||
|
||||
if (_version == GameVersion::KotOR) {
|
||||
configureControl("LBL_DECORATION", [](Control &ctrl) { ctrl.setDiscardColor(glm::vec3(0.0f, 0.0f, 0.082353f)); });
|
||||
}
|
||||
}
|
||||
|
||||
void QuickCharacterGeneration::setStep(int step) {
|
||||
if (_step != step) {
|
||||
doSetStep(step);
|
||||
}
|
||||
}
|
||||
|
||||
void QuickCharacterGeneration::doSetStep(int step) {
|
||||
_step = step;
|
||||
|
||||
setControlFocusable("LBL_1", false);
|
||||
|
@ -84,36 +99,34 @@ void QuickCharacterGeneration::setStep(int step) {
|
|||
}
|
||||
|
||||
void QuickCharacterGeneration::onClick(const string &control) {
|
||||
resetFocus();
|
||||
|
||||
if (control == "BTN_CANCEL") {
|
||||
setStep(0);
|
||||
_charGen->openQuickOrCustom();
|
||||
|
||||
if (_onCancel) {
|
||||
_onCancel();
|
||||
}
|
||||
} else if (control == "BTN_BACK") {
|
||||
if (_step == 0) {
|
||||
if (_onCancel) {
|
||||
_onCancel();
|
||||
}
|
||||
_charGen->openQuickOrCustom();
|
||||
} else {
|
||||
setStep(_step - 1);
|
||||
}
|
||||
} else if (boost::starts_with(control, "BTN_STEPNAME")) {
|
||||
int step = control[12] - '0';
|
||||
if (_onStepSelected) {
|
||||
_onStepSelected(step);
|
||||
switch (step) {
|
||||
case 1:
|
||||
_charGen->openPortraitSelection();
|
||||
break;
|
||||
case 2:
|
||||
_charGen->openNameEntry();
|
||||
break;
|
||||
default:
|
||||
_charGen->finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QuickCharacterGeneration::setOnStepSelected(const function<void(int)> &fn) {
|
||||
_onStepSelected = fn;
|
||||
}
|
||||
|
||||
void QuickCharacterGeneration::setOnCancel(const function<void()> &fn) {
|
||||
_onCancel = fn;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -23,24 +23,23 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class CharacterGeneration;
|
||||
|
||||
class QuickCharacterGeneration : public gui::GUI {
|
||||
public:
|
||||
QuickCharacterGeneration(resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
QuickCharacterGeneration(CharacterGeneration *charGen, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
|
||||
void setStep(int step);
|
||||
|
||||
void setOnStepSelected(const std::function<void(int)> &fn);
|
||||
void setOnCancel(const std::function<void()> &fn);
|
||||
|
||||
private:
|
||||
CharacterGeneration *_charGen { nullptr };
|
||||
int _step { 0 };
|
||||
|
||||
std::function<void(int)> _onStepSelected;
|
||||
std::function<void()> _onCancel;
|
||||
|
||||
void onClick(const std::string &control) override;
|
||||
|
||||
void doSetStep(int step);
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "../colors.h"
|
||||
|
||||
#include "chargen.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::gui;
|
||||
|
@ -29,7 +31,10 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
QuickOrCustom::QuickOrCustom(GameVersion version, const GraphicsOptions &opts) : GUI(version, opts) {
|
||||
QuickOrCustom::QuickOrCustom(CharacterGeneration *charGen, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_charGen(charGen) {
|
||||
|
||||
_resRef = getResRef("qorcpnl");
|
||||
|
||||
if (version == GameVersion::TheSithLords) {
|
||||
|
@ -49,25 +54,16 @@ void QuickOrCustom::load() {
|
|||
}
|
||||
|
||||
void QuickOrCustom::onClick(const string &control) {
|
||||
resetFocus();
|
||||
|
||||
if (control == "QUICK_CHAR_BTN") {
|
||||
if (_onQuickChar) {
|
||||
_onQuickChar();
|
||||
}
|
||||
_charGen->setQuickStep(0);
|
||||
_charGen->openQuick();
|
||||
} else if (control == "BTN_BACK") {
|
||||
if (_onBack) {
|
||||
_onBack();
|
||||
}
|
||||
_charGen->openClassSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void QuickOrCustom::setOnQuickCharacter(const function<void()> &fn) {
|
||||
_onQuickChar = fn;
|
||||
}
|
||||
|
||||
void QuickOrCustom::setOnBack(const function<void()> &fn) {
|
||||
_onBack = fn;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -23,18 +23,16 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class CharacterGeneration;
|
||||
|
||||
class QuickOrCustom : public gui::GUI {
|
||||
public:
|
||||
QuickOrCustom(resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
QuickOrCustom(CharacterGeneration *charGen, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
|
||||
void setOnQuickCharacter(const std::function<void()> &fn);
|
||||
void setOnBack(const std::function<void()> &fn);
|
||||
|
||||
private:
|
||||
std::function<void()> _onQuickChar;
|
||||
std::function<void()> _onBack;
|
||||
CharacterGeneration *_charGen { nullptr };
|
||||
|
||||
void onClick(const std::string &control) override;
|
||||
};
|
||||
|
|
|
@ -53,8 +53,9 @@ enum EndEntryFlags {
|
|||
kEndEntryOnAudioStop = 2
|
||||
};
|
||||
|
||||
Dialog::Dialog(GameVersion version, Game *game, const GraphicsOptions &opts) :
|
||||
GUI(version, opts), _game(game) {
|
||||
Dialog::Dialog(Game *game, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_game(game) {
|
||||
|
||||
_resRef = getResRef("dialog");
|
||||
_scaling = ScalingMode::Stretch;
|
||||
|
@ -119,18 +120,13 @@ void Dialog::configureReplies() {
|
|||
}
|
||||
|
||||
void Dialog::onReplyClicked(int index) {
|
||||
if (!_pickReplyEnabled) return;
|
||||
|
||||
if (_onReplyPicked) {
|
||||
_onReplyPicked(index);
|
||||
}
|
||||
pickReply(index);
|
||||
}
|
||||
|
||||
void Dialog::startDialog(SpatialObject &owner, const string &resRef) {
|
||||
shared_ptr<GffStruct> dlg(Resources.findGFF(resRef, ResourceType::Conversation));
|
||||
if (!dlg) {
|
||||
if (_onDialogFinished) _onDialogFinished();
|
||||
_game->openInGame();
|
||||
return;
|
||||
}
|
||||
_owner = &owner;
|
||||
|
@ -164,7 +160,7 @@ void Dialog::loadStartEntry() {
|
|||
}
|
||||
}
|
||||
if (entryIdx == -1) {
|
||||
if (_onDialogFinished) _onDialogFinished();
|
||||
_game->openInGame();
|
||||
return;
|
||||
}
|
||||
_currentEntry.reset(new DlgFile::EntryReply(_dialog->getEntry(entryIdx)));
|
||||
|
@ -234,9 +230,7 @@ void Dialog::finish() {
|
|||
if (_currentSpeaker) {
|
||||
static_cast<Creature &>(*_currentSpeaker).setTalking(false);
|
||||
}
|
||||
if (_onDialogFinished) {
|
||||
_onDialogFinished();
|
||||
}
|
||||
_game->openInGame();
|
||||
}
|
||||
|
||||
void Dialog::loadCurrentSpeaker() {
|
||||
|
@ -459,18 +453,6 @@ Camera &Dialog::camera() const {
|
|||
return cameraModel.empty() ? area->dialogCamera() : static_cast<Camera &>(area->animatedCamera());
|
||||
}
|
||||
|
||||
void Dialog::setPickReplyEnabled(bool enabled) {
|
||||
_pickReplyEnabled = enabled;
|
||||
}
|
||||
|
||||
void Dialog::setOnReplyPicked(const function<void(uint32_t)> &fn) {
|
||||
_onReplyPicked = fn;
|
||||
}
|
||||
|
||||
void Dialog::setOnDialogFinished(const function<void()> &fn) {
|
||||
_onDialogFinished = fn;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -33,7 +33,7 @@ class Game;
|
|||
|
||||
class Dialog : public gui::GUI {
|
||||
public:
|
||||
Dialog(resource::GameVersion version, Game *game, const render::GraphicsOptions &opts);
|
||||
Dialog(Game *game, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
void startDialog(SpatialObject &owner, const std::string &resRef);
|
||||
|
@ -44,10 +44,6 @@ public:
|
|||
|
||||
Camera &camera() const;
|
||||
|
||||
void setPickReplyEnabled(bool enabled);
|
||||
void setOnReplyPicked(const std::function<void(uint32_t)> &fn);
|
||||
void setOnDialogFinished(const std::function<void()> &fn);
|
||||
|
||||
private:
|
||||
Game *_game { nullptr };
|
||||
SpatialObject *_owner { nullptr };
|
||||
|
@ -55,19 +51,11 @@ private:
|
|||
std::shared_ptr<resource::DlgFile::EntryReply> _currentEntry;
|
||||
std::shared_ptr<audio::SoundInstance> _currentVoice;
|
||||
SpatialObject *_currentSpeaker { nullptr };
|
||||
bool _pickReplyEnabled { true };
|
||||
int _autoPickReplyIdx { -1 };
|
||||
int _endEntryFlags { 0 };
|
||||
uint32_t _endEntryTimestamp { 0 };
|
||||
bool _entryEnded { false };
|
||||
|
||||
// Callbacks
|
||||
|
||||
std::function<void(uint32_t)> _onReplyPicked;
|
||||
std::function<void()> _onDialogFinished;
|
||||
|
||||
// END Callbacks
|
||||
|
||||
bool handleKeyDown(SDL_Scancode key) override;
|
||||
bool handleKeyUp(SDL_Scancode key) override;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "../../system/gui/control/listbox.h"
|
||||
#include "../../system/resource/resources.h"
|
||||
|
||||
#include "../game.h"
|
||||
#include "../object/creature.h"
|
||||
#include "../object/item.h"
|
||||
|
||||
|
@ -55,7 +56,10 @@ static unordered_map<Equipment::Slot, string> g_slotNames = {
|
|||
{ Equipment::Slot::WeapR2, "WEAP_R2"}
|
||||
};
|
||||
|
||||
Equipment::Equipment(GameVersion version, const GraphicsOptions &opts) : GUI(version, opts) {
|
||||
Equipment::Equipment(Game *game, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_game(game) {
|
||||
|
||||
_resRef = getResRef("equip");
|
||||
_backgroundType = BackgroundType::Menu;
|
||||
|
||||
|
@ -129,10 +133,6 @@ void Equipment::open(SpatialObject *owner) {
|
|||
selectSlot(Slot::None);
|
||||
}
|
||||
|
||||
void Equipment::setOnClose(const function<void()> &fn) {
|
||||
_onClose = fn;
|
||||
}
|
||||
|
||||
void Equipment::preloadControl(Control &control) {
|
||||
if (control.tag() == "LB_ITEMS") {
|
||||
static_cast<ListBox &>(control).setProtoItemType(ControlType::ImageButton);
|
||||
|
@ -142,9 +142,7 @@ void Equipment::preloadControl(Control &control) {
|
|||
void Equipment::onClick(const string &control) {
|
||||
if (control == "BTN_EQUIP" || control == "BTN_BACK") {
|
||||
if (_selectedSlot == Slot::None) {
|
||||
if (_onClose) {
|
||||
_onClose();
|
||||
}
|
||||
_game->openInGame();
|
||||
} else {
|
||||
selectSlot(Slot::None);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class Game;
|
||||
|
||||
class Equipment : public gui::GUI {
|
||||
public:
|
||||
enum class Slot {
|
||||
|
@ -43,18 +45,16 @@ public:
|
|||
WeapR2
|
||||
};
|
||||
|
||||
Equipment(resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
Equipment(Game *game, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
void open(SpatialObject *owner);
|
||||
|
||||
void setOnClose(const std::function<void()> &fn);
|
||||
|
||||
private:
|
||||
Game *_game { nullptr };
|
||||
SpatialObject *_owner { nullptr };
|
||||
Slot _selectedSlot { Slot::None };
|
||||
int _selectedItemIdx { -1 };
|
||||
std::function<void()> _onClose;
|
||||
|
||||
static resource::InventorySlot getInventorySlot(Slot slot);
|
||||
static std::shared_ptr<render::Texture> getEmptySlotIcon(Slot slot);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "../../system/log.h"
|
||||
#include "../../system/gui/control/label.h"
|
||||
|
||||
#include "../game.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::gui;
|
||||
|
@ -30,8 +32,11 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
HUD::HUD(GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts), _debug(opts), _select(opts) {
|
||||
HUD::HUD(Game *game, GameVersion version, const GraphicsOptions &opts) :
|
||||
GUI(version, opts),
|
||||
_game(game),
|
||||
_debug(opts),
|
||||
_select(opts) {
|
||||
|
||||
_resRef = getResRef("mipc28x6");
|
||||
_resolutionX = 800;
|
||||
|
@ -144,9 +149,8 @@ void HUD::render() const {
|
|||
|
||||
void HUD::onClick(const string &control) {
|
||||
if (control == "BTN_EQU") {
|
||||
if (_onEquipmentClick) {
|
||||
_onEquipmentClick();
|
||||
}
|
||||
resetFocus();
|
||||
_game->openEquipment();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,10 +191,6 @@ void HUD::setContext(const GuiContext &ctx) {
|
|||
_debug.setContext(ctx.debug);
|
||||
}
|
||||
|
||||
void HUD::setOnEquipmentClick(const function<void()> &fn) {
|
||||
_onEquipmentClick = fn;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -29,23 +29,23 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class Game;
|
||||
|
||||
class HUD : public gui::GUI {
|
||||
public:
|
||||
HUD(resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
HUD(Game *game, resource::GameVersion version, const render::GraphicsOptions &opts);
|
||||
|
||||
void load() override;
|
||||
|
||||
void render() const override;
|
||||
|
||||
void setContext(const GuiContext &ctx);
|
||||
void setOnEquipmentClick(const std::function<void()> &fn);
|
||||
|
||||
private:
|
||||
Game *_game { nullptr };
|
||||
DebugOverlay _debug;
|
||||
SelectionOverlay _select;
|
||||
|
||||
std::function<void()> _onEquipmentClick;
|
||||
|
||||
void onClick(const std::string &control) override;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue