X-Git-Url: http://git.maemo.org/git/?p=lordsawar;a=blobdiff_plain;f=src%2Ffight.h;fp=src%2Ffight.h;h=5cd9798785ddf004cfa23bfbe515f73ac5bb99b4;hp=0000000000000000000000000000000000000000;hb=9eda00ff73353c55ecef6f82131166d5d4a85e29;hpb=3d34d4aa85a929f912464f71158396a388274f27;ds=sidebyside diff --git a/src/fight.h b/src/fight.h new file mode 100644 index 0000000..5cd9798 --- /dev/null +++ b/src/fight.h @@ -0,0 +1,233 @@ +// Copyright (C) 2001, 2002, 2003 Michael Bartl +// Copyright (C) 2001, 2002, 2004, 2005, 2006 Ulf Lorenz +// Copyright (C) 2004 Bryan Duff +// Copyright (C) 2006 Andrea Paternesi +// Copyright (C) 2007, 2008 Ben Asselstine +// Copyright (C) 2008 Ole Laursen +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301, USA. + +#ifndef FIGHT_H +#define FIGHT_H + +#include +#include +#include +#include + +class Stack; +class Fighter; +class Hero; +class Army; +class LocationBox; + +//! A description of a round of casualties during a Fight. +/** + * This is the structure that describes the events of the fight. It is + * played back by a fight dialog to reconstruct and show what transpired. + */ +struct FightItem +{ + //! The round number of the battle. + int turn; + //! The id of the army who was attacked in this event. + guint32 id; + //! The amount of damage that the army sustained. + int damage; +}; + + +//! Calculate the outcome of a battle. +/** + * This class is solely responsible for the _calculation_ of the fight. + * It gets the participating stacks and damages the units within according + * to the calculation. Furthermore, it creates a history of the fight, which + * can later be used by the fight dialog to reconstruct the fight or be sent + * over the network. For the graphical display, see the FightDialog class. + * + * Two things should be noted. First, the fight can include more than the + * initial two stacks, since all stacks around the defender are considered + * as potential "contributors". Second, irrespective of that, a fight is + * always considered as "won", if the defending stack was destroyed and + * "lost" if the attacking stack was crushed. + */ +class Fight +{ + public: + //! The three possibilities how a fight can end + enum Result { + //! There was no winner. + /** + * Although it is in the enumeration, every fight should always + * have a winner. No draws allowed because MAX_ROUNDS is 0. + */ + DRAW = 0, + + //! The attacking list of stacks won the battle. + ATTACKER_WON = 1, + + //! The defending list of stacks won the battle. + DEFENDER_WON = 2 + }; + + //! The kind of fight. Whether the outcome is realized or not. + enum FightType { + //! The fight doesn't mean anything, it's just to see who would win. + /** + * @note This value is used to assist in the implementation of the + * `Miltary Advisor' feature. + */ + FOR_KICKS = 0, + + //! The fight is real. If an army dies, it stays dead. + FOR_KEEPS = 1 + }; + + //! Make a new fight between two lists of stacks. + /** + * @param attacker The list of attacking stacks. + * @param defender The list of defending stacks + * @param type Optionally heal all stacks afterwards. + */ + Fight(Stack* attacker, Stack* defender, FightType type = FOR_KEEPS); + + // construct from serialized action + Fight(std::list attackers, std::list defenders, + std::list history); + + //! Destructor. + ~Fight(); + + //! Determine the outcome of the fight. + /** + * This method fills out a set of FightItem events in d_actions. + * + * @param intense Whether or not to Use 24 sided dice instead of + * 20 sided dice. Makes battles harder to win when + * set to True. + */ + void battle(bool intense); + + Result battleFromHistory(); + + //! Returns the result of the fight. + Result getResult() const {return d_result;} + + //! Returns the list of things that happened in chronological order. + std::list getCourseOfEvents() const {return d_actions;}; + + //! Returns the participating attacker stacks. + std::list getAttackers() const {return d_attackers;} + + //! Returns the participating defender stacks. + std::list getDefenders() const {return d_defenders;} + + //! Get the modified strength bonus of the given Army unit. + guint32 getModifiedStrengthBonus(Army *a); + + // CONSTANTS + //! The number of rounds the fight lasts. + /** + * @note If this is 0, then there is no maximum. + */ + static const int MAX_ROUNDS = 0; + + //! Turn a list of stacks into an ordered list of armies. + /** + * @note This is used for calculation and display purposes. + */ + static void orderArmies(std::list stacks, + std::vector &armies); + + std::map getInitialHPs() { return initial_hps; } + + static LocationBox calculateFightBox(Fight &fight); + private: + //! Calculates one round of the fight. + /** + * @return false if the maximum number of fight rounds has been + * exceeded or one side has lost. + */ + bool doRound(); + + //! Calculates the attack/defense bonus of the armies. + void calculateBonus(); + + //! Calculates the base strength of the armies fighting in the battle. + void calculateBaseStrength(std::list fighters); + + //! Add the bonuses provided by terrain. + void calculateTerrainModifiers(std::list fighters); + + //! Add the bonuses by opponents. + void calculateModifiedStrengths (std::listfriendly, + std::listenemy, + bool friendlyIsDefending, + Hero *strongestHero); + + //! Subtract stack bonuses of the opponent. + void calculateFinalStrengths (std::list friendly, + std::list enemy); + + /** + * This function just has two armies fight against each other. It + * applies the bonuses and several special bonuses to attacker and + * defender and calculates the result. + * + * @param attacker The attacking army. + * @param defender The defending army. + */ + void fightArmies(Fighter* attacker, Fighter* defender); + + //! Removes an army from the fight. + void remove(Fighter* f); + + void fillInInitialHPs(); + + // DATA + + //! The attackers. + std::list d_attackers; + + //! The defenders. + std::list d_defenders; + + //!The attackers in the fight. + std::list d_att_close; + + //! The defenders in the fight. + std::list d_def_close; + + std::map initial_hps; + + //! The list of fight events that gets calculated. + std::list d_actions; + + //! The round of the fight. + int d_turn; + + //! The result of the fight. + Result d_result; + + //! The kind of fight. + FightType d_type; + + //! Whether or not we're rolling 24-sided dice or 20 sided dice. + bool d_intense_combat; +}; + +#endif // FIGHT_H +