BUG 2506: starting regions have bad resource levels.

add some one-off custom code to fix the resource levels of selected regions
This commit is contained in:
Enno Rehling 2018-10-30 21:01:09 +01:00
parent a8ff6d2a99
commit b5b39024f2
5 changed files with 126 additions and 9 deletions

View file

@ -46,6 +46,7 @@
#include <util/log.h>
#include <util/macros.h>
#include <util/path.h>
#include <util/rand.h>
#include <util/rng.h>
#include <util/unicode.h>
@ -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;

View file

@ -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) {

View file

@ -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,

View file

@ -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;
}

View file

@ -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);