From b5b39024f27ed0c1bc04a8afacd9f9f2e1e5541d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 30 Oct 2018 21:01:09 +0100 Subject: [PATCH] BUG 2506: starting regions have bad resource levels. add some one-off custom code to fix the resource levels of selected regions --- src/gmtool.c | 100 +++++++++++++++++++++++++++++++++++++++++ src/kernel/region.c | 15 ++++++- src/kernel/region.h | 2 + src/kernel/resources.c | 17 ++++--- src/kernel/resources.h | 1 + 5 files changed, 126 insertions(+), 9 deletions(-) diff --git a/src/gmtool.c b/src/gmtool.c index 0ad9bf0ce..757841af6 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -452,7 +453,10 @@ static void paint_info_region(window * wnd, const state * st) line++; umvwprintw(win, line++, 1, "%s, age %d", r->terrain->_name, r->age); if (r->land) { + int iron = region_getresource_level(r, get_resourcetype(R_IRON)); + int stone = region_getresource_level(r, get_resourcetype(R_STONE)); mvwprintw(win, line++, 1, "$:%6d P:%5d", rmoney(r), rpeasants(r)); + mvwprintw(win, line++, 1, "S:%6d I:%5d", stone, iron); mvwprintw(win, line++, 1, "H:%6d %s:%5d", rhorses(r), (r->flags & RF_MALLORN) ? "M" : "T", r->land->trees[1] + r->land->trees[2]); @@ -530,6 +534,33 @@ static void statusline(WINDOW * win, const char *str) wnoutrefresh(win); } +static void reset_resources(region *r, const struct terrain_type *terrain) +{ + int i; + + for (i = 0; terrain->production[i].type; ++i) { + rawmaterial *rm; + const terrain_production *production = terrain->production + i; + const resource_type *rtype = production->type; + + for (rm = r->resources; rm; rm = rm->next) { + if (rm->rtype == rtype) + break; + } + if (rm) { + struct rawmaterial_type *rmt; + set_resource(rm, + dice_rand(production->startlevel), + dice_rand(production->base), + dice_rand(production->divisor)); + rmt = rmt_get(rtype); + if (rmt && rmt->terraform) { + rmt->terraform(rm, r); + } + } + } +} + static void reset_region(region *r) { unit **up = &r->units; bool players = false; @@ -555,6 +586,7 @@ static void reset_region(region *r) { } if (r->land) { init_region(r); + reset_resources(r, r->terrain); } } } @@ -600,6 +632,69 @@ static void terraform_at(coordinate * c, const terrain_type * terrain) } } +static void selection_walk(selection * selected, void(*callback)(region *, void *), void *udata) { + int i; + + for (i = 0; i != MAXTHASH; ++i) { + tag **tp = &selected->tags[i]; + while (*tp) { + region *r; + tag *t = *tp; + int nx = t->coord.x, ny = t->coord.y; + plane *pl = t->coord.pl; + + pnormalize(&nx, &ny, pl); + r = findregion(nx, ny); + if (r != NULL) { + callback(r, udata); + } + tp = &t->nexthash; + } + } +} + +static void reset_levels_cb(region *r, void *udata) { + struct rawmaterial *res; + UNUSED_ARG(udata); + for (res = r->resources; res; res = res->next) { + if (res->level > 3) { + res->level = 1; + } + } +} + +/** + * BUG 2506: reset drained mountains to level 1 + */ +static void +fix_selection(selection * selected) +{ + selection_walk(selected, reset_levels_cb, NULL); +} + +static void +reset_selection(selection * selected) +{ + int i; + + for (i = 0; i != MAXTHASH; ++i) { + tag **tp = &selected->tags[i]; + while (*tp) { + region *r; + tag *t = *tp; + int nx = t->coord.x, ny = t->coord.y; + plane *pl = t->coord.pl; + + pnormalize(&nx, &ny, pl); + r = findregion(nx, ny); + if (r != NULL) { + reset_region(r); + } + tp = &t->nexthash; + } + } +} + static void terraform_selection(selection * selected, const terrain_type * terrain) { @@ -1259,7 +1354,12 @@ static void handlekey(state * st, int c) statusline(st->wnd_status->handle, "tag-"); doupdate(); switch (getch()) { + case 'r': + reset_selection(st->selected); + break; case 'f': + fix_selection(st->selected); + break; case 't': terraform_selection(st->selected, select_terrain(st, NULL)); st->modified = 1; diff --git a/src/kernel/region.c b/src/kernel/region.c index 29f7222e1..04c46989c 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -827,7 +827,7 @@ void free_land(land_region * lr) free(lr); } -void region_setresource(region * r, const resource_type * rtype, int value) +void region_setresource(region * r, const struct resource_type *rtype, int value) { rawmaterial *rm = r->resources; while (rm) { @@ -870,7 +870,18 @@ void region_setresource(region * r, const resource_type * rtype, int value) } } -int region_getresource(const region * r, const resource_type * rtype) +int region_getresource_level(const region * r, const struct resource_type * rtype) +{ + const rawmaterial *rm; + for (rm = r->resources; rm; rm = rm->next) { + if (rm->rtype == rtype) { + return rm->level; + } + } + return -1; +} + +int region_getresource(const region * r, const struct resource_type *rtype) { const rawmaterial *rm; for (rm = r->resources; rm; rm = rm->next) { diff --git a/src/kernel/region.h b/src/kernel/region.h index bf932e9c3..f439bceed 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -261,6 +261,8 @@ extern "C" { void region_setname(struct region *self, const char *name); const char *region_getinfo(const struct region *self); void region_setinfo(struct region *self, const char *name); + int region_getresource_level(const struct region * r, + const struct resource_type * rtype); int region_getresource(const struct region *r, const struct resource_type *rtype); void region_setresource(struct region *r, const struct resource_type *rtype, diff --git a/src/kernel/resources.c b/src/kernel/resources.c index 231b763f8..4bb27616d 100644 --- a/src/kernel/resources.c +++ b/src/kernel/resources.c @@ -46,8 +46,6 @@ void update_resources(region * r) } } -extern int dice_rand(const char *s); - static void update_resource(struct rawmaterial *res, double modifier) { double amount = (res->level - res->startlevel) / 100.0 * res->divisor + 1; @@ -59,6 +57,15 @@ static void update_resource(struct rawmaterial *res, double modifier) assert(res->amount > 0); } +void set_resource(struct rawmaterial *rm, int level, int base, int divisor) +{ + rm->level = level; + rm->startlevel = level; + rm->base = base; + rm->amount = base; + rm->divisor = divisor; +} + struct rawmaterial * add_resource(region * r, int level, int base, int divisor, const resource_type * rtype) @@ -67,13 +74,9 @@ const resource_type * rtype) rm->next = r->resources; r->resources = rm; - rm->level = level; - rm->startlevel = level; - rm->base = base; - rm->amount = base; - rm->divisor = divisor; rm->flags = 0; rm->rtype = rtype; + set_resource(rm, level, base, divisor); return rm; } diff --git a/src/kernel/resources.h b/src/kernel/resources.h index 8f291c305..65431bb2c 100644 --- a/src/kernel/resources.h +++ b/src/kernel/resources.h @@ -70,6 +70,7 @@ extern "C" { const struct resource_type *); struct rawmaterial_type *rmt_get(const struct resource_type *); + void set_resource(struct rawmaterial *rm, int level, int base, int divisor); struct rawmaterial *add_resource(struct region *r, int level, int base, int divisor, const struct resource_type *rtype); struct rawmaterial_type *rmt_create(struct resource_type *rtype);