aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen
diff options
context:
space:
mode:
authorPaul Gilbert2015-02-07 18:02:03 -0500
committerPaul Gilbert2015-02-07 18:02:03 -0500
commit90db7872f14c67f990c74f6b2d971f479dc87941 (patch)
tree7f2b29f32c5c7ba69492241576a904249ba9f5ca /engines/xeen
parentb633704847f12b87b0d4287ef18282b7165a64d6 (diff)
downloadscummvm-rg350-90db7872f14c67f990c74f6b2d971f479dc87941.tar.gz
scummvm-rg350-90db7872f14c67f990c74f6b2d971f479dc87941.tar.bz2
scummvm-rg350-90db7872f14c67f990c74f6b2d971f479dc87941.zip
XEEN: Implement Quests dialog
Diffstat (limited to 'engines/xeen')
-rw-r--r--engines/xeen/dialogs_quests.cpp210
-rw-r--r--engines/xeen/dialogs_quests.h7
-rw-r--r--engines/xeen/interface.cpp6
-rw-r--r--engines/xeen/party.h4
-rw-r--r--engines/xeen/resources.cpp135
-rw-r--r--engines/xeen/resources.h12
6 files changed, 372 insertions, 2 deletions
diff --git a/engines/xeen/dialogs_quests.cpp b/engines/xeen/dialogs_quests.cpp
index 27657193b8..17255946bc 100644
--- a/engines/xeen/dialogs_quests.cpp
+++ b/engines/xeen/dialogs_quests.cpp
@@ -23,10 +23,13 @@
#include "common/scummsys.h"
#include "xeen/dialogs_quests.h"
#include "xeen/events.h"
+#include "xeen/party.h"
#include "xeen/xeen.h"
namespace Xeen {
+#define MAX_DIALOG_LINES 128
+
void Quests::show(XeenEngine *vm) {
Quests *dlg = new Quests(vm);
dlg->execute();
@@ -34,7 +37,212 @@ void Quests::show(XeenEngine *vm) {
}
void Quests::execute() {
- // TODO
+ EventsManager &events = *_vm->_events;
+ Party &party = *_vm->_party;
+ Screen &screen = *_vm->_screen;
+ bool isDarkCc = _vm->_files->_isDarkCc;
+ int count = 0;
+ bool headerShown = false;
+ int topRow = 0;
+
+ addButtons();
+ loadQuestNotes();
+
+ enum { QUEST_ITEMS, CURRENT_QUESTS, AUTO_NOTES } mode = QUEST_ITEMS;
+ bool windowFlag;
+ if (screen._windows[29]._enabled) {
+ windowFlag = false;
+ } else {
+ screen._windows[29].open();
+ screen._windows[30].open();
+ windowFlag = true;
+ }
+
+ screen._windows[29].writeString(QUESTS_DIALOG_TEXT);
+ drawButtons(&screen);
+
+ while (!_vm->shouldQuit()) {
+ Common::String lines[MAX_DIALOG_LINES];
+
+ switch (mode) {
+ case QUEST_ITEMS:
+ for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx)
+ lines[idx] = "\b \b*";
+
+ count = 0;
+ headerShown = false;
+ for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx) {
+ if (party._questItems[idx]) {
+ if (!count && !headerShown && idx < 35) {
+ lines[count++] = CLOUDS_OF_XEEN_LINE;
+ }
+ if (idx >= 35 && !headerShown) {
+ lines[count++] = DARKSIDE_OF_XEEN_LINE;
+ headerShown = true;
+ }
+
+ switch (idx) {
+ case 17:
+ case 26:
+ case 79:
+ case 80:
+ case 81:
+ case 82:
+ case 83:
+ case 84:
+ lines[count++] = Common::String::format("%d %s%c",
+ party._questItems[idx], QUEST_ITEM_NAMES[idx],
+ party._questItems[idx] == 1 ? ' ' : 's');
+ break;
+ default:
+ lines[count++] = QUEST_ITEM_NAMES[idx];
+ break;
+ }
+ }
+ }
+
+ if (count == 0) {
+ screen._windows[30].writeString(NO_QUEST_ITEMS);
+ } else {
+ screen._windows[30].writeString(Common::String::format(QUEST_ITEMS_DATA,
+ lines[topRow].c_str(), lines[topRow + 1].c_str(),
+ lines[topRow + 2].c_str(), lines[topRow + 3].c_str(),
+ lines[topRow + 4].c_str(), lines[topRow + 5].c_str(),
+ lines[topRow + 6].c_str(), lines[topRow + 7].c_str(),
+ lines[topRow + 8].c_str()
+ ));
+ }
+ break;
+
+ case CURRENT_QUESTS:
+ for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx)
+ lines[idx] = "";
+
+ count = 0;
+ headerShown = false;
+ for (int idx = 0; idx < TOTAL_QUEST_FLAGS; ++idx) {
+ if (party._quests[idx]) {
+ if (!count && !headerShown && idx < 29) {
+ lines[count++] = CLOUDS_OF_XEEN_LINE;
+ }
+ if (idx > 28 && !headerShown) {
+ lines[count++] = DARKSIDE_OF_XEEN_LINE;
+ headerShown = true;
+ }
+
+ lines[count++] = _questNotes[idx];
+ }
+ }
+
+ if (count == 0)
+ lines[1] = NO_CURRENT_QUESTS;
+
+ screen._windows[30].writeString(Common::String::format(CURRENT_QUESTS_DATA,
+ lines[topRow].c_str(), lines[topRow + 1].c_str(), lines[topRow + 2].c_str()));
+ break;
+
+ case AUTO_NOTES:
+ for (int idx = 0; idx < MAX_DIALOG_LINES; ++idx)
+ lines[idx] = "";
+
+ count = 0;
+ headerShown = false;
+ for (int idx = 0; idx < MAX_DIALOG_LINES; ++idx) {
+ if (party._worldFlags[idx]) {
+ if (!count && !headerShown && idx < 72) {
+ lines[count++] = CLOUDS_OF_XEEN_LINE;
+ }
+ if (idx >= 72 && !headerShown) {
+ lines[count++] = DARKSIDE_OF_XEEN_LINE;
+ headerShown = true;
+ }
+
+ lines[count++] = _questNotes[idx + 56];
+ }
+ }
+
+ if (count == 0)
+ lines[1] = NO_AUTO_NOTES;
+
+ screen._windows[30].writeString(Common::String::format(AUTO_NOTES_DATA,
+ lines[topRow].c_str(), lines[topRow + 1].c_str(),
+ lines[topRow + 2].c_str(), lines[topRow + 3].c_str(),
+ lines[topRow + 4].c_str(), lines[topRow + 5].c_str(),
+ lines[topRow + 6].c_str(), lines[topRow + 7].c_str(),
+ lines[topRow + 8].c_str()
+ ));
+ break;
+ }
+
+ screen._windows[30].writeString("\v000\t000");
+ screen._windows[24].update();
+
+ // Key handling
+ _buttonValue = 0;
+ while (!_vm->shouldQuit() && !_buttonValue) {
+ events.pollEventsAndWait();
+ checkEvents(_vm);
+ }
+
+ if (_buttonValue == Common::KEYCODE_ESCAPE)
+ break;
+
+ switch (_buttonValue) {
+ case Common::KEYCODE_a:
+ mode = AUTO_NOTES;
+ break;
+ case Common::KEYCODE_i:
+ mode = QUEST_ITEMS;
+ break;
+ case Common::KEYCODE_q:
+ mode = CURRENT_QUESTS;
+ break;
+ case Common::KEYCODE_HOME:
+ topRow = 0;
+ break;
+ case Common::KEYCODE_END:
+ topRow = count - 1;
+ break;
+ case Common::KEYCODE_PAGEUP:
+ topRow = MAX(topRow - 3, 0);
+ break;
+ case Common::KEYCODE_PAGEDOWN:
+ topRow = CLIP(topRow + 3, 0, count - 1);
+ break;
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_KP8:
+ topRow = MAX(topRow - 1, 0);
+ break;
+ case Common::KEYCODE_DOWN:
+ case Common::KEYCODE_KP2:
+ topRow = CLIP(topRow + 1, 0, count - 1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (windowFlag) {
+ screen._windows[30].close();
+ screen._windows[29].close();
+ }
+}
+
+void Quests::addButtons() {
+ _iconSprites.load("quest.icn");
+ addButton(Common::Rect(12, 109, 36, 129), Common::KEYCODE_i, &_iconSprites);
+ addButton(Common::Rect(80, 109, 104, 129), Common::KEYCODE_q, &_iconSprites);
+ addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_a, &_iconSprites);
+ addButton(Common::Rect(216, 109, 240, 129), Common::KEYCODE_i, &_iconSprites);
+ addButton(Common::Rect(250, 109, 274, 129), Common::KEYCODE_UP, &_iconSprites);
+ addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_DOWN, &_iconSprites);
+}
+
+void Quests::loadQuestNotes() {
+ File f("qnotes.bin");
+ while (f.pos() < f.size())
+ _questNotes.push_back(f.readString());
+ f.close();
}
} // End of namespace Xeen
diff --git a/engines/xeen/dialogs_quests.h b/engines/xeen/dialogs_quests.h
index fb39d3ace9..234accded6 100644
--- a/engines/xeen/dialogs_quests.h
+++ b/engines/xeen/dialogs_quests.h
@@ -23,6 +23,7 @@
#ifndef XEEN_DIALOGS_QUESTS_H
#define XEEN_DIALOGS_QUESTS_H
+#include "common/str-array.h"
#include "xeen/dialogs.h"
namespace Xeen {
@@ -30,10 +31,16 @@ namespace Xeen {
class Quests : public ButtonContainer {
private:
XeenEngine *_vm;
+ SpriteResource _iconSprites;
+ Common::StringArray _questNotes;
Quests(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
void execute();
+
+ void addButtons();
+
+ void loadQuestNotes();
public:
static void show(XeenEngine *vm);
};
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index 520cad5c05..34c7b548ff 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -25,6 +25,7 @@
#include "xeen/dialogs_error.h"
#include "xeen/dialogs_automap.h"
#include "xeen/dialogs_info.h"
+#include "xeen/dialogs_quests.h"
#include "xeen/dialogs_quick_ref.h"
#include "xeen/resources.h"
#include "xeen/xeen.h"
@@ -710,6 +711,11 @@ void Interface::perform() {
QuickReferenceDialog::show(_vm);
break;
+ case Common::KEYCODE_v:
+ // Show the quests dialog
+ Quests::show(_vm);
+ break;
+
default:
break;
}
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index ec7a8b99e1..b1ca067df4 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -45,6 +45,8 @@ enum Difficulty { ADVENTURER = 0, WARRIOR = 1 };
#define XEEN_TOTAL_CHARACTERS 24
#define MAX_ACTIVE_PARTY 6
#define TOTAL_STATS 7
+#define TOTAL_QUEST_ITEMS 85
+#define TOTAL_QUEST_FLAGS 56
class Roster: public Common::Array<Character> {
public:
@@ -107,7 +109,7 @@ public:
bool _gameFlags[512];
bool _worldFlags[128];
bool _quests[64];
- int _questItems[85];
+ int _questItems[TOTAL_QUEST_ITEMS];
bool _characterFlags[30][24];
public:
// Other party related runtime data
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 991c43018d..eeea54c81b 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -1144,6 +1144,94 @@ const char *const EFFECTIVENESS_NAMES[7] = {
nullptr, "Dragons", "Undead", "Golems", "Bugs", "Monsters", "Beasts"
};
+const char *const QUEST_ITEM_NAMES[85] = {
+ "Deed to New Castle",
+ "Crystal Key to Witch Tower",
+ "Skeleton Key to Darzog's Tower",
+ "Enchanted Key to Tower of High Magic",
+ "Jeweled Amulet of the Northern Sphinx",
+ "Stone of a Thousand Terrors",
+ "Golem Stone of Admittance",
+ "Yak Stone of Opening",
+ "Xeen's Scepter of Temporal Distortion",
+ "Alacorn of Falista",
+ "Elixir of Restoration",
+ "Wand of Faery Magic",
+ "Princess Roxanne's Tiara",
+ "Holy Book of Elvenkind",
+ "Scarab of Imaging",
+ "Crystals of Piezoelectricity",
+ "Scroll of Insight",
+ "Phirna Root",
+ "Orothin's Bone Whistle",
+ "Barok's Magic Pendant",
+ "Ligono's Missing Skull",
+ "Last Flower of Summer",
+ "Last Raindrop of Spring",
+ "Last Snowflake of Winter",
+ "Last Leaf of Autumn",
+ "Ever Hot Lava Rock",
+ "King's Mega Credit",
+ "Excavation Permit",
+ "Cupie Doll",
+ "Might Doll",
+ "Speed Doll",
+ "Endurance Doll",
+ "Accuracy Doll",
+ "Luck Doll",
+ "Widget",
+ "Pass to Castleview",
+ "Pass to Sandcaster",
+ "Pass to Lakeside",
+ "Pass to Necropolis",
+ "Pass to Olympus",
+ "Key to Great Western Tower",
+ "Key to Great Southern Tower",
+ "Key to Great Eastern Tower",
+ "Key to Great Northern Tower",
+ "Key to Ellinger's Tower",
+ "Key to Dragon Tower",
+ "Key to Darkstone Tower",
+ "Key to Temple of Bark",
+ "Key to Dungeon of Lost Souls",
+ "Key to Ancient Pyramid",
+ "Key to Dungeon of Death",
+ "Amulet of the Southern Sphinx",
+ "Dragon Pharoah's Orb",
+ "Cube of Power",
+ "Chime of Opening",
+ "Gold ID Card",
+ "Silver ID Card",
+ "Vulture Repellant",
+ "Bridle",
+ "Enchanted Bridle",
+ "Treasure Map (Goto E1 x1, y11)",
+ nullptr,
+ "Fake Map",
+ "Onyx Necklace",
+ "Dragon Egg",
+ "Tribble",
+ "Golden Pegasus Statuette",
+ "Golden Dragon Statuette",
+ "Golden Griffin Statuette",
+ "Chalice of Protection",
+ "Jewel of Ages",
+ "Songbird of Serenity",
+ "Sandro's Heart",
+ "Ector's Ring",
+ "Vespar's Emerald Handle",
+ "Queen Kalindra's Crown",
+ "Caleb's Magnifying Glass",
+ "Soul Box",
+ "Soul Box with Corak inside",
+ "Ruby Rock",
+ "Emerald Rock",
+ "Sapphire Rock",
+ "Diamond Rock",
+ "Monga Melon",
+ "Energy Disk"
+};
+
const int WEAPON_BASE_COSTS[35] = {
0, 50, 15, 100, 80, 40, 60, 1, 10, 150, 30, 60, 8, 50,
100, 15, 30, 15, 200, 80, 250, 150, 400, 100, 40, 120,
@@ -1288,4 +1376,51 @@ const char *const ELEMENTAL_XY_DAMAGE = "%+d %s Damage";
const char *const ATTR_XY_BONUS = "%+d %s";
const char *const EFFECTIVE_AGAINST = "x3 vs %s";
+const char *const QUESTS_DIALOG_TEXT =
+ "\r2\x2""c\v021\t017\f37I\fdtems\t085\f37Q\fduests\t153"
+ "\f37A\fduto Notes\t221\f37U\fdp\t255\f37D\fdown\t289Exit";
+
+const char *const CLOUDS_OF_XEEN_LINE = "\b \b*-- \f04Clouds of Xeen\fd --";
+const char *const DARKSIDE_OF_XEEN_LINE = "\b \b*-- \f04Darkside of Xeen\fd --";
+
+const char *const NO_QUEST_ITEMS =
+ "\rd\x3""c\v000 000Quest Items\x3l\x2\n"
+ "\n"
+ "\x3""cNo Quest Items";
+const char *const NO_CURRENT_QUESTS =
+ "\x3""c\v000\t000\n"
+ "\n"
+ "No Current Quests";
+const char *const NO_AUTO_NOTES = "\x3""cNo Auto Notes";
+
+const char *const QUEST_ITEMS_DATA =
+ "\r\x1\fd\x3""c\v000\t000Quest Items\x3l\x2\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s\n"
+ "\f04 * \fd%s";
+const char *const CURRENT_QUESTS_DATA =
+ "\r\x1\fd\x3""c\t000\v000Current Quests\x3l\x2\n"
+ "%s\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "%s";
+const char *const AUTO_NOTES_DATA =
+ "\r\x1\fd\x3""c\t000\v000Auto Notes\x3l\x2\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l\n"
+ "%s\x3l";
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 4c79a1ea27..9c0136c06f 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -387,6 +387,7 @@ extern const char *const MISC_NAMES[22];
extern const char *const ELEMENTAL_NAMES[6];
extern const char *const ATTRIBUTE_NAMES[10];
extern const char *const EFFECTIVENESS_NAMES[7];
+extern const char *const QUEST_ITEM_NAMES[85];
extern const int WEAPON_BASE_COSTS[35];
extern const int ARMOR_BASE_COSTS[25];
@@ -474,6 +475,17 @@ extern const char *const ELEMENTAL_XY_DAMAGE;
extern const char *const ATTR_XY_BONUS;
extern const char *const EFFECTIVE_AGAINST;
+extern const char *const QUESTS_DIALOG_TEXT;
+extern const char *const CLOUDS_OF_XEEN_LINE;
+extern const char *const DARKSIDE_OF_XEEN_LINE;
+
+extern const char *const NO_QUEST_ITEMS;
+extern const char *const NO_CURRENT_QUESTS;
+extern const char *const NO_AUTO_NOTES;
+extern const char *const QUEST_ITEMS_DATA;
+extern const char *const CURRENT_QUESTS_DATA;
+extern const char *const AUTO_NOTES_DATA;
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */