server/src/bind_unit.c

1055 lines
28 KiB
C
Raw Normal View History

/*
2010-08-08 10:06:34 +02:00
+-------------------+
| | 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"
#include "bind_dict.h"
#include "alchemy.h"
2010-08-08 10:06:34 +02:00
#include "bindings.h"
#include "move.h"
#include "reports.h"
2010-08-08 10:06:34 +02:00
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 */
2010-08-08 10:06:34 +02:00
#include <kernel/building.h>
#include <kernel/config.h>
#include <kernel/faction.h>
#include <kernel/group.h>
2010-08-08 10:06:34 +02:00
#include <kernel/item.h>
#include <kernel/messages.h>
2010-08-08 10:06:34 +02:00
#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/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 <tolua.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
2010-08-08 10:06:34 +02:00
static int tolua_bufunit(lua_State * L) {
char buf[8192];
unit *self = (unit *)tolua_tousertype(L, 1, 0);
int mode = (int)tolua_tonumber(L, 2, see_unit);
if (!self) return 0;
bufunit(self->faction, self, 0, mode, buf, sizeof(buf));
tolua_pushstring(L, buf);
return 1;
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, (void *)&self->attribs, USERTYPE_DICT);
return 1;
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
{
unit **unit_ptr = (unit **)lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
if (u != NULL) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
*unit_ptr = u->nextF;
return 1;
}
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
{
unit **unit_ptr = (unit **)lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
if (u != NULL) {
unit *unext = u->next;
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2011-03-07 08:02:35 +01:00
while (unext && unext->building != u->building) {
unext = unext->next;
}
*unit_ptr = unext;
2010-08-08 10:06:34 +02:00
return 1;
}
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
{
unit **unit_ptr = (unit **)lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
if (u != NULL) {
unit *unext = u->next;
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
2010-08-08 10:06:34 +02:00
while (unext && unext->ship != u->ship) {
unext = unext->next;
}
*unit_ptr = unext;
2010-08-08 10:06:34 +02:00
return 1;
}
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
{
unit **unit_ptr = (unit **)lua_touserdata(L, lua_upvalueindex(1));
unit *u = *unit_ptr;
if (u != NULL) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
*unit_ptr = u->next;
return 1;
}
else
return 0; /* no more values to return */
2010-08-08 10:06:34 +02:00
}
static int tolua_unit_get_group(lua_State * L)
{
unit *u = (unit *)tolua_tousertype(L, 1, 0);
group *g = get_group(u);
if (g) {
tolua_pushstring(L, g->name);
return 1;
}
return 0;
}
static int tolua_unit_set_group(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
int result = join_group(self, tolua_tostring(L, 2, 0));
lua_pushinteger(L, result);
return 1;
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, unit_getname(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
unit_setname(self, tolua_tostring(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, unit_getinfo(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
unit_setinfo(self, tolua_tostring(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getid(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
unit_setid(self, (int)tolua_tonumber(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_max_hp(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_gethp(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
unit_sethp(self, (int)tolua_tonumber(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->number);
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
int number = (int)tolua_tonumber(L, 2, 0);
if (self->number == 0) {
set_number(self, number);
self->hp = unit_max_hp(self) * number;
}
else {
scale_number(self, number);
}
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->flags);
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
self->flags = (int)tolua_tonumber(L, 2, 0);
return 0;
2010-08-08 10:06:34 +02:00
}
static int tolua_unit_get_guard(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
if (is_guard(self, GUARD_ALL)) {
lua_pushinteger(L, getguard(self));
return 1;
}
return 0;
}
static int tolua_unit_set_guard(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
unsigned int flags = (unsigned int)tolua_tonumber(L, 2, 0);
setguard(self, flags);
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
{
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushstring(L, unit_getmagic(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
sc_mage *mage = get_mage(u);
int mtype;
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
if (strcmp(magic_school[mtype], type) == 0)
break;
}
if (mtype == MAXMAGIETYP)
return;
if (mage == NULL) {
mage = create_mage(u, (magic_t)mtype);
}
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *type = tolua_tostring(L, 2, 0);
unit_setmagic(self, type);
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, get_spellpoints(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
set_spellpoints(self, (int)tolua_tonumber(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->age);
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
self->age = (short)tolua_tonumber(L, 2, 0);
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getstatus(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
unit_setstatus(self, (status_t)tolua_tonumber(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
int result = -1;
2010-08-08 10:06:34 +02:00
if (iname != NULL) {
const item_type *itype = it_find(iname);
if (itype != NULL) {
result = i_get(self->items, itype);
}
2010-08-08 10:06:34 +02:00
}
lua_pushinteger(L, result);
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
int number = (int)tolua_tonumber(L, 3, 0);
int result = -1;
2010-08-08 10:06:34 +02: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);
return 1;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_getskill(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
skill_t sk = findskill(skname);
int value = -1;
if (sk != NOSKILL) {
skill *sv = unit_skill(self, sk);
if (sv) {
value = sv->level;
}
else
value = 0;
}
lua_pushinteger(L, value);
return 1;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_effskill(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
skill_t sk = findskill(skname);
int value = (sk == NOSKILL) ? -1 : eff_skill(self, sk, self->region);
lua_pushinteger(L, value);
return 1;
2010-08-08 10:06:34 +02:00
}
typedef struct fctr_data {
unit *target;
int fhandle;
2010-08-08 10:06:34 +02:00
} fctr_data;
typedef struct event {
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
{
trigger *t = tp;
event evt = { 0 };
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;
lua_rawgeti(L, LUA_REGISTRYINDEX, fd->fhandle);
tolua_pushusertype(L, u, TOLUA_CAST "unit");
tolua_pushusertype(L, &evt, TOLUA_CAST "event");
if (lua_pcall(L, 2, 0, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("event (%s): %s\n", unitname(u), error);
lua_pop(L, 1);
tolua_error(L, TOLUA_CAST "event handler call failed", NULL);
}
2010-08-08 10:06:34 +02:00
return 0;
2010-08-08 10:06:34 +02:00
}
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);
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static void fctr_done(trigger * t)
2010-08-08 10:06:34 +02:00
{
fctr_data *fd = (fctr_data *)t->data.v;
lua_State *L = (lua_State *)global.vm_state;
luaL_unref(L, LUA_REGISTRYINDEX, fd->fhandle);
free(fd);
2010-08-08 10:06:34 +02:00
}
static struct trigger_type tt_lua = {
"lua_event",
fctr_init,
fctr_done,
fctr_handle
2010-08-08 10:06:34 +02:00
};
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
{
trigger *t = t_new(&tt_lua);
fctr_data *td = (fctr_data *)t->data.v;
td->target = u;
td->fhandle = handle;
return t;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_addhandler(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *ename = tolua_tostring(L, 2, 0);
int handle;
2010-08-08 10:06:34 +02:00
lua_pushvalue(L, 3);
handle = luaL_ref(L, LUA_REGISTRYINDEX);
add_trigger(&self->attribs, ename, trigger_lua(self, handle));
2010-08-08 10:06:34 +02:00
return 0;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_addnotice(lua_State * L)
2010-08-08 10:06:34 +02: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;
2010-08-08 10:06:34 +02:00
}
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);
}
else {
castorder co;
create_castorder(&co, u, 0, sp, u->region, level, (double)level, 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
{
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);
return 0;
2010-08-08 10:06:34 +02:00
}
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_warning("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
{
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;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
attrib *a = a_find(self->attribs, &at_racename);
if (a) {
tolua_pushstring(L, get_racename(a));
return 1;
}
return 0;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_setskill(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
int level = (int)tolua_tonumber(L, 3, 0);
skill_t sk = findskill(skname);
if (sk != NOSKILL) {
set_level(self, sk, level);
}
else {
level = -1;
}
lua_pushinteger(L, level);
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
int number = (int)tolua_tonumber(L, 3, 0);
const resource_type *rtype = rt_find(iname);
int result = -1;
if (rtype != NULL) {
result = use_pooled(self, rtype, GET_DEFAULT, number);
}
lua_pushinteger(L, result);
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0);
const resource_type *rtype = rt_find(iname);
int result = -1;
if (rtype != NULL) {
result = get_pooled(self, rtype, GET_DEFAULT, INT_MAX);
}
lua_pushinteger(L, result);
return 1;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static unit *unit_getfamiliar(const unit * u)
2010-08-08 10:06:34 +02:00
{
attrib *a = a_find(u->attribs, &at_familiar);
if (a != NULL) {
return (unit *)a->data.v;
}
return NULL;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, unit_getfamiliar(self), TOLUA_CAST "unit");
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
create_newfamiliar(self, (unit *)tolua_tousertype(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, self->building, TOLUA_CAST "building");
return 1;
2010-08-08 10:06:34 +02:00
}
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);
}
}
}
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, self->ship, TOLUA_CAST "ship");
return 1;
2010-08-08 10:06:34 +02:00
}
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);
if (s && u->region != s->region) {
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
if (self->faction) {
unit_setship(self, (ship *)tolua_tousertype(L, 2, 0));
}
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, self->region, TOLUA_CAST "region");
return 1;
2010-08-08 10:06:34 +02:00
}
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);
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
unit_setregion(self, (region *)tolua_tousertype(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
order *ord = parse_order(str, self->faction->locale);
unit_addorder(self, ord);
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
free_orders(&self->orders);
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02: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);
2010-08-08 10:06:34 +02:00
*item_ptr = self->items;
2010-08-08 10:06:34 +02:00
lua_pushcclosure(L, tolua_itemlist_next, 1);
2010-08-08 10:06:34 +02:00
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *) tolua_tousertype(L, 1, 0);
sc_mage *mage = self ? get_mage(self) : 0;
spellbook *sb = mage ? mage->spellbook : 0;
quicklist *slist = 0;
if (sb) {
quicklist **slist_ptr = &sb->spells;
if (slist_ptr) {
slist = *slist_ptr;
}
2010-08-08 10:06:34 +02:00
}
return tolua_quicklist_push(L, "spellbook", "spell_entry", slist);
2010-08-08 10:06:34 +02:00
}
#ifdef TODO /* spellbooks */
2012-05-26 17:20:26 +02:00
static void unit_removespell(unit * u, spell * sp)
{
quicklist **isptr;
2012-05-26 17:20:26 +02:00
isptr = get_spelllist(get_mage(u), u->faction);
ql_set_remove(isptr, sp);
2012-05-26 17:20:26 +02:00
}
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;
2012-05-26 17:20:26 +02:00
}
#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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
2010-08-08 10:06:34 +02: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);
2010-08-08 10:06:34 +02:00
*order_ptr = self->orders;
2010-08-08 10:06:34 +02:00
lua_pushcclosure(L, tolua_orderlist_next, 1);
2010-08-08 10:06:34 +02:00
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
int flag = atoi36(name);
attrib *a = find_key(self->attribs, flag);
lua_pushboolean(L, (a != NULL));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
int value = (int)tolua_tonumber(L, 3, 0);
int flag = atoi36(name);
attrib *a = find_key(self->attribs, flag);
if (a == NULL && value) {
add_key(&self->attribs, flag);
}
else if (a != NULL && !value) {
a_remove(&self->attribs, a);
}
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getweight(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getcapacity(self));
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, (void *)self->faction, TOLUA_CAST "faction");
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
faction *f = (faction *)tolua_tousertype(L, 2, 0);
u_setfaction(self, f);
return 0;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, u_race(self)->_name);
return 1;
2010-08-08 10:06:34 +02:00
}
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
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *rcname = tolua_tostring(L, 2, 0);
const race *rc = rc_find(rcname);
if (rc != NULL) {
if (self->irace == u_race(self)) {
self->irace = NULL;
}
u_setrace(self, rc);
}
return 0;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_destroy(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
if (self) {
remove_unit(&self->region->units, self);
}
return 0;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_create(lua_State * L)
2010-08-08 10:06:34 +02:00
{
faction *f = (faction *)tolua_tousertype(L, 1, 0);
region *r = (region *)tolua_tousertype(L, 2, 0);
int num = (int)tolua_tonumber(L, 3, 1);
if (f && r) {
const race *rc = f->race;
const char *rcname = tolua_tostring(L, 4, NULL);
if (rcname)
rc = rc_find(rcname);
if (rc) {
unit *u = create_unit(r, f, num, rc, 0, NULL, NULL);
tolua_pushusertype(L, u, TOLUA_CAST "unit");
return 1;
}
2010-08-08 10:06:34 +02:00
}
return 0;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_tostring(lua_State * L)
2010-08-08 10:06:34 +02:00
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
lua_pushstring(L, unitname(self));
return 1;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_event_gettype(lua_State * L)
2010-08-08 10:06:34 +02:00
{
event *self = (event *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, 0);
lua_pushstring(L, self->args[index].type);
return 1;
2010-08-08 10:06:34 +02:00
}
2011-03-07 08:02:35 +01:00
static int tolua_event_get(lua_State * L)
2010-08-08 10:06:34 +02:00
{
struct event *self = (struct event *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, 0);
event_arg *arg = self->args + index;
if (arg->type) {
if (strcmp(arg->type, "string") == 0) {
tolua_pushstring(L, (const char *)arg->data.v);
}
else if (strcmp(arg->type, "int") == 0) {
lua_pushinteger(L, arg->data.i);
}
else if (strcmp(arg->type, "float") == 0) {
lua_pushnumber(L, (lua_Number)arg->data.f);
}
else {
/* this is pretty lazy */
tolua_pushusertype(L, (void *)arg->data.v, TOLUA_CAST arg->type);
}
return 1;
2010-08-08 10:06:34 +02:00
}
tolua_error(L, TOLUA_CAST "invalid type argument for event", NULL);
return 0;
2010-08-08 10:06:34 +02:00
}
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");
2010-08-08 10:06:34 +02:00
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
2010-08-08 10:06:34 +02:00
{
tolua_cclass(L, TOLUA_CAST "event", TOLUA_CAST "event", TOLUA_CAST "",
NULL);
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);
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);
tolua_variable(L, TOLUA_CAST "id", tolua_unit_get_id, tolua_unit_set_id);
tolua_variable(L, TOLUA_CAST "group", tolua_unit_get_group, tolua_unit_set_group);
tolua_variable(L, TOLUA_CAST "info", tolua_unit_get_info, tolua_unit_set_info);
tolua_variable(L, TOLUA_CAST "hp", &tolua_unit_get_hp, tolua_unit_set_hp);
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);
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);
/* key-attributes for named flags: */
tolua_function(L, TOLUA_CAST "set_flag", &tolua_unit_set_flag);
tolua_function(L, TOLUA_CAST "get_flag", &tolua_unit_get_flag);
tolua_variable(L, TOLUA_CAST "guard", &tolua_unit_get_guard,
&tolua_unit_set_guard);
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);
/* items: */
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);
/* skills: */
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);
/* npc logic: */
tolua_function(L, TOLUA_CAST "add_handler", &tolua_unit_addhandler);
tolua_variable(L, TOLUA_CAST "race_name", &tolua_unit_get_racename,
&tolua_unit_set_racename);
tolua_function(L, TOLUA_CAST "add_spell", &tolua_unit_addspell);
2012-05-26 17:20:26 +02:00
#ifdef TODO /* spellbooks */
tolua_function(L, TOLUA_CAST "remove_spell", &tolua_unit_removespell);
2012-05-26 17:20:26 +02:00
#endif
tolua_variable(L, TOLUA_CAST "spells", &tolua_unit_get_spells, 0);
tolua_function(L, TOLUA_CAST "cast_spell", &tolua_unit_castspell);
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);
tolua_variable(L, TOLUA_CAST "hp_max", &tolua_unit_get_hpmax, 0);
tolua_variable(L, TOLUA_CAST "objects", &tolua_unit_get_objects, 0);
tolua_function(L, TOLUA_CAST "show", &tolua_bufunit);
}
tolua_endmodule(L);
2010-08-08 10:06:34 +02:00
}
tolua_endmodule(L);
}