Skip to content

Commit

Permalink
Properly port [modify_side] to Lua
Browse files Browse the repository at this point in the history
  • Loading branch information
CelticMinstrel committed Aug 24, 2016
1 parent e821e50 commit aab32a5
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 229 deletions.
19 changes: 18 additions & 1 deletion changelog
Expand Up @@ -71,7 +71,24 @@ Version 1.13.5+dev:
present in the wesnoth.wml_conditionals table. This means they can be
directly called, extended with new features, or even overridden with custom
implementations.
* New recall_filter field in unit proxy returns the [filter_recall] config
* New recall_filter field in unit proxy returns the [filter_recall] config.
* New wesnoth.set_team_id function can change flag, color, or both; it automatically
updates cached flag info for you (but you may still need to redraw to see it).
* The wesnoth.place_shroud and wesnoth.clear_shroud functions can alter shroud data
for a single side. They accept a list of locations, a shroud data string, or the
special value "all".
* New Lua API functions for altering AI:
* wesnoth.switch_ai replaces the entire AI with a definition from a file
* wesnoth.append_ai appends AI parameters to the configuation; supports goals,
stages, and simple aspects.
(Aspect tags are not fully parsed; only the id and facet subtags are used.)
* wesnoth.add_ai_component, delete_ai_component, change_ai_component
These do the work of the [modify_ai] tag for a single side.
* Side proxy changes:
* flag and flag_icon are never an empty string
* New mutable keys: suppress_end_turn_confirmation, share_vision
* New read-only keys: share_maps, share_view
* Existing keys made mutable: shroud, fog, flag, flag_icon
* Performance:
* When a heuristic determines that it's probably faster, the game predicts
battle
Expand Down
5 changes: 5 additions & 0 deletions data/lua/backwards-compatibility.lua
Expand Up @@ -10,3 +10,8 @@ local helper = wesnoth.require "lua/helper.lua"
function wesnoth.fire(name, cfg)
wesnoth.wml_actions[name](wesnoth.tovconfig(cfg or {}))
end

-- This is deprecated, as it was an improper port of the [modify_side] WML tag
function wesnoth.modify_side(cfg)
wesnoth.wml_actions.modify_side(cfg)
end
105 changes: 104 additions & 1 deletion data/lua/wml-tags.lua
Expand Up @@ -874,8 +874,111 @@ function wml_actions.label( cfg )
end
end

local side_changes_needing_redraw = {
'shroud', 'fog', 'reset_map', 'reset_view', 'shroud_data',
'share_vision', 'share_maps', 'share_view',
'color', 'flag',
}
function wml_actions.modify_side(cfg)
wesnoth.modify_side(cfg)
local sides = utils.get_sides(cfg)
for i,side in ipairs(sides) do
if cfg.team_name then
side.team_name = cfg.team_name
end
if cfg.user_team_name then
side.user_team_name = cfg.user_team_name
end
if cfg.controller then
side.controller = cfg.controller
end
if cfg.defeat_condition then
side.defeat_condition = cfg.defeat_condition
end
if cfg.recruit then
local recruits = {}
for recruit in utils.split(cfg.recruit) do
table.insert(recruits, recruit)
end
side.recruit = recruits
end
if cfg.village_support then
side.village_support = cfg.village_support
end
if cfg.village_gold then
side.village_gold = cfg.village_gold
end
if cfg.income then
side.base_income = cfg.income
end
if cfg.gold then
side.gold = cfg.gold
end

if cfg.hidden ~= nil then
side.hidden = cfg.hidden
end
if cfg.color or cfg.flag then
wesnoth.set_team_id(side.side, cfg.flag, cfg.color)
end
if cfg.flag_icon then
side.flag_icon = cfg.flag_icon
end
if cfg.suppress_end_turn_confirmation ~= nil then
side.suppress_end_turn_confirmation = cfg.suppress_end_turn_confirmation
end
if cfg.scroll_to_leader ~= nil then
side.scroll_to_leader = cfg.scroll_to_leader
end

if cfg.shroud ~= nil then
side.shroud = cfg.shroud
end
if cfg.reset_maps then
wesnoth.clear_shroud(side.side, "all")
end
if cfg.fog ~= nil then
side.fog = cfg.fog
end
if cfg.reset_view then
wesnoth.add_fog(side.side, {}, true)
end
if cfg.shroud_data then
wesnoth.clear_shroud(side, cfg.shroud_data)
end

if cfg.share_vision then
side.share_vision = cfg.share_vision
end
-- Legacy support
if cfg.share_view ~= nil or cfg.share_maps ~= nil then
if cfg.share_view then
side.share_vision = 'all'
elseif cfg.share_maps then
side.share_vision = 'shroud'
else
side.share_vision = 'none'
end
end

if cfg.switch_ai then
wesnoth.switch_ai(side.side, cfg.switch_ai)
end
local ai = {}
for next_ai in helper.child_range(cfg, "ai") do
table.insert(ai, T.ai(next_ai))
end
if #ai > 0 then
table.insert(ai, T.ai{T.stage{name=empty}})
ai = wesnoth.expand_ai_params(ai)
wesnoth.append_ai(side.side, ai)
end
end
for i,key in ipairs(side_changes_needing_redraw) do
if cfg[key] ~= nil then
wml_actions.redraw{}
return
end
end
end

function wml_actions.open_help(cfg)
Expand Down
24 changes: 16 additions & 8 deletions data/lua/wml-utils.lua
Expand Up @@ -50,19 +50,27 @@ function utils.vwriter.write(self, container)
self.index = self.index + 1
end

function utils.get_sides(cfg, key_name, filter_name)
key_name = key_name or "side"
filter_name = filter_name or "filter_side"
local filter = helper.get_child(cfg, filter_name)
if filter then
if cfg[key_name] then
wesnoth.log('warn', "ignoring duplicate side filter information (inline side=)")
end
return wesnoth.get_sides(filter)
else
return wesnoth.get_sides{side = cfg[key_name]}
end
end

function utils.optional_side_filter(cfg, key_name, filter_name)
local key_name = key_name or "side"
local sides = cfg[key_name]
local filter_name = filter_name or "filter_side"
local filter_side = helper.get_child(cfg, filter_name)
if filter_side then
sides = wesnoth.get_sides(filter_side)
elseif sides then
local dummy_cfg = {side=sides}
sides = wesnoth.get_sides(dummy_cfg)
else
if cfg[key_name] == nil and helper.get_child(cfg, filter_name) == nil then
return true
end
local sides = utils.get_sides(cfg, key_name, filter_name)
for index,side in ipairs(sides) do
if side.controller == "human" then
return true
Expand Down
70 changes: 29 additions & 41 deletions src/ai/manager.cpp
Expand Up @@ -151,33 +151,6 @@ ai_composite& holder::get_ai_ref()
}


void holder::modify_side_ai_config(config cfg)
{
// only handle aspects
// transform ai_parameters to new-style config

configuration::expand_simplified_aspects(this->side_, cfg);
cfg = cfg.child("ai");
//at this point we have a single config which contains [aspect][facet] tags
DBG_AI_MANAGER << "after transforming [modify_side][ai] into new syntax, config contains:"<< std::endl << cfg << std::endl;

// TODO: Also add [goal] tags. And what about [stage] or [engine] tags? (Maybe they're not important.)
if (this->readonly_context_ == nullptr) {
// if not initialized, append that config to the bottom of base cfg
// then, merge aspects with the same id
cfg_.merge_with(cfg);
cfg_.merge_children_by_attribute("aspect","id");
} else {
// else run 'add_facet' command on each [aspect][facet]
for (const config &cfg_a : cfg.child_range("aspect")) {
for (const config &cfg_f : cfg_a.child_range("facet")) {
readonly_context_->add_facet(cfg_a["id"],cfg_f);
}
}
}
}


void holder::modify_ai(const config &cfg)
{
if (!this->ai_) {
Expand Down Expand Up @@ -213,6 +186,27 @@ void holder::modify_ai(const config &cfg)

}

void holder::append_ai(const config& cfg)
{
if(!this->ai_) {
get_ai_ref();
}
for(const config& aspect : cfg.child_range("aspect")) {
const std::string& id = aspect["id"];
for(const config& facet : aspect.child_range("facet")) {
ai_->add_facet(id, facet);
}
}
for(const config& goal : cfg.child_range("goal")) {
ai_->add_goal(goal);
}
for(const config& stage : cfg.child_range("stage")) {
if(stage["name"] != "empty") {
ai_->add_stage(stage);
}
}
}

config holder::to_config() const
{
if (!this->ai_) {
Expand Down Expand Up @@ -708,20 +702,6 @@ void manager::clear_ais()
ai_map_.clear();
}

// =======================================================================
// Work with active AI parameters
// =======================================================================

void manager::modify_active_ai_config_old_for_side ( side_number side, const config::const_child_itors &ai_parameters )
{
config cfgs;
for (const config& cfg : ai_parameters) {
cfgs.add_child("ai", cfg);
}
cfgs.child_or_add("ai").add_child("stage");
get_active_ai_holder_for_side(side).modify_side_ai_config(cfgs);
}


void manager::modify_active_ai_for_side ( side_number side, const config &cfg )
{
Expand All @@ -733,6 +713,14 @@ void manager::modify_active_ai_for_side ( side_number side, const config &cfg )
}


void manager::append_active_ai_for_side(side_number side, const config& cfg)
{
if(!ai_info_) {
return;
}
get_active_ai_holder_for_side(side).append_ai(cfg);
}

std::string manager::get_active_ai_overview_for_side( side_number side)
{
return get_active_ai_holder_for_side(side).get_ai_overview();
Expand Down
21 changes: 10 additions & 11 deletions src/ai/manager.hpp
Expand Up @@ -64,7 +64,9 @@ class holder{
config to_config() const;

void modify_ai(const config& cfg);
void modify_side_ai_config(config cfg);


void append_ai(const config& cfg);


const std::string get_ai_overview();
Expand Down Expand Up @@ -429,26 +431,23 @@ class manager
// SET active AI parameters
// =======================================================================


/**
* Modifies AI parameters for active AI of the given @a side.
* This function is provided for backward-compatibility with [modify_side][ai]...[/ai][/modify_side]
* It can only add new facets to aspects
* This function is a backend for [modify_ai] tag
* @param side side_number (1-based, as in game_info).
* @param ai_parameters AI parameters to be modified.
* @param cfg - content of [modify_ai] tag
*/
static void modify_active_ai_config_old_for_side ( side_number side, const config::const_child_itors &ai_parameters );


static void modify_active_ai_for_side( ai::side_number side, const config &cfg );

/**
* Modifies AI parameters for active AI of the given @a side.
* This function is a backend for [modify_ai] tag
* Appends AI parameters to active AI of the given @a side.
* This function is a backend for [modify_side][ai] tag
* @param side side_number (1-based, as in game_info).
* @param cfg - content of [modify_ai] tag
* @param cfg - content of [modify_side][ai] tag
*/

static void modify_active_ai_for_side( ai::side_number side, const config &cfg );
static void append_active_ai_for_side( ai::side_number side, const config &cfg );

// =======================================================================
// PROXY
Expand Down

0 comments on commit aab32a5

Please sign in to comment.