arrow.cpp

Go to the documentation of this file.
00001 /* $Id: arrow.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2010 - 2012 by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * @file
00018  * Method bodies for the arrow class.
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_ + ")"; //magenta to current 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         // teleport in if we teleported out last hex
00195         teleport_in = teleport_out;
00196         teleport_out = false;
00197 
00198         // Determine some special cases
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         // calculate enter and exit directions, if available
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         // Now figure out the actual images
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); //impossible turn?
00262             if (enter_dir < exit_dir)
00263             {
00264                 prefix = enter;
00265                 suffix = exit;
00266             }
00267             else //(enter_dir > exit_dir)
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Tue May 22 2012 01:03:40 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs