The Battle for Wesnoth  1.15.13+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, 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, false};
79  }
80 
81  const team& current_team = get_team(u.side());
82 
83  can_move_result result = {false, false};
84  for(const map_location& adj : get_adjacent_tiles(u.get_location())) {
85  if (map().on_board(adj)) {
86  if(!result.attack_here) {
87  const unit_map::const_iterator i = units().find(adj);
88  if (i.valid() && !i->incapacitated() && current_team.is_enemy(i->side())) {
89  result.attack_here = true;
90  }
91  }
92 
93  if (!result.move && u.movement_cost(map()[adj]) <= u.movement_left()) {
94  result.move = true;
95  }
96  }
97  }
98 
99  // This should probably check if the unit can teleport too
100 
101  return result;
102 }
103 
105 {
106  if(u.user_end_turn())
107  return orb_status::moved;
108  if(u.movement_left() == u.total_movement() && u.attacks_left() == u.max_attacks())
109  return orb_status::unmoved;
110  auto can_move = unit_can_move(u);
111  if(!can_move)
112  return orb_status::moved;
113  if(can_move.move && u.attacks_left() == 0)
114  return orb_status::disengaged;
115  return orb_status::partial;
116 }
117 
119 {
120  const std::vector<team> & t = teams();
121  for(std::size_t i = 0; i != t.size(); ++i) {
122  if(t[i].owns_village(loc))
123  return i + 1;
124  }
125  return 0;
126 }
127 
128 /**
129  * Determine if we are an observer, by checking if every team is not locally controlled
130  */
132 {
133  for (const team &t : teams()) {
134  if (t.is_local())
135  return false;
136  }
137 
138  return true;
139 }
140 
141 // Static info getters previously declared at global scope in unit.?pp
142 
143 int display_context::side_units(int side) const
144 {
145  int res = 0;
146  for (const unit &u : units()) {
147  if (u.side() == side) ++res;
148  }
149  return res;
150 }
151 
153 {
154  int res = 0;
155  for (const unit &u : units()) {
156  if (u.side() == side) res += u.cost();
157  }
158  return res;
159 }
160 
161 int display_context::side_upkeep(int side) const
162 {
163  int res = 0;
164  for (const unit &u : units()) {
165  if (u.side() == side) res += u.upkeep();
166  }
167  return res;
168 }
169 
171  : side(tm.side())
172  , units(dc.side_units(side))
173  , upkeep(dc.side_upkeep(side))
174  , expenses(std::max<int>(0, upkeep - tm.support()))
175  , net_income(tm.total_income() - expenses)
176 {
177 }
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:982
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:120
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit&#39;s movement cost on a particular terrain.
Definition: unit.hpp:1428
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: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:782
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:2405
bool has_moved() const
Checks if this unit has moved.
Definition: unit.hpp:1300
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:940
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:380
bool has_goto() const
Gets whether this unit has a multi-turn destination set.
Definition: unit.hpp:1370
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:1345
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:893
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:1254
bool fogged(const map_location &loc) const
Definition: team.cpp:660
int side() const
The side this unit belongs to.
Definition: unit.hpp:333
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:1270
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
Definition: unit.hpp:966