diff --git a/src/lib/commands/prod.c b/src/lib/commands/prod.c index 16b234fd..bdec10e8 100644 --- a/src/lib/commands/prod.c +++ b/src/lib/commands/prod.c @@ -71,7 +71,6 @@ prod(void) struct pchrstr *pp; double p_e; double maxr; /* floating version of max */ - double level_p_e; double prodeff; double real; /* floating pt version of act */ int work; @@ -228,15 +227,7 @@ prod(void) /* * production effic. */ - if (pp->p_nlndx >= 0) { - level_p_e = natp->nat_level[pp->p_nlndx] - pp->p_nlmin; - if (level_p_e < 0.0) { - level_p_e = 0.0; - } - level_p_e = level_p_e / (level_p_e + pp->p_nllag); - } else { - level_p_e = 1.0; - } + prodeff = prod_eff(pp, natp->nat_level[pp->p_nlndx]); /* * raw material limit */ @@ -257,15 +248,9 @@ prod(void) */ max = (int)(work * p_e / (double)unit_work + 0.5); act = min(used, max); - /* - * some things are easier to make.. food, - * pet, etc. - */ - act = (int)(((double)pp->p_effic * 0.01 * (double)act) + 0.5); - max = (int)(((double)pp->p_effic * 0.01 * (double)max) + 0.5); - real = dmin(999.0, (double)act * level_p_e); - maxr = dmin(999.0, (double)max * level_p_e); + real = dmin(999.0, (double)act * prodeff); + maxr = dmin(999.0, (double)max * prodeff); if (vtype != 0) { if (real < 0.0) @@ -275,15 +260,12 @@ prod(void) real = dmin(real, ITEM_MAX - there); } - if (level_p_e != 0) { - take = real / level_p_e; - mtake = maxr / level_p_e; + if (prodeff != 0) { + take = real / prodeff; + mtake = maxr / prodeff; } else mtake = take = 0.0; - take = (double)take / ((double)pp->p_effic * 0.01); - mtake = (double)mtake / ((double)pp->p_effic * 0.01); - cost = (int)(take * (double)pp->p_cost); if (opt_TECH_POP) { if (pp->p_level == NAT_TLEV) { @@ -379,7 +361,6 @@ prod(void) } pr(" %-5.5s", pp->p_sname); - prodeff = level_p_e * (double)pp->p_effic * 0.01; pr(" %.2f", prodeff); pr(" $%-4d", cost); for (i = 0; i < 3; i++) { diff --git a/src/lib/update/produce.c b/src/lib/update/produce.c index 5094ea14..20b70b9b 100644 --- a/src/lib/update/produce.c +++ b/src/lib/update/produce.c @@ -59,9 +59,9 @@ produce(struct natstr *np, struct sctstr *sp, short *vec, int work, register struct pchrstr *product; int vtype; double p_e; - double level_p_e; + double prodeff; s_char *resource; - int output; + double output; int actual; int unit_work; int item; @@ -101,27 +101,23 @@ produce(struct natstr *np, struct sctstr *sp, short *vec, int work, material_consume = worker_limit; if (material_consume == 0) return 0; - level_p_e = 1.0; - if (product->p_nlndx >= 0) { - level_p_e = np->nat_level[product->p_nlndx] - product->p_nlmin; - if ((level_p_e < 0.0) && (!player->simulation)) { - wu(0, sp->sct_own, - "%s level too low to produce in %s (need %d)\n", - levelnames[product->p_nlndx], ownxy(sp), product->p_nlmin); - return 0; - } - level_p_e = level_p_e / (level_p_e + product->p_nllag); + prodeff = prod_eff(product, np->nat_level[product->p_nlndx]); + if (prodeff <= 0.0 && !player->simulation) { + wu(0, sp->sct_own, + "%s level too low to produce in %s (need %d)\n", + levelnames[product->p_nlndx], ownxy(sp), product->p_nlmin); + return 0; } /* * Adjust produced amount by commodity production ratio */ - output = roundavg(product->p_effic * 0.01 * material_consume); + output = material_consume * prodeff; if ((vtype == 0) && (!player->simulation)) { - levels[sp->sct_own][product->p_level] += output * level_p_e; + levels[sp->sct_own][product->p_level] += output; wu((natid)0, sp->sct_own, "%s (%.2f) produced in %s\n", - product->p_name, output * level_p_e, ownxy(sp)); + product->p_name, output, ownxy(sp)); } else { - if ((actual = roundavg(level_p_e * output)) <= 0) + if ((actual = roundavg(output)) <= 0) return 0; if (product->p_nrdep != 0) { if (*resource * 100 < product->p_nrdep * actual) @@ -230,3 +226,28 @@ materials_charge(struct pchrstr *product, short *vec, int count) vec[item] = n; } } + +/* + * Return level p.e. for product PP. + * Zero means level is too low for production. + * LEVEL is the affecting production of PP; it must match PP->p_nlndx. + */ +double +prod_eff(struct pchrstr *pp, float level) +{ + double level_p_e; + + if (pp->p_nlndx < 0) + level_p_e = 1.0; + else { + double delta = (double)level - (double)pp->p_nlmin; + + if (delta < 0.0) + return 0.0; + if (CANT_HAPPEN(delta + pp->p_nllag <= 0)) + return 0.0; + level_p_e = delta / (delta + pp->p_nllag); + } + + return level_p_e * pp->p_effic * 0.01; +} diff --git a/src/lib/update/ship.c b/src/lib/update/ship.c index aaace64e..9df01894 100644 --- a/src/lib/update/ship.c +++ b/src/lib/update/ship.c @@ -168,13 +168,18 @@ upd_ship(register struct shpstr *sp, register int etus, /* * take care of oil production */ - oil_gained = roundavg((sp->shp_item[I_CIVIL] * etus / 10000.0) - * sectp->sct_oil); - max_oil = vl_find(V_OIL, mp->m_vtype, mp->m_vamt, mp->m_nv); - if (sp->shp_item[I_OIL] > max_oil) - oil_gained = max_oil - sp->shp_item[I_OIL]; - sp->shp_item[I_OIL] += oil_gained; product = &pchr[P_OIL]; + oil_gained = roundavg(total_work(100, etus, + sp->shp_item[I_CIVIL], + sp->shp_item[I_MILIT], + sp->shp_item[I_UW]) + * (double)sp->shp_effic / 100.0 + * (double)sectp->sct_oil / 100.0 + * prod_eff(product, sp->shp_tech)); + max_oil = vl_find(V_OIL, mp->m_vtype, mp->m_vamt, mp->m_nv); + if (sp->shp_item[I_OIL] + oil_gained > max_oil) + oil_gained = max_oil - sp->shp_item[I_OIL]; + sp->shp_item[I_OIL] += oil_gained; if (product->p_nrdep != 0 && oil_gained > 0) { resource = ((s_char *)sectp) + product->p_nrndx; *resource -= roundavg(oil_gained * @@ -182,8 +187,14 @@ upd_ship(register struct shpstr *sp, register int etus, } } if ((mp->m_flags & M_FOOD) && sectp->sct_type == SCT_WATER) { - sp->shp_item[I_FOOD] += ((sp->shp_item[I_CIVIL] * etus) / 1000.0) - * sectp->sct_fertil; + product = &pchr[P_FOOD]; + sp->shp_item[I_FOOD] += roundavg(total_work(100, etus, + sp->shp_item[I_CIVIL], + sp->shp_item[I_MILIT], + sp->shp_item[I_UW]) + * (double)sp->shp_effic / 100.0 + * (double)sectp->sct_fertil / 100.0 + * prod_eff(product, sp->shp_tech)); } if ((n = feed_ship(sp, etus, &needed, 1)) > 0) { wu(0, sp->shp_own, "%d starved on %s\n", n, prship(sp));