00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <config.h>
00037
00038 #include "commands.h"
00039 #include "item.h"
00040 #include "optlist.h"
00041 #include "product.h"
00042
00043 static void prprod(coord, coord, int, double, double, int, char,
00044 double, double, double, char[], int[], int[], int);
00045
00046 int
00047 count_pop(int n)
00048 {
00049 int i;
00050 int pop = 0;
00051 struct sctstr *sp;
00052
00053 for (i = 0; NULL != (sp = getsectid(i)); i++) {
00054 if (sp->sct_own != n)
00055 continue;
00056 if (sp->sct_oldown != n)
00057 continue;
00058 pop += sp->sct_item[I_CIVIL];
00059 }
00060 return pop;
00061 }
00062
00063 int
00064 prod(void)
00065 {
00066 struct natstr *natp;
00067 struct sctstr sect;
00068 struct nstr_sect nstr;
00069 struct pchrstr *pp;
00070 double p_e;
00071 double maxr;
00072 double prodeff;
00073 double real;
00074 int work;
00075 int totpop;
00076 int act;
00077 double cost;
00078 int i;
00079 int max;
00080 int nsect;
00081 double take;
00082 double mtake;
00083 int there;
00084 int unit_work;
00085 int used;
00086 i_type it;
00087 i_type vtype;
00088 unsigned char *resource;
00089 char cmnem[MAXPRCON];
00090 int cuse[MAXPRCON], cmax[MAXPRCON];
00091 int lcms, hcms;
00092 int civs;
00093 int uws;
00094 int bwork;
00095 int twork;
00096 int type;
00097 int eff;
00098 int maxpop;
00099 int otype;
00100 char mnem;
00101
00102 if (!snxtsct(&nstr, player->argp[1]))
00103 return RET_SYN;
00104 player->simulation = 1;
00105 prdate();
00106 nsect = 0;
00107 while (nxtsct(&nstr, §)) {
00108 if (!player->owner)
00109 continue;
00110
00111 civs = (1.0 + obrate * etu_per_update) * sect.sct_item[I_CIVIL];
00112 uws = (1.0 + uwbrate * etu_per_update) * sect.sct_item[I_UW];
00113 natp = getnatp(sect.sct_own);
00114 maxpop = max_pop(natp->nat_level[NAT_RLEV], §);
00115
00116 work = new_work(§,
00117 total_work(sect.sct_work, etu_per_update,
00118 civs, sect.sct_item[I_MILIT], uws,
00119 maxpop));
00120 bwork = work / 2;
00121
00122 if (sect.sct_off)
00123 continue;
00124 type = sect.sct_type;
00125 eff = sect.sct_effic;
00126 if (sect.sct_newtype != type) {
00127 twork = (eff + 3) / 4;
00128 if (twork > bwork) {
00129 twork = bwork;
00130 }
00131 bwork -= twork;
00132 eff -= twork * 4;
00133 otype = type;
00134 if (eff <= 0) {
00135 type = sect.sct_newtype;
00136 eff = 0;
00137 }
00138 if (!eff && IS_BIG_CITY(otype) && !IS_BIG_CITY(type)) {
00139 natp = getnatp(sect.sct_own);
00140 maxpop = max_population(natp->nat_level[NAT_RLEV],
00141 type, eff);
00142 work = new_work(§,
00143 total_work(sect.sct_work, etu_per_update,
00144 civs, sect.sct_item[I_MILIT],
00145 uws, maxpop));
00146 bwork = MIN(work / 2, bwork);
00147 }
00148 twork = 100 - eff;
00149 if (twork > bwork) {
00150 twork = bwork;
00151 }
00152 if (dchr[type].d_lcms > 0) {
00153 lcms = sect.sct_item[I_LCM];
00154 lcms /= dchr[type].d_lcms;
00155 if (twork > lcms)
00156 twork = lcms;
00157 }
00158 if (dchr[type].d_hcms > 0) {
00159 hcms = sect.sct_item[I_HCM];
00160 hcms /= dchr[type].d_hcms;
00161 if (twork > hcms)
00162 twork = hcms;
00163 }
00164 bwork -= twork;
00165 eff += twork;
00166 } else if (eff < 100) {
00167 twork = 100 - eff;
00168 if (twork > bwork) {
00169 twork = bwork;
00170 }
00171 bwork -= twork;
00172 eff += twork;
00173 }
00174 work = (work + 1) / 2 + bwork;
00175 if (eff < 60)
00176 continue;
00177
00178 p_e = eff / 100.0;
00179 if (p_e > 1.0)
00180 p_e = 1.0;
00181
00182 if (type == SCT_ENLIST) {
00183 int maxmil;
00184 int enlisted;
00185
00186 if (sect.sct_own != sect.sct_oldown)
00187 continue;
00188 civs = (1.0 + obrate * etu_per_update) * sect.sct_item[I_CIVIL];
00189 natp = getnatp(sect.sct_own);
00190 maxpop = max_pop(natp->nat_level[NAT_RLEV], §);
00191 civs = MIN(civs, maxpop);
00192 enlisted = 0;
00193 maxmil = (civs / 2) - sect.sct_item[I_MILIT];
00194 if (maxmil > 0) {
00195 enlisted = (etu_per_update
00196 * (10 + sect.sct_item[I_MILIT])
00197 * 0.05);
00198 if (enlisted > maxmil)
00199 enlisted = maxmil;
00200 }
00201 if (enlisted < 0)
00202 enlisted = 0;
00203 prprod(sect.sct_x, sect.sct_y, type, p_e, 1.0, work,
00204 ichr[I_MILIT].i_mnem, enlisted, maxmil, enlisted * 3,
00205 "c\0\0", &enlisted, &enlisted, nsect++);
00206 continue;
00207 }
00208
00209 if (dchr[type].d_prd < 0)
00210 continue;
00211 unit_work = 0;
00212 pp = &pchr[dchr[type].d_prd];
00213 vtype = pp->p_type;
00214 natp = getnatp(sect.sct_own);
00215
00216
00217
00218 if (pp->p_nrndx != 0) {
00219 unit_work++;
00220 resource = (unsigned char *)§ + pp->p_nrndx;
00221 p_e = (*resource * p_e) / 100.0;
00222 }
00223
00224
00225
00226 prodeff = prod_eff(type, natp->nat_level[pp->p_nlndx]);
00227
00228
00229
00230 used = 9999;
00231 for (i = 0; i < MAXPRCON; ++i) {
00232 it = pp->p_ctype[i];
00233 if (!pp->p_camt[i])
00234 continue;
00235 if (CANT_HAPPEN(it <= I_NONE || I_MAX < it))
00236 continue;
00237 used = MIN(used, sect.sct_item[it] / pp->p_camt[i]);
00238 unit_work += pp->p_camt[i];
00239 }
00240 if (unit_work == 0)
00241 unit_work = 1;
00242
00243
00244
00245
00246 max = (int)(work * p_e / (double)unit_work + 0.5);
00247 if (pp->p_nrdep != 0 && vtype != I_NONE) {
00248 if (*resource * 100 < pp->p_nrdep * max)
00249 max = *resource * 100 / pp->p_nrdep;
00250 }
00251 act = MIN(used, max);
00252
00253 real = MIN(999.0, (double)act * prodeff);
00254 maxr = MIN(999.0, (double)max * prodeff);
00255
00256 if (vtype != I_NONE) {
00257 if (real < 0.0)
00258 real = 0.0;
00259
00260 there = MIN(ITEM_MAX, sect.sct_item[vtype]);
00261 real = MIN(real, ITEM_MAX - there);
00262 }
00263
00264 if (prodeff != 0) {
00265 take = real / prodeff;
00266 mtake = maxr / prodeff;
00267 } else
00268 mtake = take = 0.0;
00269
00270 cost = take * pp->p_cost;
00271 if (opt_TECH_POP) {
00272 if (pp->p_level == NAT_TLEV) {
00273 totpop = count_pop(sect.sct_own);
00274 if (totpop > 50000)
00275 cost *= totpop / 50000.0;
00276 }
00277 }
00278
00279 for (i = 0; i < MAXPRCON; ++i) {
00280 cmnem[i] = cuse[i] = cmax[i] = 0;
00281 if (!pp->p_camt[i])
00282 continue;
00283 it = pp->p_ctype[i];
00284 if (CANT_HAPPEN(it <= I_NONE || I_MAX < it))
00285 continue;
00286 cmnem[i] = ichr[it].i_mnem;
00287 cuse[i] = (int)(take * pp->p_camt[i] + 0.5);
00288 cmax[i] = (int)(mtake * pp->p_camt[i] + 0.5);
00289 }
00290
00291 if (pp->p_type != I_NONE)
00292 mnem = ichr[vtype].i_mnem;
00293 else if (pp->p_level == NAT_TLEV || pp->p_level == NAT_RLEV)
00294 mnem = '.';
00295 else
00296 mnem = 0;
00297 prprod(sect.sct_x, sect.sct_y, type, p_e, prodeff, work,
00298 mnem, real, maxr, cost,
00299 cmnem, cuse, cmax, nsect++);
00300 }
00301 player->simulation = 0;
00302 if (nsect == 0) {
00303 if (player->argp[1])
00304 pr("%s: No sector(s)\n", player->argp[1]);
00305 else
00306 pr("%s: No sector(s)\n", "");
00307 return RET_FAIL;
00308 } else
00309 pr("%d sector%s\n", nsect, splur(nsect));
00310 return RET_OK;
00311 }
00312
00313 static void
00314 prprod(coord x, coord y, int type, double p_e, double prodeff, int work,
00315 char mnem, double make, double max, double cost,
00316 char cmnem[], int cuse[], int cmax[], int nsect)
00317 {
00318 int i;
00319
00320 if (nsect == 0) {
00321 pr("PRODUCTION SIMULATION\n");
00322 pr(" sect des eff avail make p.e. cost use1 use2 use3 max1 max2 max3 max\n");
00323 }
00324
00325 prxy("%4d,%-4d", x, y, player->cnum);
00326 pr(" %c %3.0f%% %5d", dchr[type].d_mnem, p_e * 100.0, work);
00327 if (mnem == '.')
00328 pr(" %5.2f", make);
00329 else
00330 pr(" %4.0f%c", make, mnem ? mnem : ' ');
00331 pr(" %.2f $%-5.0f", prodeff, cost);
00332 for (i = 0; i < 3; i++) {
00333 if (i < MAXPRCON && cmnem[i])
00334 pr("%4d%c", cuse[i], cmnem[i]);
00335 else
00336 pr(" ");
00337 }
00338 pr(" ");
00339 for (i = 0; i < 3; i++) {
00340 if (i < MAXPRCON && cmnem[i])
00341 pr("%4d%c", cmax[i], cmnem[i]);
00342 else
00343 pr(" ");
00344 }
00345 if (mnem == '.')
00346 pr(" %5.2f\n", max);
00347 else
00348 pr(" %5.0f\n", max);
00349 }