aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorathrxx2011-08-01 22:50:51 +0200
committerJohannes Schickel2011-12-26 16:18:13 +0100
commit48f83b7bb48a1625f6c195e396f8d40047f50915 (patch)
tree28c3ae68ed7df09ddc1c2cbf9d083b31f7415660
parent84900e8e50df8490fbdebc3acb25a338949f2de9 (diff)
downloadscummvm-rg350-48f83b7bb48a1625f6c195e396f8d40047f50915.tar.gz
scummvm-rg350-48f83b7bb48a1625f6c195e396f8d40047f50915.tar.bz2
scummvm-rg350-48f83b7bb48a1625f6c195e396f8d40047f50915.zip
KYRA: (EOB) - implement npc sequences and fix some bugs
-rw-r--r--devtools/create_kyradat/create_kyradat.cpp46
-rw-r--r--devtools/create_kyradat/create_kyradat.h16
-rw-r--r--devtools/create_kyradat/extract.cpp2
-rw-r--r--devtools/create_kyradat/games.cpp16
-rw-r--r--devtools/create_kyradat/tables.cpp112
-rw-r--r--dists/engine-data/kyra.datbin458977 -> 460294 bytes
-rw-r--r--engines/kyra/eob1.cpp271
-rw-r--r--engines/kyra/eob1.h26
-rw-r--r--engines/kyra/eob2.cpp117
-rw-r--r--engines/kyra/eob2.h3
-rw-r--r--engines/kyra/eobcommon.cpp101
-rw-r--r--engines/kyra/eobcommon.h27
-rw-r--r--engines/kyra/gui_eob.cpp64
-rw-r--r--engines/kyra/gui_eob.h2
-rw-r--r--engines/kyra/items_eob.cpp59
-rw-r--r--engines/kyra/lol.cpp5
-rw-r--r--engines/kyra/loleobbase.cpp12
-rw-r--r--engines/kyra/loleobbase.h4
-rw-r--r--engines/kyra/magic_eob.cpp13
-rw-r--r--engines/kyra/resource.h16
-rw-r--r--engines/kyra/script_eob.cpp35
-rw-r--r--engines/kyra/script_eob.h7
-rw-r--r--engines/kyra/sprites_eob.cpp6
-rw-r--r--engines/kyra/staticres_eob.cpp23
-rw-r--r--engines/kyra/text_eob.cpp70
25 files changed, 884 insertions, 169 deletions
diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 276564bc64..68fc8cc5b7 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -409,6 +409,22 @@ const ExtractFilename extractFilenames[] = {
{ kEob1MonsterDistAttSfx17, kTypeRawData, false },
{ kEob1TurnUndeadString, kTypeStringList, true },
+ { kEob1NpcShpData, kTypeRawData, false },
+ { kEob1NpcSubShpIndex1, kTypeRawData, false },
+ { kEob1NpcSubShpIndex2, kTypeRawData, false },
+ { kEob1NpcSubShpY, kTypeRawData, false },
+ { kEob1Npc0Strings, kTypeStringList, true },
+ { kEob1Npc11Strings, kTypeStringList, true },
+ { kEob1Npc12Strings, kTypeStringList, true },
+ { kEob1Npc21Strings, kTypeStringList, true },
+ { kEob1Npc22Strings, kTypeStringList, true },
+ { kEob1Npc31Strings, kTypeStringList, true },
+ { kEob1Npc32Strings, kTypeStringList, true },
+ { kEob1Npc4Strings, kTypeStringList, true },
+ { kEob1Npc5Strings, kTypeStringList, true },
+ { kEob1Npc6Strings, kTypeStringList, true },
+ { kEob1Npc7Strings, kTypeStringList, true },
+
// EYE OF THE BEHOLDER II
{ kEob2MainMenuStrings, kTypeStringList, true },
@@ -1624,6 +1640,36 @@ const char *getIdString(const int id) {
return "kEob1MonsterDistAttSfx17";
case kEob1TurnUndeadString:
return "kEob1TurnUndeadString";
+ case kEob1NpcShpData:
+ return "kEob1NpcShpData";
+ case kEob1NpcSubShpIndex1:
+ return "kEob1NpcSubShpIndex1";
+ case kEob1NpcSubShpIndex2:
+ return "kEob1NpcSubShpIndex2";
+ case kEob1NpcSubShpY:
+ return "kEob1NpcSubShpY";
+ case kEob1Npc0Strings:
+ return "kEob1Npc0Strings";
+ case kEob1Npc11Strings:
+ return "kEob1Npc11Strings";
+ case kEob1Npc12Strings:
+ return "kEob1Npc12Strings";
+ case kEob1Npc21Strings:
+ return "kEob1Npc21Strings";
+ case kEob1Npc22Strings:
+ return "kEob1Npc22Strings";
+ case kEob1Npc31Strings:
+ return "kEob1Npc31Strings";
+ case kEob1Npc32Strings:
+ return "kEob1Npc32Strings";
+ case kEob1Npc4Strings:
+ return "kEob1Npc4Strings";
+ case kEob1Npc5Strings:
+ return "kEob1Npc5Strings";
+ case kEob1Npc6Strings:
+ return "kEob1Npc6Strings";
+ case kEob1Npc7Strings:
+ return "kEob1Npc7Strings";
case kEob2MainMenuStrings:
return "kEob2MainMenuStrings";
case kEob2IntroStrings:
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index a587147974..54fd91b394 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -410,6 +410,22 @@ enum kExtractID {
kEob1MonsterDistAttSfx17,
kEob1TurnUndeadString,
+ kEob1NpcShpData,
+ kEob1NpcSubShpIndex1,
+ kEob1NpcSubShpIndex2,
+ kEob1NpcSubShpY,
+ kEob1Npc0Strings,
+ kEob1Npc11Strings,
+ kEob1Npc12Strings,
+ kEob1Npc21Strings,
+ kEob1Npc22Strings,
+ kEob1Npc31Strings,
+ kEob1Npc32Strings,
+ kEob1Npc4Strings,
+ kEob1Npc5Strings,
+ kEob1Npc6Strings,
+ kEob1Npc7Strings,
+
kEob2MainMenuStrings,
kEob2IntroStrings,
kEob2IntroCPSFiles,
diff --git a/devtools/create_kyradat/extract.cpp b/devtools/create_kyradat/extract.cpp
index c9ece8223a..b330c469c6 100644
--- a/devtools/create_kyradat/extract.cpp
+++ b/devtools/create_kyradat/extract.cpp
@@ -1114,7 +1114,7 @@ bool extractEobNpcData(PAKFile &out, const ExtractInformation *info, const byte
WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
src += 4; dst += 4;
// skipping lots of zero space
- src += 60;
+ src += 64;
WRITE_BE_UINT32(dst, READ_LE_UINT32(src));
src += 4; dst += 4;
for (int ii = 0; ii < 27; ii++) {
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 4ab12028c2..5f710507f4 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -1065,6 +1065,22 @@ const int eob1FloppyNeed[] = {
kEob1MonsterDistAttSfx17,
kEob1TurnUndeadString,
+ kEob1NpcShpData,
+ kEob1NpcSubShpIndex1,
+ kEob1NpcSubShpIndex2,
+ kEob1NpcSubShpY,
+ kEob1Npc0Strings,
+ kEob1Npc11Strings,
+ kEob1Npc12Strings,
+ kEob1Npc21Strings,
+ kEob1Npc22Strings,
+ kEob1Npc31Strings,
+ kEob1Npc32Strings,
+ kEob1Npc4Strings,
+ kEob1Npc5Strings,
+ kEob1Npc6Strings,
+ kEob1Npc7Strings,
+
kEobBasePryDoorStrings,
kEobBaseWarningStrings,
diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp
index 46239c2bee..663652d4be 100644
--- a/devtools/create_kyradat/tables.cpp
+++ b/devtools/create_kyradat/tables.cpp
@@ -2368,6 +2368,102 @@ const ExtractEntrySearchData kEob1TurnUndeadStringProvider[] = {
EXTRACT_END_ENTRY
};
+const ExtractEntrySearchData kEob1NpcShpDataProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x0000004C, 0x00000A42, { { 0x70, 0x21, 0x85, 0x8C, 0xD4, 0x04, 0xAA, 0x20, 0x1D, 0x0E, 0x9D, 0xB7, 0x74, 0x58, 0xCC, 0x0C } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1NpcSubShpIndex1Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000035, { { 0x9A, 0x83, 0xF9, 0xA4, 0x27, 0xBA, 0xFC, 0xD2, 0xDE, 0x03, 0x65, 0xF2, 0xFA, 0x37, 0xDA, 0xF1 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1NpcSubShpIndex2Provider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000051, { { 0x7E, 0xAC, 0x0E, 0x54, 0x59, 0x5D, 0xF6, 0x53, 0x03, 0x22, 0x1D, 0xC7, 0xFC, 0x16, 0xC8, 0x88 } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1NpcSubShpYProvider[] = {
+ { UNK_LANG, kPlatformPC, { 0x00000006, 0x00000143, { { 0xC1, 0xED, 0x93, 0x5E, 0x84, 0xCE, 0x48, 0xCF, 0x4C, 0xF3, 0x9C, 0x93, 0xBF, 0xFE, 0xB8, 0x6F } } } },
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc0StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000044, 0x000016E2, { { 0x7C, 0x28, 0x72, 0xC9, 0x57, 0xF5, 0xAB, 0x02, 0xD1, 0x42, 0xE8, 0xA3, 0xF9, 0x33, 0x70, 0xEE } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000050, 0x00001B13, { { 0x69, 0x05, 0xEB, 0xB6, 0x86, 0x81, 0xAC, 0x09, 0x53, 0x35, 0x4D, 0x55, 0xF3, 0x13, 0x6F, 0xC0 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc11StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000001B, 0x00000928, { { 0x86, 0x08, 0x95, 0x6B, 0xBF, 0x12, 0x2D, 0xF9, 0x62, 0x25, 0xD9, 0xAE, 0x25, 0x10, 0xDF, 0xDC } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000001A, 0x000008DB, { { 0xBD, 0xBB, 0x48, 0x8E, 0x04, 0x7D, 0xE4, 0x78, 0xBB, 0x59, 0x6E, 0x86, 0xE1, 0x06, 0x27, 0x50 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc12StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000016, 0x0000079C, { { 0x22, 0x57, 0x3A, 0x9C, 0x7C, 0xDB, 0x55, 0xD0, 0x9C, 0x84, 0x28, 0xA6, 0x9D, 0x40, 0x38, 0x6E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000014, 0x000006ED, { { 0x88, 0x1C, 0x09, 0x61, 0x5D, 0x9D, 0xDE, 0x8A, 0x54, 0x1C, 0x40, 0xCF, 0x28, 0x2B, 0x52, 0x9D } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc21StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000014, 0x000006FD, { { 0x55, 0x77, 0x2F, 0xB0, 0xB3, 0x2D, 0x81, 0x29, 0xDE, 0x71, 0x83, 0x41, 0x06, 0x5B, 0x72, 0x21 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000015, 0x00000748, { { 0x3E, 0x15, 0x27, 0xFD, 0x76, 0xFB, 0x14, 0x8C, 0xF6, 0x14, 0x3E, 0x20, 0x0A, 0x04, 0xF5, 0x32 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc22StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000F, 0x000004D4, { { 0xE5, 0x97, 0x06, 0x45, 0x6A, 0xAC, 0x96, 0x6D, 0x0A, 0xC9, 0xDF, 0x8F, 0x96, 0x2D, 0x01, 0x5D } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000000D, 0x00000439, { { 0x87, 0xCB, 0x17, 0xD2, 0xC8, 0x7F, 0x34, 0xDA, 0x82, 0x30, 0xB2, 0x68, 0xB0, 0x10, 0xD9, 0x52 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc31StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000597, { { 0x5C, 0xEB, 0x0A, 0xE6, 0xB1, 0x37, 0x0E, 0x8F, 0x14, 0xB4, 0x68, 0x86, 0xE5, 0xD2, 0xDE, 0xC7 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000603, { { 0x8E, 0x68, 0x55, 0xCD, 0x29, 0x1E, 0x3C, 0x06, 0x7B, 0x97, 0xE1, 0x07, 0x49, 0x09, 0xF0, 0x57 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc32StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000020, 0x00000AE4, { { 0xED, 0x09, 0x04, 0xEC, 0xE3, 0x43, 0xDA, 0xEE, 0x5D, 0x78, 0x32, 0x63, 0x68, 0xFC, 0x4F, 0x9E } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000020, 0x00000B13, { { 0x87, 0x40, 0x88, 0xA5, 0xE2, 0x6F, 0x83, 0xBC, 0x99, 0x2B, 0xD3, 0xF5, 0x8D, 0x6B, 0x6E, 0x7D } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc4StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x0000000D, 0x0000043C, { { 0x2C, 0xE7, 0xE5, 0xAA, 0xF3, 0x50, 0xA8, 0x6D, 0xC2, 0xC6, 0x88, 0xFE, 0x12, 0x96, 0xFE, 0x54 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000014, 0x00000720, { { 0xF8, 0x58, 0x9A, 0xDB, 0xE5, 0x3F, 0x67, 0x53, 0x1F, 0x27, 0x2E, 0x8D, 0x6E, 0xAD, 0x45, 0xF5 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc5StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000021, 0x00000ABC, { { 0xF1, 0xB5, 0x9E, 0x51, 0x9E, 0xF8, 0x84, 0x95, 0x55, 0x55, 0xE7, 0xDF, 0x36, 0xE1, 0x78, 0x9A } } } },
+ { DE_DEU, kPlatformUnknown, { 0x0000001D, 0x00000A8C, { { 0x4A, 0xAE, 0x5B, 0x3B, 0xAD, 0x18, 0x91, 0x3F, 0xC9, 0x5A, 0x82, 0x5D, 0xA7, 0x06, 0x1A, 0xAE } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc6StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000011, 0x00000612, { { 0x1B, 0xE2, 0x23, 0xD9, 0x00, 0x5C, 0xB9, 0x54, 0xCE, 0xA7, 0x6A, 0x51, 0xF6, 0xBB, 0x8A, 0xC9 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000012, 0x00000647, { { 0x6C, 0x3F, 0xE2, 0xD0, 0xB0, 0x75, 0x2D, 0x73, 0xEE, 0x6F, 0x17, 0x74, 0xAA, 0x7D, 0xA2, 0x21 } } } },
+
+ EXTRACT_END_ENTRY
+};
+
+const ExtractEntrySearchData kEob1Npc7StringsProvider[] = {
+ { EN_ANY, kPlatformUnknown, { 0x00000018, 0x00000777, { { 0x60, 0xB4, 0x17, 0x72, 0x89, 0x87, 0x47, 0xE3, 0xD9, 0xC3, 0x59, 0x16, 0xFD, 0x03, 0x31, 0xD4 } } } },
+ { DE_DEU, kPlatformUnknown, { 0x00000016, 0x000007B6, { { 0xAE, 0xB6, 0x3C, 0x14, 0x2B, 0x34, 0xB8, 0x7C, 0xCF, 0x87, 0xDA, 0x70, 0xBF, 0x0D, 0xAB, 0xE2 } } } },
+
+ 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 } } } },
@@ -3725,6 +3821,22 @@ const ExtractEntry extractProviders[] = {
{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
{ kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },
+ { kEob1NpcShpData, kEob1NpcShpDataProvider },
+ { kEob1NpcSubShpIndex1, kEob1NpcSubShpIndex1Provider },
+ { kEob1NpcSubShpIndex2, kEob1NpcSubShpIndex2Provider },
+ { kEob1NpcSubShpY, kEob1NpcSubShpYProvider },
+ { kEob1Npc0Strings, kEob1Npc0StringsProvider },
+ { kEob1Npc11Strings, kEob1Npc11StringsProvider },
+ { kEob1Npc12Strings, kEob1Npc12StringsProvider },
+ { kEob1Npc21Strings, kEob1Npc21StringsProvider },
+ { kEob1Npc22Strings, kEob1Npc22StringsProvider },
+ { kEob1Npc31Strings, kEob1Npc31StringsProvider },
+ { kEob1Npc32Strings, kEob1Npc32StringsProvider },
+ { kEob1Npc4Strings, kEob1Npc4StringsProvider },
+ { kEob1Npc5Strings, kEob1Npc5StringsProvider },
+ { kEob1Npc6Strings, kEob1Npc6StringsProvider },
+ { kEob1Npc7Strings, kEob1Npc7StringsProvider },
+
{ kEob2MainMenuStrings, kEob2MainMenuStringsProvider },
{ kEob2IntroStrings, kEob2IntroStringsProvider },
{ kEob2IntroCPSFiles, kEob2IntroCPSFilesProvider },
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index 2128a448b6..3b79f0406d 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 d12283f140..95052311ff 100644
--- a/engines/kyra/eob1.cpp
+++ b/engines/kyra/eob1.cpp
@@ -46,6 +46,19 @@ Common::Error EobEngine::init() {
_itemsOverlay = _res->fileData("ITEMRMP.VGA", 0);
+ static const uint16 wX[] = { 285, 139 };
+ static const uint8 wY[] = { 189, 162 };
+ static const uint16 wW[] = { 31, 31 };
+
+ _dialogueButtonLabelCol1 = 9;
+ _dialogueButtonLabelCol2 = 15;
+ _dialogueButtonW = 95;
+ _dialogueButtonH = 9;
+ _waitButtonPresX = wX;
+ _waitButtonPresY = wY;
+ _waitButtonPresW = wW;
+ _waitButtonReverveW = 7;
+
_bkgColor_1 = 132;
_color1_1 = 135;
_color2_1 = 130;
@@ -82,11 +95,227 @@ void EobEngine::startupLoad() {
_sound->loadSoundFile("ADLIB");
}
-void EobEngine::npcSequence(int npcIndex) {
- error("EobEngine::npcSequence(): unimplemented");
+void EobEngine::drawNpcScene(int npcIndex) {
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 6, 0, Screen::CR_NO_P_CHECK);
+ switch (npcIndex) {
+ case 0:
+ encodeDrawNpcSeqShape(2, 88, 104);
+ break;
+
+ case 1:
+ if (_npcSequenceSub == -1) {
+ encodeDrawNpcSeqShape(0, 88, 104);
+ } else {
+ encodeDrawNpcSeqShape(0, 60, 104);
+ encodeDrawNpcSeqShape(5, 116, 104);
+ }
+ break;
+
+ case 2:
+ if (_npcSequenceSub == -1) {
+ encodeDrawNpcSeqShape(3, 88, 104);
+ } else {
+ encodeDrawNpcSeqShape(3, 60, 104);
+ encodeDrawNpcSeqShape(_npcSubShpIndex1[_npcSequenceSub], 116, 104);
+ encodeDrawNpcSeqShape(_npcSubShpIndex2[_npcSequenceSub], 116, _npcSubShpY[_npcSequenceSub]);
+ }
+ break;
+
+ case 3:
+ encodeDrawNpcSeqShape(7, 88, 104);
+ break;
+
+ case 4:
+ encodeDrawNpcSeqShape(6, 88, 104);
+ break;
+
+ case 5:
+ encodeDrawNpcSeqShape(18, 88, 88);
+ break;
+
+ case 6:
+ encodeDrawNpcSeqShape(17, 88, 104);
+ break;
+
+ case 7:
+ encodeDrawNpcSeqShape(4, 88, 104);
+ break;
+
+ default:
+ break;
+ }
+}
+void EobEngine::encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY) {
+ const uint8 *shpDef = &_npcShpData[npcIndex << 2];
+ _screen->_curPage = 2;
+ const uint8 *shp = _screen->encodeShape(shpDef[0], shpDef[1], shpDef[2], shpDef[3]);
+ _screen->_curPage = 0;
+ _screen->drawShape(0, shp, drawX - (shp[2] << 2), drawY - shp[1], 5);
+ delete[] shp;
}
+#define DLG2(txt, buttonstr) (runDialogue(txt, 0, _npc##buttonstr##Strings[0], _npc##buttonstr##Strings[1], 0) - 1)
+#define DLG3(txt, buttonstr) (runDialogue(txt, 1, _npc##buttonstr##Strings[0], _npc##buttonstr##Strings[1], _npc##buttonstr##Strings[2], 0) - 1)
+#define DLG2A3(cond, txt, buttonstr1, buttonstr2) ((cond) ? (DLG2(txt, buttonstr1) ? 2 : 0) : DLG3(txt, buttonstr2))
+#define TXT(txt) _txt->printDialogueText(txt, _moreStrings[0])
+
+void EobEngine::runNpcDialogue(int npcIndex) {
+ int r = 0;
+ int a = 0;
+ Item itm = 0;
+
+ switch (npcIndex) {
+ case 0:
+ for (r = 1; r == 1; ) {
+ gui_drawDialogueBox();
+ r = DLG2A3(checkScriptFlag(0x2000), 8, 12, 11);
+ if (r == 1) {
+ TXT(1);
+ setScriptFlag(0x2000);
+ } else if (r == 0) {
+ npcJoinDialogue(6, 12, 23, 2);
+ setScriptFlag(0x4000);
+ }
+ }
+ break;
+
+ case 1:
+ if (!checkScriptFlag(0x10000)) {
+ if (checkScriptFlag(0x8000)) {
+ a = 1;
+ } else {
+ setScriptFlag(0x8000);
+ r = DLG2(3, 21);
+ }
+ if (!r)
+ r = DLG2(a ? 13 : 4, 22);
+
+ if (!r) {
+ for (a = 0; a < 6; a++)
+ createItemOnCurrentBlock(55);
+ createItemOnCurrentBlock(62);
+ setScriptFlag(0x10000);
+ TXT(6);
+ npcJoinDialogue(7, 7, 29, 30);
+ } else {
+ TXT(5);
+ }
+ r = 1;
+ }
+
+ if (!checkScriptFlag(0x80000)) {
+ for (a = 0; a < 6; a++) {
+ if (testCharacter(a, 1) && _characters[a].portrait == -9)
+ break;
+ }
+ if (a != 6) {
+ TXT(25);
+ TXT(26);
+ setScriptFlag(0x80000);
+ r = 1;
+ }
+ }
+
+ if (!checkScriptFlag(0x100000)) {
+ if (deletePartyItems(6, -1)) {
+ TXT(28);
+ createItemOnCurrentBlock(32);
+ setScriptFlag(0x100000);
+ r = 1;
+ }
+ }
+
+ if (!r)
+ _txt->printDialogueText(_npc0Strings[0], true);
+
+ break;
+
+ case 2:
+ if (checkScriptFlag(0x10000)) {
+ if (checkScriptFlag(0x20000)) {
+ TXT(11);
+ } else {
+ r = DLG2A3(!countResurrectionCandidates(), 9, 31, 32);
+ if (r < 2) {
+ if (r == 0)
+ healParty();
+ else
+ resurrectionSelectDialogue();
+ setScriptFlag(0x20000);
+ }
+ }
+ } else {
+ TXT(24);
+ }
+ break;
+
+ case 3:
+ if (!DLG2(18, 4)) {
+ setScriptFlag(0x8400000);
+ for (a = 0; a < 30; a++) {
+ if (_monsters[a].mode == 8)
+ _monsters[a].mode = 5;
+ }
+ } else if (deletePartyItems(49, -1)) {
+ TXT(20);
+ setScriptFlag(0x400000);
+ } else {
+ TXT(19);
+ }
+ break;
+
+ case 4:
+ r = DLG3(14, 5);
+ if (r == 0)
+ setScriptFlag(0x200000);
+ else if (r == 1)
+ TXT(15);
+ setScriptFlag(0x800000);
+ break;
+
+ case 5:
+ if (!DLG2(16, 6)) {
+ TXT(17);
+ for (a = 0; a < 6; a++) {
+ for (r = 0; r < 2; r++) {
+ itm = _characters[a].inventory[r];
+ if (itm && (_items[itm].type < 51 || _items[itm].type > 56)) {
+ _characters[a].inventory[r] = 0;
+ setItemPosition((Item*)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+ }
+ }
+ }
+ }
+ setScriptFlag(0x2000000);
+ break;
+
+ case 6:
+ TXT(21);
+ setScriptFlag(0x1000000);
+ break;
+
+ case 7:
+ r = DLG3(22, 7);
+ if (r < 2) {
+ if (r == 0)
+ npcJoinDialogue(8, 27, 44, 45);
+ else
+ TXT(31);
+ setScriptFlag(0x4000000);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+#undef TXT
+#undef DLG2
+#undef DLG3
+#undef DLG2A3
+
void EobEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
EobItem *itm = &_items[_characters[charIndex].inventory[slot]];
if (itm->type == 48) {
@@ -269,6 +498,44 @@ bool EobEngine::checkPartyStatusExtra() {
return true;
}
+int EobEngine::resurrectionSelectDialogue() {
+ gui_drawDialogueBox();
+ _txt->printDialogueText(_npc0Strings[1]);
+
+ int r = _rrId[runDialogue(-1, 1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
+
+ if (r < 0) {
+ r = -r;
+ deletePartyItems(33, r);
+ _npcSequenceSub = r - 1;
+ drawNpcScene(2);
+ npcJoinDialogue(_npcSequenceSub, 32 + (_npcSequenceSub << 1), -1, 33 + (_npcSequenceSub << 1));
+ } else {
+ _characters[r].hitPointsCur = _characters[r].hitPointsMax;
+ }
+
+ return 1;
+}
+
+void EobEngine::healParty() {
+ int cnt = rollDice(1, 3, 2);
+ for (int i = 0; i < 6 && cnt; i++) {
+ if (testCharacter(i, 3))
+ continue;
+
+ _characters[i].flags &= ~4;
+ neutralizePoison(i);
+
+ if (_characters[i].hitPointsCur >= _characters[i].hitPointsMax)
+ continue;
+
+ cnt--;
+ _characters[i].hitPointsCur += rollDice(1, 8, 9);
+ if (_characters[i].hitPointsCur > _characters[i].hitPointsMax)
+ _characters[i].hitPointsCur = _characters[i].hitPointsMax;
+ }
+}
+
uint32 EobEngine::convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility) {
uint32 res = 0;
if (flag & 0x01)
diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h
index 8d41118e52..8b805c00e8 100644
--- a/engines/kyra/eob1.h
+++ b/engines/kyra/eob1.h
@@ -56,10 +56,25 @@ private:
void seq_playFinale();
// characters
- void npcSequence(int npcIndex);
-
- //const char *const *_npc1Strings;
- //const char *const *_npc2Strings;
+ void drawNpcScene(int npcIndex);
+ void encodeDrawNpcSeqShape(int npcIndex, int drawX, int drawY);
+ void runNpcDialogue(int npcIndex);
+
+ const uint8 *_npcShpData;
+ const uint8 *_npcSubShpIndex1;
+ const uint8 *_npcSubShpIndex2;
+ const uint8 *_npcSubShpY;
+ const char *const *_npc0Strings;
+ const char *const *_npc11Strings;
+ const char *const *_npc12Strings;
+ const char *const *_npc21Strings;
+ const char *const *_npc22Strings;
+ const char *const *_npc31Strings;
+ const char *const *_npc32Strings;
+ const char *const *_npc4Strings;
+ const char *const *_npc5Strings;
+ const char *const *_npc6Strings;
+ const char *const *_npc7Strings;
// items
void updateUsedCharacterHandItem(int charIndex, int slot);
@@ -92,6 +107,9 @@ private:
// Misc
bool checkPartyStatusExtra();
+ int resurrectionSelectDialogue();
+ void healParty();
+
uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility);
uint32 convertCharacterEffectFlagToEob2Format(uint32 flag);
};
diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp
index cd306863ba..2b4cf46afe 100644
--- a/engines/kyra/eob2.cpp
+++ b/engines/kyra/eob2.cpp
@@ -52,6 +52,19 @@ Common::Error DarkMoonEngine::init() {
_monsterProps = new EobMonsterProperty[10];
+ static const uint16 wX[] = { 221, 76 };
+ static const uint8 wY[] = { 189, 162 };
+ static const uint16 wW[] = { 95, 95 };
+
+ _dialogueButtonLabelCol1 = 9;
+ _dialogueButtonLabelCol2 = 15;
+ _dialogueButtonW = 95;
+ _dialogueButtonH = 9;
+ _waitButtonPresX = wX;
+ _waitButtonPresY = wY;
+ _waitButtonPresW = wW;
+ _waitButtonReverveW = 7;
+
_bkgColor_1 = 183;
_color1_1 = 186;
_color2_1 = 181;
@@ -77,11 +90,8 @@ void DarkMoonEngine::startupNew() {
EobCoreEngine::startupNew();
}
-void DarkMoonEngine::npcSequence(int npcIndex) {
- _screen->loadEobBitmap("OUTTAKE", 5, 3);
- _screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
+void DarkMoonEngine::drawNpcScene(int npcIndex) {
const uint8 *shpDef = &_npcShpData[npcIndex << 3];
-
for (int i = npcIndex; i != 255; i = shpDef[7]) {
shpDef = &_npcShpData[i << 3];
_screen->_curPage = 2;
@@ -90,15 +100,9 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
_screen->drawShape(0, shp, 88 + shpDef[5] - (shp[2] << 2), 104 + shpDef[6] - shp[1], 5);
delete[] shp;
}
+}
- Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
- _screen->loadFileDataToPage(s, 5, 32000);
- delete s;
-
- gui_drawBox(0, 121, 320, 79, _color1_1, _color2_1, _bkgColor_1);
- _txt->setupField(9, true);
- _txt->resetPageBreakString();
-
+void DarkMoonEngine::runNpcDialogue(int npcIndex) {
if (npcIndex == 0) {
snd_playSoundEffect(57);
if (npcJoinDialogue(0, 1, 3, 2))
@@ -108,7 +112,7 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
gui_drawDialogueBox();
_txt->printDialogueText(4, 0);
- int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1]) - 1;
+ int r = runDialogue(-1, 0, _npc1Strings[0], _npc1Strings[1], 0) - 1;
if (r == 0) {
_sound->playTrack(0);
@@ -124,7 +128,7 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
gui_drawDialogueBox();
_txt->printDialogueText(8, 0);
- int r = runDialogue(-1, 0, _npc2Strings[0], _npc2Strings[1]) - 1;
+ int r = runDialogue(-1, 0, _npc2Strings[0], _npc2Strings[1], 0) - 1;
if (r == 0) {
if (rollDice(1, 2, -1))
@@ -136,9 +140,6 @@ void DarkMoonEngine::npcSequence(int npcIndex) {
_currentDirection = 0;
}
}
-
- _txt->removePageBreakFlag();
- gui_restorePlayField();
}
void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
@@ -338,7 +339,40 @@ void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall
}
void DarkMoonEngine::restParty_npc() {
- warning("DarkMoonEngine::restParty_npc(): implement!");
+ int insalId = -1;
+ int numChar = 0;
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (testCharacter(i, 2) && _characters[i].portrait == -1)
+ insalId = i;
+ numChar++;
+ }
+
+ if (insalId == -1 || numChar < 5)
+ return;
+
+ removeCharacterFromParty(insalId);
+ if (insalId < 4)
+ exchangeCharacters(insalId, testCharacter(5, 1) ? 5 : 4);
+
+ clearScriptFlag(6);
+
+ if (!stripPartyItems(1, 1, 1, 1))
+ stripPartyItems(2, 1, 1, 1);
+ stripPartyItems(31, 0, 1, 3);
+ stripPartyItems(39, 1, 0, 3);
+ stripPartyItems(47, 0, 1, 2);
+
+ _items[createItemOnCurrentBlock(28)].value = 26;
+
+ gui_drawPlayField(false);
+ gui_drawAllCharPortraitsWithStats();
+
+ _screen->setClearScreenDim(10);
+ _gui->messageDialogue2(11, 63, 6);
+ _gui->messageDialogue2(11, 64, 6);
}
bool DarkMoonEngine::restParty_extraAbortCondition() {
@@ -357,7 +391,7 @@ void DarkMoonEngine::useHorn(int charIndex, int weaponSlot) {
}
bool DarkMoonEngine::checkPartyStatusExtra() {
- if (checkScriptFlag(0x10))
+ if (checkScriptFlag(0x100000))
seq_dranFools();
return _gui->confirmDialogue2(14, 67, 1);
}
@@ -374,49 +408,12 @@ void DarkMoonEngine::drawLightningColumn() {
}
int DarkMoonEngine::resurrectionSelectDialogue() {
- int cnt = 0;
- const char *namesList[10];
- memset(namesList, 0, 10 * sizeof(const char*));
- int8 indexList[10];
-
- for (int i = 0; i < 6; i++) {
- if (!testCharacter(i, 1))
- continue;
- if (_characters[i].hitPointsCur != -10)
- continue;
-
- namesList[cnt] = _characters[i].name;
- indexList[cnt++] = i;
- }
-
- for (int i = 0; i < 6; i++) {
- if (!testCharacter(i, 1))
- continue;
-
- for (int ii = 0; ii < 27; ii++) {
- uint16 inv = _characters[i].inventory[ii];
- if (!inv)
- continue;
-
- if (_items[inv].type != 33)
- continue;
-
- namesList[cnt] = _npcPreset[_items[inv].value - 1].name;
- indexList[cnt++] = -_items[inv].value;
- }
- }
-
- if (_itemInHand) {
- if (_items[_itemInHand].type == 33) {
- namesList[cnt] = _npcPreset[_items[_itemInHand].value - 1].name;
- indexList[cnt++] = -_items[_itemInHand].value;
- }
- }
+ countResurrectionCandidates();
- namesList[cnt] = _abortStrings[0];
- indexList[cnt++] = 99;
+ _rrNames[_rrCount] = _abortStrings[0];
+ _rrId[_rrCount++] = 99;
- int r = indexList[runDialogue(-1, 1, namesList[0], namesList[1], namesList[2], namesList[3], namesList[4], namesList[5], namesList[6], namesList[7], namesList[8]) - 1];
+ int r = _rrId[runDialogue(-1, 1, _rrNames[0], _rrNames[1], _rrNames[2], _rrNames[3], _rrNames[4], _rrNames[5], _rrNames[6], _rrNames[7], _rrNames[8]) - 1];
if (r == 99)
return 0;
diff --git a/engines/kyra/eob2.h b/engines/kyra/eob2.h
index e1c574a243..f24db79e62 100644
--- a/engines/kyra/eob2.h
+++ b/engines/kyra/eob2.h
@@ -94,7 +94,8 @@ private:
const char *const *_dranFoolsStrings;
// characters
- void npcSequence(int npcIndex);
+ void drawNpcScene(int npcIndex);
+ void runNpcDialogue(int npcIndex);
const uint8 *_npcShpData;
const char *const *_npc1Strings;
diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp
index 22c0519069..eef3873285 100644
--- a/engines/kyra/eobcommon.cpp
+++ b/engines/kyra/eobcommon.cpp
@@ -110,7 +110,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_configHpBarGraphs = true;
memset(_dialogueLastBitmap, 0, 13);
- _dlgUnk1 = 0;
+ _npcSequenceSub = 0;
_moveCounter = 0;
_partyResting = false;
@@ -137,6 +137,10 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_spellAnimBuffer = 0;
_clericSpellOffset = 0;
_restPartyElapsedTime = 0;
+
+ _rrCount = 0;
+ memset(_rrNames, 0, 10 * sizeof(const char*));
+ memset(_rrId, 0, 10 * sizeof(int8));
}
EobCoreEngine::~EobCoreEngine() {
@@ -975,6 +979,26 @@ void EobCoreEngine::neutralizePoison(int character) {
gui_drawCharPortraitWithStats(character);
}
+void EobCoreEngine::npcSequence(int npcIndex) {
+ _screen->loadEobBitmap("OUTTAKE", 5, 3);
+ _screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
+
+ drawNpcScene(npcIndex);
+
+ Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
+ _screen->loadFileDataToPage(s, 5, 32000);
+ delete s;
+
+ gui_drawBox(0, 121, 320, 79, _color1_1, _color2_1, _bkgColor_1);
+ _txt->setupField(9, true);
+ _txt->resetPageBreakString();
+
+ runNpcDialogue(npcIndex);
+
+ _txt->removePageBreakFlag();
+ gui_restorePlayField();
+}
+
void EobCoreEngine::initNpc(int npcIndex) {
EobCharacter *c = _characters;
int i = 0;
@@ -1005,7 +1029,7 @@ int EobCoreEngine::npcJoinDialogue(int npcIndex, int queryJoinTextId, int confir
gui_drawDialogueBox();
_txt->printDialogueText(queryJoinTextId, 0);
- int r = runDialogue(-1, 0, _yesNoStrings[0], _yesNoStrings[1]) - 1;
+ int r = runDialogue(-1, 0, _yesNoStrings[0], _yesNoStrings[1], 0) - 1;
if (r == 0) {
if (confirmJoinTextId == -1) {
Common::String tmp = Common::String::format(_npcJoinStrings[0], _npcPreset[npcIndex].name);
@@ -1030,7 +1054,7 @@ int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
numChars += (_characters[i].flags & 1);
if (numChars < 6) {
- deletePartyItem(itemType, itemValue);
+ deletePartyItems(itemType, itemValue);
} else {
gui_drawDialogueBox();
_txt->printDialogueText(_npcMaxStrings[0]);
@@ -1040,7 +1064,7 @@ int EobCoreEngine::prepareForNewPartyMember(int16 itemType, int16 itemValue) {
if (r == 6)
return 0;
- deletePartyItem(itemType, itemValue);
+ deletePartyItems(itemType, itemValue);
removeCharacterFromParty(r);
}
@@ -1165,11 +1189,11 @@ void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char
va_list args;
va_start(args, str1);
- const char **s5p = va_arg(args, const char**);
+ const char **sp = va_arg(args, const char**);
va_end(args);
for (int i = 1; i < numStr; i++) {
- if (s5p[i - 1])
- _dialogueButtonString[i] = s5p[i - 1];
+ if (sp[i - 1])
+ _dialogueButtonString[i] = sp[i - 1];
else
_dialogueNumButtons = numStr = i;
}
@@ -1191,7 +1215,7 @@ void EobCoreEngine::setupDialogueButtons(int presetfirst, int numStr, const char
}
void EobCoreEngine::initDialogueSequence() {
- _dlgUnk1 = -1;
+ _npcSequenceSub = -1;
_txt->setWaitButtonMode(0);
_dialogueField = true;
@@ -1435,6 +1459,47 @@ void EobCoreEngine::displayParchment(int id) {
restoreAfterDialogueSequence();
}
+int EobCoreEngine::countResurrectionCandidates() {
+ _rrCount = 0;
+ memset(_rrNames, 0, 10 * sizeof(const char*));
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+ if (_characters[i].hitPointsCur != -10)
+ continue;
+
+ _rrNames[_rrCount] = _characters[i].name;
+ _rrId[_rrCount++] = i;
+ }
+
+ for (int i = 0; i < 6; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+
+ for (int ii = 0; ii < 27; ii++) {
+ uint16 inv = _characters[i].inventory[ii];
+ if (!inv)
+ continue;
+
+ if ((_flags.gameID == GI_EOB1 && ((_itemTypes[_items[inv].type].extraProperties & 0x7f) != 8)) || (_flags.gameID == GI_EOB2 && _items[inv].type != 33))
+ continue;
+
+ _rrNames[_rrCount] = _npcPreset[_items[inv].value - 1].name;
+ _rrId[_rrCount++] = -_items[inv].value;
+ }
+ }
+
+ if (_itemInHand > 0) {
+ if ((_flags.gameID == GI_EOB1 && ((_itemTypes[_items[_itemInHand].type].extraProperties & 0x7f) == 8)) || (_flags.gameID == GI_EOB2 && _items[_itemInHand].type == 33)) {
+ _rrNames[_rrCount] = _npcPreset[_items[_itemInHand].value - 1].name;
+ _rrId[_rrCount++] = -_items[_itemInHand].value;
+ }
+ }
+
+ return _rrCount;
+}
+
void EobCoreEngine::useSlotWeapon(int charIndex, int slotIndex, Item item) {
EobCharacter *c = &_characters[charIndex];
int tp = item ? _items[item].type : 0;
@@ -1621,7 +1686,7 @@ int EobCoreEngine::calcCharacterDamage(int charIndex, int times, int itemOrPips,
EobCharacter *c = &_characters[charIndex];
if (a != 5) {
- if (checkUnkConstModifiers(c, _charClassModUnk[c->cClass], c->level[0], a, c->raceSex))
+ if (checkMonsterLevelConstModifiers(c, _charClassModUnk[c->cClass], c->level[0], a, c->raceSex))
s = recalcDamageModifier(damageType, s);
}
@@ -1699,7 +1764,7 @@ bool EobCoreEngine::characterAttackHitTest(int charIndex, int monsterIndex, int
if (_flags.gameID == GI_EOB2) {
if ((p > 0 && p < 4) || !item ){
- if (((_monsterProps[t].statusFlags & 0x200) && (d <= 0)) || ((_monsterProps[t].statusFlags & 0x1000) && (d <= 1)))
+ if (((_monsterProps[t].immunityFlags & 0x200) && (d <= 0)) || ((_monsterProps[t].immunityFlags & 0x1000) && (d <= 1)))
return false;
}
}
@@ -1877,7 +1942,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
EobMonsterProperty *p = &_monsterProps[m->type];
if (b == 5) {
- if (checkUnkConstModifiers(m, 0, p->level, b, 6))
+ if (checkMonsterLevelConstModifiers(m, 0, p->level, b, 6))
s = recalcDamageModifier(damageType, s);
}
@@ -1886,10 +1951,12 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
s = 1;
}
- if ((flags & 0x100) && ((_flags.gameID == GI_EOB2 && (p->statusFlags & 0x100)) || (_flags.gameID == GI_EOB1 && (p->capsFlags & 4))) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)))
- s >>= 1;
+ if ((flags & 0x100) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)) &&
+ ((_flags.gameID == GI_EOB2 && (p->immunityFlags & 0x100)) ||
+ (_flags.gameID == GI_EOB1 && (p->capsFlags & 4))))
+ s >>= 1;
- if (p->statusFlags & 0x2000) {
+ if (p->immunityFlags & 0x2000) {
if (flags & 0x100) {
if (_items[pips].value < 3)
s >>= 2;
@@ -1913,7 +1980,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
static const uint16 damageImmunityFlags[] = { 0x01, 0x10, 0x02, 0x20, 0x80, 0x400, 0x20, 0x800, 0x40, 0x80, 0x400, 0x40 };
for (int i = 0; i < 12; i += 2) {
- if ((flags & damageImmunityFlags[i]) && (p->statusFlags & damageImmunityFlags[i + 1]))
+ if ((flags & damageImmunityFlags[i]) && (p->immunityFlags & damageImmunityFlags[i + 1]))
s = 0;
}
@@ -1935,7 +2002,7 @@ int EobCoreEngine::calcDamageModifers(int charIndex, EobMonsterInPlay *m, int it
return (s < 0) ? 0 : s;
}
-bool EobCoreEngine::checkUnkConstModifiers(void *target, int hpModifier, int level, int b, int race) {
+bool EobCoreEngine::checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race) {
static const int8 constMod[] = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5 };
if (b == 5)
@@ -1951,7 +2018,7 @@ bool EobCoreEngine::checkUnkConstModifiers(void *target, int hpModifier, int lev
}
bool EobCoreEngine::specialAttackConstTest(int charIndex, int b) {
- return checkUnkConstModifiers(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], b, _characters[charIndex].raceSex >> 1);
+ return checkMonsterLevelConstModifiers(&_characters[charIndex], _charClassModUnk[_characters[charIndex].cClass], _characters[charIndex].level[0], b, _characters[charIndex].raceSex >> 1);
}
int EobCoreEngine::getConstModifierTableValue(int hpModifier, int level, int b) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 6463f839c8..1c730f7687 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -158,7 +158,7 @@ struct SpriteDecoration {
struct EobMonsterProperty {
int8 armorClass;
int8 hitChance;
- uint8 level;
+ int8 level;
uint8 hpDcTimes;
uint8 hpDcPips;
uint8 hpDcBase;
@@ -168,7 +168,7 @@ struct EobMonsterProperty {
uint8 pips;
int8 base;
} dmgDc[3];
- uint16 statusFlags;
+ uint16 immunityFlags;
uint32 capsFlags;
uint32 typeFlags;
int32 experience;
@@ -376,7 +376,9 @@ protected:
void modifyCharacterHitpoints(int character, int16 points);
void neutralizePoison(int character);
- virtual void npcSequence(int npcIndex) = 0;
+ void npcSequence(int npcIndex);
+ virtual void drawNpcScene(int npcIndex) = 0;
+ virtual void runNpcDialogue(int npcIndex) = 0;
void initNpc(int npcIndex);
int npcJoinDialogue(int npcIndex, int queryJoinTextId, int confirmJoinTextId, int noJoinTextId);
int prepareForNewPartyMember(int16 itemType, int16 itemValue);
@@ -405,6 +407,7 @@ protected:
const uint8 *_constModExt;
const EobCharacter *_npcPreset;
+ int _npcSequenceSub;
bool _partyResting;
bool _loading;
@@ -412,11 +415,13 @@ protected:
void loadItemDefs();
Item duplicateItem(Item itemIndex);
void setItemPosition(Item *itemQueue, int block, Item item, int pos);
- void createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot);
+ Item createItemOnCurrentBlock(Item itemIndex);
+ void createInventoryItem(EobCharacter *c, Item itemIndex, int16 itemValue, int preferedInventorySlot);
int deleteInventoryItem(int charIndex, int slot);
void deleteBlockItem(uint16 block, int type);
int validateInventorySlotForItem(Item item, int charIndex, int slot);
- void deletePartyItem(Item itemType, int16 itemValue);
+ int stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems);
+ bool deletePartyItems(int16 itemType, int16 itemValue);
virtual void updateUsedCharacterHandItem(int charIndex, int slot) = 0;
int itemUsableByCharacter(int charIndex, Item item);
int countQueuedItems(Item itemQueue, int16 id, int16 type, int count, int includeFlyingItems);
@@ -622,6 +627,7 @@ protected:
// Script
void runLevelScript(int block, int flags);
void setScriptFlag(int flag);
+ void clearScriptFlag(int flag);
bool checkScriptFlag(int flag);
const uint8 *initScriptTimers(const uint8 *pos);
@@ -739,7 +745,6 @@ protected:
int runDialogue(int dialogueTextId, int style, const char *button1, ...);
char _dialogueLastBitmap[13];
- int _dlgUnk1;
int _moveCounter;
uint8 _color4;
@@ -803,11 +808,12 @@ protected:
// misc
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
void displayParchment(int id);
+ int countResurrectionCandidates();
+ virtual int resurrectionSelectDialogue() = 0;
virtual void useHorn(int charIndex, int weaponSlot) {}
virtual bool checkPartyStatusExtra() = 0;
virtual void drawLightningColumn() {}
- virtual int resurrectionSelectDialogue() { return -1; }
virtual int charSelectDialogue() { return -1; }
virtual void characterLevelGain(int charIndex) {}
@@ -820,6 +826,10 @@ protected:
const char * const *_saveLoadStrings;
+ int _rrCount;
+ const char *_rrNames[10];
+ int8 _rrId[10];
+
Screen_Eob *_screen;
GUI_Eob *_gui;
@@ -846,7 +856,7 @@ protected:
int calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times, int pips, int offs, int flags, int b, int damageType);
int calcDamageModifers(int charIndex, EobMonsterInPlay *m, int item, int itemType, int useStrModifier);
- bool checkUnkConstModifiers(void *target, int hpModifier, int level, int b, int race);
+ bool checkMonsterLevelConstModifiers(void *target, int hpModifier, int level, int b, int race);
bool specialAttackConstTest(int charIndex, int b);
int getConstModifierTableValue(int hpModifier, int level, int b);
bool calcDamageCheckItemType(int itemType);
@@ -1045,6 +1055,7 @@ protected:
const char *const *_menuStringsDefeat;
const char *_errorSlotEmptyString;
const char *_errorSlotNoNameString;
+ const char *_menuOkString;
const char *const *_menuStringsTransfer;
const char *const *_menuStringsSpec;
diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp
index ce5f3ea53f..c495eb541f 100644
--- a/engines/kyra/gui_eob.cpp
+++ b/engines/kyra/gui_eob.cpp
@@ -385,7 +385,7 @@ void EobCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
if (itm)
drawItemIconShape(_screen->_curPage, itm, x + 8, y);
- else if (!slot && checkScriptFlag(0x8000))
+ else if (!slot && _flags.gameID == GI_EOB2 && checkScriptFlag(0x80000000))
_screen->drawShape(_screen->_curPage, _itemIconShapes[103], x + 8, y, 0);
else
_screen->drawShape(_screen->_curPage, _itemIconShapes[85], x + 8, y, 0);
@@ -2410,6 +2410,44 @@ bool GUI_Eob::confirmDialogue2(int dim, int id, int deflt) {
return newHighlight ? false : true;
}
+void GUI_Eob::messageDialogue2(int dim, int id, int buttonTextCol) {
+ drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+
+ _screen->_curPage = 2;
+ _screen->setClearScreenDim(dim);
+ drawMenuButtonBox(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, false, false);
+ _screen->printShadedText(getMenuString(id), (_screen->_curDim->sx << 3) + 5, _screen->_curDim->sy + 5, 15, 0);
+ _screen->_curPage = 0;
+ _screen->copyRegion(_screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->sx << 3, _screen->_curDim->sy, _screen->_curDim->w << 3, _screen->_curDim->h, 2, 0, Screen::CR_NO_P_CHECK);
+
+ int x = (_screen->_curDim->sx << 3) + (_screen->_curDim->w << 2) - (strlen(_vm->_menuOkString) << 2);
+ int y = _screen->_curDim->sy + _screen->_curDim->h - 21;
+ int w = (strlen(_vm->_menuOkString) << 3) + 8;
+ drawMenuButtonBox(x, y, w, 14, false, false);
+ _screen->printShadedText(_vm->_menuOkString, x + 4, y + 3, buttonTextCol, 0);
+ _screen->updateScreen();
+
+ for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
+ int inputFlag = _vm->checkInput(0, false, 0) & 0x8ff;
+ _vm->removeInputTop();
+
+ if (inputFlag == 199 || inputFlag == 201) {
+ if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, y, x + w, y + 14))
+ runLoop = false;
+ } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
+ runLoop = false;
+ }
+ }
+
+ _vm->gui_drawBox(x, y, w, 14, _vm->_color2_1, _vm->_bkgColor_1, -1);
+ _screen->updateScreen();
+ _vm->_system->delayMillis(80);
+ drawMenuButtonBox(x, y, w, 14, false, false);
+ _screen->printShadedText(_vm->_menuOkString, x + 4, y + 3, buttonTextCol, 0);
+ _screen->updateScreen();
+
+}
+
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
@@ -3375,11 +3413,12 @@ bool GUI_Eob::restParty() {
_screen->setScreenDim(4);
_screen->setFont(Screen::FID_8_FNT);
- if (!injured && !res)
- displayTextBox(43);
-
- if (res && hours > 4)
- _vm->restParty_npc();
+ if (!res) {
+ if (!injured)
+ displayTextBox(43);
+ if (hours > 4)
+ _vm->restParty_npc();
+ }
return res;
}
@@ -3447,8 +3486,6 @@ bool GUI_Eob::confirmDialogue(int id) {
}
void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
- static const char buttonText[] = "OK";
-
int od = _screen->curDimIndex();
_screen->setScreenDim(dim);
Screen::FontId of = _screen->setFont(Screen::FID_8_FNT);
@@ -3456,12 +3493,12 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
drawTextBox(dim, id);
const ScreenDim *dm = _screen->getScreenDim(dim);
- int bx = ((dm->sx + dm->w) << 3) - ((strlen(buttonText) << 3) + 16);
+ int bx = ((dm->sx + dm->w) << 3) - ((strlen(_vm->_menuOkString) << 3) + 16);
int by = dm->sy + dm->h - 19;
- int bw = (strlen(buttonText) << 3) + 7;
+ int bw = (strlen(_vm->_menuOkString) << 3) + 7;
drawMenuButtonBox(bx, by, bw, 14, false, false);
- _screen->printShadedText(buttonText, bx + 4, by + 3, buttonTextCol, 0);
+ _screen->printShadedText(_vm->_menuOkString, bx + 4, by + 3, buttonTextCol, 0);
_screen->updateScreen();
for (bool runLoop = true; runLoop && !_vm->shouldQuit(); ) {
@@ -3469,9 +3506,8 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
_vm->removeInputTop();
if (inputFlag == 199 || inputFlag == 201) {
- Common::Point p = _vm->getMousePos();
- if (_vm->posWithinRect(p.x, p.y, bx, by, bx + bw, by + 14))
- runLoop = false;
+ if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, bx, by, bx + bw, by + 14))
+ runLoop = false;
} else if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN] || inputFlag == _vm->_keyMap[Common::KEYCODE_o]) {
runLoop = false;
}
diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h
index 709c676517..af3d3d2e48 100644
--- a/engines/kyra/gui_eob.h
+++ b/engines/kyra/gui_eob.h
@@ -63,6 +63,8 @@ public:
bool runLoadMenu(int x, int y);
bool confirmDialogue2(int dim, int id, int deflt);
+ void messageDialogue2(int dim, int id, int buttonTextCol);
+
void updateBoxFrameHighLight(int box);
int getTextInput(char *dest, int x, int y, int destMaxLen, int textColor1, int textColor2, int cursorColor);
diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp
index de5fe6b32a..78d3f8b8aa 100644
--- a/engines/kyra/items_eob.cpp
+++ b/engines/kyra/items_eob.cpp
@@ -103,6 +103,12 @@ Kyra::Item EobCoreEngine::duplicateItem(Item itemIndex) {
return i;
}
+Item EobCoreEngine::createItemOnCurrentBlock(Item itemIndex) {
+ Item itm = duplicateItem(itemIndex);
+ setItemPosition((Item*)&_levelBlockProperties[_currentBlock].drawObjects, _currentBlock, itm, _dropItemDirIndex[(_currentDirection << 2) + rollDice(1, 2, -1)]);
+ return itm;
+}
+
void EobCoreEngine::setItemPosition(Item *itemQueue, int block, Item item, int pos) {
if (!item)
return;
@@ -123,7 +129,7 @@ void EobCoreEngine::setItemPosition(Item *itemQueue, int block, Item item, int p
}
}
-void EobCoreEngine::createInventoryItem(EobCharacter *c, Item itemIndex, int itemValue, int preferedInventorySlot) {
+void EobCoreEngine::createInventoryItem(EobCharacter *c, Item itemIndex, int16 itemValue, int preferedInventorySlot) {
if (itemIndex <= 0)
return;
@@ -214,7 +220,35 @@ int EobCoreEngine::validateInventorySlotForItem(Item item, int charIndex, int sl
return 0;
}
-void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
+int EobCoreEngine::stripPartyItems(int16 itemType, int16 itemValue, int handleValueMode, int numItems) {
+ int itemsLeft = numItems;
+
+ for (bool runloop = true; runloop && itemsLeft; ) {
+ runloop = false;
+ for (int i = 0; i < 6 && itemsLeft; i++) {
+ if (!testCharacter(i, 1))
+ continue;
+
+ for (int ii = 0; ii < 27 && itemsLeft; ii++) {
+ if (ii == 16)
+ continue;
+
+ Item itm = _characters[i].inventory[ii];
+ if ((_items[itm].type == itemType) && ((handleValueMode == -1 && _items[itm].value <= itemValue) || (handleValueMode == 0 && _items[itm].value == itemValue) || (handleValueMode == 1 && _items[itm].value >= itemValue))) {
+ _characters[i].inventory[ii] = 0;
+ _items[itm].block = -1;
+ itemsLeft--;
+ runloop = true;
+ }
+ }
+ }
+ }
+
+ return numItems - itemsLeft;
+}
+
+bool EobCoreEngine::deletePartyItems(int16 itemType, int16 itemValue) {
+ bool res = false;
for (int i = 0; i < 6; i++) {
if (!testCharacter(i, 1))
continue;
@@ -228,13 +262,26 @@ void EobCoreEngine::deletePartyItem(Item itemType, int16 itemValue) {
int itm = c->inventory[slot];
_items[itm].block = -1;
c->inventory[slot] = 0;
+ res = true;
- if (_currentControlMode == 0 && slot < 2 && i < 5)
- gui_drawWeaponSlot(i, slot);
+ if (!_dialogueField) {
+ if (_currentControlMode == 0 && slot < 2 && i < 5)
+ gui_drawWeaponSlot(i, slot);
- if (_currentControlMode == 1 && i == _updateCharNum)
- gui_drawInventoryItem(slot, 1, 0);
+ if (_currentControlMode == 1 && i == _updateCharNum)
+ gui_drawInventoryItem(slot, 1, 0);
+ }
}
+
+ if (_itemInHand > 0) {
+ if ((itemType == -1 || itemType == _items[_itemInHand].type) && (itemValue == -1 || itemValue == _items[_itemInHand].value)) {
+ _items[_itemInHand].block = -1;
+ setHandItem(0);
+ res = true;
+ }
+ }
+
+ return res;
}
int EobCoreEngine::itemUsableByCharacter(int charIndex, Item item) {
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 7a4a3ec3e2..4fc78c0b64 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -376,11 +376,14 @@ Common::Error LoLEngine::init() {
assert(_gui);
_gui->initStaticData();
- _txt = new TextDisplayer_LoL(this, _screen);
_dialogueButtonLabelCol1 = 144;
_dialogueButtonLabelCol2 = 254;
_dialogueButtonW = 74;
_dialogueButtonH = 9;
+ _waitButtonReverveW = 80;
+
+ _txt = new TextDisplayer_LoL(this, _screen);
+
_bkgColor_1 = -1;
_color1_1 = 136;
_color2_1 = 251;
diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp
index 47a261be6f..2ffae915b1 100644
--- a/engines/kyra/loleobbase.cpp
+++ b/engines/kyra/loleobbase.cpp
@@ -103,10 +103,14 @@ LolEobBaseEngine::LolEobBaseEngine(OSystem *system, const GameFlags &flags) : Ky
_dialogueNumButtons = _dialogueButtonYoffs = _dialogueHighlightedButton = 0;
_currentControlMode = 0;
_specialSceneFlag = 0;
- _dialogueButtonLabelCol1 = 9;
- _dialogueButtonLabelCol2 = 15;
- _dialogueButtonW = 95;
- _dialogueButtonH = 9;
+ _dialogueButtonLabelCol1 = 0;
+ _dialogueButtonLabelCol2 = 0;
+ _dialogueButtonW = 0;
+ _dialogueButtonH = 0;
+ _waitButtonPresX = 0;
+ _waitButtonPresY = 0;
+ _waitButtonPresW = 0;
+ _waitButtonReverveW = 0;
_updateCharNum = -1;
_activeVoiceFileTotalTime = 0;
diff --git a/engines/kyra/loleobbase.h b/engines/kyra/loleobbase.h
index a2c13827fc..ba59fe796b 100644
--- a/engines/kyra/loleobbase.h
+++ b/engines/kyra/loleobbase.h
@@ -281,6 +281,10 @@ protected:
int16 _dialogueButtonYoffs;
uint16 _dialogueButtonW;
uint16 _dialogueButtonH;
+ const uint16 *_waitButtonPresX;
+ const uint8 *_waitButtonPresY;
+ const uint16 *_waitButtonPresW;
+ int _waitButtonReverveW;
int _dialogueNumButtons;
int _dialogueHighlightedButton;
int _currentControlMode;
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index f828625dbb..70e4892342 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -555,11 +555,11 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d
bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod) {
EobMonsterProperty *p = &_monsterProps[m->type];
if (tryEvade) {
- if (tryMonsterAttackEvasion(m) || (p->capsFlags & 0x10))
+ if (tryMonsterAttackEvasion(m) || (p->immunityFlags & 0x10))
return true;
}
- if (checkUnkConstModifiers(m, 0, p->level, mod, 6))
+ if (checkMonsterLevelConstModifiers(m, 0, p->level, mod, 6))
return false;
int para = 0;
@@ -569,7 +569,7 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
case 1:
case 2:
para = (type == 0) ? ((p->typeFlags & 1) ? 1 : 0) : ((type == 1) ? ((p->typeFlags & 2) ? 1 : 0) : 1);
- if (para && !(p->statusFlags & 2)) {
+ if (para && !(p->immunityFlags & 2)) {
m->mode = 10;
m->spellStatusLeft = 15;
}
@@ -577,7 +577,7 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
break;
case 3:
- if (!(p->statusFlags & 8))
+ if (!(p->immunityFlags & 8))
inflictMonsterDamage(m, 1000, true);
break;
@@ -591,12 +591,11 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try
break;
case 6:
- if (!(p->statusFlags & 4) && m->mode != 7 && m->mode != 8 && m->mode != 10) {
+ if (!(_flags.gameID == GI_EOB1 && !(p->typeFlags & 3)) && !(p->immunityFlags & 4) && m->mode != 7 && m->mode != 8 && m->mode != 10) {
m->mode = 0;
m->spellStatusLeft = 20;
- para = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1;
m->flags |= 8;
- walkMonsterNextStep(m, -1, para);
+ walkMonsterNextStep(m, -1, (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1);
}
break;
diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h
index 5328aeff35..55946e5b7f 100644
--- a/engines/kyra/resource.h
+++ b/engines/kyra/resource.h
@@ -484,6 +484,22 @@ enum KyraResources {
kEob1TurnUndeadString,
+ kEob1NpcShpData,
+ kEob1NpcSubShpIndex1,
+ kEob1NpcSubShpIndex2,
+ kEob1NpcSubShpY,
+ kEob1Npc0Strings,
+ kEob1Npc11Strings,
+ kEob1Npc12Strings,
+ kEob1Npc21Strings,
+ kEob1Npc22Strings,
+ kEob1Npc31Strings,
+ kEob1Npc32Strings,
+ kEob1Npc4Strings,
+ kEob1Npc5Strings,
+ kEob1Npc6Strings,
+ kEob1Npc7Strings,
+
kEob2MainMenuStrings,
kEob2IntroStrings,
kEob2IntroCPSFiles,
diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp
index 833413c69b..1e113fb2ae 100644
--- a/engines/kyra/script_eob.cpp
+++ b/engines/kyra/script_eob.cpp
@@ -40,8 +40,12 @@ void EobCoreEngine::setScriptFlag(int flag) {
_inf->setFlag(flag);
}
+void EobCoreEngine::clearScriptFlag(int flag) {
+ _inf->clearFlag(flag);
+}
+
bool EobCoreEngine::checkScriptFlag(int flag) {
- return _inf->checkFlag(0x8000);
+ return _inf->checkFlag(flag);
}
const uint8 *EobCoreEngine::initScriptTimers(const uint8 *pos) {
@@ -188,6 +192,22 @@ void EobInfProcessor::run(int func, int sub) {
} while (!_abortScript && !_abortAfterSubroutine);
}
+void EobInfProcessor::setFlag(int flag) {
+ _flagTable[17] |= flag;
+}
+
+void EobInfProcessor::clearFlag(int flag) {
+ _flagTable[17] &= ~flag;
+}
+
+bool EobInfProcessor::checkFlag(int flag) const {
+ return (_flagTable[17] & flag) ? true : false;
+}
+
+bool EobInfProcessor::preventRest() const {
+ return _preventRest ? true : false;
+}
+
void EobInfProcessor::loadState(Common::SeekableSubReadStreamEndian &in) {
_preventRest = in.readByte();
for (int i = 0; i < 18; i++)
@@ -469,11 +489,11 @@ int EobInfProcessor::oeob_moveInventoryItemToBlock(int8 *data) {
}
int EobInfProcessor::oeob_printMessage_v1(int8 *data) {
- static const char ColorConfig[] = { 6, 33, 2, 33, 0 };
+ static const char colorConfig[] = "\x6\x21\x2\x21";
char col[5];
int8 *pos = data;
- strcpy(col, ColorConfig);
+ strcpy(col, colorConfig);
const char *str = (const char*) pos;
pos += (strlen(str) + 1);
@@ -720,7 +740,7 @@ int EobInfProcessor::oeob_eval_v1(int8 *data) {
for (i = 0; i < 6; i++) {
if (!(_vm->_characters[i].flags & 1))
continue;
- if ((_vm->_characters[a].raceSex >> 1) == cmd) {
+ if ((_vm->_characters[i].raceSex >> 1) == cmd) {
b = 1;
break;
}
@@ -1371,7 +1391,7 @@ int EobInfProcessor::oeob_identifyItems(int8 *data) {
int EobInfProcessor::oeob_sequence(int8 *data) {
int8 *pos = data;
- _vm->_dlgUnk1 = -1;
+ _vm->_npcSequenceSub = -1;
_vm->txt()->setWaitButtonMode(0);
_vm->gui_updateControls();
_vm->drawScene(1);
@@ -1402,7 +1422,6 @@ int EobInfProcessor::oeob_sequence(int8 *data) {
case -1:
// copy protection
- error("EobInfProcessor::oeob_sequence(): unimplemented cmd -1");
break;
default:
@@ -1508,8 +1527,8 @@ int EobInfProcessor::oeob_specialEvent(int8 *data) {
break;
case 5:
- _vm->deletePartyItem(46, 5);
- _vm->deletePartyItem(46, 6);
+ _vm->deletePartyItems(46, 5);
+ _vm->deletePartyItems(46, 6);
break;
case 6:
diff --git a/engines/kyra/script_eob.h b/engines/kyra/script_eob.h
index 322322ae1f..71e53bc802 100644
--- a/engines/kyra/script_eob.h
+++ b/engines/kyra/script_eob.h
@@ -42,9 +42,10 @@ public:
void loadData(const uint8 *data, uint32 dataSize);
void run(int func, int sub);
- void setFlag(int flag) { _flagTable[17] |= flag; }
- bool checkFlag(int flag) const { return (_flagTable[17] & flag) ? true : false; }
- bool preventRest() const { return _preventRest ? true : false; }
+ void setFlag(int flag);
+ void clearFlag(int flag);
+ bool checkFlag(int flag) const;
+ bool preventRest() const;
void loadState(Common::SeekableSubReadStreamEndian &in);
void saveState(Common::OutSaveFile *out);
diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp
index 0874de82e3..97ee51bd22 100644
--- a/engines/kyra/sprites_eob.cpp
+++ b/engines/kyra/sprites_eob.cpp
@@ -83,7 +83,7 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
EobMonsterProperty *d = &_monsterProps[cmd];
d->armorClass = (int8)*data++;
d->hitChance = (int8)*data++;
- d->level = *data++;
+ d->level = (int8)*data++;
d->hpDcTimes = *data++;
d->hpDcPips = *data++;
d->hpDcBase = *data++;
@@ -97,7 +97,7 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
d->dmgDc[2].times = *data++;
d->dmgDc[2].pips = *data++;
d->dmgDc[3].base = (int8)*data++;
- d->statusFlags = READ_LE_UINT16(data);
+ d->immunityFlags = READ_LE_UINT16(data);
data += 2;
d->capsFlags = READ_LE_UINT16(data);
data += 2;
@@ -185,7 +185,7 @@ void EobCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int
m->spellStatusLeft = i;
m->dir = dir;
m->palette = _flags.gameID == GI_EOB2 ? (index % 3) : 0;
- m->hitPointsCur = m->hitPointsMax = _flags.gameID == GI_EOB2 ? rollDice(p->hpDcTimes, p->hpDcPips, p->hpDcBase) : (p->hpDcTimes == 255 ? rollDice(1, 4, 0) : rollDice(p->hpDcTimes, 8, 0));
+ m->hitPointsCur = m->hitPointsMax = _flags.gameID == GI_EOB2 ? rollDice(p->hpDcTimes, p->hpDcPips, p->hpDcBase) : (p->level == -1 ? rollDice(1, 4, 0) : rollDice(p->level, 8, 0));
m->randItem = randItem;
m->fixedItem = fixedItem;
m->sub = _currentSub;
diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp
index 1cf78eef5c..ea943f32d4 100644
--- a/engines/kyra/staticres_eob.cpp
+++ b/engines/kyra/staticres_eob.cpp
@@ -151,7 +151,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p
s->raceSex = stream.readByte();
s->cClass = stream.readByte();
s->alignment = stream.readByte();
- s->portrait = stream.readByte();
+ s->portrait = stream.readSByte();
s->food = stream.readByte();
stream.read(s->level, 3);
s->experience[0] = stream.readUint32BE();
@@ -159,7 +159,7 @@ bool StaticResource::loadEobNpcData(Common::SeekableReadStream &stream, void *&p
s->experience[2] = stream.readUint32BE();
s->mageSpellsAvailableFlags = stream.readUint32BE();
for (int ii = 0; ii < 27; ii++)
- s->inventory[i] = stream.readUint16BE();
+ s->inventory[ii] = stream.readSint16BE();
}
ptr = e;
@@ -555,6 +555,7 @@ void EobCoreEngine::initStaticResource() {
_saveLoadStrings = saveLoadStrings[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
_errorSlotEmptyString = errorSlotEmptyString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
_errorSlotNoNameString = errorSlotNoNameString[(_flags.lang == Common::EN_ANY) ? 0 : ((_flags.lang == Common::DE_DEU) ? 1 : 2)];
+ _menuOkString = "OK";
}
void EobCoreEngine::initButtonData() {
@@ -1068,6 +1069,22 @@ void EobEngine::initStaticResource() {
_turnUndeadString = _staticres->loadStrings(kEob1TurnUndeadString, temp);
+ _npcShpData = _staticres->loadRawData(kEob1NpcShpData, temp);
+ _npcSubShpIndex1 = _staticres->loadRawData(kEob1NpcSubShpIndex1, temp);
+ _npcSubShpIndex2 = _staticres->loadRawData(kEob1NpcSubShpIndex2, temp);
+ _npcSubShpY = _staticres->loadRawData(kEob1NpcSubShpY, temp);
+ _npc0Strings = _staticres->loadStrings(kEob1Npc0Strings, temp);
+ _npc11Strings = _staticres->loadStrings(kEob1Npc11Strings, temp);
+ _npc12Strings = _staticres->loadStrings(kEob1Npc12Strings, temp);
+ _npc21Strings = _staticres->loadStrings(kEob1Npc21Strings, temp);
+ _npc22Strings = _staticres->loadStrings(kEob1Npc22Strings, temp);
+ _npc31Strings = _staticres->loadStrings(kEob1Npc31Strings, temp);
+ _npc32Strings = _staticres->loadStrings(kEob1Npc32Strings, temp);
+ _npc4Strings = _staticres->loadStrings(kEob1Npc4Strings, temp);
+ _npc5Strings = _staticres->loadStrings(kEob1Npc5Strings, temp);
+ _npc6Strings = _staticres->loadStrings(kEob1Npc6Strings, temp);
+ _npc7Strings = _staticres->loadStrings(kEob1Npc7Strings, temp);
+
const uint8 *ps = _staticres->loadRawData(kEob1MonsterProperties, temp);
temp /= 27;
_monsterProps = new EobMonsterProperty[temp];
@@ -1077,7 +1094,7 @@ void EobEngine::initStaticResource() {
EobMonsterProperty *p = &_monsterProps[i];
p->armorClass = (int8)*ps++;
p->hitChance = (int8)*ps++;
- p->hpDcTimes = *ps++;
+ p->level = (int8)*ps++;
p->attacksPerRound = *ps++;
p->dmgDc[0].times = *ps++;
p->dmgDc[0].pips = *ps++;
diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp
index 63d893d2cc..80858d1743 100644
--- a/engines/kyra/text_eob.cpp
+++ b/engines/kyra/text_eob.cpp
@@ -29,14 +29,16 @@
#include "common/system.h"
+#define EOBTEXTBUFFERSIZE 2048
+
namespace Kyra {
TextDisplayer_Eob::TextDisplayer_Eob(LolEobBaseEngine *engine, Screen *sScreen) : _vm(engine), _screen(sScreen),
_lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0), _allowPageBreak(true),
_numCharsLeft(0), _numCharsPrinted(0), _sjisLineBreakFlag(false), _waitButtonMode(1) {
- _dialogueBuffer = new char[1024];
- memset(_dialogueBuffer, 0, 1024);
+ _dialogueBuffer = new char[EOBTEXTBUFFERSIZE];
+ memset(_dialogueBuffer, 0, EOBTEXTBUFFERSIZE);
_currentLine = new char[85];
memset(_currentLine, 0, 85);
@@ -313,13 +315,13 @@ void TextDisplayer_Eob::printLine(char *str) {
if ((lw + _textDimData[sdx].column) > w) {
if ((lines - 1 - (_waitButtonSpace << 1)) <= _lineCount)
// cut off line to leave space for "MORE" button
- w -= 80;
+ w -= vm()->_waitButtonReverveW;
} else {
if (!_sjisLineBreakFlag || (_lineCount + 1 < lines - 1))
ct = false;
else
// cut off line to leave space for "MORE" button
- w -= 80;
+ w -= vm()->_waitButtonReverveW;
}
if (ct) {
@@ -341,7 +343,7 @@ void TextDisplayer_Eob::printLine(char *str) {
if ((lw + _textDimData[sdx].column) > w) {
if ((lines - 1) <= _lineCount && _allowPageBreak)
// cut off line to leave space for "MORE" button
- w -= (10 * (_screen->getFontWidth() + _screen->_charWidth));
+ w -= vm()->_waitButtonReverveW;
w -= _textDimData[sdx].column;
@@ -439,7 +441,10 @@ void TextDisplayer_Eob::printLine(char *str) {
}
void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakString) {
- strcpy(_dialogueBuffer, (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1])));
+ const char * str = (const char *)(screen()->getCPagePtr(5) + READ_LE_UINT16(&screen()->getCPagePtr(5)[(stringId - 1) << 1]));
+ assert (strlen(str) < EOBTEXTBUFFERSIZE);
+ Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+
displayText(_dialogueBuffer);
if (pageBreakString) {
@@ -452,6 +457,9 @@ void TextDisplayer_Eob::printDialogueText(int stringId, const char *pageBreakStr
}
void TextDisplayer_Eob::printDialogueText(const char *str, bool wait) {
+ assert (strlen(str) < EOBTEXTBUFFERSIZE);
+ Common::strlcpy(_dialogueBuffer, str, EOBTEXTBUFFERSIZE);
+
strcpy(_dialogueBuffer, str);
displayText(_dialogueBuffer);
if (wait)
@@ -471,7 +479,8 @@ void TextDisplayer_Eob::printMessage(const char *str, int textColor, ...) {
displayText(_dialogueBuffer);
- _textDimData[screen()->curDimIndex()].color1 = tc;
+ if (vm()->game() != GI_EOB1)
+ _textDimData[screen()->curDimIndex()].color1 = tc;
if (!screen()->_curPage)
screen()->updateScreen();
@@ -505,7 +514,8 @@ void TextDisplayer_Eob::textPageBreak() {
int cp = _screen->setCurPage(0);
Screen::FontId cf = screen()->setFont(vm()->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
- vm()->_timer->pauseSingleTimer(11, true);
+ if (vm()->game() == GI_LOL)
+ vm()->_timer->pauseSingleTimer(11, true);
vm()->_fadeText = false;
int resetPortraitAfterSpeechAnim = 0;
@@ -527,27 +537,31 @@ void TextDisplayer_Eob::textPageBreak() {
int x = ((dim->sx + dim->w) << 3) - (_vm->_dialogueButtonW + 3);
int y = 0;
+ int w = vm()->_dialogueButtonW;
- if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) {
- if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) {
- y = dim->sy + dim->h - 5;
+ if (vm()->game() == GI_LOL) {
+ if (vm()->_needSceneRestore && (vm()->_updateFlags & 2)) {
+ if (vm()->_currentControlMode || !(vm()->_updateFlags & 2)) {
+ y = dim->sy + dim->h - 5;
+ } else {
+ x += 6;
+ y = dim->sy + dim->h - 2;
+ }
} else {
- x += 6;
- y = dim->sy + dim->h - 2;
+ y = dim->sy + dim->h - 10;
}
- } else if (vm()->game() == GI_LOL) {
- y = dim->sy + dim->h - 10;
} else {
- y = _waitButtonMode ? 162 : 189;
- x = _waitButtonMode ? 76 : 221;
+ y = vm()->_waitButtonPresY[_waitButtonMode];
+ x = vm()->_waitButtonPresX[_waitButtonMode];
+ w = vm()->_waitButtonPresW[_waitButtonMode];
}
if (vm()->gameFlags().use16ColorMode) {
vm()->gui_drawBox(x + 8, (y & ~7) - 1, 66, 10, 0xee, 0xcc, -1);
screen()->printText(_pageBreakString, (x + 37 - (strlen(_pageBreakString) << 1) + 4) & ~3, (y + 2) & ~7, 0xc1, 0);
} else {
- vm()->gui_drawBox(x, y, vm()->_dialogueButtonW, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
- screen()->printText(_pageBreakString, x + (vm()->_dialogueButtonW >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
+ vm()->gui_drawBox(x, y, w, vm()->_dialogueButtonH, vm()->_color1_1, vm()->_color2_1, vm()->_bkgColor_1);
+ screen()->printText(_pageBreakString, x + (w >> 1) - (vm()->screen()->getTextWidth(_pageBreakString) >> 1), y + 2, vm()->_dialogueButtonLabelCol1, 0);
}
vm()->removeInputTop();
@@ -579,7 +593,7 @@ void TextDisplayer_Eob::textPageBreak() {
if (inputFlag == vm()->_keyMap[Common::KEYCODE_SPACE] || inputFlag == vm()->_keyMap[Common::KEYCODE_RETURN]) {
loop = false;
} else if (inputFlag == 199 || inputFlag == 201) {
- if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + _vm->_dialogueButtonW, y + 9)) {
+ if (vm()->posWithinRect(vm()->_mouseX, vm()->_mouseY, x, y, x + w, y + 9)) {
if (_vm->game() == GI_LOL)
target = true;
else
@@ -594,11 +608,12 @@ void TextDisplayer_Eob::textPageBreak() {
if (vm()->gameFlags().use16ColorMode)
screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);
else
- screen()->fillRect(x, y, x + 73, y + 8, _textDimData[screen()->curDimIndex()].color2);
+ screen()->fillRect(x, y, x + w - 1, y + 8, _textDimData[screen()->curDimIndex()].color2);
clearCurDim();
- vm()->_timer->pauseSingleTimer(11, false);
+ if (vm()->game() == GI_LOL)
+ vm()->_timer->pauseSingleTimer(11, false);
if (vm()->_updateCharNum != -1) {
vm()->_resetPortraitAfterSpeechAnim = resetPortraitAfterSpeechAnim;
@@ -626,11 +641,9 @@ void TextDisplayer_Eob::displayWaitButton() {
vm()->_dialogueButtonString[2] = 0;
vm()->_dialogueHighlightedButton = 0;
- static const uint16 posX[] = { 221, 76 };
- static const uint8 posY[] = { 189, 162 };
-
- vm()->_dialogueButtonPosX = &posX[_waitButtonMode];
- vm()->_dialogueButtonPosY = &posY[_waitButtonMode];
+ vm()->_dialogueButtonPosX = &vm()->_waitButtonPresX[_waitButtonMode];
+ vm()->_dialogueButtonPosY = &vm()->_waitButtonPresY[_waitButtonMode];
+ vm()->_dialogueButtonW = vm()->_waitButtonPresW[_waitButtonMode];
vm()->_dialogueButtonYoffs = 0;
SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
@@ -640,7 +653,10 @@ void TextDisplayer_Eob::displayWaitButton() {
vm()->removeInputTop();
while (!vm()->processDialogue() && !vm()->shouldQuit()) {}
+
+ vm()->_dialogueButtonW = 95;
SWAP(_vm->_dialogueButtonLabelCol1, _vm->_dialogueButtonLabelCol2);
+ clearCurDim();
}
} // End of namespace Kyra