The Battle for Wesnoth  1.17.0-dev
display_context.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2021
3  by Chris Beck <render787@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program 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 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "display_context.hpp"
17 
18 #include "map/map.hpp"
19 #include "map/location.hpp"
20 #include "team.hpp"
21 #include "units/unit.hpp"
22 #include "units/map.hpp"
23 
24 const team& display_context::get_team(int side) const
25 {
26  return teams().at(side - 1);
27 }
28 
29 bool display_context::would_be_discovered(const map_location & loc, int side_num, bool see_all)
30 {
31  for(const map_location& u_loc : get_adjacent_tiles(loc)) {
32  unit_map::const_iterator u_it = units().find(u_loc);
33  if (!u_it.valid()) {
34  continue;
35  }
36  const unit & u = *u_it;
37  if (get_team(side_num).is_enemy(u.side()) && !u.incapacitated()) {
38  // Enemy spotted in adjacent tiles, check if we can see him.
39  // Watch out to call invisible with see_all=true to avoid infinite recursive calls!
40  if(see_all) {
41  return true;
42  } else if (!get_team(side_num).fogged(u_loc)
43  && !u.invisible(u_loc, true)) {
44  return true;
45  }
46  }
47  }
48  return false;
49 }
50 
51 const unit * display_context::get_visible_unit(const map_location & loc, const team &current_team, bool see_all) const
52 {
53  if (!map().on_board(loc)) return nullptr;
54  const unit_map::const_iterator u = units().find(loc);
55  if (!u.valid() || !u->is_visible_to_team(current_team, see_all)) {
56  return nullptr;
57  }
58  return &*u;
59 }
60 
61 unit_const_ptr display_context::get_visible_unit_shared_ptr(const map_location & loc, const team &current_team, bool see_all) const
62 {
63  if (!map().on_board(loc)) return nullptr;
64  const unit_map::const_iterator u = units().find(loc);
65  if (!u.valid() || !u->is_visible_to_team(current_team, see_all)) {
66  return unit_const_ptr();
67  }
68  return u.get_shared_ptr();
69 }
70 
72 {
73  if(!u.attacks_left() && u.movement_left() == 0)
74  return {false, false};
75 
76  // Units with goto commands that have already done their gotos this turn
77  // (i.e. don't have full movement left) should have red globes.
78  if(u.has_moved() && u.has_goto()) {
79  return {false, false};
80  }
81 
82  const team& current_team = get_team(u.side());
83 
84  can_move_result result = {false, false};
85  for(const map_location& adj : get_adjacent_tiles(u.get_location())) {
86  if (map().on_board(adj)) {
87  if(!result.attack_here) {
88  const unit_map::const_iterator i = units().find(adj);
89  if (i.valid() && !i->incapacitated() && current_team.is_enemy(i->side())) {
90  result.attack_here = true;
91  }
92  }
93 
94  if (!result.move && u.movement_cost(map()[adj]) <= u.movement_left()) {
95  result.move = true;
96  }
97  }
98  }
99 
100  // This should probably check if the unit can teleport too
101 
102  return result;
103 }
104 
106 {
107  if(u.user_end_turn())
108  return orb_status::moved;
109  if(u.movement_left() == u.total_movement() && u.attacks_left() == u.max_attacks())
110  return orb_status::unmoved;
111  auto can_move = unit_can_move(u);
112  if(!can_move)
113  return orb_status::moved;
114  if(can_move.move && u.attacks_left() == 0)
115  return orb_status::disengaged;
116  return orb_status::partial;
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:983
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:475
This class represents a single unit of a specific type.
Definition: unit.hpp:121
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit&#39;s movement cost on a particular terrain.
Definition: unit.hpp:1429
const unit * get_visible_unit(const map_location &loc, const team &current_team, bool see_all=false) const
can_move_result unit_can_move(const unit &u) const
Work out what u can do - this does not check which player&#39;s turn is currently active, the result is calculated assuming that the unit&#39;s owner is currently active.
STL namespace.
orb_status
Corresponds to the colored orbs displayed above units&#39; hp-bar and xp-bar.
Definition: orb_status.hpp:24
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:27
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:72
int side_upkeep(int side_num) const
bool is_enemy(int n) const
Definition: team.hpp:255
virtual const unit_map & units() const =0
Encapsulates the map of the game.
Definition: location.hpp:38
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:783
unit_iterator find(std::size_t id)
Definition: map.cpp:310
bool invisible(const map_location &loc, bool see_all=true) const
Definition: unit.cpp:2436
bool has_moved() const
Checks if this unit has moved.
Definition: unit.hpp:1301
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:218
std::size_t i
Definition: function.cpp:967
virtual const std::vector< team > & teams() const =0
bool is_observer() const
Check if we are an observer in this game.
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:385
bool has_goto() const
Gets whether this unit has a multi-turn destination set.
Definition: unit.hpp:1371
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:65
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:1346
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:894
The unit can move but can&#39;t attack, and wouldn&#39;t be able to attack even if it was moved to a hex adja...
int total_movement() const
The maximum moves this unit has.
Definition: unit.hpp:1255
bool fogged(const map_location &loc) const
Definition: team.cpp:661
int side() const
The side this unit belongs to.
Definition: unit.hpp:334
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:274
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:1271
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
Definition: unit.hpp:967