castles were giving too much protection.
This commit is contained in:
Enno Rehling 2021-03-13 21:18:47 +01:00
parent 812907ffb5
commit 5876c1a011
7 changed files with 98 additions and 47 deletions

View File

@ -3267,7 +3267,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
for (itm = u->items; itm; itm = itm->next) { for (itm = u->items; itm; itm = itm->next) {
if (itm->type->rtype->atype) { if (itm->type->rtype->atype) {
if (i_canuse(u, itm->type)) { 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->atype = itm->type->rtype->atype;
adata->count = itm->number; adata->count = itm->number;
for (aptr = &fig->armors; *aptr; aptr = &(*aptr)->next) { for (aptr = &fig->armors; *aptr; aptr = &(*aptr)->next) {

View File

@ -186,20 +186,7 @@ static void test_select_armor(CuTest *tc) {
} }
static building_type * setup_castle(void) { static building_type * setup_castle(void) {
building_type * btype; return test_create_castle();
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;
} }
static void test_defenders_get_building_bonus(CuTest * tc) 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.fighter = af;
at.index = 0; at.index = 0;
bld->size = 10; /* stage 1 building */ bld->size = 10; /* stage 2 building */
CuAssertIntEquals(tc, 1, buildingeffsize(bld, false)); CuAssertIntEquals(tc, 2, buildingeffsize(bld, false));
CuAssertIntEquals(tc, -1, skilldiff(at, dt, 0)); CuAssertIntEquals(tc, -1, skilldiff(at, dt, 0));
CuAssertIntEquals(tc, 0, skilldiff(dt, at, 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 */ bld->size = 1; /* stage 0 building */
CuAssertIntEquals(tc, 0, buildingeffsize(bld, false)); CuAssertIntEquals(tc, 0, buildingeffsize(bld, false));
CuAssertIntEquals(tc, 0, skilldiff(at, dt, 0)); CuAssertIntEquals(tc, 0, skilldiff(at, dt, 0));
@ -323,14 +315,15 @@ static void test_building_defense_bonus(CuTest * tc)
test_setup(); test_setup();
btype = setup_castle(); 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, 0, bt_protection(btype, 0));
CuAssertIntEquals(tc, 1, bt_protection(btype, 1)); CuAssertIntEquals(tc, 0, bt_protection(btype, 1));
CuAssertIntEquals(tc, 3, bt_protection(btype, 2)); CuAssertIntEquals(tc, 1, bt_protection(btype, 2));
CuAssertIntEquals(tc, 5, bt_protection(btype, 3)); CuAssertIntEquals(tc, 2, bt_protection(btype, 3));
CuAssertIntEquals(tc, 8, bt_protection(btype, 4)); CuAssertIntEquals(tc, 3, bt_protection(btype, 4));
CuAssertIntEquals(tc, 12, bt_protection(btype, 5)); CuAssertIntEquals(tc, 4, bt_protection(btype, 5));
CuAssertIntEquals(tc, 12, bt_protection(btype, 6)); 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 */ btype->maxsize = 10; /* limited-size buildings are treated like an E3 watchtower */
CuAssertIntEquals(tc, 0, bt_protection(btype, 0)); 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)); CuAssertIntEquals(tc, 0, skilldiff(ta, td, 0));
ud->building->size = 10; 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)); CuAssertIntEquals(tc, -1, skilldiff(ta, td, 0));
create_curse(NULL, &ud->building->attribs, &ct_magicwalls, 1, 1, 1, 1); create_curse(NULL, &ud->building->attribs, &ct_magicwalls, 1, 1, 1, 1);

View File

@ -1010,6 +1010,13 @@ void continue_ship(unit * u, int want)
build_ship(u, sh, 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) void free_construction(struct construction *cons)
{ {
free(cons->materials); free(cons->materials);

View File

@ -28,6 +28,7 @@ extern "C" {
requirement *materials; /* material req'd to build one object */ requirement *materials; /* material req'd to build one object */
} construction; } construction;
void construction_init(struct construction *con, int minskill, skill_t sk, int reqsize, int maxsize);
void free_construction(struct construction *cons); void free_construction(struct construction *cons);
int destroy_cmd(struct unit *u, struct order *ord); int destroy_cmd(struct unit *u, struct order *ord);
int leave_cmd(struct unit *u, struct order *ord); int leave_cmd(struct unit *u, struct order *ord);

View File

@ -316,15 +316,15 @@ int cmp_castle_size(const building * b, const building * a)
return b->size - a->size; 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 }; static const int watch_bonus[3] = { 0, 1, 2 };
int bt_protection(const building_type * btype, int stage) int bt_protection(const building_type * btype, int stage)
{ {
assert(btype->flags & BTF_FORTIFICATION); if (btype->flags & BTF_FORTIFICATION) {
if (btype->maxsize < 0) { if (btype->maxsize < 0) {
if (stage > 5) { if (stage >= 7) {
stage = 5; stage = 6;
} }
return castle_bonus[stage]; return castle_bonus[stage];
} }
@ -332,6 +332,8 @@ int bt_protection(const building_type * btype, int stage)
stage = 2; stage = 2;
} }
return watch_bonus[stage]; return watch_bonus[stage];
}
return 0;
} }
int building_protection(const building* b) { int building_protection(const building* b) {

View File

@ -10,6 +10,7 @@
#include "reports.h" #include "reports.h"
#include "vortex.h" #include "vortex.h"
#include "kernel/build.h"
#include "kernel/calendar.h" #include "kernel/calendar.h"
#include "kernel/callbacks.h" #include "kernel/callbacks.h"
#include "kernel/config.h" #include "kernel/config.h"
@ -39,6 +40,7 @@
#include "util/message.h" #include "util/message.h"
#include "util/log.h" #include "util/log.h"
#include "util/stats.h" #include "util/stats.h"
#include "util/strings.h"
#include "util/param.h" #include "util/param.h"
#include "util/rand.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) building_type * test_create_buildingtype(const char * name)
{ {
construction *con; construction *con = NULL;
building_type *btype = bt_get_or_create(name); building_type *btype = bt_get_or_create(name);
if (btype->stages) { if (btype->stages) {
con = &btype->stages->construction; con = &btype->stages->construction;
} else { } else {
btype->stages = calloc(1, sizeof(building_stage)); btype->stages = malloc(sizeof(building_stage));
if (btype->stages) {
con = &btype->stages->construction; con = &btype->stages->construction;
con->skill = SK_BUILDING; con->materials = NULL;
con->maxsize = -1; construction_init(con, 1, SK_BUILDING, 1, -1);
con->minskill = 1; btype->stages->name = NULL;
con->reqsize = 1; btype->stages->next = NULL;
}
} }
if (con && !con->materials) { if (con && !con->materials) {
con->materials = (requirement *)calloc(2, sizeof(requirement)); con->materials = malloc(2 * sizeof(requirement));
con->materials[1].number = 0; if (con->materials) {
con->materials[0].number = 1; con->materials[0].number = 1;
con->materials[0].rtype = get_resourcetype(R_STONE); con->materials[0].rtype = get_resourcetype(R_STONE);
con->materials[1].number = 0;
}
} }
if (default_locale) { if (default_locale) {
if (locale_getstring(default_locale, name) == NULL) { if (locale_getstring(default_locale, name) == NULL) {
@ -424,6 +430,46 @@ building_type * test_create_buildingtype(const char * name)
return btype; 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) { item_type * test_create_itemtype(const char * name) {
resource_type * rtype; resource_type * rtype;
item_type * itype; item_type * itype;
@ -551,7 +597,7 @@ void test_create_world(void)
} }
} }
test_create_buildingtype("castle"); test_create_castle();
test_create_shiptype("boat"); test_create_shiptype("boat");
} }

View File

@ -59,6 +59,7 @@ extern "C" {
struct item_type * test_create_itemtype(const char * name); struct item_type * test_create_itemtype(const char * name);
struct ship_type *test_create_shiptype(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_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); 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); struct spell * test_create_spell(void);
int test_set_item(struct unit * u, const struct item_type *itype, int value); int test_set_item(struct unit * u, const struct item_type *itype, int value);