From 85c83b432b9e6c563dee50bf14d4892ab4008377 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 10 Dec 2023 12:03:22 +0100 Subject: [PATCH] Dumpfbackenbrot (#1047) * fool potion: no more than 10 effects per person * fix bad tests, allow stacking up to 10 effects --- scripts/tests/e2/astral.lua | 1 - scripts/tests/e2/items.lua | 17 ++++---- src/alchemy.c | 32 +++++++++++++++ src/alchemy.h | 6 +-- src/alchemy.test.c | 79 +++++++++++++++++++++++++++++++++++-- src/items.c | 22 ----------- src/laws.c | 6 +-- src/laws.test.c | 1 + src/tests.c | 1 + src/upkeep.test.c | 18 ++++++--- 10 files changed, 135 insertions(+), 48 deletions(-) diff --git a/scripts/tests/e2/astral.lua b/scripts/tests/e2/astral.lua index 565c26b1a..8c2cc4ac0 100644 --- a/scripts/tests/e2/astral.lua +++ b/scripts/tests/e2/astral.lua @@ -110,7 +110,6 @@ function test_pull_astral() assert_equal(u1.region, u2.region) u1.aura = 12 -- 2 Aura pro Stufe - u1.name = 'Xykon' u1:clear_orders() u1:add_order("ZAUBERE Astraler~Ruf -1 0 " .. itoa36(u2.id)) r = region.create(-1,0, 'plain') diff --git a/scripts/tests/e2/items.lua b/scripts/tests/e2/items.lua index 0069d0f8e..70e6e2295 100644 --- a/scripts/tests/e2/items.lua +++ b/scripts/tests/e2/items.lua @@ -410,26 +410,23 @@ function test_use_foolpotion() local f = faction.create("human") local u = unit.create(f, r, 1) turn_begin() - u:add_item('p7', 2) - u:clear_orders() - u:add_order("BENUTZEN 1 Dumpfbackenbrot 4242") + u:add_item('p7', 3) + u:set_orders("BENUTZEN 1 Dumpfbackenbrot 4242") turn_process() - assert_equal(2, u:get_item('p7')) + assert_equal(3, u:get_item('p7')) assert_equal(1, f:count_msg_type('feedback_unit_not_found')) local u2 = unit.create(f, r, 1) - u:clear_orders() - u:add_order("BENUTZEN 2 Dumpfbackenbrot " .. itoa36(u2.id)) + u:set_orders("BENUTZEN 2 Dumpfbackenbrot " .. itoa36(u2.id)) turn_process() - assert_equal(2, u:get_item('p7')) + assert_equal(3, u:get_item('p7')) assert_equal(1, f:count_msg_type('error64')) u:set_skill("stealth", 1) - u2.name = 'Xolgrim' u2:set_skill('crossbow', 1) turn_process() - assert_equal(0, u:get_item('p7')) - assert_equal(0, u2:effect('p7')) + assert_equal(2, u:get_item('p7')) + assert_equal(9, u2:effect('p7')) assert_equal(1, f:count_msg_type('givedumb')) turn_end() end diff --git a/src/alchemy.c b/src/alchemy.c index 9cd136ca8..d75996ea1 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -309,3 +309,35 @@ void scale_effects(attrib* alist, int n, int size) data->value = (long long)data->value * n / size; } } + +int use_foolpotion(unit *user, const item_type *itype, int amount, + struct order *ord) +{ + int targetno = read_unitid(user->faction, user->region); + unit *u = findunit(targetno); + int max_effects; + if (u == NULL || user->region != u->region) { + ADDMSG(&user->faction->msgs, msg_feedback(user, ord, "feedback_unit_not_found", + "")); + return ECUSTOM; + } + if (effskill(user, SK_STEALTH, NULL) <= effskill(u, SK_PERCEPTION, NULL)) { + cmistake(user, ord, 64, MSG_EVENT); + return ECUSTOM; + } + max_effects = u->number * 10 - get_effect(u, itype); + if (max_effects > 0) { + int use = (max_effects + 9) / 10; + int effects = max_effects; + if (use > amount) { + use = amount; + effects = use * 10; + } + change_effect(u, itype, effects); + ADDMSG(&user->faction->msgs, msg_message("givedumb", + "unit recipient amount", user, u, use)); + return use; + } + return 0; +} + diff --git a/src/alchemy.h b/src/alchemy.h index 529cf82a5..d7f670f64 100644 --- a/src/alchemy.h +++ b/src/alchemy.h @@ -1,6 +1,4 @@ #pragma once -#ifndef H_KRNL_ALCHEMY_H -#define H_KRNL_ALCHEMY_H #include @@ -53,4 +51,6 @@ bool display_potions(struct unit* u); int effect_value(const struct attrib* a); const struct item_type *effect_type(const struct attrib* a); -#endif /* ALCHEMY_H */ +int use_foolpotion(struct unit *user, const struct item_type *itype, + int amount, struct order *ord); + diff --git a/src/alchemy.test.c b/src/alchemy.test.c index 2903c4895..618ea4814 100644 --- a/src/alchemy.test.c +++ b/src/alchemy.test.c @@ -1,13 +1,20 @@ #include "alchemy.h" +#include "guard.h" +#include "laws.h" + +#include +#include + +#include #include #include +#include #include #include #include #include - -#include "guard.h" +#include #include #include "tests.h" @@ -80,7 +87,71 @@ static void test_herbsearch(CuTest * tc) test_teardown(); } -static void test_scale_effects(CuTest* tc) { +static void test_foolpotion_effect(CuTest *tc) { + unit *u; + const struct item_type *itype; + + test_setup(); + itype = oldpotiontype[P_FOOL] = it_get_or_create(rt_get_or_create("hodor")); + u = test_create_unit(test_create_faction(), test_create_plain(0, 0)); + test_set_skill(u, SK_MAGIC, 3, 1); + test_set_skill(u, SK_CROSSBOW, 2, 1); + change_effect(u, itype, 2); + demographics(); + CuAssertIntEquals(tc, 1, get_effect(u, itype)); + CuAssertIntEquals(tc, 2, unit_skill(u, SK_MAGIC)->weeks); + CuAssertIntEquals(tc, 1, unit_skill(u, SK_CROSSBOW)->weeks); + test_teardown(); +} + +static void test_use_foolpotion(CuTest *tc) { + unit *u, *u2; + const struct item_type *itype; + + test_setup(); + itype = oldpotiontype[P_FOOL] = it_get_or_create(rt_get_or_create("hodor")); + u = test_create_unit(test_create_faction(), test_create_plain(0, 0)); + u2 = test_create_unit(test_create_faction(), u->region); + u->thisorder = create_order(K_USE, u->faction->locale, itoa36(u2->no), NULL); + + init_order(u->thisorder, u->faction->locale); + CuAssertIntEquals(tc, ECUSTOM, use_foolpotion(u, itype, 2, u->thisorder)); + + /* Maximal 10 Wirkungen pro Person: */ + test_set_skill(u, SK_STEALTH, 1, 1); + init_order(u->thisorder, u->faction->locale); + CuAssertIntEquals(tc, 1, use_foolpotion(u, itype, 2, u->thisorder)); + CuAssertIntEquals(tc, 0, get_effect(u, itype)); + CuAssertIntEquals(tc, 10, get_effect(u2, itype)); + + a_removeall(&u2->attribs, &at_effect); + scale_number(u2, 2); + init_order(u->thisorder, u->faction->locale); + CuAssertIntEquals(tc, 2, use_foolpotion(u, itype, 3, u->thisorder)); + CuAssertIntEquals(tc, 20, get_effect(u2, itype)); + + a_removeall(&u2->attribs, &at_effect); + scale_number(u2, 10); + init_order(u->thisorder, u->faction->locale); + CuAssertIntEquals(tc, 10, use_foolpotion(u, itype, 20, u->thisorder)); + CuAssertIntEquals(tc, 100, get_effect(u2, itype)); + + /* limited use: */ + a_removeall(&u2->attribs, &at_effect); + scale_number(u2, 2); + init_order(u->thisorder, u->faction->locale); + CuAssertIntEquals(tc, 1, use_foolpotion(u, itype, 1, u->thisorder)); + CuAssertIntEquals(tc, 10, get_effect(u2, itype)); + + /* stacking only up to 10 effect/person: */ + init_order(u->thisorder, u->faction->locale); + CuAssertIntEquals(tc, 1, use_foolpotion(u, itype, 2, u->thisorder)); + CuAssertIntEquals(tc, 20, get_effect(u2, itype)); + + test_teardown(); +} + +static void test_scale_effects(CuTest *tc) { unit* u; const struct item_type* ptype; @@ -119,5 +190,7 @@ CuSuite *get_alchemy_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_herbsearch); SUITE_ADD_TEST(suite, test_scale_effects); + SUITE_ADD_TEST(suite, test_foolpotion_effect); + SUITE_ADD_TEST(suite, test_use_foolpotion); return suite; } diff --git a/src/items.c b/src/items.c index 977c0babe..8a180d0d2 100644 --- a/src/items.c +++ b/src/items.c @@ -255,28 +255,6 @@ struct order *ord) return 0; } -static int use_foolpotion(unit *u, const item_type *itype, int amount, - struct order *ord) -{ - int targetno = read_unitid(u->faction, u->region); - unit *target = findunit(targetno); - if (target == NULL || u->region != target->region) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", - "")); - return ECUSTOM; - } - if (effskill(u, SK_STEALTH, NULL) <= effskill(target, SK_PERCEPTION, NULL)) { - cmistake(u, ord, 64, MSG_EVENT); - return ECUSTOM; - } - ADDMSG(&u->faction->msgs, msg_message("givedumb", - "unit recipient amount", u, target, amount)); - - change_effect(target, itype, amount); - use_pooled(u, itype->rtype, GET_DEFAULT, amount); - return 0; -} - static int use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, struct order *ord) diff --git a/src/laws.c b/src/laws.c index 2f33dd22b..70ff0f186 100644 --- a/src/laws.c +++ b/src/laws.c @@ -175,6 +175,8 @@ static bool RemoveNMRNewbie(void) static void dumbeffect(unit *u) { int effect = get_effect(u, oldpotiontype[P_FOOL]); if (effect > 0) { /* Trank "Dumpfbackenbrot" */ + int weeks = u->number; + if (weeks > effect) weeks = effect; ptrdiff_t s, n = arrlen(u->skills); skill *sb = NULL; for (s = 0; s != n; ++s) { @@ -186,13 +188,11 @@ static void dumbeffect(unit *u) { } /* bestes Talent raussuchen */ if (sb != NULL) { - int weeks = u->number; - if (weeks > effect) weeks = effect; reduce_skill(u, sb, weeks); ADDMSG(&u->faction->msgs, msg_message("dumbeffect", "unit weeks skill", u, weeks, (skill_t)sb->id)); } /* sonst Glueck gehabt: wer nix weiss, kann nix vergessen... */ - change_effect(u, oldpotiontype[P_FOOL], -effect); + change_effect(u, oldpotiontype[P_FOOL], -weeks); } } diff --git a/src/laws.test.c b/src/laws.test.c index 27b5ece58..3beb17a35 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1871,6 +1871,7 @@ static void test_demon_hunger(CuTest * tc) unit *u; test_setup(); + config_set("hunger.damage", NULL); init_resources(); r = test_create_plain(0, 0); rc = test_create_race("demon"); diff --git a/src/tests.c b/src/tests.c index 3d19d32aa..41d1e8c66 100644 --- a/src/tests.c +++ b/src/tests.c @@ -313,6 +313,7 @@ void test_use_astral(void) void test_setup_test(CuTest *tc, const char *file, int line) { test_log_stderr(LOG_CPERROR); test_reset_full(); + config_set("hunger.damage", "0"); message_handle_missing(MESSAGE_MISSING_REPLACE); if (tc) { log_debug("start test: %s", tc->name); diff --git a/src/upkeep.test.c b/src/upkeep.test.c index d74b2a148..4a137bba7 100644 --- a/src/upkeep.test.c +++ b/src/upkeep.test.c @@ -13,6 +13,12 @@ #include +static void setup_upkeep(void) +{ + test_setup(); + config_set("hunger.damage", NULL); +} + void test_upkeep_default(CuTest * tc) { region *r; @@ -20,7 +26,7 @@ void test_upkeep_default(CuTest * tc) faction *f1, *f2; const item_type *i_silver; - test_setup(); + setup_upkeep(); init_resources(); i_silver = it_find("money"); assert(i_silver); @@ -49,7 +55,7 @@ void test_upkeep_hunger_damage(CuTest * tc) unit *u1; faction *f1; - test_setup(); + setup_upkeep(); init_resources(); r = test_create_plain(0, 0); @@ -72,7 +78,7 @@ void test_upkeep_from_pool(CuTest * tc) unit *u1, *u2; const item_type *i_silver; - test_setup(); + setup_upkeep(); init_resources(); i_silver = it_find("money"); @@ -106,7 +112,7 @@ void test_upkeep_from_friend(CuTest * tc) faction *f1, *f2; const item_type *i_silver; - test_setup(); + setup_upkeep(); init_resources(); i_silver = it_find("money"); @@ -139,7 +145,7 @@ void test_lifestyle(CuTest *tc) unit *u; race *rc; - test_setup(); + setup_upkeep(); u = test_create_unit(test_create_faction(), test_create_plain(0, 0)); CuAssertIntEquals(tc, 10, lifestyle(u)); u->number = 2; @@ -159,7 +165,7 @@ void test_upkeep_free(CuTest * tc) unit *u; const item_type *i_silver; - test_setup(); + setup_upkeep(); init_resources(); i_silver = it_find("money");