00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef ACTIONS_H_INCLUDED
00022 #define ACTIONS_H_INCLUDED
00023
00024 class attack_type;
00025 class game_display;
00026 class replay;
00027 struct combatant;
00028 class team;
00029 struct time_of_day;
00030
00031 #include "unit.hpp"
00032
00033 class unit_creator {
00034 public:
00035 unit_creator(team &tm, const map_location &start_pos);
00036 unit_creator& allow_show(bool b);
00037 unit_creator& allow_get_village(bool b);
00038 unit_creator& allow_rename_side(bool b);
00039 unit_creator& allow_invalidate(bool b);
00040 unit_creator& allow_discover(bool b);
00041 unit_creator& allow_add_to_recall(bool b);
00042
00043
00044
00045
00046
00047
00048 map_location find_location(const config &cfg, const unit* pass_check=NULL);
00049
00050
00051
00052
00053
00054 void add_unit(const config &cfg, const vconfig* vcfg = NULL);
00055
00056 private:
00057 void post_create(const map_location &loc, const unit &new_unit, bool anim);
00058
00059 bool add_to_recall_;
00060 bool discover_;
00061 bool get_village_;
00062 bool invalidate_;
00063 bool rename_side_;
00064 bool show_;
00065 const map_location start_pos_;
00066 team &team_;
00067
00068 };
00069
00070
00071 bool can_recruit_on(const gamemap& map, const map_location& leader, const map_location& loc);
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 std::string find_recruit_location(const int side, map_location &recruit_location, map_location& recruited_from, const std::string& unit_type);
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 std::string find_recall_location(const int side, map_location& recall_location, map_location& recall_from, const unit &unit_recall);
00102
00103
00104
00105
00106
00107
00108
00109 const std::set<std::string> get_recruits_for_location(int side, const map_location &recruit_location);
00110
00111
00112
00113
00114
00115
00116
00117
00118 const std::vector<const unit*> get_recalls_for_location(int side, const map_location &recruit_location);
00119
00120
00121
00122
00123
00124
00125 void place_recruit(const unit &u, const map_location &recruit_location, const map_location& recruited_from,
00126 bool is_recall, bool show = false, bool fire_event = true, bool full_movement = false,
00127 bool wml_triggered = false);
00128
00129
00130 struct battle_context_unit_stats
00131 {
00132 const attack_type *weapon;
00133 int attack_num;
00134 bool is_attacker;
00135 bool is_poisoned;
00136 bool is_slowed;
00137 bool slows;
00138 bool drains;
00139 bool petrifies;
00140 bool plagues;
00141 bool poisons;
00142 bool backstab_pos;
00143
00144
00145
00146 bool swarm;
00147 bool firststrike;
00148 unsigned int experience, max_experience;
00149 unsigned int level;
00150
00151 unsigned int rounds;
00152 unsigned int hp;
00153 unsigned int max_hp;
00154 unsigned int chance_to_hit;
00155 int damage;
00156 int slow_damage;
00157 int drain_percent;
00158 int drain_constant;
00159 unsigned int num_blows;
00160 unsigned int swarm_min;
00161 unsigned int swarm_max;
00162
00163 std::string plague_type;
00164
00165 battle_context_unit_stats(const unit &u, const map_location& u_loc,
00166 int u_attack_num, bool attacking,
00167 const unit &opp, const map_location& opp_loc,
00168 const attack_type *opp_weapon,
00169 const unit_map& units);
00170 ~battle_context_unit_stats();
00171
00172
00173 void dump() const;
00174 };
00175
00176
00177 class battle_context
00178 {
00179 public:
00180
00181
00182
00183
00184
00185
00186
00187 battle_context(const unit_map &units,
00188 const map_location& attacker_loc, const map_location& defender_loc,
00189 int attacker_weapon = -1, int defender_weapon = -1, double aggression = 0.0, const combatant *prev_def = NULL, const unit* attacker_ptr=NULL);
00190
00191
00192 battle_context(const battle_context_unit_stats &att, const battle_context_unit_stats &def);
00193
00194 battle_context(const battle_context &other);
00195 ~battle_context();
00196
00197 battle_context& operator=(const battle_context &other);
00198
00199
00200 const battle_context_unit_stats& get_attacker_stats() const { return *attacker_stats_; }
00201
00202
00203 const battle_context_unit_stats& get_defender_stats() const { return *defender_stats_; }
00204
00205
00206 const combatant &get_attacker_combatant(const combatant *prev_def = NULL);
00207 const combatant &get_defender_combatant(const combatant *prev_def = NULL);
00208
00209
00210 bool better_attack(class battle_context &that, double harm_weight);
00211
00212 private:
00213 bool better_combat(const combatant &us_a, const combatant &them_a,
00214 const combatant &us_b, const combatant &them_b,
00215 double harm_weight);
00216
00217 int choose_attacker_weapon(const unit &attacker, const unit &defender,
00218 const unit_map& units,
00219 const map_location& attacker_loc, const map_location& defender_loc,
00220 double harm_weight, int *defender_weapon, const combatant *prev_def);
00221
00222 int choose_defender_weapon(const unit &attacker, const unit &defender, unsigned attacker_weapon,
00223 const unit_map& units,
00224 const map_location& attacker_loc, const map_location& defender_loc, const combatant *prev_def);
00225
00226
00227 battle_context_unit_stats *attacker_stats_, *defender_stats_;
00228
00229
00230 combatant *attacker_combatant_, *defender_combatant_;
00231 };
00232
00233
00234 void attack_unit(const map_location &attacker, const map_location &defender,
00235 int attack_with, int defend_with, bool update_display = true);
00236
00237 class move_unit_spectator {
00238 public:
00239
00240 void add_seen_friend(const unit_map::const_iterator &u);
00241
00242
00243
00244 void add_seen_enemy(const unit_map::const_iterator &u);
00245
00246
00247
00248 const unit_map::const_iterator& get_ambusher() const;
00249
00250
00251
00252 const unit_map::const_iterator& get_failed_teleport() const;
00253
00254
00255
00256 const std::vector<unit_map::const_iterator>& get_seen_enemies() const;
00257
00258
00259
00260 const std::vector<unit_map::const_iterator>& get_seen_friends() const;
00261
00262
00263
00264 const unit_map::const_iterator& get_unit() const;
00265
00266
00267
00268 move_unit_spectator(const unit_map &units);
00269
00270
00271
00272 virtual ~move_unit_spectator();
00273
00274
00275 void reset(const unit_map &units);
00276
00277
00278
00279 void set_ambusher(const unit_map::const_iterator &u);
00280
00281
00282
00283 void set_failed_teleport(const unit_map::const_iterator &u);
00284
00285
00286
00287 void set_unit(const unit_map::const_iterator &u);
00288 private:
00289 unit_map::const_iterator ambusher_;
00290 unit_map::const_iterator failed_teleport_;
00291 std::vector<unit_map::const_iterator> seen_enemies_;
00292 std::vector<unit_map::const_iterator> seen_friends_;
00293 unit_map::const_iterator unit_;
00294 };
00295
00296
00297
00298
00299
00300 int village_owner(const map_location& loc, const std::vector<team>& teams);
00301
00302
00303
00304
00305
00306 bool get_village(const map_location& loc, int side, int *time_bonus = NULL);
00307
00308
00309
00310
00311
00312 void reset_resting(unit_map& units, int side);
00313
00314
00315
00316
00317
00318 void calculate_healing(int side, bool update_display);
00319
00320
00321
00322
00323 unit get_advanced_unit(const unit &u, const std::string &advance_to);
00324
00325
00326
00327
00328
00329
00330
00331 void advance_unit(map_location loc, const std::string &advance_to, const bool &fire_event = true);
00332
00333
00334
00335
00336
00337
00338
00339
00340 map_location under_leadership(const unit_map& units,
00341 const map_location& loc, int* bonus=NULL);
00342
00343
00344
00345
00346
00347 int combat_modifier(const map_location &loc,
00348 unit_type::ALIGNMENT alignment, bool is_fearless);
00349
00350
00351 struct undo_action {
00352 enum ACTION_TYPE { NONE, RECRUIT, RECALL, DISMISS };
00353
00354 undo_action(const unit& u, const std::vector<map_location>& rt, int sm,
00355 int timebonus=0, int orig=-1,
00356 const map_location::DIRECTION dir=map_location::NDIRECTIONS) :
00357 route(rt),
00358 starting_moves(sm),
00359 original_village_owner(orig),
00360 recall_loc(),
00361 recall_from(),
00362 type(NONE),
00363 affected_unit(u),
00364 countdown_time_bonus(timebonus),
00365 starting_dir(dir == map_location::NDIRECTIONS ? u.facing() : dir)
00366 {
00367 }
00368
00369 undo_action(const unit& u, const map_location& loc, const map_location& from,
00370 const ACTION_TYPE action_type=NONE) :
00371 route(),
00372 starting_moves(),
00373 original_village_owner(),
00374 recall_loc(loc),
00375 recall_from(from),
00376 type(action_type),
00377 affected_unit(u),
00378 countdown_time_bonus(1),
00379 starting_dir(u.facing())
00380 {}
00381
00382 std::vector<map_location> route;
00383 int starting_moves;
00384 int original_village_owner;
00385 map_location recall_loc;
00386 map_location recall_from;
00387 ACTION_TYPE type;
00388 unit affected_unit;
00389 int countdown_time_bonus;
00390 map_location::DIRECTION starting_dir;
00391
00392 bool is_dismiss() const { return type == DISMISS; }
00393 bool is_recall() const { return type == RECALL; }
00394 bool is_recruit() const { return type == RECRUIT; }
00395 };
00396
00397 typedef std::vector<undo_action> undo_list;
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 size_t move_unit(move_unit_spectator* move_spectator,
00408 const std::vector<map_location> &steps,
00409 replay* move_recorder, undo_list* undos,
00410 bool show_move,
00411 map_location *next_unit = NULL,
00412 bool continue_move = false, bool should_clear_shroud=true, bool is_replay=false,
00413 bool* units_sighted_result = NULL);
00414
00415
00416 void recalculate_fog(int side);
00417
00418
00419 bool clear_shroud(int side, bool reset_fog=false);
00420
00421
00422
00423
00424 void apply_shroud_changes(undo_list &undos, int side);
00425
00426
00427
00428
00429
00430 bool unit_can_move(const unit &u);
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 bool backstab_check(const map_location& attacker_loc,
00445 const map_location& defender_loc,
00446 const unit_map& units, const std::vector<team>& teams);
00447
00448 #endif