1 /* 2 * Copyright 2010-2014 OpenXcom Developers. 3 * 4 * This file is part of OpenXcom. 5 * 6 * OpenXcom is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * OpenXcom is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with OpenXcom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 #ifndef OPENXCOM_RULEREGION_H 20 #define OPENXCOM_RULEREGION_H 21 22 #include <string> 23 #include <vector> 24 #include <yaml-cpp/yaml.h> 25 #include "../fmath.h" 26 #include "../Savegame/WeightedOptions.h" 27 28 namespace OpenXcom 29 { 30 31 /** 32 * Defines a rectangle in polar coordinates. 33 * It is used to define areas for a mission zone. 34 */ 35 struct MissionArea 36 { 37 double lonMin, lonMax, latMin, latMax; 38 39 bool operator== (const MissionArea& ma) const 40 { 41 return AreSame(lonMax, ma.lonMax) && AreSame(lonMin, ma.lonMin) && AreSame(latMax, ma.latMax) && AreSame(latMin, ma.latMin); 42 } 43 }; 44 45 /** 46 * A zone (set of areas) on the globe. 47 */ 48 struct MissionZone 49 { 50 std::vector<MissionArea> areas; 51 swapMissionZone52 void swap(MissionZone &other) 53 { 54 areas.swap(other.areas); 55 } 56 }; 57 58 class City; 59 60 /** 61 * Represents a specific region of the world. 62 * Contains constant info about a region like area 63 * covered and base construction costs. 64 */ 65 class RuleRegion 66 { 67 private: 68 std::string _type; 69 int _cost; 70 std::vector<double> _lonMin, _lonMax, _latMin, _latMax; 71 std::vector<City*> _cities; 72 /// Weighted list of the different mission types for this region. 73 WeightedOptions _missionWeights; 74 /// Weight of this region when selecting regions for alien missions. 75 size_t _regionWeight; 76 /// All the mission zones in this region. 77 std::vector<MissionZone> _missionZones; 78 /// Do missions in the region defined by this string instead. 79 std::string _missionRegion; 80 public: 81 static const int CITY_MISSION_ZONE = 3; 82 static const int ALIEN_BASE_ZONE = 4; 83 /// Creates a blank region ruleset. 84 RuleRegion(const std::string &type); 85 /// Cleans up the region ruleset. 86 ~RuleRegion(); 87 /// Loads the region from YAML. 88 void load(const YAML::Node& node); 89 /// Gets the region's type. 90 std::string getType() const; 91 /// Gets the region's base cost. 92 int getBaseCost() const; 93 /// Checks if a point is inside the region. 94 bool insideRegion(double lon, double lat) const; 95 /// Gets the cities in this region. 96 std::vector<City*> *getCities(); 97 /// Gets the weight of this region for mission selection. 98 size_t getWeight() const; 99 /// Gets the weighted list of missions for this region. getAvailableMissions()100 const WeightedOptions &getAvailableMissions() const { return _missionWeights; } 101 /// Gets the substitute mission region. getMissionRegion()102 const std::string &getMissionRegion() const { return _missionRegion; } 103 /// Gets a random point inside a mission site. 104 std::pair<double, double> getRandomPoint(size_t site) const; 105 /// Gets the maximum longitude. getLonMax()106 const std::vector<double> &getLonMax() const { return _lonMax; } 107 /// Gets the minimum longitude. getLonMin()108 const std::vector<double> &getLonMin() const { return _lonMin; } 109 /// Gets the maximum latitude. getLatMax()110 const std::vector<double> &getLatMax() const { return _latMax; } 111 /// Gets the minimum latitude. getLatMin()112 const std::vector<double> &getLatMin() const { return _latMin; } 113 const std::vector<MissionZone> &getMissionZones() const; 114 }; 115 116 } 117 118 namespace YAML 119 { 120 template<> 121 struct convert<OpenXcom::MissionArea> 122 { 123 static Node encode(const OpenXcom::MissionArea& rhs) 124 { 125 Node node; 126 node.push_back(rhs.lonMin); 127 node.push_back(rhs.lonMax); 128 node.push_back(rhs.latMin); 129 node.push_back(rhs.latMax); 130 return node; 131 } 132 133 static bool decode(const Node& node, OpenXcom::MissionArea& rhs) 134 { 135 if (!node.IsSequence() || node.size() != 4) 136 return false; 137 138 rhs.lonMin = node[0].as<double>(); 139 rhs.lonMax = node[1].as<double>(); 140 rhs.latMin = node[2].as<double>(); 141 rhs.latMax = node[3].as<double>(); 142 return true; 143 } 144 }; 145 146 template<> 147 struct convert<OpenXcom::MissionZone> 148 { 149 static Node encode(const OpenXcom::MissionZone& rhs) 150 { 151 Node node; 152 node = rhs.areas; 153 return node; 154 } 155 156 static bool decode(const Node& node, OpenXcom::MissionZone& rhs) 157 { 158 if (!node.IsSequence()) 159 return false; 160 161 rhs.areas = node.as< std::vector<OpenXcom::MissionArea> >(rhs.areas); 162 return true; 163 } 164 }; 165 } 166 167 #endif 168