aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2015-02-28 18:43:04 -0500
committerPaul Gilbert2015-02-28 18:43:04 -0500
commit93cc299eafab9e385af9b812f45809cc4645a14e (patch)
tree60138bd303ce229db03effa64f49feb6ca334750 /engines
parent99aa64bda4695ca704a2902d3c6b6bd705204043 (diff)
downloadscummvm-rg350-93cc299eafab9e385af9b812f45809cc4645a14e.tar.gz
scummvm-rg350-93cc299eafab9e385af9b812f45809cc4645a14e.tar.bz2
scummvm-rg350-93cc299eafab9e385af9b812f45809cc4645a14e.zip
XEEN: Implement addHitPoints and spellFX methods
Diffstat (limited to 'engines')
-rw-r--r--engines/xeen/character.cpp35
-rw-r--r--engines/xeen/character.h4
-rw-r--r--engines/xeen/combat.cpp3
-rw-r--r--engines/xeen/combat.h6
-rw-r--r--engines/xeen/dialogs_spells.cpp67
-rw-r--r--engines/xeen/dialogs_spells.h11
-rw-r--r--engines/xeen/interface.cpp54
-rw-r--r--engines/xeen/interface.h3
-rw-r--r--engines/xeen/resources.cpp2
-rw-r--r--engines/xeen/resources.h2
-rw-r--r--engines/xeen/scripts.cpp5
-rw-r--r--engines/xeen/scripts.h1
-rw-r--r--engines/xeen/spells.cpp32
-rw-r--r--engines/xeen/spells.h2
14 files changed, 217 insertions, 10 deletions
diff --git a/engines/xeen/character.cpp b/engines/xeen/character.cpp
index d95e061515..ea0f9f532e 100644
--- a/engines/xeen/character.cpp
+++ b/engines/xeen/character.cpp
@@ -876,6 +876,15 @@ bool Character::isDisabledOrDead() const {
}
/**
+ * Returns whether the given character has a dead condition
+ */
+bool Character::isDead() const {
+ Condition condition = worstCondition();
+
+ return condition >= DEAD && condition <= ERADICATED;
+}
+
+/**
* Get the character's age
*/
int Character::getAge(bool ignoreTemp) const {
@@ -1810,6 +1819,32 @@ int Character::makeItem(int p1, int itemIndex, int p3) {
return category;
}
+/**
+ * Add hit points to a character
+ */
+void Character::addHitPoints(int amount) {
+ Interface &intf = *Party::_vm->_interface;
+ Common::fill(&intf._charFX[0], &intf._charFX[MAX_ACTIVE_PARTY], 0);
+
+ if (!isDead()) {
+ int maxHp = getMaxHP();
+ if (_currentHp <= maxHp) {
+ _currentHp = MIN(_currentHp + amount, maxHp);
+ intf.spellFX(this);
+ }
+
+ if (_currentHp > 0)
+ _conditions[UNCONSCIOUS] = 0;
+
+ intf.drawParty(true);
+ }
+
+ Common::fill(&intf._charFX[0], &intf._charFX[MAX_ACTIVE_PARTY], 0);
+}
+
+/**
+ * Remove hit points fromo the character
+ */
void Character::subtractHitPoints(int amount) {
SoundManager &sound = *Party::_vm->_sound;
_currentHp -= amount;
diff --git a/engines/xeen/character.h b/engines/xeen/character.h
index 77ab882305..f1243f1568 100644
--- a/engines/xeen/character.h
+++ b/engines/xeen/character.h
@@ -278,6 +278,8 @@ public:
bool isDisabledOrDead() const;
+ bool isDead() const;
+
int getAge(bool ignoreTemp = false) const;
int getMaxHP() const;
@@ -322,6 +324,8 @@ public:
int makeItem(int p1, int itemIndex, int p3);
+ void addHitPoints(int amount);
+
void subtractHitPoints(int amount);
bool hasSpecialItem() const;
diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp
index 74e098cdd4..7cc2ab6b22 100644
--- a/engines/xeen/combat.cpp
+++ b/engines/xeen/combat.cpp
@@ -109,7 +109,7 @@ Combat::Combat(XeenEngine *vm): _vm(vm), _missVoc("miss.voc"), _pow1Voc("pow1.vo
_whosTurn = -1;
_itemFlag = false;
_monstersAttacking = false;
- _combatMode = 0;
+ _combatMode = COMBATMODE_0;
_monsterIndex = 0;
_partyRan = false;
_monster2Attack = -1;
@@ -1883,7 +1883,6 @@ void Combat::multiAttack(int powNum) {
}
for (uint idx = 0; idx < party._activeParty.size(); ++idx) {
- Character &c = party._activeParty[idx];
if (_shooting[idx]) {
if (map._isOutdoors) {
intf._outdoorList._attackImgs1[idx]._scale = 0;
diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h
index cff9261b05..33309b243b 100644
--- a/engines/xeen/combat.h
+++ b/engines/xeen/combat.h
@@ -64,6 +64,10 @@ enum ShootType {
ST_0 = 0, ST_1 = 1
};
+enum CombatMode {
+ COMBATMODE_0 = 0, COMBATMODE_1 = 1, COMBATMODE_2 = 2
+};
+
class XeenEngine;
class Character;
class XeenItem;
@@ -108,7 +112,7 @@ public:
bool _rangeAttacking[MAX_NUM_MONSTERS];
int _gmonHit[36];
bool _monstersAttacking;
- int _combatMode;
+ CombatMode _combatMode;
int _monsterIndex;
bool _partyRan;
int _whosSpeed;
diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp
index 9a19ac2042..08828a0c8d 100644
--- a/engines/xeen/dialogs_spells.cpp
+++ b/engines/xeen/dialogs_spells.cpp
@@ -577,4 +577,71 @@ void CastSpell::loadButtons() {
addPartyButtons(_vm);
}
+/*------------------------------------------------------------------------*/
+
+int SpellOnWho::show(XeenEngine *vm, int spellId) {
+ SpellOnWho *dlg = new SpellOnWho(vm);
+ int result = dlg->execute(spellId);
+ delete dlg;
+
+ return result;
+}
+
+int SpellOnWho::execute(int spellId) {
+ Combat &combat = *_vm->_combat;
+ EventsManager &events = *_vm->_events;
+ Interface &intf = *_vm->_interface;
+ Party &party = *_vm->_party;
+ Screen &screen = *_vm->_screen;
+ Spells &spells = *_vm->_spells;
+ Window &w = screen._windows[16];
+ Mode oldMode = _vm->_mode;
+ _vm->_mode = MODE_3;
+ int result = 999;
+
+ w.open();
+ w.writeString(ON_WHO);
+ w.update();
+ addPartyButtons(_vm);
+
+ while (result == 999) {
+ do {
+ events.updateGameCounter();
+ intf.draw3d(true);
+
+ do {
+ events.pollEventsAndWait();
+ if (_vm->shouldQuit())
+ return -1;
+
+ checkEvents(_vm);
+ } while (!_buttonValue && events.timeElapsed() < 1);
+ } while (!_buttonValue);
+
+ switch (_buttonValue) {
+ case Common::KEYCODE_ESCAPE:
+ result = -1;
+ spells.addSpellCost(*combat._oldCharacter, spellId);
+ break;
+
+ case Common::KEYCODE_F1:
+ case Common::KEYCODE_F2:
+ case Common::KEYCODE_F3:
+ case Common::KEYCODE_F4:
+ case Common::KEYCODE_F5:
+ case Common::KEYCODE_F6:
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < (int)(combat._combatMode == 2 ? combat._combatParty.size() :
+ party._activeParty.size())) {
+ result = _buttonValue;
+ }
+ break;
+ }
+ }
+
+ w.close();
+ _vm->_mode = oldMode;
+ return result;
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/dialogs_spells.h b/engines/xeen/dialogs_spells.h
index 6a9e43f416..660f2ef1de 100644
--- a/engines/xeen/dialogs_spells.h
+++ b/engines/xeen/dialogs_spells.h
@@ -73,6 +73,17 @@ public:
static int show(XeenEngine *vm, Character *&c);
};
+class SpellOnWho : public ButtonContainer {
+private:
+ XeenEngine *_vm;
+
+ SpellOnWho(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
+
+ int execute(int spellId);
+public:
+ static int show(XeenEngine *vm, int spellId);
+};
+
} // End of namespace Xeen
#endif /* XEEN_DIALOGS_SPELLS_H */
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index cc027b8676..923eaeac0b 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -149,6 +149,7 @@ Interface::Interface(XeenEngine *vm) : ButtonContainer(), InterfaceMap(vm),
_face1State = _face2State = 0;
_upDoorText = false;
_tillMove = 0;
+ Common::fill(&_charFX[0], &_charFX[MAX_ACTIVE_PARTY], 0);
initDrawStructs();
}
@@ -1891,7 +1892,7 @@ void Interface::doCombat() {
bool reloadMap = false;
_upDoorText = false;
- combat._combatMode = 2;
+ combat._combatMode = COMBATMODE_2;
_vm->_mode = MODE_COMBAT;
_iconSprites.load("combat.icn");
@@ -2182,7 +2183,7 @@ void Interface::doCombat() {
DIR_EAST : DIR_SOUTH;
}
- combat._combatMode = 1;
+ combat._combatMode = COMBATMODE_1;
}
/**
@@ -2262,4 +2263,53 @@ void Interface::nextChar() {
}
}
+void Interface::spellFX(Character *c) {
+ Combat &combat = *_vm->_combat;
+ EventsManager &events = *_vm->_events;
+ Party &party = *_vm->_party;
+ Screen &screen = *_vm->_screen;
+ SoundManager &sound = *_vm->_sound;
+
+ // Ensure there's no alraedy running effect for the given character
+ uint charIndex;
+ for (charIndex = 0; charIndex < party._activeParty.size(); ++charIndex) {
+ if (&party._activeParty[charIndex] == c)
+ break;
+ }
+ if (charIndex == party._activeParty.size() || _charFX[charIndex])
+ return;
+
+ if (screen._windows[12]._enabled)
+ screen._windows[12].close();
+
+ if (combat._combatMode == COMBATMODE_2) {
+ for (uint idx = 0; idx < combat._combatParty.size(); ++idx) {
+ if (combat._combatParty[idx]->_rosterId == c->_rosterId) {
+ charIndex = idx;
+ break;
+ }
+ }
+ }
+
+ int tillMove = _tillMove;
+ _tillMove = 0;
+ sound.playFX(20);
+
+ for (int frameNum = 0; frameNum < 4; ++frameNum) {
+ events.updateGameCounter();
+ _spellFxSprites.draw(screen, frameNum, Common::Point(
+ CHAR_FACES_X[charIndex], 150));
+
+ if (!screen._windows[11]._enabled)
+ draw3d(false);
+
+ screen._windows[0].update();
+ events.wait(screen._windows[11]._enabled ? 2 : 1);
+ }
+
+ drawParty(true);
+ _tillMove = tillMove;
+}
+
+
} // End of namespace Xeen
diff --git a/engines/xeen/interface.h b/engines/xeen/interface.h
index f5e5cc34ee..24edf9d23d 100644
--- a/engines/xeen/interface.h
+++ b/engines/xeen/interface.h
@@ -119,6 +119,7 @@ public:
bool _upDoorText;
Common::String _screenText;
byte _tillMove;
+ int _charFX[6];
public:
Interface(XeenEngine *vm);
@@ -145,6 +146,8 @@ public:
void assembleBorder();
void doCombat();
+
+ void spellFX(Character *c);
};
} // End of namespace Xeen
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 5c76d29173..5893403ebd 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -1528,4 +1528,6 @@ const char *const GIVE_TREASURE_FORMATTING =
const char *const X_FOUND_Y = "\v060\t000\x03c%s found: %s";
+const char *const ON_WHO = "\x3""c\v009On Who?";
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index c98db7f0f9..b908d91cf9 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -539,6 +539,8 @@ extern const char *const GIVE_TREASURE_FORMATTING;
extern const char *const X_FOUND_Y;
+extern const char *const ON_WHO;
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 4af7af1d6a..ec00327205 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -88,7 +88,6 @@ bool MirrorEntry::synchronize(Common::SeekableReadStream &s) {
/*------------------------------------------------------------------------*/
Scripts::Scripts(XeenEngine *vm) : _vm(vm) {
- Common::fill(&_charFX[0], &_charFX[MAX_ACTIVE_PARTY], 0);
_whoWill = 0;
_itemType = 0;
_treasureItems = 0;
@@ -120,7 +119,7 @@ int Scripts::checkEvents() {
_var50 = false;
_whoWill = 0;
Mode oldMode = _vm->_mode;
- Common::fill(&_charFX[0], &_charFX[MAX_ACTIVE_PARTY], 0);
+ Common::fill(&intf._charFX[0], &intf._charFX[MAX_ACTIVE_PARTY], 0);
//int items = _treasureItems;
if (party._treasure._gold & party._treasure._gems) {
@@ -202,7 +201,7 @@ int Scripts::checkEvents() {
}
_v2 = 1;
- Common::fill(&_charFX[0], &_charFX[6], 0);
+ Common::fill(&intf._charFX[0], &intf._charFX[6], 0);
return _scriptResult;
}
diff --git a/engines/xeen/scripts.h b/engines/xeen/scripts.h
index 3a835d88b5..29de5b8b37 100644
--- a/engines/xeen/scripts.h
+++ b/engines/xeen/scripts.h
@@ -139,7 +139,6 @@ struct MirrorEntry {
class Scripts {
private:
XeenEngine *_vm;
- int _charFX[6];
int _treasureItems;
int _lineNum;
int _charIndex;
diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp
index 53c43b5233..d446b3ce6e 100644
--- a/engines/xeen/spells.cpp
+++ b/engines/xeen/spells.cpp
@@ -21,6 +21,7 @@
*/
#include "xeen/spells.h"
+#include "xeen/dialogs_spells.h"
#include "xeen/files.h"
#include "xeen/resources.h"
#include "xeen/xeen.h"
@@ -95,6 +96,16 @@ void Spells::executeSpell(int spellId) {
(this->*SPELL_LIST[spellId])();
}
+/**
+ * Spell being cast failed
+ */
+void Spells::spellFailed() {
+ ErrorScroll::show(_vm, SPELL_FAILED, WT_NONFREEZED_WAIT);
+}
+
+/**
+ * Cast a spell associated with an item
+ */
void Spells::castItemSpell(int spellId) {
if (_vm->_mode == MODE_COMBAT) {
if (spellId == 15 || spellId == 20 || spellId == 27 || spellId == 41
@@ -233,7 +244,26 @@ void Spells::magicArrow() {
combat.multiAttack(11);
}
-void Spells::firstAid() { error("TODO: spell"); }
+void Spells::firstAid() {
+ Combat &combat = *_vm->_combat;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+
+ int charIndex = SpellOnWho::show(_vm, MS_FirstAid);
+ if (charIndex == -1)
+ return;
+
+ Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
+ party._activeParty[charIndex];
+
+ if (c.isDead()) {
+ spellFailed();
+ } else {
+ sound.playFX(30);
+ c.addHitPoints(6);
+ }
+}
+
void Spells::flyingFist() { error("TODO: spell"); }
void Spells::energyBlast() { error("TODO: spell"); }
void Spells::sleep() { error("TODO: spell"); }
diff --git a/engines/xeen/spells.h b/engines/xeen/spells.h
index af52511efa..2f79670df0 100644
--- a/engines/xeen/spells.h
+++ b/engines/xeen/spells.h
@@ -69,6 +69,8 @@ private:
void executeSpell(int spellId);
+ void spellFailed();
+
// Spell list
void light();
void awaken();