The Battle for Wesnoth  1.15.7+dev
display_context.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
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 #include "display_context.hpp"
16 
17 #include "map/map.hpp"
18 #include "map/location.hpp"
19 #include "team.hpp"
20 #include "units/unit.hpp"
21 #include "units/map.hpp"
22 
23 const team& display_context::get_team(int side) const
24 {
25  return teams().at(side - 1);
26 }
27 
28 bool display_context::would_be_discovered(const map_location & loc, int side_num, bool see_all)
29 {
31  get_adjacent_tiles(loc,adjs.data());
32 
33  for (const map_location &u_loc : adjs)
34  {
35  unit_map::const_iterator u_it = units().find(u_loc);
36  if (!u_it.valid()) {
37  continue;
38  }
39  const unit & u = *u_it;
40  if (get_team(side_num).is_enemy(u.side()) && !u.incapacitated()) {
41  // Enemy spotted in adjacent tiles, check if we can see him.
42  // Watch out to call invisible with see_all=true to avoid infinite recursive calls!
43  if(see_all) {
44  return true;
45  } else if (!get_team(side_num).fogged(u_loc)
46  && !u.invisible(u_loc, true)) {
47  return true;
48  }
49  }
50  }
51  return false;
52 }
53 
54 const unit * display_context::get_visible_unit(const map_location & loc, const team &current_team, bool see_all) const
55 {
56  if (!map().on_board(loc)) return nullptr;
57  const unit_map::const_iterator u = units().find(loc);
58  if (!u.valid() || !u->is_visible_to_team(current_team, see_all)) {
59  return nullptr;
60  }
61  return &*u;
62 }
63 
64 unit_const_ptr display_context::get_visible_unit_shared_ptr(const map_location & loc, const team &current_team, bool see_all) const
65 {
66  if (!map().on_board(loc)) return nullptr;
67  const unit_map::const_iterator u = units().find(loc);
68  if (!u.valid() || !u->is_visible_to_team(current_team, see_all)) {
69  return unit_const_ptr();
70  }
71  return u.get_shared_ptr();
72 }
73 
75 {
76  if(!u.attacks_left() && u.movement_left()==0)
77  return false;
78 
79  // Units with goto commands that have already done their gotos this turn
80  // (i.e. don't have full movement left) should have red globes.
81  if(u.has_moved() && u.has_goto()) {
82  return false;
83  }
84 
85  const team &current_team = get_team(u.side());
86 
88  get_adjacent_tiles(u.get_location(), locs.data());
89  for(unsigned n = 0; n < locs.size(); ++n) {
90  if (map().on_board(locs[n])) {
91  const unit_map::const_iterator i = units().find(locs[n]);
92  if (i.valid() && !i->incapacitated() &&
93  current_team.is_enemy(i->side())) {
94  return true;
95  }
96 
97  if (u.movement_cost(map()[locs[n]]) <= u.movement_left()) {
98  return true;
99  }
100  }
101  }
102 
103  // This should probably check if the unit can teleport too
104 
105  return false;
106 }
107 
109 {
110  if(u.user_end_turn())
111  return orb_status::moved;
112  if(u.movement_left() == u.total_movement() && u.attacks_left() == u.max_attacks())
113  return orb_status::unmoved;
114  if(unit_can_move(u))
115  return orb_status::partial;
116  return orb_status::moved;
117 }
118 
120 {
121  const std::vector<team> & t = teams();
122  for(std::size_t i = 0; i != t.size(); ++i) {
123  if(t[i].owns_village(loc))
124  return i + 1;
125  }
126  return 0;
127 }
128 
129 /**
130  * Determine if we are an observer, by checking if every team is not locally controlled
131  */
133 {
134  for (const team &t : teams()) {
135  if (t.is_local())
136  return false;
137  }
138 
139  return true;
140 }
141 
142 /// Static info getters previously declared at global scope in unit.?pp
143 
144 int display_context::side_units(int side) const
145 {
146  int res = 0;
147  for (const unit &u : units()) {
148  if (u.side() == side) ++res;
149  }
150  return res;
151 }
152 
154 {
155  int res = 0;
156  for (const unit &u : units()) {
157  if (u.side() == side) res += u.cost();
158  }
159  return res;
160 }
161 
162 int display_context::side_upkeep(int side) const
163 {
164  int res = 0;
165  for (const unit &u : units()) {
166  if (u.side() == side) res += u.upkeep();
167  }
168  return res;
169 }
170 
172  : side(tm.side())
173  , units(dc.side_units(side))
174  , upkeep(dc.side_upkeep(side))
175  , expenses(std::max<int>(0, upkeep - tm.support()))
176  , net_income(tm.total_income() - expenses)
177 {
178 }
int village_owner(const map_location &loc) const
Given the location of a village, will return the 1-based number of the team that currently owns it...
int attacks_left() const
Gets the remaining number of attacks this unit can perform this turn.
Definition: unit.hpp:992
const team & get_team(int side) const
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.cpp:474
This class represents a single unit of a specific type.
Definition: unit.hpp:129
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit&#39;s movement cost on a particular terrain.
Definition: unit.hpp:1426
const unit * get_visible_unit(const map_location &loc, const team &current_team, bool see_all=false) const
STL namespace.
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:377
-file sdl_utils.hpp
bool unit_can_move(const unit &u) const
True if, and only if, at least one of the following is true:
orb_status
Corresponds to the colored orbs displayed above units&#39; hp-bar and xp-bar.
Definition: orb_status.hpp:25
virtual const gamemap & map() const =0
The unit still has full movement and all attacks available.
team_data(const display_context &dc, const team &tm)
std::shared_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:29
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:44
int side_upkeep(int side_num) const
bool is_enemy(int n) const
Definition: team.hpp:243
virtual const unit_map & units() const =0
std::array< map_location, 6 > adjacent_loc_array_t
Definition: location.hpp:170
Encapsulates the map of the game.
Definition: location.hpp:42
int side_units_cost(int side_num) const
Returns the total cost of units of side side_num.
bool user_end_turn() const
Check whether the user ended their turn.
Definition: unit.hpp:793
unit_iterator find(std::size_t id)
Definition: map.cpp:311
bool invisible(const map_location &loc, bool see_all=true) const
Definition: unit.cpp:2432
bool has_moved() const
Checks if this unit has moved.
Definition: unit.hpp:1298
pointer get_shared_ptr() const
This is exactly the same as operator-> but it&#39;s slightly more readable, and can replace &*iter syntax...
Definition: map.hpp:220
std::size_t i
Definition: function.cpp:933
virtual const std::vector< team > & teams() const =0
bool is_observer() const
Check if we are an observer in this game.
bool has_goto() const
Gets whether this unit has a multi-turn destination set.
Definition: unit.hpp:1368
All moves and possible attacks have been done.
unit_const_ptr get_visible_unit_shared_ptr(const map_location &loc, const team &current_team, bool see_all=false) const
double t
Definition: astarsearch.cpp:64
orb_status unit_orb_status(const unit &u) const
Returns an enumurated summary of whether this unit can move and/or attack.
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1343
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:904
int total_movement() const
The maximum moves this unit has.
Definition: unit.hpp:1252
bool fogged(const map_location &loc) const
Definition: team.cpp:662
int side() const
The side this unit belongs to.
Definition: unit.hpp:341
int side_units(int side_num) const
Returns the number of units of the side side_num.
There are still moves and/or attacks possible, but the unit doesn&#39;t fit in the "unmoved" status...
bool valid() const
Definition: map.hpp:276
static map_location::DIRECTION n
bool would_be_discovered(const map_location &loc, int side_num, bool see_all=true)
Given a location and a side number, indicates whether an invisible unit of that side at that location...
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
Definition: unit.hpp:1268
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
Definition: unit.hpp:976