From 5876c1a01167fe3e181ed980a78f45ab263a9d14 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 13 Mar 2021 21:18:47 +0100 Subject: [PATCH] https://bugs.eressea.de/view.php?id=2729 castles were giving too much protection. --- src/battle.c | 2 +- src/battle.test.c | 42 +++++++++++--------------- src/kernel/build.c | 7 +++++ src/kernel/build.h | 1 + src/kernel/building.c | 22 +++++++------- src/tests.c | 70 +++++++++++++++++++++++++++++++++++-------- src/tests.h | 1 + 7 files changed, 98 insertions(+), 47 deletions(-) diff --git a/src/battle.c b/src/battle.c index 4159cf0c7..425ccf6b1 100644 --- a/src/battle.c +++ b/src/battle.c @@ -3267,7 +3267,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) for (itm = u->items; itm; itm = itm->next) { if (itm->type->rtype->atype) { if (i_canuse(u, itm->type)) { - struct armor *adata = (struct armor *)malloc(sizeof(armor)), **aptr; + struct armor *adata = malloc(sizeof(armor)), **aptr; adata->atype = itm->type->rtype->atype; adata->count = itm->number; for (aptr = &fig->armors; *aptr; aptr = &(*aptr)->next) { diff --git a/src/battle.test.c b/src/battle.test.c index e9be1e93a..665aeff1e 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -186,20 +186,7 @@ static void test_select_armor(CuTest *tc) { } static building_type * setup_castle(void) { - building_type * btype; - construction *cons; - - btype = test_create_buildingtype("castle"); - assert(btype->stages); - - btype->flags |= BTF_FORTIFICATION; - cons = &btype->stages->construction; - cons->maxsize = 5; - btype->stages->next = calloc(1, sizeof(building_stage)); - assert(btype->stages->next); - cons = &btype->stages->next->construction; - cons->maxsize = -1; - return btype; + return test_create_castle(); } static void test_defenders_get_building_bonus(CuTest * tc) @@ -236,11 +223,16 @@ static void test_defenders_get_building_bonus(CuTest * tc) at.fighter = af; at.index = 0; - bld->size = 10; /* stage 1 building */ - CuAssertIntEquals(tc, 1, buildingeffsize(bld, false)); + bld->size = 10; /* stage 2 building */ + CuAssertIntEquals(tc, 2, buildingeffsize(bld, false)); CuAssertIntEquals(tc, -1, skilldiff(at, dt, 0)); CuAssertIntEquals(tc, 0, skilldiff(dt, at, 0)); + bld->size = 9; /* stage 1 building */ + CuAssertIntEquals(tc, 1, buildingeffsize(bld, false)); + CuAssertIntEquals(tc, 0, skilldiff(at, dt, 0)); + CuAssertIntEquals(tc, 0, skilldiff(dt, at, 0)); + bld->size = 1; /* stage 0 building */ CuAssertIntEquals(tc, 0, buildingeffsize(bld, false)); CuAssertIntEquals(tc, 0, skilldiff(at, dt, 0)); @@ -323,14 +315,15 @@ static void test_building_defense_bonus(CuTest * tc) test_setup(); btype = setup_castle(); - btype->maxsize = -1; /* unlimited buildigs get the castle bonus */ + btype->maxsize = -1; /* unlimited buildings get the castle bonus */ CuAssertIntEquals(tc, 0, bt_protection(btype, 0)); - CuAssertIntEquals(tc, 1, bt_protection(btype, 1)); - CuAssertIntEquals(tc, 3, bt_protection(btype, 2)); - CuAssertIntEquals(tc, 5, bt_protection(btype, 3)); - CuAssertIntEquals(tc, 8, bt_protection(btype, 4)); - CuAssertIntEquals(tc, 12, bt_protection(btype, 5)); - CuAssertIntEquals(tc, 12, bt_protection(btype, 6)); + CuAssertIntEquals(tc, 0, bt_protection(btype, 1)); + CuAssertIntEquals(tc, 1, bt_protection(btype, 2)); + CuAssertIntEquals(tc, 2, bt_protection(btype, 3)); + CuAssertIntEquals(tc, 3, bt_protection(btype, 4)); + CuAssertIntEquals(tc, 4, bt_protection(btype, 5)); + CuAssertIntEquals(tc, 5, bt_protection(btype, 6)); + CuAssertIntEquals(tc, 5, bt_protection(btype, 7)); /* illegal castle size */ btype->maxsize = 10; /* limited-size buildings are treated like an E3 watchtower */ CuAssertIntEquals(tc, 0, bt_protection(btype, 0)); @@ -748,7 +741,8 @@ static void test_battle_skilldiff_building(CuTest *tc) CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0)); ud->building->size = 10; - CuAssertIntEquals(tc, 1, buildingeffsize(ud->building, false)); + CuAssertIntEquals(tc, 2, buildingeffsize(ud->building, false)); + CuAssertIntEquals(tc, 1, building_protection(ud->building)); CuAssertIntEquals(tc, -1, skilldiff(ta, td, 0)); create_curse(NULL, &ud->building->attribs, &ct_magicwalls, 1, 1, 1, 1); diff --git a/src/kernel/build.c b/src/kernel/build.c index 6cc04d26a..2c8cd8dd9 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -1010,6 +1010,13 @@ void continue_ship(unit * u, int want) build_ship(u, sh, want); } +void construction_init(struct construction *con, int minskill, skill_t sk, int reqsize, int maxsize) { + con->minskill = minskill; + con->skill = sk; + con->reqsize = reqsize; + con->maxsize = maxsize; +} + void free_construction(struct construction *cons) { free(cons->materials); diff --git a/src/kernel/build.h b/src/kernel/build.h index 523ec0e63..a06f2bd04 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -28,6 +28,7 @@ extern "C" { requirement *materials; /* material req'd to build one object */ } construction; + void construction_init(struct construction *con, int minskill, skill_t sk, int reqsize, int maxsize); void free_construction(struct construction *cons); int destroy_cmd(struct unit *u, struct order *ord); int leave_cmd(struct unit *u, struct order *ord); diff --git a/src/kernel/building.c b/src/kernel/building.c index 97e075f8f..2cb1a129c 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -316,22 +316,24 @@ int cmp_castle_size(const building * b, const building * a) return b->size - a->size; } -static const int castle_bonus[6] = { 0, 1, 3, 5, 8, 12 }; +static const int castle_bonus[7] = { 0, 0, 1, 2, 3, 4, 5 }; static const int watch_bonus[3] = { 0, 1, 2 }; int bt_protection(const building_type * btype, int stage) { - assert(btype->flags & BTF_FORTIFICATION); - if (btype->maxsize < 0) { - if (stage > 5) { - stage = 5; + if (btype->flags & BTF_FORTIFICATION) { + if (btype->maxsize < 0) { + if (stage >= 7) { + stage = 6; + } + return castle_bonus[stage]; } - return castle_bonus[stage]; + if (stage > 2) { + stage = 2; + } + return watch_bonus[stage]; } - if (stage > 2) { - stage = 2; - } - return watch_bonus[stage]; + return 0; } int building_protection(const building* b) { diff --git a/src/tests.c b/src/tests.c index ac9e8c0f4..a85f7da41 100644 --- a/src/tests.c +++ b/src/tests.c @@ -10,6 +10,7 @@ #include "reports.h" #include "vortex.h" +#include "kernel/build.h" #include "kernel/calendar.h" #include "kernel/callbacks.h" #include "kernel/config.h" @@ -39,6 +40,7 @@ #include "util/message.h" #include "util/log.h" #include "util/stats.h" +#include "util/strings.h" #include "util/param.h" #include "util/rand.h" @@ -398,23 +400,27 @@ ship_type * test_create_shiptype(const char * name) building_type * test_create_buildingtype(const char * name) { - construction *con; + construction *con = NULL; building_type *btype = bt_get_or_create(name); if (btype->stages) { con = &btype->stages->construction; } else { - btype->stages = calloc(1, sizeof(building_stage)); - con = &btype->stages->construction; - con->skill = SK_BUILDING; - con->maxsize = -1; - con->minskill = 1; - con->reqsize = 1; + btype->stages = malloc(sizeof(building_stage)); + if (btype->stages) { + con = &btype->stages->construction; + con->materials = NULL; + construction_init(con, 1, SK_BUILDING, 1, -1); + btype->stages->name = NULL; + btype->stages->next = NULL; + } } if (con && !con->materials) { - con->materials = (requirement *)calloc(2, sizeof(requirement)); - con->materials[1].number = 0; - con->materials[0].number = 1; - con->materials[0].rtype = get_resourcetype(R_STONE); + con->materials = malloc(2 * sizeof(requirement)); + if (con->materials) { + con->materials[0].number = 1; + con->materials[0].rtype = get_resourcetype(R_STONE); + con->materials[1].number = 0; + } } if (default_locale) { if (locale_getstring(default_locale, name) == NULL) { @@ -424,6 +430,46 @@ building_type * test_create_buildingtype(const char * name) return btype; } +static building_stage **init_stage(building_stage **stage_p, int minskill, int maxsize, + const char *name, const resource_type *rtype) +{ + building_stage *stage = malloc(sizeof(building_stage)); + assert(stage); + stage->name = str_strdup(name); + construction_init(&stage->construction, minskill, SK_BUILDING, 1, maxsize); + stage->construction.materials = malloc(2 * sizeof(requirement)); + if (stage->construction.materials) { + stage->construction.materials[0].number = 1; + stage->construction.materials[0].rtype = rtype; + stage->construction.materials[1].number = 0; + } + *stage_p = stage; + return &stage->next; +} + +building_type *test_create_castle(void) { + building_type *btype = bt_get_or_create("castle"); + const resource_type *rtype = get_resourcetype(R_STONE); + if (!rtype) { + rtype = test_create_itemtype("stone")->rtype; + } + + if (!btype->stages) { + building_stage **stage_p = &btype->stages; + btype->flags |= BTF_FORTIFICATION; + stage_p = init_stage(stage_p, 1, 2, "site", rtype); + stage_p = init_stage(stage_p, 1, 8, "tradepost", rtype); + stage_p = init_stage(stage_p, 2, 40, "fortification", rtype); + stage_p = init_stage(stage_p, 3, 200, "tower", rtype); + stage_p = init_stage(stage_p, 4, 1000, "castle", rtype); + stage_p = init_stage(stage_p, 5, 5000, "fortress", rtype); + stage_p = init_stage(stage_p, 6, -1, "citadel", rtype); + *stage_p = NULL; + } + return btype; +} + + item_type * test_create_itemtype(const char * name) { resource_type * rtype; item_type * itype; @@ -551,7 +597,7 @@ void test_create_world(void) } } - test_create_buildingtype("castle"); + test_create_castle(); test_create_shiptype("boat"); } diff --git a/src/tests.h b/src/tests.h index 82f510c73..af092d992 100644 --- a/src/tests.h +++ b/src/tests.h @@ -59,6 +59,7 @@ extern "C" { struct item_type * test_create_itemtype(const char * name); struct ship_type *test_create_shiptype(const char * name); struct building_type *test_create_buildingtype(const char *name); + struct building_type* test_create_castle(void); void test_create_castorder(struct castorder *co, struct unit *u, int level, float force, int range, struct spellparameter *par); struct spell * test_create_spell(void); int test_set_item(struct unit * u, const struct item_type *itype, int value);