Merge branch 'develop' of github.com:ennorehling/eressea into develop

This commit is contained in:
Enno Rehling 2019-09-18 22:10:34 +02:00
commit 13f96e886e
6 changed files with 222 additions and 150 deletions

View File

@ -185,3 +185,50 @@ function test_trolls_pull_carts()
process_orders() process_orders()
assert_equal(r1, u1.region) assert_equal(r1, u1.region)
end end
function test_trolls_with_horses()
local r0 = region.create(0, 0, "plain")
local r1 = region.create(1, 0, "plain")
local r2 = region.create(2, 0, "plain")
local r3 = region.create(3, 0, "plain")
local f = faction.create("troll")
-- 1. 20 trolls can pull 5 loaded carts:
local u1 = unit.create(f, r0, 20)
u1:add_item("cart", 5)
-- trolls carry 10.8 GE, carts carry 100 GE:
u1:add_item("money", 100 * (5 * 100 + 2 * 108))
u1:add_order("NACH O O O")
process_orders()
assert_equal(r1, u1.region)
u1:add_item("horse", 20)
u1:add_item("money", 100 * 20 * 20)
process_orders()
assert_equal(r2, u1.region)
end
function test_trolls_ride_carts()
local r0 = region.create(0, 0, "plain")
local r1 = region.create(1, 0, "plain")
local r2 = region.create(2, 0, "plain")
local r3 = region.create(3, 0, "plain")
local r4 = region.create(4, 0, "plain")
local f = faction.create("troll")
-- 1. 20 trolls can pull 5 loaded carts:
local u1 = unit.create(f, r0, 20)
u1:add_item("cart", 5)
-- but with 10 or more horses, they should ride in the cart:
u1:set_skill("riding", 1, true)
u1:add_item("horse", 10)
-- trolls weigh 20 GE, horses carry 20, carts carry 100 GE:
u1:add_item("money", 100 * (10 * 20 + 5 * 100 - u1.number * 20))
u1:add_order("NACH O O O")
process_orders()
assert_equal(r2, u1.region)
u1:add_item("money", 1) -- just one wafer thin mint
process_orders()
assert_equal(r3, u1.region) -- can still walk
end

View File

@ -147,129 +147,129 @@ static int tolua_unit_get_group(lua_State * L)
static int tolua_unit_set_group(lua_State * L) static int tolua_unit_set_group(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
group *g = join_group(self, tolua_tostring(L, 2, 0)); group *g = join_group(u, tolua_tostring(L, 2, 0));
lua_pushboolean(L, g!=NULL); lua_pushboolean(L, g!=NULL);
return 1; return 1;
} }
static int tolua_unit_get_name(lua_State * L) static int tolua_unit_get_name(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, unit_getname(self)); tolua_pushstring(L, unit_getname(u));
return 1; return 1;
} }
static int tolua_unit_set_name(lua_State * L) static int tolua_unit_set_name(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setname(self, tolua_tostring(L, 2, 0)); unit_setname(u, tolua_tostring(L, 2, 0));
return 0; return 0;
} }
static int tolua_unit_get_info(lua_State * L) static int tolua_unit_get_info(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, unit_getinfo(self)); tolua_pushstring(L, unit_getinfo(u));
return 1; return 1;
} }
static int tolua_unit_set_info(lua_State * L) static int tolua_unit_set_info(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setinfo(self, tolua_tostring(L, 2, 0)); unit_setinfo(u, tolua_tostring(L, 2, 0));
return 0; return 0;
} }
static int tolua_unit_get_id(lua_State * L) static int tolua_unit_get_id(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getid(self)); lua_pushinteger(L, unit_getid(u));
return 1; return 1;
} }
static int tolua_unit_set_id(lua_State * L) static int tolua_unit_set_id(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setid(self, (int)tolua_tonumber(L, 2, 0)); unit_setid(u, (int)tolua_tonumber(L, 2, 0));
return 0; return 0;
} }
static int tolua_unit_get_auramax(lua_State * L) static int tolua_unit_get_auramax(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, max_spellpoints_depr(self->region, self)); lua_pushinteger(L, max_spellpoints_depr(u->region, u));
return 1; return 1;
} }
static int tolua_unit_get_hpmax(lua_State * L) static int tolua_unit_get_hpmax(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_max_hp(self)); lua_pushinteger(L, unit_max_hp(u));
return 1; return 1;
} }
static int tolua_unit_get_hp(lua_State * L) static int tolua_unit_get_hp(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_gethp(self)); lua_pushinteger(L, unit_gethp(u));
return 1; return 1;
} }
static int tolua_unit_set_hp(lua_State * L) static int tolua_unit_set_hp(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_sethp(self, (int)tolua_tonumber(L, 2, 0)); unit_sethp(u, (int)tolua_tonumber(L, 2, 0));
return 0; return 0;
} }
static int tolua_unit_get_number(lua_State * L) static int tolua_unit_get_number(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->number); lua_pushinteger(L, u->number);
return 1; return 1;
} }
static int tolua_unit_set_number(lua_State * L) static int tolua_unit_set_number(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
int number = (int)tolua_tonumber(L, 2, 0); int number = (int)tolua_tonumber(L, 2, 0);
if (self->number == 0) { if (u->number == 0) {
set_number(self, number); set_number(u, number);
self->hp = unit_max_hp(self) * number; u->hp = unit_max_hp(u) * number;
} }
else { else {
scale_number(self, number); scale_number(u, number);
} }
return 0; return 0;
} }
static int tolua_unit_get_flags(lua_State * L) static int tolua_unit_get_flags(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->flags); lua_pushinteger(L, u->flags);
return 1; return 1;
} }
static int tolua_unit_set_flags(lua_State * L) static int tolua_unit_set_flags(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
self->flags = (int)tolua_tonumber(L, 2, 0); u->flags = (int)tolua_tonumber(L, 2, 0);
return 0; return 0;
} }
static int tolua_unit_get_guard(lua_State * L) static int tolua_unit_get_guard(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushboolean(L, is_guard(self)); lua_pushboolean(L, is_guard(u));
return 1; return 1;
} }
static int tolua_unit_set_guard(lua_State * L) static int tolua_unit_set_guard(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
unsigned int flags = (unsigned int)tolua_tonumber(L, 2, 0); unsigned int flags = (unsigned int)tolua_tonumber(L, 2, 0);
setguard(self, flags!=0); setguard(u, flags!=0);
return 0; return 0;
} }
@ -285,8 +285,8 @@ static const char *unit_getmagic(const unit * u)
static int tolua_unit_get_magic(lua_State * L) static int tolua_unit_get_magic(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushstring(L, unit_getmagic(self)); lua_pushstring(L, unit_getmagic(u));
return 1; return 1;
} }
@ -306,64 +306,64 @@ static void unit_setmagic(unit * u, const char *type)
static int tolua_unit_set_magic(lua_State * L) static int tolua_unit_set_magic(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *type = tolua_tostring(L, 2, 0); const char *type = tolua_tostring(L, 2, 0);
unit_setmagic(self, type); unit_setmagic(u, type);
return 0; return 0;
} }
static int tolua_unit_get_aura(lua_State * L) static int tolua_unit_get_aura(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, get_spellpoints(self)); lua_pushinteger(L, get_spellpoints(u));
return 1; return 1;
} }
static int tolua_unit_set_aura(lua_State * L) static int tolua_unit_set_aura(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
set_spellpoints(self, (int)tolua_tonumber(L, 2, 0)); set_spellpoints(u, (int)tolua_tonumber(L, 2, 0));
return 0; return 0;
} }
static int tolua_unit_get_age(lua_State * L) static int tolua_unit_get_age(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, self->age); lua_pushinteger(L, u->age);
return 1; return 1;
} }
static int tolua_unit_set_age(lua_State * L) static int tolua_unit_set_age(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
self->age = (int)tolua_tonumber(L, 2, 0); u->age = (int)tolua_tonumber(L, 2, 0);
return 0; return 0;
} }
static int tolua_unit_get_status(lua_State * L) static int tolua_unit_get_status(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getstatus(self)); lua_pushinteger(L, unit_getstatus(u));
return 1; return 1;
} }
static int tolua_unit_set_status(lua_State * L) static int tolua_unit_set_status(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setstatus(self, (status_t)tolua_tonumber(L, 2, 0)); unit_setstatus(u, (status_t)tolua_tonumber(L, 2, 0));
return 0; return 0;
} }
static int tolua_unit_get_item(lua_State * L) static int tolua_unit_get_item(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0); const char *iname = tolua_tostring(L, 2, 0);
int result = -1; int result = -1;
if (iname != NULL) { if (iname != NULL) {
const item_type *itype = it_find(iname); const item_type *itype = it_find(iname);
if (itype != NULL) { if (itype != NULL) {
result = i_get(self->items, itype); result = i_get(u->items, itype);
} }
} }
lua_pushinteger(L, result); lua_pushinteger(L, result);
@ -372,13 +372,13 @@ static int tolua_unit_get_item(lua_State * L)
static int tolua_unit_get_effect(lua_State * L) static int tolua_unit_get_effect(lua_State * L)
{ {
const unit *self = (unit *)tolua_tousertype(L, 1, 0); const unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *potion_name = tolua_tostring(L, 2, 0); const char *potion_name = tolua_tostring(L, 2, 0);
int result = -1; int result = -1;
const item_type *it_potion = it_find(potion_name); const item_type *it_potion = it_find(potion_name);
if (it_potion != NULL) { if (it_potion != NULL) {
result = get_effect(self, it_potion); result = get_effect(u, it_potion);
} }
lua_pushinteger(L, result); lua_pushinteger(L, result);
@ -387,7 +387,7 @@ static int tolua_unit_get_effect(lua_State * L)
static int tolua_unit_add_item(lua_State * L) static int tolua_unit_add_item(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0); const char *iname = tolua_tostring(L, 2, 0);
int number = (int)tolua_tonumber(L, 3, 0); int number = (int)tolua_tonumber(L, 3, 0);
int result = -1; int result = -1;
@ -395,7 +395,7 @@ static int tolua_unit_add_item(lua_State * L)
if (iname != NULL) { if (iname != NULL) {
const item_type *itype = it_find(iname); const item_type *itype = it_find(iname);
if (itype != NULL) { if (itype != NULL) {
item *i = i_change(&self->items, itype, number); item *i = i_change(&u->items, itype, number);
result = i ? i->number : 0; result = i ? i->number : 0;
} }
} }
@ -405,12 +405,12 @@ static int tolua_unit_add_item(lua_State * L)
static int tolua_unit_getskill(lua_State * L) static int tolua_unit_getskill(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0); const char *skname = tolua_tostring(L, 2, 0);
skill_t sk = findskill(skname); skill_t sk = findskill(skname);
int value = -1; int value = -1;
if (sk != NOSKILL) { if (sk != NOSKILL) {
skill *sv = unit_skill(self, sk); skill *sv = unit_skill(u, sk);
if (sv) { if (sv) {
value = sv->level; value = sv->level;
} }
@ -423,10 +423,10 @@ static int tolua_unit_getskill(lua_State * L)
static int tolua_unit_effskill(lua_State * L) static int tolua_unit_effskill(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0); const char *skname = tolua_tostring(L, 2, 0);
skill_t sk = findskill(skname); skill_t sk = findskill(skname);
int value = (sk == NOSKILL) ? -1 : effskill(self, sk, NULL); int value = (sk == NOSKILL) ? -1 : effskill(u, sk, NULL);
lua_pushinteger(L, value); lua_pushinteger(L, value);
return 1; return 1;
} }
@ -438,10 +438,10 @@ typedef struct event {
static int tolua_unit_addnotice(lua_State * L) static int tolua_unit_addnotice(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0); const char *str = tolua_tostring(L, 2, 0);
addmessage(self->region, self->faction, str, MSG_MESSAGE, ML_IMPORTANT); addmessage(u->region, u->faction, str, MSG_MESSAGE, ML_IMPORTANT);
return 0; return 0;
} }
@ -475,11 +475,11 @@ static void unit_castspell(unit * u, const char *name, int level)
static int tolua_unit_castspell(lua_State * L) static int tolua_unit_castspell(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0); const char *str = tolua_tostring(L, 2, 0);
int level = (int)tolua_tonumber(L, 3, 1); int level = (int)tolua_tonumber(L, 3, 1);
unit_castspell(self, str, level); unit_castspell(u, str, level);
return 0; return 0;
} }
@ -505,17 +505,17 @@ static int tolua_unit_addspell(lua_State * L)
static int tolua_unit_set_racename(lua_State * L) static int tolua_unit_set_racename(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0); const char *str = tolua_tostring(L, 2, 0);
set_racename(&self->attribs, str); set_racename(&u->attribs, str);
return 0; return 0;
} }
static int tolua_unit_get_racename(lua_State * L) static int tolua_unit_get_racename(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
attrib *a = a_find(self->attribs, &at_racename); attrib *a = a_find(u->attribs, &at_racename);
if (a) { if (a) {
tolua_pushstring(L, get_racename(a)); tolua_pushstring(L, get_racename(a));
return 1; return 1;
@ -525,29 +525,30 @@ static int tolua_unit_get_racename(lua_State * L)
static int tolua_unit_setskill(lua_State * L) static int tolua_unit_setskill(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *skname = tolua_tostring(L, 2, 0); const char *skname = tolua_tostring(L, 2, 0);
int level = (int)tolua_tonumber(L, 3, 0); int level = (int)tolua_tonumber(L, 3, 0);
bool rcmod = tolua_toboolean(L, 4, 0);
skill_t sk = findskill(skname); skill_t sk = findskill(skname);
if (rcmod) level -= u_race(u)->bonus[sk];
if (sk != NOSKILL) { if (sk != NOSKILL) {
set_level(self, sk, level); set_level(u, sk, level);
}
else {
level = -1;
}
lua_pushinteger(L, level); lua_pushinteger(L, level);
return 1; return 1;
}
return 0;
} }
static int tolua_unit_use_pooled(lua_State * L) static int tolua_unit_use_pooled(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0); const char *iname = tolua_tostring(L, 2, 0);
int number = (int)tolua_tonumber(L, 3, 0); int number = (int)tolua_tonumber(L, 3, 0);
const resource_type *rtype = rt_find(iname); const resource_type *rtype = rt_find(iname);
int result = -1; int result = -1;
if (rtype != NULL) { if (rtype != NULL) {
result = use_pooled(self, rtype, GET_DEFAULT, number); result = use_pooled(u, rtype, GET_DEFAULT, number);
} }
lua_pushinteger(L, result); lua_pushinteger(L, result);
return 1; return 1;
@ -555,12 +556,12 @@ static int tolua_unit_use_pooled(lua_State * L)
static int tolua_unit_get_pooled(lua_State * L) static int tolua_unit_get_pooled(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *iname = tolua_tostring(L, 2, 0); const char *iname = tolua_tostring(L, 2, 0);
const resource_type *rtype = rt_find(iname); const resource_type *rtype = rt_find(iname);
int result = -1; int result = -1;
if (rtype != NULL) { if (rtype != NULL) {
result = get_pooled(self, rtype, GET_DEFAULT, INT_MAX); result = get_pooled(u, rtype, GET_DEFAULT, INT_MAX);
} }
lua_pushinteger(L, result); lua_pushinteger(L, result);
return 1; return 1;
@ -577,8 +578,8 @@ static unit *unit_getfamiliar(const unit * u)
static int tolua_unit_get_familiar(lua_State * L) static int tolua_unit_get_familiar(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, unit_getfamiliar(self), TOLUA_CAST "unit"); tolua_pushusertype(L, unit_getfamiliar(u), TOLUA_CAST "unit");
return 1; return 1;
} }
@ -597,8 +598,8 @@ static int tolua_unit_set_familiar(lua_State * L)
static int tolua_unit_get_building(lua_State * L) static int tolua_unit_get_building(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, self->building, TOLUA_CAST "building"); tolua_pushusertype(L, u->building, TOLUA_CAST "building");
return 1; return 1;
} }
@ -622,8 +623,8 @@ static int tolua_unit_set_building(lua_State * L)
static int tolua_unit_get_ship(lua_State * L) static int tolua_unit_get_ship(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, self->ship, TOLUA_CAST "ship"); tolua_pushusertype(L, u->ship, TOLUA_CAST "ship");
return 1; return 1;
} }
@ -638,17 +639,17 @@ static void unit_setship(unit * u, ship * s)
static int tolua_unit_set_ship(lua_State * L) static int tolua_unit_set_ship(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
if (self->faction) { if (u->faction) {
unit_setship(self, (ship *)tolua_tousertype(L, 2, 0)); unit_setship(u, (ship *)tolua_tousertype(L, 2, 0));
} }
return 0; return 0;
} }
static int tolua_unit_get_region(lua_State * L) static int tolua_unit_get_region(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, self->region, TOLUA_CAST "region"); tolua_pushusertype(L, u->region, TOLUA_CAST "region");
return 1; return 1;
} }
@ -659,29 +660,29 @@ static void unit_setregion(unit * u, region * r)
static int tolua_unit_set_region(lua_State * L) static int tolua_unit_set_region(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
unit_setregion(self, (region *)tolua_tousertype(L, 2, 0)); unit_setregion(u, (region *)tolua_tousertype(L, 2, 0));
return 0; return 0;
} }
static int tolua_unit_get_order(lua_State * L) static int tolua_unit_get_order(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, -1); int index = (int)tolua_tonumber(L, 2, -1);
order *ord = NULL; order *ord = NULL;
if (index < 0) { if (index < 0) {
ord = self->thisorder; ord = u->thisorder;
} }
else { else {
int i; int i;
ord = self->orders; ord = u->orders;
for (i = 0; ord && i != index; ++i) { for (i = 0; ord && i != index; ++i) {
ord = ord->next; ord = ord->next;
} }
} }
if (ord) { if (ord) {
char buffer[1024]; char buffer[1024];
get_command(ord, self->faction->locale, buffer, sizeof(buffer)); get_command(ord, u->faction->locale, buffer, sizeof(buffer));
lua_pushstring(L, buffer); lua_pushstring(L, buffer);
return 1; return 1;
} }
@ -690,30 +691,30 @@ static int tolua_unit_get_order(lua_State * L)
static int tolua_unit_add_order(lua_State * L) static int tolua_unit_add_order(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *str = tolua_tostring(L, 2, 0); const char *str = tolua_tostring(L, 2, 0);
order *ord = parse_order(str, self->faction->locale); order *ord = parse_order(str, u->faction->locale);
unit_addorder(self, ord); unit_addorder(u, ord);
return 0; return 0;
} }
static int tolua_unit_clear_orders(lua_State * L) static int tolua_unit_clear_orders(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
free_orders(&self->orders); free_orders(&u->orders);
return 0; return 0;
} }
static int tolua_unit_get_items(lua_State * L) static int tolua_unit_get_items(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
item **item_ptr = (item **)lua_newuserdata(L, sizeof(item *)); item **item_ptr = (item **)lua_newuserdata(L, sizeof(item *));
luaL_getmetatable(L, TOLUA_CAST "item"); luaL_getmetatable(L, TOLUA_CAST "item");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
*item_ptr = self->items; *item_ptr = u->items;
lua_pushcclosure(L, tolua_itemlist_next, 1); lua_pushcclosure(L, tolua_itemlist_next, 1);
@ -722,8 +723,8 @@ static int tolua_unit_get_items(lua_State * L)
static int tolua_unit_get_spells(lua_State * L) static int tolua_unit_get_spells(lua_State * L)
{ {
unit *self = (unit *) tolua_tousertype(L, 1, 0); unit *u = (unit *) tolua_tousertype(L, 1, 0);
struct sc_mage *mage = self ? get_mage(self) : NULL; struct sc_mage *mage = u ? get_mage(u) : NULL;
spellbook *sb = mage_get_spellbook(mage); spellbook *sb = mage_get_spellbook(mage);
selist *slist = 0; selist *slist = 0;
if (sb) { if (sb) {
@ -734,10 +735,10 @@ static int tolua_unit_get_spells(lua_State * L)
} }
static int tolua_unit_get_curse(lua_State *L) { static int tolua_unit_get_curse(lua_State *L) {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0); const char *name = tolua_tostring(L, 2, 0);
if (self->attribs) { if (u->attribs) {
curse * c = get_curse(self->attribs, ct_find(name)); curse * c = get_curse(u->attribs, ct_find(name));
if (c) { if (c) {
lua_pushnumber(L, curse_geteffect(c)); lua_pushnumber(L, curse_geteffect(c));
return 1; return 1;
@ -747,9 +748,9 @@ static int tolua_unit_get_curse(lua_State *L) {
} }
static int tolua_unit_has_attrib(lua_State *L) { static int tolua_unit_has_attrib(lua_State *L) {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0); const char *name = tolua_tostring(L, 2, 0);
attrib * a = self->attribs; attrib * a = u->attribs;
while (a) { while (a) {
if (strcmp(a->type->name, name) == 0) { if (strcmp(a->type->name, name) == 0) {
break; break;
@ -762,105 +763,105 @@ static int tolua_unit_has_attrib(lua_State *L) {
static int tolua_unit_get_key(lua_State * L) static int tolua_unit_get_key(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0); const char *name = tolua_tostring(L, 2, 0);
int flag = atoi36(name); int flag = atoi36(name);
lua_pushboolean(L, key_get(self->attribs, flag)); lua_pushboolean(L, key_get(u->attribs, flag));
return 1; return 1;
} }
static int tolua_unit_set_key(lua_State * L) static int tolua_unit_set_key(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0); const char *name = tolua_tostring(L, 2, 0);
int value = (int)tolua_tonumber(L, 3, 0); int value = (int)tolua_tonumber(L, 3, 0);
int flag = atoi36(name); int flag = atoi36(name);
if (value) { if (value) {
key_set(&self->attribs, flag, value); key_set(&u->attribs, flag, value);
} }
else { else {
key_unset(&self->attribs, flag); key_unset(&u->attribs, flag);
} }
return 0; return 0;
} }
static int tolua_unit_get_flag(lua_State * L) static int tolua_unit_get_flag(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, NULL); unit *u = (unit *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0); int bit = (int)tolua_tonumber(L, 2, 0);
lua_pushboolean(L, (self->flags & (1 << bit))); lua_pushboolean(L, (u->flags & (1 << bit)));
return 1; return 1;
} }
static int tolua_unit_set_flag(lua_State * L) static int tolua_unit_set_flag(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, NULL); unit *u = (unit *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0); int bit = (int)tolua_tonumber(L, 2, 0);
int set = tolua_toboolean(L, 3, 1); int set = tolua_toboolean(L, 3, 1);
if (set) if (set)
self->flags |= (1 << bit); u->flags |= (1 << bit);
else else
self->flags &= ~(1 << bit); u->flags &= ~(1 << bit);
return 0; return 0;
} }
static int tolua_unit_get_weight(lua_State * L) static int tolua_unit_get_weight(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getweight(self)); lua_pushinteger(L, unit_getweight(u));
return 1; return 1;
} }
static int tolua_unit_get_capacity(lua_State * L) static int tolua_unit_get_capacity(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushinteger(L, unit_getcapacity(self)); lua_pushinteger(L, unit_getcapacity(u));
return 1; return 1;
} }
static int tolua_unit_get_faction(lua_State * L) static int tolua_unit_get_faction(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushusertype(L, (void *)self->faction, TOLUA_CAST "faction"); tolua_pushusertype(L, (void *)u->faction, TOLUA_CAST "faction");
return 1; return 1;
} }
static int tolua_unit_set_faction(lua_State * L) static int tolua_unit_set_faction(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
faction *f = (faction *)tolua_tousertype(L, 2, 0); faction *f = (faction *)tolua_tousertype(L, 2, 0);
u_setfaction(self, f); u_setfaction(u, f);
return 0; return 0;
} }
static int tolua_unit_get_race(lua_State * L) static int tolua_unit_get_race(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
tolua_pushstring(L, u_race(self)->_name); tolua_pushstring(L, u_race(u)->_name);
return 1; return 1;
} }
static int tolua_unit_set_race(lua_State * L) static int tolua_unit_set_race(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
const char *rcname = tolua_tostring(L, 2, 0); const char *rcname = tolua_tostring(L, 2, 0);
const race *rc = rc_find(rcname); const race *rc = rc_find(rcname);
if (rc != NULL) { if (rc != NULL) {
if (self->irace == u_race(self)) { if (u->irace == u_race(u)) {
self->irace = NULL; u->irace = NULL;
} }
u_setrace(self, rc); u_setrace(u, rc);
} }
return 0; return 0;
} }
static int tolua_unit_destroy(lua_State * L) static int tolua_unit_destroy(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
if (self) { if (u) {
remove_unit(&self->region->units, self); remove_unit(&u->region->units, u);
} }
return 0; return 0;
} }
@ -884,25 +885,25 @@ static int tolua_unit_create(lua_State * L)
static int tolua_unit_tostring(lua_State * L) static int tolua_unit_tostring(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *u = (unit *)tolua_tousertype(L, 1, 0);
lua_pushstring(L, unitname(self)); lua_pushstring(L, unitname(u));
return 1; return 1;
} }
static int tolua_event_gettype(lua_State * L) static int tolua_event_gettype(lua_State * L)
{ {
event *self = (event *)tolua_tousertype(L, 1, 0); event *u = (event *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, 0); int index = (int)tolua_tonumber(L, 2, 0);
lua_pushstring(L, self->args[index].type); lua_pushstring(L, u->args[index].type);
return 1; return 1;
} }
static int tolua_event_get(lua_State * L) static int tolua_event_get(lua_State * L)
{ {
struct event *self = (struct event *)tolua_tousertype(L, 1, 0); struct event *u = (struct event *)tolua_tousertype(L, 1, 0);
int index = (int)tolua_tonumber(L, 2, 0); int index = (int)tolua_tonumber(L, 2, 0);
event_arg *arg = self->args + index; event_arg *arg = u->args + index;
if (arg->type) { if (arg->type) {
if (strcmp(arg->type, "string") == 0) { if (strcmp(arg->type, "string") == 0) {

View File

@ -282,10 +282,22 @@ static int forget_cmd(unit * u, order * ord)
sk = get_skill(s, u->faction->locale); sk = get_skill(s, u->faction->locale);
if (sk != NOSKILL) { if (sk != NOSKILL) {
if (sk == SK_MAGIC && is_familiar(u)) { if (sk == SK_MAGIC) {
if (is_familiar(u)) {
/* some units cannot forget their innate magical abilities */ /* some units cannot forget their innate magical abilities */
return 0; return 0;
} }
else {
unit *ufam = get_familiar(u);
if (ufam) {
a_removeall(&ufam->attribs, NULL);
u_setfaction(ufam, get_monsters());
unit_convert_race(ufam, NULL, "ghost");
}
a_removeall(&u->attribs, &at_mage);
a_removeall(&u->attribs, &at_familiar);
}
}
ADDMSG(&u->faction->msgs, msg_message("forget", "unit skill", u, sk)); ADDMSG(&u->faction->msgs, msg_message("forget", "unit skill", u, sk));
set_level(u, sk, 0); set_level(u, sk, 0);
} }

View File

@ -395,7 +395,7 @@ void save_special_items(unit *usrc)
/* some units have plural names, it would be neat if they aren't single: */ /* some units have plural names, it would be neat if they aren't single: */
scale_number(u, 2); scale_number(u, 2);
} }
set_racename(&u->attribs, "ghost"); unit_convert_race(u, rc_ghost, "ghost");
give_special_items(u, &usrc->items); give_special_items(u, &usrc->items);
} }

View File

@ -1833,3 +1833,14 @@ double u_heal_factor(const unit * u)
} }
return 1.0; return 1.0;
} }
void unit_convert_race(unit *u, const race *rc, const char *rcname)
{
if (rc && u->_race != rc) {
u_setrace(u, rc);
}
if (rcname && strcmp(rcname, u->_race->_name) != 0) {
set_racename(&u->attribs, rcname);
}
}

View File

@ -221,6 +221,7 @@ extern "C" {
char *write_unitname(const struct unit *u, char *buffer, size_t size); char *write_unitname(const struct unit *u, char *buffer, size_t size);
bool unit_name_equals_race(const struct unit *u); bool unit_name_equals_race(const struct unit *u);
void unit_convert_race(struct unit *u, const struct race *rc, const char *rcname);
/* getunit results: */ /* getunit results: */
#define GET_UNIT 0 #define GET_UNIT 0
#define GET_NOTFOUND 1 #define GET_NOTFOUND 1