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
00021 #include "arrow.hpp"
00022
00023 #include "foreach.hpp"
00024 #include "game_display.hpp"
00025 #include "log.hpp"
00026 #include "resources.hpp"
00027
00028 static lg::log_domain log_arrows("arrows");
00029 #define ERR_ARR LOG_STREAM(err, log_arrows)
00030 #define WRN_ARR LOG_STREAM(warn, log_arrows)
00031 #define LOG_ARR LOG_STREAM(info, log_arrows)
00032 #define DBG_ARR LOG_STREAM(debug, log_arrows)
00033
00034 #define SCREEN (static_cast<display*>(resources::screen))
00035
00036 arrow::arrow(bool hidden)
00037 : layer_(display::LAYER_ARROWS)
00038 , color_("red")
00039 , style_(STYLE_STANDARD)
00040 , path_()
00041 , previous_path_()
00042 , symbols_map_()
00043 , hidden_(true)
00044 {
00045 if(!hidden)
00046 show();
00047 }
00048
00049 arrow::~arrow()
00050 {
00051 hide();
00052 }
00053
00054 void arrow::hide()
00055 {
00056 if(hidden_)
00057 return;
00058 hidden_ = true;
00059
00060 if (SCREEN)
00061 {
00062 invalidate_arrow_path(path_);
00063 SCREEN->remove_arrow(*this);
00064 }
00065 }
00066
00067 void arrow::show()
00068 {
00069 if(!hidden_)
00070 return;
00071 hidden_ = false;
00072
00073 if(SCREEN)
00074 SCREEN->add_arrow(*this);
00075 }
00076
00077 void arrow::set_path(arrow_path_t const& path)
00078 {
00079 if (valid_path(path))
00080 {
00081 previous_path_ = path_;
00082 path_ = path;
00083 update_symbols();
00084 if(!hidden_)
00085 {
00086 invalidate_arrow_path(previous_path_);
00087 notify_arrow_changed();
00088 }
00089 }
00090 }
00091
00092 void arrow::reset()
00093 {
00094 invalidate_arrow_path(previous_path_);
00095 invalidate_arrow_path(path_);
00096 previous_path_.clear();
00097 path_.clear();
00098 symbols_map_.clear();
00099 notify_arrow_changed();
00100 }
00101
00102 void arrow::set_color(std::string const& color)
00103 {
00104 color_ = color;
00105 if (valid_path(path_))
00106 {
00107 update_symbols();
00108 }
00109 }
00110
00111 std::string const arrow::STYLE_STANDARD = "standard";
00112 std::string const arrow::STYLE_HIGHLIGHTED = "highlighted";
00113 std::string const arrow::STYLE_FOCUS = "focus";
00114 std::string const arrow::STYLE_FOCUS_INVALID = "focus_invalid";
00115
00116 void arrow::set_style(const std::string& style)
00117 {
00118 style_ = style;
00119 if (valid_path(path_))
00120 {
00121 update_symbols();
00122 }
00123 }
00124
00125 arrow_path_t const& arrow::get_path() const
00126 {
00127 return path_;
00128 }
00129
00130 arrow_path_t const& arrow::get_previous_path() const
00131 {
00132 return previous_path_;
00133 }
00134
00135 bool arrow::path_contains(map_location const& hex) const
00136 {
00137 bool contains = symbols_map_.find(hex) != symbols_map_.end();
00138 return contains;
00139 }
00140
00141 void arrow::draw_hex(map_location const& hex)
00142 {
00143 if(path_contains(hex))
00144 {
00145 SCREEN->render_image(SCREEN->get_location_x(hex), SCREEN->get_location_y(hex), layer_,
00146 hex, image::get_image(symbols_map_[hex], image::SCALED_TO_ZOOM));
00147 }
00148 }
00149
00150 bool arrow::valid_path(arrow_path_t const& path)
00151 {
00152 if (path.size() >= 2)
00153 return true;
00154 else
00155 return false;
00156 }
00157
00158 void arrow::update_symbols()
00159 {
00160 if (!valid_path(path_))
00161 {
00162 WRN_ARR << "arrow::update_symbols called with invalid path\n";
00163 return;
00164 }
00165
00166 symbols_map_.clear();
00167 invalidate_arrow_path(path_);
00168
00169 std::string const mods = "~RC(FF00FF>"+ color_ + ")";
00170
00171 std::string const dirname = "arrows/";
00172 map_location::DIRECTION exit_dir = map_location::NDIRECTIONS;
00173 map_location::DIRECTION enter_dir = map_location::NDIRECTIONS;
00174 std::string prefix = "";
00175 std::string suffix = "";
00176 std::string image_filename = "";
00177 arrow_path_t::const_iterator const arrow_start_hex = path_.begin();
00178 arrow_path_t::const_iterator const arrow_pre_end_hex = path_.end() - 2;
00179 arrow_path_t::const_iterator const arrow_end_hex = path_.end() - 1;
00180 bool start = false;
00181 bool pre_end = false;
00182 bool end = false;
00183 bool teleport_out = false;
00184 bool teleport_in = false;
00185
00186 arrow_path_t::iterator hex;
00187 for (hex = path_.begin(); hex != path_.end(); ++hex)
00188 {
00189 prefix = "";
00190 suffix = "";
00191 image_filename = "";
00192 start = pre_end = end = false;
00193
00194
00195 teleport_in = teleport_out;
00196 teleport_out = false;
00197
00198
00199 if (hex == arrow_start_hex)
00200 start = true;
00201 if (hex == arrow_pre_end_hex)
00202 pre_end = true;
00203 else if (hex == arrow_end_hex)
00204 end = true;
00205 if (hex != arrow_end_hex && !tiles_adjacent(*hex, *(hex + 1)))
00206 teleport_out = true;
00207
00208
00209 enter_dir = map_location::NDIRECTIONS;
00210 if (!start && !teleport_in)
00211 {
00212 enter_dir = hex->get_relative_dir(*(hex-1));
00213 }
00214 exit_dir = map_location::NDIRECTIONS;
00215 if (!end && !teleport_out)
00216 {
00217 exit_dir = hex->get_relative_dir(*(hex+1));
00218 }
00219
00220
00221 if (teleport_out)
00222 {
00223 prefix = "teleport-out";
00224 if (enter_dir != map_location::NDIRECTIONS)
00225 {
00226 suffix = map_location::write_direction(enter_dir);
00227 }
00228 }
00229 else if (teleport_in)
00230 {
00231 prefix = "teleport-in";
00232 if (exit_dir != map_location::NDIRECTIONS)
00233 {
00234 suffix = map_location::write_direction(exit_dir);
00235 }
00236 }
00237 else if (start)
00238 {
00239 prefix = "start";
00240 suffix = map_location::write_direction(exit_dir);
00241 if (pre_end)
00242 {
00243 suffix = suffix + "_ending";
00244 }
00245 }
00246 else if (end)
00247 {
00248 prefix = "end";
00249 suffix = map_location::write_direction(enter_dir);
00250 }
00251 else
00252 {
00253 std::string enter, exit;
00254 enter = map_location::write_direction(enter_dir);
00255 exit = map_location::write_direction(exit_dir);
00256 if (pre_end)
00257 {
00258 exit = exit + "_ending";
00259 }
00260
00261 assert(abs(enter_dir - exit_dir) > 1);
00262 if (enter_dir < exit_dir)
00263 {
00264 prefix = enter;
00265 suffix = exit;
00266 }
00267 else
00268 {
00269 prefix = exit;
00270 suffix = enter;
00271 }
00272 }
00273
00274 image_filename = dirname + style_ + "/" + prefix;
00275 if (suffix != "")
00276 {
00277 image_filename += ("-" + suffix);
00278 }
00279 image_filename += ".png";
00280 assert(image_filename != "");
00281
00282 image::locator image = image::locator(image_filename, mods);
00283 if (!image.file_exists())
00284 {
00285 ERR_ARR << "Image " << image_filename << " not found.\n";
00286 image = image::locator(game_config::images::missing);
00287 }
00288 symbols_map_[*hex] = image;
00289 }
00290 }
00291
00292 void arrow::invalidate_arrow_path(arrow_path_t const& path)
00293 {
00294 if(!SCREEN) return;
00295
00296 foreach(map_location const& loc, path)
00297 {
00298 SCREEN->invalidate(loc);
00299 }
00300 }
00301
00302 void arrow::notify_arrow_changed()
00303 {
00304 if(!SCREEN) return;
00305
00306 SCREEN->update_arrow(*this);
00307 }