]> git.pond.sub.org Git - empserver/blobdiff - src/lib/update/plane.c
Update copyright notice
[empserver] / src / lib / update / plane.c
index dea614c05d74456857ee7ce2a1d2199c29716c3c..80844633428f074eee237868b40f5c80e93b9fc6 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2020, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
  *  Known contributors to this file:
  *     Dave Pare, 1986
  *     Steve McClure, 1998
- *     Markus Armbruster, 2006-2008
+ *     Markus Armbruster, 2006-2016
  */
 
 #include <config.h>
 
-#include "budg.h"
+#include "chance.h"
 #include "lost.h"
+#include "nat.h"
+#include "optlist.h"
 #include "plane.h"
 #include "player.h"
+#include "prototypes.h"
 #include "ship.h"
 #include "update.h"
 
-static void planerepair(struct plnstr *, struct natstr *, struct bp *, int);
-static void upd_plane(struct plnstr *, int, struct natstr *, struct bp *, int);
+static void upd_plane(struct plnstr *, int, struct bp *, int);
+static void planerepair(struct plnstr *, struct natstr *, struct bp *,
+                       int, struct budget *);
 
-int
-prod_plane(int etus, int natnum, struct bp *bp, int buildem)
-                /* Build = 1, maintain =0 */
+void prep_planes(int etus, struct bp *bp)
 {
+    int mil, i;
+    double mil_pay;
     struct plnstr *pp;
-    struct natstr *np;
-    int n, k = 0;
-    int start_money;
 
-    for (n = 0; NULL != (pp = getplanep(n)); n++) {
+    for (i = 0; (pp = getplanep(i)); i++) {
        if (pp->pln_own == 0)
            continue;
-       if (pp->pln_own != natnum)
-           continue;
        if (pp->pln_effic < PLANE_MINEFF) {
            makelost(EF_PLANE, pp->pln_own, pp->pln_uid,
                     pp->pln_x, pp->pln_y);
@@ -66,78 +64,92 @@ prod_plane(int etus, int natnum, struct bp *bp, int buildem)
            continue;
        }
 
-       if (pln_is_in_orbit(pp)) {
-           if (!player->simulation && buildem == 0
-               && !(pp->pln_flags & PLN_SYNCHRONOUS))
-               move_sat(pp);
-           continue;
-       }
-
-       np = getnatp(pp->pln_own);
-       start_money = np->nat_money;
-       upd_plane(pp, etus, np, bp, buildem);
-       air_money[pp->pln_own] += np->nat_money - start_money;
-       if (buildem == 0 || np->nat_money != start_money)
-           k++;
-       if (player->simulation)
-           np->nat_money = start_money;
+       bp_consider_unit(bp, (struct empobj *)pp);
+       mil = plchr[pp->pln_type].pl_mat[I_MILIT];
+       /* flight pay is 5x the pay received by other military */
+       mil_pay = mil * etus * money_mil * 5;
+       nat_budget[pp->pln_own].bm[BUDG_PLN_MAINT].money += mil_pay;
+       nat_budget[pp->pln_own].money += mil_pay;
     }
+}
 
-    return k;
+void
+prod_plane(int etus, struct bp *bp, int buildem)
+                /* Build = 1, maintain =0 */
+{
+    struct plnstr *pp;
+    int i;
+
+    for (i = 0; (pp = getplanep(i)); i++) {
+       if (pp->pln_own == 0)
+           continue;
+       if (bp_skip_unit(bp, (struct empobj *)pp))
+           continue;
+       upd_plane(pp, etus, bp, buildem);
+    }
 }
 
 static void
-upd_plane(struct plnstr *pp, int etus,
-         struct natstr *np, struct bp *bp, int build)
+upd_plane(struct plnstr *pp, int etus, struct bp *bp, int build)
 {
-    struct plchrstr *pcp = &plchr[(int)pp->pln_type];
-    int mult, cost, eff;
+    struct budget *budget = &nat_budget[pp->pln_own];
+    struct plchrstr *pcp = &plchr[pp->pln_type];
+    struct natstr *np = getnatp(pp->pln_own);
+    int mult, eff_lost;
+    double cost;
 
     if (build == 1) {
-       if (!pp->pln_off && np->nat_money >= 0)
-           planerepair(pp, np, bp, etus);
+       if (!pp->pln_off && budget->money >= 0)
+           planerepair(pp, np, bp, etus, budget);
        if (!player->simulation)
            pp->pln_off = 0;
     } else {
        mult = 1;
        if (np->nat_level[NAT_TLEV] < pp->pln_tech * 0.85)
            mult = 2;
-       cost = -(mult * etus * MIN(0.0, pcp->pl_cost * money_plane));
-       if (np->nat_money < cost && !player->simulation) {
-           if ((eff = pp->pln_effic - etus / 5) < PLANE_MINEFF) {
-               wu(0, pp->pln_own,
-                  "%s lost to lack of maintenance\n", prplane(pp));
-               makelost(EF_PLANE, pp->pln_own, pp->pln_uid,
-                        pp->pln_x, pp->pln_y);
-               pp->pln_own = 0;
-               pp->pln_ship = pp->pln_land = -1;
-               return;
+       budget->bm[BUDG_PLN_MAINT].count++;
+       cost = mult * etus * -money_plane * pcp->pl_cost;
+       if (budget->money < cost && !player->simulation) {
+           eff_lost = etus / 5;
+           if (pp->pln_effic - eff_lost < PLANE_MINEFF)
+               eff_lost = pp->pln_effic - PLANE_MINEFF;
+           if (eff_lost > 0) {
+               wu(0, pp->pln_own, "%s lost %d%% to lack of maintenance\n",
+                  prplane(pp), eff_lost);
+               pp->pln_effic -= eff_lost;
            }
-           wu(0, pp->pln_own,
-              "%s lost %d%% to lack of maintenance\n",
-              prplane(pp), pp->pln_effic - eff);
-           pp->pln_effic = eff;
        } else {
-           np->nat_money -= cost;
+           budget->bm[BUDG_PLN_MAINT].money -= cost;
+           budget->money -= cost;
+       }
+
+       if (pln_is_in_orbit(pp) && !(pp->pln_flags & PLN_SYNCHRONOUS)) {
+           if (!player->simulation)
+               move_sat(pp);
        }
-       /* flight pay is 5x the pay received by other military */
-       np->nat_money += etus * pcp->pl_crew * money_mil * 5;
     }
 }
 
 static void
-planerepair(struct plnstr *pp, struct natstr *np, struct bp *bp, int etus)
+planerepair(struct plnstr *pp, struct natstr *np, struct bp *bp, int etus,
+           struct budget *budget)
 {
+    struct plchrstr *pcp = &plchr[(int)pp->pln_type];
     int build;
-    int mvec[I_MAX + 1];
     struct shpstr *carrier;
-    struct plchrstr *pcp = &plchr[(int)pp->pln_type];
-    struct sctstr *sp = getsectp(pp->pln_x, pp->pln_y);
+    struct sctstr *sp, scratch_sect;
     int delta;
     int mult;
     int avail;
-    int w_p_eff;
     int used;
+    double cost;
+
+    if (pp->pln_effic == 100)
+       return;
+
+    sp = getsectp(pp->pln_x, pp->pln_y);
+    if (sp->sct_off)
+       return;
 
     carrier = NULL;
     if (pp->pln_ship >= 0) {
@@ -148,33 +160,28 @@ planerepair(struct plnstr *pp, struct natstr *np, struct bp *bp, int etus)
            return;
        if (carrier->shp_off)
            return;
-       if ((carrier->shp_own != pp->pln_own) &&
-           (getrel(getnatp(carrier->shp_own), pp->pln_own) != ALLIED))
+       if (relations_with(carrier->shp_own, pp->pln_own) != ALLIED)
            return;
     } else {
-       if ((sp->sct_own != pp->pln_own) &&
-           (getrel(getnatp(sp->sct_own), pp->pln_own) != ALLIED))
+       if (relations_with(sp->sct_own, pp->pln_own) != ALLIED)
            return;
     }
 
-    if (sp->sct_off)
-       return;
+    if (player->simulation) {
+       scratch_sect = *sp;
+       bp_to_sect(bp, &scratch_sect);
+       sp = &scratch_sect;
+    }
+
     mult = 1;
     if (np->nat_level[NAT_TLEV] < pp->pln_tech * 0.85)
        mult = 2;
 
-    if (pp->pln_effic == 100)
-       return;
-
-    if (!player->simulation)
-       avail = sp->sct_avail * 100;
-    else
-       avail = bp_get_avail(bp, sp) * 100;
+    avail = sp->sct_avail * 100;
     if (carrier)
        avail += etus * carrier->shp_item[I_MILIT] / 2;
 
-    w_p_eff = PLN_BLD_WORK(pcp->pl_lcm, pcp->pl_hcm);
-    delta = roundavg((double)avail / w_p_eff);
+    delta = avail / pcp->pl_bwork;
     if (delta <= 0)
        return;
     if (delta > (int)((float)etus * plane_grow_scale))
@@ -182,31 +189,16 @@ planerepair(struct plnstr *pp, struct natstr *np, struct bp *bp, int etus)
     if (delta > 100 - pp->pln_effic)
        delta = 100 - pp->pln_effic;
 
-    memset(mvec, 0, sizeof(mvec));
-    mvec[I_MILIT] =  pcp->pl_crew;
-    mvec[I_LCM] =  pcp->pl_lcm;
-    mvec[I_HCM] = pcp->pl_hcm;
-    build = get_materials(sp, bp, mvec, delta);
+    build = get_materials(sp, pcp->pl_mat, delta);
 
     if (carrier)
        build = delta;
 
-    used = build * w_p_eff;
-    /*
-     * I didn't use roundavg here, because I want to
-     * penalize the player with a large number of planes.
-     */
-    if (!player->simulation)
-       avail = (sp->sct_avail * 100 - used) / 100;
-    else
-       avail = (bp_get_avail(bp, sp) * 100 - used) / 100;
-
+    used = build * pcp->pl_bwork;
+    avail = roundavg((sp->sct_avail * 100 - used) / 100.0);
     if (avail < 0)
        avail = 0;
-    if (!player->simulation)
-       sp->sct_avail = avail;
-    else
-       bp_put_avail(bp, sp, avail);
+    sp->sct_avail = avail;
 
     if (sp->sct_type != SCT_AIRPT)
        build /= 3;
@@ -215,8 +207,11 @@ planerepair(struct plnstr *pp, struct natstr *np, struct bp *bp, int etus)
            build = 80 - pp->pln_effic;
     }
 
-    np->nat_money -= mult * build * pcp->pl_cost / 100.0;
-
+    bp_set_from_sect(bp, sp);
+    cost = mult * pcp->pl_cost * build / 100.0;
+    budget->bm[BUDG_PLN_BUILD].count += !!build;
+    budget->bm[BUDG_PLN_BUILD].money -= cost;
+    budget->money -= cost;
     if (!player->simulation)
        pp->pln_effic += (signed char)build;
 }