Skip to content

Commit

Permalink
Allow adding and removing recruitment jobs (and limits) with [modify_ai]
Browse files Browse the repository at this point in the history
Also some minor syntax simplifications:
- If no [recruit] tag is provided, a default is added (as if with importance=0 and no other attributes)
- [pattern] and [total] tags expand to [recruit] with the attribute of the same name set to yes
  • Loading branch information
CelticMinstrel authored and mattsc committed Mar 22, 2016
1 parent aa791ce commit ef880c8
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 3 deletions.
71 changes: 70 additions & 1 deletion src/ai/recruitment/recruitment.cpp
Expand Up @@ -42,10 +42,11 @@
#include "util.hpp"
#include "variable.hpp"
#include "wml_exception.hpp"
#include "config_assign.hpp"

#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>
#include <math.h>
#include <cmath>

static lg::log_domain log_ai_recruitment("ai/recruitment");
#define LOG_AI_RECRUITMENT LOG_STREAM(info, log_ai_recruitment)
Expand Down Expand Up @@ -1779,5 +1780,73 @@ int recruitment::recruit_situation_change_observer::gamestate_changed() {
void recruitment::recruit_situation_change_observer::reset_gamestate_changed() {
gamestate_changed_ = 0;
}

recruitment_aspect::recruitment_aspect(readonly_context &context, const config &cfg, const std::string &id)
: standard_aspect<config>(context, cfg, id)
{
config parsed_cfg(cfg.has_child("value") ? cfg.child("value") : cfg);
// First, transform simplified tags into [recruit] tags.
BOOST_FOREACH (config pattern, parsed_cfg.child_range("pattern")) {
parsed_cfg["pattern"] = true;
parsed_cfg.add_child("recruit", pattern);
}
parsed_cfg.clear_children("pattern");
BOOST_FOREACH (config total, parsed_cfg.child_range("total")) {
parsed_cfg["total"] = true;
parsed_cfg.add_child("recruit", total);
}
parsed_cfg.clear_children("total");
// Then, if there's no [recruit], add one.
if (!parsed_cfg.has_child("recruit")) {
parsed_cfg.add_child("recruit", config_of("importance", 0));
}
// Finally, populate our lists
BOOST_FOREACH (config job, parsed_cfg.child_range("recruit")) {
create_job(jobs_, job);
}
BOOST_FOREACH (config lim, parsed_cfg.child_range("limit")) {
create_limit(limits_, lim);
}
boost::function2<void, std::vector<boost::shared_ptr<recruit_job> >&, const config&> factory_jobs =
boost::bind(&recruitment_aspect::create_job,*this,_1,_2);
boost::function2<void, std::vector<boost::shared_ptr<recruit_limit> >&, const config&> factory_limits =
boost::bind(&recruitment_aspect::create_limit,*this,_1,_2);
register_vector_property(property_handlers(), "recruit", jobs_, factory_jobs);
register_vector_property(property_handlers(), "limit", limits_, factory_limits);
}

void recruitment_aspect::recalculate() const {
config cfg;
BOOST_FOREACH (const boost::shared_ptr<recruit_job>& job, jobs_) {
cfg.add_child("recruit", job->to_config());
}
BOOST_FOREACH (const boost::shared_ptr<recruit_limit>& lim, limits_) {
cfg.add_child("limit", lim->to_config());
}
*this->value_ = cfg;
this->valid_ = true;
}

void recruitment_aspect::create_job(std::vector<boost::shared_ptr<recruit_job> > &jobs, const config &job) {
boost::shared_ptr<recruit_job> job_ptr(new recruit_job(
utils::split(job["type"]),
job["leader_id"], job["id"],
job["number"].to_int(-1), job["importance"].to_int(1),
job["total"].to_bool(false),
job["blocker"].to_bool(true),
job["pattern"].to_bool(true)
));
jobs.push_back(job_ptr);
}

void recruitment_aspect::create_limit(std::vector<boost::shared_ptr<recruit_limit> > &limits, const config &lim) {
boost::shared_ptr<recruit_limit> lim_ptr(new recruit_limit(
utils::split(lim["type"]),
lim["id"],
lim["max"].to_int(0)
));
limits.push_back(lim_ptr);
}

} // namespace default_recruitment
} // namespace ai
57 changes: 57 additions & 0 deletions src/ai/recruitment/recruitment.hpp
Expand Up @@ -21,6 +21,7 @@
#ifndef AI_DEFAULT_RECRUITMENT_HPP_INCLUDED
#define AI_DEFAULT_RECRUITMENT_HPP_INCLUDED

#include "ai/composite/aspect.hpp"
#include "ai/composite/rca.hpp"
#include "units/unit.hpp"
#include "units/map.hpp"
Expand Down Expand Up @@ -113,6 +114,62 @@ struct cached_combat_value {
}
};

struct recruit_job : public component {
std::vector<std::string> types;
std::string leader, id;
int number, importance;
bool total, pattern, blocker;
recruit_job(std::vector<std::string> t, std::string L, std::string id, int n, int i, bool s, bool p, bool b)
: types(t), leader(L), id(id)
, number(n), importance(i)
, total(s), pattern(p), blocker(b)
{}
config to_config() const {
config cfg;
cfg["number"] = number;
cfg["importance"] = importance;
cfg["total"] = total;
cfg["pattern"] = pattern;
cfg["blocker"] = blocker;
cfg["leader_id"] = leader;
cfg["id"] = id;
cfg["type"] = utils::join(types);
return cfg;
}
std::string get_id() const {return id;};
std::string get_name() const {return "recruit_job";};
std::string get_engine() const {return "cpp";};
};

struct recruit_limit : public component {
std::vector<std::string> types;
std::string id;
int limit;
recruit_limit(std::vector<std::string> t, std::string id, int lim)
: types(t), id(id), limit(lim)
{}
config to_config() const {
config cfg;
cfg["max"] = limit;
cfg["id"] = id;
cfg["type"] = utils::join(types);
return cfg;
}
std::string get_id() const {return id;};
std::string get_name() const {return "recruit_limit";};
std::string get_engine() const {return "cpp";};
};

class recruitment_aspect : public standard_aspect<config> {
std::vector<boost::shared_ptr<recruit_job> > jobs_;
std::vector<boost::shared_ptr<recruit_limit> > limits_;
public:
recruitment_aspect(readonly_context &context, const config &cfg, const std::string &id);
void recalculate() const;
void create_job(std::vector<boost::shared_ptr<recruit_job> > &jobs, const config &job);
void create_limit(std::vector<boost::shared_ptr<recruit_limit> > &limits, const config &lim);
};

typedef std::map<std::string, std::set<cached_combat_value> > table_row;
typedef std::map<std::string, table_row> cache_table;

Expand Down
4 changes: 2 additions & 2 deletions src/ai/registry.cpp
Expand Up @@ -344,7 +344,7 @@ static register_aspect_factory< standard_aspect<bool> >
static register_aspect_factory< standard_aspect<double> >
recruitment_diversity__standard_aspect_factory("recruitment_diversity*standard_aspect");

static register_aspect_factory< standard_aspect<config> >
static register_aspect_factory< default_recruitment::recruitment_aspect >
recruitment_instructions__standard_aspect_factory("recruitment_instructions*standard_aspect");

static register_aspect_factory< standard_aspect< std::vector<std::string> > >
Expand Down Expand Up @@ -422,7 +422,7 @@ static register_aspect_factory< standard_aspect<bool> >
static register_aspect_factory< standard_aspect<double> >
recruitment_diversity__standard_aspect_factory2("recruitment_diversity*");

static register_aspect_factory< standard_aspect<config> >
static register_aspect_factory< default_recruitment::recruitment_aspect >
recruitment_instructions__standard_aspect_factory2("recruitment_instructions*");

static register_aspect_factory< standard_aspect< std::vector<std::string> > >
Expand Down

0 comments on commit ef880c8

Please sign in to comment.