add [cancel_action] implements #1427

this adds a new tag [cancel_action], it currently only has an effect in
move actions. It can be used in enter_hex/exit_hex events to abort the
current movement. It can also be used in moveto events where is
cancels possible following attacks (if the user issued a move+attack
action).

This also changes the behaviour of moveto and enter/exit_hex event so
that they now no longer cancel the movement automatically, also
[allow_undo] no longer has an effect on whether the move is cancelled,
it now only allows undoing of the move.
This commit is contained in:
gfgtdf 2017-07-24 00:15:08 +02:00
parent 974f09178c
commit 821e27c34f
15 changed files with 142 additions and 91 deletions

View file

@ -940,3 +940,7 @@ function wesnoth.wml_conditionals.proceed_to_next_scenario(cfg)
return endlevel_data.proceed_to_next_level
end
end
function wesnoth.wml_actions.cancel_action(cfg)
wesnoth.cancel_action()
end

View file

@ -648,7 +648,7 @@ place_recruit_result place_recruit(unit_ptr u, const map_location &recruit_locat
const std::string event_name = is_recall ? "prerecall" : "prerecruit";
LOG_NG << "firing " << event_name << " event\n";
{
std::get<0>(res) |= resources::game_events->pump().fire(event_name, current_loc, recruited_from);
std::get<0>(res) |= std::get<0>(resources::game_events->pump().fire(event_name, current_loc, recruited_from));
}
if ( !validate_recruit_iterator(new_unit_itor, current_loc) )
return std::make_tuple(true, 0, false);
@ -670,7 +670,7 @@ place_recruit_result place_recruit(unit_ptr u, const map_location &recruit_locat
// Village capturing.
if ( resources::gameboard->map().is_village(current_loc) ) {
std::get<1>(res) = resources::gameboard->village_owner(current_loc) + 1;
std::get<0>(res) |= actions::get_village(current_loc, new_unit_itor->side(), &std::get<2>(res));
std::get<0>(res) |= std::get<0>(actions::get_village(current_loc, new_unit_itor->side(), &std::get<2>(res)));
if ( !validate_recruit_iterator(new_unit_itor, current_loc) )
return std::make_tuple(true, 0, false);
}
@ -684,14 +684,14 @@ place_recruit_result place_recruit(unit_ptr u, const map_location &recruit_locat
const std::string event_name = is_recall ? "recall" : "recruit";
LOG_NG << "firing " << event_name << " event\n";
{
std::get<0>(res) |= resources::game_events->pump().fire(event_name, current_loc, recruited_from);
std::get<0>(res) |= std::get<0>(resources::game_events->pump().fire(event_name, current_loc, recruited_from));
}
}
// "sighted" event(s).
std::get<0>(res) |= clearer.fire_events();
std::get<0>(res) |= std::get<0>(clearer.fire_events());
if ( new_unit_itor.valid() )
std::get<0>(res) |= actions::actor_sighted(*new_unit_itor);
std::get<0>(res) |= std::get<0>(actions::actor_sighted(*new_unit_itor));
return res;
}

View file

@ -136,12 +136,12 @@ void move_unit_spectator::set_unit(const unit_map::const_iterator &u)
}
bool get_village(const map_location& loc, int side, bool *action_timebonus, bool fire_event)
game_events::pump_result_t get_village(const map_location& loc, int side, bool *action_timebonus, bool fire_event)
{
std::vector<team> &teams = resources::gameboard->teams();
team *t = unsigned(side - 1) < teams.size() ? &teams[side - 1] : nullptr;
if (t && t->owns_village(loc)) {
return false;
return game_events::pump_result_t();
}
bool not_defeated = t && !resources::gameboard->team_is_defeated(*t);
@ -164,8 +164,10 @@ bool get_village(const map_location& loc, int side, bool *action_timebonus, bool
}
}
if (!t) return false;
if (!t) {
return game_events::pump_result_t();
}
if(grants_timebonus) {
t->set_action_bonus_count(1 + t->action_bonus_count());
*action_timebonus = true;
@ -178,7 +180,7 @@ bool get_village(const map_location& loc, int side, bool *action_timebonus, bool
return t->get_village(loc, old_owner_side, fire_event ? resources::gamedata : nullptr);
}
return false;
return game_events::pump_result_t();
}
@ -222,7 +224,7 @@ namespace { // Private helpers for move_unit()
bool interrupted(bool include_end_of_move_events=true) const
{
return ambushed_ || blocked() || sighted_ || teleport_failed_ ||
(include_end_of_move_events ? event_mutated_ : event_mutated_mid_move_ ) ||
(include_end_of_move_events ? (wml_removed_unit_ || wml_move_aborted_): event_mutated_mid_move_ ) ||
!move_it_.valid();
}
@ -233,7 +235,7 @@ namespace { // Private helpers for move_unit()
void cache_hidden_units(const route_iterator & start,
const route_iterator & stop);
/// Fires the enter_hex or exit_hex event and updates our data as needed.
bool fire_hex_event(const std::string & event_name,
void fire_hex_event(const std::string & event_name,
const route_iterator & current,
const route_iterator & other);
/// AI moves are supposed to not change the "goto" order.
@ -242,8 +244,8 @@ namespace { // Private helpers for move_unit()
route_iterator plot_turn(const route_iterator & start,
const route_iterator & stop);
/// Updates our stored info after a WML event might have changed something.
bool post_wml(const route_iterator & step);
bool post_wml() { return post_wml(full_end_); }
void post_wml(game_events::pump_result_t pump_res, const route_iterator & step);
void post_wml(game_events::pump_result_t pump_res) { return post_wml(pump_res, full_end_); }
/// Fires the sighted events that were raised earlier.
void pump_sighted(const route_iterator & from);
/// Returns the ambush alert (if any) for the given unit.
@ -253,7 +255,7 @@ namespace { // Private helpers for move_unit()
/// Returns whether or not undoing this move should be blocked.
bool undo_blocked() const
{ return ambushed_ || blocked() || event_mutated_ || fog_changed_ ||
{ return ambushed_ || blocked() || wml_removed_unit_ || wml_undo_disabled_ || fog_changed_ ||
teleport_failed_; }
// The remaining private functions are suggested to be inlined because
@ -319,8 +321,10 @@ namespace { // Private helpers for move_unit()
map_location blocked_loc_; // Location of a blocking, enemy, non-ambusher unit.
bool ambushed_;
bool show_ambush_alert_;
bool event_mutated_;
bool event_mutated_mid_move_; // Cache of event_mutated_ from just before the end-of-move handling.
bool wml_removed_unit_;
bool wml_undo_disabled_;
bool wml_move_aborted_;
bool event_mutated_mid_move_; // Cache of wml_removed_unit_ || wml_move_aborted_ from just before the end-of-move handling.
bool fog_changed_;
bool sighted_; // Records if sightings were made that could interrupt movement.
bool sighted_stop_; // Records if sightings were made that did interrupt movement (the same as sighted_ unless movement ended for another reason).
@ -375,7 +379,9 @@ namespace { // Private helpers for move_unit()
blocked_loc_(map_location::null_location()),
ambushed_(false),
show_ambush_alert_(false),
event_mutated_(false),
wml_removed_unit_(false),
wml_undo_disabled_(false),
wml_move_aborted_(false),
event_mutated_mid_move_(false),
fog_changed_(false),
sighted_(false),
@ -718,27 +724,15 @@ namespace { // Private helpers for move_unit()
* @param[in] current The currently occupied hex.
* @param[in] other The secondary hex to provide to the event.
*
* @return true if this event should interrupt movement.
* (This is also stored in event_mutated_.)
*/
bool unit_mover::fire_hex_event(const std::string & event_name,
void unit_mover::fire_hex_event(const std::string & event_name,
const route_iterator & current,
const route_iterator & other)
{
const size_t track = resources::game_events->pump().wml_tracking();
bool valid = true;
const game_events::entity_location mover(*move_it_, *current);
const bool event = resources::game_events->pump().fire(event_name, mover, *other);
if (track != resources::game_events->pump().wml_tracking()) {
// Some WML fired, so update our status.
valid = post_wml(current);
}
if (event || !valid) {
event_mutated_ = true;
}
return event || !valid;
post_wml(resources::game_events->pump().fire(event_name, mover, *other), current);
}
@ -814,8 +808,11 @@ namespace { // Private helpers for move_unit()
*
* @returns false if continuing is impossible (i.e. we lost the moving unit).
*/
bool unit_mover::post_wml(const route_iterator & step)
void unit_mover::post_wml(game_events::pump_result_t pump_res, const route_iterator & step)
{
wml_move_aborted_ |= std::get<1>(pump_res);
wml_undo_disabled_ |= std::get<0>(pump_res);
// Re-find the moving unit.
move_it_ = resources::gameboard->units().find(*move_loc_);
const bool found = move_it_ != resources::gameboard->units().end();
@ -837,7 +834,7 @@ namespace { // Private helpers for move_unit()
}
}
return found;
wml_removed_unit_ |= !found;
}
@ -846,22 +843,18 @@ namespace { // Private helpers for move_unit()
*
* @param[in] from Points to the hex the sighting unit currently occupies.
*
* @return sets event_mutated_ to true if this event should interrupt movement.
* @return sets event_mutated_ || wml_move_aborted_ to true if this event should interrupt movement.
*/
void unit_mover::pump_sighted(const route_iterator & from)
{
const size_t track = resources::game_events->pump().wml_tracking();
bool valid = true;
const bool non_undoable_events_happened = clearer_.fire_events();
auto pump_res = clearer_.fire_events();
if (track != resources::game_events->pump().wml_tracking()) {
// Some WML fired, so update our status.
valid = post_wml(from);
}
if (non_undoable_events_happened || !valid) {
event_mutated_ = true;
}
post_wml(pump_res, from);
}
}
@ -922,8 +915,14 @@ namespace { // Private helpers for move_unit()
// Make sure this hex is drawn correctly.
disp.invalidate(hex);
// Fire sighted events.
event_mutated_ |= actor_sighted(*ambusher, &sight_cache);
post_wml();
bool wml_undo_blocked = false;
bool wml_move_aborted = false;
std::tie(wml_undo_blocked, wml_move_aborted) = actor_sighted(*ambusher, &sight_cache);
// TODO: should we call post_wml ?
wml_move_aborted_ |= wml_move_aborted;
wml_undo_disabled_ |= wml_undo_blocked;
}
}
@ -931,7 +930,7 @@ namespace { // Private helpers for move_unit()
// Public interface:
/**
* Determines how far along the route the unit can expect to move this turn.
* Determines how far along the route the unit can expect to move this turn.
* This is based solely on data known to the player, and will not plot a move
* that ends on another (known) unit.
* (For example, this prevents a player from plotting a multi-turn move that
@ -981,18 +980,17 @@ namespace { // Private helpers for move_unit()
// See if we can leave *step_from.
// Already accounted for: ambusher
if ( event_mutated_ )
{
if ( wml_removed_unit_ || wml_move_aborted_) {
break;
}
if ( sighted_ && is_reasonable_stop(*step_from) )
{
if ( sighted_ && is_reasonable_stop(*step_from) ) {
sighted_stop_ = true;
break;
}
// Already accounted for: ZoC
// Already accounted for: movement cost
if ( fire_hex_event(exit_hex_str, step_from, real_end_) ) {
fire_hex_event(exit_hex_str, step_from, real_end_);
if (wml_removed_unit_ || wml_move_aborted_) {
break;
}
if ( real_end_ == obstructed_ ) {
@ -1011,7 +1009,7 @@ namespace { // Private helpers for move_unit()
// Fire the events for this step.
// (These return values are not checked since real_end_ still
// needs to be incremented. The event_mutated_ check will break
// needs to be incremented. The wml_move_aborted_ check will break
// us out of the loop if needed.)
fire_hex_event(enter_hex_str, real_end_, step_from);
// Sighted events only fire if we could stop due to sighting.
@ -1026,7 +1024,14 @@ namespace { // Private helpers for move_unit()
// Finish animating.
animator.finish(move_it_.get_shared_ptr());
// Check for the moving unit being seen.
event_mutated_ |= actor_sighted(*move_it_, &not_seeing);
bool wml_undo_blocked = false;
bool wml_move_aborted = false;
std::tie(wml_undo_blocked, wml_move_aborted) = actor_sighted(*move_it_, &not_seeing);
// TODO: should we call post_wml ?
wml_move_aborted_ |= wml_move_aborted;
wml_undo_disabled_ |= wml_undo_blocked;
}
}//if
@ -1039,7 +1044,7 @@ namespace { // Private helpers for move_unit()
teleport_failed_ = teleport_failed_ && obstructed_stop;
// event_mutated_ does not get unset, regardless of other reasons
// for stopping, but we do save its current value.
event_mutated_mid_move_ = event_mutated_;
event_mutated_mid_move_ = wml_removed_unit_ || wml_move_aborted_;
}
@ -1080,15 +1085,13 @@ namespace { // Private helpers for move_unit()
if ( orig_village_owner != current_side_) {
// Captured. Zap movement and take over the village.
move_it_->set_movement(0, true);
event_mutated_ |= get_village(final_loc, current_side_, &action_time_bonus);
post_wml();
post_wml(get_village(final_loc, current_side_, &action_time_bonus));
}
}
}
// Finally, the moveto event.
event_mutated_ |= resources::game_events->pump().fire("moveto", final_loc, *begin_);
post_wml();
post_wml(resources::game_events->pump().fire("moveto", final_loc, *begin_));
// Record keeping.
if (spectator_) {

View file

@ -24,6 +24,7 @@ class replay;
class unit;
#include "units/map.hpp"
#include "game_events/fwd.hpp"
#include <vector>
@ -96,7 +97,7 @@ private:
* Returns true if getting the village triggered a mutating event.
* side can be 0 to make teh village uncaptured.
*/
bool get_village(const map_location& loc, int side, bool *time_bonus = nullptr, bool fire_event = true);
game_events::pump_result_t get_village(const map_location& loc, int side, bool *time_bonus = nullptr, bool fire_event = true);
/// Moves a unit across the board.
/// And enters the synced context.

View file

@ -487,7 +487,7 @@ bool undo_list::apply_shroud_changes() const
disp.draw();
// Fire sighted events
if ( clearer.fire_events() ) {
if ( std::get<0>(clearer.fire_events() )) {
// Fix up the display in case WML changed stuff.
clear_shroud(side_);
disp.invalidate_unit();

View file

@ -543,13 +543,13 @@ void shroud_clearer::drop_events()
* Fires the sighted events that were recorded by earlier fog/shroud clearing.
* @return true if the events have mutated the game state.
*/
bool shroud_clearer::fire_events()
game_events::pump_result_t shroud_clearer::fire_events()
{
const unit_map & units = resources::gameboard->units();
// Possible/probable quick abort.
if ( sightings_.empty() )
return false;
return game_events::pump_result_t();
// In case of exceptions, clear sightings_ before processing events.
std::vector<sight_data> sight_list;
@ -619,7 +619,7 @@ std::vector<int> get_sides_not_seeing(const unit & target)
*
* @returns true if an event has mutated the game state.
*/
bool actor_sighted(const unit & target, const std::vector<int> * cache)
game_events::pump_result_t actor_sighted(const unit & target, const std::vector<int> * cache)
/* Current logic:
* 1) One event is fired per side that can see the target.
* 2) The second unit for the event is one that can see the target, if possible.

View file

@ -20,6 +20,7 @@
#pragma once
#include "movetype.hpp"
#include "game_events/fwd.hpp"
struct map_location;
class team;
@ -111,7 +112,7 @@ public:
void drop_events();
/// Fires the sighted events that were earlier recorded by fog/shroud clearing.
bool fire_events();
game_events::pump_result_t fire_events();
/// The invalidations that should occur after invoking clear_unit().
void invalidate_after_clear();
@ -144,7 +145,7 @@ private: // data
/// Returns the sides that cannot currently see @a target.
std::vector<int> get_sides_not_seeing(const unit & target);
/// Fires sighted events for the sides that can see @a target.
bool actor_sighted(const unit & target, const std::vector<int> * cache = nullptr);
game_events::pump_result_t actor_sighted(const unit & target, const std::vector<int> * cache = nullptr);
/// Function that recalculates the fog of war.

8
src/game_events/fwd.hpp Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include <tuple>
namespace game_events
{
using pump_result_t = std::tuple<bool /* undo_disabled*/, bool /* action_aborted */>;
}

View file

@ -63,10 +63,12 @@ namespace context
struct state
{
bool undo_disabled;
bool action_canceled;
bool skip_messages;
explicit state(bool s, bool m = true)
: undo_disabled(m)
, action_canceled(false)
, skip_messages(s)
{
}
@ -279,14 +281,14 @@ bool wml_event_pump::filter_event(const event_handler& handler, const queued_eve
*
* @returns true if the game state changed.
*/
bool wml_event_pump::process_event(handler_ptr& handler_p, const queued_event& ev)
void wml_event_pump::process_event(handler_ptr& handler_p, const queued_event& ev)
{
DBG_EH << "processing event " << ev.name << " with id=" << ev.id << "\n";
// We currently never pass a null pointer to this function, but to
// guard against future modifications:
if(!handler_p) {
return false;
return;
}
unit_map& units = resources::gameboard->units();
@ -296,7 +298,7 @@ bool wml_event_pump::process_event(handler_ptr& handler_p, const queued_event& e
scoped_weapon_info second_weapon("second_weapon", ev.data.child("second"));
if(!filter_event(*handler_p, ev)) {
return false;
return;
}
// The event hasn't been filtered out, so execute the handler.
@ -313,8 +315,6 @@ bool wml_event_pump::process_event(handler_ptr& handler_p, const queued_event& e
if(resources::screen != nullptr) {
resources::screen->maybe_rebuild();
}
return undo_disabled();
}
/**
@ -431,8 +431,11 @@ context::scoped::~scoped()
{
assert(contexts_.size() > 1);
bool undo_disabled = contexts_.top().undo_disabled;
bool action_canceled = contexts_.top().action_canceled;
contexts_.pop();
contexts_.top().undo_disabled |= undo_disabled;
contexts_.top().action_canceled |= action_canceled;
}
bool wml_event_pump::undo_disabled()
@ -447,6 +450,19 @@ void wml_event_pump::set_undo_disabled(bool b)
impl_->contexts_.top().undo_disabled = b;
}
bool wml_event_pump::action_canceled()
{
assert(impl_->contexts_.size() > 0);
return impl_->contexts_.top().action_canceled;
}
void wml_event_pump::set_action_canceled()
{
assert(impl_->contexts_.size() > 0);
impl_->contexts_.top().action_canceled = true;
}
bool wml_event_pump::context_skip_messages()
{
assert(impl_->contexts_.size() > 0);
@ -476,14 +492,14 @@ void wml_event_pump::put_wml_message(const std::string& logger, const std::strin
}
}
bool wml_event_pump::fire(
pump_result_t wml_event_pump::fire(
const std::string& event, const entity_location& loc1, const entity_location& loc2, const config& data)
{
raise(event, loc1, loc2, data);
return (*this)();
}
bool wml_event_pump::fire(const std::string& event,
pump_result_t wml_event_pump::fire(const std::string& event,
const std::string& id,
const entity_location& loc1,
const entity_location& loc2,
@ -507,23 +523,23 @@ void wml_event_pump::raise(const std::string& event,
impl_->events_queue.emplace_back(event, id, loc1, loc2, data);
}
bool wml_event_pump::operator()()
pump_result_t wml_event_pump::operator()()
{
// Quick aborts:
if(resources::screen == nullptr) {
return false;
return pump_result_t();
}
assert(resources::lua_kernel != nullptr);
if(impl_->events_queue.empty()) {
DBG_EH << "Processing queued events, but none found.\n";
return false;
return pump_result_t();
}
if(impl_->instance_count >= game_config::max_loop) {
ERR_NG << "game_events pump waiting to process new events because "
<< "recursion level would exceed maximum: " << game_config::max_loop << '\n';
return false;
return pump_result_t();
}
if(!lg::debug().dont_log("event_handler")) {
@ -605,7 +621,7 @@ bool wml_event_pump::operator()()
resources::whiteboard->on_gamestate_change();
}
return undo_disabled();
return std::make_tuple(undo_disabled(), action_canceled());
}
void wml_event_pump::flush_messages()

View file

@ -27,6 +27,7 @@
#pragma once
#include "game_events/fwd.hpp"
#include "game_events/entity_location.hpp"
#include "game_events/handlers.hpp"
#include "game_events/manager.hpp"
@ -82,13 +83,21 @@ public:
/**
* Context: The general environment within which events are processed.
* Returns whether or not we believe WML might have changed something.
* Returns whether or not audoing is impossible due to wml.
*/
bool undo_disabled();
/** Sets whether or not we believe WML might have changed something. */
/** [allow_undo] implementation */
void set_undo_disabled(bool mutated);
/**
* Returns whether or not wml wants to abort the currently executed user action.
*/
bool action_canceled();
/** Sets whether or not wml wants to abort the currently executed user action. */
void set_action_canceled();
/** Returns whether or not we are skipping messages. */
bool context_skip_messages();
@ -106,12 +115,12 @@ public:
*
* Events may have up to two arguments, both of which must be locations.
*/
bool fire(const std::string& event,
pump_result_t 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());
bool fire(const std::string& event,
pump_result_t fire(const std::string& event,
const std::string& id,
const entity_location& loc1 = entity_location::null_entity,
const entity_location& loc2 = entity_location::null_entity,
@ -131,7 +140,7 @@ public:
raise(event, "", loc1, loc2, data);
}
bool operator()();
pump_result_t operator()();
/** Flushes WML messages and errors. */
void flush_messages();
@ -142,7 +151,7 @@ public:
private:
bool filter_event(const event_handler& handler, const queued_event& ev);
bool process_event(handler_ptr& handler_p, const queued_event& ev);
void process_event(handler_ptr& handler_p, const queued_event& ev);
void fill_wml_messages_map(std::map<std::string, int>& msg_map, std::stringstream& source);

View file

@ -712,10 +712,10 @@ int game_lua_kernel::intf_fire_event(lua_State *L, const bool by_id)
bool b = false;
if (by_id) {
b = play_controller_.pump().fire("", m, l1, l2, data);
b = std::get<0>(play_controller_.pump().fire("", m, l1, l2, data));
}
else {
b = play_controller_.pump().fire(m, l1, l2, data);
b = std::get<0>(play_controller_.pump().fire(m, l1, l2, data));
}
lua_pushboolean(L, b);
return 1;
@ -3536,6 +3536,12 @@ int game_lua_kernel::intf_allow_undo(lua_State * L)
return 0;
}
int game_lua_kernel::intf_cancel_action(lua_State*)
{
play_controller_.pump().action_canceled();
return 0;
}
/// Adding new time_areas dynamically with Standard Location Filters.
int game_lua_kernel::intf_add_time_area(lua_State * L)
{
@ -3997,6 +4003,7 @@ game_lua_kernel::game_lua_kernel(game_state & gs, play_controller & pc, reports
{ "allow_end_turn", &dispatch<&game_lua_kernel::intf_allow_end_turn > },
{ "allow_undo", &dispatch<&game_lua_kernel::intf_allow_undo > },
{ "append_ai", &intf_append_ai },
{ "cancel_action", &dispatch<&game_lua_kernel::intf_cancel_action > },
{ "clear_menu_item", &dispatch<&game_lua_kernel::intf_clear_menu_item > },
{ "clear_messages", &dispatch<&game_lua_kernel::intf_clear_messages > },
{ "color_adjust", &dispatch<&game_lua_kernel::intf_color_adjust > },

View file

@ -71,6 +71,7 @@ class game_lua_kernel : public lua_kernel_base
// Private lua callbacks
int intf_allow_end_turn(lua_State *);
int intf_allow_undo(lua_State *);
int intf_cancel_action(lua_State *);
int intf_add_time_area(lua_State *);
int intf_remove_time_area(lua_State *);
int intf_animate_unit(lua_State *);

View file

@ -327,9 +327,9 @@ SYNCED_COMMAND_HANDLER_FUNCTION(fire_event, child, use_undo, /*show*/, /*error_
}
const std::string &event_name = child["raise"];
if (const config &source = child.child("source")) {
undoable = undoable & !resources::game_events->pump().fire(event_name, map_location(source, resources::gamedata));
undoable = undoable & !std::get<0>(resources::game_events->pump().fire(event_name, map_location(source, resources::gamedata)));
} else {
undoable = undoable & !resources::game_events->pump().fire(event_name);
undoable = undoable & !std::get<0>(resources::game_events->pump().fire(event_name));
}
// Not clearing the undo stack here casues OOS because we added an entry to the replay but no entry to the undo stack.

View file

@ -374,10 +374,10 @@ void team::write(config& cfg) const
cfg["action_bonus_count"] = action_bonus_count_;
}
bool team::get_village(const map_location& loc, const int owner_side, game_data * gamedata)
game_events::pump_result_t team::get_village(const map_location& loc, const int owner_side, game_data * gamedata)
{
villages_.insert(loc);
bool gamestate_changed = false;
game_events::pump_result_t res;
if(gamedata) {
config::attribute_value& var = gamedata->get_variable("owner_side");
const config::attribute_value old_value = var;
@ -385,7 +385,7 @@ bool team::get_village(const map_location& loc, const int owner_side, game_data
// During team building, game_events pump is not guaranteed to exist yet. (At current revision.) We skip capture events in this case.
if (resources::game_events) {
gamestate_changed = resources::game_events->pump().fire("capture",loc);
res = resources::game_events->pump().fire("capture", loc);
}
if(old_value.blank())
@ -393,7 +393,7 @@ bool team::get_village(const map_location& loc, const int owner_side, game_data
else
var = old_value;
}
return gamestate_changed;
return res;
}
void team::lose_village(const map_location& loc)

View file

@ -16,6 +16,7 @@
#include "color_range.hpp"
#include "game_config.hpp"
#include "game_events/fwd.hpp"
#include "utils/make_enum.hpp"
#include "map/location.hpp"
#include "recall_list_manager.hpp"
@ -176,7 +177,7 @@ public:
void write(config& cfg) const;
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 desired to fire an event -- a "capture" event with owner_side variable scoped in will be fired. For no event, pass it nullptr. Default is the resources::gamedata pointer
game_events::pump_result_t 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 desired to fire an event -- a "capture" event with owner_side variable scoped in will be fired. For no event, pass it nullptr. Default is the resources::gamedata pointer
void lose_village(const map_location&);
void clear_villages() { villages_.clear(); }
const std::set<map_location>& villages() const { return villages_; }