diff options
-rw-r--r-- | engines/xeen/combat.cpp | 57 | ||||
-rw-r--r-- | engines/xeen/combat.h | 41 | ||||
-rw-r--r-- | engines/xeen/interface.cpp | 10 | ||||
-rw-r--r-- | engines/xeen/interface_scene.cpp | 42 |
4 files changed, 88 insertions, 62 deletions
diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp index 2559559d47..bed9b26f60 100644 --- a/engines/xeen/combat.cpp +++ b/engines/xeen/combat.cpp @@ -93,11 +93,6 @@ static const int MONSTER_ITEM_RANGES[6] = { 10, 20, 50, 100, 100, 100 }; Combat::Combat(XeenEngine *vm): _vm(vm), _missVoc("miss.voc") { Common::fill(&_attackMonsters[0], &_attackMonsters[26], 0); - Common::fill(&_charsArray1[0], &_charsArray1[12], 0); - Common::fill(&_monPow[0], &_monPow[12], 0); - Common::fill(&_monsterScale[0], &_monsterScale[12], 0); - Common::fill(&_elemPow[0], &_elemPow[12], ELEM_FIRE); - Common::fill(&_elemScale[0], &_elemScale[12], 0); Common::fill(&_shootingRow[0], &_shootingRow[MAX_PARTY_COUNT], 0); Common::fill(&_monsterMap[0][0], &_monsterMap[32][32], 0); Common::fill(&_monsterMoved[0], &_monsterMoved[MAX_NUM_MONSTERS], false); @@ -109,7 +104,7 @@ Combat::Combat(XeenEngine *vm): _vm(vm), _missVoc("miss.voc") { _itemFlag = false; _monstersAttacking = false; _combatMode = COMBATMODE_0; - _monsterIndex = 0; + _attackDurationCtr = 0; _partyRan = false; _monster2Attack = -1; _whosSpeed = 0; @@ -1181,13 +1176,13 @@ Common::String Combat::getMonsterDescriptions() { } } - if (_monsterIndex == 2 && _attackMonsters[2] != -1) { + if (_attackDurationCtr == 2 && _attackMonsters[2] != -1) { _monster2Attack = _attackMonsters[2]; - } if (_monsterIndex == 1 && _attackMonsters[1] != -1) { + } if (_attackDurationCtr == 1 && _attackMonsters[1] != -1) { _monster2Attack = _attackMonsters[1]; } else { _monster2Attack = _attackMonsters[0]; - _monsterIndex = 0; + _attackDurationCtr = 0; } return Common::String::format(Res.COMBAT_DETAILS, lines[0].c_str(), @@ -1278,7 +1273,7 @@ void Combat::attack(Character &c, RangeType rangeType) { } } } else { - Common::fill(&_elemPow[0], &_elemPow[PARTY_AND_MONSTERS], ELEM_FIRE); + _pow.resetElementals(); damage = 0; for (uint charIndex = 0; charIndex < party._activeParty.size(); ++charIndex) { @@ -1427,8 +1422,8 @@ void Combat::attack2(int damage, RangeType rangeType) { } if (damage) { - _charsArray1[_monsterIndex] = 3; - _monPow[_monsterIndex] = _damageType == DT_PHYSICAL && (rangeType == 3 || rangeType == 0); + _pow[_attackDurationCtr]._duration = 3; + _pow[_attackDurationCtr]._active = _damageType == DT_PHYSICAL && (rangeType == RT_HIT || rangeType == RT_SINGLE); monster._frame = 11; monster._postAttackDelay = 5; } @@ -1436,13 +1431,13 @@ void Combat::attack2(int damage, RangeType rangeType) { int monsterResist = getMonsterResistence(rangeType); damage += monsterResist; if (monsterResist > 0) { - _elemPow[_monsterIndex] = _attackWeapon->getElementalCategory(); - _elemScale[_monsterIndex] = getDamageScale(monsterResist); + _pow[_attackDurationCtr]._elemFrame = _attackWeapon->getElementalCategory(); + _pow[_attackDurationCtr]._elemScale = getDamageScale(monsterResist); } else if (rangeType != 3) { - _elemPow[_monsterIndex] = ELEM_FIRE; + _pow[_attackDurationCtr]._elemFrame = 0; } - if (rangeType != 0 && rangeType != 3) { + if (rangeType != RT_SINGLE && rangeType != RT_HIT) { monster._effect2 = DAMAGE_TYPE_EFFECTS[_damageType]; monster._effect1 = 0; } @@ -1473,7 +1468,7 @@ void Combat::attack2(int damage, RangeType rangeType) { sound.playSound(_missVoc, 1); sound.playFX(6); } else { - _monsterScale[_monsterIndex] = getDamageScale(damage); + _pow[_attackDurationCtr]._scale = getDamageScale(damage); intf.draw3d(true); sound.stopSound(); @@ -1572,13 +1567,13 @@ void Combat::attack2(int damage, RangeType rangeType) { } monster._position = Common::Point(0x80, 0x80); - _charsArray1[_monsterIndex] = 0; + _pow[_attackDurationCtr]._duration = 0; _monster2Attack = -1; intf.draw3d(true); if (_attackMonsters[0] != -1) { _monster2Attack = _attackMonsters[0]; - _monsterIndex = 0; + _attackDurationCtr = 0; } } } @@ -1861,7 +1856,7 @@ void Combat::rangedAttack(PowType powNum) { intf._charsShooting = true; _powSprites.load(Common::String::format("pow%d.icn", (int)powNum)); - int monsterIndex = _monsterIndex; + int monsterIndex = _attackDurationCtr; int monster2Attack = _monster2Attack; bool attackedFlag = false; @@ -1871,9 +1866,9 @@ void Combat::rangedAttack(PowType powNum) { attackMonsters.push_back(_attackMonsters[idx]); } - _monsterIndex = -1; + _attackDurationCtr = -1; if (_monster2Attack != -1) { - _monsterIndex--; + _attackDurationCtr--; if (attackMonsters.empty()) attackMonsters.resize(1); attackMonsters[0] = monster2Attack; @@ -1905,8 +1900,8 @@ void Combat::rangedAttack(PowType powNum) { intf.draw3d(true); - ++_monsterIndex; - for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_monsterIndex) { + ++_attackDurationCtr; + for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_attackDurationCtr) { Common::fill(&_missedShot[0], &_missedShot[MAX_PARTY_COUNT], false); _monster2Attack = attackMonsters[monIdx]; attack(*_oldCharacter, RT_GROUP); @@ -1955,8 +1950,8 @@ void Combat::rangedAttack(PowType powNum) { attackMonsters.push_back(_attackMonsters[idx]); } - ++_monsterIndex; - for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_monsterIndex) { + ++_attackDurationCtr; + for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_attackDurationCtr) { Common::fill(&_missedShot[0], &_missedShot[MAX_PARTY_COUNT], false); _monster2Attack = attackMonsters[monIdx]; attack(*_oldCharacter, RT_GROUP); @@ -2005,8 +2000,8 @@ void Combat::rangedAttack(PowType powNum) { attackMonsters.push_back(_attackMonsters[idx]); } - ++_monsterIndex; - for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_monsterIndex) { + ++_attackDurationCtr; + for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_attackDurationCtr) { Common::fill(&_missedShot[0], &_missedShot[MAX_PARTY_COUNT], false); _monster2Attack = attackMonsters[monIdx]; attack(*_oldCharacter, RT_GROUP); @@ -2055,8 +2050,8 @@ void Combat::rangedAttack(PowType powNum) { attackMonsters.push_back(_attackMonsters[idx]); } - ++_monsterIndex; - for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_monsterIndex) { + ++_attackDurationCtr; + for (uint monIdx = 0; monIdx < attackMonsters.size(); ++monIdx, ++_attackDurationCtr) { Common::fill(&_missedShot[0], &_missedShot[MAX_PARTY_COUNT], false); _monster2Attack = attackMonsters[monIdx]; attack(*_oldCharacter, RT_GROUP); @@ -2076,7 +2071,7 @@ finished: done: clearShooting(); _monster2Attack = monster2Attack; - _monsterIndex = monsterIndex; + _attackDurationCtr = monsterIndex; party.giveTreasure(); } diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h index 92efc058b4..efff2d521f 100644 --- a/engines/xeen/combat.h +++ b/engines/xeen/combat.h @@ -32,6 +32,7 @@ namespace Xeen { #define MAX_NUM_MONSTERS 107 #define PARTY_AND_MONSTERS 12 +#define POW_COUNT 12 #define ATTACK_MONSTERS_COUNT 26 enum DamageType { @@ -82,6 +83,38 @@ class XeenEngine; class Character; class XeenItem; +struct PowSlot { + bool _active; + int _duration; + int _scale; + int _elemFrame; + int _elemScale; + + PowSlot() : _active(false), _duration(0), _scale(0), + _elemFrame(0), _elemScale(0) {} +}; + +class PowSlots { +private: + PowSlot _data[POW_COUNT]; +public: + /** + * Gets a slot entry + */ + PowSlot &operator[](uint idx) { + assert(idx < POW_COUNT); + return _data[idx]; + } + + /** + * Resets the elemental frame used in all the slots + */ + void resetElementals() { + for (int idx = 0; idx < POW_COUNT; ++idx) + _data[idx]._elemFrame = 0; + } +}; + class Combat { private: XeenEngine *_vm; @@ -109,11 +142,7 @@ public: SpriteResource _powSprites; int _attackMonsters[ATTACK_MONSTERS_COUNT]; int _monster2Attack; - int _charsArray1[PARTY_AND_MONSTERS]; - bool _monPow[PARTY_AND_MONSTERS]; - int _monsterScale[PARTY_AND_MONSTERS]; - ElementalCategory _elemPow[PARTY_AND_MONSTERS]; - int _elemScale[PARTY_AND_MONSTERS]; + PowSlots _pow; int _missedShot[8]; Common::Array<int> _speedTable; int _shootingRow[8]; @@ -126,7 +155,7 @@ public: int _gmonHit[36]; bool _monstersAttacking; CombatMode _combatMode; - int _monsterIndex; + int _attackDurationCtr; bool _partyRan; int _whosSpeed; DamageType _damageType; diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp index 3e1dd67e78..dff6dc7372 100644 --- a/engines/xeen/interface.cpp +++ b/engines/xeen/interface.cpp @@ -1459,9 +1459,9 @@ void Interface::doCombat() { combat._combatParty.clear(); combat._charsGone.clear(); combat.clearBlocked(); - combat._charsArray1[0] = 0; - combat._charsArray1[1] = 0; - combat._charsArray1[2] = 0; + combat._pow[0]._duration = 0; + combat._pow[1]._duration = 0; + combat._pow[2]._duration = 0; combat._monstersAttacking = false; combat._partyRan = false; @@ -1498,7 +1498,7 @@ void Interface::doCombat() { // Write out the description of the monsters being battled w.writeString(combat.getMonsterDescriptions()); - _combatIcons.draw(0, 32, Common::Point(233, combat._monsterIndex * 10 + 27), + _combatIcons.draw(0, 32, Common::Point(233, combat._attackDurationCtr * 10 + 27), SPRFLAG_800, 1); w.update(); @@ -1539,7 +1539,7 @@ void Interface::doCombat() { _buttonValue -= Common::KEYCODE_1; if (combat._attackMonsters[_buttonValue] != -1) { combat._monster2Attack = combat._attackMonsters[_buttonValue]; - combat._monsterIndex = _buttonValue; + combat._attackDurationCtr = _buttonValue; } break; diff --git a/engines/xeen/interface_scene.cpp b/engines/xeen/interface_scene.cpp index d937dce846..4225d874fd 100644 --- a/engines/xeen/interface_scene.cpp +++ b/engines/xeen/interface_scene.cpp @@ -28,8 +28,8 @@ namespace Xeen { const int COMBAT_POS_X[3][2] = { { 102, 134 },{ 36, 67 },{ 161, 161 } }; -const int INDOOR_INDEXES[3] = { 157, 151, 154 }; -const int OUTDOOR_INDEXES[3] = { 119, 113, 116 }; +const int INDOOR_POW_INDEXES[3] = { 157, 151, 154 }; +const int OUTDOOR_POW_INDEXES[3] = { 119, 113, 116 }; const int COMBAT_OFFSET_X[4] = { 8, 6, 4, 2 }; OutdoorDrawList::OutdoorDrawList() : _sky1(_data[0]), _sky2(_data[1]), @@ -462,20 +462,21 @@ void InterfaceScene::drawOutdoorsScene() { _isAnimReset = false; int attackMon2 = combat._attackMonsters[2]; + // Only the front rank of pow points result in a Pow splatter effect for (int idx = 0; idx < 3; ++idx) { - DrawStruct &ds1 = _outdoorList[OUTDOOR_INDEXES[idx] + 1]; - DrawStruct &ds2 = _outdoorList[OUTDOOR_INDEXES[idx]]; + DrawStruct &ds1 = _outdoorList[OUTDOOR_POW_INDEXES[idx] + 1]; + DrawStruct &ds2 = _outdoorList[OUTDOOR_POW_INDEXES[idx]]; ds1._sprites = nullptr; ds2._sprites = nullptr; - if (combat._charsArray1[idx]) { + if (combat._pow[idx]._duration) { int vIndex = combat._attackMonsters[1] && !attackMon2 ? 1 : 0; - combat._charsArray1[idx]--; + combat._pow[idx]._duration--; - if (combat._monPow[idx]) { + if (combat._pow[idx]._active) { ds2._x = COMBAT_POS_X[idx][vIndex]; ds2._frame = 0; - ds2._scale = combat._monsterScale[idx]; + ds2._scale = combat._pow[idx]._scale; if (ds2._scale == SCALE_ENLARGE) { ds2._x /= 3; @@ -488,10 +489,10 @@ void InterfaceScene::drawOutdoorsScene() { ds2._sprites = &_charPowSprites; } - if (combat._elemPow[idx]) { + if (combat._pow[idx]._elemFrame) { ds1._x = COMBAT_POS_X[idx][vIndex] + COMBAT_OFFSET_X[idx]; - ds1._frame = combat._elemPow[idx]; - ds1._scale = combat._elemScale[idx]; + ds1._frame = combat._pow[idx]._elemFrame; + ds1._scale = combat._pow[idx]._elemScale; if (ds1._scale == SCALE_ENLARGE) ds1._x /= 3; @@ -600,20 +601,21 @@ void InterfaceScene::drawIndoorsScene() { // Code in the original that's not being used //MazeObject &objObject = map._mobData._objects[_objNumber - 1]; + // Only the front rank of pow points result in a Pow splatter effect for (int idx = 0; idx < 3; ++idx) { - DrawStruct &ds1 = _indoorList[INDOOR_INDEXES[idx]]; - DrawStruct &ds2 = _indoorList[INDOOR_INDEXES[idx] + 1]; + DrawStruct &ds1 = _indoorList[INDOOR_POW_INDEXES[idx]]; + DrawStruct &ds2 = _indoorList[INDOOR_POW_INDEXES[idx] + 1]; ds1._sprites = nullptr; ds2._sprites = nullptr; - if (combat._charsArray1[idx]) { + if (combat._pow[idx]._duration) { int posIndex = combat._attackMonsters[1] && !combat._attackMonsters[2] ? 1 : 0; - --combat._charsArray1[idx]; + --combat._pow[idx]._duration; - if (combat._monPow[idx]) { + if (combat._pow[idx]._active) { ds1._x = COMBAT_POS_X[idx][posIndex]; ds1._frame = 0; - ds1._scale = combat._monsterScale[idx]; + ds1._scale = combat._pow[idx]._scale; if (ds1._scale == SCALE_ENLARGE) { ds1._x /= 3; ds1._y = 60; @@ -625,10 +627,10 @@ void InterfaceScene::drawIndoorsScene() { ds1._sprites = &_charPowSprites; } - if (combat._elemPow[idx]) { + if (combat._pow[idx]._elemFrame) { ds2._x = COMBAT_POS_X[idx][posIndex] + COMBAT_OFFSET_X[idx]; - ds2._frame = combat._elemPow[idx]; - ds2._scale = combat._elemScale[idx]; + ds2._frame = combat._pow[idx]._elemFrame; + ds2._scale = combat._pow[idx]._elemScale; if (ds2._scale == SCALE_ENLARGE) ds2._x /= 3; ds2._flags = SPRFLAG_4000 | SPRFLAG_SCENE_CLIPPED; |