]> git.pond.sub.org Git - empserver/commitdiff
(pln_mine, pln_dropoff): Split off aerial mining into new pln_mine().
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 14 Aug 2004 17:12:20 +0000 (17:12 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 14 Aug 2004 17:12:20 +0000 (17:12 +0000)
Callers changed.

(drop): Do not disclose anything about target sector before planes
actually got there, unless the target sector is owned by the player or
an ally.  This plugs a major loophole.  Consequently, the command can
no longer always refuse to attempt to drop stuff where it won't work.
Instead, the planes fly out to try.  Other plane commands (para, bomb)
behave exactly the same.  Also closes #909859.
(pln_dropoff): Cope with planes trying to drop where they can't.

(drop): Refuse to drop civilians into allied sectors, for consistency
with other means to move around stuff.

include/prototypes.h
src/lib/commands/drop.c
src/lib/subs/plnsub.c

index ccbc51f6e7a2fa444d9dd370a849020df976b2ba..74b86d6d1277074798f0d1f6fd9f64a386a77fd4 100644 (file)
@@ -400,6 +400,7 @@ extern int can_be_on_ship(int, int);
 extern int put_plane_on_ship(struct plnstr *, struct shpstr *);
 extern void pln_dropoff(struct emp_qelem *, struct ichrstr *,
                        coord, coord, void *, int);
+extern void pln_mine(struct emp_qelem *list, struct sctstr *sectp);
 extern void pln_sel(struct nstr_item *, struct emp_qelem *,
                    struct sctstr *, int, int, int, int);
 extern int pln_arm(struct emp_qelem *, int, int, struct ichrstr *,
index 7dbadfab1bb8b9644190f3ac7394ee75f39a3a8b..f91567cb3f52e755893722f48b5e48d63e2f50ac 100644 (file)
@@ -50,7 +50,6 @@
 int
 drop(void)
 {
-    int rel;
     s_char *p;
     int mission_flags;
     int tech;
@@ -87,28 +86,37 @@ drop(void)
     }
     ax = x;
     ay = y;
-    if (getpath(flightpath, player->argp[4], ax, ay, 0, 0,
-               0, P_FLYING) == 0 || *flightpath == 0)
+    if (getpath(flightpath, player->argp[4], ax, ay, 0, 0, 0, P_FLYING) == 0
+       || *flightpath == 0)
        return RET_SYN;
     tx = ax;
     ty = ay;
     (void)pathtoxy(flightpath, &tx, &ty, fcost);
     pr("target is %s\n", xyas(tx, ty, player->cnum));
+    if ((ip = whatitem(player->argp[5], "Drop off what? ")) == 0)
+       return RET_SYN;
     getsect(tx, ty, &target);
 
-    rel = getrel(getnatp(target.sct_own), player->cnum);
-    if (rel != ALLIED && target.sct_own != player->cnum
-       && target.sct_type != SCT_WATER) {
-       pr("You don't own %s!\n", xyas(tx, ty, player->cnum));
-       return RET_FAIL;
+    if (target.sct_own == player->cnum
+       || getrel(getnatp(target.sct_own), player->cnum) == ALLIED) {
+       if (ip->i_vtype == V_CIVIL) {
+           if (target.sct_own != player->cnum) {
+               pr("Your civilians refuse to emigrate!\n");
+               return RET_FAIL;
+           } else if (target.sct_own != target.sct_oldown) {
+               pr("Can't drop civilians into occupied sectors.\n");
+               return RET_FAIL;
+           }
+       }
+    } else {
+       /* into the unknown... */
+       if (ip->i_vtype != V_SHELL) {
+           pr("You don't own %s!\n", xyas(tx, ty, player->cnum));
+           return RET_FAIL;
+       }
+       wantflags = P_MINE;
     }
 
-    if ((ip = whatitem(player->argp[5], "Drop off what? ")) == 0)
-       return RET_SYN;
-    if (ip->i_vtype == V_CIVIL && target.sct_own != target.sct_oldown) {
-       pr("Can't drop civilians into occupied sectors.\n");
-       return RET_FAIL;
-    }
     ap_to_target = strlen(flightpath);
     if (*(flightpath + strlen(flightpath) - 1) == 'h')
        ap_to_target--;
@@ -119,6 +127,10 @@ drop(void)
     mission_flags = 0;
     pln_sel(&ni_bomb, &bomb_list, &ap_sect, ap_to_target,
            2, wantflags, P_M | P_O);
+    if (QEMPTY(&bomb_list)) {
+       pr("No planes could be equipped for the mission.\n");
+       return RET_FAIL;
+    }
     pln_sel(&ni_esc, &esc_list, &ap_sect, ap_to_target,
            2, P_ESC | P_F, P_M | P_O);
     /*
@@ -130,28 +142,25 @@ drop(void)
     mission_flags |= P_X;      /* stealth (shhh) */
     mission_flags |= P_H;      /* gets turned off if not all choppers */
     mission_flags |= P_MINE;
-    mission_flags =
-       pln_arm(&bomb_list, 2 * ap_to_target, 'd', ip, 0, mission_flags,
-               &tech);
-    if (rel != ALLIED && target.sct_own != player->cnum
-       && target.sct_type == SCT_WATER && !(mission_flags & P_MINE)) {
-       pr("You don't own %s!\n", xyas(tx, ty, player->cnum));
-       return RET_FAIL;
-    }
+    mission_flags = pln_arm(&bomb_list, 2 * ap_to_target, 'd',
+                           ip, 0, mission_flags, &tech);
     if (QEMPTY(&bomb_list)) {
        pr("No planes could be equipped for the mission.\n");
        return RET_FAIL;
     }
-    mission_flags =
-       pln_arm(&esc_list, 2 * ap_to_target, 'd', ip, P_ESC | P_F,
-               mission_flags, &tech);
+    mission_flags = pln_arm(&esc_list, 2 * ap_to_target, 'd',
+                           ip, P_ESC | P_F, mission_flags, &tech);
     ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, mission_flags,
                 0, 0, 0);
     if (QEMPTY(&bomb_list)) {
        pr("No planes got through fighter defenses\n");
     } else {
        getsect(tx, ty, &target);
-       pln_dropoff(&bomb_list, ip, tx, ty, (s_char *)&target, EF_SECTOR);
+       if (target.sct_type == SCT_WATER && (mission_flags & P_MINE)
+           && ip->i_vtype == V_SHELL)
+           pln_mine(&bomb_list, &target);
+       else
+           pln_dropoff(&bomb_list, ip, tx, ty, (s_char *)&target, EF_SECTOR);
     }
     pln_put(&bomb_list);
     pln_put(&esc_list);
index c97f1c891ce53ec475815b9463ee5d2bcb685dbc..3e0bc1adc07e54796b586e38eddcd6ef16c62a90 100644 (file)
@@ -279,15 +279,22 @@ pln_dropoff(struct emp_qelem *list, struct ichrstr *ip, coord tx, coord ty,
     }
     if (type == EF_SECTOR) {
        sectp = ptr;
-       if (sectp->sct_type == SCT_WATER && ip->i_vtype == V_SHELL) {
-           /* aerial mining */
-           sectp->sct_mines = min(sectp->sct_mines + amt, MINES_MAX);
-           pr("%d mines laid in %s.\n", amt,
-              xyas(sectp->sct_x, sectp->sct_y, player->cnum));
-           if (amt > 0
-               && map_set(player->cnum, sectp->sct_x, sectp->sct_y, 'X', 0))
-               writemap(player->cnum);
-           putsect(sectp);
+       if (!sectp->sct_own) {
+           if (sectp->sct_type == SCT_WATER)
+               pr("Your %s sink like a rock!\n", ip->i_name);
+           else
+               pr("Your %s vanish without a trace.\n", ip->i_name);
+           return;
+       }
+       if (sectp->sct_own != player->cnum
+           && getrel(getnatp(sectp->sct_own), player->cnum) != ALLIED) {
+           pr("You don't own %s!  Cargo jettisoned...\n",
+              xyas(tx, ty, player->cnum));
+           return;
+       }
+       if (ip->i_vtype == V_CIVIL && sectp->sct_own != sectp->sct_oldown) {
+           pr("%s is occupied.  Your civilians suffer from identity crisis and die.\n",
+              xyas(tx, ty, player->cnum));
            return;
        }
        there = sectp->sct_item[ip->i_vtype];
@@ -326,6 +333,29 @@ pln_dropoff(struct emp_qelem *list, struct ichrstr *ip, coord tx, coord ty,
     }
 }
 
+void
+pln_mine(struct emp_qelem *list, struct sctstr *sectp)
+{
+    struct emp_qelem *qp;
+    struct plist *plp;
+    int amt;
+
+    amt = 0;
+    for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
+       plp = (struct plist *)qp;
+       amt += plp->misc;
+
+    }
+    if (amt > 0) {
+       sectp->sct_mines = min(sectp->sct_mines + amt, MINES_MAX);
+       pr("%d mines laid in %s.\n", amt,
+          xyas(sectp->sct_x, sectp->sct_y, player->cnum));
+       if (map_set(player->cnum, sectp->sct_x, sectp->sct_y, 'X', 0))
+           writemap(player->cnum);
+       putsect(sectp);
+    }
+}
+
 void
 pln_sel(struct nstr_item *ni, struct emp_qelem *list, struct sctstr *ap,
        int ap_to_target, int rangemult, int wantflags, int nowantflags)