From aab32a5a04cc111d608f41393d417eb640895667 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Thu, 4 Aug 2016 14:26:33 -0400 Subject: [PATCH] Properly port [modify_side] to Lua --- changelog | 19 ++- data/lua/backwards-compatibility.lua | 5 + data/lua/wml-tags.lua | 105 +++++++++++- data/lua/wml-utils.lua | 24 ++- src/ai/manager.cpp | 70 ++++---- src/ai/manager.hpp | 21 ++- src/scripting/game_lua_kernel.cpp | 232 ++++++++------------------- src/scripting/game_lua_kernel.hpp | 2 +- src/scripting/lua_team.cpp | 20 ++- 9 files changed, 269 insertions(+), 229 deletions(-) diff --git a/changelog b/changelog index 52503e4419d5..307433f5b4b8 100644 --- a/changelog +++ b/changelog @@ -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 diff --git a/data/lua/backwards-compatibility.lua b/data/lua/backwards-compatibility.lua index 93036a848436..e9b19cd73efc 100644 --- a/data/lua/backwards-compatibility.lua +++ b/data/lua/backwards-compatibility.lua @@ -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 diff --git a/data/lua/wml-tags.lua b/data/lua/wml-tags.lua index dd17928949ad..96aa11758d27 100644 --- a/data/lua/wml-tags.lua +++ b/data/lua/wml-tags.lua @@ -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) diff --git a/data/lua/wml-utils.lua b/data/lua/wml-utils.lua index aefd766b6dca..2f512e45a29f 100644 --- a/data/lua/wml-utils.lua +++ b/data/lua/wml-utils.lua @@ -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 diff --git a/src/ai/manager.cpp b/src/ai/manager.cpp index 8fea11d52b74..4ecd0728688c 100644 --- a/src/ai/manager.cpp +++ b/src/ai/manager.cpp @@ -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_) { @@ -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_) { @@ -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 ) { @@ -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(); diff --git a/src/ai/manager.hpp b/src/ai/manager.hpp index 39250ac0986a..63962422d7d4 100644 --- a/src/ai/manager.hpp +++ b/src/ai/manager.hpp @@ -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(); @@ -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 diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index b44366f2a384..fa58610aaf26 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -107,6 +107,7 @@ #include "variable.hpp" // for vconfig, etc #include "variable_info.hpp" #include "wml_exception.hpp" +#include "config_assign.hpp" #include "utils/functional.hpp" // for bind_t, bind #include @@ -737,21 +738,29 @@ int game_lua_kernel::intf_set_next_scenario(lua_State *L) int game_lua_kernel::intf_shroud_op(lua_State *L, bool place_shroud) { - vconfig cfg = luaW_checkvconfig(L, 1); - - // Filter the sides. - std::vector sides = get_sides_vector(cfg); - size_t index; - // Filter the locations. - std::set locs; - const terrain_filter filter(cfg, &game_state_); - filter.get_locations(locs, true); + int side_num = luaL_checkinteger(L, 1); - for (const int &side_num : sides) - { - index = side_num - 1; - team &t = teams()[index]; + if(!lua_isstring(L, 2)) { + std::string data = lua_tostring(L, 2); + // Special case - using a shroud_data string, or "all" + team& side = teams()[side_num - 1]; + if(place_shroud) { + side.reshroud(); + } + if(data != "all") { + side.merge_shroud_map_data(data); + } else if(!place_shroud) { + bool was_shrouded = side.uses_shroud(); + side.set_shroud(false); + actions::clear_shroud(side.side()); + side.set_shroud(was_shrouded); + } + return 0; + } else if(lua_istable(L, 2)) { + std::vector locs_v = lua_check>(L, 2); + std::set locs(locs_v.begin(), locs_v.end()); + team &t = teams()[side_num - 1]; for (map_location const &loc : locs) { @@ -761,6 +770,8 @@ int game_lua_kernel::intf_shroud_op(lua_State *L, bool place_shroud) t.clear_shroud(loc); } } + } else { + return luaL_argerror(L, 2, "expected list of locations or shroud data string"); } game_display_->labels().recalculate_shroud(); @@ -2823,6 +2834,28 @@ int game_lua_kernel::intf_match_side(lua_State *L) return 1; } +int game_lua_kernel::intf_set_team_id(lua_State *L) +{ + int team_i = luaL_checkinteger(L, 1) - 1; + std::string flag = luaL_optlstring(L, 2, "", nullptr); + std::string color = luaL_optlstring(L, 3, "", nullptr); + + if(flag.empty() && color.empty()) { + return 0; + } + team& side = teams()[team_i]; + + if(!color.empty()) { + side.set_color(color); + } + if(!flag.empty()) { + side.set_flag(flag); + } + + game_display_->reinit_flags_for_side(team_i); + return 0; +} + int game_lua_kernel::intf_modify_ai_wml(lua_State *L) { vconfig cfg(luaW_checkvconfig(L, 1)); @@ -2836,160 +2869,28 @@ int game_lua_kernel::intf_modify_ai_wml(lua_State *L) return 0; } -int game_lua_kernel::intf_modify_side(lua_State *L) +static int intf_switch_ai(lua_State *L) { - vconfig cfg(luaW_checkvconfig(L, 1)); - - bool invalidate_screen = false; - - std::string team_name = cfg["team_name"]; - std::string user_team_name = cfg["user_team_name"]; - std::string controller = cfg["controller"]; - std::string defeat_condition = cfg["defeat_condition"]; - std::string recruit_str = cfg["recruit"]; - std::string shroud_data = cfg["shroud_data"]; - std::string village_support = cfg["village_support"]; - const config& parsed = cfg.get_parsed_config(); - const config::const_child_itors &ai = parsed.child_range("ai"); - std::string switch_ai = cfg["switch_ai"]; - - std::vector sides = get_sides_vector(cfg); - size_t team_index; - - for(const int &side_num : sides) - { - team_index = side_num - 1; - - team & tm = teams()[team_index]; - - LOG_LUA << "modifying side: " << side_num << "\n"; - if(!team_name.empty()) { - LOG_LUA << "change side's team to team_name '" << team_name << "'\n"; - tm.change_team(team_name, - user_team_name); - } else if(!user_team_name.empty()) { - LOG_LUA << "change side's user_team_name to '" << user_team_name << "'\n"; - tm.change_team(tm.team_name(), - user_team_name); - } - // Modify recruit list (override) - if (!recruit_str.empty()) { - tm.set_recruits(utils::set_split(recruit_str)); - } - // Modify income - config::attribute_value income = cfg["income"]; - if (!income.empty()) { - tm.set_base_income(income.to_int() + game_config::base_income); - } - // Modify total gold - config::attribute_value gold = cfg["gold"]; - if (!gold.empty()) { - tm.set_gold(gold); - } - // Set controller - if (!controller.empty()) { - tm.change_controller_by_wml(controller); - } - // Set defeat_condition - if (!defeat_condition.empty()) { - tm.set_defeat_condition_string(defeat_condition); - } - // Set shroud - config::attribute_value shroud = cfg["shroud"]; - if (!shroud.empty()) { - tm.set_shroud(shroud.to_bool(true)); - invalidate_screen = true; - } - // Reset shroud - if ( cfg["reset_maps"].to_bool(false) ) { - tm.reshroud(); - invalidate_screen = true; - } - // Merge shroud data - if (!shroud_data.empty()) { - tm.merge_shroud_map_data(shroud_data); - invalidate_screen = true; - } - // Set whether team is hidden in status table - config::attribute_value hidden = cfg["hidden"]; - if (!hidden.empty()) { - tm.set_hidden(hidden.to_bool(true)); - } - // Set fog - config::attribute_value fog = cfg["fog"]; - if (!fog.empty()) { - tm.set_fog(fog.to_bool(true)); - invalidate_screen = true; - } - // Reset fog - if ( cfg["reset_view"].to_bool(false) ) { - tm.refog(); - invalidate_screen = true; - } - // Set income per village - config::attribute_value village_gold = cfg["village_gold"]; - if (!village_gold.empty()) { - tm.set_village_gold(village_gold); - } - // Set support (unit levels supported per village, for upkeep purposes) - if (!village_support.empty()) { - tm.set_village_support(lexical_cast_default(village_support, game_config::village_support)); - } - // Redeploy ai from location (this ignores current AI parameters) - if (!switch_ai.empty()) { - ai::manager::add_ai_for_side_from_file(side_num,switch_ai,true); - } - // Override AI parameters - if (!ai.empty()) { - ai::manager::modify_active_ai_config_old_for_side(side_num,ai); - } - // Change team color - config::attribute_value color = cfg["color"]; - if(!color.empty()) { - tm.set_color(color); - invalidate_screen = true; - } - // Change flag imageset - config::attribute_value flag = cfg["flag"]; - if(!flag.empty()) { - tm.set_flag(flag); - // Needed especially when map isn't animated. - invalidate_screen = true; - } - // If either the flag set or the team color changed, we need to - // rebuild the team's flag cache to reflect the changes. Note that - // this is not required for flag icons (used by the theme UI only). - if((!color.empty() || !flag.empty()) && game_display_) { - game_display_->reinit_flags_for_side(team_index); - } - // Change flag icon - config::attribute_value flag_icon = cfg["flag_icon"]; - if(!flag_icon.empty()) { - tm.set_flag_icon(flag_icon); - // Not needed. - //invalidate_screen = true; - } - tm.handle_legacy_share_vision(cfg.get_parsed_config()); - // Suppress end turn confirmations? - config::attribute_value setc = cfg["suppress_end_turn_confirmation"]; - if ( !setc.empty() ) { - tm.set_no_turn_confirmation(setc.to_bool()); - } - - // Change leader scrolling options - config::attribute_value stl = cfg["scroll_to_leader"]; - if ( !stl.empty()) { - tm.set_scroll_to_leader(stl.to_bool(true)); - } + int side_num = luaL_checkinteger(L, 1) - 1; + std::string file = luaL_checkstring(L, 2); + if(!ai::manager::add_ai_for_side_from_file(side_num, file)) { + std::string err = formatter() << "Could not load AI for side " << side_num + 1 << " from file " << file; + lua_pushlstring(L, err.c_str(), err.length()); + return lua_error(L); } + return 0; +} - // Flag an update of the screen, if needed. - if ( invalidate_screen && game_display_) { - game_display_->recalculate_minimap(); - game_display_->invalidate_all(); +static int intf_append_ai(lua_State *L) +{ + int side_num = luaL_checkinteger(L, 1); + config cfg = luaW_checkconfig(L, 2); + if(!cfg.has_child("ai")) { + cfg = config_of("ai", cfg); } - - + cfg.child("ai").add_child("stage", config_of("name", "empty")); + ai::configuration::expand_simplified_aspects(side_num, cfg); + ai::manager::append_active_ai_for_side(side_num, cfg.child("ai")); return 0; } @@ -4115,6 +4016,8 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle { "allow_end_turn", &dispatch<&game_lua_kernel::intf_allow_end_turn > }, { "allow_undo", &dispatch<&game_lua_kernel::intf_allow_undo > }, { "animate_unit", &dispatch<&game_lua_kernel::intf_animate_unit > }, + { "append_ai", &intf_append_ai }, + { "check_end_level_disabled", &dispatch<&game_lua_kernel::intf_check_end_level_disabled > }, { "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 > }, @@ -4165,7 +4068,6 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle { "match_unit", &dispatch<&game_lua_kernel::intf_match_unit > }, { "message", &dispatch<&game_lua_kernel::intf_message > }, { "modify_ai_wml", &dispatch<&game_lua_kernel::intf_modify_ai_wml > }, - { "modify_side", &dispatch<&game_lua_kernel::intf_modify_side > }, { "open_help", &dispatch<&game_lua_kernel::intf_open_help > }, { "play_sound", &dispatch<&game_lua_kernel::intf_play_sound > }, { "print", &dispatch<&game_lua_kernel::intf_print > }, @@ -4191,11 +4093,13 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle { "set_end_campaign_text", &dispatch<&game_lua_kernel::intf_set_end_campaign_text > }, { "set_menu_item", &dispatch<&game_lua_kernel::intf_set_menu_item > }, { "set_next_scenario", &dispatch<&game_lua_kernel::intf_set_next_scenario > }, + { "set_team_id", &dispatch<&game_lua_kernel::intf_set_team_id > }, { "set_terrain", &dispatch<&game_lua_kernel::intf_set_terrain > }, { "set_variable", &dispatch<&game_lua_kernel::intf_set_variable > }, { "set_side_variable", &dispatch<&game_lua_kernel::intf_set_side_variable > }, { "set_village_owner", &dispatch<&game_lua_kernel::intf_set_village_owner > }, { "simulate_combat", &dispatch<&game_lua_kernel::intf_simulate_combat > }, + { "switch_ai", &intf_switch_ai }, { "synchronize_choice", &intf_synchronize_choice }, { "synchronize_choices", &intf_synchronize_choices }, { "teleport", &dispatch<&game_lua_kernel::intf_teleport > }, diff --git a/src/scripting/game_lua_kernel.hpp b/src/scripting/game_lua_kernel.hpp index d67d0ba22ab4..0a1892e4135e 100644 --- a/src/scripting/game_lua_kernel.hpp +++ b/src/scripting/game_lua_kernel.hpp @@ -141,8 +141,8 @@ class game_lua_kernel : public lua_kernel_base int intf_get_villages(lua_State *L); int intf_match_location(lua_State *L); int intf_match_side(lua_State *L); + int intf_set_team_id(lua_State *L); int intf_modify_ai_wml(lua_State *L); - int intf_modify_side(lua_State *L); int intf_get_sides(lua_State* L); int intf_add_tile_overlay(lua_State *L); int intf_remove_tile_overlay(lua_State *L); diff --git a/src/scripting/lua_team.cpp b/src/scripting/lua_team.cpp index dbaae853fcb7..2fb78ac4f4ca 100644 --- a/src/scripting/lua_team.cpp +++ b/src/scripting/lua_team.cpp @@ -64,8 +64,8 @@ static int impl_side_get(lua_State *L) return_bool_attrib("shroud", t.uses_shroud()); return_bool_attrib("hidden", t.hidden()); return_bool_attrib("scroll_to_leader", t.get_scroll_to_leader()); - return_string_attrib("flag", t.flag()); - return_string_attrib("flag_icon", t.flag_icon()); + return_string_attrib("flag", t.flag().empty() ? game_config::images::flag : t.flag()); + return_string_attrib("flag_icon", t.flag_icon().empty() ? game_config::images::flag_icon : t.flag_icon()); return_tstring_attrib("user_team_name", t.user_team_name()); return_string_attrib("team_name", t.team_name()); return_string_attrib("faction", t.faction()); @@ -79,6 +79,10 @@ static int impl_side_get(lua_State *L) return_bool_attrib("carryover_add", t.carryover_add()); return_bool_attrib("lost", t.lost()); return_bool_attrib("persistent", t.persistent()); + return_bool_attrib("suppress_end_turn_confirmation", t.no_turn_confirmation()); + return_string_attrib("share_vision", t.share_vision().to_string()); + return_bool_attrib("share_maps", t.share_maps()); + return_bool_attrib("share_view", t.share_view()); if (strcmp(m, "recruit") == 0) { std::set const &recruits = t.recruits(); @@ -127,6 +131,18 @@ static int impl_side_set(lua_State *L) modify_bool_attrib("carryover_add", t.set_carryover_add(value)); modify_bool_attrib("lost", t.set_lost(value)); modify_bool_attrib("persistent", t.set_persistent(value)); + modify_bool_attrib("suppress_end_turn_confirmation", t.set_no_turn_confirmation(value)); + modify_bool_attrib("shroud", t.set_shroud(value)); + modify_bool_attrib("fog", t.set_fog(value)); + modify_string_attrib("flag_icon", t.set_flag_icon(value)); + modify_string_attrib("share_vision", { + team::SHARE_VISION v; + if(v.parse(value)) { + t.set_share_vision(v); + } else { + return luaL_argerror(L, 3, "Invalid share_vision value (should be 'all', 'none', or 'shroud')"); + } + }); if (strcmp(m, "carryover_bonus") == 0) { t.set_carryover_bonus(luaL_checknumber(L, 3));