editor/map/map_fragment.cpp

Go to the documentation of this file.
00001 /* $Id: map_fragment.cpp 53522 2012-03-13 18:19:16Z fendrin $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Tomasz Sniatowski <kailoran@gmail.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 #define GETTEXT_DOMAIN "wesnoth-editor"
00016 
00017 #include "map_fragment.hpp"
00018 
00019 #include "foreach.hpp"
00020 #include "util.hpp"
00021 
00022 namespace editor {
00023 
00024 map_fragment::map_fragment()
00025     : items_()
00026     , area_()
00027 {
00028 }
00029 
00030 map_fragment::map_fragment(const gamemap& map, const std::set<map_location>& area)
00031     : items_()
00032     , area_()
00033 {
00034     add_tiles(map, area);
00035 }
00036 
00037 void map_fragment::add_tile(const gamemap& map, const map_location& loc)
00038 {
00039     if (area_.find(loc) == area_.end()) {
00040         items_.push_back(tile_info(map, loc));
00041         area_.insert(loc);
00042     }
00043 }
00044 
00045 void map_fragment::add_tiles(const gamemap& map, const std::set<map_location>& locs)
00046 {
00047     foreach (const map_location& loc, locs) {
00048         add_tile(map, loc);
00049     }
00050 }
00051 
00052 std::set<map_location> map_fragment::get_area() const
00053 {
00054     return area_;
00055 }
00056 
00057 std::set<map_location> map_fragment::get_offset_area(const map_location& loc) const
00058 {
00059     std::set<map_location> result;
00060     foreach (const tile_info& i, items_) {
00061         result.insert(i.offset.vector_sum(loc));
00062     }
00063     return result;
00064 }
00065 
00066 void map_fragment::paste_into(gamemap& map, const map_location& loc) const
00067 {
00068     foreach (const tile_info& i, items_) {
00069         map.set_terrain(i.offset.vector_sum(loc), i.terrain);
00070     }
00071 }
00072 
00073 void map_fragment::shift(const map_location& offset)
00074 {
00075     foreach (tile_info& ti, items_) {
00076         ti.offset.vector_sum_assign(offset);
00077     }
00078 }
00079 
00080 map_location map_fragment::center_of_mass() const
00081 {
00082     map_location sum(0, 0);
00083     foreach (const tile_info& ti, items_) {
00084         sum.vector_sum_assign(ti.offset);
00085     }
00086     sum.x /= static_cast<int>(items_.size());
00087     sum.y /= static_cast<int>(items_.size());
00088     return sum;
00089 }
00090 
00091 void map_fragment::center_by_mass()
00092 {
00093     shift(center_of_mass().vector_negation());
00094     area_.clear();
00095     foreach (tile_info& ti, items_) {
00096         area_.insert(ti.offset);
00097     }
00098 }
00099 
00100 void map_fragment::rotate_60_cw()
00101 {
00102     area_.clear();
00103     foreach (tile_info& ti, items_) {
00104         map_location l(0,0);
00105         int x = ti.offset.x;
00106         int y = ti.offset.y;
00107         // rotate the X-Y axes to SOUTH/SOUTH_EAST - SOUTH_WEST axes
00108         // but if x is odd, simply using x/2 + x/2 will lack a step
00109         l = l.get_direction(map_location::SOUTH, (x+is_odd(x))/2);
00110         l = l.get_direction(map_location::SOUTH_EAST, (x-is_odd(x))/2 );
00111         l = l.get_direction(map_location::SOUTH_WEST, y);
00112         ti.offset = l;
00113         area_.insert(l);
00114     }
00115     if (get_area().size() != items_.size()) {
00116         throw editor_exception("Map fragment rotation resulted in duplicate entries");
00117     }
00118 }
00119 
00120 void map_fragment::rotate_60_ccw()
00121 {
00122     area_.clear();
00123     foreach (tile_info& ti, items_) {
00124         map_location l(0,0);
00125         int x = ti.offset.x;
00126         int y = ti.offset.y;
00127         // rotate the X-Y axes to NORTH/NORTH_EAST - SOUTH_EAST axes'
00128         // reverse of what the cw rotation does
00129         l = l.get_direction(map_location::NORTH, (x-is_odd(x))/2);
00130         l = l.get_direction(map_location::NORTH_EAST, (x+is_odd(x))/2 );
00131         l = l.get_direction(map_location::SOUTH_EAST, y);
00132         ti.offset = l;
00133         area_.insert(l);
00134     }
00135     if (get_area().size() != items_.size()) {
00136         throw editor_exception("Map fragment rotation resulted in duplicate entries");
00137     }
00138 }
00139 
00140 void map_fragment::flip_horizontal()
00141 {
00142     foreach (tile_info& ti, items_) {
00143         ti.offset.x = -ti.offset.x;
00144     }
00145     center_by_mass();
00146 }
00147 
00148 void map_fragment::flip_vertical()
00149 {
00150     foreach (tile_info& ti, items_) {
00151         ti.offset.y = -ti.offset.y;
00152         if (ti.offset.x % 2) {
00153             ti.offset.y--;
00154         }
00155     }
00156     center_by_mass();
00157 }
00158 
00159 
00160 bool map_fragment::empty() const
00161 {
00162     return items_.empty();
00163 }
00164 
00165 std::string map_fragment::dump() const
00166 {
00167     std::stringstream ss;
00168     ss << "MF: ";
00169     foreach (const tile_info& ti, items_) {
00170         ss << "(" << ti.offset << ")";
00171     }
00172     ss << " -- ";
00173     foreach (const map_location& loc, area_) {
00174         ss << "(" << loc << ")";
00175     }
00176     return ss.str();
00177 }
00178 
00179 } //end namespace editor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:50 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs