mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-03 15:41:41 +00:00
KYRA: (EOB) - fix various bugs and implement some spells
This commit is contained in:
parent
9140fd8e91
commit
c302b3e43b
@ -272,7 +272,7 @@ void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, in
|
||||
}
|
||||
|
||||
bool DarkMoonEngine::killMonsterExtra(EobMonsterInPlay *m) {
|
||||
if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].flags & 4)) {
|
||||
if (_currentLevel == 16 && _currentSub == 1 && (_monsterProps[m->type].capsFlags & 4)) {
|
||||
if (m->type) {
|
||||
_playFinale = true;
|
||||
_runFlag = false;
|
||||
|
@ -1547,7 +1547,7 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g
|
||||
m->hitPointsCur -= damage;
|
||||
m->flags = (m->flags & 0xf7) | 1;
|
||||
|
||||
if (_monsterProps[m->type].flags & 0x2000) {
|
||||
if (_monsterProps[m->type].capsFlags & 0x2000) {
|
||||
explodeMonster(m);
|
||||
checkSceneUpdateNeed(m->block);
|
||||
m->hitPointsCur = 0;
|
||||
@ -1762,7 +1762,7 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
|
||||
}
|
||||
|
||||
if (dmg > 0) {
|
||||
if ((_monsterProps[m->type].flags & 0x80) && rollDice(1, 4, -1) != 3) {
|
||||
if ((_monsterProps[m->type].capsFlags & 0x80) && rollDice(1, 4, -1) != 3) {
|
||||
int slot = rollDice(1, 27, -1);
|
||||
for (int iii = 0; iii < 27; iii++) {
|
||||
Item itm = _characters[c].inventory[slot];
|
||||
@ -1782,20 +1782,20 @@ void EobCoreEngine::monsterCloseAttack(EobMonsterInPlay *m) {
|
||||
|
||||
inflictCharacterDamage(c, dmg);
|
||||
|
||||
if (_monsterProps[m->type].flags & 0x10) {
|
||||
if (_monsterProps[m->type].capsFlags & 0x10) {
|
||||
statusAttack(c, 2, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 3 : 2], 0, 1, 8, 1);
|
||||
_characters[c].effectFlags &= ~0x2000;
|
||||
}
|
||||
|
||||
if (_monsterProps[m->type].flags & 0x20)
|
||||
if (_monsterProps[m->type].capsFlags & 0x20)
|
||||
statusAttack(c, 4, _monsterSpecAttStrings[_flags.gameID == GI_EOB1 ? 4 : 3], 2, 5, 9, 1);
|
||||
|
||||
if (_monsterProps[m->type].flags & 0x8000)
|
||||
if (_monsterProps[m->type].capsFlags & 0x8000)
|
||||
statusAttack(c, 8, _monsterSpecAttStrings[4], 2, 0, 0, 1);
|
||||
|
||||
}
|
||||
|
||||
if (!(_monsterProps[m->type].flags & 0x4000))
|
||||
if (!(_monsterProps[m->type].capsFlags & 0x4000))
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1848,7 +1848,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
|
||||
s = 1;
|
||||
}
|
||||
|
||||
if ((flags & 0x100) && ((_flags.gameID == GI_EOB2 && (p->statusFlags & 0x100)) || (_flags.gameID == GI_EOB1 && (p->flags & 4))) && (!(_itemTypes[_items[pips].type].allowedClasses & 4 /* bug in original code ??*/)))
|
||||
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 (p->statusFlags & 0x2000) {
|
||||
@ -1866,7 +1866,7 @@ int EobCoreEngine::calcCloseDistanceMonsterDamage(EobMonsterInPlay *m, int times
|
||||
}
|
||||
|
||||
if (flags & 1) {
|
||||
if (checkMonsterDamageEvasion(m))
|
||||
if (tryMonsterAttackEvasion(m))
|
||||
s = 0;
|
||||
}
|
||||
|
||||
@ -1887,7 +1887,7 @@ int EobCoreEngine::calcDamageModifers(int charIndex, EobMonsterInPlay *m, int it
|
||||
if (item) {
|
||||
EobItemType *p = &_itemTypes[itemType];
|
||||
int t = m ? m->type : 0;
|
||||
s += ((m && (_monsterProps[t].flags & 1)) ? rollDice(p->dmgNumDiceL, p->dmgNumPipsL, p->dmgIncS /* bug in original code ? */) :
|
||||
s += ((m && (_monsterProps[t].capsFlags & 1)) ? rollDice(p->dmgNumDiceL, p->dmgNumPipsL, p->dmgIncS /* bug in original code ? */) :
|
||||
rollDice(p->dmgNumDiceS, p->dmgNumPipsS, p->dmgIncS));
|
||||
s += _items[item].value;
|
||||
} else {
|
||||
@ -1941,7 +1941,7 @@ int EobCoreEngine::recalcDamageModifier(int damageType, int dmgModifier) {
|
||||
return dmgModifier;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::checkMonsterDamageEvasion(EobMonsterInPlay *m) {
|
||||
bool EobCoreEngine::tryMonsterAttackEvasion(EobMonsterInPlay *m) {
|
||||
return rollDice(1, 100) < _monsterProps[m->type].dmgModifierEvade ? true : false;
|
||||
}
|
||||
|
||||
|
@ -169,8 +169,8 @@ struct EobMonsterProperty {
|
||||
int8 base;
|
||||
} dmgDc[3];
|
||||
uint16 statusFlags;
|
||||
uint16 flags;
|
||||
int32 u22;
|
||||
uint32 capsFlags;
|
||||
uint32 typeFlags;
|
||||
int32 experience;
|
||||
|
||||
uint8 u30;
|
||||
@ -182,7 +182,7 @@ struct EobMonsterProperty {
|
||||
|
||||
int8 remoteWeapons[5];
|
||||
|
||||
uint8 u41;
|
||||
uint8 tuResist;
|
||||
uint8 dmgModifierEvade;
|
||||
|
||||
uint8 decorations[3];
|
||||
@ -199,7 +199,7 @@ struct EobMonsterInPlay {
|
||||
int8 mode;
|
||||
int8 f_9;
|
||||
int8 curAttackFrame;
|
||||
uint8 f_b;
|
||||
int8 spellStatusLeft;
|
||||
int16 hitPointsMax;
|
||||
int16 hitPointsCur;
|
||||
uint16 dest;
|
||||
@ -334,7 +334,7 @@ protected:
|
||||
void setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer);
|
||||
void deleteCharEventTimer(int charIndex, int evnt);
|
||||
void setupCharacterTimers();
|
||||
void manualAdvanceTimer(int sysTimer, uint32 millis);
|
||||
void advanceTimers(uint32 millis);
|
||||
|
||||
void timerProcessMonsters(int timerNum);
|
||||
void timerSpecialCharacterUpdate(int timerNum);
|
||||
@ -511,7 +511,7 @@ protected:
|
||||
bool walkMonsterNextStep(EobMonsterInPlay *m, int destBlock, int direction);
|
||||
void updateMonsterFollowPath(EobMonsterInPlay *m, int turnSteps);
|
||||
void updateMonstersStraying(EobMonsterInPlay *m, int a);
|
||||
void updateMonsters_mode710(EobMonsterInPlay *m);
|
||||
void updateMonstersSpellStatus(EobMonsterInPlay *m);
|
||||
void setBlockMonsterDirection(int block, int dir);
|
||||
|
||||
uint8 *_monsterOvl1;
|
||||
@ -829,7 +829,7 @@ protected:
|
||||
int getConstModifierTableValue(int hpModifier, int level, int b);
|
||||
bool calcDamageCheckItemType(int itemType);
|
||||
int recalcDamageModifier(int damageType, int dmgModifier);
|
||||
bool checkMonsterDamageEvasion(EobMonsterInPlay *m);
|
||||
bool tryMonsterAttackEvasion(EobMonsterInPlay *m);
|
||||
int getStrHitChanceModifier(int charIndex);
|
||||
int getStrDamageModifier(int charIndex);
|
||||
int getDexHitChanceModifier(int charIndex);
|
||||
@ -856,7 +856,11 @@ protected:
|
||||
void setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer);
|
||||
void sortCharacterSpellList(int charIndex);
|
||||
|
||||
bool magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
|
||||
bool magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level);
|
||||
bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod);
|
||||
|
||||
void printWarning(const char* str);
|
||||
void printNoEffectWarning();
|
||||
|
||||
void spellCallback_start_empty() {}
|
||||
bool spellCallback_end_empty(EobFlyingObject *fo) { return true; }
|
||||
|
@ -665,11 +665,13 @@ void EobCoreEngine::gui_drawSpellbook() {
|
||||
int textXs = 71;
|
||||
int textY = 170;
|
||||
int col3 = _bkgColor_1;
|
||||
int col4 = _color6;
|
||||
|
||||
if (_flags.gameID == GI_EOB1) {
|
||||
textCol2 = 11;
|
||||
textXa = textXs = 73;
|
||||
textY = 168;
|
||||
col4 = _bkgColor_1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
@ -686,7 +688,7 @@ void EobCoreEngine::gui_drawSpellbook() {
|
||||
if (d >= 0 && i < 6 && (i + _openBookSpellListOffset) < 9)
|
||||
_screen->printText(_openBookSpellList[d], textXs, 132 + 6 * i, textCol1, col3);
|
||||
else
|
||||
_screen->printText(_magicStrings1[0], textXa, textY, 12, _color6);
|
||||
_screen->printText(_magicStrings1[0], textXa, textY, 12, col4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -805,7 +807,7 @@ void EobCoreEngine::gui_initButton(int index, int, int, int) {
|
||||
|
||||
if (_flags.gameID == GI_EOB1) {
|
||||
// EOB1 spellbook modifications
|
||||
if (index > 61 && index < 67)
|
||||
if (index > 60 && index < 66)
|
||||
d = &_buttonDefs[index + 33];
|
||||
if (index == 88)
|
||||
d = &_buttonDefs[index + 12];
|
||||
@ -867,7 +869,7 @@ int EobCoreEngine::clickedCamp(Button *button) {
|
||||
_screen->updateScreen();
|
||||
|
||||
enableSysTimer(2);
|
||||
manualAdvanceTimer(2, _restPartyElapsedTime);
|
||||
advanceTimers(_restPartyElapsedTime);
|
||||
_restPartyElapsedTime = 0;
|
||||
|
||||
checkPartyStatus(true);
|
||||
@ -1083,7 +1085,7 @@ int EobCoreEngine::clickedSpellbookList(Button *button) {
|
||||
|
||||
int s = _openBookAvailableSpells[_openBookSpellLevel * 10 + _openBookSpellListOffset + _openBookSpellSelectedItem];
|
||||
if (_openBookType == 1)
|
||||
s += _mageSpellListSize;
|
||||
s += _clericSpellOffset;
|
||||
|
||||
castSpell(s, 0);
|
||||
|
||||
@ -1100,11 +1102,10 @@ int EobCoreEngine::clickedSpellbookList(Button *button) {
|
||||
}
|
||||
|
||||
int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) {
|
||||
_activeSpellCaster = button->arg;
|
||||
_activeSpellCaster = button->arg & 0xff;
|
||||
|
||||
if (_activeSpellCaster == 255) {
|
||||
_txt->printMessage(_magicStrings3[1]);
|
||||
snd_playSoundEffect(79);
|
||||
if (_activeSpellCaster == 0xff) {
|
||||
printWarning(_magicStrings3[_flags.gameID == GI_EOB1 ? 2 : 1]);
|
||||
if (_castScrollSlot) {
|
||||
gui_updateSlotAfterScrollUse();
|
||||
} else {
|
||||
@ -2774,7 +2775,7 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
|
||||
|
||||
for (int i = 0; i < 80; i++) {
|
||||
int8 s = charSpellList[i];
|
||||
if (s == 0 || s == _vm->_spellLevelsClericSize)
|
||||
if (s == 0 || (_vm->game() == GI_EOB2 && s == 29))
|
||||
continue;
|
||||
|
||||
if (s < 0)
|
||||
@ -2938,8 +2939,8 @@ void GUI_Eob::runMemorizePrayMenu(int charIndex, int spellType) {
|
||||
_screen->setFont(Screen::FID_8_FNT);
|
||||
|
||||
memset(charSpellList, 0, 80);
|
||||
if (spellType)
|
||||
charSpellList[0] = _vm->_spellLevelsClericSize;
|
||||
if (spellType && _vm->game() == GI_EOB2)
|
||||
charSpellList[0] = 29;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (_numAssignedSpellsOfType[i * 2] < _numAssignedSpellsOfType[i * 2 + 1])
|
||||
@ -3187,7 +3188,7 @@ bool GUI_Eob::restParty() {
|
||||
|
||||
*list *= -1;
|
||||
crs[i] = 48;
|
||||
_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_mageSpellListSize + *list].name).c_str());
|
||||
_vm->_txt->printMessage(Common::String::format(_vm->_menuStringsRest2[0], _vm->_characters[i].name, _vm->_spells[_vm->_clericSpellOffset + *list].name).c_str());
|
||||
_vm->delay(80);
|
||||
break;
|
||||
}
|
||||
@ -3485,7 +3486,7 @@ void GUI_Eob::messageDialogue(int dim, int id, int buttonTextCol) {
|
||||
}
|
||||
|
||||
int GUI_Eob::selectCharacterDialogue(int id) {
|
||||
uint8 flags = (id == 26) ? 0x14 : 0x02;
|
||||
uint8 flags = (id == 26) ? (_vm->game() == GI_EOB1 ? 0x04 : 0x14) : 0x02;
|
||||
_vm->removeInputTop();
|
||||
|
||||
_charSelectRedraw = false;
|
||||
@ -3613,10 +3614,13 @@ int GUI_Eob::selectCharacterDialogue(int id) {
|
||||
_screen->setFont(Screen::FID_8_FNT);
|
||||
|
||||
if (result != -1 && id != 53) {
|
||||
if (flags == 0x14) {
|
||||
if (_vm->_classModifierFlags[_vm->_characters[result].cClass] & 0x10 && _vm->_characters[result].level[0] < 9) {
|
||||
displayTextBox(24);
|
||||
result = -1;
|
||||
if (flags & 4) {
|
||||
int lv = _vm->getCharacterLevelIndex(4, _vm->_characters[result].cClass);
|
||||
if (lv != -1) {
|
||||
if (_vm->_characters[result].level[lv] < 9) {
|
||||
displayTextBox(24);
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_vm->checkInventoryForItem(result, 29, -1) == -1) {
|
||||
|
@ -445,8 +445,7 @@ void EobCoreEngine::eatItemInHand(int charIndex) {
|
||||
} else if (_itemInHand && _items[_itemInHand].type != 31) {
|
||||
_txt->printMessage(_warningStrings[3]);
|
||||
} else if (_items[_itemInHand].value == -1) {
|
||||
_txt->printMessage(_warningStrings[2]);
|
||||
snd_playSoundEffect(79);
|
||||
printWarning(_warningStrings[2]);
|
||||
} else {
|
||||
c->food += _items[_itemInHand].value;
|
||||
if (c->food > 100)
|
||||
|
@ -156,14 +156,12 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
|
||||
|
||||
if (s->flags & 0x400) {
|
||||
if (c->inventory[0] && c->inventory[1]) {
|
||||
_txt->printMessage(_magicStrings1[2]);
|
||||
snd_playSoundEffect(79);
|
||||
printWarning(_magicStrings1[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMagicWeapon(c->inventory[0]) || isMagicWeapon(c->inventory[1])) {
|
||||
_txt->printMessage(_magicStrings1[3]);
|
||||
snd_playSoundEffect(79);
|
||||
printWarning(_magicStrings1[3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -205,10 +203,8 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
|
||||
EobCharacter *c = &_characters[charIndex];
|
||||
EobSpell *s = &_spells[spell];
|
||||
|
||||
if (showWarning) {
|
||||
_txt->printMessage(_magicStrings3[2], -1, c->name, s->name);
|
||||
snd_playSoundEffect(79);
|
||||
}
|
||||
if (showWarning)
|
||||
printWarning(Common::String::format(_magicStrings3[_flags.gameID == GI_EOB1 ? 3 : 2], c->name, s->name).c_str());
|
||||
|
||||
if (s->endCallback)
|
||||
(this->*s->endCallback)(0);
|
||||
@ -262,8 +258,7 @@ void EobCoreEngine::removeAllCharacterEffects(int charIndex) {
|
||||
}
|
||||
|
||||
void EobCoreEngine::castOnWhomDialogue() {
|
||||
_txt->printMessage(_magicStrings3[0]);
|
||||
snd_playSoundEffect(79);
|
||||
printWarning(_magicStrings3[0]);
|
||||
gui_setCastOnWhomButtons();
|
||||
}
|
||||
|
||||
@ -281,15 +276,13 @@ void EobCoreEngine::startSpell(int spell) {
|
||||
|
||||
if (s->flags & 0x20) {
|
||||
_txt->printMessage(c->name);
|
||||
_txt->printMessage(_magicStrings1[5]);
|
||||
_txt->printMessage(_flags.gameID == GI_EOB1 ? _magicStrings3[1] : _magicStrings1[5]);
|
||||
}
|
||||
|
||||
if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
|
||||
_txt->printMessage(_magicStrings7[0], -1, c->name, s->name);
|
||||
snd_playSoundEffect(79);
|
||||
printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
|
||||
} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
|
||||
_txt->printMessage(_magicStrings7[1], -1, s->name);
|
||||
snd_playSoundEffect(79);
|
||||
printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
|
||||
} else {
|
||||
if (s->flags & 8)
|
||||
setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
|
||||
@ -452,7 +445,7 @@ void EobCoreEngine::sortCharacterSpellList(int charIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
|
||||
bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level) {
|
||||
int ignoreAttackerId = fo->flags & 0x10;
|
||||
int singleTargetCheckAdjacent = fo->flags & 1;
|
||||
int blockDamage = fo->flags & 2;
|
||||
@ -527,6 +520,70 @@ bool EobCoreEngine::magicObjectHit(EobFlyingObject *fo, int dcTimes, int dcPips,
|
||||
return res;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod) {
|
||||
EobMonsterProperty *p = &_monsterProps[m->type];
|
||||
if (tryEvade) {
|
||||
if (tryMonsterAttackEvasion(m) || (p->capsFlags & 0x10))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (checkUnkConstModifiers(m, 0, p->level, mod, 6))
|
||||
return false;
|
||||
|
||||
int para = 0;
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
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)) {
|
||||
m->mode = 10;
|
||||
m->spellStatusLeft = 15;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (!(p->statusFlags & 8))
|
||||
inflictMonsterDamage(m, 1000, true);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
inflictMonsterDamage(m, 1000, true);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m->flags |= 0x20;
|
||||
_sceneUpdateRequired = true;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (!(p->statusFlags & 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);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EobCoreEngine::printWarning(const char* str) {
|
||||
_txt->printMessage(str);
|
||||
snd_playSoundEffect(79);
|
||||
}
|
||||
|
||||
void EobCoreEngine::printNoEffectWarning() {
|
||||
printWarning(_magicStrings4[0]);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_armor() {
|
||||
|
||||
}
|
||||
@ -548,7 +605,7 @@ void EobCoreEngine::spellCallback_start_magicMissile() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 1, 4, 1, (getCharacterMageLevel(fo->attackerId) - 1) >> 1);
|
||||
return magicObjectDamageHit(fo, 1, 4, 1, (getCharacterMageLevel(fo->attackerId) - 1) >> 1);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_shockingGrasp() {
|
||||
@ -568,7 +625,7 @@ void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
|
||||
return magicObjectDamageHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_dispelMagic() {
|
||||
@ -580,7 +637,7 @@ void EobCoreEngine::spellCallback_start_fireball() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
return magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_flameArrow() {
|
||||
@ -588,7 +645,7 @@ void EobCoreEngine::spellCallback_start_flameArrow() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 5, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
return magicObjectDamageHit(fo, 5, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_holdPerson() {
|
||||
@ -596,7 +653,28 @@ void EobCoreEngine::spellCallback_start_holdPerson() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
|
||||
return true;
|
||||
bool res = false;
|
||||
|
||||
if (_flags.gameID == GI_EOB2 && fo->curBlock == _currentBlock) {
|
||||
// party hit
|
||||
int numChar = rollDice(1, 4, 0);
|
||||
int charIndex = rollDice(1, 6, 0);
|
||||
for (int i = 0; i < 6 && numChar; i++) {
|
||||
if (testCharacter(charIndex, 3)) {
|
||||
statusAttack(charIndex, 4, _magicStrings8[1], 4, 5, 9, 1);
|
||||
numChar--;
|
||||
}
|
||||
charIndex = (charIndex + 1) % 6;
|
||||
}
|
||||
res = true;
|
||||
|
||||
} else {
|
||||
// monster hit
|
||||
for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, 1, 1); *m != -1; m++)
|
||||
res |= magicObjectStatusHit(&_monsters[*m], 0, true, 4);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_lightningBolt() {
|
||||
@ -604,7 +682,7 @@ void EobCoreEngine::spellCallback_start_lightningBolt() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
return magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_vampiricTouch() {
|
||||
@ -616,7 +694,12 @@ bool EobCoreEngine::spellCallback_end_vampiricTouch(EobFlyingObject*) {
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_fear() {
|
||||
|
||||
sparkEffectOffensive();
|
||||
uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].block == bl)
|
||||
magicObjectStatusHit(&_monsters[i], 6, true, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_iceStorm() {
|
||||
@ -625,12 +708,12 @@ void EobCoreEngine::spellCallback_start_iceStorm() {
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
|
||||
static int8 blockAdv[] = { -32, 32, 1, -1 };
|
||||
bool res = magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
bool res = magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
if (res) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint16 bl = fo->curBlock;
|
||||
fo->curBlock = (fo->curBlock + blockAdv[i]) & 0x3ff;
|
||||
magicObjectHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
magicObjectDamageHit(fo, 1, 6, 0, getCharacterMageLevel(fo->attackerId));
|
||||
fo->curBlock = bl;
|
||||
}
|
||||
}
|
||||
@ -650,7 +733,10 @@ void EobCoreEngine::spellCallback_start_holdMonster() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) {
|
||||
return true;
|
||||
bool res = false;
|
||||
for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, 1, 1); *m != -1; m++)
|
||||
res |= magicObjectStatusHit(&_monsters[*m], 1, true, 4);
|
||||
return res;
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_wallOfForce() {
|
||||
@ -662,18 +748,27 @@ void EobCoreEngine::spellCallback_start_disintegrate() {
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_fleshToStone() {
|
||||
|
||||
sparkEffectOffensive();
|
||||
int t = getClosestMonsterPos(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
|
||||
if (t != -1)
|
||||
magicObjectStatusHit(&_monsters[t], 5, true, 4);
|
||||
else
|
||||
printWarning(_magicStrings8[4]);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_stoneToFlesh() {
|
||||
|
||||
if (_characters[_activeSpellCaster].flags & 8)
|
||||
_characters[_activeSpellCaster].flags &= ~8;
|
||||
else
|
||||
printNoEffectWarning();
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_trueSeeing() {
|
||||
|
||||
_wllVmpMap[46] = 0;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_trueSeeing(EobFlyingObject*) {
|
||||
_wllVmpMap[46] = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -722,7 +817,13 @@ void EobCoreEngine::spellCallback_start_createFood() {
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_removeParalysis() {
|
||||
|
||||
int numChar = 4;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (!(_characters[i].flags & 4) || !numChar)
|
||||
continue;
|
||||
_characters[i].flags &= ~4;
|
||||
numChar--;
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
|
||||
@ -750,7 +851,7 @@ void EobCoreEngine::spellCallback_start_flameStrike() {
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 6, 8, 0, 0);
|
||||
return magicObjectDamageHit(fo, 6, 8, 0, 0);
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_raiseDead() {
|
||||
@ -763,12 +864,10 @@ void EobCoreEngine::spellCallback_start_harm() {
|
||||
|
||||
void EobCoreEngine::spellCallback_start_heal() {
|
||||
EobCharacter *c = &_characters[_activeSpellCaster];
|
||||
if (c->hitPointsMax <= c->hitPointsCur) {
|
||||
_txt->printMessage(_magicStrings4[0]);
|
||||
snd_playSoundEffect(79);
|
||||
} else {
|
||||
if (c->hitPointsMax <= c->hitPointsCur)
|
||||
printWarning(_magicStrings4[0]);
|
||||
else
|
||||
modifyCharacterHitpoints(_activeSpellCaster, c->hitPointsMax - c->hitPointsCur);
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::spellCallback_start_layOnHands() {
|
||||
@ -782,19 +881,19 @@ void EobCoreEngine::spellCallback_start_turnUndead() {
|
||||
bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) {
|
||||
bool res = false;
|
||||
if (_partyEffectFlags & 0x20000) {
|
||||
res = magicObjectHit(fo, 4, 10, 6, 0);
|
||||
res = magicObjectDamageHit(fo, 4, 10, 6, 0);
|
||||
if (res) {
|
||||
gui_drawAllCharPortraitsWithStats();
|
||||
_partyEffectFlags &= ~0x20000;
|
||||
}
|
||||
} else {
|
||||
res = magicObjectHit(fo, 12, 10, 6, 0);
|
||||
res = magicObjectDamageHit(fo, 12, 10, 6, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_unk2Passive(EobFlyingObject *fo) {
|
||||
return magicObjectHit(fo, 0, 0, 18, 0);
|
||||
return magicObjectDamageHit(fo, 0, 0, 18, 0);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::spellCallback_end_deathSpellPassive(EobFlyingObject *fo) {
|
||||
|
@ -315,7 +315,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) {
|
||||
m->mode = in.readSByte();
|
||||
m->f_9 = in.readSByte();
|
||||
m->curAttackFrame = in.readSByte();
|
||||
m->f_b = in.readByte();
|
||||
m->spellStatusLeft = in.readSByte();
|
||||
m->hitPointsMax = in.readSint16BE();
|
||||
m->hitPointsCur = in.readSint16BE();
|
||||
m->dest = in.readUint16BE();
|
||||
@ -523,7 +523,7 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName,
|
||||
out->writeSByte(m->mode);
|
||||
out->writeSByte(m->f_9);
|
||||
out->writeSByte(m->curAttackFrame);
|
||||
out->writeByte(m->f_b);
|
||||
out->writeSByte(m->spellStatusLeft);
|
||||
out->writeSint16BE(m->hitPointsMax);
|
||||
out->writeSint16BE(m->hitPointsCur);
|
||||
out->writeUint16BE(m->dest);
|
||||
|
@ -583,7 +583,7 @@ void LolEobBaseEngine::openCloseDoor(int block, int openClose) {
|
||||
}
|
||||
}
|
||||
|
||||
enableTimer(_flags.gameID == GI_LOL ? 0 : 12);
|
||||
enableTimer(_flags.gameID == GI_LOL ? 0 : 4);
|
||||
|
||||
} else {
|
||||
while (!(flg & _wllWallFlags[v]))
|
||||
|
@ -99,9 +99,9 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
|
||||
d->dmgDc[3].base = (int8)*data++;
|
||||
d->statusFlags = READ_LE_UINT16(data);
|
||||
data += 2;
|
||||
d->flags = READ_LE_UINT16(data);
|
||||
d->capsFlags = READ_LE_UINT16(data);
|
||||
data += 2;
|
||||
d->u22 = (int16)READ_LE_UINT16(data);
|
||||
d->typeFlags = READ_LE_UINT16(data);
|
||||
data += 2;
|
||||
d->experience = READ_LE_UINT16(data);
|
||||
data += 2;
|
||||
@ -121,7 +121,7 @@ const uint8 *EobCoreEngine::loadMonsterProperties(const uint8 *data) {
|
||||
}
|
||||
}
|
||||
|
||||
d->u41 = *data++;
|
||||
d->tuResist = *data++;
|
||||
d->dmgModifierEvade = *data++;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
@ -176,7 +176,7 @@ void EobCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int
|
||||
m->pos = pos;
|
||||
m->shpIndex = shpIndex;
|
||||
m->mode = mode;
|
||||
m->f_b = i;
|
||||
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));
|
||||
@ -503,11 +503,11 @@ void EobCoreEngine::drawMonsters(int index) {
|
||||
|
||||
EobMonsterProperty *p = &_monsterProps[d->type];
|
||||
|
||||
if (_flags.gameID == GI_EOB2 && (p->flags & 0x100) && !(_partyEffectFlags & 0x220) && !(d->flags & 2))
|
||||
if (_flags.gameID == GI_EOB2 && (p->capsFlags & 0x100) && !(_partyEffectFlags & 0x220) && !(d->flags & 2))
|
||||
continue;
|
||||
|
||||
int f = (d->animStep << 4) + cDirOffs + d->dir;
|
||||
f = (p->flags & 2) ? _monsterFrmOffsTable1[f] : _monsterFrmOffsTable2[f];
|
||||
f = (p->capsFlags & 2) ? _monsterFrmOffsTable1[f] : _monsterFrmOffsTable2[f];
|
||||
|
||||
if (!blockDistance && d->curAttackFrame < 0)
|
||||
f = d->curAttackFrame + 7;
|
||||
@ -719,7 +719,7 @@ void EobCoreEngine::updateMonsters(int unit) {
|
||||
break;
|
||||
case 7:
|
||||
case 10:
|
||||
updateMonsters_mode710(m);
|
||||
updateMonstersSpellStatus(m);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -871,7 +871,7 @@ void EobCoreEngine::updateMoveMonster(EobMonsterInPlay *m) {
|
||||
EobMonsterProperty *p = &_monsterProps[m->type];
|
||||
int d = getNextMonsterDirection(m->block, _currentBlock);
|
||||
|
||||
if ((p->flags & 0x800) && !(d & 1))
|
||||
if ((p->capsFlags & 0x800) && !(d & 1))
|
||||
d >>= 1;
|
||||
else
|
||||
d = m->dir;
|
||||
@ -892,13 +892,13 @@ void EobCoreEngine::updateMoveMonster(EobMonsterInPlay *m) {
|
||||
m->curAttackFrame = 0;
|
||||
walkMonster(m, m->dest);
|
||||
|
||||
if (p->flags & 8)
|
||||
if (p->capsFlags & 8)
|
||||
updateMonsterTryCloseAttack(m, -1);
|
||||
}
|
||||
|
||||
bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) {
|
||||
EobMonsterProperty *p = &_monsterProps[m->type];
|
||||
if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->flags & 0x40)))
|
||||
if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->capsFlags & 0x40)))
|
||||
return false;
|
||||
|
||||
if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack == 5) || (_flags.gameID == GI_EOB2 && rollDice(1, 3) > m->stepsTillRemoteAttack)) {
|
||||
@ -1073,8 +1073,8 @@ void EobCoreEngine::walkMonster(EobMonsterInPlay *m, int destBlock) {
|
||||
if (m->flags & 8) {
|
||||
if (_flags.gameID == GI_EOB1 ) {
|
||||
d ^= 4;
|
||||
} else if (--m->f_b <= 0) {
|
||||
m->f_b = 0;
|
||||
} else if (--m->spellStatusLeft <= 0) {
|
||||
m->spellStatusLeft = 0;
|
||||
m->flags &= ~8;
|
||||
} else {
|
||||
d ^= 4;
|
||||
@ -1095,7 +1095,7 @@ void EobCoreEngine::walkMonster(EobMonsterInPlay *m, int destBlock) {
|
||||
} else if (_flags.gameID == GI_EOB2) {
|
||||
if (d & 1) {
|
||||
int e = _monsterStepTable1[((d - 1) << 1) + m->dir];
|
||||
if (e && !((_monsterProps[m->type].flags & 0x200) && (rollDice(1, 4) == 4))) {
|
||||
if (e && !((_monsterProps[m->type].capsFlags & 0x200) && (rollDice(1, 4) == 4))) {
|
||||
if (walkMonsterNextStep(m, b + e, -1))
|
||||
return;
|
||||
}
|
||||
@ -1144,11 +1144,11 @@ bool EobCoreEngine::walkMonsterNextStep(EobMonsterInPlay *m, int destBlock, int
|
||||
uint8 w = l->walls[direction ^ 2];
|
||||
|
||||
if (!(_wllWallFlags[w] & 4)) {
|
||||
if (_flags.gameID == GI_EOB1 ||!(p->flags & 0x1000) || _wllShapeMap[w] != -1)
|
||||
if (_flags.gameID == GI_EOB1 || !(p->capsFlags & 0x1000) || _wllShapeMap[w] != -1)
|
||||
return false;
|
||||
|
||||
if (_wllWallFlags[w] & 0x20) {
|
||||
if (p->flags & 4 && m->type == 1)
|
||||
if (p->capsFlags & 4 && m->type == 1)
|
||||
l->walls[direction] = l->walls[direction ^ 2] = 72;
|
||||
else
|
||||
openDoor(destBlock);
|
||||
@ -1219,9 +1219,9 @@ void EobCoreEngine::updateMonstersStraying(EobMonsterInPlay *m, int a) {
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::updateMonsters_mode710(EobMonsterInPlay *m) {
|
||||
if (m->f_b) {
|
||||
if (!--m->f_b)
|
||||
void EobCoreEngine::updateMonstersSpellStatus(EobMonsterInPlay *m) {
|
||||
if (m->spellStatusLeft) {
|
||||
if (!--m->spellStatusLeft)
|
||||
m->mode = 0;
|
||||
}
|
||||
}
|
||||
|
@ -631,7 +631,7 @@ void EobCoreEngine::initButtonData() {
|
||||
{ 4, 0, 0x1100, 113, 122, 20, 8, EOB_CB(clickedSpellbookTab), 2 },
|
||||
{ 5, 0, 0x1100, 134, 122, 20, 8, EOB_CB(clickedSpellbookTab), 3 },
|
||||
{ 6, 0, 0x1100, 155, 122, 20, 8, EOB_CB(clickedSpellbookTab), 4 },
|
||||
{ 110, 0, 0x1100, 75, 168, 97, 6, EOB_CB(clickedSpellbookAbort), 0 },
|
||||
{ 110, 0, 0x1100, 75, 168, 97, 6, EOB_CB(clickedSpellbookAbort), 0 }
|
||||
};
|
||||
|
||||
_buttonDefs = buttonDefs;
|
||||
@ -975,11 +975,19 @@ void EobCoreEngine::initSpells() {
|
||||
ec2(fleshToStonePassive);
|
||||
|
||||
_spells = new EobSpell[_numSpells];
|
||||
memset(_spells, 0, _numSpells * sizeof(EobSpell));
|
||||
memset(_spells, 0, _numSpells * sizeof(EobSpell));
|
||||
|
||||
for (int i = 0; i < _numSpells; i++) {
|
||||
for (int i = 0, n = 0; i < _numSpells; i++, n++) {
|
||||
EobSpell *s = &_spells[i];
|
||||
s->name = _flags.gameID == GI_EOB2 ? ((i == 0 || i == _mageSpellListSize) ? _mageSpellList[0] : ((i < (_mageSpellListSize + 1)) ? _spellNames[i - 1] : _spellNames[i - 2])) : _spellNames[i];
|
||||
|
||||
// Fix Eob 1 spell names
|
||||
bool skip = false;
|
||||
if (i == 5 || i == 9) {
|
||||
n--;
|
||||
skip = true;
|
||||
}
|
||||
|
||||
s->name = _flags.gameID == GI_EOB2 ? ((i == 0 || i == _mageSpellListSize) ? _mageSpellList[0] : ((i < (_mageSpellListSize + 1)) ? _spellNames[i - 1] : _spellNames[i - 2])) : (skip ? _spellNames[0] : _spellNames[n]);
|
||||
s->startCallback = startCallback[i];
|
||||
s->timingPara = magicTimingParaAssign[i];
|
||||
s->endCallback = endCallback[i];
|
||||
@ -1031,8 +1039,7 @@ void EobEngine::initStaticResource() {
|
||||
temp /= 27;
|
||||
_monsterProps = new EobMonsterProperty[temp];
|
||||
memset(_monsterProps, 0, temp * sizeof(EobMonsterProperty));
|
||||
// Try to convert EOB1 (hard coded) monster properties to EOB2 type monster properties.
|
||||
// This is still WIP, since most properties are unknown for now.
|
||||
// Convert EOB1 (hard coded) monster properties to EOB2 type monster properties.
|
||||
for (int i = 0; i < temp; i++) {
|
||||
EobMonsterProperty *p = &_monsterProps[i];
|
||||
p->armorClass = (int8)*ps++;
|
||||
@ -1049,9 +1056,9 @@ void EobEngine::initStaticResource() {
|
||||
p->dmgDc[2].pips = *ps++;
|
||||
p->dmgDc[2].base = (int8)*ps++;
|
||||
ps++;
|
||||
p->flags = *ps++;
|
||||
ps++;
|
||||
ps++;
|
||||
p->capsFlags = *ps++;
|
||||
p->typeFlags = READ_LE_UINT16(ps);
|
||||
ps += 2;
|
||||
ps++;
|
||||
ps++;
|
||||
p->experience = READ_LE_UINT16(ps);
|
||||
@ -1060,7 +1067,7 @@ void EobEngine::initStaticResource() {
|
||||
p->sound1 = *ps++;
|
||||
p->sound2 = *ps++;
|
||||
p->numRemoteAttacks = *ps++;
|
||||
ps++;
|
||||
p->tuResist = *ps++;
|
||||
p->dmgModifierEvade = *ps++;
|
||||
}
|
||||
}
|
||||
@ -1132,7 +1139,7 @@ void EobEngine::initSpells() {
|
||||
|
||||
int temp;
|
||||
const uint8 *src = _staticres->loadRawData(kEobBaseSpellProperties, temp);
|
||||
_clericSpellOffset -= 3;
|
||||
_clericSpellOffset -= 1;
|
||||
|
||||
for (int i = 0; i < _numSpells; i++) {
|
||||
EobSpell *s = &_spells[i];
|
||||
|
@ -129,26 +129,6 @@ void TimerManager::update() {
|
||||
}
|
||||
}
|
||||
|
||||
void TimerManager::manualAdvance(uint32 millis) {
|
||||
uint32 curTime = _system->getMillis();
|
||||
for (Iterator pos = _timers.begin(); pos != _timers.end(); ++pos) {
|
||||
if (pos->enabled == 1 && pos->countdown >= 0) {
|
||||
pos->nextRun -= curTime;
|
||||
while (pos->nextRun <= millis) {
|
||||
if (pos->func && pos->func->isValid())
|
||||
(*pos->func)(pos->id);
|
||||
|
||||
pos->lastUpdate = curTime;
|
||||
pos->nextRun = pos->countdown * _vm->tickLength();
|
||||
millis -= pos->nextRun;
|
||||
}
|
||||
pos->nextRun += curTime;
|
||||
_nextRun = MIN(_nextRun, pos->nextRun);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TimerManager::resync() {
|
||||
const uint32 curTime = _isPaused ? _pauseStart : _system->getMillis();
|
||||
|
||||
|
@ -61,8 +61,6 @@ public:
|
||||
|
||||
void update();
|
||||
|
||||
void manualAdvance(uint32 millis);
|
||||
|
||||
void resetNextRun();
|
||||
|
||||
void setCountdown(uint8 id, int32 countdown);
|
||||
|
@ -133,19 +133,21 @@ void EobCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt,
|
||||
_timer->setNextRun(timerId, ntime);
|
||||
|
||||
if (updateExistingTimer) {
|
||||
bool br = false;
|
||||
bool updated = false;
|
||||
int d = -1;
|
||||
|
||||
for (int i = 0; i < 10 && br == false; i++) {
|
||||
for (int i = 0; i < 10 && updated == false; i++) {
|
||||
if (d == -1 && !c->timers[i])
|
||||
d = i;
|
||||
|
||||
if (!br && c->events[i] == evnt) {
|
||||
if (!updated && c->events[i] == evnt) {
|
||||
d = i;
|
||||
br = true;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
assert(d != -1);
|
||||
|
||||
c->timers[d] = ntime;
|
||||
c->events[d] = evnt;
|
||||
} else {
|
||||
@ -179,7 +181,7 @@ void EobCoreEngine::setupCharacterTimers() {
|
||||
uint32 nextTimer = 0xffffffff;
|
||||
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
if (c->timers[ii] < nextTimer)
|
||||
if (c->timers[ii] && c->timers[ii] < nextTimer)
|
||||
nextTimer = c->timers[ii];
|
||||
}
|
||||
uint32 ctime = _system->getMillis();
|
||||
@ -193,21 +195,28 @@ void EobCoreEngine::setupCharacterTimers() {
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::manualAdvanceTimer(int sysTimer, uint32 millis) {
|
||||
if (sysTimer != 2)
|
||||
return;
|
||||
|
||||
void EobCoreEngine::advanceTimers(uint32 millis) {
|
||||
uint32 ct = _system->getMillis();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
EobCharacter *c = &_characters[i];
|
||||
for (int ii = 0; ii < 10; ii++) {
|
||||
if (_characters[i].timers[ii]) {
|
||||
uint32 chrt = _characters[i].timers[ii] - ct;
|
||||
_characters[i].timers[ii] = chrt > millis ? chrt - millis : 1;
|
||||
if (c->timers[ii] > ct) {
|
||||
uint32 chrt = c->timers[ii] - ct;
|
||||
c->timers[ii] = chrt > millis ? chrt - millis : ct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_timer->manualAdvance(millis);
|
||||
setupCharacterTimers();
|
||||
|
||||
if (_scriptTimersMode & 2) {
|
||||
for (int i = 0; i < _scriptTimersCount; i++) {
|
||||
if (_scriptTimers[i].next > ct) {
|
||||
uint32 chrt = _scriptTimers[i].next - ct;
|
||||
_scriptTimers[i].next = chrt > millis ? chrt - millis : ct;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EobCoreEngine::timerProcessCharacterExchange(int timerNum) {
|
||||
@ -314,7 +323,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
|
||||
calcAndInflictCharacterDamage(charIndex, 0, 0, 5, 0x400, 5, 3);
|
||||
setCharEventTimer(charIndex, 546, 8, 1);
|
||||
} else {
|
||||
c->flags &= 0xfd;
|
||||
c->flags &= ~2;
|
||||
gui_drawCharPortraitWithStats(charIndex);
|
||||
}
|
||||
break;
|
||||
@ -329,7 +338,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
|
||||
|
||||
case 11:
|
||||
if (c->disabledSlots & 4) {
|
||||
c->disabledSlots &= 0xfb;
|
||||
c->disabledSlots &= ~4;
|
||||
if (_openBookChar == charIndex && _updateFlags)
|
||||
gui_drawSpellbook();
|
||||
}
|
||||
@ -345,13 +354,13 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32 nextTimer = (uint32)(-1);
|
||||
uint32 nextTimer = 0xffffffff;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (c->timers[i] && c->timers[i] < nextTimer)
|
||||
nextTimer = c->timers[i];
|
||||
}
|
||||
|
||||
if (nextTimer == (uint32)(-1))
|
||||
if (nextTimer == 0xffffffff)
|
||||
_timer->disable(timerNum);
|
||||
else
|
||||
_timer->setCountdown(timerNum, (nextTimer - ctime) / _tickLength);
|
||||
|
Loading…
Reference in New Issue
Block a user