aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/xeen/combat.cpp57
-rw-r--r--engines/xeen/combat.h41
-rw-r--r--engines/xeen/interface.cpp10
-rw-r--r--engines/xeen/interface_scene.cpp42
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;