diff --git a/scripts/tests/common.lua b/scripts/tests/common.lua index 06fe05807..3e17d3414 100644 --- a/scripts/tests/common.lua +++ b/scripts/tests/common.lua @@ -1097,3 +1097,82 @@ function test_building_unique() assert_equal(1, bcount) -- only one should be completed end end + +function test_bug_1875_use_normal() + -- see http://bugs.eressea.de/view.php?id=1875 + local r = region.create(0, 0, "plain") + r:set_resource("peasant", 0) + + settings.set("rules.economy.food", "0") -- food is not free + + local f = faction.create("noreply@eressea.de", "demon", "de") + local u = unit.create(f, r, 1) + + u:add_item("peasantblood", 1) + u:add_order("BENUTZE 1 Bauernblut") + + assert_equal(1, u:get_item("peasantblood")) + assert_equal(0, u:get_potion("peasantblood")) + + process_orders() + + assert_equal(0, u:get_item("peasantblood")) + assert_equal(0, r:get_resource("peasant")) + assert_equal(99, u:get_potion("peasantblood")) -- unit used one peasantblood effect +end + +function test_bug_1875_use_help() + -- see http://bugs.eressea.de/view.php?id=1875 + local r = region.create(0, 0, "plain") + r:set_resource("peasant", 0) + + settings.set("rules.economy.food", "0") -- food is not free + + local f = faction.create("noreply@eressea.de", "demon", "de") + local u = unit.create(f, r, 1) + local u2 = unit.create(f, r, 1) + + u:add_item("peasantblood", 1) + u:add_order("BENUTZE 1 Bauernblut") + + assert_equal(1, u:get_item("peasantblood")) + assert_equal(0, u:get_potion("peasantblood")) + assert_equal(0, u2:get_item("peasantblood")) + assert_equal(0, u2:get_potion("peasantblood")) + + process_orders() + + assert_equal(0, u:get_item("peasantblood")) + assert_equal(0, r:get_resource("peasant")) + assert_equal(0, u2:get_potion("peasantblood")) -- first unit helps this unit + assert_equal(98, u:get_potion("peasantblood")) -- unit uses one peasantblood effect +end + +function test_bug_1875_use_own_first() + -- see http://bugs.eressea.de/view.php?id=1875 + local r = region.create(0, 0, "plain") + r:set_resource("peasant", 0) + + settings.set("rules.economy.food", "0") -- food is not free + + local f = faction.create("noreply@eressea.de", "demon", "de") + local u = unit.create(f, r, 1) + local u2 = unit.create(f, r, 1) + + u:add_item("peasantblood", 1) + u:add_order("BENUTZE 1 Bauernblut") + u2:add_item("peasantblood", 1) + u2:add_order("BENUTZE 1 Bauernblut") + + assert_equal(1, u:get_item("peasantblood")) + assert_equal(0, u:get_potion("peasantblood")) + assert_equal(1, u2:get_item("peasantblood")) + assert_equal(0, u2:get_potion("peasantblood")) + + process_orders() + + assert_equal(0, u:get_item("peasantblood")) + assert_equal(0, r:get_resource("peasant")) + assert_equal(99, u:get_potion("peasantblood")) -- unit uses one peasantblood effect + assert_equal(99, u2:get_potion("peasantblood")) -- u2 uses its own effect before u's +end diff --git a/src/bindings/bind_unit.c b/src/bindings/bind_unit.c index 3a016b900..e2d6f5efd 100644 --- a/src/bindings/bind_unit.c +++ b/src/bindings/bind_unit.c @@ -23,6 +23,7 @@ without prior permission by the authors of Eressea. #include /* kernel includes */ +#include #include #include #include @@ -330,6 +331,24 @@ static int tolua_unit_get_item(lua_State * L) return 1; } +static int tolua_unit_get_effect(lua_State * L) +{ + const unit *self = (unit *)tolua_tousertype(L, 1, 0); + const char *potion_name = tolua_tostring(L, 2, 0); + int result = -1; + const potion_type *pt_potion; + const item_type *it_potion = it_find(potion_name); + + if (it_potion != NULL) { + pt_potion = it_potion->rtype->ptype; + if (pt_potion != NULL) + result = get_effect(self, pt_potion); + } + + lua_pushinteger(L, result); + return 1; +} + static int tolua_unit_add_item(lua_State * L) { unit *self = (unit *) tolua_tousertype(L, 1, 0); @@ -947,6 +966,9 @@ void tolua_unit_open(lua_State * L) tolua_function(L, TOLUA_CAST "get_pooled", &tolua_unit_get_pooled); tolua_function(L, TOLUA_CAST "use_pooled", &tolua_unit_use_pooled); + /* effects */ + tolua_function(L, TOLUA_CAST "get_potion", &tolua_unit_get_effect); + /* skills: */ tolua_function(L, TOLUA_CAST "get_skill", &tolua_unit_getskill); tolua_function(L, TOLUA_CAST "eff_skill", &tolua_unit_effskill); diff --git a/src/gamecode/laws.c b/src/gamecode/laws.c index 6965a8f7d..69e7efc45 100644 --- a/src/gamecode/laws.c +++ b/src/gamecode/laws.c @@ -333,20 +333,27 @@ void get_food(region * r) */ for (u = r->units; u; u = u->next) { if (u->race == new_race[RC_DAEMON]) { - unit *donor = r->units; int hungry = u->number; - while (donor != NULL && hungry > 0) { - /* always start with the first known unit that may have some blood */ - static const struct potion_type *pt_blood; - if (pt_blood == NULL) { - const item_type *it_blood = it_find("peasantblood"); - if (it_blood) - pt_blood = it_blood->rtype->ptype; - } - if (pt_blood != NULL) { + /* use peasantblood before eating the peasants themselves */ + static const struct potion_type *pt_blood; + if (pt_blood == NULL) { + const item_type *it_blood = it_find("peasantblood"); + if (it_blood) + pt_blood = it_blood->rtype->ptype; + } + if (pt_blood != NULL) { + /* always start with the unit itself, then the first known unit that may have some blood */ + unit *donor = u; + while (donor != NULL && hungry > 0) { + int blut = get_effect(donor, pt_blood); + blut = MIN(blut, hungry); + change_effect(donor, pt_blood, -blut); + hungry -= blut; + if (donor == u) + donor = r->units; while (donor != NULL) { - if (donor->race == new_race[RC_DAEMON]) { + if (donor->race == new_race[RC_DAEMON] && donor!=u) { if (get_effect(donor, pt_blood)) { /* if he's in our faction, drain him: */ if (donor->faction == u->faction) @@ -355,14 +362,9 @@ void get_food(region * r) } donor = donor->next; } - if (donor != NULL) { - int blut = get_effect(donor, pt_blood); - blut = MIN(blut, hungry); - change_effect(donor, pt_blood, -blut); - hungry -= blut; - } } } + /* remaining demons feed on peasants */ if (pl == NULL || !fval(pl, PFL_NOFEED)) { if (peasantfood >= hungry) { peasantfood -= hungry; @@ -377,15 +379,9 @@ void get_food(region * r) demon_hunger = get_param_int(global.parameters, "hunger.demons", 0); } if (demon_hunger == 0) { - /* nicht gefütterte dämonen hungern */ -#ifdef PEASANT_HUNGRY_DAEMONS_HAVE_FULL_SKILLS - /* wdw special rule */ - hunger(hungry, u); -#else + /* demons who don't feed are hungry */ if (hunger(hungry, u)) fset(u, UFL_HUNGER); -#endif - /* used to be: hunger(hungry, u); */ } else { /* no damage, but set the hungry-flag */ fset(u, UFL_HUNGER); diff --git a/src/gamecode/randenc.c b/src/gamecode/randenc.c index 61ecf3ac5..43d3370b2 100644 --- a/src/gamecode/randenc.c +++ b/src/gamecode/randenc.c @@ -1181,8 +1181,8 @@ static void rotting_herbs(void) for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { - item **itmp = &u->items, *hbag = - *i_find(itmp, olditemtype[I_SACK_OF_CONSERVATION]); + item **itmp = &u->items; + item *hbag = *i_find(itmp, olditemtype[I_SACK_OF_CONSERVATION]); int rot_chance = rule_rot; if (hbag) diff --git a/src/kernel/alchemy.h b/src/kernel/alchemy.h index 2654c1a21..7444d49ab 100644 --- a/src/kernel/alchemy.h +++ b/src/kernel/alchemy.h @@ -18,6 +18,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef H_KRNL_ALCHEMY_H #define H_KRNL_ALCHEMY_H + +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -56,6 +60,7 @@ extern "C" { int amount, struct order *); extern void init_potions(void); + extern int get_effect(const struct unit *u, const struct potion_type *effect); extern int change_effect(struct unit *u, const struct potion_type *effect, int value);