server/src/bindings/bind_unit.c

1016 lines
26 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 <platform.h>
#include "bind_unit.h"
#ifdef BSON_ATTRIB
# include "bind_attrib.h"
#endif
2010-08-08 10:06:34 +02:00
#include "bindings.h"
2011-03-07 17:26:50 +01:00
/* attributes includes */
2010-08-08 10:06:34 +02:00
#include <attributes/racename.h>
#include <attributes/key.h>
2011-03-07 17:26:50 +01:00
/* kernel includes */
#include <kernel/alchemy.h>
2010-08-08 10:06:34 +02:00
#include <kernel/building.h>
#include <kernel/config.h>
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/magic.h>
#include <kernel/message.h>
#include <kernel/move.h>
#include <kernel/order.h>
#include <kernel/pool.h>
#include <kernel/race.h>
#include <kernel/region.h>
#include <kernel/spellbook.h>
2010-08-08 10:06:34 +02:00
#include <kernel/ship.h>
#include <kernel/skill.h>
#include <kernel/spell.h>
#include <kernel/unit.h>
2011-03-07 17:26:50 +01:00
/* util includes */
2010-08-08 10:06:34 +02:00
#include <util/attrib.h>
#include <util/base36.h>
#include <util/event.h>
#include <util/lists.h>
#include <util/log.h>
#include <quicklist.h>
2010-08-08 10:06:34 +02:00
#include <lua.h>
#include <tolua.h>
#include <assert.h>
#include <errno.h>
#include <limits.h>
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_objects(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, (void *)&self->attribs, TOLUA_CAST "hashtable");
2010-08-08 10:06:34 +02:00
return 1;
}
#ifdef BSON_ATTRIB
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_attribs(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
attrib **attrib_ptr = (attrib **) lua_newuserdata(L, sizeof(attrib *));
attrib *a = tolua_get_lua_ext(self->attribs);
2010-08-08 10:06:34 +02:00
luaL_getmetatable(L, "attrib");
lua_setmetatable(L, -2);
*attrib_ptr = a;
lua_pushcclosure(L, tolua_attriblist_next, 1);
return 1;
}
#endif
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
int tolua_unitlist_nextf(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit **unit_ptr = (unit **) lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
2010-08-08 10:06:34 +02:00
if (u != NULL) {
2011-03-07 08:02:35 +01:00
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2010-08-08 10:06:34 +02:00
*unit_ptr = u->nextF;
return 1;
2011-03-07 08:02:35 +01:00
} else
return 0; /* no more values to return */
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
int tolua_unitlist_nextb(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit **unit_ptr = (unit **) lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
2010-08-08 10:06:34 +02:00
if (u != NULL) {
2011-03-07 08:02:35 +01:00
unit *unext = u->next;
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
while (unext && unext->building != u->building) {
2010-08-08 10:06:34 +02:00
unext = unext->next;
}
*unit_ptr = unext;
return 1;
2011-03-07 08:02:35 +01:00
} else
return 0; /* no more values to return */
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
int tolua_unitlist_nexts(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit **unit_ptr = (unit **) lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
2010-08-08 10:06:34 +02:00
if (u != NULL) {
2011-03-07 08:02:35 +01:00
unit *unext = u->next;
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
while (unext && unext->ship != u->ship) {
2010-08-08 10:06:34 +02:00
unext = unext->next;
}
*unit_ptr = unext;
return 1;
2011-03-07 08:02:35 +01:00
} else
return 0; /* no more values to return */
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
int tolua_unitlist_next(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit **unit_ptr = (unit **) lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
2010-08-08 10:06:34 +02:00
if (u != NULL) {
2011-03-07 08:02:35 +01:00
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2010-08-08 10:06:34 +02:00
*unit_ptr = u->next;
return 1;
2011-03-07 08:02:35 +01:00
} else
return 0; /* no more values to return */
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_name(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
tolua_pushstring(L, self->name);
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_name(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
unit_setname(self, tolua_tostring(L, 2, 0));
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_info(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
tolua_pushstring(L, unit_getinfo(self));
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_info(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
unit_setinfo(self, tolua_tostring(L, 2, 0));
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_id(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getid(self));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_id(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
unit_setid(self, (int)tolua_tonumber(L, 2, 0));
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_hpmax(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_max_hp(self));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_hp(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_gethp(self));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_hp(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
unit_sethp(self, (int)tolua_tonumber(L, 2, 0));
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_number(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->number);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_number(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
int number = (int)tolua_tonumber(L, 2, 0);
2011-03-07 08:02:35 +01:00
if (self->number == 0) {
2010-08-08 10:06:34 +02:00
set_number(self, number);
self->hp = unit_max_hp(self) * number;
} else {
scale_number(self, number);
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_flags(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->flags);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_flags(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
self->flags = (int)tolua_tonumber(L, 2, 0);
return 0;
}
2011-03-07 08:02:35 +01:00
static const char *unit_getmagic(const unit * u)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
sc_mage *mage = get_mage(u);
return mage ? magic_school[mage->magietyp] : NULL;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_magic(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
lua_pushstring(L, unit_getmagic(self));
return 1;
}
2011-03-07 08:02:35 +01:00
static void unit_setmagic(unit * u, const char *type)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
sc_mage *mage = get_mage(u);
2010-08-08 10:06:34 +02:00
magic_t mtype;
2011-03-07 08:02:35 +01:00
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
if (strcmp(magic_school[mtype], type) == 0)
break;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
if (mtype == MAXMAGIETYP)
return;
if (mage == NULL) {
2010-08-08 10:06:34 +02:00
mage = create_mage(u, mtype);
}
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_magic(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *type = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
unit_setmagic(self, type);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_aura(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, get_spellpoints(self));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_aura(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
set_spellpoints(self, (int)tolua_tonumber(L, 2, 0));
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_age(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->age);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_age(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
self->age = (short)tolua_tonumber(L, 2, 0);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_status(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getstatus(self));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_status(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
unit_setstatus(self, (status_t) tolua_tonumber(L, 2, 0));
2010-08-08 10:06:34 +02:00
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_item(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
int result = -1;
2011-03-07 08:02:35 +01:00
if (iname != NULL) {
const item_type *itype = it_find(iname);
if (itype != NULL) {
2010-08-08 10:06:34 +02:00
result = i_get(self->items, itype);
}
}
lua_pushinteger(L, result);
2010-08-08 10:06:34 +02:00
return 1;
}
static int tolua_unit_get_effect(lua_State * L)
{
const unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *potion_name = tolua_tostring(L, 2, 0);
int result = -1;
const potion_type *pt_potion;
const item_type *it_potion = it_find(potion_name);
if (it_potion != NULL) {
pt_potion = it_potion->rtype->ptype;
if (pt_potion != NULL)
result = get_effect(self, pt_potion);
}
lua_pushinteger(L, result);
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_add_item(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
int number = (int)tolua_tonumber(L, 3, 0);
int result = -1;
2011-03-07 08:02:35 +01:00
if (iname != NULL) {
const item_type *itype = it_find(iname);
if (itype != NULL) {
item *i = i_change(&self->items, itype, number);
result = i ? i->number : 0;
2010-08-08 10:06:34 +02:00
}
}
lua_pushinteger(L, result);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_getskill(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
skill_t sk = sk_find(skname);
int value = -1;
2011-03-07 08:02:35 +01:00
if (sk != NOSKILL) {
skill *sv = get_skill(self, sk);
2010-08-08 10:06:34 +02:00
if (sv) {
value = sv->level;
2011-03-07 08:02:35 +01:00
} else
value = 0;
2010-08-08 10:06:34 +02:00
}
lua_pushinteger(L, value);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_effskill(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
skill_t sk = sk_find(skname);
2011-03-07 08:02:35 +01:00
int value = (sk == NOSKILL) ? -1 : eff_skill(self, sk, self->region);
lua_pushinteger(L, value);
2010-08-08 10:06:34 +02:00
return 1;
}
typedef struct fctr_data {
2011-03-07 08:02:35 +01:00
unit *target;
2010-08-08 10:06:34 +02:00
int fhandle;
} fctr_data;
typedef struct event {
2011-03-07 08:02:35 +01:00
struct event_arg *args;
char *msg;
2010-08-08 10:06:34 +02:00
} event;
2011-03-07 08:02:35 +01:00
int fctr_handle(struct trigger *tp, void *data)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
trigger *t = tp;
2010-08-08 10:06:34 +02:00
event evt = { 0 };
2011-03-07 08:02:35 +01:00
fctr_data *fd = (fctr_data *) t->data.v;
lua_State *L = (lua_State *) global.vm_state;
unit *u = fd->target;
evt.args = (event_arg *) data;
2010-08-08 10:06:34 +02:00
lua_rawgeti(L, LUA_REGISTRYINDEX, fd->fhandle);
tolua_pushusertype(L, u, TOLUA_CAST "unit");
tolua_pushusertype(L, &evt, TOLUA_CAST "event");
2011-03-07 08:02:35 +01:00
if (lua_pcall(L, 2, 0, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("event (%s): %s\n", unitname(u), error);
2010-08-08 10:06:34 +02:00
lua_pop(L, 1);
tolua_error(L, TOLUA_CAST "event handler call failed", NULL);
}
return 0;
}
2011-03-07 08:02:35 +01:00
static void fctr_init(trigger * t)
2010-08-08 10:06:34 +02:00
{
t->data.v = calloc(sizeof(fctr_data), 1);
}
2011-03-07 08:02:35 +01:00
static void fctr_done(trigger * t)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
fctr_data *fd = (fctr_data *) t->data.v;
lua_State *L = (lua_State *) global.vm_state;
2010-08-08 10:06:34 +02:00
luaL_unref(L, LUA_REGISTRYINDEX, fd->fhandle);
free(fd);
}
static struct trigger_type tt_lua = {
"lua_event",
fctr_init,
fctr_done,
fctr_handle
};
2011-03-07 08:02:35 +01:00
static trigger *trigger_lua(struct unit *u, int handle)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
trigger *t = t_new(&tt_lua);
fctr_data *td = (fctr_data *) t->data.v;
2010-08-08 10:06:34 +02:00
td->target = u;
td->fhandle = handle;
return t;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_addhandler(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *ename = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
int handle;
lua_pushvalue(L, 3);
handle = luaL_ref(L, LUA_REGISTRYINDEX);
add_trigger(&self->attribs, ename, trigger_lua(self, handle));
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_addnotice(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
addmessage(self->region, self->faction, str, MSG_MESSAGE, ML_IMPORTANT);
return 0;
}
static void unit_castspell(unit * u, const char *name, int level)
2010-08-08 10:06:34 +02:00
{
spell *sp = find_spell(name);
if (sp) {
spellbook *book = unit_get_spellbook(u);
if (spellbook_get(book, sp)) {
if (!sp->cast) {
log_error("spell '%s' has no function.\n", sp->sname);
2010-08-08 10:06:34 +02:00
} else {
castorder co;
create_castorder(&co, u, 0, sp, u->region, level, level * MagicPower(), 0, 0, 0);
sp->cast(&co);
free_castorder(&co);
2010-08-08 10:06:34 +02:00
}
}
}
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_castspell(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
int level = (int)tolua_tonumber(L, 3, 1);
unit_castspell(self, str, level);
2010-08-08 10:06:34 +02:00
return 0;
}
static int tolua_unit_addspell(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *u = (unit *) tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
int level = (int)tolua_tonumber(L, 3, 1);
int err = 0;
spell *sp = find_spell(str);
if (!sp) {
log_error("spell %s could not be found\n", str);
return EINVAL;
} else {
unit_add_spell(u, 0, sp, level);
}
2010-08-08 10:06:34 +02:00
lua_pushinteger(L, err);
return 1;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_racename(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
set_racename(&self->attribs, str);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_racename(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
attrib *a = a_find(self->attribs, &at_racename);
2010-08-08 10:06:34 +02:00
if (a) {
tolua_pushstring(L, get_racename(a));
return 1;
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_setskill(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
int level = (int)tolua_tonumber(L, 3, 0);
skill_t sk = sk_find(skname);
2011-03-07 08:02:35 +01:00
if (sk != NOSKILL) {
2010-08-08 10:06:34 +02:00
set_level(self, sk, level);
} else {
level = -1;
}
lua_pushinteger(L, level);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_use_pooled(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
int number = (int)tolua_tonumber(L, 3, 0);
2011-03-07 08:02:35 +01:00
const resource_type *rtype = rt_find(iname);
2010-08-08 10:06:34 +02:00
int result = -1;
2011-03-07 08:02:35 +01:00
if (rtype != NULL) {
2010-08-08 10:06:34 +02:00
result = use_pooled(self, rtype, GET_DEFAULT, number);
}
lua_pushinteger(L, result);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_pooled(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
const resource_type *rtype = rt_find(iname);
2010-08-08 10:06:34 +02:00
int result = -1;
2011-03-07 08:02:35 +01:00
if (rtype != NULL) {
2010-08-08 10:06:34 +02:00
result = get_pooled(self, rtype, GET_DEFAULT, INT_MAX);
}
lua_pushinteger(L, result);
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static unit *unit_getfamiliar(const unit * u)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
attrib *a = a_find(u->attribs, &at_familiar);
if (a != NULL) {
return (unit *) a->data.v;
2010-08-08 10:06:34 +02:00
}
return NULL;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_familiar(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
tolua_pushusertype(L, unit_getfamiliar(self), TOLUA_CAST "unit");
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_familiar(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
create_newfamiliar(self, (unit *) tolua_tousertype(L, 2, 0));
2010-08-08 10:06:34 +02:00
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_building(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
tolua_pushusertype(L, self->building, TOLUA_CAST "building");
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_building(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *u = (unit *) tolua_tousertype(L, 1, 0);
if (u->faction) {
building * b = (building *) tolua_tousertype(L, 2, 0);
if (b!=u->building) {
leave(u, true);
if (b) {
if (u->region != b->region) {
move_unit(u, b->region, NULL);
}
u_set_building(u, b);
}
}
2010-08-08 10:06:34 +02:00
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_ship(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
tolua_pushusertype(L, self->ship, TOLUA_CAST "ship");
return 1;
}
2011-03-07 08:02:35 +01:00
static void unit_setship(unit * u, ship * s)
2010-08-08 10:06:34 +02:00
{
leave(u, true);
2011-03-07 08:02:35 +01:00
if (s && u->region != s->region) {
2010-08-08 10:06:34 +02:00
move_unit(u, s->region, NULL);
}
u_set_ship(u, s);
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_ship(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
if (self->faction) {
2011-03-07 08:02:35 +01:00
unit_setship(self, (ship *) tolua_tousertype(L, 2, 0));
2010-08-08 10:06:34 +02:00
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_region(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
tolua_pushusertype(L, self->region, TOLUA_CAST "region");
return 1;
}
2011-03-07 08:02:35 +01:00
static void unit_setregion(unit * u, region * r)
2010-08-08 10:06:34 +02:00
{
move_unit(u, r, NULL);
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_region(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
unit_setregion(self, (region *) tolua_tousertype(L, 2, 0));
2010-08-08 10:06:34 +02:00
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_add_order(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
order *ord = parse_order(str, self->faction->locale);
2010-08-08 10:06:34 +02:00
unit_addorder(self, ord);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_clear_orders(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
free_orders(&self->orders);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_items(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
item **item_ptr = (item **) lua_newuserdata(L, sizeof(item *));
2010-08-08 10:06:34 +02:00
luaL_getmetatable(L, TOLUA_CAST "item");
lua_setmetatable(L, -2);
*item_ptr = self->items;
lua_pushcclosure(L, tolua_itemlist_next, 1);
return 1;
}
2012-05-26 17:20:26 +02:00
#ifdef TODO /* spellbooks */
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_spells(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
sc_mage *mage = get_mage(self);
quicklist *slist = 0;
2010-08-08 10:06:34 +02:00
if (mage) {
2011-03-07 08:02:35 +01:00
quicklist **slist_ptr = get_spelllist(mage, self->faction);
if (slist_ptr) {
slist = *slist_ptr;
2010-08-08 10:06:34 +02:00
}
}
return tolua_quicklist_push(L, "spell_list", "spell", slist);
2010-08-08 10:06:34 +02:00
}
2012-05-26 17:20:26 +02:00
static void unit_removespell(unit * u, spell * sp)
{
quicklist **isptr;
isptr = get_spelllist(get_mage(u), u->faction);
ql_set_remove(isptr, sp);
}
static int tolua_unit_removespell(lua_State * L)
{
unit *self = (unit *) tolua_tousertype(L, 1, 0);
spell *sp = (spell *) tolua_tousertype(L, 2, 0);
unit_removespell(self, sp);
return 0;
}
#endif
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_orders(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
2011-03-07 08:02:35 +01:00
order **order_ptr = (order **) lua_newuserdata(L, sizeof(order *));
2010-08-08 10:06:34 +02:00
luaL_getmetatable(L, TOLUA_CAST "order");
lua_setmetatable(L, -2);
*order_ptr = self->orders;
lua_pushcclosure(L, tolua_orderlist_next, 1);
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_flag(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
int flag = atoi36(name);
2011-03-07 08:02:35 +01:00
attrib *a = find_key(self->attribs, flag);
lua_pushboolean(L, (a != NULL));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_flag(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
int value = (int)tolua_tonumber(L, 3, 0);
int flag = atoi36(name);
2011-03-07 08:02:35 +01:00
attrib *a = find_key(self->attribs, flag);
if (a == NULL && value) {
2010-08-08 10:06:34 +02:00
add_key(&self->attribs, flag);
2011-03-07 08:02:35 +01:00
} else if (a != NULL && !value) {
2010-08-08 10:06:34 +02:00
a_remove(&self->attribs, a);
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_weight(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getweight(self));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_capacity(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getcapacity(self));
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_faction(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, (void *)self->faction, TOLUA_CAST "faction");
2010-08-08 10:06:34 +02:00
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_faction(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
faction *f = (faction *) tolua_tousertype(L, 2, 0);
2010-08-08 10:06:34 +02:00
u_setfaction(self, f);
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_get_race(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
tolua_pushstring(L, self->race->_name[0]);
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_set_race(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *rcname = tolua_tostring(L, 2, 0);
race *rc = rc_find(rcname);
if (rc != NULL) {
if (count_unit(self))
--self->faction->no_units;
if (self->irace == self->race)
self->irace = NULL;
2010-08-08 10:06:34 +02:00
self->race = rc;
2011-03-07 08:02:35 +01:00
if (count_unit(self))
--self->faction->no_units;
2010-08-08 10:06:34 +02:00
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_destroy(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
if (self) {
remove_unit(&self->region->units, self);
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_create(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
faction *f = (faction *) tolua_tousertype(L, 1, 0);
region *r = (region *) tolua_tousertype(L, 2, 0);
2010-08-08 10:06:34 +02:00
int num = (int)tolua_tonumber(L, 3, 1);
if (f && r) {
2011-03-07 08:02:35 +01:00
const race *rc = f->race;
const char *rcname = tolua_tostring(L, 4, NULL);
if (rcname)
rc = rc_find(rcname);
2010-08-08 10:06:34 +02:00
if (rc) {
2011-03-07 08:02:35 +01:00
unit *u = create_unit(r, f, num, rc, 0, NULL, NULL);
2010-08-08 10:06:34 +02:00
tolua_pushusertype(L, u, TOLUA_CAST "unit");
return 1;
}
}
return 0;
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_tostring(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
unit *self = (unit *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
lua_pushstring(L, unitname(self));
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_event_gettype(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
event *self = (event *) tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
int index = (int)tolua_tonumber(L, 2, 0);
lua_pushstring(L, self->args[index].type);
return 1;
}
2011-03-07 08:02:35 +01:00
static int tolua_event_get(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2011-03-07 08:02:35 +01:00
struct event *self = (struct event *)tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02:00
int index = (int)tolua_tonumber(L, 2, 0);
2011-03-07 08:02:35 +01:00
event_arg *arg = self->args + index;
2010-08-08 10:06:34 +02:00
if (arg->type) {
2011-03-07 08:02:35 +01:00
if (strcmp(arg->type, "string") == 0) {
2010-08-08 10:06:34 +02:00
tolua_pushstring(L, (const char *)arg->data.v);
2011-03-07 08:02:35 +01:00
} else if (strcmp(arg->type, "int") == 0) {
lua_pushinteger(L, arg->data.i);
2011-03-07 08:02:35 +01:00
} else if (strcmp(arg->type, "float") == 0) {
lua_pushnumber(L, (lua_Number) arg->data.f);
2010-08-08 10:06:34 +02:00
} else {
/* this is pretty lazy */
2011-03-07 08:02:35 +01:00
tolua_pushusertype(L, (void *)arg->data.v, TOLUA_CAST arg->type);
2010-08-08 10:06:34 +02:00
}
return 1;
}
tolua_error(L, TOLUA_CAST "invalid type argument for event", NULL);
return 0;
}
2011-03-07 08:02:35 +01:00
void tolua_unit_open(lua_State * L)
2010-08-08 10:06:34 +02:00
{
/* register user types */
tolua_usertype(L, TOLUA_CAST "unit");
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
{
2011-03-07 08:02:35 +01:00
tolua_cclass(L, TOLUA_CAST "event", TOLUA_CAST "event", TOLUA_CAST "",
NULL);
2010-08-08 10:06:34 +02:00
tolua_beginmodule(L, TOLUA_CAST "event");
{
tolua_function(L, TOLUA_CAST "get_type", &tolua_event_gettype);
tolua_function(L, TOLUA_CAST "get", &tolua_event_get);
}
tolua_endmodule(L);
tolua_cclass(L, TOLUA_CAST "unit", TOLUA_CAST "unit", TOLUA_CAST "", NULL);
tolua_beginmodule(L, TOLUA_CAST "unit");
{
tolua_function(L, TOLUA_CAST "__tostring", &tolua_unit_tostring);
tolua_function(L, TOLUA_CAST "create", &tolua_unit_create);
tolua_function(L, TOLUA_CAST "destroy", &tolua_unit_destroy);
2011-03-07 08:02:35 +01:00
tolua_variable(L, TOLUA_CAST "name", &tolua_unit_get_name,
tolua_unit_set_name);
tolua_variable(L, TOLUA_CAST "faction", &tolua_unit_get_faction,
tolua_unit_set_faction);
2010-08-08 10:06:34 +02:00
tolua_variable(L, TOLUA_CAST "id", &tolua_unit_get_id, tolua_unit_set_id);
2011-03-07 08:02:35 +01:00
tolua_variable(L, TOLUA_CAST "info", &tolua_unit_get_info,
tolua_unit_set_info);
2010-08-08 10:06:34 +02:00
tolua_variable(L, TOLUA_CAST "hp", &tolua_unit_get_hp, tolua_unit_set_hp);
2011-03-07 08:02:35 +01:00
tolua_variable(L, TOLUA_CAST "status", &tolua_unit_get_status,
tolua_unit_set_status);
tolua_variable(L, TOLUA_CAST "familiar", &tolua_unit_get_familiar,
tolua_unit_set_familiar);
2010-08-08 10:06:34 +02:00
tolua_variable(L, TOLUA_CAST "weight", &tolua_unit_get_weight, 0);
tolua_variable(L, TOLUA_CAST "capacity", &tolua_unit_get_capacity, 0);
tolua_function(L, TOLUA_CAST "add_order", &tolua_unit_add_order);
tolua_function(L, TOLUA_CAST "clear_orders", &tolua_unit_clear_orders);
tolua_variable(L, TOLUA_CAST "orders", &tolua_unit_get_orders, 0);
2011-03-07 17:26:50 +01:00
/* key-attributes for named flags: */
2010-08-08 10:06:34 +02:00
tolua_function(L, TOLUA_CAST "set_flag", &tolua_unit_set_flag);
tolua_function(L, TOLUA_CAST "get_flag", &tolua_unit_get_flag);
2011-03-07 08:02:35 +01:00
tolua_variable(L, TOLUA_CAST "flags", &tolua_unit_get_flags,
&tolua_unit_set_flags);
tolua_variable(L, TOLUA_CAST "age", &tolua_unit_get_age,
tolua_unit_set_age);
2010-08-08 10:06:34 +02:00
2011-03-07 17:26:50 +01:00
/* items: */
2010-08-08 10:06:34 +02:00
tolua_function(L, TOLUA_CAST "get_item", &tolua_unit_get_item);
tolua_function(L, TOLUA_CAST "add_item", &tolua_unit_add_item);
tolua_variable(L, TOLUA_CAST "items", &tolua_unit_get_items, 0);
tolua_function(L, TOLUA_CAST "get_pooled", &tolua_unit_get_pooled);
tolua_function(L, TOLUA_CAST "use_pooled", &tolua_unit_use_pooled);
/* effects */
tolua_function(L, TOLUA_CAST "get_potion", &tolua_unit_get_effect);
2011-03-07 17:26:50 +01:00
/* skills: */
2010-08-08 10:06:34 +02:00
tolua_function(L, TOLUA_CAST "get_skill", &tolua_unit_getskill);
tolua_function(L, TOLUA_CAST "eff_skill", &tolua_unit_effskill);
tolua_function(L, TOLUA_CAST "set_skill", &tolua_unit_setskill);
tolua_function(L, TOLUA_CAST "add_notice", &tolua_unit_addnotice);
2011-03-07 17:26:50 +01:00
/* npc logic: */
2010-08-08 10:06:34 +02:00
tolua_function(L, TOLUA_CAST "add_handler", &tolua_unit_addhandler);
2011-03-07 08:02:35 +01:00
tolua_variable(L, TOLUA_CAST "race_name", &tolua_unit_get_racename,
&tolua_unit_set_racename);
2010-08-08 10:06:34 +02:00
tolua_function(L, TOLUA_CAST "add_spell", &tolua_unit_addspell);
2012-05-26 17:20:26 +02:00
#ifdef TODO /* spellbooks */
2010-08-08 10:06:34 +02:00
tolua_function(L, TOLUA_CAST "remove_spell", &tolua_unit_removespell);
2012-05-26 17:20:26 +02:00
tolua_variable(L, TOLUA_CAST "spells", &tolua_unit_get_spells, 0);
#endif
2010-08-08 10:06:34 +02:00
tolua_function(L, TOLUA_CAST "cast_spell", &tolua_unit_castspell);
2011-03-07 08:02:35 +01:00
tolua_variable(L, TOLUA_CAST "magic", &tolua_unit_get_magic,
tolua_unit_set_magic);
tolua_variable(L, TOLUA_CAST "aura", &tolua_unit_get_aura,
tolua_unit_set_aura);
tolua_variable(L, TOLUA_CAST "building", &tolua_unit_get_building,
tolua_unit_set_building);
tolua_variable(L, TOLUA_CAST "ship", &tolua_unit_get_ship,
tolua_unit_set_ship);
tolua_variable(L, TOLUA_CAST "region", &tolua_unit_get_region,
tolua_unit_set_region);
tolua_variable(L, TOLUA_CAST "number", &tolua_unit_get_number,
tolua_unit_set_number);
tolua_variable(L, TOLUA_CAST "race", &tolua_unit_get_race,
tolua_unit_set_race);
2010-08-08 10:06:34 +02:00
tolua_variable(L, TOLUA_CAST "hp_max", &tolua_unit_get_hpmax, 0);
tolua_variable(L, TOLUA_CAST "objects", &tolua_unit_get_objects, 0);
#ifdef BSON_ATTRIB
2010-08-08 10:06:34 +02:00
tolua_variable(L, TOLUA_CAST "attribs", &tolua_unit_get_attribs, 0);
#endif
2010-08-08 10:06:34 +02:00
}
tolua_endmodule(L);
}
tolua_endmodule(L);
}