server/src/bindings/helpers.c

657 lines
18 KiB
C
Raw Normal View History

2010-08-08 10:06:34 +02:00
/* vi: set ts=2:
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include "helpers.h"
#include <platform.h>
#include <util/attrib.h>
#include <util/base36.h>
#include <util/functions.h>
#include <util/log.h>
#include <kernel/config.h>
#include <kernel/equipment.h>
#include <kernel/faction.h>
#include <kernel/magic.h>
#include <kernel/race.h>
#include <kernel/unit.h>
#include <kernel/building.h>
#include <kernel/item.h>
#include <kernel/region.h>
#include <gamecode/archetype.h>
#include <lua.h>
#include <tolua.h>
#include <assert.h>
static int
2011-03-07 08:02:35 +01:00
lua_giveitem(unit * s, unit * d, const item_type * itype, int n,
struct order *ord)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
char fname[64];
int result = -1;
2011-03-07 08:02:35 +01:00
const char *iname = itype->rtype->_name[0];
assert(s != NULL);
2010-08-08 10:06:34 +02:00
strcat(strcpy(fname, iname), "_give");
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, s, TOLUA_CAST "unit");
tolua_pushusertype(L, d, TOLUA_CAST "unit");
tolua_pushstring(L, iname);
2011-03-07 08:02:35 +01:00
tolua_pushnumber(L, (lua_Number) n);
if (lua_pcall(L, 4, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error(("unit %s calling '%s': %s.\n", unitname(s), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("unit %s trying to call '%s' : not a function.\n",
2011-03-07 08:02:35 +01:00
unitname(s), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static int limit_resource(const region * r, const resource_type * rtype)
2010-08-08 10:06:34 +02:00
{
char fname[64];
int result = -1;
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
snprintf(fname, sizeof(fname), "%s_limit", rtype->_name[0]);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)r, TOLUA_CAST "region");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("limit(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
regionname(r, NULL), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("limit(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
regionname(r, NULL), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
static void
produce_resource(region * r, const resource_type * rtype, int norders)
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
char fname[64];
snprintf(fname, sizeof(fname), "%s_produce", rtype->_name[0]);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)r, TOLUA_CAST "region");
2011-03-07 08:02:35 +01:00
tolua_pushnumber(L, (lua_Number) norders);
if (lua_pcall(L, 2, 0, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("produce(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
regionname(r, NULL), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
} else {
log_error(("produce(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
regionname(r, NULL), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
}
2011-03-07 08:02:35 +01:00
static int lc_age(struct attrib *a)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
building_action *data = (building_action *) a->data.v;
const char *fname = data->fname;
const char *fparam = data->param;
building *b = data->b;
2010-08-08 10:06:34 +02:00
int result = -1;
2011-03-07 08:02:35 +01:00
assert(b != NULL);
if (fname != NULL) {
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
if (fparam) {
tolua_pushstring(L, fparam);
}
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, fparam ? 2 : 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("lc_age(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("lc_age(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
}
2011-03-07 08:02:35 +01:00
return (result != 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
2010-08-08 10:06:34 +02:00
}
static void push_param(lua_State * L, char c, spllprm * param)
{
2011-03-07 08:02:35 +01:00
if (c == 'u')
tolua_pushusertype(L, param->data.u, "unit");
else if (c == 'b')
tolua_pushusertype(L, param->data.b, "building");
else if (c == 's')
tolua_pushusertype(L, param->data.sh, "ship");
else if (c == 'r')
tolua_pushusertype(L, param->data.sh, "region");
else if (c == 'c')
tolua_pushstring(L, param->data.s);
2010-08-08 10:06:34 +02:00
else {
log_error(("unsupported syntax %c.\n", c));
lua_pushnil(L);
}
}
/** callback to use lua for spell functions */
2011-03-07 08:02:35 +01:00
static int lua_callspell(castorder * co)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
const char *fname = co->sp->sname;
unit *mage = co->familiar ? co->familiar : co->magician.u;
2010-08-08 10:06:34 +02:00
int result = -1;
2011-03-07 08:02:35 +01:00
const char *hashpos = strchr(fname, '#');
2010-08-08 10:06:34 +02:00
char fbuf[64];
2011-03-07 08:02:35 +01:00
if (hashpos != NULL) {
2010-08-08 10:06:34 +02:00
ptrdiff_t len = hashpos - fname;
2011-03-07 08:02:35 +01:00
assert(len < (ptrdiff_t) sizeof(fbuf));
2010-08-08 10:06:34 +02:00
strncpy(fbuf, fname, len);
fbuf[len] = '\0';
fname = fbuf;
}
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
int nparam = 4;
tolua_pushusertype(L, co->rt, TOLUA_CAST "region");
tolua_pushusertype(L, mage, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
tolua_pushnumber(L, (lua_Number) co->level);
tolua_pushnumber(L, (lua_Number) co->force);
2010-08-08 10:06:34 +02:00
if (co->sp->parameter && co->par->length) {
2011-03-07 08:02:35 +01:00
const char *synp = co->sp->parameter;
2010-08-08 10:06:34 +02:00
int i = 0;
++nparam;
lua_newtable(L);
2011-03-07 08:02:35 +01:00
while (*synp && i < co->par->length) {
spllprm *param = co->par->param[i];
2010-08-08 10:06:34 +02:00
char c = *synp;
2011-03-07 08:02:35 +01:00
if (c == '+') {
push_param(L, *(synp - 1), param);
2010-08-08 10:06:34 +02:00
} else {
push_param(L, c, param);
++synp;
}
lua_rawseti(L, -2, ++i);
}
}
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, nparam, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("spell(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
unitname(mage), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("spell(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
unitname(mage), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
/** callback to initialize a familiar from lua. */
2011-03-07 08:02:35 +01:00
static void lua_initfamiliar(unit * u)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
char fname[64];
int result = -1;
snprintf(fname, sizeof(fname), "initfamiliar_%s", u->race->_name[0]);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("familiar(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_warning(("familiar(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
create_mage(u, M_GRAY);
snprintf(fname, sizeof(fname), "%s_familiar", u->race->_name[0]);
equip_unit(u, get_equipment(fname));
}
static int
2011-03-07 08:02:35 +01:00
lua_changeresource(unit * u, const struct resource_type *rtype, int delta)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
int result = -1;
char fname[64];
snprintf(fname, sizeof(fname), "%s_changeresource", rtype->_name[0]);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
tolua_pushnumber(L, (lua_Number) delta);
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error(("change(%s) calling '%s': %s.\n", unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("change(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static int lua_getresource(unit * u, const struct resource_type *rtype)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
int result = -1;
char fname[64];
snprintf(fname, sizeof(fname), "%s_getresource", rtype->_name[0]);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error(("get(%s) calling '%s': %s.\n", unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
2011-03-07 08:02:35 +01:00
log_error(("get(%s) calling '%s': not a function.\n", unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static boolean lua_canuse_item(const unit * u, const struct item_type *itype)
2010-08-08 10:06:34 +02:00
{
static int function_exists = 1;
boolean result = true;
if (function_exists) {
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
const char *fname = "item_canuse";
2010-08-08 10:06:34 +02:00
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
tolua_pushstring(L, itype->rtype->_name[0]);
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error(("get(%s) calling '%s': %s.\n", unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = lua_toboolean(L, -1);
lua_pop(L, 1);
}
} else {
function_exists = 0;
log_error(("get(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
}
return result;
}
static int
lua_wage(const region * r, const faction * f, const race * rc, int in_turn)
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
const char *fname = "wage";
2010-08-08 10:06:34 +02:00
int result = -1;
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)r, TOLUA_CAST "region");
tolua_pushusertype(L, (void *)f, TOLUA_CAST "faction");
2011-03-07 08:02:35 +01:00
tolua_pushstring(L, rc ? rc->_name[0] : 0);
tolua_pushnumber(L, (lua_Number) in_turn);
if (lua_pcall(L, 3, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("wage(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
regionname(r, NULL), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("wage(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
regionname(r, NULL), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static void lua_agebuilding(building * b)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
char fname[64];
snprintf(fname, sizeof(fname), "age_%s", b->type->_name);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 1, 0, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("agebuilding(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
} else {
log_error(("agebuilding(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
}
2011-03-07 08:02:35 +01:00
static int lua_building_protection(building * b, unit * u)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
const char *fname = "building_protection";
2010-08-08 10:06:34 +02:00
int result = 0;
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("building_protection(%s, %s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("building_protection(%s, %s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static double lua_building_taxes(building * b, int level)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
const char *fname = "building_taxes";
2010-08-08 10:06:34 +02:00
double result = 0.0F;
int type;
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
2011-03-07 08:02:35 +01:00
type = lua_type(L, 1);
2010-08-08 10:06:34 +02:00
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)b, TOLUA_CAST "building");
tolua_pushnumber(L, level);
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("building_taxes(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (double)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("building_taxes(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
buildingname(b), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static int lua_maintenance(const unit * u)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
const char *fname = "maintenance";
2010-08-08 10:06:34 +02:00
int result = -1;
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
2010-08-08 10:06:34 +02:00
log_error(("maintenance(%s) calling '%s': %s.\n",
2011-03-07 08:02:35 +01:00
unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("maintenance(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static void lua_equipmentcallback(const struct equipment *eq, unit * u)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
char fname[64];
int result = -1;
snprintf(fname, sizeof(fname), "equip_%s", eq->name);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 1, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error(("equip(%s) calling '%s': %s.\n", unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
log_error(("equip(%s) calling '%s': not a function.\n",
2011-03-07 08:02:35 +01:00
unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
}
/** callback for an item-use function written in lua. */
int
2011-03-07 08:02:35 +01:00
lua_useitem(struct unit *u, const struct item_type *itype, int amount,
struct order *ord)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
int result = 0;
char fname[64];
snprintf(fname, sizeof(fname), "use_%s", itype->rtype->_name[0]);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
tolua_pushnumber(L, (lua_Number) amount);
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error(("use(%s) calling '%s': %s.\n", unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
2011-03-07 08:02:35 +01:00
log_error(("use(%s) calling '%s': not a function.\n", unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
static int lua_recruit(struct unit *u, const struct archetype *arch, int amount)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
int result = 0;
char fname[64];
snprintf(fname, sizeof(fname), "recruit_%s", arch->name[0]);
lua_pushstring(L, fname);
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_isfunction(L, 1)) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
tolua_pushnumber(L, (lua_Number) amount);
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error(("use(%s) calling '%s': %s.\n", unitname(u), fname, error));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
} else {
result = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
}
} else {
2011-03-07 08:02:35 +01:00
log_error(("use(%s) calling '%s': not a function.\n", unitname(u), fname));
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
}
return result;
}
2011-03-07 08:02:35 +01:00
int tolua_toid(lua_State * L, int idx, int def)
2010-08-08 10:06:34 +02:00
{
int no = 0;
int type = lua_type(L, idx);
2011-03-07 08:02:35 +01:00
if (type == LUA_TNUMBER) {
2010-08-08 10:06:34 +02:00
no = (int)tolua_tonumber(L, idx, def);
} else {
2011-03-07 08:02:35 +01:00
const char *str = tolua_tostring(L, idx, NULL);
no = str ? atoi36(str) : def;
2010-08-08 10:06:34 +02:00
}
return no;
}
2011-03-07 08:02:35 +01:00
void register_tolua_helpers(void)
2010-08-08 10:06:34 +02:00
{
at_building_action.age = lc_age;
2011-03-07 08:02:35 +01:00
register_function((pf_generic) & lua_building_protection,
TOLUA_CAST "lua_building_protection");
register_function((pf_generic) & lua_building_taxes,
TOLUA_CAST "lua_building_taxes");
register_function((pf_generic) & lua_agebuilding,
TOLUA_CAST "lua_agebuilding");
register_function((pf_generic) & lua_recruit, TOLUA_CAST "lua_recruit");
register_function((pf_generic) & lua_callspell, TOLUA_CAST "lua_castspell");
register_function((pf_generic) & lua_initfamiliar,
TOLUA_CAST "lua_initfamiliar");
2010-08-08 10:06:34 +02:00
register_item_use(&lua_useitem, TOLUA_CAST "lua_useitem");
2011-03-07 08:02:35 +01:00
register_function((pf_generic) & lua_getresource,
TOLUA_CAST "lua_getresource");
register_function((pf_generic) & lua_canuse_item,
TOLUA_CAST "lua_canuse_item");
register_function((pf_generic) & lua_changeresource,
TOLUA_CAST "lua_changeresource");
register_function((pf_generic) & lua_equipmentcallback,
TOLUA_CAST "lua_equip");
register_function((pf_generic) & lua_wage, TOLUA_CAST "lua_wage");
register_function((pf_generic) & lua_maintenance,
TOLUA_CAST "lua_maintenance");
register_function((pf_generic) produce_resource,
TOLUA_CAST "lua_produceresource");
register_function((pf_generic) limit_resource,
TOLUA_CAST "lua_limitresource");
2010-08-08 10:06:34 +02:00
register_item_give(lua_giveitem, TOLUA_CAST "lua_giveitem");
}