1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef XEEN_COMBAT_H 24 #define XEEN_COMBAT_H 25 26 #include "common/scummsys.h" 27 #include "common/rect.h" 28 #include "xeen/files.h" 29 #include "xeen/sprites.h" 30 31 namespace Xeen { 32 33 #define MAX_NUM_MONSTERS 107 34 #define PARTY_AND_MONSTERS 12 35 #define POW_COUNT 12 36 #define ATTACK_MONSTERS_COUNT 26 37 38 enum DamageType { 39 DT_PHYSICAL = 0, DT_MAGICAL = 1, DT_FIRE = 2, DT_ELECTRICAL = 3, 40 DT_COLD = 4, DT_POISON = 5, DT_ENERGY = 6, DT_SLEEP = 7, 41 DT_FINGEROFDEATH = 8, DT_HOLYWORD = 9, DT_MASS_DISTORTION = 10, 42 DT_UNDEAD = 11, DT_BEASTMASTER = 12, DT_DRAGONSLEEP = 13, 43 DT_GOLEMSTOPPER = 14, DT_HYPNOTIZE = 15, DT_INSECT_SPRAY = 16, 44 DT_POISON_VOLLEY = 17, DT_MAGIC_ARROW = 18 45 }; 46 47 enum SpecialAttack { 48 SA_NONE = 0, SA_MAGIC = 1, SA_FIRE = 2, SA_ELEC = 3, SA_COLD = 4, 49 SA_POISON = 5, SA_ENERGY = 6, SA_DISEASE = 7, SA_INSANE = 8, 50 SA_SLEEP = 9, SA_CURSEITEM = 10, SA_INLOVE = 11, SA_DRAINSP = 12, 51 SA_CURSE = 13, SA_PARALYZE = 14, SA_UNCONSCIOUS = 15, 52 SA_CONFUSE = 16, SA_BREAKWEAPON = 17, SA_WEAKEN = 18, 53 SA_ERADICATE = 19, SA_AGING = 20, SA_DEATH = 21, SA_STONE = 22 54 }; 55 56 enum ShootType { 57 ST_0 = 0, ST_1 = 1 58 }; 59 60 enum CombatMode { 61 COMBATMODE_STARTUP = 0, COMBATMODE_INTERACTIVE = 1, COMBATMODE_2 = 2 62 }; 63 64 enum PowType { 65 POW_INVALID = -1, POW_FIREBALL = 0, POW_INCINERATE = 1, 66 POW_FIERY_FLAIL = 2, POW_LIGHTNING = 3, POW_MEGAVOLTS = 4, 67 POW_SPARKS = 5, POW_STOPPER = 6, POW_MAGIC_ORB = 7, 68 POW_COLD_RAY = 8, POW_FROST_WAVE = 9, POW_SPRAY = 10, 69 POW_ARROW = 11, POW_MAGIC_ARROW = 12, POW_ENERGY_BLAST = 13, 70 POW_SPARKLES = 14, POW_DEADLY_SWARM = 15 71 }; 72 73 enum RangeType { 74 RT_SINGLE = 0, RT_GROUP = 1, RT_ALL = 2, RT_HIT = 3 75 }; 76 77 class XeenEngine; 78 class Character; 79 class XeenItem; 80 class MonsterStruct; 81 82 struct PowSlot { 83 bool _active; 84 int _duration; 85 int _scale; 86 int _elemFrame; 87 int _elemScale; 88 PowSlotPowSlot89 PowSlot() : _active(false), _duration(0), _scale(0), 90 _elemFrame(0), _elemScale(0) {} 91 }; 92 93 class PowSlots { 94 private: 95 PowSlot _data[POW_COUNT]; 96 public: 97 /** 98 * Gets a slot entry 99 */ 100 PowSlot &operator[](uint idx) { 101 assert(idx < POW_COUNT); 102 return _data[idx]; 103 } 104 105 /** 106 * Resets the elemental frame used in all the slots 107 */ resetElementals()108 void resetElementals() { 109 for (int idx = 0; idx < POW_COUNT; ++idx) 110 _data[idx]._elemFrame = 0; 111 } 112 }; 113 114 class Combat { 115 private: 116 XeenEngine *_vm; 117 118 /** 119 * Handles the logic for attacking with a given amount of damage 120 */ 121 void attack2(int damage, RangeType rangeType); 122 123 /** 124 * Returns true if the character successfully hits the monster 125 */ 126 bool hitMonster(Character &c, RangeType rangeType); 127 128 /** 129 * Gets the damage a given character's equipped weapon will do 130 */ 131 void getWeaponDamage(Character &c, RangeType rangeType); 132 133 /** 134 * Returns how much damage will be done to a monster 135 */ 136 int getMonsterDamage(Character &c); 137 138 /** 139 * Gets the scale of damage, used for sprite display in the scene 140 */ 141 int getDamageScale(int v); 142 143 /** 144 * Gets the current monster's damage resistance to the currently set damage type 145 */ 146 int getMonsterResistence(RangeType rangeType); 147 148 /** 149 * Distribute experience between active party members 150 */ 151 void giveExperience(int experience); 152 public: 153 Common::Array<Character *> _combatParty; 154 bool _charsBlocked[PARTY_AND_MONSTERS]; 155 int _charsGone[PARTY_AND_MONSTERS]; 156 SpriteResource _powSprites; 157 int _attackMonsters[ATTACK_MONSTERS_COUNT]; 158 int _monster2Attack; 159 PowSlots _pow; 160 int _missedShot[8]; 161 Common::Array<int> _speedTable; 162 int _shootingRow[8]; 163 int _globalCombat; 164 int _whosTurn; 165 bool _itemFlag; 166 int _monsterMap[32][32]; 167 bool _monsterMoved[MAX_NUM_MONSTERS]; 168 bool _rangeAttacking[MAX_NUM_MONSTERS]; 169 int _gmonHit[36]; 170 bool _monstersAttacking; 171 CombatMode _combatMode; 172 int _attackDurationCtr; 173 bool _partyRan; 174 int _whosSpeed; 175 DamageType _damageType; 176 Character *_oldCharacter; 177 int _monsterDamage; 178 int _weaponDamage; 179 int _weaponDie, _weaponDice; 180 int _weaponElemMaterial; 181 XeenItem *_attackWeapon; 182 int _attackWeaponId; 183 File _missVoc; 184 int _hitChanceBonus; 185 bool _dangerPresent; 186 bool _moveMonsters; 187 RangeType _rangeType; 188 ShootType _shootType; 189 int _combatTarget; 190 public: 191 Combat(XeenEngine *vm); 192 193 /** 194 * Clear the list of attacking monsters 195 */ 196 void clearAttackers(); 197 198 /** 199 * Clear the list of blocked characters 200 */ 201 void clearBlocked(); 202 203 /** 204 * Clear the list of ros projectiles are on headed for part members 205 */ 206 void clearShooting(); 207 208 /** 209 * Resets all combat related data 210 */ 211 void reset(); 212 213 /** 214 * Gives damage to character or characters in the party 215 */ 216 void giveCharDamage(int damage, DamageType attackType, int charIndex); 217 218 /** 219 * Do damage to a specific character 220 */ 221 void doCharDamage(Character &c, int charNum, int monsterDataIndex); 222 223 /** 224 * Handles moving monsters by a space between game turns 225 */ 226 void moveMonsters(); 227 228 /** 229 * Setup the combat party with a copy of the currently active party 230 */ 231 void setupCombatParty(); 232 233 /** 234 * Sets up a table of speeds to determine the order in which characters and monsters fight 235 */ 236 void setSpeedTable(); 237 238 /** 239 * Returns true if all participants in the combat are disabled 240 */ 241 bool allHaveGone() const; 242 243 /** 244 * Returns true if all the characters of the party are disabled 245 */ 246 bool charsCantAct() const; 247 248 /** 249 * Return a description of the monsters being faced 250 */ 251 Common::String getMonsterDescriptions(); 252 253 /** 254 * Main method for characters to attack 255 */ 256 void attack(Character &c, RangeType rangeType); 257 258 /** 259 * Flag the currently active character as blocking/defending 260 */ 261 void block(); 262 263 /** 264 * Perform whatever the current combat character's quick action is 265 */ 266 void quickFight(); 267 268 /** 269 * Current selected character is trying to run away 270 */ 271 void run(); 272 273 /** 274 * Called to handle monsters doing ranged attacks against the party 275 */ 276 void monstersAttack(); 277 278 void setupMonsterAttack(int monsterDataIndex, const Common::Point &pt); 279 280 /** 281 * Determines whether a given monster can move 282 * @param pt Monster position 283 * @param wallShift Shift mask for determining direction being moved 284 * @param xDiff X Delta for move 285 * @param yDiff Y Delta for move 286 * @param monsterId Monster number being tested 287 */ 288 bool canMonsterMove(const Common::Point &pt, int wallShift, int xDiff, int yDiff, int monsterId); 289 290 /** 291 * Moves a monster by a given delta amount if it's a valid move 292 */ 293 void moveMonster(int monsterId, const Common::Point &moveDelta); 294 295 /** 296 * Handle a monster's turn at attacking combat party members 297 */ 298 void doMonsterTurn(int monsterId); 299 300 /** 301 * Handles a monster's turn at attacking a specific member of the combat party 302 */ 303 void doMonsterTurn(int monsterId, int charNum); 304 305 /** 306 * Called when combat has ended 307 */ 308 void endAttack(); 309 310 void monsterOvercome(); 311 312 /** 313 * Checks whether a given position on the map will stop a ranged attack 314 */ 315 int stopAttack(const Common::Point &diffPt); 316 317 /** 318 * Called to do ranged attacks, both with bows or using a spell 319 */ 320 void rangedAttack(PowType powNum); 321 322 /** 323 * Fires off a ranged attack at all oncoming monsters 324 */ 325 void shootRangedWeapon(); 326 327 /** 328 * Returns true if there are any monsters in the vacinity 329 */ 330 bool areMonstersPresent() const; 331 }; 332 333 } // End of namespace Xeen 334 335 #endif /* XEEN_COMBAT_H */ 336