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
00037 #include <config.h>
00038
00039 #include "budg.h"
00040 #include "land.h"
00041 #include "lost.h"
00042 #include "news.h"
00043 #include "plague.h"
00044 #include "player.h"
00045 #include "ship.h"
00046 #include "update.h"
00047 #include <math.h>
00048
00049 static void landrepair(struct lndstr *, struct natstr *, struct bp *, int);
00050 static void upd_land(struct lndstr *, int, struct natstr *, struct bp *, int);
00051 static int feed_land(struct lndstr *, int);
00052
00053 int
00054 prod_land(int etus, int natnum, struct bp *bp, int build)
00055
00056 {
00057 struct lndstr *lp;
00058 struct sctstr *sp;
00059 struct natstr *np;
00060 int n, k = 0;
00061 int start_money;
00062 int lastx = 9999, lasty = 9999;
00063
00064 bp_enable_cachepath();
00065 for (n = 0; NULL != (lp = getlandp(n)); n++) {
00066 if (lp->lnd_own == 0)
00067 continue;
00068 if (lp->lnd_own != natnum)
00069 continue;
00070 if (lp->lnd_effic < LAND_MINEFF) {
00071 makelost(EF_LAND, lp->lnd_own, lp->lnd_uid,
00072 lp->lnd_x, lp->lnd_y);
00073 lp->lnd_own = 0;
00074 continue;
00075 }
00076
00077 sp = getsectp(lp->lnd_x, lp->lnd_y);
00078 if (sp->sct_type == SCT_SANCT)
00079 continue;
00080 if (lastx == 9999 || lasty == 9999) {
00081 lastx = lp->lnd_x;
00082 lasty = lp->lnd_y;
00083 }
00084 if (lastx != lp->lnd_x || lasty != lp->lnd_y) {
00085
00086 bp_disable_cachepath();
00087 bp_clear_cachepath();
00088 bp_enable_cachepath();
00089 }
00090 np = getnatp(lp->lnd_own);
00091 start_money = np->nat_money;
00092 upd_land(lp, etus, np, bp, build);
00093 lnd_money[lp->lnd_own] += np->nat_money - start_money;
00094 if (!build || np->nat_money != start_money)
00095 k++;
00096 if (player->simulation)
00097 np->nat_money = start_money;
00098 }
00099 bp_disable_cachepath();
00100 bp_clear_cachepath();
00101
00102 return k;
00103 }
00104
00105 static void
00106 upd_land(struct lndstr *lp, int etus,
00107 struct natstr *np, struct bp *bp, int build)
00108
00109 {
00110 struct lchrstr *lcp;
00111 int pstage, ptime;
00112 int n;
00113 int min = morale_base - (int)np->nat_level[NAT_HLEV];
00114 int mult;
00115 int cost;
00116 int eff;
00117
00118 if (!player->simulation)
00119 if (lp->lnd_retreat < min)
00120 lp->lnd_retreat = min;
00121
00122 lcp = &lchr[(int)lp->lnd_type];
00123 if (build == 1) {
00124 if (!lp->lnd_off && np->nat_money >= 0)
00125 landrepair(lp, np, bp, etus);
00126 if (!player->simulation)
00127 lp->lnd_off = 0;
00128 } else {
00129 mult = 1;
00130 if (np->nat_level[NAT_TLEV] < lp->lnd_tech * 0.85)
00131 mult = 2;
00132 if (lcp->l_flags & L_ENGINEER)
00133 mult *= 3;
00134 cost = -(mult * etus * MIN(0.0, money_land * lcp->l_cost));
00135 if (np->nat_money < cost && !player->simulation) {
00136 if ((eff = lp->lnd_effic - etus / 5) < LAND_MINEFF) {
00137 wu(0, lp->lnd_own,
00138 "%s lost to lack of maintenance\n", prland(lp));
00139 makelost(EF_LAND, lp->lnd_own, lp->lnd_uid,
00140 lp->lnd_x, lp->lnd_y);
00141 lp->lnd_own = 0;
00142 return;
00143 }
00144 wu(0, lp->lnd_own,
00145 "%s lost %d%% to lack of maintenance\n",
00146 prland(lp), lp->lnd_effic - eff);
00147 lp->lnd_effic = eff;
00148 } else {
00149 np->nat_money -= cost;
00150 }
00151
00152 if (!player->simulation) {
00153
00154 if ((n = feed_land(lp, etus)) > 0) {
00155 wu(0, lp->lnd_own, "%d starved in %s%s\n",
00156 n, prland(lp),
00157 (lp->lnd_effic < LAND_MINEFF ? ", killing it" : ""));
00158 if (n > 10)
00159 nreport(lp->lnd_own, N_DIE_FAMINE, 0, 1);
00160 }
00161
00162
00163
00164
00165 pstage = lp->lnd_pstage;
00166 ptime = lp->lnd_ptime;
00167 if (pstage != PLG_HEALTHY) {
00168 n = plague_people(np, lp->lnd_item, &pstage, &ptime, etus);
00169 switch (n) {
00170 case PLG_DYING:
00171 wu(0, lp->lnd_own,
00172 "PLAGUE deaths reported on %s\n", prland(lp));
00173 nreport(lp->lnd_own, N_DIE_PLAGUE, 0, 1);
00174 break;
00175 case PLG_INFECT:
00176 wu(0, lp->lnd_own, "%s battling PLAGUE\n", prland(lp));
00177 break;
00178 case PLG_INCUBATE:
00179
00180 if (n == pstage) {
00181
00182 if (ptime <= etus) {
00183
00184 wu(0, lp->lnd_own,
00185 "Outbreak of PLAGUE on %s!\n", prland(lp));
00186 nreport(lp->lnd_own, N_OUT_PLAGUE, 0, 1);
00187 }
00188 } else {
00189
00190 wu(0, lp->lnd_own,
00191 "%s battling PLAGUE\n", prland(lp));
00192 }
00193 break;
00194 case PLG_EXPOSED:
00195
00196 if (n != pstage) {
00197
00198 if (ptime <= etus) {
00199
00200 wu(0, lp->lnd_own,
00201 "Outbreak of PLAGUE on %s!\n", prland(lp));
00202 nreport(lp->lnd_own, N_OUT_PLAGUE, 0, 1);
00203 }
00204 }
00205 break;
00206 default:
00207 break;
00208 }
00209 lp->lnd_pstage = pstage;
00210 lp->lnd_ptime = ptime;
00211 }
00212 }
00213 }
00214 }
00215
00216 static void
00217 landrepair(struct lndstr *land, struct natstr *np, struct bp *bp, int etus)
00218 {
00219 int delta;
00220 struct sctstr *sp;
00221 struct lchrstr *lp;
00222 int build;
00223 int avail;
00224 int w_p_eff;
00225 int mult;
00226 int mvec[I_MAX + 1];
00227
00228 lp = &lchr[(int)land->lnd_type];
00229 sp = getsectp(land->lnd_x, land->lnd_y);
00230 if (sp->sct_off)
00231 return;
00232 mult = 1;
00233 if (np->nat_level[NAT_TLEV] < land->lnd_tech * 0.85)
00234 mult = 2;
00235
00236 if (land->lnd_effic == 100) {
00237
00238 return;
00239 }
00240 if ((sp->sct_own != land->lnd_own) &&
00241 (getrel(getnatp(sp->sct_own), land->lnd_own) != ALLIED))
00242 return;
00243
00244 if (!player->simulation)
00245 avail = sp->sct_avail * 100;
00246 else
00247 avail = bp_get_avail(bp, sp) * 100;
00248
00249 w_p_eff = LND_BLD_WORK(lp->l_lcm, lp->l_hcm);
00250 delta = roundavg((double)avail / w_p_eff);
00251 if (delta <= 0)
00252 return;
00253 if (delta > (int)((float)etus * land_grow_scale))
00254 delta = (int)((float)etus * land_grow_scale);
00255 if (delta > 100 - land->lnd_effic)
00256 delta = 100 - land->lnd_effic;
00257
00258 memset(mvec, 0, sizeof(mvec));
00259 mvec[I_LCM] = lp->l_lcm;
00260 mvec[I_HCM] = lp->l_hcm;
00261 build = get_materials(sp, bp, mvec, delta);
00262
00263 if ((sp->sct_type != SCT_HEADQ) && (sp->sct_type != SCT_FORTR))
00264 build /= 3;
00265
00266 avail -= build * w_p_eff;
00267 if (avail < 0)
00268 avail = 0;
00269 if (!player->simulation)
00270 sp->sct_avail = avail / 100;
00271 else
00272 bp_put_avail(bp, sp, avail / 100);
00273
00274 if (build < 0)
00275 logerror("land unit %d building %d ! \n", land->lnd_uid, build);
00276 np->nat_money -= mult * lp->l_cost * build / 100.0;
00277 if (!player->simulation) {
00278 land->lnd_effic += (signed char)build;
00279 }
00280 }
00281
00282
00283
00284
00285 static int
00286 feed_land(struct lndstr *lp, int etus)
00287 {
00288 int needed;
00289
00290 if (opt_NOFOOD)
00291 return 0;
00292
00293 needed = (int)ceil(food_needed(lp->lnd_item, etus));
00294
00295
00296 if (needed > lp->lnd_item[I_FOOD])
00297 resupply_commod(lp, I_FOOD);
00298
00299 return feed_people(lp->lnd_item, etus);
00300 }