Beispiel #1
0
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;
}
Beispiel #2
0
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;
}