diff options
author | Paul Gilbert | 2015-02-20 08:47:38 -0500 |
---|---|---|
committer | Paul Gilbert | 2015-02-20 08:47:38 -0500 |
commit | caf7f376b3fd8bb1bfd3e658139b547695033dde (patch) | |
tree | 6b0ed8edb2fcc94bbd75626ed40db57cf999edb2 | |
parent | b66bf1a838b01181c93b19e214c59c810e05955d (diff) | |
download | scummvm-rg350-caf7f376b3fd8bb1bfd3e658139b547695033dde.tar.gz scummvm-rg350-caf7f376b3fd8bb1bfd3e658139b547695033dde.tar.bz2 scummvm-rg350-caf7f376b3fd8bb1bfd3e658139b547695033dde.zip |
XEEN: Implemented monsterAttack
-rw-r--r-- | engines/xeen/combat.cpp | 184 | ||||
-rw-r--r-- | engines/xeen/combat.h | 2 | ||||
-rw-r--r-- | engines/xeen/map.h | 2 |
3 files changed, 187 insertions, 1 deletions
diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp index a9ead958a8..b6d1f7fe1d 100644 --- a/engines/xeen/combat.cpp +++ b/engines/xeen/combat.cpp @@ -236,6 +236,13 @@ loop: } } +/** + * Do damage to a specific character + */ +void Combat::doCharDamage(Character *c, int monsterDataIndex) { + error("TODO"); +} + void Combat::moveMonsters() { Interface &intf = *_vm->_interface; Map &map = *_vm->_map; @@ -565,7 +572,184 @@ void Combat::monsterOvercome() { } void Combat::attackMonster(int monsterId) { + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + SoundManager &sound = *_vm->_sound; + int monRefId; + + if (_monstersAttacking) { + warning("TODO: Original used uninitialized variables if flag was set"); + return; + } + + int monsterIndex; + switch (_whosTurn - _combatParty.size()) { + case 0: + monsterIndex = _attackMonsters[0]; + intf._indoorList[156]._scale = 0; + break; + case 1: + monsterIndex = _attackMonsters[1]; + intf._indoorList[150]._scale = 0; + break; + case 2: + default: + monsterIndex = _attackMonsters[2]; + intf._indoorList[153]._scale = 0; + } + + MazeMonster &monster = map._mobData._monsters[monsterIndex]; + MonsterStruct &monsterData = map._monsterData[monster._spriteId]; + if (monster._field7) + return; + + monster._frame = 8; + monster._fieldA = 3; + monster._field9 = 0; + intf.draw3d(true); + intf.draw3d(true); + + File f(monsterData._attackVoc); + sound.playSample(&f, 0); + bool flag = false; + + for (int attackNum = 0; attackNum < monsterData._numberOfAttacks; ++attackNum) { + int charNum = -1; + bool isHated = false; + + if (monsterData._hatesClass != -1) { + if (monsterData._hatesClass == 15) + // Monster hates all classes + goto loop; + + for (uint charIndex = 0; charIndex < _combatParty.size(); ++charIndex) { + Character &c = *_combatParty[charIndex]; + Condition cond = c.worstCondition(); + if (cond >= PARALYZED && cond <= ERADICATED) + continue; + + bool isHated = false; + switch (monsterData._hatesClass) { + case CLASS_KNIGHT: + case CLASS_PALADIN: + case CLASS_ARCHER: + case CLASS_CLERIC: + case CLASS_SORCERER: + case CLASS_ROBBER: + case CLASS_NINJA: + case CLASS_BARBARIAN: + case CLASS_DRUID: + case CLASS_RANGER: + isHated = c._class == monsterData._hatesClass; + break; + case 12: + isHated = c._race == DWARF; + break; + default: + break; + } + + if (isHated) { + charNum = charIndex; + break; + } + } + } + + if (!isHated) { + // No particularly hated foe, so decide which character to start with + switch (_combatParty.size()) { + case 1: + charNum = 0; + break; + case 2: + case 3: + case 4: + case 5: + charNum = _vm->getRandomNumber(0, _combatParty.size() - 1); + break; + case 6: + if (_vm->getRandomNumber(1, 6) == 6) + charNum = 5; + else + charNum = _vm->getRandomNumber(0, 4); + break; + } + } + + // Attacking loop + do { + if (!flag) { + Condition cond = _combatParty[charNum]->worstCondition(); + + if (cond >= PARALYZED && cond <= ERADICATED) { + Common::Array<int> ableChars; + bool skip = false; + + for (uint idx = 0; idx < _combatParty.size() && !skip; ++idx) { + switch (_combatParty[idx]->worstCondition()) { + case PARALYZED: + case UNCONSCIOUS: + if (flag) + skip = true; + break; + case DEAD: + case STONED: + case ERADICATED: + break; + default: + ableChars.push_back(idx); + break; + } + } + + if (!skip) { + if (ableChars.size() == 0) { + party._dead = true; + _vm->_mode = MODE_1; + return; + } + + charNum = ableChars[_vm->getRandomNumber(0, ableChars.size() - 1)]; + } + } + } + + // Unconditional if to get around goto initialization errors + if (true) { + Character &c = *_combatParty[charNum]; + if (monsterData._attackType != DT_PHYSICAL || c._conditions[ASLEEP]) { + doCharDamage(&c, monster._spriteId); + } else { + int v = _vm->getRandomNumber(1, 20); + if (v == 1) { + sound.playFX(6); + } else { + if (v == 20) + doCharDamage(&c, monster._spriteId); + v += monsterData._hitChance / 4 + _vm->getRandomNumber(1, + monsterData._hitChance); + + int ac = c.getArmorClass() + (!_charsBlocked[charNum] ? 10 : + c.getCurrentLevel() / 2 + 15); + if (ac > v) { + sound.playFX(6); + } else { + doCharDamage(&c, monster._spriteId); + } + } + } + + if (flag) + break; + } +loop: + flag = true; + } while (++charNum < (int)_combatParty.size()); + } + intf.drawParty(true); } int Combat::stopAttack(const Common::Point &diffPt) { diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h index b9293233e7..df42a4031f 100644 --- a/engines/xeen/combat.h +++ b/engines/xeen/combat.h @@ -107,6 +107,8 @@ public: void giveCharDamage(int damage, DamageType attackType, int charIndex); + void doCharDamage(Character *c, int monsterDataIndex); + void moveMonsters(); void setupCombatParty(); diff --git a/engines/xeen/map.h b/engines/xeen/map.h index a43cef516e..05ead5b974 100644 --- a/engines/xeen/map.h +++ b/engines/xeen/map.h @@ -54,7 +54,7 @@ public: int _accuracy; int _speed; int _numberOfAttacks; - CharacterClass _hatesClass; + int _hatesClass; int _strikes; int _dmgPerStrike; DamageType _attackType; |