mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-11 19:54:03 +00:00
KYRA: (EOB) - implement party resting
This commit is contained in:
parent
db83458330
commit
9140fd8e91
@ -492,7 +492,8 @@ const ExtractFilename extractFilenames[] = {
|
||||
{ kEob2Npc1Strings, kTypeStringList, true },
|
||||
{ kEob2Npc2Strings, kTypeStringList, true },
|
||||
{ kEob2MonsterDustStrings, kTypeStringList, true },
|
||||
|
||||
{ kEob2DranFoolsStrings, kTypeStringList, true },
|
||||
|
||||
// LANDS OF LORE
|
||||
|
||||
// Ingame
|
||||
@ -1767,6 +1768,8 @@ const char *getIdString(const int id) {
|
||||
return "kEob2Npc2Strings";
|
||||
case kEob2MonsterDustStrings:
|
||||
return "kEob2MonsterDustStrings";
|
||||
case kEob2DranFoolsStrings:
|
||||
return "kEob2DranFoolsStrings";
|
||||
case kLolIngamePakFiles:
|
||||
return "kLolIngamePakFiles";
|
||||
case kLolCharacterDefs:
|
||||
|
@ -474,6 +474,8 @@ enum kExtractID {
|
||||
kEob2Npc2Strings,
|
||||
kEob2MonsterDustStrings,
|
||||
|
||||
kEob2DranFoolsStrings,
|
||||
|
||||
kLolIngamePakFiles,
|
||||
kLolCharacterDefs,
|
||||
kLolIngameSfxFiles,
|
||||
|
@ -1484,6 +1484,7 @@ const int eob2FloppyNeed[] = {
|
||||
kEob2Npc1Strings,
|
||||
kEob2Npc2Strings,
|
||||
kEob2MonsterDustStrings,
|
||||
kEob2DranFoolsStrings,
|
||||
|
||||
kLolEobCommonDscShapeIndex,
|
||||
kLolEobCommonDscX,
|
||||
|
@ -2772,6 +2772,12 @@ const ExtractEntrySearchData kEob2MonsterDustStringsProvider[] = {
|
||||
EXTRACT_END_ENTRY
|
||||
};
|
||||
|
||||
const ExtractEntrySearchData kEob2DranFoolsStringsProvider[] = {
|
||||
{ EN_ANY, kPlatformUnknown, { 0x0000001A, 0x00000887, { { 0xA6, 0xB4, 0x45, 0x1B, 0x33, 0x54, 0x36, 0xAD, 0x1D, 0xB1, 0xDA, 0xC3, 0x12, 0x85, 0x3C, 0x58 } } } },
|
||||
{ DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000511, { { 0xEE, 0x21, 0xA8, 0x6E, 0xF7, 0xEC, 0x9A, 0x8D, 0xBA, 0x8D, 0xE3, 0x4A, 0x17, 0x15, 0xCA, 0x8C } } } },
|
||||
EXTRACT_END_ENTRY
|
||||
};
|
||||
|
||||
const ExtractEntrySearchData kLolIngamePakFilesProvider[] = {
|
||||
{ UNK_LANG, kPlatformPC, { 0x00000088, 0x0000224F, { { 0xDA, 0x24, 0x18, 0xA3, 0xEF, 0x16, 0x70, 0x8F, 0xA8, 0xC2, 0x2E, 0xC2, 0xED, 0x39, 0x03, 0xD1 } } } },
|
||||
{ UNK_LANG, kPlatformPC98, { 0x00000084, 0x00002125, { { 0x7A, 0x89, 0xE2, 0x36, 0xEC, 0x6F, 0x52, 0x2B, 0xEF, 0xBA, 0x3D, 0x28, 0x54, 0xDA, 0xFB, 0x72 } } } },
|
||||
@ -3660,6 +3666,7 @@ const ExtractEntry extractProviders[] = {
|
||||
{ kEob2Npc1Strings, kEob2Npc1StringsProvider },
|
||||
{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
|
||||
{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
|
||||
{ kEob2DranFoolsStrings, kEob2DranFoolsStringsProvider },
|
||||
|
||||
{ kLolIngamePakFiles, kLolIngamePakFilesProvider },
|
||||
{ kLolCharacterDefs, kLolCharacterDefsProvider },
|
||||
|
@ -1270,10 +1270,10 @@ void CharacterGenerator::finish() {
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (_vm->_classModifierFlags[_characters[i].cClass] & 2)
|
||||
_characters[i].mageSpellsAvailabilityFlags = (_vm->game() == GI_EOB2) ? 0x81CB6 : 0x26C;
|
||||
_characters[i].mageSpellsAvailableFlags = (_vm->game() == GI_EOB2) ? 0x81CB6 : 0x26C;
|
||||
|
||||
if (_vm->_classModifierFlags[_characters[i].cClass] & 0x14 && _vm->game() == GI_EOB2) {
|
||||
// Cleric: Turn Undead
|
||||
// Cleric/Paladin: Add Turn Undead spell
|
||||
_characters[i].clericSpells[0] = 29;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "kyra/eob1.h"
|
||||
#include "kyra/resource.h"
|
||||
#include "kyra/sound.h"
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
@ -77,6 +78,10 @@ void EobEngine::startupNew() {
|
||||
EobCoreEngine::startupNew();
|
||||
}
|
||||
|
||||
void EobEngine::startupLoad() {
|
||||
_sound->loadSoundFile("ADLIB");
|
||||
}
|
||||
|
||||
void EobEngine::npcSequence(int npcIndex) {
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ private:
|
||||
|
||||
// Main loop
|
||||
void startupNew();
|
||||
void startupLoad() {}
|
||||
void startupLoad();
|
||||
|
||||
// Intro/Outro
|
||||
void seq_playOpeningCredits();
|
||||
|
@ -271,6 +271,24 @@ void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, in
|
||||
initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem);
|
||||
}
|
||||
|
||||
bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
|
||||
if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].flags & 4)) {
|
||||
if (m->type) {
|
||||
_playFinale = true;
|
||||
_runFlag = false;
|
||||
} else {
|
||||
m->hitPointsCur = 150;
|
||||
m->curRemoteWeapon = 0;
|
||||
m->numRemoteAttacks = 255;
|
||||
m->shpIndex++;
|
||||
m->type++;
|
||||
seq_dranDragonTransformation();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs) {
|
||||
_screen->loadEobBitmap(filename, 3, 3);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
@ -319,6 +337,24 @@ void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall
|
||||
drawBlockObject(0, 2, _doorSwitches[shapeIndex].shp, _doorSwitches[shapeIndex].x + w, _doorSwitches[shapeIndex].y, 5);
|
||||
}
|
||||
|
||||
void DarkMoonEngine::restParty_npc() {
|
||||
|
||||
}
|
||||
|
||||
bool DarkMoonEngine::restParty_extraAbortCondition() {
|
||||
if (_currentLevel != 3)
|
||||
return false;
|
||||
|
||||
seq_nightmare();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DarkMoonEngine::checkPartyStatusExtra() {
|
||||
if (checkScriptFlag(0x10))
|
||||
seq_dranFools();
|
||||
}
|
||||
|
||||
void DarkMoonEngine::drawLightningColumn() {
|
||||
int f = rollDice(1, 2, -1);
|
||||
int y = 0;
|
||||
|
@ -60,6 +60,7 @@ private:
|
||||
// Main Menu
|
||||
int mainMenu();
|
||||
int mainMenuLoop();
|
||||
|
||||
int _menuChoiceInit;
|
||||
|
||||
// Main loop
|
||||
@ -85,6 +86,13 @@ private:
|
||||
static const char *_palFilesIntro[];
|
||||
static const char *_palFilesFinale[];
|
||||
|
||||
// Ingame sequence
|
||||
void seq_nightmare();
|
||||
void seq_dranFools();
|
||||
void seq_dranDragonTransformation();
|
||||
|
||||
const char *const *_dranFoolsStrings;
|
||||
|
||||
// characters
|
||||
void npcSequence(int npcIndex);
|
||||
|
||||
@ -99,6 +107,7 @@ private:
|
||||
void generateMonsterPalettes(const char *file, int16 monsterIndex);
|
||||
void loadMonsterDecoration(const char *file, int16 monsterIndex);
|
||||
void replaceMonster(int unit, uint16 block, int d, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem);
|
||||
bool killMonsterExtra(EobMonsterInPlay *m);
|
||||
|
||||
// Level
|
||||
const uint8 *loadDoorShapes(const char *filename, int doorIndex, const uint8 *shapeDefs);
|
||||
@ -106,7 +115,12 @@ private:
|
||||
|
||||
const uint8 *_dscDoorType5Offs;
|
||||
|
||||
// Rest party
|
||||
void restParty_npc();
|
||||
bool restParty_extraAbortCondition();
|
||||
|
||||
// misc
|
||||
void checkPartyStatusExtra();
|
||||
void drawLightningColumn();
|
||||
int resurrectionSelectDialogue();
|
||||
int charSelectDialogue();
|
||||
|
@ -135,6 +135,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
|
||||
_spells = 0;
|
||||
_spellAnimBuffer = 0;
|
||||
_clericSpellOffset = 0;
|
||||
_restPartyElapsedTime = 0;
|
||||
}
|
||||
|
||||
EobCoreEngine::~EobCoreEngine() {
|
||||
@ -351,6 +352,7 @@ Common::Error EobCoreEngine::go() {
|
||||
if (_gameToLoad != -1) {
|
||||
if (loadGameState(_gameToLoad).getCode() != Common::kNoError)
|
||||
error("Couldn't load game slot %d on startup", _gameToLoad);
|
||||
startupLoad();
|
||||
_gameToLoad = -1;
|
||||
} else {
|
||||
action = mainMenu();
|
||||
@ -434,7 +436,7 @@ void EobCoreEngine::runLoop() {
|
||||
|
||||
while (!shouldQuit() && _runFlag) {
|
||||
//_runLoopUnk2 = _currentBlock;
|
||||
updateCharacterEvents(true);
|
||||
checkPartyStatus(true);
|
||||
checkInput(_activeButtons, true, 0);
|
||||
removeInputTop();
|
||||
|
||||
@ -444,16 +446,18 @@ void EobCoreEngine::runLoop() {
|
||||
if (_sceneUpdateRequired)
|
||||
drawScene(1);
|
||||
|
||||
if (_envAudioTimer >= _system->getMillis())
|
||||
if (_envAudioTimer >= _system->getMillis() || (_flags.gameID == GI_EOB1 && (_currentLevel == 0 || _currentLevel > 3)))
|
||||
continue;
|
||||
|
||||
_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
|
||||
snd_processEnvironmentalSoundEffect(rollDice(1, 2, -1) ? 27 : 28, _currentBlock + rollDice(1, 12, -1));
|
||||
snd_processEnvironmentalSoundEffect(_flags.gameID == GI_EOB1 ? 30 : (rollDice(1, 2, -1) ? 27 : 28), _currentBlock + rollDice(1, 12, -1));
|
||||
updateEnvironmentalSfx(0);
|
||||
//TODO
|
||||
//EOB1__level_2_7__turnUndead();
|
||||
}
|
||||
}
|
||||
|
||||
bool EobCoreEngine::updateCharacterEvents(bool a) {
|
||||
bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
|
||||
int numChars = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
numChars += testCharacter(i, 13);
|
||||
@ -461,21 +465,22 @@ bool EobCoreEngine::updateCharacterEvents(bool a) {
|
||||
if (numChars)
|
||||
return false;
|
||||
|
||||
if (!a)
|
||||
if (!handleDeath)
|
||||
return true;
|
||||
|
||||
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
checkPartyStatusExtra();
|
||||
|
||||
/// TODO
|
||||
/// if (checkScriptFlag(0x10))
|
||||
/// j_dranThoseFools()
|
||||
|
||||
/// TODO
|
||||
|
||||
/// TODO
|
||||
|
||||
if (_gui->confirmDialogue2(14, 67, 1)) {
|
||||
_screen->setFont(Screen::FID_8_FNT);
|
||||
gui_updateControls();
|
||||
if (_gui->runLoadMenu(0, 0)) {
|
||||
_screen->setFont(Screen::FID_6_FNT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
quitGame();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -932,13 +937,13 @@ int EobCoreEngine::countCharactersWithSpecificItems(int16 itemType, int16 itemVa
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 1))
|
||||
continue;
|
||||
if (checkCharacterInventoryForItem(i, itemType, itemValue) != -1)
|
||||
if (checkInventoryForItem(i, itemType, itemValue) != -1)
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int EobCoreEngine::checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue) {
|
||||
int EobCoreEngine::checkInventoryForItem(int character, int16 itemType, int16 itemValue) {
|
||||
for (int i = 0; i < 27; i++) {
|
||||
uint16 inv = _characters[character].inventory[i];
|
||||
if (!inv)
|
||||
@ -1275,6 +1280,118 @@ int EobCoreEngine::runDialogue(int dialogueTextId, int style, const char *button
|
||||
return res;
|
||||
}
|
||||
|
||||
void EobCoreEngine::restParty_displayWarning(const char *str) {
|
||||
int od = _screen->curDimIndex();
|
||||
_screen->setScreenDim(7);
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
|
||||
_screen->setCurPage(0);
|
||||
|
||||
_txt->printMessage(Common::String::format("\r%s\r", str).c_str());
|
||||
|
||||
_screen->setFont(of);
|
||||
_screen->setScreenDim(od);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::restParty_updateMonsters() {
|
||||
bool sfxEnabled = _sound->sfxEnabled();
|
||||
bool musicEnabled = _sound->musicEnabled();
|
||||
_sound->enableSFX(false);
|
||||
_sound->enableMusic(false);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
_partyResting = true;
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
|
||||
int od = _screen->curDimIndex();
|
||||
_screen->setScreenDim(7);
|
||||
updateMonsters(0);
|
||||
updateMonsters(1);
|
||||
timerProcessFlyingObjects(0);
|
||||
_screen->setScreenDim(od);
|
||||
_screen->setFont(of);
|
||||
_partyResting = false;
|
||||
|
||||
for (int ii = 0; ii < 30; ii++) {
|
||||
if (_monsters[ii].mode == 8)
|
||||
continue;
|
||||
if (getBlockDistance(_currentBlock, _monsters[ii].block) >= 2)
|
||||
continue;
|
||||
|
||||
restParty_displayWarning(_menuStringsRest4[0]);
|
||||
_sound->enableSFX(sfxEnabled);
|
||||
_sound->enableMusic(musicEnabled);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_sound->enableSFX(sfxEnabled);
|
||||
_sound->enableMusic(musicEnabled);
|
||||
return false;
|
||||
}
|
||||
|
||||
int EobCoreEngine::restParty_getCharacterWithLowestHp() {
|
||||
int lhp = 900;
|
||||
int res = -1;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 3))
|
||||
continue;
|
||||
if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
|
||||
continue;
|
||||
if (_characters[i].hitPointsCur < lhp) {
|
||||
lhp = _characters[i].hitPointsCur;
|
||||
res = i;
|
||||
}
|
||||
}
|
||||
|
||||
return res + 1;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::restParty_checkHealSpells(int charIndex) {
|
||||
static const uint8 eob1healSpells[] = { 2, 15, 20 };
|
||||
static const uint8 eob2healSpells[] = { 3, 16, 20 };
|
||||
const uint8 *spells = _flags.gameID == GI_EOB1 ? eob1healSpells : eob2healSpells;
|
||||
const int8 *list = _characters[charIndex].clericSpells;
|
||||
|
||||
for (int i = 0; i < 80; i++) {
|
||||
int s = list[i] < 0 ? -list[i] : list[i];
|
||||
if (s == spells[0] || s == spells[1] || s == spells[2])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::restParty_checkSpellsToLearn() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 0x43))
|
||||
continue;
|
||||
|
||||
if ((getCharacterLevelIndex(2, _characters[i].cClass) != -1 || getCharacterLevelIndex(4, _characters[i].cClass) != -1) && (checkInventoryForItem(i, 30, -1) != -1)) {
|
||||
for (int ii = 0; ii < 80; ii++) {
|
||||
if (_characters[i].clericSpells[ii] < 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((getCharacterLevelIndex(1, _characters[i].cClass) != -1) && (checkInventoryForItem(i, 29, -1) != -1)) {
|
||||
for (int ii = 0; ii < 80; ii++) {
|
||||
if (_characters[i].mageSpells[ii] < 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EobCoreEngine::restParty_npc() {
|
||||
|
||||
}
|
||||
|
||||
bool EobCoreEngine::restParty_extraAbortCondition() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void EobCoreEngine::delay(uint32 millis, bool, bool) {
|
||||
while (millis && !shouldQuit() && !skipFlag()) {
|
||||
updateInput();
|
||||
@ -1319,28 +1436,6 @@ void EobCoreEngine::displayParchment(int id) {
|
||||
restoreAfterDialogueSequence();
|
||||
}
|
||||
|
||||
bool EobCoreEngine::restParty() {
|
||||
if (_inf->preventRest()) {
|
||||
assert(_menuStringsRest3[0]);
|
||||
displayRestWarning(_menuStringsRest3[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::displayRestWarning(const char *str) {
|
||||
int od = _screen->curDimIndex();
|
||||
_screen->setScreenDim(7);
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
|
||||
_screen->setCurPage(0);
|
||||
|
||||
_txt->printMessage(Common::String::format("\r%s\r", str).c_str());
|
||||
|
||||
_screen->setFont(of);
|
||||
_screen->setScreenDim(od);
|
||||
}
|
||||
|
||||
void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, int item) {
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
int tp = item ? _items[item].type : 0;
|
||||
|
@ -108,7 +108,7 @@ struct EobCharacter {
|
||||
|
||||
int8 mageSpells[80];
|
||||
int8 clericSpells[80];
|
||||
uint32 mageSpellsAvailabilityFlags;
|
||||
uint32 mageSpellsAvailableFlags;
|
||||
|
||||
Item inventory[27];
|
||||
uint32 timers[10];
|
||||
@ -311,7 +311,7 @@ protected:
|
||||
virtual void startupLoad() = 0;
|
||||
void runLoop();
|
||||
void update() { screen()->updateScreen(); }
|
||||
bool updateCharacterEvents(bool a);
|
||||
bool checkPartyStatus(bool handleDeath);
|
||||
|
||||
bool _runFlag;
|
||||
//int _runLoopUnk2;
|
||||
@ -334,6 +334,7 @@ protected:
|
||||
void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
|
||||
void deleteCharEventTimer(int charIndex, int evnt);
|
||||
void setupCharacterTimers();
|
||||
void manualAdvanceTimer(int sysTimer, uint32 millis);
|
||||
|
||||
void timerProcessMonsters(int timerNum);
|
||||
void timerSpecialCharacterUpdate(int timerNum);
|
||||
@ -349,6 +350,8 @@ protected:
|
||||
static const uint8 _clock2Timers[];
|
||||
static const uint8 _numClock2Timers;
|
||||
|
||||
int32 _restPartyElapsedTime;
|
||||
|
||||
// Mouse
|
||||
void setHandItem(Item itemIndex);
|
||||
|
||||
@ -369,7 +372,7 @@ protected:
|
||||
int getCharacterLevelIndex(int type, int cClass);
|
||||
|
||||
int countCharactersWithSpecificItems(int16 itemType, int16 itemValue);
|
||||
int checkCharacterInventoryForItem(int character, int16 itemType, int16 itemValue);
|
||||
int checkInventoryForItem(int character, int16 itemType, int16 itemValue);
|
||||
void modifyCharacterHitpoints(int character, int16 points);
|
||||
void neutralizePoison(int character);
|
||||
|
||||
@ -471,6 +474,7 @@ protected:
|
||||
void placeMonster(EobMonsterInPlay *m, uint16 block, int dir);
|
||||
virtual void replaceMonster(int b, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) = 0;
|
||||
void killMonster(EobMonsterInPlay *m, bool giveExperience);
|
||||
virtual bool killMonsterExtra(EobMonsterInPlay *m);
|
||||
int countSpecificMonsters(int type);
|
||||
void updateAttackingMonsterFlags();
|
||||
|
||||
@ -533,7 +537,7 @@ protected:
|
||||
const uint8 *_monsterProximityTable;
|
||||
const uint8 *_findBlockMonstersTable;
|
||||
const char *const *_monsterDustStrings;
|
||||
|
||||
|
||||
const uint8 *_monsterDistAttType10;
|
||||
const uint8 *_monsterDistAttSfx10;
|
||||
const uint8 *_monsterDistAttType17;
|
||||
@ -766,12 +770,19 @@ protected:
|
||||
const char *const *_cancelStrings;
|
||||
const char *const *_abortStrings;
|
||||
|
||||
// Rest party
|
||||
void restParty_displayWarning(const char *str);
|
||||
bool restParty_updateMonsters();
|
||||
int restParty_getCharacterWithLowestHp();
|
||||
bool restParty_checkHealSpells(int charIndex);
|
||||
bool restParty_checkSpellsToLearn();
|
||||
virtual void restParty_npc();
|
||||
virtual bool restParty_extraAbortCondition();
|
||||
|
||||
// misc
|
||||
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
|
||||
void displayParchment(int id);
|
||||
|
||||
bool restParty();
|
||||
void displayRestWarning(const char *str);
|
||||
virtual void checkPartyStatusExtra() {}
|
||||
|
||||
virtual void drawLightningColumn() {}
|
||||
virtual int resurrectionSelectDialogue() { return -1; }
|
||||
@ -843,7 +854,7 @@ protected:
|
||||
void sparkEffectDefensive(int charIndex);
|
||||
void sparkEffectOffensive();
|
||||
void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
|
||||
void cleanupCharacterSpellList(int charIndex);
|
||||
void sortCharacterSpellList(int charIndex);
|
||||
|
||||
bool magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "kyra/eobcommon.h"
|
||||
#include "kyra/gui_eob.h"
|
||||
#include "kyra/script_eob.h"
|
||||
#include "kyra/text_eob.h"
|
||||
#include "kyra/timer.h"
|
||||
#include "kyra/util.h"
|
||||
@ -508,7 +509,7 @@ void EobCoreEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32
|
||||
}
|
||||
|
||||
void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
|
||||
uint8 boxColor = ((_partyEffectFlags & 0x20000) | (_partyEffectFlags & 0xffff)) ? 4 : 6;
|
||||
uint8 redGreenColor = (_partyEffectFlags & 0x20000) ? 4 : 6;
|
||||
|
||||
static const uint8 xCoords[] = { 8, 80 };
|
||||
static const uint8 yCoords[] = { 2, 54, 106 };
|
||||
@ -520,18 +521,16 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
|
||||
|
||||
EobCharacter *c = &_characters[index];
|
||||
|
||||
int v8 = (_flags.gameID == GI_EOB2 && ((c->effectFlags & 0x4818) || c->effectsRemainder[0] || c->effectsRemainder[1] || ((_partyEffectFlags & 0x20000) | (_partyEffectFlags & 0xffff)))) ||
|
||||
(_flags.gameID == GI_EOB1 && ((c->effectFlags & 0x302) || c->effectsRemainder[0] || c->effectsRemainder[1])) ? 1 : 0;
|
||||
int vA = (_flags.gameID == GI_EOB2 && ((((c->effectFlags & 0x3000) | (c->effectFlags & 0x10000)) || (_partyEffectFlags & 0x8420)))) ||
|
||||
(_flags.gameID == GI_EOB1 && ((c->effectFlags & 0x4c8) || _partyEffectFlags & 300000))? 1 : 0;
|
||||
bool redGreen = ((c->effectFlags & 0x4818) || (_partyEffectFlags & 0x20000) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
|
||||
bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
|
||||
|
||||
if (v8 || vA) {
|
||||
if (v8 && !vA) {
|
||||
_screen->drawBox(x, y, x + 63, y + 49, boxColor);
|
||||
if (redGreen || yellow) {
|
||||
if (redGreen && !yellow) {
|
||||
_screen->drawBox(x, y, x + 63, y + 49, redGreenColor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vA && !v8) {
|
||||
if (yellow && !redGreen) {
|
||||
_screen->drawBox(x, y, x + 63, y + 49, 5);
|
||||
return;
|
||||
}
|
||||
@ -541,11 +540,11 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
|
||||
|
||||
for (int i = 0; i < 64; i += 16) {
|
||||
x = iX + i;
|
||||
if (v8) {
|
||||
_screen->drawClippedLine(x, y, x + 7, y, boxColor);
|
||||
_screen->drawClippedLine(x + 8, y + 49, x + 15, y + 49, boxColor);
|
||||
if (redGreen) {
|
||||
_screen->drawClippedLine(x, y, x + 7, y, redGreenColor);
|
||||
_screen->drawClippedLine(x + 8, y + 49, x + 15, y + 49, redGreenColor);
|
||||
}
|
||||
if (vA) {
|
||||
if (yellow) {
|
||||
_screen->drawClippedLine(x + 8, y, x + 15, y, 5);
|
||||
_screen->drawClippedLine(x, y + 49, x + 7, y + 49, 5);
|
||||
}
|
||||
@ -556,13 +555,13 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
|
||||
for (int i = 1; i < 48; i += 12) {
|
||||
y = iY + i - 1;
|
||||
|
||||
if (vA) {
|
||||
if (yellow) {
|
||||
_screen->drawClippedLine(x, y + 1, x, y + 6, 5);
|
||||
_screen->drawClippedLine(x + 63, y + 7, x + 63, y + 12, 5);
|
||||
}
|
||||
if (v8) {
|
||||
_screen->drawClippedLine(x, y + 7, x, y + 12, boxColor);
|
||||
_screen->drawClippedLine(x + 63, y + 1, x + 63, y + 6, boxColor);
|
||||
if (redGreen) {
|
||||
_screen->drawClippedLine(x, y + 7, x, y + 12, redGreenColor);
|
||||
_screen->drawClippedLine(x + 63, y + 1, x + 63, y + 6, redGreenColor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -859,7 +858,7 @@ int EobCoreEngine::clickedCamp(Button *button) {
|
||||
drawScene(0);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
cleanupCharacterSpellList(i);
|
||||
sortCharacterSpellList(i);
|
||||
|
||||
_screen->setCurPage(0);
|
||||
const ScreenDim *dm = _screen->getScreenDim(10);
|
||||
@ -867,8 +866,11 @@ int EobCoreEngine::clickedCamp(Button *button) {
|
||||
|
||||
_screen->updateScreen();
|
||||
|
||||
enableSysTimer(2);
|
||||
updateCharacterEvents(true);
|
||||
enableSysTimer(2);
|
||||
manualAdvanceTimer(2, _restPartyElapsedTime);
|
||||
_restPartyElapsedTime = 0;
|
||||
|
||||
checkPartyStatus(true);
|
||||
|
||||
return button->arg;
|
||||
}
|
||||
@ -2174,11 +2176,12 @@ void GUI_Eob::runCampMenu() {
|
||||
|
||||
switch (inputFlag) {
|
||||
case 0x8001:
|
||||
if (_vm->restParty())
|
||||
if (restParty())
|
||||
runLoop = false;
|
||||
else
|
||||
_needRest = false;
|
||||
redrawPortraits = true;
|
||||
newMenu = 0;
|
||||
break;
|
||||
|
||||
case 0x8002:
|
||||
@ -2286,7 +2289,7 @@ void GUI_Eob::runCampMenu() {
|
||||
if (_charSelectRedraw || redrawPortraits) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
_vm->gui_drawCharPortraitWithStats(i);
|
||||
_vm->cleanupCharacterSpellList(i);
|
||||
_vm->sortCharacterSpellList(i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2334,6 +2337,74 @@ bool GUI_Eob::runLoadMenu(int x, int y) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
|
||||
int od = _screen->curDimIndex();
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
|
||||
_screen->setScreenDim(dim);
|
||||
|
||||
drawTextBox(dim, id);
|
||||
|
||||
int16 x[2];
|
||||
x[0] = (_screen->_curDim->sx << 3) + 8;
|
||||
x[1] = (_screen->_curDim->sx + _screen->_curDim->w - 5) << 3;
|
||||
int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21;
|
||||
int newHighlight = deflt ^ 1;
|
||||
int lastHighlight = -1;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
drawMenuButtonBox(x[i], y, 32, 14, false, false);
|
||||
|
||||
for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
|
||||
Common::Point p = _vm->getMousePos();
|
||||
if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14))
|
||||
newHighlight = 0;
|
||||
else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14))
|
||||
newHighlight = 1;
|
||||
|
||||
int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
|
||||
_vm->removeInputTop();
|
||||
|
||||
if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
|
||||
runLoop = false;
|
||||
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6]) {
|
||||
newHighlight ^= 1;
|
||||
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_n]) {
|
||||
newHighlight = 1;
|
||||
runLoop = false;
|
||||
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_y]) {
|
||||
newHighlight = 0;
|
||||
runLoop = false;
|
||||
} else if (inputFlag == 199 || inputFlag == 201) {
|
||||
if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14)) {
|
||||
newHighlight = 0;
|
||||
runLoop = false;
|
||||
} else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14)) {
|
||||
newHighlight = 1;
|
||||
runLoop = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (newHighlight != lastHighlight) {
|
||||
for (int i = 0; i < 2; i++)
|
||||
_screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0);
|
||||
_screen->updateScreen();
|
||||
lastHighlight = newHighlight;
|
||||
}
|
||||
}
|
||||
|
||||
drawMenuButtonBox(x[newHighlight], y, 32, 14, true, true);
|
||||
_screen->updateScreen();
|
||||
_vm->_system->delayMillis(80);
|
||||
drawMenuButtonBox(x[newHighlight], y, 32, 14, false, true);
|
||||
_screen->updateScreen();
|
||||
|
||||
_screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
|
||||
_screen->setFont(of);
|
||||
_screen->setScreenDim(od);
|
||||
|
||||
return newHighlight ? false : true;
|
||||
}
|
||||
|
||||
void GUI_Eob::updateBoxFrameHighLight(int box) {
|
||||
static const uint8 colorTable[] = { 0x0F, 0xB0, 0xB2, 0xB4, 0xB6,
|
||||
0xB8, 0xBA, 0xBC, 0x0C, 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0x00
|
||||
@ -2686,7 +2757,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
|
||||
for (int i = 0; i < _numPages; i++)
|
||||
np[i] = _vm->_numSpellsMage[lv * _numPages + i];
|
||||
|
||||
avltyFlags = c->mageSpellsAvailabilityFlags;
|
||||
avltyFlags = c->mageSpellsAvailableFlags;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2916,7 +2987,7 @@ void GUI_Eob::scribeScrollDialogue() {
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
for (int ii = 0; ii < 6; ii++) {
|
||||
scrollInvSlot[i] = _vm->checkCharacterInventoryForItem(ii, 34, i + 1) + 1;
|
||||
scrollInvSlot[i] = _vm->checkInventoryForItem(ii, 34, i + 1) + 1;
|
||||
if (scrollInvSlot[i] > 0) {
|
||||
numScrolls++;
|
||||
scrollCharacter[i] = ii;
|
||||
@ -2936,7 +3007,7 @@ void GUI_Eob::scribeScrollDialogue() {
|
||||
if (!scrollInvSlot[i])
|
||||
continue;
|
||||
|
||||
if (c->mageSpellsAvailabilityFlags & (1 << i))
|
||||
if (c->mageSpellsAvailableFlags & (1 << i))
|
||||
scrollInvSlot[i] = 0;
|
||||
else
|
||||
menuItems[s++] = i + 1;
|
||||
@ -3005,7 +3076,7 @@ void GUI_Eob::scribeScrollDialogue() {
|
||||
if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP5]) {
|
||||
int t = menuItems[newHighLight] - 1;
|
||||
Item scItem = _vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1];
|
||||
c->mageSpellsAvailabilityFlags |= (1 << t);
|
||||
c->mageSpellsAvailableFlags |= (1 << t);
|
||||
_vm->_characters[scrollCharacter[t]].inventory[scrollInvSlot[t] - 1] = 0;
|
||||
_vm->gui_drawCharPortraitWithStats(_vm->_characters[scrollCharacter[t]].id);
|
||||
scrollInvSlot[t] = 0;
|
||||
@ -3030,6 +3101,284 @@ void GUI_Eob::scribeScrollDialogue() {
|
||||
delete[] scrollInvSlot;
|
||||
}
|
||||
|
||||
bool GUI_Eob::restParty() {
|
||||
static const int8 eob1healSpells[] = { 2, 15, 20, 24 };
|
||||
static const int8 eob2healSpells[] = { 3, 16, 20, 28 };
|
||||
const int8 *spells = _vm->game() == GI_EOB1 ? eob1healSpells : eob2healSpells;
|
||||
|
||||
uint8 crs[6];
|
||||
memset(crs, 0, 6);
|
||||
int hours = 0;
|
||||
|
||||
if (_vm->_inf->preventRest()) {
|
||||
assert(_vm->_menuStringsRest3[0]);
|
||||
_vm->restParty_displayWarning(_vm->_menuStringsRest3[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_vm->restParty_updateMonsters())
|
||||
return true;
|
||||
|
||||
if (_vm->restParty_extraAbortCondition())
|
||||
return true;
|
||||
|
||||
drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
|
||||
|
||||
int nonPoisoned = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!_vm->testCharacter(i, 1))
|
||||
continue;
|
||||
nonPoisoned |= _vm->testCharacter(i, 0x10);
|
||||
}
|
||||
|
||||
if (!nonPoisoned) {
|
||||
if (!confirmDialogue(59))
|
||||
return false;
|
||||
}
|
||||
|
||||
int8 *list = 0;
|
||||
bool useHealers = false;
|
||||
bool res = false;
|
||||
bool restLoop = true;
|
||||
bool restContinue = false;
|
||||
int injured = _vm->restParty_getCharacterWithLowestHp();
|
||||
|
||||
if (injured > 0) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!_vm->testCharacter(i, 13))
|
||||
continue;
|
||||
if (_vm->getCharacterLevelIndex(2, _vm->_characters[i].cClass) == -1 && _vm->getCharacterLevelIndex(4, _vm->_characters[i].cClass) == -1)
|
||||
continue;
|
||||
if (_vm->checkInventoryForItem(i, 30, -1) == -1)
|
||||
continue;
|
||||
if (_vm->restParty_checkHealSpells(i))
|
||||
useHealers = confirmDialogue(40);
|
||||
}
|
||||
}
|
||||
|
||||
_screen->setClearScreenDim(7);
|
||||
_screen->setFont(Screen::FID_6_FNT);
|
||||
|
||||
restParty_updateRestTime(hours, true);
|
||||
|
||||
for (int l = 0; !res && restLoop && !_vm->shouldQuit(); ) {
|
||||
l++;
|
||||
|
||||
// Regenerate spells
|
||||
for (int i = 0; i < 6; i++) {
|
||||
crs[i]++;
|
||||
|
||||
if (!_vm->_characters[i].food)
|
||||
continue;
|
||||
if (!_vm->testCharacter(i, 5))
|
||||
continue;
|
||||
|
||||
if (_vm->checkInventoryForItem(i, 30, -1) != -1) {
|
||||
list = _vm->_characters[i].clericSpells;
|
||||
|
||||
for (int ii = 0; ii < 80; ii++) {
|
||||
if ((ii / 10 + 48) >= crs[i])
|
||||
break;
|
||||
|
||||
if (*list >= 0) {
|
||||
list++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*list *= -1;
|
||||
crs[i] = 48;
|
||||
_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_mageSpellListSize + *list].name).c_str());
|
||||
_vm->delay(80);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_vm->checkInventoryForItem(i, 29, -1) != -1) {
|
||||
list = _vm->_characters[i].mageSpells;
|
||||
|
||||
for (int ii = 0; ii < 80; ii++) {
|
||||
if ((ii / 6 + 48) >= crs[i])
|
||||
break;
|
||||
|
||||
if (*list >= 0) {
|
||||
list++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*list *= -1;
|
||||
crs[i] = 48;
|
||||
_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[1], _vm->_characters[i].name, _vm->_spells[*list].name).c_str());
|
||||
_vm->delay(80);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Heal party members
|
||||
if (useHealers) {
|
||||
for (int i = 0; i < 6 && injured; i++) {
|
||||
if (_vm->getCharacterLevelIndex(2, _vm->_characters[i].cClass) == -1 && _vm->getCharacterLevelIndex(4, _vm->_characters[i].cClass) == -1)
|
||||
continue;
|
||||
if (_vm->checkInventoryForItem(i, 30, -1) == -1)
|
||||
continue;
|
||||
|
||||
list = 0;
|
||||
if (crs[i] >= 48) {
|
||||
for (int ii = 0; !list && ii < 3; ii++)
|
||||
list = (int8*)memchr(_vm->_characters[i].clericSpells, -spells[ii], 80);
|
||||
}
|
||||
|
||||
if (list)
|
||||
break;
|
||||
|
||||
list = _vm->_characters[i].clericSpells;
|
||||
for (int ii = 0; ii < 80 && injured; ii++) {
|
||||
int healHp = 0;
|
||||
if (*list == spells[0])
|
||||
healHp = _vm->rollDice(1, 8, 0);
|
||||
else if (*list == spells[1])
|
||||
healHp = _vm->rollDice(2, 8, 1);
|
||||
else if (*list == spells[2])
|
||||
healHp = _vm->rollDice(3, 8, 3);
|
||||
|
||||
if (!healHp) {
|
||||
list++;
|
||||
continue;
|
||||
}
|
||||
|
||||
*list *= -1;
|
||||
list++;
|
||||
|
||||
crs[i] = 0;
|
||||
injured--;
|
||||
|
||||
_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[2], _vm->_characters[i].name, _vm->_characters[injured].name).c_str());
|
||||
_vm->delay(80);
|
||||
|
||||
_vm->_characters[injured].hitPointsCur += healHp;
|
||||
if (_vm->_characters[injured].hitPointsCur > _vm->_characters[injured].hitPointsMax)
|
||||
_vm->_characters[injured].hitPointsCur = _vm->_characters[injured].hitPointsMax;
|
||||
|
||||
_vm->gui_drawCharPortraitWithStats(injured++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (l == 6) {
|
||||
l = 0;
|
||||
restParty_updateRestTime(++hours, false);
|
||||
_vm->_restPartyElapsedTime += (32760 * _vm->_tickLength);
|
||||
|
||||
// Update poisoning
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!_vm->testCharacter(i, 1))
|
||||
continue;
|
||||
if (_vm->testCharacter(i, 16))
|
||||
continue;
|
||||
_vm->inflictCharacterDamage(i, 10);
|
||||
_vm->delayWithTicks(5);
|
||||
}
|
||||
|
||||
if (!(hours % 8)) {
|
||||
bool starving = false;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
// Add Lay On Hands spell
|
||||
if (_vm->_characters[i].cClass == 2) {
|
||||
list = (int8*)memchr(_vm->_characters[i].clericSpells, spells[3], 10);
|
||||
if (list) {
|
||||
*list = spells[3];
|
||||
} else {
|
||||
list = (int8*)memchr(_vm->_characters[i].clericSpells, -spells[3], 10);
|
||||
if (list) {
|
||||
*list = spells[3];
|
||||
} else if (!memchr(_vm->_characters[i].clericSpells, spells[3], 10)) {
|
||||
list = (int8*)memchr(_vm->_characters[i].clericSpells, 0, 10);
|
||||
*list = spells[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_vm->testCharacter(i, 3))
|
||||
continue;
|
||||
|
||||
// Update hitpoints and food status
|
||||
if (_vm->_characters[i].food) {
|
||||
if (_vm->_characters[i].hitPointsCur < _vm->_characters[i].hitPointsMax) {
|
||||
_vm->_characters[i].hitPointsCur++;
|
||||
_screen->setFont(Screen::FID_6_FNT);
|
||||
_vm->gui_drawCharPortraitWithStats(i);
|
||||
}
|
||||
|
||||
if (!_vm->checkInventoryForRings(i, 2)) {
|
||||
if (_vm->_characters[i].food <= 5) {
|
||||
_vm->_characters[i].food = 0;
|
||||
starving = true;
|
||||
} else {
|
||||
_vm->_characters[i].food -= 5;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((hours % 24) || (_vm->_characters[i].hitPointsCur <= -10))
|
||||
continue;
|
||||
_vm->inflictCharacterDamage(i, 1);
|
||||
starving = true;
|
||||
_screen->setFont(Screen::FID_6_FNT);
|
||||
_vm->gui_drawCharPortraitWithStats(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (starving) {
|
||||
if (!confirmDialogue(47)) {
|
||||
restContinue = false;
|
||||
restLoop = false;
|
||||
}
|
||||
restParty_updateRestTime(hours, true);
|
||||
}
|
||||
injured = restLoop ? _vm->restParty_getCharacterWithLowestHp() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_vm->restParty_checkSpellsToLearn() && restLoop && !restContinue && injured) {
|
||||
restContinue = confirmDialogue(41);
|
||||
restParty_updateRestTime(hours, true);
|
||||
if (!restContinue)
|
||||
restLoop = false;
|
||||
}
|
||||
|
||||
int in = _vm->checkInput(0, false, 0);
|
||||
_vm->removeInputTop();
|
||||
if (in)
|
||||
restLoop = false;
|
||||
|
||||
if (restLoop) {
|
||||
res = _vm->restParty_updateMonsters();
|
||||
if (!res)
|
||||
res = _vm->checkPartyStatus(false);
|
||||
}
|
||||
|
||||
if (!_vm->restParty_checkSpellsToLearn()) {
|
||||
if (!restContinue) {
|
||||
if (!useHealers)
|
||||
restLoop = false;
|
||||
}
|
||||
if (!injured)
|
||||
restLoop = false;
|
||||
}
|
||||
}
|
||||
|
||||
_vm->removeInputTop();
|
||||
_screen->setScreenDim(4);
|
||||
_screen->setFont(Screen::FID_8_FNT);
|
||||
|
||||
if (!injured && !res)
|
||||
displayTextBox(43);
|
||||
|
||||
if (res && hours > 4)
|
||||
_vm->restParty_npc();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool GUI_Eob::confirmDialogue(int id) {
|
||||
int od = _screen->curDimIndex();
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
|
||||
@ -3092,74 +3441,6 @@ bool GUI_Eob::confirmDialogue(int id) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
|
||||
int od = _screen->curDimIndex();
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
|
||||
_screen->setScreenDim(dim);
|
||||
|
||||
drawTextBox(dim, id);
|
||||
|
||||
int16 x[2];
|
||||
x[0] = (_screen->_curDim->sx << 3) + 8;
|
||||
x[1] = (_screen->_curDim->sx + _screen->_curDim->w - 5) << 3;
|
||||
int16 y = _screen->_curDim->sy + _screen->_curDim->h - 21;
|
||||
int newHighlight = deflt ^ 1;
|
||||
int lastHighlight = -1;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
drawMenuButtonBox(x[i], y, 32, 14, false, false);
|
||||
|
||||
for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
|
||||
Common::Point p = _vm->getMousePos();
|
||||
if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14))
|
||||
newHighlight = 0;
|
||||
else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14))
|
||||
newHighlight = 1;
|
||||
|
||||
int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
|
||||
_vm->removeInputTop();
|
||||
|
||||
if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) {
|
||||
runLoop = false;
|
||||
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_LEFT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP4] || inputFlag == _vm->_keyMap[Common::KEYCODE_RIGHT] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP6]) {
|
||||
newHighlight ^= 1;
|
||||
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_n]) {
|
||||
newHighlight = 1;
|
||||
runLoop = false;
|
||||
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_y]) {
|
||||
newHighlight = 0;
|
||||
runLoop = false;
|
||||
} else if (inputFlag == 199 || inputFlag == 201) {
|
||||
if (_vm->posWithinRect(p.x, p.y, x[0], y, x[0] + 32, y + 14)) {
|
||||
newHighlight = 0;
|
||||
runLoop = false;
|
||||
} else if (_vm->posWithinRect(p.x, p.y, x[1], y, x[1] + 32, y + 14)) {
|
||||
newHighlight = 1;
|
||||
runLoop = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (newHighlight != lastHighlight) {
|
||||
for (int i = 0; i < 2; i++)
|
||||
_screen->printShadedText(_vm->_menuYesNoStrings[i], x[i] + 16 - (strlen(_vm->_menuYesNoStrings[i]) << 2) + 1, y + 3, i == newHighlight ? 6 : 15, 0);
|
||||
_screen->updateScreen();
|
||||
lastHighlight = newHighlight;
|
||||
}
|
||||
}
|
||||
|
||||
drawMenuButtonBox(x[newHighlight], y, 32, 14, true, true);
|
||||
_screen->updateScreen();
|
||||
_vm->_system->delayMillis(80);
|
||||
drawMenuButtonBox(x[newHighlight], y, 32, 14, false, true);
|
||||
_screen->updateScreen();
|
||||
|
||||
_screen->copyRegion(0, _screen->_curDim->h, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
|
||||
_screen->setFont(of);
|
||||
_screen->setScreenDim(od);
|
||||
|
||||
return newHighlight ? false : true;
|
||||
}
|
||||
|
||||
void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
|
||||
static const char buttonText[] = "OK";
|
||||
|
||||
@ -3338,7 +3619,7 @@ int GUI_Eob::selectCharacterDialogue(int id) {
|
||||
result = -1;
|
||||
}
|
||||
} else {
|
||||
if (_vm->checkCharacterInventoryForItem(result, 29, -1) == -1) {
|
||||
if (_vm->checkInventoryForItem(result, 29, -1) == -1) {
|
||||
displayTextBox(25);
|
||||
result = -1;
|
||||
}
|
||||
@ -3635,6 +3916,31 @@ int GUI_Eob::getHighlightSlot() {
|
||||
return res;
|
||||
}
|
||||
|
||||
void GUI_Eob::restParty_updateRestTime(int hours, bool init) {
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
|
||||
int od = _screen->curDimIndex();
|
||||
_screen->setScreenDim(10);
|
||||
|
||||
if (init) {
|
||||
_screen->setCurPage(0);
|
||||
_vm->_txt->clearCurDim();
|
||||
drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
|
||||
_screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 0, 2, Screen::CR_NO_P_CHECK);
|
||||
_screen->printShadedText(getMenuString(42), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 5, 9, 0);
|
||||
}
|
||||
|
||||
_screen->setCurPage(2);
|
||||
_screen->printShadedText(Common::String::format(_vm->_menuStringsRest2[3], hours).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy + 20, 15, _vm->_bkgColor_1);
|
||||
_screen->setCurPage(0);
|
||||
_screen->copyRegion(((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, ((_screen->_curDim->sx + 1) << 3) - 1, _screen->_curDim->sy + 20, 144, 8, 2, 0, Screen::CR_NO_P_CHECK);
|
||||
_screen->updateScreen();
|
||||
|
||||
_vm->delay(160);
|
||||
|
||||
_screen->setScreenDim(od);
|
||||
_screen->setFont(of);
|
||||
}
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
@ -62,6 +62,7 @@ public:
|
||||
void runCampMenu();
|
||||
bool runLoadMenu(int x, int y);
|
||||
|
||||
bool confirmDialogue2(int dim, int id, int deflt);
|
||||
void updateBoxFrameHighLight(int box);
|
||||
|
||||
int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
|
||||
@ -78,9 +79,9 @@ private:
|
||||
int selectSaveSlotDialogue(int x, int y, int id);
|
||||
void runMemorizePrayMenu(int charIndex, int spellType);
|
||||
void scribeScrollDialogue();
|
||||
bool restParty();
|
||||
|
||||
bool confirmDialogue(int id);
|
||||
bool confirmDialogue2(int dim, int id, int deflt);
|
||||
void messageDialogue(int dim, int id, int buttonTextCol);
|
||||
int selectCharacterDialogue(int id);
|
||||
void displayTextBox(int id);
|
||||
@ -100,6 +101,8 @@ private:
|
||||
void setupSaveMenuSlots();
|
||||
int getHighlightSlot();
|
||||
|
||||
void restParty_updateRestTime(int hours, bool init);
|
||||
|
||||
Button _scrollUpButton;//////////////////77
|
||||
Button _scrollDownButton;
|
||||
|
||||
|
@ -221,7 +221,7 @@ void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
|
||||
continue;
|
||||
|
||||
EobCharacter *c = &_characters[i];
|
||||
int slot = checkCharacterInventoryForItem(i, itemType, itemValue);
|
||||
int slot = checkInventoryForItem(i, itemType, itemValue);
|
||||
|
||||
if (slot == -1)
|
||||
continue;
|
||||
|
@ -235,7 +235,7 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
|
||||
if (showWarning) {
|
||||
if (s->flags & 0x20A0)
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
else if (s->flags & 0x20A0)
|
||||
else if (s->flags & 0x40)
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
}
|
||||
}
|
||||
@ -416,8 +416,40 @@ void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timer
|
||||
setCharEventTimer(_activeSpellCaster, countdown, -spell, updateExistingTimer);
|
||||
}
|
||||
|
||||
void EobCoreEngine::cleanupCharacterSpellList(int charIndex) {
|
||||
void EobCoreEngine::sortCharacterSpellList(int charIndex) {
|
||||
int8 *list = _characters[charIndex].mageSpells;
|
||||
|
||||
for (int i = 0; i < 16; ) {
|
||||
bool p = false;
|
||||
for (int ii = 0; ii < 9; ii++) {
|
||||
int8 *pos = &list[ii];
|
||||
|
||||
int s1 = pos[0];
|
||||
int s2 = pos[1];
|
||||
|
||||
if (s1 == 0)
|
||||
s1 = 80;
|
||||
else if (s1 < 0)
|
||||
s1 = s1 * -1 + 40;
|
||||
|
||||
if (s2 == 0)
|
||||
s2 = 80;
|
||||
else if (s2 < 0)
|
||||
s2 = s2 * -1 + 40;
|
||||
|
||||
if (s1 > s2) {
|
||||
SWAP(pos[0], pos[1]);
|
||||
p = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (p)
|
||||
continue;
|
||||
|
||||
list += 10;
|
||||
if (++i == 8)
|
||||
list = _characters[charIndex].clericSpells;
|
||||
}
|
||||
}
|
||||
|
||||
bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
|
||||
@ -685,7 +717,7 @@ void EobCoreEngine::spellCallback_start_createFood() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!testCharacter(i, 3))
|
||||
continue;
|
||||
_characters[_activeSpellCaster].food = 100;
|
||||
_characters[i].food = 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,6 +546,8 @@ enum KyraResources {
|
||||
kEob2Npc2Strings,
|
||||
kEob2MonsterDustStrings,
|
||||
|
||||
kEob2DranFoolsStrings,
|
||||
|
||||
kLolIngamePakFiles,
|
||||
kLolCharacterDefs,
|
||||
kLolIngameSfxFiles,
|
||||
|
@ -185,7 +185,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
|
||||
c->faceShape = 0;
|
||||
in.read(c->mageSpells, 80);
|
||||
in.read(c->clericSpells, 80);
|
||||
c->mageSpellsAvailabilityFlags = in.readUint32BE();
|
||||
c->mageSpellsAvailableFlags = in.readUint32BE();
|
||||
for (int ii = 0; ii < 27; ii++)
|
||||
c->inventory[ii] = in.readSint16BE();
|
||||
uint32 ct = _system->getMillis();
|
||||
@ -427,7 +427,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
|
||||
out->writeUint32BE(c->experience[ii]);
|
||||
out->write(c->mageSpells, 80);
|
||||
out->write(c->clericSpells, 80);
|
||||
out->writeUint32BE(c->mageSpellsAvailabilityFlags);
|
||||
out->writeUint32BE(c->mageSpellsAvailableFlags);
|
||||
for (int ii = 0; ii < 27; ii++)
|
||||
out->writeSint16BE(c->inventory[ii]);
|
||||
uint32 ct = _system->getMillis();
|
||||
|
@ -1271,6 +1271,79 @@ void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim
|
||||
}
|
||||
}
|
||||
|
||||
void DarkMoonEngine::seq_nightmare() {
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
|
||||
_screen->copyRegion(0, 0, 0, 120, 176, 24, 14, 2, Screen::CR_NO_P_CHECK);
|
||||
|
||||
initDialogueSequence();
|
||||
gui_drawDialogueBox();
|
||||
|
||||
_txt->printDialogueText(99, 0);
|
||||
snd_playSoundEffect(54);
|
||||
|
||||
static const int8 dreamSteps[] = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 3, 2, 1, 0, -1 };
|
||||
static const uint8 seqX[] = { 0, 20, 0, 20 };
|
||||
static const uint8 seqY[] = { 0, 0, 96, 96 };
|
||||
static const uint8 seqDelay[] = { 12, 7, 7, 12 };
|
||||
|
||||
for (const int8 *i = dreamSteps; *i != -1; ++i) {
|
||||
drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
|
||||
delay(seqDelay[*i] * _tickLength);
|
||||
}
|
||||
|
||||
_txt->printDialogueText(20, _okStrings[0]);
|
||||
|
||||
restoreAfterDialogueSequence();
|
||||
|
||||
_screen->setFont(of);
|
||||
}
|
||||
|
||||
void DarkMoonEngine::seq_dranFools() {
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
|
||||
|
||||
initDialogueSequence();
|
||||
gui_drawDialogueBox();
|
||||
|
||||
static const char file[] = "KHELDRAN";
|
||||
_txt->printDialogueText(_dranFoolsStrings[0]);
|
||||
drawSequenceBitmap(file, 0, 0, 0, 0);
|
||||
_txt->printDialogueText(20, _moreStrings[0]);
|
||||
snd_playSoundEffect(56);
|
||||
drawSequenceBitmap(file, 0, 20, 0, 0);
|
||||
delay(10 * _tickLength);
|
||||
drawSequenceBitmap(file, 0, 0, 96, 0);
|
||||
delay(10 * _tickLength);
|
||||
drawSequenceBitmap(file, 0, 20, 96, 0);
|
||||
delay(7 * _tickLength);
|
||||
_txt->printDialogueText(76, _okStrings[0]);
|
||||
|
||||
restoreAfterDialogueSequence();
|
||||
|
||||
_screen->setFont(of);
|
||||
}
|
||||
|
||||
void DarkMoonEngine::seq_dranDragonTransformation() {
|
||||
Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
|
||||
|
||||
initDialogueSequence();
|
||||
gui_drawDialogueBox();
|
||||
|
||||
static const char file[] = "DRANX";
|
||||
drawSequenceBitmap(file, 0, 0, 0, 0);
|
||||
_txt->printDialogueText(120, _moreStrings[0]);
|
||||
snd_playSoundEffect(56);
|
||||
drawSequenceBitmap(file, 0, 20, 0, 0);
|
||||
delay(7 * _tickLength);
|
||||
drawSequenceBitmap(file, 0, 0, 96, 0);
|
||||
delay(7 * _tickLength);
|
||||
drawSequenceBitmap(file, 0, 20, 96, 0);
|
||||
delay(18 * _tickLength);
|
||||
|
||||
restoreAfterDialogueSequence();
|
||||
|
||||
_screen->setFont(of);
|
||||
}
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
||||
#endif // ENABLE_EOB
|
||||
|
@ -224,20 +224,7 @@ void EobCoreEngine::killMonster(EobMonsterInPlay *m, bool giveExperience) {
|
||||
if (giveExperience)
|
||||
increasePartyExperience(_monsterProps[m->type].experience);
|
||||
|
||||
if ((_flags.gameID == GI_EOB2) && (_currentLevel == 16) && (_currentSub == 1) && (_monsterProps[m->type].flags & 4)) {
|
||||
if (m->type) {
|
||||
_playFinale = true;
|
||||
_runFlag = false;
|
||||
} else {
|
||||
m->hitPointsCur = 150;
|
||||
m->curRemoteWeapon = 0;
|
||||
m->numRemoteAttacks = 255;
|
||||
m->shpIndex++;
|
||||
m->type++;
|
||||
//// TODO
|
||||
// dranDragonTransformation();
|
||||
}
|
||||
} else {
|
||||
if (killMonsterExtra(m)) {
|
||||
placeMonster(m, 0, -1);
|
||||
|
||||
if ((_flags.gameID == GI_EOB1) && (m->type == 21)) {
|
||||
@ -250,6 +237,10 @@ void EobCoreEngine::killMonster(EobMonsterInPlay *m, bool giveExperience) {
|
||||
}
|
||||
}
|
||||
|
||||
bool EobCoreEngine::killMonsterExtra(EobMonsterInPlay*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int EobCoreEngine::countSpecificMonsters(int type) {
|
||||
int res = 0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
|
@ -157,7 +157,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p
|
||||
s->experience[0] = stream.readUint32BE();
|
||||
s->experience[1] = stream.readUint32BE();
|
||||
s->experience[2] = stream.readUint32BE();
|
||||
s->mageSpellsAvailabilityFlags = stream.readUint32BE();
|
||||
s->mageSpellsAvailableFlags = stream.readUint32BE();
|
||||
for (int ii = 0; ii < 27; ii++)
|
||||
s->inventory[i] = stream.readUint16BE();
|
||||
}
|
||||
@ -1184,6 +1184,7 @@ void DarkMoonEngine::initStaticResource() {
|
||||
_npc1Strings = _staticres->loadStrings(kEob2Npc1Strings, temp);
|
||||
_npc2Strings = _staticres->loadStrings(kEob2Npc2Strings, temp);
|
||||
_monsterDustStrings = _staticres->loadStrings(kEob2MonsterDustStrings, temp);
|
||||
_dranFoolsStrings = _staticres->loadStrings(kEob2DranFoolsStrings, temp);
|
||||
}
|
||||
|
||||
void DarkMoonEngine::initSpells() {
|
||||
|
@ -445,9 +445,11 @@ void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakStr
|
||||
displayText(_dialogueBuffer);
|
||||
|
||||
if (pageBreakString) {
|
||||
strcpy(_pageBreakString, pageBreakString);
|
||||
displayWaitButton();
|
||||
resetPageBreakString();
|
||||
if (pageBreakString[0]) {
|
||||
strcpy(_pageBreakString, pageBreakString);
|
||||
displayWaitButton();
|
||||
resetPageBreakString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,26 @@ void TimerManager::update() {
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::manualAdvance(uint32 millis) {
|
||||
uint32 curTime = _system->getMillis();
|
||||
for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
|
||||
if (pos->enabled == 1 && pos->countdown >= 0) {
|
||||
pos->nextRun -= curTime;
|
||||
while (pos->nextRun <= millis) {
|
||||
if (pos->func && pos->func->isValid())
|
||||
(*pos->func)(pos->id);
|
||||
|
||||
pos->lastUpdate = curTime;
|
||||
pos->nextRun = pos->countdown * _vm->tickLength();
|
||||
millis -= pos->nextRun;
|
||||
}
|
||||
pos->nextRun += curTime;
|
||||
_nextRun = MIN(_nextRun, pos->nextRun);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TimerManager::resync() {
|
||||
const uint32 curTime = _isPaused ? _pauseStart : _system->getMillis();
|
||||
|
||||
|
@ -61,6 +61,8 @@ public:
|
||||
|
||||
void update();
|
||||
|
||||
void manualAdvance(uint32 millis);
|
||||
|
||||
void resetNextRun();
|
||||
|
||||
void setCountdown(uint8 id, int32 countdown);
|
||||
|
@ -193,6 +193,23 @@ void EobCoreEngine::setupCharacterTimers() {
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::manualAdvanceTimer(int sysTimer, uint32 millis) {
|
||||
if (sysTimer != 2)
|
||||
return;
|
||||
|
||||
uint32 ct = _system->getMillis();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
if (_characters[i].timers[ii]) {
|
||||
uint32 chrt = _characters[i].timers[ii] - ct;
|
||||
_characters[i].timers[ii] = chrt > millis ? chrt - millis : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_timer->manualAdvance(millis);
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerProcessCharacterExchange(int timerNum) {
|
||||
_charExchangeSwap ^= 1;
|
||||
if (_charExchangeSwap) {
|
||||
|
Loading…
Reference in New Issue
Block a user