server/src/bind_unit.c

1064 lines
28 KiB
C
Raw Normal View History

#ifdef _MSC_VER
#include <platform.h>
#endif
2010-08-08 10:06:34 +02:00
#include "bind_unit.h"
#include "alchemy.h"
2010-08-08 10:06:34 +02:00
#include "bindings.h"
#include "reports.h"
#include "guard.h"
2018-09-23 19:44:05 +02:00
#include "magic.h"
#include "skill.h"
2010-08-08 10:06:34 +02:00
2018-09-23 19:44:05 +02:00
/* util includes */
#include <kernel/attrib.h>
2018-09-23 19:44:05 +02:00
#include <util/base36.h>
#include <kernel/event.h>
2018-09-23 19:44:05 +02:00
#include <util/log.h>
#include <util/macros.h>
#include "util/variant.h"
2010-08-08 10:06:34 +02:00
2011-03-07 17:26:50 +01:00
/* kernel includes */
2018-09-23 19:44:05 +02:00
#include "kernel/skills.h"
#include "kernel/types.h"
2010-08-08 10:06:34 +02:00
#include <kernel/building.h>
#include <kernel/curse.h>
#include "kernel/equipment.h"
2010-08-08 10:06:34 +02:00
#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>
2018-09-23 19:44:05 +02:00
/* attributes includes */
#include <attributes/racename.h>
#include <attributes/key.h>
#include <selist.h>
2010-08-08 10:06:34 +02:00
2018-09-23 19:44:05 +02:00
#include <lauxlib.h>
#include <lua.h>
2010-08-08 10:06:34 +02:00
#include <tolua.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
2018-09-23 19:44:05 +02:00
#include <stdbool.h>
#include <stdlib.h>
#include <limits.h>
2010-08-08 10:06:34 +02:00
static int tolua_bufunit(lua_State * L) {
unit *u = (unit *)tolua_tousertype(L, 1, 0);
if (u) {
faction *f = (faction *)tolua_tousertype(L, 2, u->faction);
if (f) {
char buf[8192];
int mode = (int)tolua_tonumber(L, 3, (int)seen_unit);
2018-11-24 12:26:52 +01:00
bufunit_depr(f, u, mode, buf, sizeof(buf));
tolua_pushstring(L, buf);
return 1;
}
}
return 0;
}
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)
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
group *g = join_group(u, tolua_tostring(L, 2, 0));
lua_pushboolean(L, g!=NULL);
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, unit_getname(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setname(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, unit_getinfo(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setinfo(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getid(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setid(u, (int)tolua_tonumber(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
static int tolua_unit_get_auramax(lua_State * L)
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, max_spellpoints_depr(u->region, u));
return 1;
}
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_max_hp(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_gethp(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_sethp(u, (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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
int number = (int)tolua_tonumber(L, 2, 0);
2019-09-15 20:32:07 +02:00
if (u->number == 0) {
set_number(u, number);
u->hp = unit_max_hp(u) * number;
}
else {
2019-09-15 20:32:07 +02:00
scale_number(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
u->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)
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushboolean(L, is_guard(u));
return 1;
}
static int tolua_unit_set_guard(lua_State * L)
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
unsigned int flags = (unsigned int)tolua_tonumber(L, 2, 0);
2019-09-15 20:32:07 +02:00
setguard(u, flags!=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
{
struct sc_mage *mage = get_mage(u);
if (mage) {
magic_t mtype = mage_get_type(mage);
return magic_school[mtype];
}
return 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushstring(L, unit_getmagic(u));
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
{
struct sc_mage *mage = get_mage(u);
if (mage == NULL) {
int mtype;
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
if (strcmp(magic_school[mtype], type) == 0) {
create_mage(u, (magic_t)mtype);
return;
}
}
}
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *type = tolua_tostring(L, 2, 0);
2019-09-15 20:32:07 +02:00
unit_setmagic(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, get_spellpoints(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
set_spellpoints(u, (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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
u->age = (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_status(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getstatus(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setstatus(u, (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
{
2019-09-15 20:32:07 +02:00
unit *u = (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) {
2019-09-15 20:32:07 +02:00
result = i_get(u->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)
{
2019-09-15 20:32:07 +02:00
const unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *potion_name = tolua_tostring(L, 2, 0);
int result = -1;
const item_type *it_potion = it_find(potion_name);
if (it_potion != NULL) {
2019-09-15 20:32:07 +02:00
result = get_effect(u, it_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
{
2019-09-15 20:32:07 +02:00
unit *u = (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) {
2019-09-15 20:32:07 +02:00
item *i = i_change(&u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (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) {
2019-09-15 20:32:07 +02:00
skill *sv = unit_skill(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
skill_t sk = findskill(skname);
2019-09-15 20:32:07 +02:00
int value = (sk == NOSKILL) ? -1 : effskill(u, sk, NULL);
lua_pushinteger(L, value);
return 1;
2010-08-08 10:06:34 +02:00
}
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
static int tolua_unit_addnotice(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
2019-09-15 20:32:07 +02:00
addmessage(u->region, u->faction, str, MSG_MESSAGE, ML_IMPORTANT);
return 0;
2010-08-08 10:06:34 +02:00
}
2018-01-17 17:37:37 +01:00
static int bind_unit_effect(lua_State * L)
{
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
const char *str = tolua_tostring(L, 2, NULL);
const item_type *itype = it_find(str);
if (itype) {
int effect = get_effect(u, itype);
lua_pushinteger(L, effect);
return 1;
}
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)) {
castorder co;
create_castorder(&co, u, 0, sp, u->region, level, (double)level, 0, 0, 0);
cast_spell(&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
{
2019-09-15 20:32:07 +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);
2019-09-15 20:32:07 +02:00
unit_castspell(u, 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, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
2010-08-08 10:06:34 +02:00
2019-09-15 20:32:07 +02:00
set_racename(&u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
attrib *a = a_find(u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0);
int level = (int)tolua_tonumber(L, 3, 0);
2019-09-15 20:32:07 +02:00
bool rcmod = tolua_toboolean(L, 4, 0);
skill_t sk = findskill(skname);
2019-09-15 20:32:07 +02:00
if (sk != NOSKILL) {
if (rcmod) level -= u_race(u)->bonus[sk];
2019-09-15 20:32:07 +02:00
set_level(u, sk, level);
lua_pushinteger(L, level);
return 1;
}
2019-09-15 20:32:07 +02:00
return 0;
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
{
2019-09-15 20:32:07 +02:00
unit *u = (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) {
2019-09-15 20:32:07 +02:00
result = use_pooled(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (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) {
2019-09-15 20:32:07 +02:00
result = get_pooled(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, unit_getfamiliar(u), 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 *mag = (unit *)tolua_tousertype(L, 1, NULL);
unit *fam = (unit *)tolua_tousertype(L, 2, NULL);
if (fam) {
set_familiar(mag, fam);
}
else {
remove_familiar(mag);
}
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
if (u->faction) {
unit_setship(u, (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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setregion(u, (region *)tolua_tousertype(L, 2, 0));
return 0;
2010-08-08 10:06:34 +02:00
}
2017-12-10 20:54:02 +01:00
static int tolua_unit_get_order(lua_State * L)
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
2017-12-10 20:54:02 +01:00
int index = (int)tolua_tonumber(L, 2, -1);
order *ord = NULL;
if (index < 0) {
2019-09-15 20:32:07 +02:00
ord = u->thisorder;
2017-12-10 20:54:02 +01:00
}
else {
int i;
2019-09-15 20:32:07 +02:00
ord = u->orders;
2017-12-10 20:54:02 +01:00
for (i = 0; ord && i != index; ++i) {
ord = ord->next;
}
}
if (ord) {
char buffer[1024];
2019-09-15 20:32:07 +02:00
get_command(ord, u->faction->locale, buffer, sizeof(buffer));
2017-12-10 20:54:02 +01:00
lua_pushstring(L, buffer);
return 1;
}
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0);
2019-09-15 20:32:07 +02:00
order *ord = parse_order(str, u->faction->locale);
unit_addorder(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
free_orders(&u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (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
2019-09-15 20:32:07 +02:00
*item_ptr = u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *) tolua_tousertype(L, 1, 0);
struct sc_mage *mage = u ? get_mage(u) : NULL;
spellbook *sb = mage_get_spellbook(mage);
selist *slist = 0;
if (sb) {
selist **slist_ptr = &sb->spells;
2016-11-23 19:19:04 +01:00
slist = *slist_ptr;
2010-08-08 10:06:34 +02:00
}
return tolua_selist_push(L, "spellbook", "spell_entry", slist);
2010-08-08 10:06:34 +02:00
}
2017-02-27 20:16:50 +01:00
static int tolua_unit_get_curse(lua_State *L) {
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
2019-09-15 20:32:07 +02:00
if (u->attribs) {
curse * c = get_curse(u->attribs, ct_find(name));
2017-02-27 20:16:50 +01:00
if (c) {
lua_pushnumber(L, curse_geteffect(c));
return 1;
}
}
return 0;
}
2019-09-19 05:03:01 +02:00
static int tolua_unit_clear_attribs(lua_State *L) {
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
const attrib_type *at = name ? at_find(name) : NULL;
a_removeall(&u->attribs, at);
return 0;
}
static int tolua_unit_has_attrib(lua_State *L) {
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
2019-09-15 20:32:07 +02:00
attrib * a = u->attribs;
while (a) {
if (strcmp(a->type->name, name) == 0) {
break;
}
a = a->nexttype;
}
lua_pushboolean(L, a != NULL);
return 1;
}
static int tolua_unit_get_key(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
int flag = atoi36(name);
2019-09-15 20:32:07 +02:00
lua_pushboolean(L, key_get(u->attribs, flag));
return 1;
2010-08-08 10:06:34 +02:00
}
static int tolua_unit_set_key(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2019-09-15 20:32:07 +02:00
unit *u = (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);
if (value) {
2019-09-15 20:32:07 +02:00
key_set(&u->attribs, flag, value);
}
else {
2019-09-15 20:32:07 +02:00
key_unset(&u->attribs, flag);
}
return 0;
2010-08-08 10:06:34 +02:00
}
static int tolua_unit_get_flag(lua_State * L)
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0);
2019-09-15 20:32:07 +02:00
lua_pushboolean(L, (u->flags & (1 << bit)));
return 1;
}
static int tolua_unit_set_flag(lua_State * L)
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0);
int set = tolua_toboolean(L, 3, 1);
if (set)
2019-09-15 20:32:07 +02:00
u->flags |= (1 << bit);
else
2019-09-15 20:32:07 +02:00
u->flags &= ~(1 << bit);
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getweight(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getcapacity(u));
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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, (void *)u->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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
faction *f = (faction *)tolua_tousertype(L, 2, 0);
2019-09-15 20:32:07 +02:00
u_setfaction(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, u_race(u)->_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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *rcname = tolua_tostring(L, 2, 0);
const race *rc = rc_find(rcname);
if (rc != NULL) {
2019-09-15 20:32:07 +02:00
if (u->irace == u_race(u)) {
u->irace = NULL;
}
2019-09-15 20:32:07 +02:00
u_setrace(u, 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
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
if (u) {
remove_unit(&u->region->units, u);
}
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);
unit *u;
int num = (int)tolua_tonumber(L, 3, 1);
const char *rcname = tolua_tostring(L, 4, NULL);
const race *rc;
if (!r) {
log_warning("unit.create: arg(2) is not a region");
return 0;
}
if (!f) {
log_warning("unit.create: arg(1) is not a faction");
return 0;
}
rc = rcname ? rc_find(rcname) : f->race;
if (!rc) {
log_warning("unit.create: unknown race %s", rcname);
return 0;
}
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
}
2011-03-07 08:02:35 +01:00
static int tolua_unit_tostring(lua_State * L)
2010-08-08 10:06:34 +02:00
{
2019-09-15 20:32:07 +02:00
unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushstring(L, unitname(u));
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
{
2019-09-15 20:32:07 +02:00
event *u = (event *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, 0);
2019-09-15 20:32:07 +02:00
lua_pushstring(L, u->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
{
2019-09-15 20:32:07 +02:00
struct event *u = (struct event *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, 0);
2019-09-15 20:32:07 +02:00
event_arg *arg = u->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
}
static int tolua_equipunit(lua_State * L)
{
unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *eqname = tolua_tostring(L, 2, 0);
int mask = (int)tolua_tonumber(L, 3, EQUIP_ALL);
assert(u && mask > 0);
equip_unit_mask(u, eqname, mask);
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");
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");
{
2017-10-08 17:07:42 +02:00
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");
{
2017-10-08 17:07:42 +02:00
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);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "name", tolua_unit_get_name,
tolua_unit_set_name);
2017-10-08 17:07:42 +02:00
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);
2017-10-08 17:07:42 +02:00
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);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "familiar", tolua_unit_get_familiar,
tolua_unit_set_familiar);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "weight", tolua_unit_get_weight, 0);
tolua_variable(L, TOLUA_CAST "capacity", tolua_unit_get_capacity, 0);
2017-12-10 20:54:02 +01:00
tolua_function(L, TOLUA_CAST "get_order", tolua_unit_get_order);
2017-10-08 17:07:42 +02:00
tolua_function(L, TOLUA_CAST "add_order", tolua_unit_add_order);
tolua_function(L, TOLUA_CAST "clear_orders", tolua_unit_clear_orders);
tolua_function(L, TOLUA_CAST "get_curse", tolua_unit_get_curse);
2019-09-19 05:03:01 +02:00
tolua_function(L, TOLUA_CAST "clear_attribs", tolua_unit_clear_attribs);
2017-10-08 17:07:42 +02:00
tolua_function(L, TOLUA_CAST "has_attrib", tolua_unit_has_attrib);
/* key-attributes for named flags: */
tolua_function(L, TOLUA_CAST "set_key", tolua_unit_set_key);
tolua_function(L, TOLUA_CAST "get_key", tolua_unit_get_key);
2017-10-08 17:07:42 +02:00
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: */
2017-10-08 17:07:42 +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 */
2017-10-08 17:07:42 +02:00
tolua_function(L, TOLUA_CAST "get_potion", tolua_unit_get_effect);
/* skills: */
2017-10-08 17:07:42 +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);
2017-10-08 17:07:42 +02:00
tolua_function(L, TOLUA_CAST "add_notice", tolua_unit_addnotice);
2017-10-08 17:07:42 +02:00
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);
tolua_variable(L, TOLUA_CAST "spells", tolua_unit_get_spells, 0);
tolua_function(L, TOLUA_CAST "cast_spell", tolua_unit_castspell);
2018-01-17 17:37:37 +01:00
tolua_function(L, TOLUA_CAST "effect", bind_unit_effect);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "magic", tolua_unit_get_magic,
tolua_unit_set_magic);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "aura", tolua_unit_get_aura,
tolua_unit_set_aura);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "building", tolua_unit_get_building,
tolua_unit_set_building);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "ship", tolua_unit_get_ship,
tolua_unit_set_ship);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "region", tolua_unit_get_region,
tolua_unit_set_region);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "number", tolua_unit_get_number,
tolua_unit_set_number);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "race", tolua_unit_get_race,
tolua_unit_set_race);
2017-10-08 17:07:42 +02:00
tolua_variable(L, TOLUA_CAST "hp_max", tolua_unit_get_hpmax, 0);
tolua_variable(L, TOLUA_CAST "aura_max", tolua_unit_get_auramax, 0);
tolua_function(L, TOLUA_CAST "equip", tolua_equipunit);
2017-10-08 17:07:42 +02:00
tolua_function(L, TOLUA_CAST "show", tolua_bufunit);
}
tolua_endmodule(L);
2010-08-08 10:06:34 +02:00
}
tolua_endmodule(L);
}