Skip to content

Commit

Permalink
KYRA: (EOB) - lots of bug fixes, mostly for EOB II
Browse files Browse the repository at this point in the history
  • Loading branch information
athrxx authored and Johannes Schickel committed Dec 26, 2011
1 parent f7032c1 commit c35de37
Show file tree
Hide file tree
Showing 20 changed files with 137 additions and 98 deletions.
9 changes: 6 additions & 3 deletions devtools/create_kyradat/create_kyradat.cpp
Expand Up @@ -570,7 +570,8 @@ const ExtractFilename extractFilenames[] = {
{ kEob2Npc1Strings, kTypeStringList, true },
{ kEob2Npc2Strings, kTypeStringList, true },
{ kEob2MonsterDustStrings, kTypeStringList, true },
{ kEob2DranFoolsStrings, kTypeStringList, true },
{ kEob2DreamSteps, kTypeRawData, false },
{ kEob2KheldranStrings, kTypeStringList, true },
{ kEob2HornStrings, kTypeStringList, true },
{ kEob2HornSounds, kTypeRawData, false },
{ kEob2WallOfForceDsX, kLolTypeRaw16, false },
Expand Down Expand Up @@ -1991,8 +1992,10 @@ const char *getIdString(const int id) {
return "kEob2Npc2Strings";
case kEob2MonsterDustStrings:
return "kEob2MonsterDustStrings";
case kEob2DranFoolsStrings:
return "kEob2DranFoolsStrings";
case kEob2DreamSteps:
return "kEob2DreamSteps";
case kEob2KheldranStrings:
return "kEob2KheldranStrings";
case kEob2HornStrings:
return "kEob2HornStrings";
case kEob2HornSounds:
Expand Down
3 changes: 2 additions & 1 deletion devtools/create_kyradat/create_kyradat.h
Expand Up @@ -552,7 +552,8 @@ enum kExtractID {
kEob2Npc2Strings,
kEob2MonsterDustStrings,

kEob2DranFoolsStrings,
kEob2DreamSteps,
kEob2KheldranStrings,
kEob2HornStrings,
kEob2HornSounds,

Expand Down
3 changes: 2 additions & 1 deletion devtools/create_kyradat/games.cpp
Expand Up @@ -1594,7 +1594,8 @@ const int eob2FloppyNeed[] = {
kEob2Npc1Strings,
kEob2Npc2Strings,
kEob2MonsterDustStrings,
kEob2DranFoolsStrings,
kEob2DreamSteps,
kEob2KheldranStrings,
kEob2HornStrings,
kEob2HornSounds,
kEob2WallOfForceDsX,
Expand Down
10 changes: 8 additions & 2 deletions devtools/create_kyradat/tables.cpp
Expand Up @@ -3187,7 +3187,12 @@ const ExtractEntrySearchData kEob2MonsterDustStringsProvider[] = {
EXTRACT_END_ENTRY
};

const ExtractEntrySearchData kEob2DranFoolsStringsProvider[] = {
const ExtractEntrySearchData kEob2DreamStepsProvider[] = {
{ UNK_LANG, kPlatformUnknown, { 0x0000000E, 0x00000114, { { 0x27, 0x32, 0xCB, 0x89, 0x27, 0xC5, 0xDD, 0x91, 0xBE, 0x97, 0x62, 0xF5, 0x76, 0xF7, 0xCD, 0x25 } } } },
EXTRACT_END_ENTRY
};

const ExtractEntrySearchData kEob2KheldranStringsProvider[] = {
{ 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
Expand Down Expand Up @@ -4198,7 +4203,8 @@ const ExtractEntry extractProviders[] = {
{ kEob2Npc1Strings, kEob2Npc1StringsProvider },
{ kEob2Npc2Strings, kEob2Npc2StringsProvider },
{ kEob2MonsterDustStrings, kEob2MonsterDustStringsProvider },
{ kEob2DranFoolsStrings, kEob2DranFoolsStringsProvider },
{ kEob2DreamSteps, kEob2DreamStepsProvider },
{ kEob2KheldranStrings, kEob2KheldranStringsProvider },
{ kEob2HornStrings, kEob2HornStringsProvider },
{ kEob2HornSounds, kEob2HornSoundsProvider },
{ kEob2WallOfForceDsX, kEob2WallOfForceDsXProvider },
Expand Down
Binary file modified dists/engine-data/kyra.dat
Binary file not shown.
10 changes: 5 additions & 5 deletions engines/kyra/detection.cpp
Expand Up @@ -188,7 +188,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
// In Kyra games slot 0 can't be deleted, it's for restarting the game(s).
// An exception makes Lands of Lore here, it does not have any way to restart the
// game except via its main menu.
if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol"))
if (slot == 0 && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") && !ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2"))
return;

Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
Expand All @@ -198,7 +198,7 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename);
const bool lolGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol");
bool nonKyraGame = ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("lol") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob") || ConfMan.getDomain(target)->getVal("gameid").equalsIgnoreCase("eob2");

if (in) {
Kyra::KyraEngine_v1::SaveHeader header;
Expand All @@ -212,12 +212,12 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s

// Slot 0 is used for the 'restart game' save in all three Kyrandia games, thus
// we prevent it from being deleted.
desc.setDeletableFlag(slot != 0 || lolGame);
desc.setDeletableFlag(slot != 0 || nonKyraGame);

// We don't allow quick saves (slot 990 till 998) to be overwritten.
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);
desc.setThumbnail(header.thumbnail);

return desc;
Expand All @@ -229,7 +229,7 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
// We don't allow quick saves (slot 990 till 998) to be overwritten.
// The same goes for the 'Autosave', which is slot 999. Slot 0 will also
// be protected in Kyra 1-3, since it's the 'restart game' save.
desc.setWriteProtectedFlag((slot == 0 && !lolGame) || slot >= 990);
desc.setWriteProtectedFlag((slot == 0 && !nonKyraGame) || slot >= 990);

return desc;
}
Expand Down
10 changes: 8 additions & 2 deletions engines/kyra/eob2.cpp
Expand Up @@ -77,6 +77,10 @@ Common::Error DarkMoonEngine::init() {
_color13 = 177;
_color14 = 182;

// Necessary wall hacks (where the original code makes out of bounds accesses)
_wllWallFlags[183] = 0x50;
_wllVmpMap[183] = 1;

return Common::kNoError;
}

Expand Down Expand Up @@ -312,6 +316,8 @@ const uint8 *DarkMoonEngine::loadDoorShapes(const char *filename, int doorIndex,
void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall, int mDim, int16, int16) {
int shapeIndex = type * 3 + 2 - mDim;
uint8 *shp = _doorShapes[shapeIndex];
if (!shp)
return;

if ((_doorType[type] == 0) || (_doorType[type] == 1)) {
y = _dscDoorY1[mDim] - shp[1];
Expand Down Expand Up @@ -392,7 +398,7 @@ void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {

bool DarkMoonEngine::checkPartyStatusExtra() {
if (checkScriptFlags(0x100000))
seq_dranFools();
seq_kheldran();
return _gui->confirmDialogue2(14, 67, 1);
}

Expand Down Expand Up @@ -462,7 +468,7 @@ void DarkMoonEngine::characterLevelGain(int charIndex) {
if (er == 0xffffffff)
continue;

increaseCharacterExperience(charIndex, er - c->experience[i]);
increaseCharacterExperience(charIndex, er - c->experience[i] + 1);
}
}

Expand Down
5 changes: 3 additions & 2 deletions engines/kyra/eob2.h
Expand Up @@ -88,10 +88,11 @@ friend class DarkmoonSequenceHelper;

// Ingame sequence
void seq_nightmare();
void seq_dranFools();
void seq_kheldran();
void seq_dranDragonTransformation();

const char *const *_dranFoolsStrings;
const int8 *_dreamSteps;
const char *const *_kheldranStrings;

// characters
void drawNpcScene(int npcIndex);
Expand Down
20 changes: 10 additions & 10 deletions engines/kyra/eobcommon.cpp
Expand Up @@ -302,13 +302,6 @@ Common::Error EobCoreEngine::init() {
memset(&_wllShapeMap[3], -1, 5);
memset(&_wllShapeMap[13], -1, 5);

/*int clen = _flags.gameID == GI_EOB2 ? 80 : 70;
memcpy(&_wllShapeMap[256 - clen], _wllVmpMap, clen);
memcpy(&_specialWallTypes[256 - 2 * clen], _wllVmpMap, clen);
memcpy(&_specialWallTypes[256 - clen], _wllShapeMap, clen);
memcpy(&_wllWallFlags[256 - 2 * clen], _wllShapeMap, clen);
memcpy(&_wllWallFlags[256 - clen], _specialWallTypes, clen);*/

_wllVcnOffset = 16;

_monsters = new EobMonsterInPlay[30];
Expand Down Expand Up @@ -1248,6 +1241,7 @@ void EobCoreEngine::initDialogueSequence() {

_txt->resetPageBreakString();
gui_updateControls();
//_allowSkip = true;

_sound->playTrack(0);
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
Expand All @@ -1263,6 +1257,7 @@ void EobCoreEngine::restoreAfterDialogueSequence() {
_dialogueLastBitmap[0] = 0;

gui_restorePlayField();
//_allowSkip = false;
_screen->setScreenDim(7);

if (_flags.gameID == GI_EOB2)
Expand Down Expand Up @@ -1603,14 +1598,18 @@ bool EobCoreEngine::checkPassword() {
for (int i = 0; i < 3; i++) {
_screen->fillRect(_screen->_curDim->sx << 3, _screen->_curDim->sy, ((_screen->_curDim->sx + _screen->_curDim->w) << 3) - 1, (_screen->_curDim->sy + _screen->_curDim->h) - 1, _bkgColor_1);
int c = rollDice(1, _mnNumWord - 1, -1);
_screen->drawShape(0, _largeItemShapes[_mnDef[c << 2]], 100, 2, 13);
const uint8 *shp = (_mnDef[c << 2] < _numLargeItemShapes) ? _largeItemShapes[_mnDef[c << 2]] : (_mnDef[c << 2] < 15 ? 0 : _smallItemShapes[_mnDef[c << 2] - 15]);
assert(shp);
_screen->drawShape(0, shp, 100, 2, 13);
_screen->printShadedText(Common::String::format(_mnPrompt[0], _mnDef[(c << 2) + 1], _mnDef[(c << 2) + 2]).c_str(), (_screen->_curDim->sx + 1) << 3, _screen->_curDim->sy, _screen->_curDim->unk8, _bkgColor_1);
memset(answ, 0, 20);
gui_drawBox(76, 100, 133, 14, _color2_1, _color1_1, -1);
gui_drawBox(77, 101, 131, 12, _color2_1, _color1_1, -1);
if (_gui->getTextInput(answ, 10, 103, 15, _screen->_curDim->unk8, _bkgColor_1, 8) < 0)
i = 3;
if (scumm_stricmp(_mnWord[c], answ) && i == 2)
if (!scumm_stricmp(_mnWord[c], answ))
break;
else if (i == 2)
return false;
}

Expand Down Expand Up @@ -1806,7 +1805,7 @@ int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips,
EobCharacter *c = &_characters[charIndex];

if (savingThrowType != 5) {
if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex))
if (trySavingThrow(c, _charClassModUnk[c->cClass], c->level[0], savingThrowType, c->raceSex >> 1 /*fix bug in original code by adding a right shift*/))
s = savingThrowReduceDamage(savingThrowEffect, s);
}

Expand Down Expand Up @@ -2006,6 +2005,7 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
_txt->printMessage(_ripItemStrings[(_characters[c].raceSex & 1) ^ 1], -1, _characters[c].name);
printFullItemName(itm);
_txt->printMessage(_ripItemStrings[2]);
break;
}
gui_drawCharPortraitWithStats(c);
}
Expand Down
17 changes: 11 additions & 6 deletions engines/kyra/magic_eob.cpp
Expand Up @@ -360,7 +360,7 @@ void EobCoreEngine::startSpell(int spell) {
if (_castScrollSlot) {
gui_updateSlotAfterScrollUse();
} else {
c->disabledSlots |= 4;
_characters[_openBookChar].disabledSlots |= 4;
setCharEventTimer(_openBookChar, 72, 11, 1);
gui_toggleButtons();
gui_drawSpellbook();
Expand Down Expand Up @@ -405,7 +405,6 @@ void EobCoreEngine::sparkEffectDefensive(int charIndex) {
_screen->updateScreen();
}
}
resetSkipFlag();
delay(2 * _tickLength);
}

Expand All @@ -430,7 +429,6 @@ void EobCoreEngine::sparkEffectOffensive() {
if (shpIndex)
_screen->drawShape(2, _sparkShapes[shpIndex - 1], _sparkEffectOfX[ii], _sparkEffectOfY[ii], 0);
}
resetSkipFlag();
delay(2 * _tickLength);
_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
Expand All @@ -444,6 +442,7 @@ void EobCoreEngine::sparkEffectOffensive() {
}

void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
assert (spell >= 0);
int l = _openBookType == 1 ? getClericPaladinLevel(_openBookChar) : getMageLevel(_openBookChar);
uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
Expand Down Expand Up @@ -753,7 +752,7 @@ int EobCoreEngine::findFirstCharacterSpellTarget() {
}

int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
for (; _characterSpellTarget < 6; _characterSpellTarget++) {
for (_characterSpellTarget++; _characterSpellTarget < 6; ) {
if (++curCharIndex == 6)
curCharIndex = 0;
if (testCharacter(curCharIndex, 3))
Expand All @@ -763,8 +762,14 @@ int EobCoreEngine::findNextCharacterSpellTarget(int curCharIndex) {
}

int EobCoreEngine::charDeathSavingThrow(int charIndex, int div) {
if (specialAttackSavingThrow(charIndex, 4))
bool _beholderOrgBhv = true;
// Due to a bug in the original code the saving throw result is completely ignored
// here. The Beholders' disintegrate spell will alway succeed while their flesh to
// stone spell will always fail.
if (_beholderOrgBhv)
div >>= 1;
else
div = specialAttackSavingThrow(charIndex, 4) ? 1 : 0;
return div;
}

Expand Down Expand Up @@ -1226,7 +1231,7 @@ bool EobCoreEngine::spellCallback_end_flameStrike(void *obj) {
}

void EobCoreEngine::spellCallback_start_raiseDead() {
if (_characters[_activeSpellCharId].hitPointsCur == -10 || ((_characters[_activeSpellCharId].raceSex >> 1) == 1)) {
if (_characters[_activeSpellCharId].hitPointsCur == -10 && ((_characters[_activeSpellCharId].raceSex >> 1) != 1)) {
_characters[_activeSpellCharId].hitPointsCur = 1;
gui_drawCharPortraitWithStats(_activeSpellCharId);
} else {
Expand Down
3 changes: 2 additions & 1 deletion engines/kyra/resource.h
Expand Up @@ -626,7 +626,8 @@ enum KyraResources {
kEob2Npc2Strings,
kEob2MonsterDustStrings,

kEob2DranFoolsStrings,
kEob2DreamSteps,
kEob2KheldranStrings,
kEob2HornStrings,
kEob2HornSounds,

Expand Down
7 changes: 7 additions & 0 deletions engines/kyra/saveload_eob.cpp
Expand Up @@ -366,6 +366,13 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
_sceneUpdateRequired = true;
_screen->setFont(Screen::FID_6_FNT);

for (int i = 0; i < 6; i++) {
for (int ii = 0; ii < 10; ii++) {
if (_characters[i].events[ii] == -57)
spellCallback_start_trueSeeing();
}
}

_screen->setCurPage(0);
gui_drawPlayField(false);

Expand Down
10 changes: 7 additions & 3 deletions engines/kyra/scene_eob.cpp
Expand Up @@ -647,8 +647,12 @@ void EobCoreEngine::loadLevel(int level, int sub) {
delete s;
}

Common::String gfxFile = initLevelData(sub);

Common::String gfxFile;
// Work around for issue with corrupt (incomplete) monster property data
// when loading a savegame saved in a sub level
for (int i = 0; i <= sub; i++)
gfxFile = initLevelData(i);

const uint8 *data = _screen->getCPagePtr(5);
const uint8 *pos = data + READ_LE_UINT16(data);
uint16 len = READ_LE_UINT16(pos);
Expand Down Expand Up @@ -1142,7 +1146,7 @@ int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint1
int f = _wllWallFlags[w];

//if (!f)
assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));
assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80));

if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) {
for (int i = 0; i < 5; i++) {
Expand Down
17 changes: 1 addition & 16 deletions engines/kyra/screen_eob.cpp
Expand Up @@ -774,15 +774,8 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS
int16 py = ((ptr3[i] >> 6) >> scale) + gy2;
if (py > ymax)
py = ymax;
if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) {
if (posWithinRect(px, py, rX1, rY1, rX2, rY2))
setPagePixel(0, px, py, ptr6[i]);
if (i % 5 == 0) {
updateScreen();
uint32 cur = _system->getMillis();
if (end > cur)
_system->delayMillis(end - cur);
}
}
}
}

Expand Down Expand Up @@ -914,14 +907,6 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int
int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1);
int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1);
setPagePixel(0, px, py, pixBackup[ii]);

if (ii % 15 == 0) {
updateScreen();
uint32 cur = _system->getMillis();
if (nextDelay > cur)
_system->delayMillis(nextDelay - cur);
nextDelay += 1;
}
}
}

Expand Down

0 comments on commit c35de37

Please sign in to comment.