54 #define DBG_NG LOG_STREAM(debug, log_engine)
103 : ambusher_(units.
end()),failed_teleport_(units.
end()),seen_enemies_(),seen_friends_(),
unit_(units.
end())
143 team *
t = unsigned(side - 1) < teams.size() ? &teams[side - 1] :
nullptr;
150 bool grants_timebonus =
false;
152 int old_owner_side = 0;
156 int i_side =
i - teams.begin() + 1;
157 if (!t || not_defeated || t->
is_enemy(i_side)) {
158 if(
i->owns_village(loc)) {
159 old_owner_side = i_side;
160 i->lose_village(loc);
162 if (side != i_side && action_timebonus) {
163 grants_timebonus =
true;
168 if (!t)
return false;
170 if(grants_timebonus) {
172 *action_timebonus =
true;
189 class unit_mover :
public boost::noncopyable {
190 typedef std::vector<map_location>::const_iterator route_iterator;
193 unit_mover(
const std::vector<map_location> & route,
194 move_unit_spectator *move_spectator,
195 bool skip_sightings,
bool skip_ally_sightings);
199 bool check_expected_movement();
201 void try_actual_movement(
bool show);
205 void feedback()
const;
208 std::vector<map_location> expected_path()
const
214 size_t steps_travelled()
const
220 bool interrupted(
bool include_end_of_move_events=
true)
const
231 void cache_hidden_units(
const route_iterator &
start,
232 const route_iterator & stop);
234 bool fire_hex_event(
const std::string & event_name,
235 const route_iterator & current,
236 const route_iterator & other);
238 bool is_ai_move()
const {
return spectator_ !=
nullptr; }
240 route_iterator plot_turn(
const route_iterator &
start,
241 const route_iterator & stop);
243 bool post_wml(
const route_iterator & step);
244 bool post_wml() {
return post_wml(
full_end_); }
246 bool pump_sighted(
const route_iterator & from);
250 void reveal_ambusher(
const map_location & hex,
bool update_alert=
true);
253 bool undo_blocked()
const
262 inline void check_for_ambushers(
const map_location & hex);
264 inline bool check_for_obstructing_unit(
const map_location & hex,
267 inline bool do_move(
const route_iterator & step_from,
268 const route_iterator & step_to,
271 inline void handle_fog(
const map_location & hex,
bool new_animation);
272 inline bool is_reasonable_stop(
const map_location & hex)
const;
274 inline void reveal_ambushers();
276 inline void validate_ambushers();
288 const std::vector<map_location> &
route_;
342 unit_mover::unit_mover(
const std::vector<map_location> & route,
343 move_unit_spectator *move_spectator,
344 bool skip_sightings,
bool skip_ally_sightings) :
398 unit_mover::~unit_mover()
417 inline void unit_mover::check_for_ambushers(
const map_location & hex)
424 for (
int i = 0;
i != 6; ++
i )
428 if ( neighbor_it != units.
end() &&
430 neighbor_it->invisible(adjacent[i]) )
447 inline bool unit_mover::check_for_obstructing_unit(
const map_location & hex,
481 inline bool unit_mover::do_move(
const route_iterator & step_from,
482 const route_iterator & step_to,
495 move_it_->anim_comp().invalidate(disp);
499 std::pair<unit_map::iterator, bool> move_result =
501 if ( move_result.second )
505 move_it_->set_facing(step_from->get_relative_dir(*step_to));
509 move_it_->anim_comp().set_standing(
false);
522 return move_result.second;
532 inline void unit_mover::handle_fog(
const map_location & hex,
560 inline bool unit_mover::is_reasonable_stop(
const map_location & hex)
const
580 inline void unit_mover::reveal_ambushers()
588 reveal_ambusher(reveal,
true);
603 inline void unit_mover::validate_ambushers()
609 while ( i != ambushers_.size() ) {
610 if ( units.
count(ambushers_[i]) == 0 )
612 ambushers_.
erase(ambushers_.begin() +
i);
633 void unit_mover::cache_hidden_units(
const route_iterator &
start,
634 const route_iterator & stop)
644 validate_ambushers();
657 if ( start == stop ) {
693 bool unit_mover::fire_hex_event(
const std::string & event_name,
694 const route_iterator & current,
695 const route_iterator & other)
705 valid = post_wml(current);
707 if (
event || !valid )
710 return event || !
valid;
722 unit_mover::route_iterator unit_mover::plot_turn(
const route_iterator & start,
723 const route_iterator & stop)
732 int remaining_moves =
move_it_->movement_left();
738 if ( !
move_it_->get_ability_bool(
"skirmisher", *start) &&
745 route_iterator
end = start + 1;
746 for ( ; end != stop; ++
end )
752 remaining_moves -=
move_it_->movement_cost(map[*end]);
753 if ( remaining_moves < 0 ) {
761 if ( !
move_it_->get_ability_bool(
"skirmisher", *end) &&
768 route_iterator min_end = start ==
begin_ ? start : start + 1;
786 bool unit_mover::post_wml(
const route_iterator & step)
797 current_team_->auto_shroud_updates() );
801 const route_iterator new_limit = plot_turn(step,
expected_end_);
802 cache_hidden_units(step, new_limit);
819 bool unit_mover::pump_sighted(
const route_iterator & from)
824 const bool event =
clearer_.fire_events();
828 valid = post_wml(from);
830 if (
event || !valid )
833 return event || !
valid;
844 const std::string & ambush_string = (*hide.first)[
"alert"].str();
845 if ( !ambush_string.empty() )
846 return ambush_string;
859 void unit_mover::reveal_ambusher(
const map_location & hex,
bool update_alert)
867 if ( ambusher != units.
end() ) {
879 if ( update_alert ) {
910 bool unit_mover::check_expected_movement()
923 void unit_mover::try_actual_movement(
bool show)
925 static const std::string enter_hex_str(
"enter hex");
929 bool obstructed_stop =
false;
947 const route_iterator step_from =
real_end_ - 1;
955 if (
sighted_ && is_reasonable_stop(*step_from) )
962 if ( fire_hex_event(exit_hex_str, step_from,
real_end_) ) {
970 obstructed_stop =
true;
975 bool new_animation = do_move(step_from,
real_end_, animator);
985 fire_hex_event(enter_hex_str,
real_end_, step_from);
1004 if ( !obstructed_stop )
1017 void unit_mover::post_move(undo_list *
undo_stack)
1021 int orig_village_owner = 0;
1022 bool action_time_bonus =
false;
1063 if ( mover_valid ) {
1065 undo_stack->add_move(
1067 action_time_bonus, orig_village_owner,
orig_dir_);
1070 if ( !mover_valid || undo_blocked() ||
1073 undo_stack->clear();
1086 void unit_mover::feedback()
const
1091 bool redraw =
false;
1100 message_prefix +=
" \n";
1106 std::string teleport_string =
_(
"Failed teleport! Exit not empty");
1108 message_prefix +=
" \n";
1120 SDL_Color msg_color;
1123 symbols[
"friendphrase"] =
vngettext(
"Part of 'Units sighted! (...)' sentence^1 friendly",
"$friends friendly",
friend_count_, symbols);
1124 symbols[
"enemyphrase"] =
vngettext(
"Part of 'Units sighted! (...)' sentence^1 enemy",
"$enemies enemy",
enemy_count_, symbols);
1125 message =
vgettext(
"Units sighted! ($friendphrase, $enemyphrase)", symbols);
1137 disp.
announce(message_prefix + message, msg_color);
1138 message_prefix +=
" \n";
1146 if ( !name.empty() ) {
1148 symbols[
"hotkey"] =
name;
1151 message_prefix +=
" \n";
1172 *interrupted =
false;
1175 mover.try_actual_movement(show_move);
1179 (
"stopped_early", mover.stopped_early())
1180 (
"final_hex_x", mover.final_hex().x + 1)
1181 (
"final_hex_y", mover.final_hex().y + 1);
1185 replay::process_error(
"calculated movement destination (x="+ cn[
"final_hex_x"].str() +
" y=" + cn[
"final_hex_y"].str() +
1186 ") didn't match the original destination(x="+ co[
"final_hex_x"].str() +
" y=" + co[
"final_hex_y"].str() +
")\n");
1193 mover.post_move(undo_stack);
1199 *interrupted = mover.interrupted();
1201 return mover.steps_travelled();
1227 bool continued_move,
bool show_move,
1233 if ( steps.size() < 2 || (steps.size() == 2 && steps.front() == steps.back()) ) {
1234 DBG_NG <<
"Ignoring a unit trying to jump on its hex at " <<
1241 const team ¤t_team = (*resources::teams)[
1248 unit_mover mover(steps, move_spectator, continued_move, skip_ally_sighted);
1249 if ( !mover.check_expected_movement() )
1273 bool continued_move,
bool skip_ally_sighted,
bool show_move)
1276 unit_mover mover(steps,
nullptr, continued_move,skip_ally_sighted);
1277 if ( !mover.check_expected_movement() )
play_controller * controller
void invalidate_unit_after_move(const map_location &src, const map_location &dst)
Same as invalidate_unit() if moving the displayed unit.
bool fogged(const map_location &loc) const
Returns true if location (x,y) is covered in fog.
move_unit_spectator *const spectator_
size_t move_unit_and_record(const std::vector< map_location > &steps, undo_list *undo_stack, bool continued_move, bool show_move, bool *interrupted, move_unit_spectator *move_spectator)
Moves a unit across the board.
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
void reset(const unit_map &units)
reset all locations to empty values
Various functions implementing vision (through fog of war and shroud).
void do_final_checkup(bool dont_throw=false)
bool get_village(const map_location &loc, int side, bool *action_timebonus, bool fire_event)
Makes it so the village at the given location is owned by the given side.
size_t count(const map_location &loc) const
std::deque< int > moves_left_
const std::vector< unit_map::const_iterator > & get_seen_friends() const
get the locations of seen friends
bool owns_village(const map_location &loc) const
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
bool is_village(const map_location &loc) const
bool is_enemy(int n) const
bool actor_sighted(const unit &target, const std::vector< int > *cache)
Fires sighted events for the sides that can see target.
static config get_movement(const std::vector< map_location > &steps, bool skip_sighted, bool skip_ally_sighted)
Records a move that follows the provided steps.
unit_map::iterator move_it_
unit_map::const_iterator failed_teleport_
bool fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
int village_owner(const map_location &loc) const
Given the location of a village, will return the 0-based index of the team that currently owns it...
void check_victory()
Checks to see if a side has won.
virtual void draw()
Draws invalidated items.
const SDL_Color NORMAL_COLOR
bool team_is_defeated(const team &t) const
Calculates whether a team is defeated.
void redraw_minimap()
Schedule the minimap to be redrawn.
map_location ambush_stop_
void add_synced_command(const std::string &name, const config &command)
static synced_state get_synced_state()
const std::vector< unit_map::const_iterator > & get_seen_enemies() const
get the locations of seen enemies
std::vector< unit_map::const_iterator > seen_friends_
const SDL_Color GOOD_COLOR
const unit_map::const_iterator & get_failed_teleport() const
get the location of a failed teleport
static std::vector< team > *& teams
static void clear_status_caches()
Clear the unit status cache for all units.
This class stores all the data for a single 'side' (in game nomenclature).
route_iterator expected_end_
bool fog_or_shroud() const
static UNUSEDNOWARN std::string _(const char *str)
bool event_mutated_mid_move_
std::map< std::string, t_string > string_map
static lg::log_domain log_engine("engine")
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
void finish(unit_ptr u, map_location::DIRECTION dir=map_location::NDIRECTIONS)
Finishes the display of movement for the supplied unit.
std::vector< team > * teams
pointer get_shared_ptr() const
const SDL_Color BAD_COLOR
void add_seen_enemy(const unit_map::const_iterator &u)
add the location of new seen enemy
void proceed_to(unit_ptr u, size_t path_index, bool update=false, bool wait=true)
Visually moves a unit from the last hex we drew to the one specified by path_index.
void set_failed_teleport(const unit_map::const_iterator &u)
set the location of a failed teleport
size_t wml_tracking()
This function can be used to detect when no WML/Lua has been executed.
Encapsulates the map of the game.
checkup * checkup_instance
A class to encapsulate the steps of drawing a unit's move.
void wait_for_anims()
Waits for the final animation of the most recent proceed_to() to finish.
void set_ambusher(const unit_map::const_iterator &u)
set the location of an ambusher
static const map_location & null_location()
unit_map::const_iterator ambusher_
game_events::manager * game_events
move_unit_spectator(const unit_map &units)
constructor
void show(CVideo &video, const std::string &window_id, const t_string &message, const tpoint &mouse)
Shows a tip.
Encapsulates the map of the game.
std::vector< unit_map::const_iterator > seen_enemies_
Various functions related to moving units.
static void process_error(const std::string &msg)
void maybe_throw_return_to_play_side()
const route_iterator begin_
std::vector< map_location > ambushers_
map_location blocked_loc_
const unit_map::const_iterator & get_ambusher() const
get the location of an ambusher
size_t move_unit_from_replay(const std::vector< map_location > &steps, undo_list *undo_stack, bool continued_move, bool skip_ally_sighted, bool show_move)
Moves a unit across the board.
bool interrupt_when_ally_sighted()
std::pair< const config *, map_location > unit_ability
The things contained within a unit_ability_list.
Define the game's event mechanism.
void start(unit_ptr u)
Initiates the display of movement for the supplied unit.
std::string ambush_string_
const unit_map::const_iterator & get_unit() const
get new location of moved unit
DIRECTION
Valid directions which can be moved in our hexagonal world.
const bool skip_sighting_
GLdouble GLdouble GLdouble r
std::string get_names(std::string id)
Returns a comma-separated string of hotkey names.
bool fire_event(const tevent event, std::vector< std::pair< twidget *, tevent > > &event_chain, twidget *dispatcher, twidget *widget, F functor)
Helper function for fire_event.
std::pair< unit_iterator, bool > move(const map_location &src, const map_location &dst)
Moves a unit from location src to location dst.
unit_ability_list get_abilities(const std::string &tag_name, const map_location &loc) const
game_events::t_pump & pump()
route_iterator ambush_limit_
GLuint const GLchar * name
virtual const gamemap & map() const
size_t erase(const map_location &l)
Erases the unit at location l, if any.
unit_map::const_iterator unit_
void set_unit(const unit_map::const_iterator &u)
set the iterator to moved unit
Class to store the actions that a player can undo and redo.
void add_seen_friend(const unit_map::const_iterator &u)
add a location of a seen friend
bool find(E event, F functor)
Tests whether an event handler is available.
Various functions that implement the undoing (and redoing) of in-game commands.
void set_action_bonus_count(const int count)
Standard logging facilities (interface).
Container associating units to locations.
GLsizei GLenum GLuint GLuint GLsizei char * message
const bool playing_team_is_viewing_
boost::shared_ptr< wb::manager > whiteboard
route_iterator obstructed_
actions::undo_list * undo_stack
unit_iterator find(size_t id)
virtual bool local_checkup(const config &expected_data, config &real_data)=0
Compares data to the results calculated during the original game.
const route_iterator full_end_
const map_location::DIRECTION orig_dir_
A config object defines a single node in a WML file, with access to child nodes.
int action_bonus_count() const
static size_t move_unit_internal(undo_list *undo_stack, bool show_move, bool *interrupted, unit_mover &mover)
void announce(const std::string &msg, const SDL_Color &color=font::GOOD_COLOR)
Announce a message prominently.
std::vector< int > get_sides_not_seeing(const unit &target)
Returns the sides that cannot currently see target.
const bool skip_ally_sighting_
This module contains various pathfinding functions and utilities.
GLsizei const GLcharARB ** string
Display units performing various actions: moving, attacking, and dying.
bool enemy_zoc(team const ¤t_team, map_location const &loc, team const &viewing_team, bool see_all)
Determines if a given location is in an enemy zone of control.
bool get_village(const map_location &, const int owner_side, game_data *fire_event)
Acquires a village from owner_side. Pointer fire_event should be the game_data for the game if it is ...
static const hotkey_command & get_command_by_command(HOTKEY_COMMAND command)
the execute_command argument was changed from HOTKEY_COMMAND to hotkey_command, to be able to call it...
const std::vector< map_location > & route_
const std::string valid
Little parts of regex templates used to parse Wml annoations.
virtual ~move_unit_spectator()
destructor