aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devtools/create_kyradat/create_kyradat.cpp6
-rw-r--r--devtools/create_kyradat/create_kyradat.h2
-rw-r--r--devtools/create_kyradat/games.cpp5
-rw-r--r--devtools/create_kyradat/tables.cpp19
-rw-r--r--dists/engine-data/kyra.datbin458387 -> 458977 bytes
-rw-r--r--engines/kyra/eob1.cpp51
-rw-r--r--engines/kyra/eob1.h6
-rw-r--r--engines/kyra/eob2.cpp2
-rw-r--r--engines/kyra/eobcommon.cpp18
-rw-r--r--engines/kyra/eobcommon.h11
-rw-r--r--engines/kyra/gui_eob.cpp15
-rw-r--r--engines/kyra/magic_eob.cpp46
-rw-r--r--engines/kyra/resource.h3
-rw-r--r--engines/kyra/saveload_eob.cpp7
-rw-r--r--engines/kyra/scene_eob.cpp6
-rw-r--r--engines/kyra/script_eob.cpp4
-rw-r--r--engines/kyra/sprites_eob.cpp15
-rw-r--r--engines/kyra/staticres_eob.cpp3
-rw-r--r--engines/kyra/text_eob.cpp2
-rw-r--r--engines/kyra/timer_eob.cpp5
20 files changed, 189 insertions, 37 deletions
diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 9f749f0dfd..276564bc64 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -395,6 +395,7 @@ const ExtractFilename extractFilenames[] = {
{ kEobBaseSparkOfY, kTypeRawData, false },
{ kEobBaseSpellProperties, kTypeRawData, false },
{ kEobBaseMagicFlightProps, kTypeRawData, false },
+ { kEobBaseTurnUndeadEffect, kTypeRawData, false },
// EYE OF THE BEHOLDER I
{ kEob1MainMenuStrings, kTypeStringList, true },
@@ -406,6 +407,7 @@ const ExtractFilename extractFilenames[] = {
{ kEob1MonsterDistAttSfx10, kTypeRawData, false },
{ kEob1MonsterDistAttType17, kTypeRawData, false },
{ kEob1MonsterDistAttSfx17, kTypeRawData, false },
+ { kEob1TurnUndeadString, kTypeStringList, true },
// EYE OF THE BEHOLDER II
{ kEob2MainMenuStrings, kTypeStringList, true },
@@ -1602,6 +1604,8 @@ const char *getIdString(const int id) {
return "kEobBaseSpellProperties";
case kEobBaseMagicFlightProps:
return "kEobBaseMagicFlightProps";
+ case kEobBaseTurnUndeadEffect:
+ return "kEobBaseTurnUndeadEffect";
case kEob1MainMenuStrings:
return "kEob1MainMenuStrings";
case kEob1DoorShapeDefs:
@@ -1618,6 +1622,8 @@ const char *getIdString(const int id) {
return "kEob1MonsterDistAttType17";
case kEob1MonsterDistAttSfx17:
return "kEob1MonsterDistAttSfx17";
+ case kEob1TurnUndeadString:
+ return "kEob1TurnUndeadString";
case kEob2MainMenuStrings:
return "kEob2MainMenuStrings";
case kEob2IntroStrings:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 598050d80c..a587147974 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -396,6 +396,7 @@ enum kExtractID {
kEobBaseSpellProperties,
kEobBaseMagicFlightProps,
+ kEobBaseTurnUndeadEffect,
kEob1MainMenuStrings,
kEob1DoorShapeDefs,
@@ -407,6 +408,7 @@ enum kExtractID {
kEob1MonsterDistAttSfx10,
kEob1MonsterDistAttType17,
kEob1MonsterDistAttSfx17,
+ kEob1TurnUndeadString,
kEob2MainMenuStrings,
kEob2IntroStrings,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 0496acc4b1..4ab12028c2 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1063,6 +1063,7 @@ const int eob1FloppyNeed[] = {
kEob1MonsterDistAttSfx10,
kEob1MonsterDistAttType17,
kEob1MonsterDistAttSfx17,
+ kEob1TurnUndeadString,
kEobBasePryDoorStrings,
kEobBaseWarningStrings,
@@ -1077,6 +1078,8 @@ const int eob1FloppyNeed[] = {
kEobBaseMagicObjectStrings,
kEobBaseMagicObject5String,
kEobBasePatternSuffix,
+ kEobBasePatternGrFix1,
+ kEobBasePatternGrFix2,
kEobBaseValidateArmorString,
kEobBaseValidateNoDropString,
kEobBasePotionStrings,
@@ -1169,6 +1172,7 @@ const int eob1FloppyNeed[] = {
kEobBaseSpellProperties,
kEobBaseMagicFlightProps,
+ kEobBaseTurnUndeadEffect,
kLolEobCommonDscDoorShapeIndex,
kEobBaseWllFlagPreset,
@@ -1382,6 +1386,7 @@ const int eob2FloppyNeed[] = {
kEobBaseSpellProperties,
kEobBaseMagicFlightProps,
+ kEobBaseTurnUndeadEffect,
kLolEobCommonDscDoorShapeIndex,
kEobBaseWllFlagPreset,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index c45b3d4c26..46239c2bee 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2089,8 +2089,7 @@ const ExtractEntrySearchData kEobBaseSlotValidationFlagsProvider[] = {
};
const ExtractEntrySearchData kEobBaseProjectileWeaponTypesProvider[] = {
- { UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000063E, { { 0xA6, 0x75, 0x6C, 0x39, 0x96, 0xCB, 0xA7, 0xC2, 0x31, 0xE0, 0x2A, 0x75, 0x30, 0x96, 0x58, 0x05 } } } }, // EOB 1
- { UNK_LANG, kPlatformPC, { 0x0000000C, 0x0000063E, { { 0x3E, 0x99, 0x6D, 0xE4, 0x6B, 0xC8, 0x49, 0x1B, 0x17, 0xD2, 0xBE, 0x9B, 0xE0, 0xCD, 0xA1, 0xC2 } } } }, // EOB 1
+ { UNK_LANG, kPlatformPC, { 0x00000008, 0x0000061C, { { 0x05, 0x55, 0xA6, 0xD1, 0x3C, 0x12, 0x84, 0xDA, 0xA9, 0x33, 0xCF, 0x07, 0x05, 0x2A, 0xB2, 0x29 } } } }, // EOB 1
{ UNK_LANG, kPlatformPC, { 0x0000000F, 0x00000829, { { 0x9F, 0x6A, 0x13, 0x8A, 0xA7, 0x40, 0xE8, 0x40, 0x2E, 0x87, 0x49, 0x6B, 0x67, 0xED, 0xE8, 0xCE } } } }, // EOB 2
EXTRACT_END_ENTRY
};
@@ -2310,6 +2309,12 @@ const ExtractEntrySearchData kEobBaseMagicFlightPropsProvider[] = {
EXTRACT_END_ENTRY
};
+const ExtractEntrySearchData kEobBaseTurnUndeadEffectProvider[] = {
+ { UNK_LANG, kPlatformUnknown, { 0x0000008C, 0x00002E8B, { { 0x96, 0x15, 0x61, 0x12, 0x43, 0xCF, 0x3A, 0x84, 0x1A, 0x89, 0xB5, 0x32, 0x0D, 0xB3, 0x20, 0x67 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
const ExtractEntrySearchData kEob1MainMenuStringsProvider[] = {
{ EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } },
{ DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } },
@@ -2356,6 +2361,14 @@ const ExtractEntrySearchData kEob1MonsterDistAttSfx17Provider[] = {
EXTRACT_END_ENTRY
};
+const ExtractEntrySearchData kEob1TurnUndeadStringProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000027, 0x00000BF2, { { 0x43, 0x0A, 0x1E, 0xEE, 0x84, 0xD6, 0xD6, 0x87, 0x20, 0x9F, 0x15, 0x22, 0x9B, 0x65, 0x24, 0xDB } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000030, 0x00000F48, { { 0xDA, 0x59, 0xEC, 0xC1, 0x9B, 0xCF, 0x90, 0x4A, 0x93, 0x3E, 0xE5, 0x26, 0x20, 0x8B, 0x74, 0x92 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+
const ExtractEntrySearchData kEob2MainMenuStringsProvider[] = {
{ EN_ANY, kPlatformUnknown, { 0x0000005F, 0x000017BE, { { 0x77, 0x8A, 0x50, 0x9F, 0x42, 0xD8, 0x00, 0x05, 0x60, 0x2A, 0x80, 0x25, 0x00, 0xDC, 0x7C, 0x92 } } } },
{ DE_DEU, kPlatformUnknown, { 0x0000005E, 0x000017F3, { { 0xD0, 0x93, 0x2E, 0x5F, 0x9D, 0xDB, 0xC4, 0xFB, 0x9E, 0x9F, 0x14, 0xD6, 0xB4, 0xBE, 0x3D, 0x0C } } } },
@@ -3698,6 +3711,7 @@ const ExtractEntry extractProviders[] = {
{ kEobBaseSpellProperties, kEobBaseSpellPropertiesProvider },
{ kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider },
+ { kEobBaseTurnUndeadEffect, kEobBaseTurnUndeadEffectProvider },
{ kEob1MainMenuStrings, kEob1MainMenuStringsProvider },
{ kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider },
@@ -3709,6 +3723,7 @@ const ExtractEntry extractProviders[] = {
{ kEob1MonsterDistAttSfx10, kEob1MonsterDistAttSfx10Provider },
{ kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider },
{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
+ { kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },
{ kEob2MainMenuStrings, kEob2MainMenuStringsProvider },
{ kEob2IntroStrings, kEob2IntroStringsProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index cd51c0b54c..2128a448b6 100644
--- a/dists/engine-data/kyra.dat
+++ b/dists/engine-data/kyra.dat
Binary files differ
diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp
index a9051de833..d12283f140 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -83,7 +83,7 @@ void EobEngine::startupLoad() {
}
void EobEngine::npcSequence(int npcIndex) {
-
+ error("EobEngine::npcSequence(): unimplemented");
}
@@ -210,10 +210,54 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
}
}
+void EobEngine::turnUndeadAuto() {
+ if (_currentLevel != 2 && _currentLevel != 7)
+ return;
+
+ int oc = _openBookChar;
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 0x0d))
+ continue;
+
+ EobCharacter *c = &_characters[i];
+
+ if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6)
+ continue;
+
+ int l = getCharacterLevelIndex(2, c->cClass);
+ if (l > -1) {
+ if (c->level[l] > _openBookCasterLevel) {
+ _openBookCasterLevel = c->level[l];
+ _openBookChar = i;
+ }
+ } else {
+ l = getCharacterLevelIndex(4, c->cClass);
+ if (l > -1) {
+ if ((c->level[l] - 2) > _openBookCasterLevel) {
+ _openBookCasterLevel = (c->level[l] - 2);
+ _openBookChar = i;
+ }
+ }
+ }
+ }
+
+ if (_openBookCasterLevel)
+ spellCallback_start_turnUndead();
+
+ _openBookChar = oc;
+ _openBookCasterLevel = 0;
+}
+
+void EobEngine::turnUndeadAutoHit() {
+ _txt->printMessage(_turnUndeadString[0], -1, _characters[_openBookChar].name);
+ sparkEffectOffensive();
+}
+
bool EobEngine::checkPartyStatusExtra() {
_screen->copyPage(0, 10);
- gui_drawBox(0, 121, 319, 200, _color2_1, _color1_1, _bkgColor_1);
- _screen->setScreenDim(9);
+ gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1);
+ _txt->setupField(9, false);
_txt->printMessage(_menuStringsDefeat[0]);
while (!shouldQuit()) {
removeInputTop();
@@ -221,6 +265,7 @@ bool EobEngine::checkPartyStatusExtra() {
break;
}
_screen->copyPage(10, 0);
+ _eventList.clear();
return true;
}
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 3460ac7591..8d41118e52 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -84,6 +84,12 @@ private:
const uint8 *_doorSwitchShapeEncodeDefs;
const uint8 *_doorSwitchCoords;
+ // Magic
+ void turnUndeadAuto();
+ void turnUndeadAutoHit();
+
+ const char * const *_turnUndeadString;
+
// Misc
bool checkPartyStatusExtra();
uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index c3169b10bf..cd306863ba 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -338,7 +338,7 @@ void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall
}
void DarkMoonEngine::restParty_npc() {
-
+ warning("DarkMoonEngine::restParty_npc(): implement!");
}
bool DarkMoonEngine::restParty_extraAbortCondition() {
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 07c1f0760a..22c0519069 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -46,6 +46,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_playFinale = false;
_runFlag = true;
_configMouse = true;
+ _loading = false;
_largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes =
_wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
@@ -82,7 +83,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_monsterOvl1 = _monsterOvl2 = 0;
_monsters = 0;
_dstMonsterIndex = 0;
- _inflictMonsterDamageUnk = 0;
+ _preventMonsterFlash = false;
_teleporterPulse = 0;
@@ -124,7 +125,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_openBookSpellLevel = 0;
_openBookSpellSelectedItem = 0;
_openBookSpellListOffset = 0;
- _openBookChar = _openBookCharBackup = 0;
+ _openBookChar = _openBookCharBackup = _openBookCasterLevel = 0;
_openBookType = _openBookTypeBackup = 0;
_openBookSpellList = 0;
_openBookAvailableSpells = 0;
@@ -415,7 +416,7 @@ void EobCoreEngine::writeSettings() {
void EobCoreEngine::startupNew() {
gui_setPlayFieldButtons();
_screen->_curPage = 0;
- gui_drawPlayField(0);
+ gui_drawPlayField(false);
_screen->_curPage = 0;
gui_drawAllCharPortraitsWithStats();
drawScene(1);
@@ -452,8 +453,7 @@ void EobCoreEngine::runLoop() {
_envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength);
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();
+ turnUndeadAuto();
}
}
@@ -1540,7 +1540,11 @@ int EobCoreEngine::thrownAttack(int charIndex, int slotIndex, Item item) {
int EobCoreEngine::projectileWeaponAttack(int charIndex, Item item) {
int tp = _items[item].type;
- int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 2 : tp];
+
+ if (_flags.gameID == GI_EOB1)
+ assert(tp >= 7);
+
+ int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 7 : tp];
Item ammoItem = 0;
if (t == 16) {
@@ -1588,7 +1592,7 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g
} else {
if (checkSceneUpdateNeed(m->block)) {
m->flags |= 2;
- if (_inflictMonsterDamageUnk)
+ if (_preventMonsterFlash)
return;
flashMonsterShape(m);
}
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 39919ca086..6463f839c8 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -406,6 +406,7 @@ protected:
const EobCharacter *_npcPreset;
bool _partyResting;
+ bool _loading;
// Items
void loadItemDefs();
@@ -634,7 +635,7 @@ protected:
uint8 _scriptTimersMode;
// Gui
- void gui_drawPlayField(int pageNum);
+ void gui_drawPlayField(bool refresh);
void gui_restorePlayField();
void gui_drawAllCharPortraitsWithStats();
void gui_drawCharPortraitWithStats(int index);
@@ -858,7 +859,7 @@ protected:
void explodeMonster(EobMonsterInPlay *m);
int _dstMonsterIndex;
- int _inflictMonsterDamageUnk;
+ bool _preventMonsterFlash;
int16 _foundMonstersArray[5];
// magic
@@ -867,6 +868,9 @@ protected:
void usePotion(int charIndex, int weaponSlot);
void useWand(int charIndex, int weaponSlot);
+ virtual void turnUndeadAuto() {};
+ virtual void turnUndeadAutoHit() {};
+
void castSpell(int spell, int weaponSlot);
void removeCharacterEffect(int spell, int charIndex, int showWarning);
void removeAllCharacterEffects(int charIndex);
@@ -880,6 +884,7 @@ protected:
bool magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
+ bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel);
void printWarning(const char* str);
void printNoEffectWarning();
@@ -958,6 +963,7 @@ protected:
uint8 _openBookType;
uint8 _openBookCharBackup;
uint8 _openBookTypeBackup;
+ uint8 _openBookCasterLevel;
const char *const *_openBookSpellList;
int8 *_openBookAvailableSpells;
uint8 _activeSpellCaster;
@@ -1011,6 +1017,7 @@ protected:
const uint8 *_sparkEffectOfY;
const uint8 *_magicFlightObjectProperties;
+ const uint8 *_turnUndeadEffect;
// Menu
EobMenuDef *_menuDefs;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index c7972299d1..ce5f3ea53f 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -149,17 +149,19 @@ Button *EobCoreEngine::gui_getButton(Button *buttonList, int index) {
return 0;
}
-void EobCoreEngine::gui_drawPlayField(int pageNum) {
+void EobCoreEngine::gui_drawPlayField(bool refresh) {
_screen->loadEobCpsFileToPage("PLAYFLD", 0, 5, 3, 2);
int cp = _screen->setCurPage(2);
gui_drawCompass(true);
- if (pageNum && !_sceneDrawPage2)
+ if (refresh && !_sceneDrawPage2)
drawScene(0);
_screen->setCurPage(cp);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
- _screen->updateScreen();
+
+ if (!_loading)
+ _screen->updateScreen();
_screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2);
}
@@ -167,7 +169,7 @@ void EobCoreEngine::gui_drawPlayField(int pageNum) {
void EobCoreEngine::gui_restorePlayField() {
loadVcnData(0, 0);
_screen->_curPage = 0;
- gui_drawPlayField(1);
+ gui_drawPlayField(true);
gui_drawAllCharPortraitsWithStats();
}
@@ -706,7 +708,8 @@ void EobCoreEngine::gui_drawSpellbook() {
_screen->setCurPage(0);
_screen->copyRegion(64, 121, 64, 121, 112, 56, 2, 0, Screen::CR_NO_P_CHECK);
- _screen->updateScreen();
+ if (!_loading)
+ _screen->updateScreen();
}
void EobCoreEngine::gui_drawSpellbookScrollArrow(int x, int y, int direction) {
@@ -2245,7 +2248,7 @@ void GUI_Eob::runCampMenu() {
if (cnt > 4) {
_vm->dropCharacter(selectCharacterDialogue(53));
- _vm->gui_drawPlayField(0);
+ _vm->gui_drawPlayField(false);
res = true;
_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK);
_screen->setFont(Screen::FID_6_FNT);
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 593ef63544..f828625dbb 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -80,6 +80,9 @@ void EobCoreEngine::usePotion(int charIndex, int weaponSlot) {
int val = deleteInventoryItem(charIndex, weaponSlot);
snd_playSoundEffect(10);
+ if (_flags.gameID == GI_EOB1)
+ val--;
+
switch (val) {
case 0:
sparkEffectDefensive(charIndex);
@@ -496,7 +499,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
level = 1;
if ((_levelBlockProperties[fo->curBlock].flags & 7) && (fo->attackerId >= 0 || ignoreAttackerId)) {
- _inflictMonsterDamageUnk = 1;
+ _preventMonsterFlash = true;
for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, blockDamage, singleTargetCheckAdjacent); *m != -1; m++) {
int dmg = rollDice(dcTimes, dcPips, dcOffs) * level;
@@ -604,6 +607,23 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
return true;
}
+bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel) {
+ uint8 e = _turnUndeadEffect[_monsterProps[m->type].tuResist * 14 + MIN(casterLevel, 14)];
+
+ if (e == 0xff) {
+ calcAndInflictMonsterDamage(m, 0, 0, 500, 0x200, 5, 3);
+ } else if (hitChance < e) {
+ return false;
+ } else {
+ m->mode = 0;
+ m->flags |= 8;
+ m->spellStatusLeft = 40;
+ m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;
+ }
+
+ return true;
+}
+
void EobCoreEngine::printWarning(const char* str) {
_txt->printMessage(str);
snd_playSoundEffect(79);
@@ -900,11 +920,33 @@ void EobCoreEngine::spellCallback_start_heal() {
}
void EobCoreEngine::spellCallback_start_layOnHands() {
-
+ modifyCharacterHitpoints(_activeSpellCaster, _characters[_openBookChar].level[0] << 1);
}
void EobCoreEngine::spellCallback_start_turnUndead() {
+ uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
+ if (!(_levelBlockProperties[bl].flags & 7))
+ return;
+
+ int cl = _openBookCasterLevel ? _openBookCasterLevel : getCharacterClericPaladinLevel(_openBookChar);
+ int r = rollDice(1, 20);
+ bool hit = false;
+
+ for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) {
+ if ((_monsterProps[_monsters[*m].type].typeFlags & 4) && !(_monsters[*m].flags & 0x10)) {
+ _preventMonsterFlash = true;
+ _monsters[*m].flags |= 0x10;
+ hit |= turnUndeadHit(&_monsters[*m], r, cl);
+ }
+ }
+
+ if (hit) {
+ turnUndeadAutoHit();
+ snd_playSoundEffect(95);
+ updateAllMonsterShapes();
+ }
+ _preventMonsterFlash = false;
}
bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 02ee384f5c..5328aeff35 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -469,6 +469,7 @@ enum KyraResources {
kEobBaseSpellProperties,
kEobBaseMagicFlightProps,
+ kEobBaseTurnUndeadEffect,
kEob1MainMenuStrings,
kEob1DoorShapeDefs,
@@ -481,6 +482,8 @@ enum KyraResources {
kEob1MonsterDistAttType17,
kEob1MonsterDistAttSfx17,
+ kEob1TurnUndeadString,
+
kEob2MainMenuStrings,
kEob2IntroStrings,
kEob2IntroCPSFiles,
diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp
index 1fa26c26b1..43a230e590 100644
--- a/engines/kyra/saveload_eob.cpp
+++ b/engines/kyra/saveload_eob.cpp
@@ -149,6 +149,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
return Common::Error(Common::kReadingFailed);
Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
+ _loading = true;
+ _screen->fadeToBlack(10);
for (int i = 0; i < 6; i++) {
EobCharacter *c = &_characters[i];
@@ -356,7 +358,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
_screen->setFont(Screen::FID_6_FNT);
_screen->setCurPage(0);
- gui_drawPlayField(0);
+ gui_drawPlayField(false);
if (_currentControlMode)
_screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);
@@ -378,6 +380,9 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
while (!_screen->isMouseVisible())
_screen->showMouse();
+ _loading = false;
+ _screen->fadeFromBlack(20);
+
return Common::kNoError;
}
diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp
index 36584d462b..e6b3c26394 100644
--- a/engines/kyra/scene_eob.cpp
+++ b/engines/kyra/scene_eob.cpp
@@ -997,7 +997,9 @@ void EobCoreEngine::drawScene(int refresh) {
if (refresh)
_screen->fillRect(0, 0, 176, 120, 12);
- _screen->setScreenPalette(_screen->getPalette(0));
+ if (!_loading)
+ _screen->setScreenPalette(_screen->getPalette(0));
+
_sceneDrawPage2 = 0;
}
@@ -1025,7 +1027,7 @@ void EobCoreEngine::drawScene(int refresh) {
if (!_dialogueField && refresh && !_updateFlags)
gui_drawCompass(false);
- if (refresh && !_partyResting)
+ if (refresh && !_partyResting && !_loading)
_screen->updateScreen();
if (_sceneDefaultUpdate) {
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 9e18a14fb2..833413c69b 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -1397,12 +1397,12 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
case -2:
// portal sequence
- pos=pos;
+ error("EobInfProcessor::oeob_sequence(): unimplemented cmd -2");
break;
case -1:
// copy protection
- pos=pos;
+ error("EobInfProcessor::oeob_sequence(): unimplemented cmd -1");
break;
default:
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index baa7a0bfda..0874de82e3 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -140,6 +140,12 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level)
_timer->setCountdown(0x21 + (p << 1), v);
}
+ uint32 ct = _system->getMillis();
+ for (int i = 0x20; i < 0x24; i++) {
+ int32 del = _timer->getDelay(i);
+ _timer->setNextRun(i, (i & 1) ? ct + (del >> 1) : ct + del);
+ }
+
if (_hasTempDataFlags & (1 << (level - 1)))
return data + 420;
@@ -302,12 +308,12 @@ bool EobCoreEngine::isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, i
const int16 *EobCoreEngine::findBlockMonsters(uint16 block, int pos, int dir, int blockDamage, int singleTargetCheckAdjacent) {
static const uint8 cpos4[] = { 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1 };
- int checkPos4 = (pos <= 4) ? cpos4[(dir << 2) + pos] : 1;
+ int include4 = (pos < 4) ? cpos4[(dir << 2) + pos] : 1;
int16 *dst = _foundMonstersArray;
if (blockDamage) {
for (int i = 0; i < 30; i++) {
- if (_monsters[i].block == block && (_monsters[i].pos != 4 || checkPos4))
+ if (_monsters[i].block == block && (_monsters[i].pos != 4 || include4))
*dst++ = i;
}
@@ -338,7 +344,7 @@ const int16 *EobCoreEngine::findBlockMonsters(uint16 block, int pos, int dir, in
} else {
for (int i = 0; i < 30; i++) {
- if (isMonsterOnPos(&_monsters[i], block, pos, checkPos4))
+ if (isMonsterOnPos(&_monsters[i], block, pos, include4))
*dst++ = i;
}
}
@@ -395,7 +401,7 @@ void EobCoreEngine::updateAllMonsterShapes() {
} else {
_sceneUpdateRequired = false;
}
- _inflictMonsterDamageUnk = 0;
+ _preventMonsterFlash = false;
}
void EobCoreEngine::drawBlockItems(int index) {
@@ -684,7 +690,6 @@ void EobCoreEngine::drawTeleporter(int index) {
void EobCoreEngine::updateMonsters(int unit) {
for (int i = 0; i < 30; i++) {
EobMonsterInPlay *m = &_monsters[i];
-
if (m->unit == unit) {
if (m->hitPointsCur <= 0 || m->flags & 0x20)
continue;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 19e2512da5..1cf78eef5c 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -528,6 +528,7 @@ void EobCoreEngine::initStaticResource() {
_sparkEffectOfX = _staticres->loadRawData(kEobBaseSparkOfX, temp);
_sparkEffectOfY = _staticres->loadRawData(kEobBaseSparkOfY, temp);
_magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp);
+ _turnUndeadEffect = _staticres->loadRawData(kEobBaseTurnUndeadEffect, temp);
// Hard code the following strings, since EOB I doesn't have them in the original.
// EOB I doesn't have load and save menus, because there is only one single
@@ -1065,6 +1066,8 @@ void EobEngine::initStaticResource() {
_monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp);
_monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp);
+ _turnUndeadString = _staticres->loadStrings(kEob1TurnUndeadString, temp);
+
const uint8 *ps = _staticres->loadRawData(kEob1MonsterProperties, temp);
temp /= 27;
_monsterProps = new EobMonsterProperty[temp];
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index c350666226..63d893d2cc 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -70,8 +70,6 @@ void TextDisplayer_Eob::setupField(int dim, bool mode) {
clearCurDim();
else
resetDimTextPositions(dim);
-
- //_textPageBreakFunc = textPageBreakMore; + 0x25
}
void TextDisplayer_Eob::resetDimTextPositions(int dim) {
diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp
index 903dec2102..9e03bdebcf 100644
--- a/engines/kyra/timer_eob.cpp
+++ b/engines/kyra/timer_eob.cpp
@@ -101,6 +101,7 @@ void EobCoreEngine::setupTimers() {
_timer->addTimer(0x21, TimerV2(timerProcessMonsters), 20, true);
_timer->addTimer(0x22, TimerV2(timerProcessMonsters), 20, true);
_timer->addTimer(0x23, TimerV2(timerProcessMonsters), 20, true);
+ _timer->setNextRun(0x20, _system->getMillis());
_timer->setNextRun(0x21, _system->getMillis() + 7 * _tickLength);
_timer->setNextRun(0x22, _system->getMillis() + 14 * _tickLength);
_timer->setNextRun(0x23, _system->getMillis() + 14 * _tickLength);
@@ -274,7 +275,6 @@ void EobCoreEngine::timerProcessMonsters(int timerNum) {
updateMonsters(timerNum & 0x0f);
}
-
void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
int charIndex = timerNum & 0x0f;
EobCharacter *c = &_characters[charIndex];
@@ -346,7 +346,8 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
case 12:
c->effectFlags &= ~0x1000;
- _txt->printMessage(_characterStatusStrings12[0], -1, c->name);
+ if (_characterStatusStrings12)
+ _txt->printMessage(_characterStatusStrings12[0], -1, c->name);
break;
default: