The Battle for Wesnoth  1.15.9+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 {
30  for(const map_location& u_loc : get_adjacent_tiles(loc)) {
31  unit_map::const_iterator u_it = units().find(u_loc);
32  if (!u_it.valid()) {
33  continue;
34  }
35  const unit & u = *u_it;
36  if (get_team(side_num).is_enemy(u.side()) && !u.incapacitated()) {
37  // Enemy spotted in adjacent tiles, check if we can see him.
38  // Watch out to call invisible with see_all=true to avoid infinite recursive calls!
39  if(see_all) {
40  return true;
41  } else if (!get_team(side_num).fogged(u_loc)
42  && !u.invisible(u_loc, true)) {
43  return true;
44  }
45  }
46  }
47  return false;
48 }
49 
50 const unit * display_context::get_visible_unit(const map_location & loc, const team &current_team, bool see_all) const
51 {
52  if (!map().on_board(loc)) return nullptr;
53  const unit_map::const_iterator u = units().find(loc);
54  if (!u.valid() || !u->is_visible_to_team(current_team, see_all)) {
55  return nullptr;
56  }
57  return &*u;
58 }
59 
60 unit_const_ptr display_context::get_visible_unit_shared_ptr(const map_location & loc, const team &current_team, bool see_all) const
61 {
62  if (!map().on_board(loc)) return nullptr;
63  const unit_map::const_iterator u = units().find(loc);
64  if (!u.valid() || !u->is_visible_to_team(current_team, see_all)) {
65  return unit_const_ptr();
66  }
67  return u.get_shared_ptr();
68 }
69 
71 {
72  if(!u.attacks_left() && u.movement_left()==0)
73  return false;
74 
75  // Units with goto commands that have already done their gotos this turn
76  // (i.e. don't have full movement left) should have red globes.
77  if(u.has_moved() && u.has_goto()) {
78  return false;
79  }
80 
81  const team &current_team = get_team(u.side());
82 
83  for(const map_location& adj : get_adjacent_tiles(u.get_location())) {
84  if (map().on_board(adj)) {
85  const unit_map::const_iterator i = units().find(adj);
86  if (i.valid() && !i->incapacitated() &&
87  current_team.is_enemy(i->side())) {
88  return true;
89  }
90 
91  if (u.movement_cost(map()[adj]) <= u.movement_left()) {
92  return true;
93  }
94  }
95  }
96 
97  // This should probably check if the unit can teleport too
98 
99  return false;
100 }
101 
103 {
104  if(u.user_end_turn())
105  return orb_status::moved;
106  if(u.movement_left() == u.total_movement() && u.attacks_left() == u.max_attacks())
107  return orb_status::unmoved;
108  if(unit_can_move(u))
109  return orb_status::partial;
110  return orb_status::moved;
111 }
112 
114 {
115  const std::vector<team> & t = teams();
116  for(std::size_t i = 0; i != t.size(); ++i) {
117  if(t[i].owns_village(loc))
118  return i + 1;
119  }
120  return 0;
121 }
122 
123 /**
124  * Determine if we are an observer, by checking if every team is not locally controlled
125  */
127 {
128  for (const team &t : teams()) {
129  if (t.is_local())
130  return false;
131  }
132 
133  return true;
134 }
135 
136 // Static info getters previously declared at global scope in unit.?pp
137 
138 int display_context::side_units(int side) const
139 {
140  int res = 0;
141  for (const unit &u : units()) {
142  if (u.side() == side) ++res;
143  }
144  return res;
145 }
146 
148 {
149  int res = 0;
150  for (const unit &u : units()) {
151  if (u.side() == side) res += u.cost();
152  }
153  return res;
154 }
155 
156 int display_context::side_upkeep(int side) const
157 {
158  int res = 0;
159  for (const unit &u : units()) {
160  if (u.side() == side) res += u.upkeep();
161  }
162  return res;
163 }
164 
166  : side(tm.side())
167  , units(dc.side_units(side))
168  , upkeep(dc.side_upkeep(side))
169  , expenses(std::max<int>(0, upkeep - tm.support()))
170  , net_income(tm.total_income() - expenses)
171 {
172 }
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:984
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:119
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit&#39;s movement cost on a particular terrain.
Definition: unit.hpp:1421
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:382
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:23
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:26
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:251
virtual const unit_map & units() const =0
Encapsulates the map of the game.
Definition: location.hpp:37
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:784
unit_iterator find(std::size_t id)
Definition: map.cpp:309
bool invisible(const map_location &loc, bool see_all=true) const
Definition: unit.cpp:2408
bool has_moved() const
Checks if this unit has moved.
Definition: unit.hpp:1293
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:217
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:1363
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:1338
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:895
int total_movement() const
The maximum moves this unit has.
Definition: unit.hpp:1247
bool fogged(const map_location &loc) const
Definition: team.cpp:662
int side() const
The side this unit belongs to.
Definition: unit.hpp:332
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:273
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:1263
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
Definition: unit.hpp:968