1 /* 2 Copyright (C) 2003 - 2018 by David White <dave@whitevine.net> 3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/ 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY. 11 12 See the COPYING file for more details. 13 */ 14 15 /** 16 * @file 17 * Various functions implementing vision (through fog of war and shroud). 18 */ 19 20 #pragma once 21 22 #include "movetype.hpp" 23 #include "game_events/fwd.hpp" 24 25 struct map_location; 26 class team; 27 class unit; 28 29 #include <cstring> 30 #include <map> 31 #include <set> 32 #include <vector> 33 34 35 namespace actions { 36 class move_unit_spectator; 37 38 /// Class that stores the part of a unit's data that is needed for fog clearing. 39 /// (Used by the undo stack as that cannot rely on a unit sticking around, and 40 /// we do not really need to copy the entire unit.) 41 struct clearer_info { 42 size_t underlying_id; 43 int sight_range; 44 bool slowed; 45 /// costs is always non-null, all of the constructors initialize it 46 std::unique_ptr<movetype::terrain_costs> costs; 47 48 clearer_info(const unit & viewer); 49 clearer_info(const config & cfg); 50 51 void write(config & cfg) const; 52 }; 53 54 /// Class to encapsulate fog/shroud clearing and the resultant sighted events. 55 /// Note: This class uses teams as parameters (instead of sides) since a 56 /// function using this should first check to see if fog/shroud is in use (to 57 /// save processing when it is not), which implies the team is readily available. 58 class shroud_clearer { 59 public: 60 shroud_clearer(const shroud_clearer&) = delete; 61 shroud_clearer& operator=(const shroud_clearer&) = delete; 62 63 shroud_clearer(); 64 ~shroud_clearer(); 65 66 /// Function to be called if units have moved or otherwise changed. 67 /// It can also be called if it is desirable to calculate the cache 68 /// in advance of fog clearing. 69 /// @param[in] new_team The team whose vision will be used. If left as 70 /// nullptr, the cache will be just be cleared (to be 71 /// recalculated later as needed). cache_units(const team * new_team=nullptr)72 void cache_units(const team * new_team=nullptr) { calculate_jamming(new_team); } 73 // cache_units() is currently a near-synonym for calculate_jamming(). The 74 // reason for the two names is so the private function says what it does, 75 // while the public one says why it might be invoked. 76 77 /// Clears shroud (and fog) around the provided location for @a view_team 78 /// based on @a sight_range, @a costs, and @a slowed. 79 bool clear_unit(const map_location &view_loc, team &view_team, 80 size_t viewer_id, int sight_range, bool slowed, 81 const movetype::terrain_costs & costs, 82 const map_location & real_loc, 83 const std::set<map_location>* known_units = nullptr, 84 size_t * enemy_count = nullptr, size_t * friend_count = nullptr, 85 move_unit_spectator * spectator = nullptr, bool instant = true); 86 /// Clears shroud (and fog) around the provided location for @a view_team 87 /// as if @a viewer was standing there. 88 bool clear_unit(const map_location &view_loc, 89 const unit &viewer, team &view_team, 90 const std::set<map_location>* known_units = nullptr, 91 size_t * enemy_count = nullptr, size_t * friend_count = nullptr, 92 move_unit_spectator * spectator = nullptr, bool instant = true); 93 /// Clears shroud (and fog) around the provided location for @a view_team 94 /// as if @a viewer was standing there. Setting @a instant to false 95 /// allows some drawing delays that are used to make movement look better. clear_unit(const map_location & view_loc,const unit & viewer,team & view_team,bool instant)96 bool clear_unit(const map_location &view_loc, const unit &viewer, 97 team &view_team, bool instant) 98 { return clear_unit(view_loc, viewer, view_team, nullptr, nullptr, nullptr, nullptr, instant); } 99 /// Clears shroud (and fog) around the provided location for @a view_team 100 /// as if @a viewer was standing there. 101 bool clear_unit(const map_location &view_loc, team &view_team, 102 const clearer_info &viewer, bool instant); 103 /// Clears shroud (and fog) around the provided location as if @a viewer 104 /// was standing there. 105 bool clear_unit(const map_location &view_loc, const unit &viewer, 106 bool can_delay = false, bool invalidate = true, 107 bool instant = true); 108 109 /// Clears shroud (and fog) at the provided location and its immediate neighbors. 110 bool clear_dest(const map_location &dest, const unit &viewer); 111 112 /// Erases the record of sighted events from earlier fog/shroud clearing. 113 void drop_events(); 114 115 /// Fires the sighted events that were earlier recorded by fog/shroud clearing. 116 game_events::pump_result_t fire_events(); 117 118 /// The invalidations that should occur after invoking clear_unit(). 119 void invalidate_after_clear(); 120 121 private: 122 /// A record of a sighting event. 123 struct sight_data; 124 125 /// Causes this object's "jamming" map to be recalculated. 126 void calculate_jamming(const team * new_team); 127 128 /// Clears shroud from a single location. 129 bool clear_loc(team &tm, const map_location &loc, const map_location &view_loc, 130 const map_location &event_non_loc, size_t viewer_id, 131 bool check_units, size_t &enemy_count, size_t &friend_count, 132 move_unit_spectator * spectator = nullptr); 133 134 /// Convenience wrapper for adding sighting data to the sightings_ vector. 135 inline void record_sighting(const unit & seen, const map_location & seen_loc, 136 size_t sighter_id, const map_location & sighter_loc); 137 138 private: // data 139 std::map<map_location, int> jamming_; 140 std::vector<sight_data> sightings_; 141 /// Keeps track of the team associated with jamming_. 142 const team * view_team_; 143 }; 144 145 146 /// Returns the sides that cannot currently see @a target. 147 std::vector<int> get_sides_not_seeing(const unit & target); 148 /// Fires sighted events for the sides that can see @a target. 149 game_events::pump_result_t actor_sighted(const unit & target, const std::vector<int> * cache = nullptr); 150 151 152 /// Function that recalculates the fog of war. 153 void recalculate_fog(int side); 154 155 /// Function that will clear shroud (and fog) based on current unit positions. 156 bool clear_shroud(int side, bool reset_fog = false, bool fire_events = true); 157 158 159 }//namespace actions 160