diff options
author | Paul Gilbert | 2015-02-20 23:57:45 -0500 |
---|---|---|
committer | Paul Gilbert | 2015-02-20 23:57:45 -0500 |
commit | b790e9bac1ee20482cbea6056dcf084bd85c0da5 (patch) | |
tree | b6de327fe088930d969e4f249297857808e805bc | |
parent | 917b143ec9e7fd9f5c9b28088c2b7f6310c16cee (diff) | |
download | scummvm-rg350-b790e9bac1ee20482cbea6056dcf084bd85c0da5.tar.gz scummvm-rg350-b790e9bac1ee20482cbea6056dcf084bd85c0da5.tar.bz2 scummvm-rg350-b790e9bac1ee20482cbea6056dcf084bd85c0da5.zip |
XEEN: Implemented attack2
-rw-r--r-- | engines/xeen/character.h | 5 | ||||
-rw-r--r-- | engines/xeen/combat.cpp | 225 | ||||
-rw-r--r-- | engines/xeen/combat.h | 17 | ||||
-rw-r--r-- | engines/xeen/items.cpp | 3 | ||||
-rw-r--r-- | engines/xeen/items.h | 11 | ||||
-rw-r--r-- | engines/xeen/module.mk | 1 | ||||
-rw-r--r-- | engines/xeen/party.cpp | 7 | ||||
-rw-r--r-- | engines/xeen/party.h | 14 | ||||
-rw-r--r-- | engines/xeen/scripts.cpp | 11 | ||||
-rw-r--r-- | engines/xeen/scripts.h | 2 | ||||
-rw-r--r-- | engines/xeen/xeen.h | 1 |
11 files changed, 262 insertions, 35 deletions
diff --git a/engines/xeen/character.h b/engines/xeen/character.h index 6acd433adc..372014f7fc 100644 --- a/engines/xeen/character.h +++ b/engines/xeen/character.h @@ -74,11 +74,6 @@ enum Condition { NO_CONDITION = 16 }; -enum ElementalCategory { - ELEM_FIRE = 0, ELEM_ELECTRICITY = 1, ELEM_COLD = 2, - ELEM_ACID_POISON = 3, ELEM_ENERGY = 4, ELEM_MAGIC = 5 -}; - enum AttributeCategory { ATTR_MIGHT = 0, ATTR_INTELLECT = 1, ATTR_PERSONALITY = 2, ATTR_SPEED = 3, ATTR_ACCURACY = 4, ATTR_LUCK = 5, ATTR_HIT_POINTS = 6, ATTR_SPELL_POINTS = 7, diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp index 776821a5f4..a8b5a50a4e 100644 --- a/engines/xeen/combat.cpp +++ b/engines/xeen/combat.cpp @@ -77,16 +77,27 @@ static const int MONSTER_SHOOT_POW[7] = { 12, 14, 0, 4, 8, 10, 13 }; static const int COMBAT_SHOOTING[4] = { 1, 1, 2, 3 }; -#define monsterSavingThrow(MONINDEX) (_vm->getRandomNumber(1, 50 + MONINDEX) <= MONINDEX) +static const int DAMAGE_TYPE_EFFECTS[19] = { + 3, 10, 4, 11, 1, 2, 5, 9, 5, 14, 5, 14, 10, 8, 3, 9, 2, 2, 3 +}; + +static const int POW_WEAPON_VOCS[35] = { + 0, 5, 4, 5, 5, 5, 5, 2, 4, 5, 3, 5, 4, 2, 3, 2, 2, 4, 5, 5, + 5, 5, 5, 1, 3, 2, 5, 1, 1, 1, 0, 0, 0, 2, 2 +}; + +static const int MONSTER_ITEM_RANGES[6] = { 10, 20, 50, 100, 100, 100 }; + +#define monsterSavingThrow(MONINDEX) (_vm->getRandomNumber(1, 50 + (MONINDEX)) <= (MONINDEX)) /*------------------------------------------------------------------------*/ -Combat::Combat(XeenEngine *vm): _vm(vm) { +Combat::Combat(XeenEngine *vm): _vm(vm), _missVoc("miss.voc"), _pow1Voc("pow1.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], 0); + Common::fill(&_elemPow[0], &_elemPow[12], ELEM_FIRE); Common::fill(&_elemScale[0], &_elemScale[12], 0); Common::fill(&_shooting[0], &_shooting[8], 0); Common::fill(&_monsterMap[0][0], &_monsterMap[32][32], 0); @@ -108,6 +119,7 @@ Combat::Combat(XeenEngine *vm): _vm(vm) { _shootType = 0; _monsterDamage = 0; _weaponDamage = 0; + _attackWeapon = nullptr; } void Combat::clear() { @@ -1251,7 +1263,7 @@ void Combat::attack(Character &c, int ranged) { } } } else { - Common::fill(&_elemPow[0], &_elemPow[PARTY_AND_MONSTERS], 0); + Common::fill(&_elemPow[0], &_elemPow[PARTY_AND_MONSTERS], ELEM_FIRE); damage = 0; for (uint charIndex = 0; charIndex < party._activeParty.size(); ++charIndex) { @@ -1363,7 +1375,193 @@ void Combat::attack(Character &c, int ranged) { } void Combat::attack2(int damage, int ranged) { - error("TODO"); + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + SoundManager &sound = *_vm->_sound; + bool isDarkCc = _vm->_files->_isDarkCc; + MazeMonster &monster = map._mobData._monsters[_monster2Attack]; + MonsterStruct &monsterData = map._monsterData[monster._spriteId]; + bool monsterDied = false; + + if (!isDarkCc && damage && ranged && monster._spriteId == 89) + damage = 0; + + if (!damage) { + sound.playSample(&_missVoc, 1); + sound.playFX(6); + } else { + if (!isDarkCc && monster._spriteId == 89) + damage += 100; + if (monster._damageType == DT_SLEEP || monster._damageType == DT_DRAGONSLEEP) + monster._damageType = DT_PHYSICAL; + + if ((!ranged || !_damageType) && _attackWeapon->_id != 34) { + if (monsterData._phsyicalResistence != 0) { + if (monsterData._phsyicalResistence == 100) { + damage = 0; + } else { + // This doesn't seem to have any effect? + damage = (damage * 100) / 100; + } + } + } + + if (damage) { + _charsArray1[_monsterIndex] = 3; + _monPow[_monsterIndex] = _damageType == DT_PHYSICAL && (ranged == 3 || ranged == 0); + monster._frame = 11; + monster._fieldA = 5; + } + + int monsterResist = getMonsterResistence(ranged); + damage += monsterResist; + if (monsterResist > 0) { + _elemPow[_monsterIndex] = _attackWeapon->getElementalCategory(); + _elemScale[_monsterIndex] = getDamageScale(monsterResist); + } else if (ranged != 3) { + _elemPow[_monsterIndex] = ELEM_FIRE; + } + + if (ranged != 0 && ranged != 3) { + monster._effect2 = DAMAGE_TYPE_EFFECTS[_damageType]; + monster._effect1 = 0; + } + + if (ranged && monsterSavingThrow(monster._spriteId)) { + switch (_damageType) { + case DT_FINGEROFDEATH: + case DT_MASS_DISTORTION: + damage = 5; + break; + case DT_SLEEP: + case DT_HOLYWORD: + case DT_UNDEAD: + case DT_BEASTMASTER: + case DT_DRAGONSLEEP: + case DT_GOLEMSTOPPER: + case DT_HYPNOTIZE: + case DT_INSECT_SPRAY: + case DT_MAGIC_ARROW: + break; + default: + damage /= 2; + break; + } + } + + if (damage < 1) { + sound.playSample(&_missVoc, 1); + sound.playFX(6); + } else { + _monsterScale[_monsterIndex] = getDamageScale(damage); + intf.draw3d(true); + + sound.playSample(nullptr, 0); + File powVoc(Common::String::format("pow%d.voc", + POW_WEAPON_VOCS[_attackWeapon->_id])); + sound.playFX(60 + POW_WEAPON_VOCS[_attackWeapon->_id]); + sound.playSample(&powVoc, 1); + + if (monster._hp > damage) { + monster._hp -= damage; + } else { + monster._hp = 0; + monsterDied = true; + } + } + } + + intf.draw3d(true); + + if (monsterDied) { + if (!isDarkCc) { + if (_monster2Attack == 20 && party._mazeId == 41) + party._gameFlags[11] = true; + if (_monster2Attack == 8 && party._mazeId == 78) { + party._gameFlags[60] = true; + party._quests[23] = false; + + for (uint idx = 0; idx < party._activeParty.size(); ++idx) + party._activeParty[idx].setAward(42, true); + + if (_monster2Attack == 27 && party._mazeId == 29) + party._gameFlags[104] = true; + } + } + + giveExperience(monsterData._experience); + + if (party._mazeId != 85) { + party._treasure._gold = monsterData._gold; + party._treasure._gems = monsterData._gems; + + if (!isDarkCc && monster._spriteId == 89) { + party._treasure._weapons[0]._id = 90; + party._treasure._weapons[0]._bonusFlags = 0; + party._treasure._weapons[0]._material = 0; + party._treasure._hasItems = true; + party._questItems[8]++; + } + + int itemDrop = monsterData._itemDrop; + if (itemDrop) { + if (MONSTER_ITEM_RANGES[itemDrop] >= _vm->getRandomNumber(1, 100)) { + Character tempChar; + int category = tempChar.makeItem(itemDrop, 0, 0); + + switch (category) { + case CATEGORY_WEAPON: + for (int idx = 0; idx < MAX_TREASURE_ITEMS; ++idx) { + if (party._treasure._weapons[idx]._id == 0) { + party._treasure._weapons[idx] = tempChar._weapons[0]; + party._treasure._hasItems = 1; + break; + } + } + break; + case CATEGORY_ARMOR: + for (int idx = 0; idx < MAX_TREASURE_ITEMS; ++idx) { + if (party._treasure._armor[idx]._id == 0) { + party._treasure._armor[idx] = tempChar._armor[0]; + party._treasure._hasItems = 1; + break; + } + } + break; + case CATEGORY_ACCESSORY: + for (int idx = 0; idx < MAX_TREASURE_ITEMS; ++idx) { + if (party._treasure._accessories[idx]._id == 0) { + party._treasure._accessories[idx] = tempChar._accessories[0]; + party._treasure._hasItems = 1; + break; + } + } + break; + case CATEGORY_MISC: + for (int idx = 0; idx < MAX_TREASURE_ITEMS; ++idx) { + if (party._treasure._accessories[idx]._id == 0) { + party._treasure._accessories[idx] = tempChar._accessories[0]; + party._treasure._hasItems = 1; + break; + } + } + break; + } + } + } + } + + monster._position = Common::Point(0x80, 0x80); + _charsArray1[_monsterIndex] = 0; + _monster2Attack = -1; + intf.draw3d(true); + + if (_attackMonsters[0] != -1) { + _monster2Attack = _attackMonsters[0]; + _monsterIndex = 0; + } + } } /** @@ -1434,5 +1632,22 @@ int Combat::getMonsterDamage(Character &c) { error("TODO"); } +int Combat::getDamageScale(int v) { + if (v < 10) + return 5; + else if (v < 100) + return 0; + else + return 0x8000; +} + +int Combat::getMonsterResistence(int ranged) { + error("TODO"); +} + +void Combat::giveExperience(int experience) { + error("TODO"); +} + } // End of namespace Xeen diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h index 1e1ca82808..75614ccdf7 100644 --- a/engines/xeen/combat.h +++ b/engines/xeen/combat.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/rect.h" +#include "xeen/files.h" #include "xeen/sprites.h" namespace Xeen { @@ -50,8 +51,14 @@ enum SpecialAttack { SA_ERADICATE = 19, SA_AGING = 20, SA_DEATH = 21, SA_STONE = 22 }; +enum ElementalCategory { + ELEM_FIRE = 0, ELEM_ELECTRICITY = 1, ELEM_COLD = 2, + ELEM_ACID_POISON = 3, ELEM_ENERGY = 4, ELEM_MAGIC = 5 +}; + class XeenEngine; class Character; +class XeenItem; class Combat { private: @@ -64,6 +71,12 @@ private: bool getWeaponDamage(Character &c, int ranged); int getMonsterDamage(Character &c); + + int getDamageScale(int v); + + int getMonsterResistence(int ranged); + + void giveExperience(int experience); public: Common::Array<Character *> _combatParty; Common::Array<bool> _charsBlocked; @@ -74,7 +87,7 @@ public: int _charsArray1[PARTY_AND_MONSTERS]; bool _monPow[PARTY_AND_MONSTERS]; int _monsterScale[PARTY_AND_MONSTERS]; - int _elemPow[PARTY_AND_MONSTERS]; + ElementalCategory _elemPow[PARTY_AND_MONSTERS]; int _elemScale[PARTY_AND_MONSTERS]; int _missedShot[8]; Common::Array<int> _speedTable; @@ -96,6 +109,8 @@ public: int _shootType; int _monsterDamage; int _weaponDamage; + XeenItem *_attackWeapon; + File _missVoc, _pow1Voc; public: Combat(XeenEngine *vm); diff --git a/engines/xeen/items.cpp b/engines/xeen/items.cpp index b9b531db7b..e8c0249803 100644 --- a/engines/xeen/items.cpp +++ b/engines/xeen/items.cpp @@ -25,8 +25,5 @@ namespace Xeen { -Treasure::Treasure() { - _hasItems = false; -} } // End of namespace Xeen diff --git a/engines/xeen/items.h b/engines/xeen/items.h index 1e208615f8..bfbd9e4481 100644 --- a/engines/xeen/items.h +++ b/engines/xeen/items.h @@ -27,18 +27,7 @@ namespace Xeen { -#define TOTAL_ITEMS 10 -class Treasure { -public: - XeenItem _misc[TOTAL_ITEMS]; - XeenItem _accessories[TOTAL_ITEMS]; - XeenItem _armor[TOTAL_ITEMS]; - XeenItem _weapons[TOTAL_ITEMS]; - bool _hasItems; -public: - Treasure(); -}; } // End of namespace Xeen diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk index a17311c6af..1fe29c6a8e 100644 --- a/engines/xeen/module.mk +++ b/engines/xeen/module.mk @@ -32,7 +32,6 @@ MODULE_OBJS := \ font.o \ interface.o \ interface_map.o \ - items.o \ map.o \ party.o \ resources.o \ diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp index 993f156204..ab8abd7f92 100644 --- a/engines/xeen/party.cpp +++ b/engines/xeen/party.cpp @@ -57,6 +57,13 @@ void Roster::synchronize(Common::Serializer &s) { /*------------------------------------------------------------------------*/ +Treasure::Treasure() { + _hasItems = false; + _gold = _gems = 0; +} + +/*------------------------------------------------------------------------*/ + XeenEngine *Party::_vm; Party::Party(XeenEngine *vm) { diff --git a/engines/xeen/party.h b/engines/xeen/party.h index 5d98c55b82..841fcd393a 100644 --- a/engines/xeen/party.h +++ b/engines/xeen/party.h @@ -48,6 +48,7 @@ enum Difficulty { ADVENTURER = 0, WARRIOR = 1 }; #define TOTAL_STATS 7 #define TOTAL_QUEST_ITEMS 85 #define TOTAL_QUEST_FLAGS 56 +#define MAX_TREASURE_ITEMS 10 class Roster: public Common::Array<Character> { public: @@ -58,6 +59,18 @@ public: void synchronize(Common::Serializer &s); }; +class Treasure { +public: + XeenItem _misc[MAX_TREASURE_ITEMS]; + XeenItem _accessories[MAX_TREASURE_ITEMS]; + XeenItem _armor[MAX_TREASURE_ITEMS]; + XeenItem _weapons[MAX_TREASURE_ITEMS]; + bool _hasItems; + int _gems, _gold; +public: + Treasure(); +}; + class Party { friend class Character; friend class InventoryItems; @@ -124,6 +137,7 @@ public: int _fallDamage; DamageType _damageType; bool _dead; + Treasure _treasure; public: Party(XeenEngine *vm); diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index 8b3888934b..7aab04c4c4 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -92,8 +92,6 @@ Scripts::Scripts(XeenEngine *vm) : _vm(vm) { _whoWill = 0; _itemType = 0; _treasureItems = 0; - _treasureGold = 0; - _treasureGems = 0; _lineNum = 0; _charIndex = 0; _v2 = 0; @@ -125,7 +123,7 @@ int Scripts::checkEvents() { Common::fill(&_charFX[0], &_charFX[MAX_ACTIVE_PARTY], 0); //int items = _treasureItems; - if (_treasureGold & _treasureItems) { + if (party._treasure._gold & party._treasure._gems) { // TODO } else { // TODO @@ -591,6 +589,7 @@ void Scripts::cmdGiveExtended(Common::Array<byte> ¶ms) { void Scripts::cmdConfirmWord(Common::Array<byte> ¶ms) { Map &map = *_vm->_map; + Party &party = *_vm->_party; Common::String msg1 = params[2] ? map._events._text[params[2]] : _vm->_interface->_interfaceText; Common::String msg2; @@ -621,13 +620,13 @@ void Scripts::cmdConfirmWord(Common::Array<byte> ¶ms) { doWorldEnd(); } else { if (result == 59 && !_vm->_files->_isDarkCc) { - for (int idx = 0; idx < TOTAL_ITEMS; ++idx) { - XeenItem &item = _vm->_treasure._weapons[idx]; + for (int idx = 0; idx < MAX_TREASURE_ITEMS; ++idx) { + XeenItem &item = party._treasure._weapons[idx]; if (!item._id) { item._id = 34; item._material = 0; item._bonusFlags = 0; - _vm->_treasure._hasItems = true; + party._treasure._hasItems = true; cmdExit(params); return; diff --git a/engines/xeen/scripts.h b/engines/xeen/scripts.h index cc32a9667f..1db672bd18 100644 --- a/engines/xeen/scripts.h +++ b/engines/xeen/scripts.h @@ -141,8 +141,6 @@ private: XeenEngine *_vm; int _charFX[6]; int _treasureItems; - int _treasureGold; - int _treasureGems; int _lineNum; int _charIndex; int _mirrorId; diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h index d0a72f5868..76cb1c1159 100644 --- a/engines/xeen/xeen.h +++ b/engines/xeen/xeen.h @@ -149,7 +149,6 @@ public: SoundManager *_sound; Spells *_spells; Town *_town; - Treasure _treasure; Mode _mode; GameEvent _gameEvent; Common::SeekableReadStream *_eventData; |