From ea9e31d1b2eea6463108886019bf1f4da906194c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 15 Sep 2019 20:32:07 +0200 Subject: [PATCH 1/2] tests for trolls riding on carts. --- scripts/tests/e2/carts.lua | 47 ++++++ src/bind_unit.c | 293 +++++++++++++++++++------------------ 2 files changed, 194 insertions(+), 146 deletions(-) diff --git a/scripts/tests/e2/carts.lua b/scripts/tests/e2/carts.lua index c2acbc25e..025b473df 100644 --- a/scripts/tests/e2/carts.lua +++ b/scripts/tests/e2/carts.lua @@ -185,3 +185,50 @@ function test_trolls_pull_carts() process_orders() assert_equal(r1, u1.region) 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 diff --git a/src/bind_unit.c b/src/bind_unit.c index c5954082b..f12b60b55 100644 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -147,129 +147,129 @@ static int tolua_unit_get_group(lua_State * L) static int tolua_unit_set_group(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - group *g = join_group(self, tolua_tostring(L, 2, 0)); + 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; } static int tolua_unit_get_name(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushstring(L, unit_getname(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushstring(L, unit_getname(u)); return 1; } static int tolua_unit_set_name(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - unit_setname(self, tolua_tostring(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + unit_setname(u, tolua_tostring(L, 2, 0)); return 0; } static int tolua_unit_get_info(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushstring(L, unit_getinfo(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushstring(L, unit_getinfo(u)); return 1; } static int tolua_unit_set_info(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - unit_setinfo(self, tolua_tostring(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + unit_setinfo(u, tolua_tostring(L, 2, 0)); return 0; } static int tolua_unit_get_id(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, unit_getid(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, unit_getid(u)); return 1; } static int tolua_unit_set_id(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - unit_setid(self, (int)tolua_tonumber(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + unit_setid(u, (int)tolua_tonumber(L, 2, 0)); return 0; } static int tolua_unit_get_auramax(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, max_spellpoints_depr(self->region, self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, max_spellpoints_depr(u->region, u)); return 1; } static int tolua_unit_get_hpmax(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, unit_max_hp(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, unit_max_hp(u)); return 1; } static int tolua_unit_get_hp(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, unit_gethp(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, unit_gethp(u)); return 1; } static int tolua_unit_set_hp(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - unit_sethp(self, (int)tolua_tonumber(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + unit_sethp(u, (int)tolua_tonumber(L, 2, 0)); return 0; } static int tolua_unit_get_number(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, self->number); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, u->number); return 1; } 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); - if (self->number == 0) { - set_number(self, number); - self->hp = unit_max_hp(self) * number; + if (u->number == 0) { + set_number(u, number); + u->hp = unit_max_hp(u) * number; } else { - scale_number(self, number); + scale_number(u, number); } return 0; } static int tolua_unit_get_flags(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, self->flags); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, u->flags); return 1; } static int tolua_unit_set_flags(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - self->flags = (int)tolua_tonumber(L, 2, 0); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + u->flags = (int)tolua_tonumber(L, 2, 0); return 0; } static int tolua_unit_get_guard(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushboolean(L, is_guard(self)); + 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) { - 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); - setguard(self, flags!=0); + setguard(u, flags!=0); return 0; } @@ -285,8 +285,8 @@ static const char *unit_getmagic(const unit * u) static int tolua_unit_get_magic(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushstring(L, unit_getmagic(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushstring(L, unit_getmagic(u)); return 1; } @@ -306,64 +306,64 @@ static void unit_setmagic(unit * u, const char *type) 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); - unit_setmagic(self, type); + unit_setmagic(u, type); return 0; } static int tolua_unit_get_aura(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, get_spellpoints(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, get_spellpoints(u)); return 1; } static int tolua_unit_set_aura(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - set_spellpoints(self, (int)tolua_tonumber(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + set_spellpoints(u, (int)tolua_tonumber(L, 2, 0)); return 0; } static int tolua_unit_get_age(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, self->age); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, u->age); return 1; } static int tolua_unit_set_age(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - self->age = (int)tolua_tonumber(L, 2, 0); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + u->age = (int)tolua_tonumber(L, 2, 0); return 0; } static int tolua_unit_get_status(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, unit_getstatus(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, unit_getstatus(u)); return 1; } static int tolua_unit_set_status(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - unit_setstatus(self, (status_t)tolua_tonumber(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + unit_setstatus(u, (status_t)tolua_tonumber(L, 2, 0)); return 0; } 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); int result = -1; if (iname != NULL) { const item_type *itype = it_find(iname); if (itype != NULL) { - result = i_get(self->items, itype); + result = i_get(u->items, itype); } } 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) { - 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); int result = -1; const item_type *it_potion = it_find(potion_name); if (it_potion != NULL) { - result = get_effect(self, it_potion); + result = get_effect(u, it_potion); } 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) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); + 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; @@ -395,7 +395,7 @@ static int tolua_unit_add_item(lua_State * L) if (iname != NULL) { const item_type *itype = it_find(iname); if (itype != NULL) { - item *i = i_change(&self->items, itype, number); + item *i = i_change(&u->items, itype, number); 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) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); + 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) { - skill *sv = unit_skill(self, sk); + skill *sv = unit_skill(u, sk); if (sv) { value = sv->level; } @@ -423,10 +423,10 @@ static int tolua_unit_getskill(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); 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); return 1; } @@ -438,10 +438,10 @@ typedef struct event { 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); - addmessage(self->region, self->faction, str, MSG_MESSAGE, ML_IMPORTANT); + addmessage(u->region, u->faction, str, MSG_MESSAGE, ML_IMPORTANT); 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) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); + unit *u = (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); + unit_castspell(u, str, level); return 0; } @@ -505,17 +505,17 @@ static int tolua_unit_addspell(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); - set_racename(&self->attribs, str); + set_racename(&u->attribs, str); return 0; } static int tolua_unit_get_racename(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - attrib *a = a_find(self->attribs, &at_racename); + 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; @@ -525,29 +525,30 @@ static int tolua_unit_get_racename(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); int level = (int)tolua_tonumber(L, 3, 0); + bool rcmod = tolua_toboolean(L, 4, 0); skill_t sk = findskill(skname); + + if (rcmod) level -= u_race(u)->bonus[sk]; if (sk != NOSKILL) { - set_level(self, sk, level); + set_level(u, sk, level); + lua_pushinteger(L, level); + return 1; } - else { - level = -1; - } - lua_pushinteger(L, level); - return 1; + return 0; } 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); 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); + result = use_pooled(u, rtype, GET_DEFAULT, number); } lua_pushinteger(L, result); return 1; @@ -555,12 +556,12 @@ static int tolua_unit_use_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 resource_type *rtype = rt_find(iname); int result = -1; 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); return 1; @@ -577,8 +578,8 @@ static unit *unit_getfamiliar(const unit * u) static int tolua_unit_get_familiar(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushusertype(L, unit_getfamiliar(self), TOLUA_CAST "unit"); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushusertype(L, unit_getfamiliar(u), TOLUA_CAST "unit"); return 1; } @@ -597,8 +598,8 @@ static int tolua_unit_set_familiar(lua_State * L) static int tolua_unit_get_building(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushusertype(L, self->building, TOLUA_CAST "building"); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushusertype(L, u->building, TOLUA_CAST "building"); return 1; } @@ -622,8 +623,8 @@ static int tolua_unit_set_building(lua_State * L) static int tolua_unit_get_ship(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushusertype(L, self->ship, TOLUA_CAST "ship"); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushusertype(L, u->ship, TOLUA_CAST "ship"); return 1; } @@ -638,17 +639,17 @@ static void unit_setship(unit * u, ship * s) static int tolua_unit_set_ship(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - if (self->faction) { - unit_setship(self, (ship *)tolua_tousertype(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + if (u->faction) { + unit_setship(u, (ship *)tolua_tousertype(L, 2, 0)); } return 0; } static int tolua_unit_get_region(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushusertype(L, self->region, TOLUA_CAST "region"); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushusertype(L, u->region, TOLUA_CAST "region"); return 1; } @@ -659,29 +660,29 @@ static void unit_setregion(unit * u, region * r) static int tolua_unit_set_region(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - unit_setregion(self, (region *)tolua_tousertype(L, 2, 0)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + unit_setregion(u, (region *)tolua_tousertype(L, 2, 0)); return 0; } 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); order *ord = NULL; if (index < 0) { - ord = self->thisorder; + ord = u->thisorder; } else { int i; - ord = self->orders; + ord = u->orders; for (i = 0; ord && i != index; ++i) { ord = ord->next; } } if (ord) { 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); return 1; } @@ -690,30 +691,30 @@ static int tolua_unit_get_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); - order *ord = parse_order(str, self->faction->locale); - unit_addorder(self, ord); + order *ord = parse_order(str, u->faction->locale); + unit_addorder(u, ord); return 0; } static int tolua_unit_clear_orders(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - free_orders(&self->orders); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + free_orders(&u->orders); return 0; } 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 *)); luaL_getmetatable(L, TOLUA_CAST "item"); lua_setmetatable(L, -2); - *item_ptr = self->items; + *item_ptr = u->items; 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) { - unit *self = (unit *) tolua_tousertype(L, 1, 0); - struct sc_mage *mage = self ? get_mage(self) : NULL; + 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) { @@ -734,10 +735,10 @@ static int tolua_unit_get_spells(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); - if (self->attribs) { - curse * c = get_curse(self->attribs, ct_find(name)); + if (u->attribs) { + curse * c = get_curse(u->attribs, ct_find(name)); if (c) { lua_pushnumber(L, curse_geteffect(c)); return 1; @@ -747,9 +748,9 @@ static int tolua_unit_get_curse(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); - attrib * a = self->attribs; + attrib * a = u->attribs; while (a) { if (strcmp(a->type->name, name) == 0) { break; @@ -762,105 +763,105 @@ static int tolua_unit_has_attrib(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); int flag = atoi36(name); - lua_pushboolean(L, key_get(self->attribs, flag)); + lua_pushboolean(L, key_get(u->attribs, flag)); return 1; } 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); int value = (int)tolua_tonumber(L, 3, 0); int flag = atoi36(name); if (value) { - key_set(&self->attribs, flag, value); + key_set(&u->attribs, flag, value); } else { - key_unset(&self->attribs, flag); + key_unset(&u->attribs, flag); } return 0; } 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); - lua_pushboolean(L, (self->flags & (1 << bit))); + lua_pushboolean(L, (u->flags & (1 << bit))); return 1; } 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 set = tolua_toboolean(L, 3, 1); if (set) - self->flags |= (1 << bit); + u->flags |= (1 << bit); else - self->flags &= ~(1 << bit); + u->flags &= ~(1 << bit); return 0; } static int tolua_unit_get_weight(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, unit_getweight(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, unit_getweight(u)); return 1; } static int tolua_unit_get_capacity(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushinteger(L, unit_getcapacity(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushinteger(L, unit_getcapacity(u)); return 1; } static int tolua_unit_get_faction(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushusertype(L, (void *)self->faction, TOLUA_CAST "faction"); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushusertype(L, (void *)u->faction, TOLUA_CAST "faction"); return 1; } 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); - u_setfaction(self, f); + u_setfaction(u, f); return 0; } static int tolua_unit_get_race(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - tolua_pushstring(L, u_race(self)->_name); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + tolua_pushstring(L, u_race(u)->_name); return 1; } 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 race *rc = rc_find(rcname); if (rc != NULL) { - if (self->irace == u_race(self)) { - self->irace = NULL; + if (u->irace == u_race(u)) { + u->irace = NULL; } - u_setrace(self, rc); + u_setrace(u, rc); } return 0; } static int tolua_unit_destroy(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - if (self) { - remove_unit(&self->region->units, self); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + if (u) { + remove_unit(&u->region->units, u); } return 0; } @@ -884,25 +885,25 @@ static int tolua_unit_create(lua_State * L) static int tolua_unit_tostring(lua_State * L) { - unit *self = (unit *)tolua_tousertype(L, 1, 0); - lua_pushstring(L, unitname(self)); + unit *u = (unit *)tolua_tousertype(L, 1, 0); + lua_pushstring(L, unitname(u)); return 1; } 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); - lua_pushstring(L, self->args[index].type); + lua_pushstring(L, u->args[index].type); return 1; } 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); - event_arg *arg = self->args + index; + event_arg *arg = u->args + index; if (arg->type) { if (strcmp(arg->type, "string") == 0) { From d5104fa55a02186fc0abd2192a112da39b9150d8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 18 Sep 2019 20:55:44 +0200 Subject: [PATCH 2/2] Bug 2609 VERGESSE Magie --- src/economy.c | 18 +++++++++++++++--- src/kernel/faction.c | 2 +- src/kernel/unit.c | 11 +++++++++++ src/kernel/unit.h | 1 + 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/economy.c b/src/economy.c index 1fd202369..b73845c06 100644 --- a/src/economy.c +++ b/src/economy.c @@ -282,9 +282,21 @@ static int forget_cmd(unit * u, order * ord) sk = get_skill(s, u->faction->locale); if (sk != NOSKILL) { - if (sk == SK_MAGIC && is_familiar(u)) { - /* some units cannot forget their innate magical abilities */ - return 0; + if (sk == SK_MAGIC) { + if (is_familiar(u)) { + /* some units cannot forget their innate magical abilities */ + 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)); set_level(u, sk, 0); diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 882c1333a..81f2d42b1 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -395,7 +395,7 @@ void save_special_items(unit *usrc) /* some units have plural names, it would be neat if they aren't single: */ scale_number(u, 2); } - set_racename(&u->attribs, "ghost"); + unit_convert_race(u, rc_ghost, "ghost"); give_special_items(u, &usrc->items); } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index f8e737587..06463820c 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1833,3 +1833,14 @@ double u_heal_factor(const unit * u) } 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); + } +} + diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 3290c4f78..863dccd13 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -221,6 +221,7 @@ extern "C" { char *write_unitname(const struct unit *u, char *buffer, size_t size); 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: */ #define GET_UNIT 0 #define GET_NOTFOUND 1