aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2018-04-11 21:04:51 -0400
committerPaul Gilbert2018-04-11 21:04:51 -0400
commit8fdd055bf114840cdee906dec0a09e859f5cf434 (patch)
tree877ea914edac002004f009714b3cf2ecf105b1f1
parentfe81c9c1d3175de12ece23f33a1857c19ca8bfa2 (diff)
downloadscummvm-rg350-8fdd055bf114840cdee906dec0a09e859f5cf434.tar.gz
scummvm-rg350-8fdd055bf114840cdee906dec0a09e859f5cf434.tar.bz2
scummvm-rg350-8fdd055bf114840cdee906dec0a09e859f5cf434.zip
XEEN: Fix monster attacks that target the entire party
-rw-r--r--engines/xeen/character.h2
-rw-r--r--engines/xeen/combat.cpp143
-rw-r--r--engines/xeen/combat.h9
3 files changed, 78 insertions, 76 deletions
diff --git a/engines/xeen/character.h b/engines/xeen/character.h
index 6639d837f3..47312efe66 100644
--- a/engines/xeen/character.h
+++ b/engines/xeen/character.h
@@ -55,7 +55,7 @@ enum CharacterClass {
};
enum HatesClass {
- HATES_DWARF = 12, HATES_ALL_CLASSES = 15, HATES_NO_CLASSES = 16
+ HATES_DWARF = 12, HATES_PARTY = 15, HATES_NOBODY = 16
};
enum Attribute {
diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp
index 0ac80650eb..e5e518fa37 100644
--- a/engines/xeen/combat.cpp
+++ b/engines/xeen/combat.cpp
@@ -814,15 +814,20 @@ void Combat::doMonsterTurn(int monsterId) {
}
MonsterStruct &monsterData = map._monsterData[monsterId];
- bool flag = false;
for (int attackNum = 0; attackNum < monsterData._numberOfAttacks; ++attackNum) {
int charNum = -1;
bool isHated = false;
- if (monsterData._hatesClass != -1) {
- if (monsterData._hatesClass == HATES_ALL_CLASSES)
- // Monster hates all classes
- goto loop;
+ if (monsterData._hatesClass != CLASS_PALADIN) {
+ if (monsterData._hatesClass == HATES_PARTY) {
+ // Monster hates entire party, even the disabled/dead
+ for (uint idx = 0; idx < _combatParty.size(); ++idx) {
+ doMonsterTurn(monsterId, idx);
+ }
+
+ // Move onto monster's next attack (if any)
+ continue;
+ }
for (uint charIndex = 0; charIndex < _combatParty.size(); ++charIndex) {
Character &c = *_combatParty[charIndex];
@@ -830,10 +835,8 @@ void Combat::doMonsterTurn(int monsterId) {
if (cond >= PARALYZED && cond <= ERADICATED)
continue;
- isHated = false;
switch (monsterData._hatesClass) {
case CLASS_KNIGHT:
- case CLASS_PALADIN:
case CLASS_ARCHER:
case CLASS_CLERIC:
case CLASS_SORCERER:
@@ -859,88 +862,78 @@ void Combat::doMonsterTurn(int monsterId) {
}
if (!isHated) {
- // No particularly hated foe, so decide which character to start with
+ // No particularly hated foe, so pick a random character to start with
// Note: Original had a whole switch statement depending on party size, that boiled down to
// picking a random character in all cases anyway
charNum = _vm->getRandomNumber(0, _combatParty.size() - 1);
}
- // 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)];
- }
+ // If the chosen character is already disabled, we need to pick a still able body character
+ // from the remainder of the combat party
+ Condition cond = _combatParty[charNum]->worstCondition();
+ if (cond >= PARALYZED && cond <= ERADICATED) {
+ Common::Array<int> ableChars;
+
+ for (uint idx = 0; idx < _combatParty.size(); ++idx) {
+ switch (_combatParty[idx]->worstCondition()) {
+ case PARALYZED:
+ case UNCONSCIOUS:
+ case DEAD:
+ case STONED:
+ case ERADICATED:
+ break;
+ default:
+ ableChars.push_back(idx);
+ break;
}
}
- // Unconditional if to get around goto initialization errors
- if (true) {
- Character &c = *_combatParty[charNum];
- if (monsterData._attackType != DT_PHYSICAL || c._conditions[ASLEEP]) {
- doCharDamage(c, charNum, monsterId);
- } else {
- int v = _vm->getRandomNumber(1, 20);
- if (v == 1) {
- // Critical Save
- sound.playFX(6);
- } else {
- if (v == 20)
- // Critical failure
- doCharDamage(c, charNum, monsterId);
- 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, charNum, monsterId);
- }
- }
- }
-
- if (flag)
- break;
+ if (ableChars.size() == 0) {
+ party._dead = true;
+ _vm->_mode = MODE_1;
+ return;
}
-loop:
- flag = true;
- } while (++charNum < (int)_combatParty.size());
+
+ charNum = ableChars[_vm->getRandomNumber(0, ableChars.size() - 1)];
+ }
+
+ doMonsterTurn(monsterId, charNum);
}
intf.drawParty(true);
}
+void Combat::doMonsterTurn(int monsterId, int charNum) {
+ Map &map = *_vm->_map;
+ Sound &sound = *_vm->_sound;
+ MonsterStruct &monsterData = map._monsterData[monsterId];
+ Character &c = *_combatParty[charNum];
+
+ if (monsterData._attackType != DT_PHYSICAL || c._conditions[ASLEEP]) {
+ doCharDamage(c, charNum, monsterId);
+ } else {
+ int v = _vm->getRandomNumber(1, 20);
+ if (v == 1) {
+ // Critical Save
+ sound.playFX(6);
+ } else {
+ if (v == 20)
+ // Critical failure
+ doCharDamage(c, charNum, monsterId);
+ 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, charNum, monsterId);
+ }
+ }
+ }
+}
+
int Combat::stopAttack(const Common::Point &diffPt) {
Map &map = *_vm->_map;
Party &party = *_vm->_party;
diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h
index e55c8b7553..e6ac1e27bb 100644
--- a/engines/xeen/combat.h
+++ b/engines/xeen/combat.h
@@ -77,6 +77,7 @@ enum RangeType {
class XeenEngine;
class Character;
class XeenItem;
+class MonsterStruct;
struct PowSlot {
bool _active;
@@ -291,9 +292,17 @@ public:
*/
void moveMonster(int monsterId, const Common::Point &moveDelta);
+ /**
+ * Handle a monster's turn at attacking combat party members
+ */
void doMonsterTurn(int monsterId);
/**
+ * Handles a monster's turn at attacking a specific member of the combat party
+ */
+ void doMonsterTurn(int monsterId, int charNum);
+
+ /**
* Called when combat has ended
*/
void endAttack();