add wesnoth.create_side()

wesnoth.create_side() can create a side while the scenario
is running, this is especially useful for [modification]s
that can not define sides by default.
This commit is contained in:
gfgtdf 2019-11-18 16:25:38 +01:00
parent 1035825152
commit 45a33e6e3a
6 changed files with 71 additions and 0 deletions

View file

@ -27,6 +27,7 @@
#include "random_deterministic.hpp"
#include "reports.hpp"
#include "scripting/game_lua_kernel.hpp"
#include "synced_context.hpp"
#include "teambuilder.hpp"
#include "units/unit.hpp"
#include "whiteboard/manager.hpp"
@ -409,3 +410,47 @@ const game_events::wmi_manager& game_state::get_wml_menu_items() const
{
return this->events_manager_->wml_menu_items();
}
namespace
{
//not really a 'choice' we just need to make sure to inform the server about this.
class add_side_wml_choice : public synced_context::server_choice
{
public:
add_side_wml_choice()
{
}
/// We are in a game with no mp server and need to do this choice locally
virtual config local_choice() const
{
return config{};
}
/// tThe request which is sent to the mp server.
virtual config request() const
{
return config{};
}
virtual const char* name() const
{
return "add_side_wml";
}
private:
};
} // end anon namespace
void game_state::add_side_wml(config cfg)
{
cfg["side"] = board_.teams_.size() + 1;
//if we want to also allow setting the controller we must update the server code.
cfg["controller"] = "null";
//TODO: is this it? are there caches which must be cleared?
board_.teams_.emplace_back();
board_.teams_.back().build(cfg, board_.map(), cfg["gold"].to_int());
config choice = synced_context::ask_server_choice(add_side_wml_choice());
}

View file

@ -125,4 +125,7 @@ public:
/// Checks if any of the sides leaders can recruit at a location
bool side_can_recruit_on(int side, map_location loc) const;
///creates a new side during a game. todo: maybe add parameters like id etc?
void add_side_wml(config cfg);
};

View file

@ -773,6 +773,16 @@ int game_lua_kernel::intf_set_variable(lua_State *L)
return 0;
}
int game_lua_kernel::intf_create_side(lua_State *L)
{
int new_side_num = board().teams().size() + 1;
config cfg = luaW_checkconfig(L, 1);
game_state_.add_side_wml(cfg);
return 0;
}
int game_lua_kernel::intf_set_menu_item(lua_State *L)
{
game_state_.get_wml_menu_items().set_item(luaL_checkstring(L, 1), luaW_checkvconfig(L,2));
@ -4213,6 +4223,7 @@ game_lua_kernel::game_lua_kernel(game_state & gs, play_controller & pc, reports
{ "is_shrouded", &dispatch2<&game_lua_kernel::intf_get_fog_or_shroud, false > },
{ "set_end_campaign_credits", &dispatch<&game_lua_kernel::intf_set_end_campaign_credits > },
{ "set_end_campaign_text", &dispatch<&game_lua_kernel::intf_set_end_campaign_text > },
{ "create_side", &dispatch<&game_lua_kernel::intf_create_side > },
{ "set_next_scenario", &dispatch<&game_lua_kernel::intf_set_next_scenario > },
{ "set_terrain", &dispatch<&game_lua_kernel::intf_set_terrain > },
{ "set_variable", &dispatch<&game_lua_kernel::intf_set_variable > },

View file

@ -128,6 +128,7 @@ class game_lua_kernel : public lua_kernel_base
int intf_set_end_campaign_credits(lua_State *L);
int intf_set_end_campaign_text(lua_State *L);
int intf_clear_menu_item(lua_State *L);
int intf_create_side(lua_State *L);
int intf_set_menu_item(lua_State *L);
int intf_set_next_scenario(lua_State *L);
int intf_shroud_op(lua_State *L, bool place_shroud);

View file

@ -1168,6 +1168,13 @@ void game::handle_random_choice(const simple_wml::node&)
record_data(mdata);
}
void game::handle_add_side_wml(const simple_wml::node&)
{
++nsides_;
side_controllers_.push_back(CONTROLLER::EMPTY);
sides_.emplace_back();
}
void game::handle_controller_choice(const simple_wml::node& req)
{
const std::size_t side_index = req["side"].to_int() - 1;
@ -1270,6 +1277,8 @@ void game::handle_choice(const simple_wml::node& data, const socket_ptr& user)
handle_random_choice(*rand);
} else if(const simple_wml::node* ccw = data.child("change_controller_wml")) {
handle_controller_choice(*ccw);
} else if(const simple_wml::node* asw = data.child("add_side_wml")) {
handle_add_side_wml(*asw);
} else {
send_and_record_server_message("Found unknown server choice request: [" + data.first_child().to_string() + "]");
}

View file

@ -315,6 +315,8 @@ public:
void handle_controller_choice(const simple_wml::node& data);
void handle_add_side_wml(const simple_wml::node& req);
void reset_last_synced_context_id()
{
last_choice_request_id_ = -1;