/* * Copyright 2010-2016 OpenXcom Developers. * * This file is part of OpenXcom. * * OpenXcom is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenXcom is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenXcom. If not, see . */ #include "Target.h" #include "Craft.h" #include "SerializationHelper.h" #include "../fmath.h" #include "../Engine/Language.h" namespace OpenXcom { /** * Initializes a target with blank coordinates. */ Target::Target() : _lon(0.0), _lat(0.0), _id(0) { } /** * Make sure no crafts are chasing this target. */ Target::~Target() { std::vector followers = getCraftFollowers(); for (std::vector::iterator i = followers.begin(); i != followers.end(); ++i) { (*i)->returnToBase(); } } /** * Loads the target from a YAML file. * @param node YAML node. */ void Target::load(const YAML::Node &node) { _lon = node["lon"].as(_lon); _lat = node["lat"].as(_lat); _id = node["id"].as(_id); if (const YAML::Node &name = node["name"]) { _name = name.as(); } } /** * Saves the target to a YAML file. * @returns YAML node. */ YAML::Node Target::save() const { YAML::Node node; node["lon"] = serializeDouble(_lon); node["lat"] = serializeDouble(_lat); if (_id) node["id"] = _id; if (!_name.empty()) node["name"] = _name; return node; } /** * Saves the target's unique identifiers to a YAML file. * @return YAML node. */ YAML::Node Target::saveId() const { YAML::Node node; node["lon"] = serializeDouble(_lon); node["lat"] = serializeDouble(_lat); node["type"] = getType(); node["id"] = _id; return node; } /** * Returns the longitude coordinate of the target. * @return Longitude in radian. */ double Target::getLongitude() const { return _lon; } /** * Changes the longitude coordinate of the target. * @param lon Longitude in radian. */ void Target::setLongitude(double lon) { _lon = lon; // Keep between 0 and 2xPI while (_lon < 0) _lon += 2 * M_PI; while (_lon >= 2 * M_PI) _lon -= 2 * M_PI; } /** * Returns the latitude coordinate of the target. * @return Latitude in radian. */ double Target::getLatitude() const { return _lat; } /** * Changes the latitude coordinate of the target. * @param lat Latitude in radian. */ void Target::setLatitude(double lat) { _lat = lat; // If you travel past a pole, continue on the other side of the globe. if (_lat < -M_PI/2) { _lat = -M_PI - _lat; setLongitude(_lon + M_PI); } else if (_lat > M_PI/2) { _lat = M_PI - _lat; setLongitude(_lon - M_PI); } } /** * Returns the target's unique ID. * @return Unique ID, 0 if none. */ int Target::getId() const { return _id; } /** * Changes the target's unique ID. * @param id Unique ID. */ void Target::setId(int id) { _id = id; } /** * Returns the target's user-readable name. * If there's no custom name, the language default is used. * @param lang Language to get strings from. * @return Full name. */ std::string Target::getName(Language *lang) const { if (_name.empty()) return getDefaultName(lang); return _name; } /** * Changes the target's custom name. * @param newName New custom name. If set to blank, the language default is used. */ void Target::setName(const std::string &newName) { _name = newName; } /** * Returns the target's unique default name. * @param lang Language to get strings from. * @return Full name. */ std::string Target::getDefaultName(Language *lang) const { return lang->getString(getMarkerName()).arg(_id); } /** * Returns the name on the globe for the target. * @return String ID. */ std::string Target::getMarkerName() const { return getType() + "_"; } /** * Returns the marker ID on the globe for the target. * @return Marker ID. */ int Target::getMarkerId() const { return _id; } /** * Returns the list of targets currently * following this target. * @return Pointer to list of targets. */ std::vector *Target::getFollowers() { return &_followers; } /** * Returns the list of crafts currently * following this target. * @return List of crafts. */ std::vector Target::getCraftFollowers() const { std::vector crafts; for (std::vector::const_iterator i = _followers.begin(); i != _followers.end(); ++i) { Craft *craft = dynamic_cast(*i); if (craft) { crafts.push_back(craft); } } return crafts; } /** * Returns the great circle distance to another * target on the globe. * @param lon Longitude. * @param lat Latitude. * @returns Distance in radian. */ double Target::getDistance(double lon, double lat) const { if (AreSame(lon, _lon) && AreSame(lat, _lat)) return 0.0; return acos(cos(_lat) * cos(lat) * cos(lon - _lon) + sin(_lat) * sin(lat)); } }