1 // Copyright (C) 2001, 2002, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2004 Bryan Duff
4 // Copyright (C) 2006 Andrea Paternesi
5 // Copyright (C) 2007, 2008 Ben Asselstine
6 // Copyright (C) 2008 Ole Laursen
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Library General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 //! A description of a round of casualties during a Fight.
39 * This is the structure that describes the events of the fight. It is
40 * played back by a fight dialog to reconstruct and show what transpired.
44 //! The round number of the battle.
46 //! The id of the army who was attacked in this event.
48 //! The amount of damage that the army sustained.
53 //! Calculate the outcome of a battle.
55 * This class is solely responsible for the _calculation_ of the fight.
56 * It gets the participating stacks and damages the units within according
57 * to the calculation. Furthermore, it creates a history of the fight, which
58 * can later be used by the fight dialog to reconstruct the fight or be sent
59 * over the network. For the graphical display, see the FightDialog class.
61 * Two things should be noted. First, the fight can include more than the
62 * initial two stacks, since all stacks around the defender are considered
63 * as potential "contributors". Second, irrespective of that, a fight is
64 * always considered as "won", if the defending stack was destroyed and
65 * "lost" if the attacking stack was crushed.
70 //! The three possibilities how a fight can end
72 //! There was no winner.
74 * Although it is in the enumeration, every fight should always
75 * have a winner. No draws allowed because MAX_ROUNDS is 0.
79 //! The attacking list of stacks won the battle.
82 //! The defending list of stacks won the battle.
86 //! The kind of fight. Whether the outcome is realized or not.
88 //! The fight doesn't mean anything, it's just to see who would win.
90 * @note This value is used to assist in the implementation of the
91 * `Miltary Advisor' feature.
95 //! The fight is real. If an army dies, it stays dead.
99 //! Make a new fight between two lists of stacks.
101 * @param attacker The list of attacking stacks.
102 * @param defender The list of defending stacks
103 * @param type Optionally heal all stacks afterwards.
105 Fight(Stack* attacker, Stack* defender, FightType type = FOR_KEEPS);
107 // construct from serialized action
108 Fight(std::list<Stack*> attackers, std::list<Stack*> defenders,
109 std::list<FightItem> history);
114 //! Determine the outcome of the fight.
116 * This method fills out a set of FightItem events in d_actions.
118 * @param intense Whether or not to Use 24 sided dice instead of
119 * 20 sided dice. Makes battles harder to win when
122 void battle(bool intense);
124 Result battleFromHistory();
126 //! Returns the result of the fight.
127 Result getResult() const {return d_result;}
129 //! Returns the list of things that happened in chronological order.
130 std::list<FightItem> getCourseOfEvents() const {return d_actions;};
132 //! Returns the participating attacker stacks.
133 std::list<Stack*> getAttackers() const {return d_attackers;}
135 //! Returns the participating defender stacks.
136 std::list<Stack*> getDefenders() const {return d_defenders;}
138 //! Get the modified strength bonus of the given Army unit.
139 guint32 getModifiedStrengthBonus(Army *a);
142 //! The number of rounds the fight lasts.
144 * @note If this is 0, then there is no maximum.
146 static const int MAX_ROUNDS = 0;
148 //! Turn a list of stacks into an ordered list of armies.
150 * @note This is used for calculation and display purposes.
152 static void orderArmies(std::list<Stack*> stacks,
153 std::vector<Army*> &armies);
155 std::map<guint32, guint32> getInitialHPs() { return initial_hps; }
157 static LocationBox calculateFightBox(Fight &fight);
159 //! Calculates one round of the fight.
161 * @return false if the maximum number of fight rounds has been
162 * exceeded or one side has lost.
166 //! Calculates the attack/defense bonus of the armies.
167 void calculateBonus();
169 //! Calculates the base strength of the armies fighting in the battle.
170 void calculateBaseStrength(std::list<Fighter*> fighters);
172 //! Add the bonuses provided by terrain.
173 void calculateTerrainModifiers(std::list<Fighter*> fighters);
175 //! Add the bonuses by opponents.
176 void calculateModifiedStrengths (std::list<Fighter*>friendly,
177 std::list<Fighter*>enemy,
178 bool friendlyIsDefending,
179 Hero *strongestHero);
181 //! Subtract stack bonuses of the opponent.
182 void calculateFinalStrengths (std::list<Fighter*> friendly,
183 std::list<Fighter*> enemy);
186 * This function just has two armies fight against each other. It
187 * applies the bonuses and several special bonuses to attacker and
188 * defender and calculates the result.
190 * @param attacker The attacking army.
191 * @param defender The defending army.
193 void fightArmies(Fighter* attacker, Fighter* defender);
195 //! Removes an army from the fight.
196 void remove(Fighter* f);
198 void fillInInitialHPs();
203 std::list<Stack*> d_attackers;
206 std::list<Stack*> d_defenders;
208 //!The attackers in the fight.
209 std::list<Fighter*> d_att_close;
211 //! The defenders in the fight.
212 std::list<Fighter*> d_def_close;
214 std::map<guint32, guint32> initial_hps;
216 //! The list of fight events that gets calculated.
217 std::list<FightItem> d_actions;
219 //! The round of the fight.
222 //! The result of the fight.
225 //! The kind of fight.
228 //! Whether or not we're rolling 24-sided dice or 20 sided dice.
229 bool d_intense_combat;