do not use floats for material-save.

abusing variants for storing short fractions.
remove unused RMF_SAVERESOURCE.
This commit is contained in:
Enno Rehling 2017-02-17 21:45:10 +01:00
parent ed94ef6d48
commit 2328975dc2
4 changed files with 32 additions and 22 deletions

View File

@ -863,7 +863,7 @@ static void manufacture(unit * u, const item_type * itype, int want)
typedef struct allocation {
struct allocation *next;
int want, get;
double save;
variant save;
unsigned int flags;
unit *unit;
} allocation;
@ -883,17 +883,18 @@ enum {
AFL_LOWSKILL = 1 << 1
};
struct message * get_modifiers(unit *u, const resource_mod *mod, double *savep, int *skillp) {
struct message * get_modifiers(unit *u, const resource_mod *mod, variant *savep, int *skillp) {
struct building *b = inside_building(u);
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
double save = 1.0;
int save_n = 1, save_d = 1;
int skill = 0;
for (; mod->flags != 0; ++mod) {
if (mod->btype == NULL || mod->btype == btype) {
if (mod->race == NULL || mod->race == u_race(u)) {
if (mod->flags & RMF_SAVEMATERIAL) {
save *= mod->value.f;
save_n *= mod->value.sa[0];
save_d *= mod->value.sa[1];
}
if (mod->flags & RMF_SKILL) {
skill += mod->value.i;
@ -904,7 +905,12 @@ struct message * get_modifiers(unit *u, const resource_mod *mod, double *savep,
}
}
*skillp = skill;
*savep = save;
assert(save_n < SHRT_MAX);
assert(save_n > SHRT_MIN);
assert(save_d < SHRT_MAX);
assert(save_d > SHRT_MIN);
savep->sa[0] = (short)save_n;
savep->sa[1] = (short)save_d;
return NULL;
}
@ -919,7 +925,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
resource_limit *rdata = (resource_limit *)a->data.v;
const resource_type *rring;
int amount, skill, skill_mod = 0;
double save_mod = 1.0;
variant save_mod;
/* momentan kann man keine ressourcen abbauen, wenn man daf<61>r
* Materialverbrauch hat: */
@ -947,6 +953,10 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
return;
}
}
else {
save_mod.sa[0] = 1;
save_mod.sa[1] = 1;
}
/* Bergw<67>chter k<>nnen Abbau von Eisen/Laen durch Bewachen verhindern.
* Als magische Wesen 'sehen' Bergw<EFBFBD>chter alles und werden durch
@ -1023,9 +1033,9 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
alist->data = al;
}
static int required(int want, double save)
static int required(int want, variant save)
{
int req = (int)(want * save);
int req = (int)(want * save.sa[0] / save.sa[1]);
return req;
}
@ -1088,7 +1098,7 @@ leveled_allocation(const resource_type * rtype, region * r, allocation * alist)
use += x;
nreq -= want;
need -= x;
al->get = MIN(al->want, al->get + (int)(1 + x / al->save));
al->get = MIN(al->want, al->get + x * al->save.sa[1] / al->save.sa[0]);
}
}
if (use) {
@ -1126,12 +1136,13 @@ attrib_allocation(const resource_type * rtype, region * r, allocation * alist)
if (avail > 0) {
int want = required(al->want, al->save);
int x = avail * want / nreq;
/* Wenn Rest, dann w<>rfeln, ob ich was bekomme: */
if (rng_int() % nreq < (avail * want) % nreq)
++x;
int rx = (avail * want) % nreq;
/* Wenn Rest, dann wuerfeln, ob ich was bekomme: */
if (rx>0 && rng_int() % nreq < rx) ++x;
avail -= x;
nreq -= want;
al->get = MIN(al->want, (int)(x / al->save));
al->get = x * al->save.sa[0] / al->save.sa[1];
al->get = MIN(al->want, al->get);
if (rdata->produce) {
int use = required(al->get, al->save);
if (use)
@ -2619,8 +2630,9 @@ expandwork(region * r, request * work_begin, request * work_end, int maxwork)
if (jobs >= working)
workers = u->number;
else {
int r = (u->number * jobs) % working;
workers = u->number * jobs / working;
if (rng_int() % working < (u->number * jobs) % working)
if (r > 0 && rng_int() % working < r)
workers++;
}

View File

@ -350,6 +350,7 @@ static void test_make_item(CuTest *tc) {
resource_type *rtype;
attrib *a;
resource_limit *rdata;
double d = 0.6;
test_setup();
init_resources();
@ -397,7 +398,8 @@ static void test_make_item(CuTest *tc) {
rdata->modifiers = calloc(2, sizeof(resource_mod));
rdata->modifiers[0].flags = RMF_SAVEMATERIAL;
rdata->modifiers[0].race = u->_race;
rdata->modifiers[0].value.f = (float)0.6;
rdata->modifiers[0].value.sa[0] = (short)(0.5+100*d);
rdata->modifiers[0].value.sa[1] = 100;
make_item(u, itype, 10);
split_allocations(u->region);
CuAssertIntEquals(tc, 21, get_item(u, itype));

View File

@ -91,8 +91,7 @@ extern "C" {
/* resource-limits for regions */
#define RMF_SKILL 0x01 /* int, bonus on resource production skill */
#define RMF_SAVEMATERIAL 0x02 /* float, multiplier on resource usage */
#define RMF_SAVERESOURCE 0x03 /* int, bonus on resource production skill */
#define RMF_SAVEMATERIAL 0x02 /* fraction (sa[0]/sa[1]), multiplier on resource usage */
#define RMF_REQUIREDBUILDING 0x04 /* building, required to build */
typedef struct resource_mod {

View File

@ -1025,13 +1025,10 @@ static int parse_resources(xmlDocPtr doc)
rdata->modifiers[k].flags = RMF_SKILL;
}
else if (strcmp((const char *)propValue, "material") == 0) {
rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0);
rdata->modifiers[k].value.sa[0] = (short)(0.5+100*xml_fvalue(node, "value", 0));
rdata->modifiers[k].value.sa[1] = 100;
rdata->modifiers[k].flags = RMF_SAVEMATERIAL;
}
else if (strcmp((const char *)propValue, "resource") == 0) {
rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0);
rdata->modifiers[k].flags = RMF_SAVERESOURCE;
}
else if (strcmp((const char *)propValue, "require") == 0) {
xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building");
if (propBldg != NULL) {