Include builtin conditions in wesnoth.wml_conditions
This excludes the [true] and [false] ConditionalWML tags, which are still hard-coded. (People shouldn't be trying to override or extend these anyway.)
This commit is contained in:
parent
e75eaca5a0
commit
44d171ab58
5 changed files with 49 additions and 8 deletions
|
@ -31,6 +31,9 @@ Version 1.13.5+dev:
|
|||
modifications of the chosen type from a unit. The most efficient use is to
|
||||
remove all modifications with a specific duration value.
|
||||
Also callable as u:remove_modifications.
|
||||
* The built-in conditionals have_unit, have_location, and variable are now
|
||||
present in the wesnoth.wml_conditionals table. This means they can be directly
|
||||
called, extended with new features, or even overridden with custom implementations.
|
||||
* Performance:
|
||||
* When a heuristic determines that it's probably faster, the game predicts battle
|
||||
outcome by simulating a few thousand fights instead of calculating exact
|
||||
|
|
|
@ -43,7 +43,7 @@ static lg::log_domain log_engine("engine");
|
|||
// This file is in the game_events namespace.
|
||||
namespace game_events {
|
||||
|
||||
namespace { // Support functions
|
||||
namespace builtin_conditions {
|
||||
std::vector<std::pair<int,int> > default_counts = utils::parse_ranges("1-99999");
|
||||
|
||||
bool have_unit(const vconfig& cfg)
|
||||
|
@ -143,7 +143,9 @@ namespace { // Support functions
|
|||
#undef TEST_BOL_ATTR
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace { // Support functions
|
||||
bool internal_conditional_passed(const vconfig& cond)
|
||||
{
|
||||
if(cond.has_child("true")) {
|
||||
|
@ -160,13 +162,7 @@ namespace { // Support functions
|
|||
for(vconfig::all_children_iterator it = cond.ordered_begin(); it != cond_end; ++it) {
|
||||
std::string key = it.get_key();
|
||||
bool result = true;
|
||||
if(key == "have_unit") {
|
||||
result = have_unit(it.get_child());
|
||||
} else if(key == "have_location") {
|
||||
result = have_location(it.get_child());
|
||||
} else if(key == "variable") {
|
||||
result = variable_matches(it.get_child());
|
||||
} else if(std::find(skip.begin(), skip.end(), key) == skip.end()) {
|
||||
if(std::find(skip.begin(), skip.end(), key) == skip.end()) {
|
||||
assert(resources::lua_kernel);
|
||||
result = resources::lua_kernel->run_wml_conditional(key, it.get_child());
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ namespace game_events
|
|||
{
|
||||
bool conditional_passed(const vconfig& cond);
|
||||
bool matches_special_filter(const config &cfg, const vconfig& filter);
|
||||
|
||||
namespace builtin_conditions {
|
||||
bool have_unit(const vconfig& cfg);
|
||||
bool have_location(const vconfig& cfg);
|
||||
bool variable_matches(const vconfig& cfg);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GAME_EVENTS_CONDITIONAL_WML_H_INCLUDED
|
||||
|
|
|
@ -4895,6 +4895,9 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
|
|||
lua_newtable(L);
|
||||
lua_setfield(L, -2, "wml_conditionals");
|
||||
lua_pop(L, 1);
|
||||
set_wml_condition("have_unit", &game_events::builtin_conditions::have_unit);
|
||||
set_wml_condition("have_location", &game_events::builtin_conditions::have_location);
|
||||
set_wml_condition("variable", &game_events::builtin_conditions::variable_matches);
|
||||
|
||||
// Create the effects table.
|
||||
cmd_log_ << "Adding effects table...\n";
|
||||
|
@ -5225,6 +5228,38 @@ void game_lua_kernel::set_wml_action(std::string const &cmd, game_events::wml_ac
|
|||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
using wml_conditional_handler = bool(*)(const vconfig&);
|
||||
|
||||
/**
|
||||
* Executes its upvalue as a wml condition and returns the result.
|
||||
*/
|
||||
static int cfun_wml_condition(lua_State *L)
|
||||
{
|
||||
wml_conditional_handler h = reinterpret_cast<wml_conditional_handler>
|
||||
(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
|
||||
vconfig vcfg = luaW_checkvconfig(L, 1);
|
||||
lua_pushboolean(L, h(vcfg));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a function for use as a conditional handler.
|
||||
*/
|
||||
void game_lua_kernel::set_wml_condition(std::string const &cmd, wml_conditional_handler h)
|
||||
{
|
||||
lua_State *L = mState;
|
||||
|
||||
lua_getglobal(L, "wesnoth");
|
||||
lua_pushstring(L, "wml_conditionals");
|
||||
lua_rawget(L, -2);
|
||||
lua_pushstring(L, cmd.c_str());
|
||||
lua_pushlightuserdata(L, reinterpret_cast<void *>(h));
|
||||
lua_pushcclosure(L, &cfun_wml_condition, 1);
|
||||
lua_rawset(L, -3);
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a command from an event handler.
|
||||
* @return true if there is a handler for the command.
|
||||
|
|
|
@ -201,6 +201,7 @@ public:
|
|||
bool run_event(game_events::queued_event const &);
|
||||
void push_builtin_effect();
|
||||
void set_wml_action(std::string const &, game_events::wml_action::handler);
|
||||
void set_wml_condition(std::string const &, bool(*)(const vconfig&));
|
||||
bool run_wml_action(std::string const &, vconfig const &,
|
||||
game_events::queued_event const &);
|
||||
bool run_filter(char const *name, unit const &u);
|
||||
|
|
Loading…
Add table
Reference in a new issue