MM: MM1: Adding a character select dialog

This commit is contained in:
Paul Gilbert 2023-02-21 22:29:35 -08:00
parent 914dbbad05
commit 9bfdc779f1
11 changed files with 196 additions and 7 deletions

View File

@ -479,6 +479,8 @@ enhdialogs:
exchange: "\x01""37Exch"
conditions:
good: "Good"
character_select:
title: "Select target"
location:
store: "store"
options: "options"

View File

@ -165,5 +165,14 @@ void Party::rearrange(const Common::Array<Character *> &party) {
}
}
int Party::indexOf(const Character *c) {
for (uint i = 0; i < size(); ++i) {
if (&(*this)[i] == c)
return i;
}
return -1;
}
} // namespace MM1
} // namespace MM

View File

@ -97,6 +97,11 @@ struct Party : public Common::Array<Character> {
* Synchronizes the party to/from savegames
*/
void synchronize(Common::Serializer &s);
/**
* Return the index of a given character
*/
int indexOf(const Character *c);
};
} // namespace MM1

View File

@ -0,0 +1,75 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "mm/mm1/views_enh/character_select.h"
#include "mm/mm1/events.h"
#include "mm/mm1/globals.h"
namespace MM {
namespace MM1 {
namespace ViewsEnh {
CharacterSelect::CharacterSelect() : PartyView("CharacterSelect") {
_bounds = Common::Rect(225, 18 * 8, 320, 200);
}
bool CharacterSelect::msgFocus(const FocusMessage &msg) {
_currCharacter = g_globals->_currCharacter;
g_globals->_currCharacter = nullptr;
return PartyView::msgFocus(msg);
}
void CharacterSelect::draw() {
ScrollView::draw();
_fontReduced = true;
writeString(STRING["enhdialogs.character_select.title"]);
}
bool CharacterSelect::msgAction(const ActionMessage &msg) {
if (msg._action == KEYBIND_ESCAPE) {
close();
g_events->send(g_events->focusedView()->getName(),
GameMessage("CHAR_SELECTED", -1));
return true;
} else {
return PartyView::msgAction(msg);
}
}
bool CharacterSelect::msgGame(const GameMessage &msg) {
if (msg._name == "UPDATE") {
close();
int charNum = g_globals->_party.indexOf(g_globals->_currCharacter);
g_globals->_currCharacter = _currCharacter;
g_events->send(g_events->focusedView()->getName(),
GameMessage("CHAR_SELECTED", charNum));
return true;
}
return true;
}
} // namespace ViewsEnh
} // namespace MM1
} // namespace MM

View File

@ -0,0 +1,60 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef MM1_VIEWS_ENH_CHARACTER_SELECT_H
#define MM1_VIEWS_ENH_CHARACTER_SELECT_H
#include "mm/mm1/messages.h"
#include "mm/mm1/data/character.h"
#include "mm/mm1/views_enh/party_view.h"
namespace MM {
namespace MM1 {
namespace ViewsEnh {
/**
* Dialog for choosing a character target
*/
class CharacterSelect : public PartyView {
private:
Character *_currCharacter = nullptr;
protected:
/**
* Return true if a character should be selected by default
*/
virtual bool selectCharByDefault() const {
return false;
}
public:
CharacterSelect();
virtual ~CharacterSelect() {}
bool msgFocus(const FocusMessage &msg) override;
void draw() override;
bool msgAction(const ActionMessage &msg) override;
bool msgGame(const GameMessage &msg) override;
};
} // namespace ViewsEnh
} // namespace MM1
} // namespace MM
#endif

View File

@ -28,6 +28,7 @@
#include "mm/mm1/views/protect.h"
#include "mm/mm1/views/title.h"
#include "mm/mm1/views_enh/character_info.h"
#include "mm/mm1/views_enh/character_select.h"
#include "mm/mm1/views_enh/game.h"
#include "mm/mm1/views_enh/main_menu.h"
#include "mm/mm1/views_enh/map_popup.h"
@ -53,13 +54,14 @@ private:
Views::Protect _protect;
Views::Title _title;
// Views::ViewCharacter _viewCharacter;
ViewsEnh::Locations::Market _market;
ViewsEnh::Locations::Temple _temple;
ViewsEnh::Spells::CastSpell _castSpell;
ViewsEnh::Spells::Spellbook _spellbook;
ViewsEnh::CharacterSelect _characterSelect;
ViewsEnh::MainMenu _mainMenu;
ViewsEnh::MapPopup _mapPopup;
ViewsEnh::QuickRef _quickRef;
ViewsEnh::Locations::Market _market;
ViewsEnh::Locations::Temple _temple;
public:
Dialogs() {}
};

View File

@ -31,7 +31,7 @@ namespace ViewsEnh {
bool PartyView::msgFocus(const FocusMessage &msg) {
// Turn on highlight for selected character
if (!g_globals->_currCharacter)
if (!g_globals->_currCharacter && selectCharByDefault())
g_globals->_currCharacter = &g_globals->_party[0];
g_events->send("GameParty", GameMessage("CHAR_HIGHLIGHT", (int)true));

View File

@ -36,6 +36,13 @@ protected:
virtual bool canSwitchChar() const {
return true;
}
/**
* Return true if a character should be selected by default
*/
virtual bool selectCharByDefault() const {
return true;
}
public:
PartyView(const Common::String &name) : ScrollView(name) {}
PartyView(const Common::String &name, UIElement *owner) :

View File

@ -80,13 +80,20 @@ void CastSpell::draw() {
bool CastSpell::msgKeypress(const KeypressMessage &msg) {
if (msg.keycode == Common::KEYCODE_c) {
close();
// Cast a spell
const Character &c = *g_globals->_currCharacter;
if (c._nonCombatSpell != -1) {
// TODO: Cast spell here
if (!canCast()) {
close();
spellError();
} else if (hasCharTarget()) {
addView("CharacterSelect");
} else {
close();
castSpell();
}
return true;
} else if (msg.keycode == Common::KEYCODE_n) {
// Select a new spell
addView("Spellbook");
@ -113,6 +120,9 @@ bool CastSpell::msgGame(const GameMessage &msg) {
updateSelectedSpell();
draw();
return true;
} else if (msg._name == "CHAR_SELECTED" && msg._value != -1) {
close();
castSpell(&g_globals->_party[msg._value]);
}
return true;
@ -133,6 +143,14 @@ void CastSpell::updateSelectedSpell() {
}
}
void CastSpell::castSpell(Character *target) {
warning("TODO: cast spell");
}
void CastSpell::spellError() {
warning("TODO: spell error");
}
} // namespace Spells
} // namespace ViewsEnh
} // namespace MM1

View File

@ -43,6 +43,16 @@ private:
*/
void updateSelectedSpell();
/**
* Casts the selected spell
*/
void castSpell(Character *target = nullptr);
/**
* Handles spell errors
*/
void spellError();
public:
CastSpell();
virtual ~CastSpell() {}

View File

@ -123,6 +123,7 @@ MODULE_OBJS += \
mm1/views_enh/spells/spellbook.o \
mm1/views_enh/button_container.o \
mm1/views_enh/character_info.o \
mm1/views_enh/character_select.o \
mm1/views_enh/dialogs.o \
mm1/views_enh/game.o \
mm1/views_enh/game_commands.o \