Merge branch 'lua'

This commit is contained in:
Chris Beck 2014-12-28 19:05:46 -05:00
commit 64ee2d8e10
11 changed files with 230 additions and 137 deletions

View File

@ -1041,6 +1041,10 @@ function wml_actions.harm_unit(cfg)
end_var_scope("this_unit", this_unit)
end
function wml_actions.heal_unit(cfg)
wesnoth.heal_unit(cfg)
end
function wml_actions.transform_unit(cfg)
local transform_to = cfg.transform_to

View File

@ -970,6 +970,7 @@ set(wesnoth-main_SRC
scripting/lua_gui2.cpp
scripting/lua_kernel_base.cpp
scripting/lua_map_location_ops.cpp
scripting/lua_race.cpp
scripting/lua_rng.cpp
scripting/lua_team.cpp
scripting/lua_types.cpp

View File

@ -543,6 +543,7 @@ wesnoth_sources = Split("""
scripting/lua_gui2.cpp
scripting/lua_kernel_base.cpp
scripting/lua_map_location_ops.cpp
scripting/lua_race.cpp
scripting/lua_rng.cpp
scripting/lua_team.cpp
scripting/lua_types.cpp

View File

@ -547,82 +547,6 @@ WML_HANDLER_FUNCTION(get_global_variable,/**/,pcfg)
verify_and_get_global_variable(pcfg);
}
WML_HANDLER_FUNCTION(heal_unit, event_info, cfg)
{
unit_map* units = resources::units;
const vconfig & healers_filter = cfg.child("filter_second");
std::vector<unit*> healers;
if (!healers_filter.null()) {
const unit_filter ufilt(healers_filter, resources::filter_con);
BOOST_FOREACH(unit& u, *units) {
if ( ufilt(u) && u.has_ability_type("heals") ) {
healers.push_back(&u);
}
}
}
const config::attribute_value amount = cfg["amount"];
const config::attribute_value moves = cfg["moves"];
const bool restore_attacks = cfg["restore_attacks"].to_bool(false);
const bool restore_statuses = cfg["restore_statuses"].to_bool(true);
const bool animate = cfg["animate"].to_bool(false);
const vconfig & healed_filter = cfg.child("filter");
bool only_unit_at_loc1 = healed_filter.null();
bool heal_amount_to_set = true;
const unit_filter ufilt(healed_filter, resources::filter_con);
for(unit_map::unit_iterator u = units->begin(); u != units->end(); ++u) {
if (only_unit_at_loc1)
{
u = units->find(event_info.loc1);
if(!u.valid()) return;
}
else if ( !ufilt(*u) ) continue;
int heal_amount = u->max_hitpoints() - u->hitpoints();
if(amount.blank() || amount == "full") u->set_hitpoints(u->max_hitpoints());
else {
heal_amount = lexical_cast_default<int, config::attribute_value> (amount, heal_amount);
const int new_hitpoints = std::max(1, std::min(u->max_hitpoints(), u->hitpoints() + heal_amount));
heal_amount = new_hitpoints - u->hitpoints();
u->set_hitpoints(new_hitpoints);
}
if(!moves.blank()) {
if(moves == "full") u->set_movement(u->total_movement());
else {
// set_movement doesn't set below 0
u->set_movement(std::min<int>(
u->total_movement(),
u->movement_left() + lexical_cast_default<int, config::attribute_value> (moves, 0)
));
}
}
if(restore_attacks) u->set_attacks(u->max_attacks());
if(restore_statuses)
{
u->set_state(unit::STATE_POISONED, false);
u->set_state(unit::STATE_SLOWED, false);
u->set_state(unit::STATE_PETRIFIED, false);
u->set_state(unit::STATE_UNHEALABLE, false);
u->anim_comp().set_standing();
}
if (heal_amount_to_set)
{
heal_amount_to_set = false;
resources::gamedata->get_variable("heal_amount") = heal_amount;
}
if(animate) unit_display::unit_healing(*u, healers, heal_amount);
if(only_unit_at_loc1) return;
}
}
WML_HANDLER_FUNCTION(lift_fog, /*event_info*/, cfg)
{
toggle_fog(true, cfg, !cfg["multiturn"].to_bool(false));

View File

@ -69,7 +69,6 @@
#include "pathfind/pathfind.hpp" // for full_cost_map, plain_route, etc
#include "pathfind/teleport.hpp" // for get_teleport_locations, etc
#include "play_controller.hpp" // for play_controller
#include "race.hpp" // for unit_race, race_map
#include "recall_list_manager.hpp" // for recall_list_manager
#include "replay.hpp" // for get_user_choice, etc
#include "reports.hpp" // for register_generator, etc
@ -77,6 +76,7 @@
#include "scripting/lua_common.hpp"
#include "scripting/lua_cpp_function.hpp"
#include "scripting/lua_gui2.hpp" // for show_gamestate_inspector
#include "scripting/lua_race.hpp"
#include "scripting/lua_team.hpp"
#include "scripting/lua_types.hpp" // for getunitKey, dlgclbkKey, etc
#include "scripting/lua_unit_type.hpp"
@ -200,32 +200,6 @@ namespace {
};
}//unnamed namespace for queued_event_context
/**
* Gets some data on a race (__index metamethod).
* - Arg 1: table containing an "id" field.
* - Arg 2: string containing the name of the property.
* - Ret 1: something containing the attribute.
*/
static int impl_race_get(lua_State* L)
{
char const* m = luaL_checkstring(L, 2);
lua_pushstring(L, "id");
lua_rawget(L, 1);
const unit_race* raceptr = unit_types.find_race(lua_tostring(L, -1));
if(!raceptr) return luaL_argerror(L, 1, "unknown race");
unit_race const &race = *raceptr;
return_tstring_attrib("description", race.description());
return_tstring_attrib("name", race.name());
return_int_attrib("num_traits", race.num_traits());
return_tstring_attrib("plural_name", race.plural_name());
return_bool_attrib("ignore_global_traits", !race.uses_global_traits());
return_string_attrib("undead_variation", race.undead_variation());
return_cfgref_attrib("__cfg", race.get_cfg());
return 0;
}
/**
* Destroys a unit object before it is collected (__gc metamethod).
*/
@ -1906,6 +1880,88 @@ int game_lua_kernel::intf_find_cost_map(lua_State *L)
return 1;
}
int game_lua_kernel::intf_heal_unit(lua_State *L)
{
vconfig cfg(luaW_checkvconfig(L, 1));
const game_events::queued_event &event_info = get_event_info();
unit_map & temp = units();
unit_map* units = & temp;
const vconfig & healers_filter = cfg.child("filter_second");
std::vector<unit*> healers;
if (!healers_filter.null()) {
const unit_filter ufilt(healers_filter, &game_state_);
BOOST_FOREACH(unit& u, *units) {
if ( ufilt(u) && u.has_ability_type("heals") ) {
healers.push_back(&u);
}
}
}
const config::attribute_value amount = cfg["amount"];
const config::attribute_value moves = cfg["moves"];
const bool restore_attacks = cfg["restore_attacks"].to_bool(false);
const bool restore_statuses = cfg["restore_statuses"].to_bool(true);
const bool animate = cfg["animate"].to_bool(false);
const vconfig & healed_filter = cfg.child("filter");
bool only_unit_at_loc1 = healed_filter.null();
bool heal_amount_to_set = true;
const unit_filter ufilt(healed_filter, &game_state_);
for(unit_map::unit_iterator u = units->begin(); u != units->end(); ++u) {
if (only_unit_at_loc1)
{
u = units->find(event_info.loc1);
if(!u.valid()) return 0;
}
else if ( !ufilt(*u) ) continue;
int heal_amount = u->max_hitpoints() - u->hitpoints();
if(amount.blank() || amount == "full") u->set_hitpoints(u->max_hitpoints());
else {
heal_amount = lexical_cast_default<int, config::attribute_value> (amount, heal_amount);
const int new_hitpoints = std::max(1, std::min(u->max_hitpoints(), u->hitpoints() + heal_amount));
heal_amount = new_hitpoints - u->hitpoints();
u->set_hitpoints(new_hitpoints);
}
if(!moves.blank()) {
if(moves == "full") u->set_movement(u->total_movement());
else {
// set_movement doesn't set below 0
u->set_movement(std::min<int>(
u->total_movement(),
u->movement_left() + lexical_cast_default<int, config::attribute_value> (moves, 0)
));
}
}
if(restore_attacks) u->set_attacks(u->max_attacks());
if(restore_statuses)
{
u->set_state(unit::STATE_POISONED, false);
u->set_state(unit::STATE_SLOWED, false);
u->set_state(unit::STATE_PETRIFIED, false);
u->set_state(unit::STATE_UNHEALABLE, false);
u->anim_comp().set_standing();
}
if (heal_amount_to_set)
{
heal_amount_to_set = false;
gamedata().get_variable("heal_amount") = heal_amount;
}
if(animate) unit_display::unit_healing(*u, healers, heal_amount);
if(only_unit_at_loc1) return 0;
}
return 0;
}
/**
* Places a unit on the map.
* - Args 1,2: (optional) location.
@ -3600,6 +3656,7 @@ game_lua_kernel::game_lua_kernel(const config &cfg, CVideo * video, game_state &
{ "get_villages", boost::bind(&game_lua_kernel::intf_get_villages, this, _1) },
{ "get_village_owner", boost::bind(&game_lua_kernel::intf_get_village_owner, this, _1) },
{ "get_displayed_unit", boost::bind(&game_lua_kernel::intf_get_displayed_unit, this, _1) },
{ "heal_unit", boost::bind(&game_lua_kernel::intf_heal_unit, this, _1) },
{ "highlight_hex", boost::bind(&game_lua_kernel::intf_highlight_hex, this, _1) },
{ "is_enemy", boost::bind(&game_lua_kernel::intf_is_enemy, this, _1) },
{ "kill", boost::bind(&game_lua_kernel::intf_kill, this, _1) },
@ -3650,16 +3707,7 @@ game_lua_kernel::game_lua_kernel(const config &cfg, CVideo * video, game_state &
cmd_log_ << lua_unit_type::register_metatable(L);
//Create the getrace metatable
cmd_log_ << "Adding getrace metatable...\n";
lua_pushlightuserdata(L
, getraceKey);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, impl_race_get);
lua_setfield(L, -2, "__index");
lua_pushstring(L, "race");
lua_setfield(L, -2, "__metatable");
lua_rawset(L, LUA_REGISTRYINDEX);
cmd_log_ << lua_race::register_metatable(L);
// Create the getunit metatable.
cmd_log_ << "Adding getunit metatable...\n";
@ -3817,23 +3865,9 @@ void game_lua_kernel::initialize()
lua_settop(L, 0);
lua_getglobal(L, "wesnoth");
lua_pushlightuserdata(L
, getraceKey);
lua_rawget(L, LUA_REGISTRYINDEX);
const race_map& races = unit_types.races();
lua_createtable(L, 0, races.size());
BOOST_FOREACH(const race_map::value_type &race, races)
{
lua_createtable(L, 0, 1);
char const* id = race.first.c_str();
lua_pushstring(L, id);
lua_setfield(L, -2, "id");
lua_pushvalue(L, -3);
lua_setmetatable(L, -2);
lua_setfield(L, -2, id);
}
lua_setfield(L, -3, "races");
lua_pop(L, 2);
luaW_pushracetable(L);
lua_setfield(L, -2, "races");
lua_pop(L, 1);
// Execute the preload scripts.
cmd_log_ << "Running preload scripts...\n";

View File

@ -109,6 +109,7 @@ class game_lua_kernel : public lua_kernel_base
int intf_find_path(lua_State *L);
int intf_find_reach(lua_State *L);
int intf_find_cost_map(lua_State *L);
int intf_heal_unit(lua_State *L);
int intf_message(lua_State *L);
int intf_open_help(lua_State *L);
int intf_play_sound(lua_State *L);

View File

@ -0,0 +1,98 @@
/*
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "scripting/lua_race.hpp"
#include "lua/lua.h"
#include "lua/lauxlib.h"
#include "race.hpp"
#include "scripting/lua_common.hpp"
#include "unit_types.hpp"
#include <boost/foreach.hpp>
#include <string>
/**
* Implementation for a lua reference to a race,
* used by the wesnoth in-game races table.
*/
// Registry key
static const char * Race = "race";
/**
* Gets some data on a race (__index metamethod).
* - Arg 1: table containing an "id" field.
* - Arg 2: string containing the name of the property.
* - Ret 1: something containing the attribute.
*/
static int impl_race_get(lua_State* L)
{
char const* m = luaL_checkstring(L, 2);
lua_pushstring(L, "id");
lua_rawget(L, 1);
const unit_race* raceptr = unit_types.find_race(lua_tostring(L, -1));
if(!raceptr) return luaL_argerror(L, 1, "unknown race");
unit_race const &race = *raceptr;
return_tstring_attrib("description", race.description());
return_tstring_attrib("name", race.name());
return_int_attrib("num_traits", race.num_traits());
return_tstring_attrib("plural_name", race.plural_name());
return_bool_attrib("ignore_global_traits", !race.uses_global_traits());
return_string_attrib("undead_variation", race.undead_variation());
return_cfgref_attrib("__cfg", race.get_cfg());
return 0;
}
namespace lua_race {
std::string register_metatable(lua_State * L)
{
luaL_newmetatable(L, Race);
static luaL_Reg const callbacks[] = {
{ "__index", &impl_race_get},
{ NULL, NULL }
};
luaL_setfuncs(L, callbacks, 0);
lua_pushstring(L, "race");
lua_setfield(L, -2, "__metatable");
return "Adding getrace metatable...\n";
}
}
void luaW_pushrace(lua_State *L, const unit_race & race)
{
lua_createtable(L, 0, 1);
lua_pushstring(L, race.id().c_str());
lua_setfield(L, -2, "id");
luaL_setmetatable(L, Race);
}
void luaW_pushracetable(lua_State *L)
{
const race_map& races = unit_types.races();
lua_createtable(L, 0, races.size());
BOOST_FOREACH(const race_map::value_type &race, races)
{
assert(race.first == race.second.id());
luaW_pushrace(L, race.second);
lua_setfield(L, -2, race.first.c_str());
}
}

View File

@ -0,0 +1,35 @@
/*
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef LUA_RACE_HPP_INCLUDED
#define LUA_RACE_HPP_INCLUDED
class unit_race;
struct lua_State;
#include <string>
/**
* This namespace contains bindings for lua to hold a pointer to a race,
* and to access and modify it.
*/
namespace lua_race {
std::string register_metatable(lua_State *);
} //end namespace lua_team
// Create a lua reference to the race.
void luaW_pushrace(lua_State *, const unit_race &);
void luaW_pushracetable(lua_State *);
#endif

View File

@ -16,14 +16,12 @@
/* Dummy pointer for getting unique keys for Lua's registry. */
static char const v_executeKey = 0;
static char const v_getraceKey = 0;
static char const v_getunitKey = 0;
static char const v_unitvarKey = 0;
static char const v_ustatusKey = 0;
luatypekey const executeKey = static_cast<void *>(const_cast<char *>(&v_executeKey));
luatypekey const getraceKey = static_cast<void *>(const_cast<char *>(&v_getraceKey));
luatypekey const getunitKey = static_cast<void *>(const_cast<char *>(&v_getunitKey));
luatypekey const unitvarKey = static_cast<void *>(const_cast<char *>(&v_unitvarKey));
luatypekey const ustatusKey = static_cast<void *>(const_cast<char *>(&v_ustatusKey));

View File

@ -20,7 +20,6 @@ typedef void* luatypekey;
// i dont want to cast to void* each time ....
// a drawback is, that these are now normal static variables wich are initialised at initialisation time (so you shoudn't use these at/before initialisation time).
extern luatypekey const executeKey;
extern luatypekey const getraceKey;
extern luatypekey const getunitKey;
extern luatypekey const unitvarKey;
extern luatypekey const ustatusKey;

View File

@ -49,16 +49,14 @@
namespace seed_rng {
#ifdef SEED_RNG_USE_BOOST_RANDOM_DEVICE
uint32_t next_seed() {
#ifdef SEED_RNG_USE_BOOST_RANDOM_DEVICE
static boost::random_device rnd_;
return rnd_();
}
#else
uint32_t next_seed() {
return static_cast<uint32_t> (std::time(0));
}
#endif
}
std::string next_seed_str() {
uint32_t random_seed_ = next_seed();