remove ai.synced_command
fixes #1649 . ai.synced_command could easily be used to implement all types of undeteced cheats so it was removed. As a replacement this commit adds a [custom_command] synced command that just calls wesnoth.game_events.on_synced_command which calls a lua handler that must first be set.
This commit is contained in:
parent
e752a172d1
commit
fef953a48e
15 changed files with 101 additions and 35 deletions
|
@ -60,6 +60,7 @@
|
|||
{scenario-story.cfg}
|
||||
{ai/scenarios/}
|
||||
{ai/micro_ais/scenarios/}
|
||||
{ai/utils/custom_command.cfg}
|
||||
#define DONT_RELOAD_CORE
|
||||
#enddef
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ local W = H.set_wml_action_metatable {}
|
|||
local AH = wesnoth.require "ai/lua/ai_helper.lua"
|
||||
local LS = wesnoth.require "location_set"
|
||||
local M = wesnoth.map
|
||||
local T = H.set_wml_tag_metatable {}
|
||||
|
||||
local function get_forest_animals(cfg)
|
||||
-- We want the deer/rabbits to move first, tuskers afterward
|
||||
|
@ -157,8 +158,7 @@ function ca_forest_animals_move:execution(cfg)
|
|||
|
||||
-- If this is a rabbit ending on a hole -> disappears
|
||||
if (unit.type == rabbit_type) and hole_map:get(farthest_hex[1], farthest_hex[2]) then
|
||||
local command = "wesnoth.erase_unit(x1, y1)"
|
||||
ai.synced_command(command, farthest_hex[1], farthest_hex[2])
|
||||
wesnoth.invoke_synced_command("rabbit_despawn", { x = farthest_hex[1], y = farthest_hex[2]})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
local H = wesnoth.require "helper"
|
||||
local W = H.set_wml_action_metatable {}
|
||||
local AH = wesnoth.require "ai/lua/ai_helper.lua"
|
||||
local T = H.set_wml_tag_metatable {}
|
||||
|
||||
local ca_forest_animals_new_rabbit = {}
|
||||
|
||||
|
@ -58,12 +59,7 @@ function ca_forest_animals_new_rabbit:execution(cfg)
|
|||
x, y = wesnoth.find_vacant_tile(holes[i].x, holes[i].y)
|
||||
end
|
||||
|
||||
local command = "wesnoth.put_unit({ side = "
|
||||
.. wesnoth.current.side
|
||||
.. ", type = '"
|
||||
.. cfg.rabbit_type
|
||||
.. "' }, x1, y1)"
|
||||
ai.synced_command(command, x, y)
|
||||
wesnoth.invoke_synced_command("rabbit_spawn", { rabbit_type = cfg.rabbit_type, x = x, y = y})
|
||||
end
|
||||
|
||||
if wesnoth.sides[wesnoth.current.side].shroud then
|
||||
|
|
18
data/ai/utils/custom_command.cfg
Normal file
18
data/ai/utils/custom_command.cfg
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
#define ENABLE_AI_COMMAND_RABBIT_SPAWN
|
||||
[lua]
|
||||
code = <<
|
||||
|
||||
function wesnoth.custom_synced_commands.rabbit_despawn(cfg)
|
||||
--TODO: maybe we only want to allow erasing of unit of certain types/sides/locations ?
|
||||
wesnoth.erase_unit(cfg.x, cfg.y)
|
||||
end
|
||||
|
||||
function wesnoth.custom_synced_commands.rabbit_spawn(cfg)
|
||||
--TODO: maybe we only want to allow creation of unit of certain types/sides/locations ?
|
||||
wesnoth.put_unit({ side = wesnoth.current.side, type = cfg.rabbit_type}, cfg.x, cfg.y)
|
||||
end
|
||||
|
||||
>>
|
||||
[/lua]
|
||||
#enddef
|
|
@ -1,6 +1,7 @@
|
|||
local H = wesnoth.require "helper"
|
||||
local LS = wesnoth.require "location_set"
|
||||
local M = wesnoth.map
|
||||
local T = H.set_wml_tag_metatable {}
|
||||
|
||||
local ca_transport = {}
|
||||
|
||||
|
@ -110,29 +111,12 @@ function ca_transport:execution()
|
|||
-- Also unload units
|
||||
table.sort(best_adj_tiles, function(a, b) return a[3] > b[3] end)
|
||||
|
||||
local command = "local unit = wesnoth.get_unit(x1, y1) "
|
||||
.. "unit.variables.landed = 'yes' "
|
||||
.. "unit.variables.destination_x = 1 "
|
||||
.. "unit.variables.destination_y = 30"
|
||||
ai.synced_command(command, best_unit.x, best_unit.y)
|
||||
local command_data = { x = best_unit.x, y = best_unit.y }
|
||||
for i = 1, math.min(#best_adj_tiles, 3) do
|
||||
table.insert(command_data, T.dst { x = best_adj_tiles[i][1], y = best_adj_tiles[i][2]} )
|
||||
end
|
||||
|
||||
-- Unload 1 level 2 unit
|
||||
local l2_type = H.rand('Swordsman,Javelineer,Pikeman')
|
||||
local command = "wesnoth.put_unit({ side = " .. wesnoth.current.side
|
||||
.. ", type = '" .. l2_type
|
||||
.. "', moves = 2 }, "
|
||||
.. best_adj_tiles[1][1] .. "," .. best_adj_tiles[1][2] .. ")"
|
||||
ai.synced_command(command, best_unit.x, best_unit.y)
|
||||
|
||||
-- Unload up to 2 level 1 units
|
||||
for i = 2, math.min(#best_adj_tiles, 3) do
|
||||
local l1_type = H.rand('Fencer,Mage,Cavalryman,Bowman,Spearman')
|
||||
local command = "wesnoth.put_unit({ side = " .. wesnoth.current.side
|
||||
.. ", type = '" .. l1_type
|
||||
.. "', moves = 2 }, "
|
||||
.. best_adj_tiles[i][1] .. "," .. best_adj_tiles[i][2] .. ")"
|
||||
ai.synced_command(command, best_unit.x, best_unit.y)
|
||||
end
|
||||
wesnoth.invoke_synced_command("ship_unload", command_data)
|
||||
|
||||
return
|
||||
end
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
[/side]
|
||||
|
||||
{SOTBE_TRACK {JOURNEY_06_NEW} }
|
||||
{ENABLE_AI_COMMAND_CA_TRANSPORT_S6}
|
||||
|
||||
[event]
|
||||
name=prestart
|
||||
|
|
|
@ -199,3 +199,30 @@
|
|||
[/unstore_unit]
|
||||
[/event]
|
||||
#enddef
|
||||
|
||||
#define ENABLE_AI_COMMAND_CA_TRANSPORT_S6
|
||||
[lua]
|
||||
code = <<
|
||||
local helper = wesnoth.require "helper"
|
||||
|
||||
function wesnoth.custom_synced_commands.ship_unload(cfg)
|
||||
|
||||
local unit = wesnoth.get_unit(cfg.x, cfg.y)
|
||||
unit.variables.landed = 'yes'
|
||||
unit.variables.destination_x = 1
|
||||
unit.variables.destination_y = 30
|
||||
|
||||
local locs = helper.child_array(cfg, "dst")
|
||||
|
||||
local l2_type = helper.rand('Swordsman,Javelineer,Pikeman')
|
||||
wesnoth.put_unit({ side = wesnoth.current.side, type = l2_type, moves = 2 }, locs[1].x, locs[1].y)
|
||||
|
||||
for i = 2, #locs do
|
||||
local l1_type = helper.rand('Fencer,Mage,Cavalryman,Bowman,Spearman')
|
||||
wesnoth.put_unit({ side = wesnoth.current.side, type = l1_type, moves = 2 }, locs[i].x, locs[i].y)
|
||||
end
|
||||
end
|
||||
|
||||
>>
|
||||
[/lua]
|
||||
#enddef
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
wesnoth.dofile 'lua/backwards-compatibility.lua'
|
||||
wesnoth.dofile 'lua/wml-tags.lua'
|
||||
wesnoth.dofile 'lua/feeding.lua'
|
||||
wesnoth.dofile 'lua/custom_command.lua'
|
||||
>>
|
||||
[/lua]
|
||||
|
||||
|
|
20
data/lua/custom_command.lua
Normal file
20
data/lua/custom_command.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
local helper = wesnoth.require "helper"
|
||||
local T = helper.set_wml_tag_metatable {}
|
||||
|
||||
wesnoth.custom_synced_commands = {}
|
||||
|
||||
function wesnoth.game_events.on_synced_command(cfg)
|
||||
local handler = wesnoth.custom_synced_commands[cfg.name]
|
||||
local data = helper.get_child(cfg, "data")
|
||||
if handler then
|
||||
handler(data)
|
||||
end
|
||||
end
|
||||
|
||||
function wesnoth.register_synced_command(name, handler)
|
||||
wesnoth.custom_synced_commands[name] = handler
|
||||
end
|
||||
|
||||
function wesnoth.invoke_synced_command(name, data)
|
||||
wesnoth.wml_actions.do_command { T.custom_command { name=name, T.data(data) } }
|
||||
end
|
|
@ -968,7 +968,7 @@ void synced_command_result::do_execute()
|
|||
}
|
||||
s << lua_code_;
|
||||
|
||||
synced_context::run_in_synced_context_if_not_already("lua_ai", replay_helper::get_lua_ai(s.str()));
|
||||
//synced_context::run_in_synced_context_if_not_already("lua_ai", replay_helper::get_lua_ai(s.str()));
|
||||
|
||||
try {
|
||||
set_gamestate_changed();
|
||||
|
|
|
@ -273,6 +273,12 @@ static int cfun_ai_check_stopunit(lua_State *L)
|
|||
|
||||
static int ai_synced_command(lua_State *L, bool exec)
|
||||
{
|
||||
#if 1
|
||||
(void)L;
|
||||
(void)exec;
|
||||
ERR_LUA << "synced_command was removed, use wesnoth.wml_actions.do_command with [custom_command] instead\n";
|
||||
return 0;
|
||||
#else
|
||||
const char *lua_code = luaL_checkstring(L, 1);
|
||||
int side = get_readonly_context(L).get_side();
|
||||
map_location location;
|
||||
|
@ -283,6 +289,7 @@ static int ai_synced_command(lua_State *L, bool exec)
|
|||
|
||||
ai::synced_command_result_ptr synced_command_result = ai::actions::execute_synced_command_action(side,exec,std::string(lua_code),location);
|
||||
return transform_ai_action(L,synced_command_result);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int cfun_ai_execute_synced_command(lua_State *L)
|
||||
|
|
|
@ -281,7 +281,7 @@ WML_HANDLER_FUNCTION(do_command,, cfg)
|
|||
return;
|
||||
}
|
||||
|
||||
static const std::set<std::string> allowed_tags {"attack", "move", "recruit", "recall", "disband", "fire_event", "lua_ai"};
|
||||
static const std::set<std::string> allowed_tags {"attack", "move", "recruit", "recall", "disband", "fire_event", "custom_command"};
|
||||
|
||||
const bool is_too_early = resources::gamedata->phase() != game_data::START && resources::gamedata->phase() != game_data::PLAY;
|
||||
const bool is_unsynced_too_early = resources::gamedata->phase() != game_data::PLAY;
|
||||
|
|
|
@ -4395,6 +4395,17 @@ bool game_lua_kernel::run_event(const game_events::queued_event& ev)
|
|||
return true;
|
||||
}
|
||||
|
||||
void game_lua_kernel::custom_command(const config& cfg)
|
||||
{
|
||||
lua_State *L = mState;
|
||||
|
||||
if (!luaW_getglobal(L, "wesnoth", "game_events", "on_synced_command")) {
|
||||
return;
|
||||
}
|
||||
luaW_pushconfig(L, cfg);
|
||||
luaW_pcall(L, 1, 0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies its upvalue as an effect
|
||||
* Arg 1: The unit to apply to
|
||||
|
|
|
@ -200,6 +200,7 @@ public:
|
|||
void save_game(config & level);
|
||||
void load_game(const config& level);
|
||||
bool run_event(const game_events::queued_event&);
|
||||
void custom_command(const config&);
|
||||
void push_builtin_effect();
|
||||
void set_wml_action(const std::string&, game_events::wml_action::handler);
|
||||
void set_wml_condition(const std::string&, bool(*)(const vconfig&));
|
||||
|
|
|
@ -344,11 +344,10 @@ SYNCED_COMMAND_HANDLER_FUNCTION(fire_event, child, use_undo, /*show*/, /*error_
|
|||
return true;
|
||||
}
|
||||
|
||||
SYNCED_COMMAND_HANDLER_FUNCTION(lua_ai, child, /*use_undo*/, /*show*/, /*error_handler*/)
|
||||
SYNCED_COMMAND_HANDLER_FUNCTION(custom_command, child, /*use_undo*/, /*show*/, /*error_handler*/)
|
||||
{
|
||||
const std::string &lua_code = child["code"];
|
||||
assert(resources::lua_kernel);
|
||||
resources::lua_kernel->run(lua_code.c_str());
|
||||
resources::lua_kernel->custom_command(child);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue