aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2015-01-26 21:35:50 -0500
committerPaul Gilbert2015-01-26 21:35:50 -0500
commit81e1bd2930bf4192fa8bfdbb805c65795e68c6e1 (patch)
tree8c067b34f4c22c7c26157e2529634a7619eb1745 /engines
parentf11e11006b5cbe7d9bcd547f98ab2b4dba358764 (diff)
downloadscummvm-rg350-81e1bd2930bf4192fa8bfdbb805c65795e68c6e1.tar.gz
scummvm-rg350-81e1bd2930bf4192fa8bfdbb805c65795e68c6e1.tar.bz2
scummvm-rg350-81e1bd2930bf4192fa8bfdbb805c65795e68c6e1.zip
XEEN: Implemented createTownText
Diffstat (limited to 'engines')
-rw-r--r--engines/xeen/party.cpp59
-rw-r--r--engines/xeen/party.h8
-rw-r--r--engines/xeen/resources.cpp64
-rw-r--r--engines/xeen/resources.h24
-rw-r--r--engines/xeen/town.cpp172
-rw-r--r--engines/xeen/town.h18
-rw-r--r--engines/xeen/xeen.cpp10
-rw-r--r--engines/xeen/xeen.h4
8 files changed, 349 insertions, 10 deletions
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index 388b8de261..1baa25404f 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -757,6 +757,65 @@ void Character::setValue(int id, uint value) {
}
}
+bool Character::guildMember() const {
+ Party &party = *Party::_vm->_party;
+
+ if (party._mazeId == 49 && !Party::_vm->_files->_isDarkCc) {
+ return hasAward(5);
+ }
+
+ switch (party._mazeId) {
+ case 29:
+ return hasAward(83);
+ case 31:
+ return hasAward(84);
+ case 33:
+ return hasAward(85);
+ case 35:
+ return hasAward(86);
+ default:
+ return hasAward(87);
+ }
+}
+
+uint Character::nextExperienceLevel() const {
+ uint base = currentExperienceLevel();
+ uint curr = getCurrentExperience();
+ return (curr < base) ? 0 : curr - base;
+}
+
+uint Character::currentExperienceLevel() const {
+ int shift, base;
+ if (_level._permanent >= 12) {
+ base = _level._permanent - 12;
+ shift = 10;
+ } else {
+ base = 0;
+ shift = _level._permanent;
+ }
+
+ return (base * 1024000) + (CLASS_EXP_LEVELS[_class] << shift);
+}
+
+uint Character::getCurrentExperience() const {
+ int lev = _level._permanent - 1;
+ int shift, base;
+
+ if (lev > 0 && lev < 12)
+ return _experience;
+
+ if (lev >= 12) {
+ base = lev - 12;
+ shift = 10;
+ } else {
+ base = 0;
+ shift = lev - 1;
+ }
+
+ return (base * 1024000) + (CLASS_EXP_LEVELS[_class] << shift) +
+ _experience;
+}
+
/*------------------------------------------------------------------------*/
void Roster::synchronize(Common::Serializer &s) {
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index c77364bd10..0b7572cccf 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -167,6 +167,14 @@ public:
int itemScan(int itemId) const;
void setValue(int id, uint value);
+
+ bool guildMember() const;
+
+ uint nextExperienceLevel() const;
+
+ uint currentExperienceLevel() const;
+
+ uint getCurrentExperience() const;
};
class Roster: public Common::Array<Character> {
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 9e11a17aa7..c1951d704c 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -290,6 +290,10 @@ const char *const CLASS_NAMES[11] = {
"Ninja", "Barbarian", "Druid", "Ranger", nullptr
};
+const uint CLASS_EXP_LEVELS[10] = {
+ 1500, 2000, 2000, 1500, 2000, 1000, 1500, 1500, 1500, 2000
+};
+
const char *const CONDITION_NAMES[18] = {
nullptr, "Cursed", "Heart Broken", "Weak", "Poisoned", "Diseased",
"Insane", "In Love", "Drunk", "Asleep", "Depressed", "Confused",
@@ -585,4 +589,64 @@ const int TOWN_ACTION_FILES[2][7] = {
{ 3, 2, 4, 2, 4, 2, 1 }, { 5, 3, 7, 5, 4, 6, 1 }
};
+const char *const BANK_TEXT = "\x0D\x02\x03""c\x0B""122\x09""013"
+ "\x0C""37D\x0C""dep\x09""040\x0C""37W\x0C""dith\x09""067ESC"
+ "\x01\x09""000\x0B""000Bank of Xeen\x0B""015\n"
+ "Bank\x03l\n"
+ "Gold\x03r\x09""000%s\x03l\n"
+ "Gems\x03r\x09""000%s\x03""c\n"
+ "\n"
+ "Party\x03l\n"
+ "Gold\x03r\x09""000%s\x03l\n"
+ "Gems\x03r\x09""000%s";
+
+const char *const BLACKSMITH_TEXT = "\x01\x0D\x03""c\x0B""000\x09""000"
+ "Store Options for\x09""039\x0B""027%s\x03""l\x0B""046\n"
+ "\x09""011\x0C""37B\x0C""drowse\n"
+ "\x09""000\x0B""090Gold\x03r\x09""000%s"
+ "\x02\x03""c\x0B""122\x09""040ESC\x01";
+
+const char *const GUILD_NOT_MEMBER_TEXT =
+ "\n\nYou have to be a member to shop here.";
+
+const char *const GUILD_TEXT = "\x03""c\x0B""027\x09""039%s"
+ "\x03l\x0B""046\n"
+ "\x09""012\x0C""37B\x0C""duy Spells\n"
+ "\x09""012\x0C""37S\x0C""dpell Info";
+
+const char *const TAVERN_TEXT =
+ "\x0D\x03""c\x0B""000\x09""000Tavern Options for\x09""039"
+ "\x0B""027%s%s\x03l\x09""000"
+ "\x0B""090Gold\x03r\x09""000%s\x02\x03""c\x0B""122"
+ "\x09""021\x0C""37S\x0C""dign in\x09""060ESC\x01";
+
+const char *const FOOD_AND_DRINK =
+ "\x03l\x09""017\x0B""046\x0C""37D\x0C""drink\n"
+ "\x09""017\x0C""37F\x0C""dood\n"
+ "\x09""017\x0C""37T\x0C""dip\n"
+ "\x09""017\x0C""37R\x0C""dumors";
+
+const char *const TEMPLE_TEXT =
+ "\x0D\x03""c\x0B""000\x09""000Temple Options for"
+ "\x09""039\x0B""027%s\x03l\x09""000\x0B""046"
+ "\x0C""37H\x0C""deal\x03r\x09""000%lu\x03l\n"
+ "\x0C""37D\x0C""donation\x03r\x09""000%lu\x03l\n"
+ "\x0C""37U\x0C""dnCurse\x03r\x09""000%s"
+ "\x03l\x09""000\x0B""090Gold\x03r\x09""000%s"
+ "\x02\x03""c\x0B""122\x09""040ESC\x01";
+
+const char *const EXPERIENCE_FOR_LEVEL =
+ "%s needs %lu experience for level %u.";
+
+const char *const LEARNED_ALL = "%s has learned all we can teach!";
+
+const char *const ELIGIBLE_FOR_LEVEL = "%s is eligible for level %d.";
+
+const char *const TRAINING_TEXT =
+ "\x0D\x03""cTraining Options\n"
+ "\n"
+ "%s\x03l\x0B""090\x09""000Gold\x03r\x09"
+ "000%s\x02\x03""c\x0B""122\x09""021"
+ "\x0C""37T\x0C""drain\x09""060ESC\x01";
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index ff192023a3..a6f52cb50e 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -66,6 +66,8 @@ extern const int RACE_SP_BONUSES[5][2];
extern const char *const CLASS_NAMES[11];
+extern const uint CLASS_EXP_LEVELS[10];
+
extern const char *const ALIGNMENT_NAMES[3];
extern const char *const SEX_NAMES[2];
@@ -158,6 +160,28 @@ extern const char *const TOWN_ACTION_SHAPES[4];
extern const int TOWN_ACTION_FILES[2][7];
+extern const char *const BANK_TEXT;
+
+extern const char *const BLACKSMITH_TEXT;
+
+extern const char *const GUILD_NOT_MEMBER_TEXT;
+
+extern const char *const GUILD_TEXT;
+
+extern const char *const TAVERN_TEXT;
+
+extern const char *const FOOD_AND_DRINK;
+
+extern const char *const TEMPLE_TEXT;
+
+extern const char *const EXPERIENCE_FOR_LEVEL;
+
+extern const char *const LEARNED_ALL;
+
+extern const char *const ELIGIBLE_FOR_LEVEL;
+
+extern const char *const TRAINING_TEXT;
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */
diff --git a/engines/xeen/town.cpp b/engines/xeen/town.cpp
index 214454b058..bb8590fc48 100644
--- a/engines/xeen/town.cpp
+++ b/engines/xeen/town.cpp
@@ -27,12 +27,23 @@
namespace Xeen {
Town::Town(XeenEngine *vm) : _vm(vm) {
+ Common::fill(&_arr1[0], &_arr1[6], 0);
_townMaxId = 0;
_townActionId = 0;
_townCurrent = 0;
+ _currentCharLevel = 0;
_v1 = 0;
_v2 = 0;
- Common::fill(&_arr1[0], &_arr1[6], 0);
+ _donation = 0;
+ _healCost = 0;
+ _v5 = _v6 = 0;
+ _v10 = _v11 = 0;
+ _v12 = _v13 = 0;
+ _v14 = 0;
+ _v20 = 0;
+ _uncurseCost = 0;
+ _flag1 = false;
+ _nextExperienceLevel = 0;
}
void Town::loadStrings(const Common::String &name) {
@@ -191,7 +202,8 @@ int Town::townAction(int actionId) {
_townSprites[idx].load(shapesName);
}
- Common::String title = createTownText();
+ Character *charP = &party._activeParty[0];
+ Common::String title = createTownText(*charP);
intf._face1UIFrame = intf._face2UIFrame = 0;
intf._dangerSenseUIFrame = 0;
intf._spotDoorsUIFrame = 0;
@@ -222,7 +234,7 @@ int Town::townAction(int actionId) {
do {
townWait();
- doTownOptions();
+ charP = doTownOptions(charP);
screen._windows[10].writeString(title);
drawButtons(&screen);
} while (!_vm->shouldQuit() && _buttonValue != Common::KEYCODE_ESCAPE);
@@ -309,11 +321,159 @@ void Town::dwarfEvent() {
error("TODO: dwarfEvent");
}
-Common::String Town::createTownText() {
- error("TODO");
+Common::String Town::createTownText(Character &ch) {
+ Interface &intf = *_vm->_interface;
+ Party &party = *_vm->_party;
+ Common::String msg;
+
+ switch (_townActionId) {
+ case 0:
+ // Bank
+ return Common::String::format(BANK_TEXT,
+ XeenEngine::printMil(party._bankGold).c_str(),
+ XeenEngine::printMil(party._bankGems).c_str(),
+ XeenEngine::printMil(party._gold).c_str(),
+ XeenEngine::printMil(party._gems).c_str());
+ case 1:
+ // Blacksmith
+ return Common::String::format(BLACKSMITH_TEXT,
+ XeenEngine::printMil(party._gold));
+
+ case 2:
+ // Guild
+ return !ch.guildMember() ? GUILD_NOT_MEMBER_TEXT :
+ Common::String::format(GUILD_TEXT, ch._name.c_str());
+
+ case 3:
+ // Tavern
+ return Common::String::format(TAVERN_TEXT, ch._name,
+ FOOD_AND_DRINK, XeenEngine::printMil(party._gold).c_str());
+
+ case 4:
+ // Temple
+ _donation = 0;
+ _uncurseCost = 0;
+ _v5 = 0;
+ _v6 = 0;
+ _healCost = 0;
+
+ if (party._mazeId == (_vm->_files->_isDarkCc ? 29 : 28)) {
+ _v10 = _v11 = _v12 = _v13 = 0;
+ _v14 = 10;
+ } else if (party._mazeId == (_vm->_files->_isDarkCc ? 31 : 30)) {
+ _v13 = 10;
+ _v12 = 50;
+ _v11 = 500;
+ _v10 = 100;
+ _v14 = 25;
+ } else if (party._mazeId == (_vm->_files->_isDarkCc ? 37 : 73)) {
+ _v13 = 20;
+ _v12 = 100;
+ _v11 = 1000;
+ _v10 = 200;
+ _v14 = 50;
+ } else if (_vm->_files->_isDarkCc || party._mazeId == 49) {
+ _v13 = 100;
+ _v12 = 500;
+ _v11 = 5000;
+ _v10 = 300;
+ _v14 = 100;
+ }
+
+ _currentCharLevel = ch.getCurrentLevel();
+ if (ch._currentHp < ch.getMaxHP()) {
+ _healCost = _currentCharLevel * 10 + _v13;
+ }
+
+ for (int attrib = HEART_BROKEN; attrib <= UNCONSCIOUS; ++attrib) {
+ if (ch._conditions[attrib])
+ _healCost += _currentCharLevel * 10;
+ }
+
+ _v6 = 0;
+ if (ch._conditions[DEAD]) {
+ _v6 += (_currentCharLevel * 100) + (ch._conditions[DEAD] * 50) + _v12;
+ }
+ if (ch._conditions[STONED]) {
+ _v6 += (_currentCharLevel * 100) + (ch._conditions[STONED] * 50) + _v12;
+ }
+ if (ch._conditions[ERADICATED]) {
+ _v5 = (_currentCharLevel * 1000) + (ch._conditions[ERADICATED] * 500) + _v11;
+ }
+
+ for (int idx = 0; idx < 9; ++idx) {
+ _uncurseCost |= ch._weapons[idx]._bonusFlags & 0x40;
+ _uncurseCost |= ch._armor[idx]._bonusFlags & 0x40;
+ _uncurseCost |= ch._accessories[idx]._bonusFlags & 0x40;
+ _uncurseCost |= ch._misc[idx]._bonusFlags & 0x40;
+ }
+
+ if (_uncurseCost || ch._conditions[CURSED])
+ _v5 = (_currentCharLevel * 20) + _v10;
+
+ _donation = _flag1 ? 0 : _v14;
+ _healCost += _v6 + _v5;
+
+ return Common::String::format(TEMPLE_TEXT, ch._name.c_str(),
+ _healCost, _donation, XeenEngine::printK(_uncurseCost).c_str(),
+ XeenEngine::printMil(party._gold).c_str());
+
+ case 5:
+ // Training
+ if (_vm->_files->_isDarkCc) {
+ switch (party._mazeId) {
+ case 29:
+ _v20 = 30;
+ break;
+ case 31:
+ _v20 = 50;
+ break;
+ case 37:
+ _v20 = 200;
+ break;
+ default:
+ _v20 = 100;
+ break;
+ }
+ } else {
+ switch (party._mazeId) {
+ case 28:
+ _v20 = 10;
+ break;
+ case 30:
+ _v20 = 15;
+ break;
+ default:
+ _v20 = 20;
+ break;
+ }
+ }
+
+ _nextExperienceLevel = ch.nextExperienceLevel();
+
+ if (_nextExperienceLevel >= 0x10000 && ch._level._permanent < _v20) {
+ int nextLevel = ch._level._permanent + 1;
+ return Common::String::format(EXPERIENCE_FOR_LEVEL,
+ ch._name.c_str(), _nextExperienceLevel, nextLevel);
+ } else if (ch._level._permanent >= 20) {
+ _nextExperienceLevel = 1;
+ msg = Common::String::format(LEARNED_ALL, ch._name.c_str());
+ } else {
+ msg = Common::String::format(ELIGIBLE_FOR_LEVEL,
+ ch._name.c_str(), ch._level._permanent + 1);
+ }
+
+ return Common::String::format(TRAINING_TEXT,
+ XeenEngine::printMil(party._gold).c_str());
+
+ default:
+ return "";
+ }
}
-void Town::doTownOptions() {
+Character *Town::doTownOptions(Character *charP) {
+ Common::String result;
+
error("TODO: doTownOptions");
}
diff --git a/engines/xeen/town.h b/engines/xeen/town.h
index 2221ed5400..07e9badc46 100644
--- a/engines/xeen/town.h
+++ b/engines/xeen/town.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/str-array.h"
#include "xeen/dialogs.h"
+#include "xeen/party.h"
namespace Xeen {
@@ -40,10 +41,19 @@ private:
int _townMaxId;
int _townActionId;
int _townCurrent;
- int _v1;
- int _v2;
+ int _v1, _v2;
+ int _donation;
+ int _healCost;
+ int _v5, _v6;
+ int _v10, _v11, _v12;
+ int _v13, _v14;
+ int _v20;
+ int _uncurseCost;
Common::Point _townPos;
int _arr1[6];
+ int _currentCharLevel;
+ bool _flag1;
+ uint _nextExperienceLevel;
void loadStrings(const Common::String &name);
@@ -59,11 +69,11 @@ private:
void dwarfEvent();
- Common::String createTownText();
+ Common::String createTownText(Character &ch);
void townWait();
- void doTownOptions();
+ Character *doTownOptions(Character *charP);
public:
Town(XeenEngine *vm);
diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp
index 8d646fbcf5..d7a85fbbf8 100644
--- a/engines/xeen/xeen.cpp
+++ b/engines/xeen/xeen.cpp
@@ -339,4 +339,14 @@ void XeenEngine::gameLoop() {
}
}
+Common::String XeenEngine::printMil(uint value) {
+ return (value >= 1000000) ? Common::String::format("%lu mil", value / 1000000) :
+ Common::String::format("%lu", value);
+}
+
+Common::String XeenEngine::printK(uint value) {
+ return (value > 9999) ? Common::String::format("%uk", value / 1000) :
+ Common::String::format("%u", value);
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h
index 1145072d6d..cb09c280cd 100644
--- a/engines/xeen/xeen.h
+++ b/engines/xeen/xeen.h
@@ -198,6 +198,10 @@ public:
* Write out a savegame header
*/
void writeSavegameHeader(Common::OutSaveFile *out, XeenSavegameHeader &header);
+
+ static Common::String printMil(uint value);
+
+ static Common::String printK(uint value);
};
} // End of namespace Xeen