Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "attack.hpp"
00021
00022 #include "visitor.hpp"
00023
00024 #include "arrow.hpp"
00025 #include "play_controller.hpp"
00026 #include "resources.hpp"
00027 #include "unit.hpp"
00028 #include "unit_map.hpp"
00029
00030 namespace wb
00031 {
00032
00033 std::ostream &operator<<(std::ostream &s, attack_ptr attack)
00034 {
00035 assert(attack);
00036 return attack->print(s);
00037 }
00038
00039 std::ostream &operator<<(std::ostream &s, attack_const_ptr attack)
00040 {
00041 assert(attack);
00042 return attack->print(s);
00043 }
00044
00045 std::ostream& attack::print(std::ostream& s) const
00046 {
00047 s << "Attack on (" << get_target_hex() << ") preceded by ";
00048 move::print(s);
00049 return s;
00050 }
00051
00052 attack::attack(size_t team_index, bool hidden, unit& u, const map_location& target_hex, int weapon_choice, const pathfind::marked_route& route,
00053 arrow_ptr arrow, fake_unit_ptr fake_unit)
00054 : move(team_index, hidden, u, route, arrow, fake_unit),
00055 target_hex_(target_hex),
00056 weapon_choice_(weapon_choice),
00057 attack_movement_cost_(get_unit()->attacks()[weapon_choice_].movement_used()),
00058 temp_movement_subtracted_(0)
00059 {
00060 this->init();
00061 }
00062
00063 attack::attack(config const& cfg, bool hidden)
00064 : move(cfg,hidden)
00065 , target_hex_(cfg.child("target_hex_")["x"],cfg.child("target_hex_")["y"])
00066 , weapon_choice_(cfg["weapon_choice_"].to_int(-1))
00067 , attack_movement_cost_()
00068 , temp_movement_subtracted_(0)
00069 {
00070
00071 if(!tiles_adjacent(target_hex_,get_dest_hex()))
00072 throw action::ctor_err("attack: Invalid target_hex_");
00073
00074
00075 if(weapon_choice_ < 0 || weapon_choice_ >= static_cast<int>(get_unit()->attacks().size()))
00076 throw action::ctor_err("attack: Invalid weapon_choice_");
00077
00078
00079 attack_movement_cost_ = get_unit()->attacks()[weapon_choice_].movement_used();
00080
00081 this->init();
00082 }
00083
00084 void attack::init()
00085 {
00086 resources::screen->invalidate(target_hex_);
00087 }
00088
00089 attack::~attack()
00090 {
00091 invalidate();
00092 }
00093
00094 void attack::accept(visitor& v)
00095 {
00096 v.visit(shared_from_this());
00097 }
00098
00099
00100 void attack::invalidate()
00101 {
00102 if(resources::screen)
00103 {
00104
00105 resources::screen->invalidate(get_dest_hex());
00106 resources::screen->invalidate(target_hex_);
00107 }
00108 }
00109
00110 void attack::execute(bool& success, bool& complete)
00111 {
00112 if (!valid_) {
00113 success = false;
00114
00115 complete = true;
00116 return;
00117 }
00118
00119 LOG_WB << "Executing: " << shared_from_this() << "\n";
00120
00121 if (route_->steps.size() >= 2)
00122 {
00123 bool m_success, m_complete;
00124 move::execute(m_success,m_complete);
00125 if(!m_success) {
00126
00127 success = false;
00128 complete = true;
00129 return;
00130 }
00131 }
00132
00133 resources::controller->get_mouse_handler_base().attack_enemy(get_dest_hex(), get_target_hex(), weapon_choice_);
00134 complete = true;
00135
00136
00137 unit_map::const_iterator survivor = resources::units->find(get_dest_hex());
00138 if(!survivor.valid() || survivor->id() != unit_id_)
00139 {
00140 success = false;
00141 }
00142
00143 success = true;
00144 }
00145
00146 void attack::apply_temp_modifier(unit_map& unit_map)
00147 {
00148 move::apply_temp_modifier(unit_map);
00149 assert(get_unit());
00150 unit& unit = *get_unit();
00151 DBG_WB << unit.name() << " [" << unit.id()
00152 << "] has " << unit.attacks_left() << " attacks, decreasing by one" << "\n";
00153 assert(unit.attacks_left() > 0);
00154 unit.set_attacks(unit.attacks_left() - 1);
00155
00156
00157 temp_movement_subtracted_ = unit.movement_left() >= attack_movement_cost_ ? attack_movement_cost_ : 0 ;
00158 DBG_WB << "Attack: Changing movement points for unit " << unit.name() << " [" << unit.id()
00159 << "] from " << unit.movement_left() << " to "
00160 << unit.movement_left() - temp_movement_subtracted_ << ".\n";
00161 unit.set_movement(unit.movement_left() - temp_movement_subtracted_);
00162
00163
00164
00165 if (fake_unit_) {
00166 fake_unit_->set_movement(unit.movement_left());
00167 fake_unit_->set_attacks(unit.attacks_left());
00168 }
00169 }
00170
00171 void attack::remove_temp_modifier(unit_map& unit_map)
00172 {
00173 assert(get_unit());
00174 unit& unit = *get_unit();
00175 DBG_WB << unit.name() << " [" << unit.id()
00176 << "] has " << unit.attacks_left() << " attacks, increasing by one" << "\n";
00177 unit.set_attacks(unit.attacks_left() + 1);
00178 DBG_WB << "Attack: Changing movement points for unit " << unit.name() << " [" << unit.id()
00179 << "] from " << unit.movement_left() << " to "
00180 << unit.movement_left() + temp_movement_subtracted_ << ".\n";
00181 unit.set_movement(unit.movement_left() + temp_movement_subtracted_);
00182 temp_movement_subtracted_ = 0;
00183 move::remove_temp_modifier(unit_map);
00184 }
00185
00186 void attack::draw_hex(const map_location& hex)
00187 {
00188 if (hex == get_dest_hex() || hex == target_hex_)
00189 {
00190
00191
00192 const display::tdrawing_layer layer = display::LAYER_FOOTSTEPS;
00193
00194
00195 std::string direction_text = map_location::write_direction(
00196 get_dest_hex().get_relative_dir(target_hex_));
00197
00198 if (hex == get_dest_hex())
00199 {
00200 int xpos = resources::screen->get_location_x(get_dest_hex());
00201 int ypos = resources::screen->get_location_y(get_dest_hex());
00202
00203 resources::screen->drawing_buffer_add(layer, get_dest_hex(), xpos, ypos,
00204 image::get_image("whiteboard/attack-indicator-src-" + direction_text + ".png", image::SCALED_TO_HEX));
00205 }
00206 else if (hex == target_hex_)
00207 {
00208 int xpos = resources::screen->get_location_x(target_hex_);
00209 int ypos = resources::screen->get_location_y(target_hex_);
00210
00211 resources::screen->drawing_buffer_add(layer, target_hex_, xpos, ypos,
00212 image::get_image("whiteboard/attack-indicator-dst-" + direction_text + ".png", image::SCALED_TO_HEX));
00213 }
00214 }
00215 }
00216
00217 config attack::to_config() const
00218 {
00219 config final_cfg = move::to_config();
00220
00221 final_cfg["type"] = "attack";
00222 final_cfg["weapon_choice_"] = weapon_choice_;
00223
00224
00225
00226 config target_hex_cfg;
00227 target_hex_cfg["x"]=target_hex_.x;
00228 target_hex_cfg["y"]=target_hex_.y;
00229 final_cfg.add_child("target_hex_",target_hex_cfg);
00230
00231 return final_cfg;
00232 }
00233
00234 }