KYRA: (EOB) - implemented some spells and fixed more bugs

This commit is contained in:
athrxx 2011-08-07 03:31:15 +02:00 committed by Johannes Schickel
parent bac0caeb0f
commit fc5b29fdbc
15 changed files with 181 additions and 113 deletions

View File

@ -411,8 +411,8 @@ const ExtractFilename extractFilenames[] = {
{ kEob1DoorSwitchShapeDefs, kTypeRawData, false }, { kEob1DoorSwitchShapeDefs, kTypeRawData, false },
{ kEob1DoorSwitchCoords, kTypeRawData, false }, { kEob1DoorSwitchCoords, kTypeRawData, false },
{ kEob1MonsterProperties, kTypeRawData, false }, { kEob1MonsterProperties, kTypeRawData, false },
{ kEob1MonsterDistAttType10, kTypeRawData, false }, { kEob1EnemyMageSpellList, kTypeRawData, false },
{ kEob1MonsterDistAttSfx10, kTypeRawData, false }, { kEob1EnemyMageSfx, kTypeRawData, false },
{ kEob1MonsterDistAttType17, kTypeRawData, false }, { kEob1MonsterDistAttType17, kTypeRawData, false },
{ kEob1MonsterDistAttSfx17, kTypeRawData, false }, { kEob1MonsterDistAttSfx17, kTypeRawData, false },
{ kEob1TurnUndeadString, kTypeStringList, true }, { kEob1TurnUndeadString, kTypeStringList, true },
@ -1652,10 +1652,10 @@ const char *getIdString(const int id) {
return "kEob1DoorSwitchCoords"; return "kEob1DoorSwitchCoords";
case kEob1MonsterProperties: case kEob1MonsterProperties:
return "kEob1MonsterProperties"; return "kEob1MonsterProperties";
case kEob1MonsterDistAttType10: case kEob1EnemyMageSpellList:
return "kEob1MonsterDistAttType10"; return "kEob1EnemyMageSpellList";
case kEob1MonsterDistAttSfx10: case kEob1EnemyMageSfx:
return "kEob1MonsterDistAttSfx10"; return "kEob1EnemyMageSfx";
case kEob1MonsterDistAttType17: case kEob1MonsterDistAttType17:
return "kEob1MonsterDistAttType17"; return "kEob1MonsterDistAttType17";
case kEob1MonsterDistAttSfx17: case kEob1MonsterDistAttSfx17:

View File

@ -412,8 +412,8 @@ enum kExtractID {
kEob1DoorSwitchCoords, kEob1DoorSwitchCoords,
kEob1MonsterProperties, kEob1MonsterProperties,
kEob1MonsterDistAttType10, kEob1EnemyMageSpellList,
kEob1MonsterDistAttSfx10, kEob1EnemyMageSfx,
kEob1MonsterDistAttType17, kEob1MonsterDistAttType17,
kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17,
kEob1TurnUndeadString, kEob1TurnUndeadString,

View File

@ -1059,8 +1059,8 @@ const int eob1FloppyNeed[] = {
kEob1DoorSwitchShapeDefs, kEob1DoorSwitchShapeDefs,
kEob1DoorSwitchCoords, kEob1DoorSwitchCoords,
kEob1MonsterProperties, kEob1MonsterProperties,
kEob1MonsterDistAttType10, kEob1EnemyMageSpellList,
kEob1MonsterDistAttSfx10, kEob1EnemyMageSfx,
kEob1MonsterDistAttType17, kEob1MonsterDistAttType17,
kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17,
kEob1TurnUndeadString, kEob1TurnUndeadString,

View File

@ -2388,12 +2388,12 @@ const ExtractEntrySearchData kEob1MonsterPropertiesProvider[] = {
EXTRACT_END_ENTRY EXTRACT_END_ENTRY
}; };
const ExtractEntrySearchData kEob1MonsterDistAttType10Provider[] = { const ExtractEntrySearchData kEob1EnemyMageSpellListProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000000F, { { 0x01, 0x1B, 0x9C, 0x51, 0xC9, 0xA2, 0x10, 0xBB, 0xA7, 0x82, 0xD4, 0x91, 0x7E, 0x84, 0x54, 0x93 } } } }, { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000000F, { { 0x01, 0x1B, 0x9C, 0x51, 0xC9, 0xA2, 0x10, 0xBB, 0xA7, 0x82, 0xD4, 0x91, 0x7E, 0x84, 0x54, 0x93 } } } },
EXTRACT_END_ENTRY EXTRACT_END_ENTRY
}; };
const ExtractEntrySearchData kEob1MonsterDistAttSfx10Provider[] = { const ExtractEntrySearchData kEob1EnemyMageSfxProvider[] = {
{ UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000029B, { { 0xA2, 0x9F, 0x2E, 0xDE, 0x15, 0x23, 0x78, 0xDD, 0x26, 0x98, 0x6E, 0xA3, 0x77, 0xEA, 0xB5, 0x80 } } } }, { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000029B, { { 0xA2, 0x9F, 0x2E, 0xDE, 0x15, 0x23, 0x78, 0xDD, 0x26, 0x98, 0x6E, 0xA3, 0x77, 0xEA, 0xB5, 0x80 } } } },
EXTRACT_END_ENTRY EXTRACT_END_ENTRY
}; };
@ -3870,8 +3870,8 @@ const ExtractEntry extractProviders[] = {
{ kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider }, { kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider },
{ kEob1MonsterProperties, kEob1MonsterPropertiesProvider }, { kEob1MonsterProperties, kEob1MonsterPropertiesProvider },
{ kEob1MonsterDistAttType10, kEob1MonsterDistAttType10Provider }, { kEob1EnemyMageSpellList, kEob1EnemyMageSpellListProvider },
{ kEob1MonsterDistAttSfx10, kEob1MonsterDistAttSfx10Provider }, { kEob1EnemyMageSfx, kEob1EnemyMageSfxProvider },
{ kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider }, { kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider },
{ kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider }, { kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider },
{ kEob1TurnUndeadString, kEob1TurnUndeadStringProvider }, { kEob1TurnUndeadString, kEob1TurnUndeadStringProvider },

View File

@ -438,9 +438,9 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal
case 11: case 11:
v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1; v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1;
x -= (shp[2] << 2); x -= (shp[2] << 2);
y = _dscDoorY3[mDim] + v; y = _dscDoorY4[mDim] + v;
drawBlockObject(0, 2, shp, x, y + v, 5); drawBlockObject(0, 2, shp, x, y + v, 5);
v >>= 4; v = (v >> 3) + (v >> 2);
y = _dscDoorY5[mDim]; y = _dscDoorY5[mDim];
drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5); drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5);
if (_wllShapeMap[wall] == -1) if (_wllShapeMap[wall] == -1)
@ -505,6 +505,7 @@ void EobEngine::turnUndeadAutoHit() {
bool EobEngine::checkPartyStatusExtra() { bool EobEngine::checkPartyStatusExtra() {
_screen->copyPage(0, 10); _screen->copyPage(0, 10);
int cd = _screen->curDimIndex();
gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1); gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1);
_txt->setupField(9, false); _txt->setupField(9, false);
_txt->printMessage(_menuStringsDefeat[0]); _txt->printMessage(_menuStringsDefeat[0]);
@ -515,6 +516,8 @@ bool EobEngine::checkPartyStatusExtra() {
} }
_screen->copyPage(10, 0); _screen->copyPage(10, 0);
_eventList.clear(); _eventList.clear();
_screen->setScreenDim(cd);
_txt->removePageBreakFlag();
return true; return true;
} }

View File

@ -55,8 +55,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_tempIconShape = 0; _tempIconShape = 0;
_monsterDustStrings = 0; _monsterDustStrings = 0;
_monsterDistAttType10 = 0; _enemyMageSpellList = 0;
_monsterDistAttSfx10 = 0; _enemyMageSfx = 0;
_monsterDistAttType17 = 0; _monsterDistAttType17 = 0;
_monsterDistAttSfx17 = 0; _monsterDistAttSfx17 = 0;
@ -130,8 +130,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa
_openBookType = _openBookTypeBackup = 0; _openBookType = _openBookTypeBackup = 0;
_openBookSpellList = 0; _openBookSpellList = 0;
_openBookAvailableSpells = 0; _openBookAvailableSpells = 0;
_activeSpellCaster = 0; _activeSpellCharId = 0;
_activeSpellCasterPos = 0; _activeSpellCharacterPos = 0;
_activeSpell = 0; _activeSpell = 0;
_returnAfterSpellCallback = false; _returnAfterSpellCallback = false;
_spells = 0; _spells = 0;
@ -473,7 +473,7 @@ bool EobCoreEngine::checkPartyStatus(bool handleDeath) {
if (!handleDeath) if (!handleDeath)
return true; return true;
gui_drawAllCharPortraitsWithStats(); gui_drawAllCharPortraitsWithStats();
if (checkPartyStatusExtra()) { if (checkPartyStatusExtra()) {
@ -1550,13 +1550,14 @@ void EobCoreEngine::seq_portal() {
} else { } else {
s--; s--;
_screen->copyRegion((s % 5) << 6, s / 5 * 77, 56, 27, 64, 77, 2, 0, Screen::CR_NO_P_CHECK); _screen->copyRegion((s % 5) << 6, s / 5 * 77, 56, 27, 64, 77, 2, 0, Screen::CR_NO_P_CHECK);
if (s == 0) }
snd_playSoundEffect(31);
else if (s == 3) { if (s == 1)
if (*(pos - 2) == 3) snd_playSoundEffect(31);
snd_playSoundEffect(90); else if (s == 3) {
} if (*(pos - 2) == 3)
} snd_playSoundEffect(90);
}
_screen->updateScreen(); _screen->updateScreen();
delay(2 * _tickLength); delay(2 * _tickLength);
@ -1646,7 +1647,7 @@ int EobCoreEngine::closeDistanceAttack(int charIndex, Item item) {
return -3; return -3;
uint16 d = calcNewBlockPosition(_currentBlock, _currentDirection); uint16 d = calcNewBlockPosition(_currentBlock, _currentDirection);
int r = getClosestMonsterPos(charIndex, d); int r = getClosestMonster(charIndex, d);
if (r == -1) { if (r == -1) {
uint8 w = _specialWallTypes[_levelBlockProperties[d].walls[_sceneDrawVarDown]]; uint8 w = _specialWallTypes[_levelBlockProperties[d].walls[_sceneDrawVarDown]];

View File

@ -486,8 +486,8 @@ protected:
int countSpecificMonsters(int type); int countSpecificMonsters(int type);
void updateAttackingMonsterFlags(); void updateAttackingMonsterFlags();
const int8 *getMonsterBlockPositions(uint16 block); const int8 *getMonstersOnBlockPositions(uint16 block);
int getClosestMonsterPos(int charIndex, int block); int getClosestMonster(int charIndex, int block);
bool blockHasMonsters(uint16 block); bool blockHasMonsters(uint16 block);
bool isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, int checkPos4); bool isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, int checkPos4);
@ -547,8 +547,8 @@ protected:
const uint8 *_findBlockMonstersTable; const uint8 *_findBlockMonstersTable;
const char *const *_monsterDustStrings; const char *const *_monsterDustStrings;
const uint8 *_monsterDistAttType10; const uint8 *_enemyMageSpellList;
const uint8 *_monsterDistAttSfx10; const uint8 *_enemyMageSfx;
const uint8 *_monsterDistAttType17; const uint8 *_monsterDistAttType17;
const uint8 *_monsterDistAttSfx17; const uint8 *_monsterDistAttSfx17;
const char *const *_monsterSpecAttStrings; const char *const *_monsterSpecAttStrings;
@ -912,7 +912,9 @@ protected:
bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod); bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel); bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel);
void printWarning(const char* str); int findSingleSpellTarget(int dist);
void printWarning(const char *str);
void printNoEffectWarning(); void printNoEffectWarning();
void spellCallback_start_empty() {} void spellCallback_start_empty() {}
@ -993,8 +995,8 @@ protected:
uint8 _openBookCasterLevel; uint8 _openBookCasterLevel;
const char *const *_openBookSpellList; const char *const *_openBookSpellList;
int8 *_openBookAvailableSpells; int8 *_openBookAvailableSpells;
uint8 _activeSpellCaster; uint8 _activeSpellCharId;
uint8 _activeSpellCasterPos; uint8 _activeSpellCharacterPos;
uint8 _activeSpell; uint8 _activeSpell;
bool _returnAfterSpellCallback; bool _returnAfterSpellCallback;
@ -1046,6 +1048,11 @@ protected:
const uint8 *_magicFlightObjectProperties; const uint8 *_magicFlightObjectProperties;
const uint8 *_turnUndeadEffect; const uint8 *_turnUndeadEffect;
const uint8 *_burningHandsDest; const uint8 *_burningHandsDest;
const int8 *_coneOfColdDest1;
const int8 *_coneOfColdDest2;
const int8 *_coneOfColdDest3;
const int8 *_coneOfColdDest4;
const int8 *_coneOfColdGfxTbl;
// Menu // Menu
EobMenuDef *_menuDefs; EobMenuDef *_menuDefs;

View File

@ -524,7 +524,7 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
EobCharacter *c = &_characters[index]; EobCharacter *c = &_characters[index];
bool redGreen = ((c->effectFlags & 0x4818) || (_partyEffectFlags & 0x20000) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false; bool redGreen = ((c->effectFlags & 0x4818) || (_partyEffectFlags & 0x20000) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false;
bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false; bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420)) ? true : false;
if (redGreen || yellow) { if (redGreen || yellow) {
if (redGreen && !yellow) { if (redGreen && !yellow) {
@ -1108,9 +1108,9 @@ int EobCoreEngine::clickedSpellbookList(Button *button) {
} }
int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) { int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) {
_activeSpellCaster = button->arg & 0xff; _activeSpellCharId = button->arg & 0xff;
if (_activeSpellCaster == 0xff) { if (_activeSpellCharId == 0xff) {
printWarning(_magicStrings3[_flags.gameID == GI_EOB1 ? 2 : 1]); printWarning(_magicStrings3[_flags.gameID == GI_EOB1 ? 2 : 1]);
if (_castScrollSlot) { if (_castScrollSlot) {
gui_updateSlotAfterScrollUse(); gui_updateSlotAfterScrollUse();
@ -1119,7 +1119,7 @@ int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) {
gui_drawSpellbook(); gui_drawSpellbook();
} }
} else { } else {
if (_characters[_activeSpellCaster].flags & 1) if (_characters[_activeSpellCharId].flags & 1)
startSpell(_activeSpell); startSpell(_activeSpell);
} }

View File

@ -256,22 +256,19 @@ bool EobCoreEngine::deletePartyItems(int16 itemType, int16 itemValue) {
continue; continue;
EobCharacter *c = &_characters[i]; EobCharacter *c = &_characters[i];
int slot = checkInventoryForItem(i, itemType, itemValue); for (int slot = checkInventoryForItem(i, itemType, itemValue); slot != -1; slot = checkInventoryForItem(i, itemType, itemValue)) {
int itm = c->inventory[slot];
_items[itm].block = -1;
c->inventory[slot] = 0;
res = true;
if (slot == -1) if (!_dialogueField) {
continue; if (_currentControlMode == 0 && slot < 2 && i < 5)
gui_drawWeaponSlot(i, slot);
int itm = c->inventory[slot]; if (_currentControlMode == 1 && i == _updateCharNum)
_items[itm].block = -1; gui_drawInventoryItem(slot, 1, 0);
c->inventory[slot] = 0; }
res = true;
if (!_dialogueField) {
if (_currentControlMode == 0 && slot < 2 && i < 5)
gui_drawWeaponSlot(i, slot);
if (_currentControlMode == 1 && i == _updateCharNum)
gui_drawInventoryItem(slot, 1, 0);
} }
} }
@ -379,9 +376,9 @@ void EobCoreEngine::printFullItemName(Item item) {
if (v == 0) if (v == 0)
tmpString = nameUnid; tmpString = nameUnid;
else if (v < 0) else if (v < 0)
tmpString = Common::String::format(_cursedString[0], v, nameUnid); tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_cursedString[0], nameUnid, v) : Common::String::format(_cursedString[0], v, nameUnid);
else else
tmpString = Common::String::format(_enchantedString[0], v, nameUnid); tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_enchantedString[0], nameUnid, v) : Common::String::format(_enchantedString[0], v, nameUnid);
break; break;
case 9: case 9:

View File

@ -184,7 +184,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
if (ci > 3) if (ci > 3)
ci -= 2; ci -= 2;
_activeSpellCasterPos = _dropItemDirIndex[(_currentDirection << 2) + ci]; _activeSpellCharacterPos = _dropItemDirIndex[(_currentDirection << 2) + ci];
if (s->flags & 0x400) { if (s->flags & 0x400) {
if (c->inventory[0] && c->inventory[1]) { if (c->inventory[0] && c->inventory[1]) {
@ -226,7 +226,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
return; return;
} }
_activeSpellCaster = _openBookChar; _activeSpellCharId = _openBookChar;
startSpell(spell); startSpell(spell);
} }
@ -258,7 +258,7 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
} }
if (s->flags & 0x2) if (s->flags & 0x2)
recalcArmorClass(_activeSpellCaster); recalcArmorClass(_activeSpellCharId);
if (showWarning) { if (showWarning) {
if (s->flags & 0x20A0) if (s->flags & 0x20A0)
@ -296,11 +296,11 @@ void EobCoreEngine::castOnWhomDialogue() {
void EobCoreEngine::startSpell(int spell) { void EobCoreEngine::startSpell(int spell) {
EobSpell *s = &_spells[spell]; EobSpell *s = &_spells[spell];
EobCharacter *c = &_characters[_activeSpellCaster]; EobCharacter *c = &_characters[_activeSpellCharId];
snd_playSoundEffect(s->sound); snd_playSoundEffect(s->sound);
if (s->flags & 0xa0) if (s->flags & 0xa0)
sparkEffectDefensive(_activeSpellCaster); sparkEffectDefensive(_activeSpellCharId);
else if (s->flags & 0x40) else if (s->flags & 0x40)
sparkEffectDefensive(-1); sparkEffectDefensive(-1);
else if (s->flags & 0x1000) else if (s->flags & 0x1000)
@ -312,9 +312,17 @@ void EobCoreEngine::startSpell(int spell) {
} }
if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) { if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str()); if (_flags.gameID == GI_EOB1) {
// TODO: warnings seem to exist at least for bless and aid
} else {
printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
}
} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) { } else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
printWarning(Common::String::format(_magicStrings7[1], s->name).c_str()); if (_flags.gameID == GI_EOB1) {
// TODO: warnings seem to exist at least for bless and aid
} else {
printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
}
} else { } else {
if (s->flags & 8) if (s->flags & 8)
setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]); setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
@ -341,10 +349,10 @@ void EobCoreEngine::startSpell(int spell) {
} }
if (s->flags & 2) if (s->flags & 2)
recalcArmorClass(_activeSpellCaster); recalcArmorClass(_activeSpellCharId);
if (s->flags & 0x20A0) if (s->flags & 0x20A0)
gui_drawCharPortraitWithStats(_activeSpellCaster); gui_drawCharPortraitWithStats(_activeSpellCharId);
if (s->flags & 0x40) if (s->flags & 0x40)
gui_drawAllCharPortraitsWithStats(); gui_drawAllCharPortraitsWithStats();
} }
@ -438,7 +446,7 @@ void EobCoreEngine::sparkEffectOffensive() {
void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) { void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
int l = _openBookType == 1 ? getCharacterClericPaladinLevel(_openBookChar) : getCharacterMageLevel(_openBookChar); int l = _openBookType == 1 ? getCharacterClericPaladinLevel(_openBookChar) : getCharacterMageLevel(_openBookChar);
uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor; uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
setCharEventTimer(_activeSpellCaster, countdown, -spell, updateExistingTimer); setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
} }
void EobCoreEngine::sortCharacterSpellList(int charIndex) { void EobCoreEngine::sortCharacterSpellList(int charIndex) {
@ -624,7 +632,23 @@ bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int caster
return true; return true;
} }
void EobCoreEngine::printWarning(const char* str) { int EobCoreEngine::findSingleSpellTarget(int dist) {
uint16 bl = _currentBlock;
int res = -1;
for (int i = 0; i < dist && res == -1; i++) {
bl = calcNewBlockPosition(bl, _currentDirection);
res = getClosestMonster(_openBookChar, bl);
if (!(_wllWallFlags[_levelBlockProperties[bl].walls[_sceneDrawVarDown]] & 1)) {
i = dist;
res = -1;
}
}
return res;
}
void EobCoreEngine::printWarning(const char *str) {
_txt->printMessage(str); _txt->printMessage(str);
snd_playSoundEffect(79); snd_playSoundEffect(79);
} }
@ -634,7 +658,9 @@ void EobCoreEngine::printNoEffectWarning() {
} }
void EobCoreEngine::spellCallback_start_armor() { void EobCoreEngine::spellCallback_start_armor() {
_characters[_activeSpellCharId].effectsRemainder[0] = getCharacterMageLevel(_openBookChar) + 8;
if ((getDexterityArmorClassModifier(_characters[_activeSpellCharId].dexterityCur) + 6) >= _characters[_activeSpellCharId].armorClass)
printWarning(Common::String::format(_magicStrings6[0], _characters[_activeSpellCharId].name).c_str());
} }
void EobCoreEngine::spellCallback_start_burningHands() { void EobCoreEngine::spellCallback_start_burningHands() {
@ -649,7 +675,7 @@ void EobCoreEngine::spellCallback_start_burningHands() {
int cl = getCharacterMageLevel(_openBookChar); int cl = getCharacterMageLevel(_openBookChar);
int bl = calcNewBlockPosition(_currentBlock, _currentDirection); int bl = calcNewBlockPosition(_currentBlock, _currentDirection);
const int8 *pos = getMonsterBlockPositions(bl); const int8 *pos = getMonstersOnBlockPositions(bl);
_preventMonsterFlash = true; _preventMonsterFlash = true;
int numDest = (_flags.gameID == GI_EOB1) ? 2 : 6; int numDest = (_flags.gameID == GI_EOB1) ? 2 : 6;
@ -674,7 +700,7 @@ bool EobCoreEngine::spellCallback_end_detectMagic(EobFlyingObject*) {
} }
void EobCoreEngine::spellCallback_start_magicMissile() { void EobCoreEngine::spellCallback_start_magicMissile() {
launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) {
@ -694,10 +720,11 @@ void EobCoreEngine::spellCallback_start_improvedIdentify() {
} }
void EobCoreEngine::spellCallback_start_melfsAcidArrow() { void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) {
assert(fo);
return magicObjectDamageHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3); return magicObjectDamageHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
} }
@ -706,7 +733,7 @@ void EobCoreEngine::spellCallback_start_dispelMagic() {
} }
void EobCoreEngine::spellCallback_start_fireball() { void EobCoreEngine::spellCallback_start_fireball() {
launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
@ -714,7 +741,7 @@ bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
} }
void EobCoreEngine::spellCallback_start_flameArrow() { void EobCoreEngine::spellCallback_start_flameArrow() {
launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
@ -722,7 +749,7 @@ bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
} }
void EobCoreEngine::spellCallback_start_holdPerson() { void EobCoreEngine::spellCallback_start_holdPerson() {
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
@ -751,7 +778,7 @@ bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
} }
void EobCoreEngine::spellCallback_start_lightningBolt() { void EobCoreEngine::spellCallback_start_lightningBolt() {
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) {
@ -776,7 +803,7 @@ void EobCoreEngine::spellCallback_start_fear() {
} }
void EobCoreEngine::spellCallback_start_iceStorm() { void EobCoreEngine::spellCallback_start_iceStorm() {
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
@ -794,15 +821,32 @@ bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
} }
void EobCoreEngine::spellCallback_start_removeCurse() { void EobCoreEngine::spellCallback_start_removeCurse() {
for (int i = 0; i < 27; i++) {
Item itm = _characters[_activeSpellCharId].inventory[i];
if (itm && (_items[itm].flags & 0x20) && !isMagicWeapon(itm))
_items[itm].flags = (_items[itm].flags & ~0x20) | 0x40;
}
} }
void EobCoreEngine::spellCallback_start_coneOfCold() { void EobCoreEngine::spellCallback_start_coneOfCold() {
static const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
int cl = getCharacterMageLevel(_openBookChar);
//drawConeOfColdEffect(150, 50, 10, 1, 100, _coneOfColdGfxTbl);
const int8 *tbl = dirTables[_currentDirection];
_preventMonsterFlash = true;
for (int i = 0; i < 7; i++) {
for (const int16 *m = findBlockMonsters((_currentBlock + tbl[i]) & 0x3ff, 4, _currentDirection, 1, 1); *m != -1; m++)
calcAndInflictMonsterDamage(&_monsters[*m], cl, 4, cl, 0x41, 5, 0);
}
updateAllMonsterShapes();
} }
void EobCoreEngine::spellCallback_start_holdMonster() { void EobCoreEngine::spellCallback_start_holdMonster() {
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 7 : 6, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) {
@ -817,12 +861,16 @@ void EobCoreEngine::spellCallback_start_wallOfForce() {
} }
void EobCoreEngine::spellCallback_start_disintegrate() { void EobCoreEngine::spellCallback_start_disintegrate() {
int d = findSingleSpellTarget(1);
if (d != -1)
magicObjectStatusHit(&_monsters[d], 4, true, 4);
memset(_visibleBlocks[13]->walls, 0, 4);
_sceneUpdateRequired = true;
} }
void EobCoreEngine::spellCallback_start_fleshToStone() { void EobCoreEngine::spellCallback_start_fleshToStone() {
sparkEffectOffensive(); sparkEffectOffensive();
int t = getClosestMonsterPos(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection)); int t = getClosestMonster(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
if (t != -1) if (t != -1)
magicObjectStatusHit(&_monsters[t], 5, true, 4); magicObjectStatusHit(&_monsters[t], 5, true, 4);
else else
@ -830,8 +878,8 @@ void EobCoreEngine::spellCallback_start_fleshToStone() {
} }
void EobCoreEngine::spellCallback_start_stoneToFlesh() { void EobCoreEngine::spellCallback_start_stoneToFlesh() {
if (_characters[_activeSpellCaster].flags & 8) if (_characters[_activeSpellCharId].flags & 8)
_characters[_activeSpellCaster].flags &= ~8; _characters[_activeSpellCharId].flags &= ~8;
else else
printNoEffectWarning(); printNoEffectWarning();
} }
@ -846,11 +894,18 @@ bool EobCoreEngine::spellCallback_end_trueSeeing(EobFlyingObject*) {
} }
void EobCoreEngine::spellCallback_start_slayLiving() { void EobCoreEngine::spellCallback_start_slayLiving() {
int d = findSingleSpellTarget(2);
if (d != -1)
if (!magicObjectStatusHit(&_monsters[d], 3, true, 4))
inflictMonsterDamage(&_monsters[d], rollDice(2, 8, 1), true);
} }
void EobCoreEngine::spellCallback_start_powerWordStun() { void EobCoreEngine::spellCallback_start_powerWordStun() {
int d = findSingleSpellTarget(2);
if (d != -1) {
if (_monsters[d].hitPointsCur < 90)
magicObjectStatusHit(&_monsters[d], 5, true, 4);
}
} }
void EobCoreEngine::spellCallback_start_causeLightWounds() { void EobCoreEngine::spellCallback_start_causeLightWounds() {
@ -858,7 +913,7 @@ void EobCoreEngine::spellCallback_start_causeLightWounds() {
} }
void EobCoreEngine::spellCallback_start_cureLightWounds() { void EobCoreEngine::spellCallback_start_cureLightWounds() {
modifyCharacterHitpoints(_activeSpellCaster, rollDice(1, 8)); modifyCharacterHitpoints(_activeSpellCharId, rollDice(1, 8));
} }
void EobCoreEngine::spellCallback_start_aid() { void EobCoreEngine::spellCallback_start_aid() {
@ -904,7 +959,7 @@ void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
} }
void EobCoreEngine::spellCallback_start_cureSeriousWounds() { void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
modifyCharacterHitpoints(_activeSpellCaster, rollDice(2, 8, 1)); modifyCharacterHitpoints(_activeSpellCharId, rollDice(2, 8, 1));
} }
void EobCoreEngine::spellCallback_start_neutralizePoison() { void EobCoreEngine::spellCallback_start_neutralizePoison() {
@ -916,11 +971,11 @@ void EobCoreEngine::spellCallback_start_causeCriticalWounds() {
} }
void EobCoreEngine::spellCallback_start_cureCriticalWounds() { void EobCoreEngine::spellCallback_start_cureCriticalWounds() {
modifyCharacterHitpoints(_activeSpellCaster, rollDice(3, 8, 3)); modifyCharacterHitpoints(_activeSpellCharId, rollDice(3, 8, 3));
} }
void EobCoreEngine::spellCallback_start_flameStrike() { void EobCoreEngine::spellCallback_start_flameStrike() {
launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCasterPos, _currentDirection); launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCharacterPos, _currentDirection);
} }
bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) { bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
@ -928,7 +983,12 @@ bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
} }
void EobCoreEngine::spellCallback_start_raiseDead() { void EobCoreEngine::spellCallback_start_raiseDead() {
if (_characters[_activeSpellCharId].hitPointsCur == -10 || ((_characters[_activeSpellCharId].raceSex >> 1) == 1)) {
_characters[_activeSpellCharId].hitPointsCur = 1;
gui_drawCharPortraitWithStats(_activeSpellCharId);
} else {
printNoEffectWarning();
}
} }
void EobCoreEngine::spellCallback_start_harm() { void EobCoreEngine::spellCallback_start_harm() {
@ -936,15 +996,15 @@ void EobCoreEngine::spellCallback_start_harm() {
} }
void EobCoreEngine::spellCallback_start_heal() { void EobCoreEngine::spellCallback_start_heal() {
EobCharacter *c = &_characters[_activeSpellCaster]; EobCharacter *c = &_characters[_activeSpellCharId];
if (c->hitPointsMax <= c->hitPointsCur) if (c->hitPointsMax <= c->hitPointsCur)
printWarning(_magicStrings4[0]); printWarning(_magicStrings4[0]);
else else
modifyCharacterHitpoints(_activeSpellCaster, c->hitPointsMax - c->hitPointsCur); modifyCharacterHitpoints(_activeSpellCharId, c->hitPointsMax - c->hitPointsCur);
} }
void EobCoreEngine::spellCallback_start_layOnHands() { void EobCoreEngine::spellCallback_start_layOnHands() {
modifyCharacterHitpoints(_activeSpellCaster, _characters[_openBookChar].level[0] << 1); modifyCharacterHitpoints(_activeSpellCharId, _characters[_openBookChar].level[0] << 1);
} }
void EobCoreEngine::spellCallback_start_turnUndead() { void EobCoreEngine::spellCallback_start_turnUndead() {

View File

@ -485,8 +485,8 @@ enum KyraResources {
kEob1DoorSwitchCoords, kEob1DoorSwitchCoords,
kEob1MonsterProperties, kEob1MonsterProperties,
kEob1MonsterDistAttType10, kEob1EnemyMageSpellList,
kEob1MonsterDistAttSfx10, kEob1EnemyMageSfx,
kEob1MonsterDistAttType17, kEob1MonsterDistAttType17,
kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17,

View File

@ -241,8 +241,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
_openBookType = in.readByte(); _openBookType = in.readByte();
_openBookCharBackup = in.readByte(); _openBookCharBackup = in.readByte();
_openBookTypeBackup = in.readByte(); _openBookTypeBackup = in.readByte();
_activeSpellCaster = in.readByte(); _activeSpellCharId = in.readByte();
_activeSpellCasterPos = in.readByte(); _activeSpellCharacterPos = in.readByte();
_activeSpell = in.readByte(); _activeSpell = in.readByte();
_returnAfterSpellCallback = in.readByte() ? true : false; _returnAfterSpellCallback = in.readByte() ? true : false;
@ -465,8 +465,8 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
out->writeByte(_openBookType); out->writeByte(_openBookType);
out->writeByte(_openBookCharBackup); out->writeByte(_openBookCharBackup);
out->writeByte(_openBookTypeBackup); out->writeByte(_openBookTypeBackup);
out->writeByte(_activeSpellCaster); out->writeByte(_activeSpellCharId);
out->writeByte(_activeSpellCasterPos); out->writeByte(_activeSpellCharacterPos);
out->writeByte(_activeSpell); out->writeByte(_activeSpell);
out->writeByte(_returnAfterSpellCallback ? 1 : 0); out->writeByte(_returnAfterSpellCallback ? 1 : 0);

View File

@ -54,8 +54,8 @@ int LolEobBaseEngine::getBlockDistance(uint16 block1, uint16 block2) {
namespace Kyra { namespace Kyra {
void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) { void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) {
Common::String s = _flags.gameID == GI_EOB1 && !scumm_stricmp(filename, "spider") ? "spider1" : filename; Common::String s = filename;
if (GI_EOB1 && !scumm_stricmp(filename, "rust")) if (GI_EOB1 && !scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn"))
s += "1"; s += "1";
_screen->loadShapeSetBitmap(s.c_str(), 3, 3); _screen->loadShapeSetBitmap(s.c_str(), 3, 3);
@ -147,7 +147,7 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level)
uint32 ct = _system->getMillis(); uint32 ct = _system->getMillis();
for (int i = 0x20; i < 0x24; i++) { for (int i = 0x20; i < 0x24; i++) {
int32 del = _timer->getDelay(i); int32 del = _timer->getDelay(i);
_timer->setNextRun(i, (i & 1) ? ct + (del >> 1) : ct + del); _timer->setNextRun(i, (i & 1) ? ct + (del >> 1) * _tickLength : ct + del * _tickLength);
} }
if (_hasTempDataFlags & (1 << (level - 1))) if (_hasTempDataFlags & (1 << (level - 1)))
@ -178,7 +178,7 @@ void EobCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int
if (index & 1) if (index & 1)
unit++; unit++;
m->stepsTillRemoteAttack = _flags.gameID == GI_EOB2 ? rollDice(1, 3, 0) : 0; m->stepsTillRemoteAttack = _flags.gameID == GI_EOB2 ? rollDice(1, 3, 0) : 5;
m->type = type; m->type = type;
m->numRemoteAttacks = p->numRemoteAttacks; m->numRemoteAttacks = p->numRemoteAttacks;
m->curRemoteWeapon = 0; m->curRemoteWeapon = 0;
@ -278,7 +278,7 @@ void EobCoreEngine::updateAttackingMonsterFlags() {
_inf->setFlag(0x800); _inf->setFlag(0x800);
} }
const int8 *EobCoreEngine::getMonsterBlockPositions(uint16 block) { const int8 *EobCoreEngine::getMonstersOnBlockPositions(uint16 block) {
memset(_monsterBlockPosArray, -1, sizeof(_monsterBlockPosArray)); memset(_monsterBlockPosArray, -1, sizeof(_monsterBlockPosArray));
for (int8 i = 0; i < 30; i++) { for (int8 i = 0; i < 30; i++) {
if (_monsters[i].block != block) if (_monsters[i].block != block)
@ -289,8 +289,8 @@ const int8 *EobCoreEngine::getMonsterBlockPositions(uint16 block) {
return _monsterBlockPosArray; return _monsterBlockPosArray;
} }
int EobCoreEngine::getClosestMonsterPos(int charIndex, int block) { int EobCoreEngine::getClosestMonster(int charIndex, int block) {
const int8 *pos = getMonsterBlockPositions(block); const int8 *pos = getMonstersOnBlockPositions(block);
if (pos[4] != -1) if (pos[4] != -1)
return pos[4]; return pos[4];
@ -915,7 +915,7 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->capsFlags & 0x40))) if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->capsFlags & 0x40)))
return false; return false;
if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack == 5) || (_flags.gameID == GI_EOB2 && rollDice(1, 3) > m->stepsTillRemoteAttack)) { if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack < 5) || (_flags.gameID == GI_EOB2 && (rollDice(1, 3) > m->stepsTillRemoteAttack))) {
m->stepsTillRemoteAttack++; m->stepsTillRemoteAttack++;
return false; return false;
} }
@ -940,8 +940,8 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
snd_processEnvironmentalSoundEffect(31, m->block); snd_processEnvironmentalSoundEffect(31, m->block);
break; break;
case 10: case 10:
launchMagicObject(-1, _monsterDistAttType10[m->numRemoteAttacks], m->block, m->pos, m->dir); launchMagicObject(-1, _enemyMageSpellList[m->numRemoteAttacks], m->block, m->pos, m->dir);
snd_processEnvironmentalSoundEffect(_monsterDistAttSfx10[m->numRemoteAttacks], m->block); snd_processEnvironmentalSoundEffect(_enemyMageSfx[m->numRemoteAttacks], m->block);
break; break;
case 11: case 11:
itm = duplicateItem(60); itm = duplicateItem(60);

View File

@ -1070,8 +1070,8 @@ void EobEngine::initStaticResource() {
_dscDoorY7 = _staticres->loadRawData(kEobBaseDscDoorY7, temp); _dscDoorY7 = _staticres->loadRawData(kEobBaseDscDoorY7, temp);
_dscDoorCoordsExt = (const int16*)_staticres->loadRawDataBe16(kEobBaseDscDoorCoordsExt, temp); _dscDoorCoordsExt = (const int16*)_staticres->loadRawDataBe16(kEobBaseDscDoorCoordsExt, temp);
_monsterDistAttType10 = _staticres->loadRawData(kEob1MonsterDistAttType10, temp); _enemyMageSpellList = _staticres->loadRawData(kEob1EnemyMageSpellList, temp);
_monsterDistAttSfx10 = _staticres->loadRawData(kEob1MonsterDistAttSfx10, temp); _enemyMageSfx = _staticres->loadRawData(kEob1EnemyMageSfx, temp);
_monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp); _monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp);
_monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp); _monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp);

View File

@ -203,7 +203,7 @@ void EobCoreEngine::advanceTimers(uint32 millis) {
for (int ii = 0; ii < 10; ii++) { for (int ii = 0; ii < 10; ii++) {
if (c->timers[ii] > ct) { if (c->timers[ii] > ct) {
uint32 chrt = c->timers[ii] - ct; uint32 chrt = c->timers[ii] - ct;
c->timers[ii] = chrt > millis ? chrt - millis : ct; c->timers[ii] = chrt > millis ? ct + chrt - millis : ct;
} }
} }
} }
@ -214,7 +214,7 @@ void EobCoreEngine::advanceTimers(uint32 millis) {
for (int i = 0; i < _scriptTimersCount; i++) { for (int i = 0; i < _scriptTimersCount; i++) {
if (_scriptTimers[i].next > ct) { if (_scriptTimers[i].next > ct) {
uint32 chrt = _scriptTimers[i].next - ct; uint32 chrt = _scriptTimers[i].next - ct;
_scriptTimers[i].next = chrt > millis ? chrt - millis : ct; _scriptTimers[i].next = chrt > millis ? ct + chrt - millis : ct;
} }
} }
} }
@ -331,7 +331,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
case 9: case 9:
if (c->flags & 4) { if (c->flags & 4) {
_txt->printMessage(_characterStatusStrings9[0], -1, c->name); _txt->printMessage(_characterStatusStrings9[0], -1, c->name);
c->flags &= 0xfb; c->flags &= ~4;
gui_drawCharPortraitWithStats(charIndex); gui_drawCharPortraitWithStats(charIndex);
} }
break; break;