int produce(struct natstr *np, struct sctstr *sp, short *vec, int work, int desig, int neweff, int *cost, int *amount) { struct pchrstr *product; double p_e; double prodeff; unsigned char *resource; double output; int actual; int unit_work, work_used; i_type item; double worker_limit; int material_limit, res_limit; int material_consume; int val; if (dchr[desig].d_prd < 0) return 0; product = &pchr[dchr[desig].d_prd]; item = product->p_type; if (product->p_nrndx) resource = (unsigned char *)sp + product->p_nrndx; else resource = NULL; *amount = 0; *cost = 0; material_limit = prod_materials_cost(product, vec, &unit_work); if (material_limit <= 0) return 0; /* sector p.e. */ p_e = neweff / 100.0; if (resource) { unit_work++; p_e *= *resource / 100.0; } if (unit_work == 0) unit_work = 1; worker_limit = work * p_e / unit_work; res_limit = prod_resource_limit(product, resource); material_consume = res_limit; if (material_consume > worker_limit) material_consume = (int)worker_limit; if (material_consume > material_limit) material_consume = material_limit; if (material_consume == 0) return 0; prodeff = prod_eff(desig, 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 = material_consume * prodeff; if (item == I_NONE) { actual = ldround(output, 1); if (!player->simulation) { levels[sp->sct_own][product->p_level] += output; wu(0, sp->sct_own, "%s (%.2f) produced in %s\n", product->p_name, output, ownxy(sp)); } } else { actual = roundavg(output); if (actual <= 0) return 0; if (actual > 999) { actual = 999; material_consume = roundavg(actual / prodeff); } if (vec[item] + actual > ITEM_MAX) { actual = ITEM_MAX - vec[item]; material_consume = roundavg(actual / prodeff); if (material_consume < 0) material_consume = 0; if (sp->sct_own && !player->simulation) wu(0, sp->sct_own, "%s production backlog in %s\n", product->p_name, ownxy(sp)); } vec[item] += actual; } /* * Reset produced amount by commodity production ratio */ if (!player->simulation) { materials_charge(product, vec, material_consume); if (resource && product->p_nrdep != 0) { /* * lower natural resource in sector depending on * amount produced */ val = *resource - roundavg(product->p_nrdep * material_consume / 100.0); if (val < 0) val = 0; *resource = val; } } *amount = actual; *cost = product->p_cost * material_consume; if (opt_TECH_POP) { if (product->p_level == NAT_TLEV) { if (tpops[sp->sct_own] > 50000) *cost *= tpops[sp->sct_own] / 50000.0; } } if (CANT_HAPPEN(p_e <= 0.0)) return 0; work_used = roundavg(unit_work * material_consume / p_e); if (CANT_HAPPEN(work_used > work)) return work; return work_used; }
void do_plague(struct sctstr *sp, struct natstr *np, int etu) { int pstage, ptime; int n; if (opt_NO_PLAGUE) /* no plague nothing to do */ return; pstage = sp->sct_pstage; ptime = sp->sct_ptime; if (pstage == PLG_HEALTHY) { pstage = infect_people(np, sp); ptime = 0; } else { n = plague_people(np, sp->sct_item, &pstage, &ptime, etu); switch (n) { case PLG_DYING: wu(0, sp->sct_own, "PLAGUE deaths reported in %s.\n", ownxy(sp)); nreport(sp->sct_own, N_DIE_PLAGUE, 0, 1); break; case PLG_INFECT: wu(0, sp->sct_own, "%s battling PLAGUE\n", ownxy(sp)); break; case PLG_INCUBATE: /* Are we still incubating? */ if (n == pstage) { /* Yes. Will it turn "infectious" next time? */ if (ptime <= etu) { /* Yes. Report an outbreak. */ wu(0, sp->sct_own, "Outbreak of PLAGUE in %s!\n", ownxy(sp)); nreport(sp->sct_own, N_OUT_PLAGUE, 0, 1); } } else { /* It has already moved on to "infectious" */ wu(0, sp->sct_own, "%s battling PLAGUE\n", ownxy(sp)); } break; case PLG_EXPOSED: /* Has the plague moved to "incubation" yet? */ if (n != pstage) { /* Yes. Will it turn "infectious" next time? */ if (ptime <= etu) { /* Yes. Report an outbreak. */ wu(0, sp->sct_own, "Outbreak of PLAGUE in %s!\n", ownxy(sp)); nreport(sp->sct_own, N_OUT_PLAGUE, 0, 1); } } break; default: break; } } if (sp->sct_item[I_CIVIL] == 0 && sp->sct_item[I_MILIT] == 0 && !has_units(sp->sct_x, sp->sct_y, sp->sct_own, NULL)) { makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y); sp->sct_own = 0; sp->sct_oldown = 0; } sp->sct_pstage = pstage; sp->sct_ptime = ptime; }