XEEN: Some refactoring needed for resources the party dialog will need

This commit is contained in:
Paul Gilbert 2015-02-09 20:57:19 -05:00
parent ccb224d89a
commit 62eb39515b
14 changed files with 242 additions and 143 deletions

View File

@ -0,0 +1,153 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#include "xeen/dialogs_party.h"
#include "xeen/character.h"
#include "xeen/events.h"
#include "xeen/party.h"
#include "xeen/xeen.h"
namespace Xeen {
void PartyDialog::show(XeenEngine *vm) {
PartyDialog *dlg = new PartyDialog(vm);
dlg->execute();
delete dlg;
}
void PartyDialog::execute() {
EventsManager &events = *_vm->_events;
Map &map = *_vm->_map;
Screen &screen = *_vm->_screen;
loadButtons();
setupBackground();
_vm->_mode = MODE_1;
Common::Array<int> xeenSideChars;
// Build up a list of characters on the same Xeen side being loaded
for (int i = 0; i < XEEN_TOTAL_CHARACTERS; ++i) {
Character &player = _vm->_roster[i];
if (player._name.empty() || player._xeenSide != (map._loadDarkSide ? 1 : 0))
continue;
xeenSideChars.push_back(i);
}
Window &w = screen._windows[11];
w.open();
setupFaces(0, xeenSideChars, false);
w.writeString(_displayText);
w.drawList(&_faceDrawStructs[0], 4);
_iconSprites.draw(w, 0, Common::Point(16, 100));
_iconSprites.draw(w, 2, Common::Point(52, 100));
_iconSprites.draw(w, 4, Common::Point(87, 100));
_iconSprites.draw(w, 6, Common::Point(122, 100));
_iconSprites.draw(w, 8, Common::Point(157, 100));
_iconSprites.draw(w, 10, Common::Point(192, 100));
screen.loadPalette("mm4.pal");
// TODO
}
void PartyDialog::loadButtons() {
_iconSprites.load("inn.icn");
addButton(Common::Rect(16, 100, 40, 120), Common::KEYCODE_UP, &_iconSprites);
addButton(Common::Rect(52, 100, 76, 120), Common::KEYCODE_DOWN, &_iconSprites);
addButton(Common::Rect(87, 100, 111, 120), Common::KEYCODE_d, &_iconSprites);
addButton(Common::Rect(122, 100, 146, 120), Common::KEYCODE_r, &_iconSprites);
addButton(Common::Rect(157, 100, 181, 120), Common::KEYCODE_c, &_iconSprites);
addButton(Common::Rect(192, 100, 116, 120), Common::KEYCODE_x, &_iconSprites);
addButton(Common::Rect(0, 0, 0, 0), Common::KEYCODE_ESCAPE, &_iconSprites, false);
addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1, &_iconSprites, false);
addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2, &_iconSprites, false);
addButton(Common::Rect(59, 59, 91, 91), Common::KEYCODE_3, &_iconSprites, false);
addButton(Common::Rect(117, 59, 151, 91), Common::KEYCODE_4, &_iconSprites, false);
}
void PartyDialog::initDrawStructs() {
_faceDrawStructs[0] = DrawStruct(0, 0, 0);
_faceDrawStructs[1] = DrawStruct(0, 101, 0);
_faceDrawStructs[2] = DrawStruct(0, 0, 43);
_faceDrawStructs[3] = DrawStruct(0, 101, 43);
}
void PartyDialog::setupBackground() {
_vm->_screen->loadBackground("back.raw");
_vm->_interface->assembleBorder();
}
/**
* Sets up the faces for display in the party dialog
*/
void PartyDialog::setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag) {
Resources &res = *_vm->_resources;
Common::String charNames[4];
Common::String charRaces[4];
Common::String charSex[4];
Common::String charClasses[4];
int posIndex;
int charId;
for (posIndex = 0; posIndex < 4; ++posIndex) {
charId = xeenSideChars[charIndex];
bool isInParty = _vm->_party->isInParty(charId);
if (charId == 0xff) {
while ((int)_buttons.size() >(7 + posIndex))
_buttons.remove_at(_buttons.size() - 1);
break;
}
Common::Rect &b = _buttons[7 + posIndex]._bounds;
b.moveTo((posIndex & 1) ? 117 : 16, b.top);
Character &ps = _vm->_roster[xeenSideChars[charIndex + posIndex]];
charNames[posIndex] = isInParty ? IN_PARTY : ps._name;
charRaces[posIndex] = RACE_NAMES[ps._race];
charSex[posIndex] = SEX_NAMES[ps._sex];
charClasses[posIndex] = CLASS_NAMES[ps._class];
}
charIconsPrint(updateFlag);
// Set up the sprite set to use for each face
charId = xeenSideChars[charIndex];
_faceDrawStructs[0]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &res._charFaces[charId];
charId = xeenSideChars[charIndex + 1];
_faceDrawStructs[1]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &res._charFaces[charId];
charId = xeenSideChars[charIndex + 2];
_faceDrawStructs[2]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &res._charFaces[charId];
charId = xeenSideChars[charIndex + 3];
_faceDrawStructs[3]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &res._charFaces[charId];
_displayText = Common::String::format(PARTY_DETAILS,
charNames[0].c_str(), charRaces[0].c_str(), charSex[0].c_str(), charClasses[0].c_str(),
charNames[1].c_str(), charRaces[1].c_str(), charSex[1].c_str(), charClasses[1].c_str(),
charNames[2].c_str(), charRaces[2].c_str(), charSex[2].c_str(), charClasses[2].c_str(),
charNames[3].c_str(), charRaces[3].c_str(), charSex[3].c_str(), charClasses[3].c_str()
);
}
} // End of namespace Xeen

View File

@ -0,0 +1,58 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef XEEN_DIALOGS_PARTY_H
#define XEEN_DIALOGS_PARTY_H
#include "xeen/dialogs.h"
#include "xeen/screen.h"
#include "xeen/sprites.h"
namespace Xeen {
class PartyDialog : public ButtonContainer {
private:
XeenEngine *_vm;
SpriteResource _iconSprites;
DrawStruct _faceDrawStructs[4];
Common::String _displayText;
PartyDialog(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
void execute();
void loadButtons();
void initDrawStructs();
void setupBackground();
void charIconsPrint(bool updateFlag);
void setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag);
public:
static void show(XeenEngine *vm);
};
} // End of namespace Xeen
#endif /* XEEN_DIALOGS_PARTY_H */

View File

@ -168,7 +168,7 @@ bool EventsManager::wait(uint numFrames, bool interruptable) {
return false;
}
void EventsManager::ipause(int amount) {
void EventsManager::ipause(uint amount) {
updateGameCounter();
do {
_vm->_interface->draw3d(true);

View File

@ -91,7 +91,7 @@ public:
bool wait(uint numFrames, bool interruptable = false);
void ipause(int amount);
void ipause(uint amount);
};
class GameEvent {

View File

@ -46,11 +46,6 @@ Interface::Interface(XeenEngine *vm) : ButtonContainer(), InterfaceMap(vm), _vm(
void Interface::initDrawStructs() {
_faceDrawStructs[0] = DrawStruct(0, 0, 0);
_faceDrawStructs[1] = DrawStruct(0, 101, 0);
_faceDrawStructs[2] = DrawStruct(0, 0, 43);
_faceDrawStructs[3] = DrawStruct(0, 101, 43);
_mainList[0] = DrawStruct(7, 232, 74);
_mainList[1] = DrawStruct(0, 235, 75);
_mainList[2] = DrawStruct(2, 260, 75);
@ -85,70 +80,8 @@ void Interface::setup() {
}
void Interface::manageCharacters(bool soundPlayed) {
EventsManager &events = *_vm->_events;
Map &map = *_vm->_map;
Screen &screen = *_vm->_screen;
bool flag = false;
start:
if (_vm->_party->_mazeId != 0) {
_vm->_mode = MODE_0;
_buttonsLoaded = true;
} else {
if (!soundPlayed) {
warning("TODO: loadSound?");
}
if (!_partyFaces[0]) {
// Xeen only uses 24 of possible 30 character slots
loadCharIcons();
for (int i = 0; i < _vm->_party->_partyCount; ++i)
_partyFaces[i] = &_charFaces[_vm->_party->_partyMembers[i]];
}
_vm->_mode = MODE_1;
Common::Array<int> xeenSideChars;
// Build up a list of characters on the same Xeen side being loaded
for (int i = 0; i < XEEN_TOTAL_CHARACTERS; ++i) {
Character &player = _vm->_roster[i];
if (player._name.empty() || player._xeenSide != (map._loadDarkSide ? 1 : 0))
continue;
xeenSideChars.push_back(i);
}
// Add in buttons for the UI
_interfaceText = "";
_buttonsLoaded = true;
addButton(Common::Rect(16, 100, 40, 120), 242, &_uiSprites, true);
addButton(Common::Rect(52, 100, 76, 120), 243, &_uiSprites, true);
addButton(Common::Rect(87, 100, 111, 120), 68, &_uiSprites, true);
addButton(Common::Rect(122, 100, 146, 120), 82, &_uiSprites, true);
addButton(Common::Rect(157, 100, 181, 120), 67, &_uiSprites, true);
addButton(Common::Rect(192, 100, 216, 120), 88, &_uiSprites, true);
addButton(Common::Rect(), 27, &_uiSprites, false);
addButton(Common::Rect(16, 16, 48, 48), 49, &_uiSprites, false);
addButton(Common::Rect(117, 16, 139, 48), 50, &_uiSprites, false);
addButton(Common::Rect(16, 59, 48, 81), 51, &_uiSprites, false);
addButton(Common::Rect(117, 59, 149, 81), 52, &_uiSprites, false);
setupBackground();
Window &w = screen._windows[11];
w.open();
setupFaces(0, xeenSideChars, false);
w.writeString(_interfaceText);
w.drawList(&_faceDrawStructs[0], 4);
_uiSprites.draw(w, 0, Common::Point(16, 100));
_uiSprites.draw(w, 2, Common::Point(52, 100));
_uiSprites.draw(w, 4, Common::Point(87, 100));
_uiSprites.draw(w, 6, Common::Point(122, 100));
_uiSprites.draw(w, 8, Common::Point(157, 100));
_uiSprites.draw(w, 10, Common::Point(192, 100));
screen.loadPalette("mm4.pal");
/*
if (flag) {
screen._windows[0].update();
@ -264,76 +197,23 @@ start:
for (int i = 0; i < TOTAL_CHARACTERS; ++i)
_charFaces[i].clear();
*/
}
void Interface::loadCharIcons() {
for (int i = 0; i < XEEN_TOTAL_CHARACTERS; ++i) {
// Load new character resource
Common::String name = Common::String::format("char%02d.fac", i + 1);
_charFaces[i].load(name);
}
_dseFace.load("dse.fac");
}
void Interface::loadPartyIcons() {
for (int i = 0; i < _vm->_party->_partyCount; ++i)
_partyFaces[i] = &_charFaces[_vm->_party->_partyMembers[i]];
}
Party &party = *_vm->_party;
Resources &res = *_vm->_resources;
void Interface::setupBackground() {
_vm->_screen->loadBackground("back.raw");
assembleBorder();
}
void Interface::setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag) {
Common::String playerNames[4];
Common::String playerRaces[4];
Common::String playerSex[4];
Common::String playerClass[4];
int posIndex;
int charId;
for (posIndex = 0; posIndex < 4; ++posIndex) {
charId = xeenSideChars[charIndex];
bool isInParty = _vm->_party->isInParty(charId);
if (charId == 0xff) {
while ((int)_buttons.size() > (7 + posIndex))
_buttons.remove_at(_buttons.size() - 1);
break;
}
Common::Rect &b = _buttons[7 + posIndex]._bounds;
b.moveTo((posIndex & 1) ? 117 : 16, b.top);
Character &ps = _vm->_roster[xeenSideChars[charIndex + posIndex]];
playerNames[posIndex] = isInParty ? IN_PARTY : ps._name;
playerRaces[posIndex] = RACE_NAMES[ps._race];
playerSex[posIndex] = SEX_NAMES[ps._sex];
playerClass[posIndex] = CLASS_NAMES[ps._class];
}
charIconsPrint(updateFlag);
// Set up the sprite set to use for each face
charId = xeenSideChars[charIndex];
_faceDrawStructs[0]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
charId = xeenSideChars[charIndex + 1];
_faceDrawStructs[1]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
charId = xeenSideChars[charIndex + 2];
_faceDrawStructs[2]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
charId = xeenSideChars[charIndex + 3];
_faceDrawStructs[3]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
_interfaceText = Common::String::format(PARTY_DETAILS,
playerNames[0].c_str(), playerRaces[0].c_str(), playerSex[0].c_str(), playerClass[0].c_str(),
playerNames[1].c_str(), playerRaces[1].c_str(), playerSex[1].c_str(), playerClass[1].c_str(),
playerNames[2].c_str(), playerRaces[2].c_str(), playerSex[2].c_str(), playerClass[2].c_str(),
playerNames[3].c_str(), playerRaces[3].c_str(), playerSex[3].c_str(), playerClass[3].c_str()
);
for (int i = 0; i < party._partyCount; ++i)
_partyFaces[i] = &res._charFaces[_vm->_party->_partyMembers[i]];
}
void Interface::charIconsPrint(bool updateFlag) {
Resources &res = *_vm->_resources;
Screen &screen = *_vm->_screen;
bool stateFlag = _vm->_mode == MODE_COMBAT;
_restoreSprites.draw(screen, 0, Common::Point(8, 149));
@ -346,8 +226,7 @@ void Interface::charIconsPrint(bool updateFlag) {
Condition charCondition = ps.worstCondition();
int charFrame = FACE_CONDITION_FRAMES[charCondition];
SpriteResource *sprites = (charFrame > 4 && !_charFaces[0].empty()) ?
&_dseFace : _partyFaces[charIndex];
SpriteResource *sprites = (charFrame > 4) ? &_dseFace : _partyFaces[charIndex];
if (charFrame > 4)
charFrame -= 5;

View File

@ -44,8 +44,6 @@ private:
SpriteResource _hpSprites;
SpriteResource _uiSprites;
SpriteResource _iconSprites;
SpriteResource _charFaces[TOTAL_CHARACTERS];
DrawStruct _faceDrawStructs[4];
DrawStruct _mainList[16];
int _combatCharIds[8];
@ -59,8 +57,6 @@ private:
void setupBackground();
void setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag);
void drawViewBackground(int bgType);
void moveCharacterToRoster();

View File

@ -19,6 +19,7 @@ MODULE_OBJS := \
dialogs_info.o \
dialogs_input.o \
dialogs_items.o \
dialogs_party.o \
dialogs_query.o \
dialogs_quests.o \
dialogs_quick_ref.o \

View File

@ -31,6 +31,12 @@ Resources::Resources() {
while (f.pos() < f.size())
_maeNames.push_back(f.readString());
f.close();
for (int i = 0; i < XEEN_TOTAL_CHARACTERS; ++i) {
// Load new character resource
Common::String name = Common::String::format("char%02d.fac", i + 1);
_charFaces[i].load(name);
}
}
/*------------------------------------------------------------------------*/

View File

@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/str-array.h"
#include "gui/debugger.h"
#include "xeen/party.h"
#include "xeen/spells.h"
namespace Xeen {
@ -34,6 +35,7 @@ class Resources {
public:
// Magic and equipment names
Common::StringArray _maeNames;
SpriteResource _charFaces[TOTAL_CHARACTERS];
public:
Resources();
};

View File

@ -107,7 +107,7 @@ Scripts::Scripts(XeenEngine *vm) : _vm(vm) {
_var50 = false;
}
bool Scripts::checkEvents() {
int Scripts::checkEvents() {
Combat &combat = *_vm->_combat;
EventsManager &events = *_vm->_events;
Interface &intf = *_vm->_interface;

View File

@ -233,7 +233,7 @@ public:
public:
Scripts(XeenEngine *vm);
bool checkEvents();
int checkEvents();
void giveTreasure();

View File

@ -630,6 +630,7 @@ Character *Town::doTavernOptions(Character *c) {
}
break;
case Common::KEYCODE_f: {
// Food
if (party._mazeId == (isDarkCc ? 29 : 28)) {
_v22 = party._partyCount * 15;
_v23 = 10;
@ -680,6 +681,7 @@ Character *Town::doTavernOptions(Character *c) {
}
case Common::KEYCODE_r: {
// Rumors
if (party._mazeId == (isDarkCc ? 29 : 28)) {
idx = 0;
} else if (party._mazeId == (isDarkCc ? 31 : 30)) {
@ -701,8 +703,7 @@ Character *Town::doTavernOptions(Character *c) {
}
case Common::KEYCODE_s: {
// Save game
// TODO: This needs to be fit in better with ScummVM framework
// Sign In
int idx = isDarkCc ? (party._mazeId - 29) >> 1 : party._mazeId - 28;
assert(idx >= 0);
party._mazePosition.x = TAVERN_EXIT_LIST[isDarkCc ? 1 : 0][_townActionId][idx][0];
@ -723,7 +724,7 @@ Character *Town::doTavernOptions(Character *c) {
party.addTime(1440);
party._mazeId = 0;
_vm->quitGame();
_vm->_quitMode = 2;
break;
}

View File

@ -51,6 +51,7 @@ XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc)
_spells = nullptr;
_town = nullptr;
_eventData = nullptr;
_quitMode = 0;
_dangerSenseAllowed = false;
_noDirectionSense = false;
_moveMonsters = false;
@ -289,6 +290,7 @@ void XeenEngine::playGame() {
*/
void XeenEngine::play() {
// TODO: Init variables
_quitMode = 0;
_interface->setup();
_screen->loadBackground("back.raw");
@ -331,8 +333,8 @@ void XeenEngine::gameLoop() {
while (!shouldQuit()) {
_map->cellFlagLookup(_party->_mazePosition);
if (_map->_currentIsEvent) {
_scripts->checkEvents();
if (shouldQuit())
_quitMode = _scripts->checkEvents();
if (shouldQuit() || _quitMode)
return;
}
_scripts->giveTreasure();

View File

@ -153,6 +153,7 @@ public:
GameEvent _gameEvent;
Common::SeekableReadStream *_eventData;
Roster _roster;
int _quitMode;
bool _dangerSenseAllowed;
bool _noDirectionSense;
bool _moveMonsters;