00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef ACTIONS_H_INCLUDED
00019 #define ACTIONS_H_INCLUDED
00020
00021 class display;
00022 class gamestatus;
00023 class game_display;
00024 class replay;
00025 struct combatant;
00026 class unit;
00027
00028 class attack_type;
00029 class team;
00030 class unit_type_data;
00031
00032 #include "global.hpp"
00033 #include "map.hpp"
00034 #include "unit.hpp"
00035 #include "unit_map.hpp"
00036 #include "unit_types.hpp"
00037
00038 #include <deque>
00039 #include <sstream>
00040
00041 #define RECRUIT_POS -2
00042
00043 bool can_recruit_on(const gamemap& map, const gamemap::location& leader, const gamemap::location loc);
00044
00045 struct end_level_exception;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 std::string recruit_unit(const gamemap& map, const int side, unit_map& units,
00060 unit u, gamemap::location& recruit_location,const bool is_recall,
00061 const bool show=false,const bool need_castle=true,
00062 const bool full_movement=false,const bool wml_triggered=false);
00063
00064
00065 class battle_context
00066 {
00067 public:
00068
00069 struct unit_stats
00070 {
00071 const attack_type *weapon;
00072 int attack_num;
00073 bool is_attacker;
00074 bool is_poisoned;
00075 bool is_slowed;
00076 bool slows;
00077 bool drains;
00078 bool stones;
00079 bool plagues;
00080 bool poisons;
00081 bool backstab_pos;
00082
00083 bool swarm;
00084 bool firststrike;
00085
00086 unsigned int rounds;
00087 unsigned int hp;
00088 unsigned int max_hp;
00089 unsigned int chance_to_hit;
00090 int damage;
00091 int slow_damage;
00092 unsigned int num_blows;
00093 unsigned int swarm_min;
00094 unsigned int swarm_max;
00095
00096 std::string plague_type;
00097
00098 unit_stats(const unit &u, const gamemap::location& u_loc,
00099 int u_attack_num, bool attacking,
00100 const unit &opp, const gamemap::location& opp_loc,
00101 const attack_type *opp_weapon,
00102 const unit_map& units,
00103 const std::vector<team>& teams,
00104 const gamestatus& status, const gamemap& map);
00105 ~unit_stats();
00106
00107
00108 void dump() const;
00109 };
00110
00111
00112
00113
00114
00115 battle_context(const gamemap& map, const std::vector<team>& teams, const unit_map& units,
00116 const gamestatus& status,
00117 const gamemap::location& attacker_loc, const gamemap::location& defender_loc,
00118 int attacker_weapon = -1, int defender_weapon = -1, double aggression = 0.0, const combatant *prev_def = NULL, const unit* attacker_ptr=NULL);
00119
00120
00121 battle_context(const unit_stats &att, const unit_stats &def);
00122
00123 battle_context(const battle_context &other);
00124 ~battle_context();
00125
00126 battle_context& operator=(const battle_context &other);
00127
00128
00129 const unit_stats& get_attacker_stats() const { return *attacker_stats_; }
00130
00131
00132 const unit_stats& get_defender_stats() const { return *defender_stats_; }
00133
00134
00135 const combatant &get_attacker_combatant(const combatant *prev_def = NULL);
00136 const combatant &get_defender_combatant(const combatant *prev_def = NULL);
00137
00138
00139 bool better_attack(class battle_context &that, double harm_weight);
00140
00141 private:
00142 bool better_combat(const combatant &us_a, const combatant &them_a,
00143 const combatant &us_b, const combatant &them_b,
00144 double harm_weight);
00145
00146 int choose_attacker_weapon(const unit &attacker, const unit &defender,
00147 const gamemap& map, const std::vector<team>& teams, const unit_map& units,
00148 const gamestatus& status,
00149 const gamemap::location& attacker_loc, const gamemap::location& defender_loc,
00150 double harm_weight, int *defender_weapon, const combatant *prev_def);
00151
00152 int choose_defender_weapon(const unit &attacker, const unit &defender, unsigned attacker_weapon,
00153 const gamemap& map, const std::vector<team>& teams, const unit_map& units,
00154 const gamestatus& status,
00155 const gamemap::location& attacker_loc, const gamemap::location& defender_loc, const combatant *prev_def);
00156
00157
00158 unit_stats *attacker_stats_, *defender_stats_;
00159
00160
00161 combatant *attacker_combatant_, *defender_combatant_;
00162 };
00163
00164
00165 class attack {
00166 public:
00167 attack(game_display& gui, const gamemap& map,
00168 std::vector<team>& teams,
00169 gamemap::location attacker,
00170 gamemap::location defender,
00171 int attack_with,
00172 int defend_with,
00173 unit_map& units,
00174 const gamestatus& state,
00175 bool update_display = true);
00176 ~attack();
00177 private:
00178 class attack_end_exception {};
00179 void fire_event(const std::string& n);
00180 void refresh_bc();
00181 game_display& gui_;
00182 const gamemap& map_;
00183 std::vector<team>& teams_;
00184 gamemap::location attacker_;
00185 gamemap::location defender_;
00186 int attack_with_;
00187 int defend_with_;
00188 unit_map& units_;
00189 const gamestatus& state_;
00190 unit_map::iterator a_,d_;
00191 std::string a_id_, d_id_;
00192 std::stringstream errbuf_;
00193 battle_context* bc_;
00194 const battle_context::unit_stats* a_stats_;
00195 const battle_context::unit_stats* d_stats_;
00196 int orig_attacks_,orig_defends_;
00197 int n_attacks_,n_defends_;
00198 int attacker_cth_,defender_cth_;
00199 int attacker_damage_,defender_damage_;
00200 int attackerxp_,defenderxp_;
00201
00202 bool update_display_;
00203 bool OOS_error_;
00204 end_level_exception* delayed_exception;
00205
00206 };
00207
00208
00209
00210 int village_owner(const gamemap::location& loc, const std::vector<team>& teams);
00211
00212
00213
00214
00215 bool get_village(const gamemap::location& loc, game_display& disp,
00216 std::vector<team>& teams, size_t team_num,
00217 const unit_map& units, int *time_bonus = NULL);
00218
00219
00220
00221 unit_map::iterator find_leader(unit_map& units, int side);
00222
00223 unit_map::const_iterator find_leader(const unit_map& units, int side);
00224
00225
00226
00227 void reset_resting(unit_map& units, unsigned int side);
00228
00229
00230
00231 void calculate_healing(game_display& disp, const gamemap& map,
00232 unit_map& units, unsigned int side,
00233 const std::vector<team>& teams, bool update_display);
00234
00235
00236
00237
00238
00239 unit get_advanced_unit(unit_map& units,
00240 const gamemap::location& loc, const std::string& advance_to);
00241
00242
00243
00244
00245
00246 void advance_unit(unit_map& units,
00247 gamemap::location loc, const std::string& advance_to);
00248
00249
00250
00251
00252
00253
00254 gamemap::location under_leadership(const unit_map& units,
00255 const gamemap::location& loc, int* bonus=NULL);
00256
00257
00258
00259
00260 void check_victory(unit_map& units, std::vector<team>& teams, display& disp);
00261
00262
00263
00264
00265
00266 time_of_day timeofday_at(const gamestatus& status,
00267 const unit_map& units,
00268 const gamemap::location& loc,
00269 const gamemap& map);
00270
00271
00272
00273 int combat_modifier(const gamestatus& status,
00274 const unit_map& units,
00275 const gamemap::location& loc,
00276 unit_type::ALIGNMENT alignment,
00277 bool is_fearless,
00278 const gamemap& map);
00279
00280
00281 struct undo_action {
00282 undo_action(const unit& u,
00283 const std::vector<gamemap::location>& rt,
00284 int sm, int timebonus = 0, int orig = -1) :
00285 route(rt),
00286 starting_moves(sm),
00287 original_village_owner(orig),
00288 recall_loc(),
00289 recall_pos(-1),
00290 affected_unit(u),
00291 countdown_time_bonus(timebonus)
00292 {}
00293
00294 undo_action(const unit& u, const gamemap::location& loc, const int pos) :
00295 route(),
00296 starting_moves(),
00297 original_village_owner(),
00298 recall_loc(loc),
00299 recall_pos(pos),
00300 affected_unit(u),
00301 countdown_time_bonus(1)
00302 {}
00303
00304 std::vector<gamemap::location> route;
00305 int starting_moves;
00306 int original_village_owner;
00307 gamemap::location recall_loc;
00308 int recall_pos;
00309 unit affected_unit;
00310 int countdown_time_bonus;
00311 bool is_recall() const { return recall_pos >= 0; }
00312 bool is_recruit() const { return recall_pos == RECRUIT_POS; }
00313 };
00314
00315 typedef std::deque<undo_action> undo_list;
00316
00317
00318
00319
00320
00321
00322 size_t move_unit(game_display* disp,
00323 const gamemap& map,
00324 unit_map& units, std::vector<team>& teams,
00325 std::vector<gamemap::location> steps,
00326 replay* move_recorder, undo_list* undos,
00327 gamemap::location *next_unit = NULL,
00328 bool continue_move = false, bool should_clear_shroud=true);
00329
00330
00331 void recalculate_fog(const gamemap& map,
00332 unit_map& units, std::vector<team>& teams, int team);
00333
00334
00335
00336
00337 bool clear_shroud(game_display& disp,
00338 const gamemap& map,
00339 unit_map& units, std::vector<team>& teams, int team);
00340
00341
00342
00343 void apply_shroud_changes(undo_list& undos, game_display* disp, const gamemap& map,
00344 unit_map& units, std::vector<team>& teams, int team);
00345
00346
00347
00348 bool unit_can_move(const gamemap::location& loc, const unit_map& units,
00349 const gamemap& map, const std::vector<team>& teams);
00350
00351
00352 namespace victory_conditions {
00353 void set_victory_when_enemies_defeated(const bool on);
00354 void set_carryover_percentage(const int percentage);
00355 void set_carryover_add(const bool add);
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 bool backstab_check(const gamemap::location& attacker_loc,
00369 const gamemap::location& defender_loc,
00370 const unit_map& units, const std::vector<team>& teams);
00371
00372 #endif