Skip to content

Commit

Permalink
add filter_context class, use in unit_filter
Browse files Browse the repository at this point in the history
The filter context is, game_board + tod manager.
game_display can (and now does) implement this interface,
also game_state. This permits both animations and engine
components to use it.
  • Loading branch information
cbeck88 committed Jul 3, 2014
1 parent d803cde commit d86b59f
Show file tree
Hide file tree
Showing 27 changed files with 145 additions and 75 deletions.
5 changes: 3 additions & 2 deletions src/actions/create.cpp
Expand Up @@ -25,6 +25,7 @@

#include "../config.hpp"
#include "../config_assign.hpp"
#include "../filter_context.hpp"
#include "../game_board.hpp"
#include "../game_display.hpp"
#include "../game_events/pump.hpp"
Expand Down Expand Up @@ -434,7 +435,7 @@ namespace { // Helpers for get_recalls()
if ( unit_filter::matches_filter( rfilter,
recall_unit,
map_location::null_location(),
resources::gameboard) )
resources::filter_con) )
{
result.push_back(recall_unit_ptr);
if ( already_added != NULL )
Expand Down Expand Up @@ -537,7 +538,7 @@ namespace { // Helpers for check_recall_location()
if ( !unit_filter::matches_filter(rfilter,
recall_unit,
map_location::null_location(),
resources::gameboard) )
resources::filter_con) )
return RECRUIT_NO_ABLE_LEADER;

// Make sure the unit is on a keep.
Expand Down
4 changes: 2 additions & 2 deletions src/ai/composite/goal.cpp
Expand Up @@ -135,7 +135,7 @@ void target_unit_goal::add_targets(std::back_insert_iterator< std::vector< targe

//find the enemy leaders and explicit targets
BOOST_FOREACH(const unit &u, *resources::units) {
if (unit_filter::matches_filter(vconfig(criteria), u, u.get_location(), resources::gameboard)) {
if (unit_filter::matches_filter(vconfig(criteria), u, u.get_location(), resources::filter_con)) {
LOG_AI_GOAL << "found explicit target unit at ... " << u.get_location() << " with value: " << value() << "\n";
*target_list = target(u.get_location(), value(), target::EXPLICIT);
}
Expand Down Expand Up @@ -264,7 +264,7 @@ void protect_goal::add_targets(std::back_insert_iterator< std::vector< target >
continue;
}
//TODO: we will protect hidden units, by not testing for invisibility to current side
if (unit_filter::matches_filter(vconfig(criteria), u, u.get_location(), resources::gameboard)) {
if (unit_filter::matches_filter(vconfig(criteria), u, u.get_location(), resources::filter_con)) {
DBG_AI_GOAL << "side " << get_side() << ": in " << goal_type << ": " << u.get_location() << " should be protected\n";
items.insert(u.get_location());
}
Expand Down
5 changes: 3 additions & 2 deletions src/ai/recruitment/recruitment.cpp
Expand Up @@ -25,6 +25,7 @@
#include "../manager.hpp"
#include "../../actions/attack.hpp"
#include "../../attack_prediction.hpp"
#include "../../filter_context.hpp"
#include "../../game_board.hpp"
#include "../../game_display.hpp"
#include "../../log.hpp"
Expand Down Expand Up @@ -252,7 +253,7 @@ void recruitment::execute() {
BOOST_FOREACH(const unit_const_ptr & recall, current_team().recall_list()) {
// Check if this leader is allowed to recall this unit.
vconfig filter = vconfig(leader->recall_filter());
if (!unit_filter::matches_filter(filter, *recall, map_location::null_location(), resources::gameboard)) {
if (!unit_filter::matches_filter(filter, *recall, map_location::null_location(), resources::filter_con)) {
continue;
}
data.recruits.insert(recall->type_id());
Expand Down Expand Up @@ -477,7 +478,7 @@ const std::string* recruitment::get_appropriate_recall(const std::string& type,
}
// Check if this leader is allowed to recall this unit.
vconfig filter = vconfig(leader_data.leader->recall_filter());
if (!unit_filter::matches_filter(filter, *recall_unit, map_location::null_location(), resources::gameboard)) {
if (!unit_filter::matches_filter(filter, *recall_unit, map_location::null_location(), resources::filter_con)) {
LOG_AI_RECRUITMENT << "Refused recall because of filter: " << recall_unit->id() << "\n";
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/ai/testing/aspect_attacks.cpp
Expand Up @@ -76,7 +76,7 @@ boost::shared_ptr<attacks_vector> aspect_attacks::analyze_targets() const
std::vector<map_location> unit_locs;
for(unit_map::const_iterator i = units_.begin(); i != units_.end(); ++i) {
if (i->side() == get_side() && i->attacks_left() && !(i->can_recruit() && get_passive_leader())) {
if (!unit_filter::matches_filter(vconfig(filter_own_), *i, i->get_location(), resources::gameboard)) {
if (!unit_filter::matches_filter(vconfig(filter_own_), *i, i->get_location(), resources::filter_con)) {
continue;
}
unit_locs.push_back(i->get_location());
Expand All @@ -99,7 +99,7 @@ boost::shared_ptr<attacks_vector> aspect_attacks::analyze_targets() const
if (current_team().is_enemy(j->side()) && !j->incapacitated() &&
!j->invisible(j->get_location()))
{
if (!unit_filter::matches_filter(vconfig(filter_enemy_), *j, j->get_location(), resources::gameboard)) {
if (!unit_filter::matches_filter(vconfig(filter_enemy_), *j, j->get_location(), resources::filter_con)) {
continue;
}
map_location adjacent[6];
Expand Down
10 changes: 10 additions & 0 deletions src/display.cpp
Expand Up @@ -416,6 +416,16 @@ const time_of_day & display::get_time_of_day(const map_location& /*loc*/) const
return tod;
}

/**
* Display objects don't hold a tod maanger, instead game_display objects do. If the base version of this method is called,
* try to get it from resources and use an assert to check for failure.
*/
const tod_manager & display::get_tod_man() const
{
assert(resources::tod_manager);
return *resources::tod_manager;
}

void display::update_tod() {
const time_of_day& tod = get_time_of_day();
tod_color col = color_adjust_ + tod.color;
Expand Down
4 changes: 3 additions & 1 deletion src/display.hpp
Expand Up @@ -49,6 +49,7 @@ namespace wb {

#include "animated.hpp"
#include "display_context.hpp"
#include "filter_context.hpp"
#include "font.hpp"
#include "image.hpp" //only needed for enums (!)
#include "key.hpp"
Expand All @@ -71,7 +72,7 @@ namespace wb {

class gamemap;

class display
class display : public filter_context
{
public:
display(const display_context * dc, CVideo& video, boost::weak_ptr<wb::manager> wb,
Expand Down Expand Up @@ -164,6 +165,7 @@ class display

void change_display_context(const display_context * dc);
const display_context & get_disp_context() const { return *dc_; }
virtual const tod_manager & get_tod_man() const; //!< This is implemented properly in game_display. The display:: impl could be pure virtual here but we decide not to.

void reset_halo_manager();
void reset_halo_manager(halo::manager & hm);
Expand Down
43 changes: 43 additions & 0 deletions src/filter_context.hpp
@@ -0,0 +1,43 @@
/*
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/

/**
*
* This class is an abstract base class which represents a display context
* (game map, units, and teams) together with a TOD manager. This, plus
* a lua kernel (currently a singleton) is sufficient to evaluate filters.
*
**/

#ifndef FILTER_CONTEXT_HPP_INCLUDED
#define FILTER_CONTEXT_HPP_INCLUDED

#include <vector>

class display_context;
class tod_manager;

class filter_context {
public:
// accessors

virtual const display_context & get_disp_context() const = 0;
virtual const tod_manager & get_tod_man() const = 0;

// Dtor

virtual ~filter_context() {}
};

#endif
2 changes: 1 addition & 1 deletion src/game_board.hpp
Expand Up @@ -60,7 +60,7 @@ class game_board : public display_context {
friend class play_controller;
friend class events::mouse_handler;
friend class events::menu_handler;
friend struct game_state;
friend class game_state;

/**
* Temporary unit move structs:
Expand Down
2 changes: 2 additions & 0 deletions src/game_display.hpp
Expand Up @@ -130,6 +130,8 @@ class game_display : public display

bool has_time_area() const;

const tod_manager & get_tod_man() const { return tod_manager_; } //<! Allows this class to properly implement filter context, used for animations

protected:
/**
* game_display pre_draw does specific things related e.g. to unit rendering
Expand Down
28 changes: 14 additions & 14 deletions src/game_events/action_wml.cpp
Expand Up @@ -406,7 +406,7 @@ namespace { // Support functions
speaker = units->find(event_info.loc2);
} else if(speaker_str != "narrator") {
for(speaker = units->begin(); speaker != units->end(); ++speaker){
if ( unit_filter::matches_filter(cfg,*speaker, resources::gameboard) )
if ( unit_filter::matches_filter(cfg,*speaker, resources::filter_con) )
break;
}
}
Expand Down Expand Up @@ -779,7 +779,7 @@ WML_HANDLER_FUNCTION(heal_unit, event_info, cfg)
std::vector<unit*> healers;
if (!healers_filter.null()) {
BOOST_FOREACH(unit& u, *units) {
if ( unit_filter::matches_filter(healers_filter,u, resources::gameboard) && u.has_ability_type("heals") ) {
if ( unit_filter::matches_filter(healers_filter,u, resources::filter_con) && u.has_ability_type("heals") ) {
healers.push_back(&u);
}
}
Expand All @@ -800,7 +800,7 @@ WML_HANDLER_FUNCTION(heal_unit, event_info, cfg)
u = units->find(event_info.loc1);
if(!u.valid()) return;
}
else if ( !unit_filter::matches_filter(healed_filter,*u, resources::gameboard) ) continue;
else if ( !unit_filter::matches_filter(healed_filter,*u, resources::filter_con) ) continue;

int heal_amount = u->max_hitpoints() - u->hitpoints();
if(amount.blank() || amount == "full") u->set_hitpoints(u->max_hitpoints());
Expand Down Expand Up @@ -859,7 +859,7 @@ WML_HANDLER_FUNCTION(kill, event_info, cfg)
secondary_unit = false;
for(unit_map::const_unit_iterator unit = resources::units->begin();
unit != resources::units->end(); ++unit) {
if ( unit_filter::matches_filter(cfg.child("secondary_unit"), *unit, resources::gameboard) )
if ( unit_filter::matches_filter(cfg.child("secondary_unit"), *unit, resources::filter_con) )
{
killer_loc = entity_location(*unit);
secondary_unit = true;
Expand All @@ -874,7 +874,7 @@ WML_HANDLER_FUNCTION(kill, event_info, cfg)
//Find all the dead units first, because firing events ruins unit_map iteration
std::vector<unit *> dead_men_walking;
BOOST_FOREACH(unit & u, *resources::units){
if ( unit_filter::matches_filter(cfg,u, resources::gameboard) ) {
if ( unit_filter::matches_filter(cfg,u, resources::filter_con) ) {
dead_men_walking.push_back(&u);
}
}
Expand Down Expand Up @@ -948,7 +948,7 @@ WML_HANDLER_FUNCTION(kill, event_info, cfg)
{
for(std::vector<unit_ptr>::iterator j = pi->recall_list().begin(); j != pi->recall_list().end();) { //TODO: This block is really messy, cleanup somehow...
scoped_recall_unit auto_store("this_unit", pi->save_id(), j - pi->recall_list().begin());
if (unit_filter::matches_filter(cfg, *(*j), map_location(), resources::gameboard)) {
if (unit_filter::matches_filter(cfg, *(*j), map_location(), resources::filter_con)) {
j = pi->recall_list().erase(j);
} else {
++j;
Expand Down Expand Up @@ -1416,7 +1416,7 @@ WML_HANDLER_FUNCTION(object, event_info, cfg)
map_location loc;
if(!filter.null()) {
BOOST_FOREACH(const unit &u, *resources::units) {
if ( unit_filter::matches_filter(filter,u, resources::gameboard) ) {
if ( unit_filter::matches_filter(filter,u, resources::filter_con) ) {
loc = u.get_location();
break;
}
Expand All @@ -1431,7 +1431,7 @@ WML_HANDLER_FUNCTION(object, event_info, cfg)

std::string command_type = "then";

if ( u != resources::units->end() && (filter.null() || unit_filter::matches_filter(filter,*u, resources::gameboard)) )
if ( u != resources::units->end() && (filter.null() || unit_filter::matches_filter(filter,*u, resources::filter_con)) )
{
///@deprecated This can be removed (and a proper duration=level implemented) after 1.11.2
/// Don't forget to remove it from wmllint too!
Expand Down Expand Up @@ -1546,7 +1546,7 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg)
for(std::vector<unit_ptr>::iterator u = avail.begin(); u != avail.end(); ++u) {
DBG_NG << "checking unit against filter...\n";
scoped_recall_unit auto_store("this_unit", player_id, u - avail.begin());
if (unit_filter::matches_filter(unit_filter, *(*u), map_location(), resources::gameboard)) {
if (unit_filter::matches_filter(unit_filter, *(*u), map_location(), resources::filter_con)) {
DBG_NG << (*u)->id() << " matched the filter...\n";
const unit_ptr to_recruit = *u;
const unit* pass_check = to_recruit.get();
Expand All @@ -1557,8 +1557,8 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg)
BOOST_FOREACH(unit_map::const_unit_iterator leader, leaders) {
DBG_NG << "...considering " + leader->id() + " as the recalling leader...\n";
map_location loc = cfg_loc;
if ( (leader_filter.null() || unit_filter::matches_filter(leader_filter, *leader, resources::gameboard)) &&
unit_filter::matches_filter(vconfig(leader->recall_filter()), *(*u),map_location(), resources::gameboard) ) {
if ( (leader_filter.null() || unit_filter::matches_filter(leader_filter, *leader, resources::filter_con)) &&
unit_filter::matches_filter(vconfig(leader->recall_filter()), *(*u),map_location(), resources::filter_con) ) {
DBG_NG << "...matched the leader filter and is able to recall the unit.\n";
if(!resources::gameboard->map().on_board(loc))
loc = leader->get_location();
Expand Down Expand Up @@ -1726,7 +1726,7 @@ WML_HANDLER_FUNCTION(role, /*event_info*/, cfg)
}
unit_map::iterator itor;
BOOST_FOREACH(unit &u, *resources::units) {
if ( unit_filter::matches_filter(filter,u, resources::gameboard) ) {
if ( unit_filter::matches_filter(filter,u, resources::filter_con) ) {
u.set_role(cfg["role"]);
found = true;
break;
Expand Down Expand Up @@ -1763,7 +1763,7 @@ WML_HANDLER_FUNCTION(role, /*event_info*/, cfg)
for(size_t i=0; i < pi->recall_list().size(); ++i) {
unit_ptr u = pi->recall_list()[i];
scoped_recall_unit auto_store("this_unit", player_id, i); //TODO: Should this not be inside the if? Explain me.
if (unit_filter::matches_filter(filter, *u, map_location(), resources::gameboard)) {
if (unit_filter::matches_filter(filter, *u, map_location(), resources::filter_con)) {
u->set_role(cfg["role"]);
found=true;
break;
Expand Down Expand Up @@ -2287,7 +2287,7 @@ WML_HANDLER_FUNCTION(teleport, event_info, cfg)
const vconfig & filter = cfg.child("filter");
if(!filter.null()) {
for (u = resources::units->begin(); u != resources::units->end(); ++u){
if ( unit_filter::matches_filter(filter,*u, resources::gameboard) )
if ( unit_filter::matches_filter(filter,*u, resources::filter_con) )
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/game_events/conditional_wml.cpp
Expand Up @@ -76,7 +76,7 @@ namespace { // Support functions
int match_count = 0;
BOOST_FOREACH(const unit &i, *resources::units)
{
if ( i.hitpoints() > 0 && unit_filter::matches_filter(*u,i, resources::gameboard) ) {
if ( i.hitpoints() > 0 && unit_filter::matches_filter(*u,i, resources::filter_con) ) {
++match_count;
if(counts == default_counts) {
// by default a single match is enough, so avoid extra work
Expand All @@ -97,7 +97,7 @@ namespace { // Support functions
break;
}
scoped_recall_unit auto_store("this_unit", team->save_id(), t);
if ( unit_filter::matches_filter(*u,*team->recall_list()[t], resources::gameboard) ) {
if ( unit_filter::matches_filter(*u,*team->recall_list()[t], resources::filter_con) ) {
++match_count;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/game_events/entity_location.cpp
Expand Up @@ -101,7 +101,7 @@ bool entity_location::matches_unit_filter(const unit_map::const_iterator & un_it

// Filter the unit at the filter location (should be the unit's
// location if no special filter location was specified).
return unit_filter::matches_filter(filter, *un_it, filter_loc_, resources::gameboard) &&
return unit_filter::matches_filter(filter, *un_it, filter_loc_, resources::filter_con) &&
matches_unit(un_it);
}

Expand Down
8 changes: 7 additions & 1 deletion src/game_state.hpp
Expand Up @@ -17,6 +17,7 @@

class config;

#include "filter_context.hpp"
#include "game_board.hpp"
#include "game_data.hpp"
#include "tod_manager.hpp"
Expand All @@ -25,7 +26,9 @@ class config;

namespace pathfind { class manager; }

struct game_state {
class game_state : public filter_context
{
public:
const config& level_;
game_data gamedata_;
game_board board_;
Expand All @@ -43,6 +46,9 @@ struct game_state {
void init(int ticks, const config & replay_start);

config to_config() const;

virtual const display_context & get_disp_context() const { return board_; }
virtual const tod_manager & get_tod_man() const { return tod_manager_; }
};

#endif
2 changes: 1 addition & 1 deletion src/pathfind/teleport.cpp
Expand Up @@ -76,7 +76,7 @@ void teleport_group::get_teleport_pair(
vconfig filter(cfg_.child_or_empty("filter"), true);
vconfig source(cfg_.child_or_empty("source"), true);
vconfig target(cfg_.child_or_empty("target"), true);
if (unit_filter::matches_filter(filter, u, loc, resources::gameboard)) {
if (unit_filter::matches_filter(filter, u, loc, resources::filter_con)) {

scoped_xy_unit teleport_unit("teleport_unit", loc.x, loc.y, *resources::units);

Expand Down
3 changes: 2 additions & 1 deletion src/play_controller.cpp
Expand Up @@ -79,6 +79,7 @@ static lg::log_domain log_engine_enemies("engine/enemies");
static void clear_resources()
{
resources::controller = NULL;
resources::filter_con = NULL;
resources::gameboard = NULL;
resources::gamedata = NULL;
resources::persist = NULL;
Expand Down Expand Up @@ -145,7 +146,7 @@ play_controller::play_controller(const config& level, saved_game& state_of_game,
resources::tod_manager = &gamestate_.tod_manager_;
resources::undo_stack = undo_stack_.get();
resources::units = &gamestate_.board_.units_;

resources::filter_con = &gamestate_;

resources::classification = &saved_game_.classification();
resources::mp_settings = &saved_game_.mp_settings();
Expand Down

0 comments on commit d86b59f

Please sign in to comment.