Skip to content

Commit

Permalink
XEEN: Implement addHitPoints and spellFX methods
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Feb 28, 2015
1 parent 99aa64b commit 93cc299
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 10 deletions.
35 changes: 35 additions & 0 deletions engines/xeen/character.cpp
Expand Up @@ -875,6 +875,15 @@ bool Character::isDisabledOrDead() const {
return condition == ASLEEP || (condition >= PARALYZED && condition <= ERADICATED);
}

/**
* 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
*/
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions engines/xeen/character.h
Expand Up @@ -278,6 +278,8 @@ class Character {

bool isDisabledOrDead() const;

bool isDead() const;

int getAge(bool ignoreTemp = false) const;

int getMaxHP() const;
Expand Down Expand Up @@ -322,6 +324,8 @@ class Character {

int makeItem(int p1, int itemIndex, int p3);

void addHitPoints(int amount);

void subtractHitPoints(int amount);

bool hasSpecialItem() const;
Expand Down
3 changes: 1 addition & 2 deletions engines/xeen/combat.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion engines/xeen/combat.h
Expand Up @@ -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;
Expand Down Expand Up @@ -108,7 +112,7 @@ class Combat {
bool _rangeAttacking[MAX_NUM_MONSTERS];
int _gmonHit[36];
bool _monstersAttacking;
int _combatMode;
CombatMode _combatMode;
int _monsterIndex;
bool _partyRan;
int _whosSpeed;
Expand Down
67 changes: 67 additions & 0 deletions engines/xeen/dialogs_spells.cpp
Expand Up @@ -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
11 changes: 11 additions & 0 deletions engines/xeen/dialogs_spells.h
Expand Up @@ -73,6 +73,17 @@ class CastSpell : public ButtonContainer {
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 */
54 changes: 52 additions & 2 deletions engines/xeen/interface.cpp
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -2182,7 +2183,7 @@ void Interface::doCombat() {
DIR_EAST : DIR_SOUTH;
}

combat._combatMode = 1;
combat._combatMode = COMBATMODE_1;
}

/**
Expand Down Expand Up @@ -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
3 changes: 3 additions & 0 deletions engines/xeen/interface.h
Expand Up @@ -119,6 +119,7 @@ class Interface: public ButtonContainer, public InterfaceMap, public PartyDrawer
bool _upDoorText;
Common::String _screenText;
byte _tillMove;
int _charFX[6];
public:
Interface(XeenEngine *vm);

Expand All @@ -145,6 +146,8 @@ class Interface: public ButtonContainer, public InterfaceMap, public PartyDrawer
void assembleBorder();

void doCombat();

void spellFX(Character *c);
};

} // End of namespace Xeen
Expand Down
2 changes: 2 additions & 0 deletions engines/xeen/resources.cpp
Expand Up @@ -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
2 changes: 2 additions & 0 deletions engines/xeen/resources.h
Expand Up @@ -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 */
5 changes: 2 additions & 3 deletions engines/xeen/scripts.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 0 additions & 1 deletion engines/xeen/scripts.h
Expand Up @@ -139,7 +139,6 @@ struct MirrorEntry {
class Scripts {
private:
XeenEngine *_vm;
int _charFX[6];
int _treasureItems;
int _lineNum;
int _charIndex;
Expand Down
32 changes: 31 additions & 1 deletion engines/xeen/spells.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"); }
Expand Down

0 comments on commit 93cc299

Please sign in to comment.