src/lib/commands/scut.c

Go to the documentation of this file.
00001 /*
00002  *  Empire - A multi-player, client/server Internet based war game.
00003  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
00004  *                           Ken Stevens, Steve McClure
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  ---
00021  *
00022  *  See files README, COPYING and CREDITS in the root of the source
00023  *  tree for related information and legal notices.  It is expected
00024  *  that future projects/authors will amend these files as needed.
00025  *
00026  *  ---
00027  *
00028  *  scut.c: Scuttle ships, planes or land units
00029  * 
00030  *  Known contributors to this file:
00031  *     
00032  */
00033 
00034 #include <config.h>
00035 
00036 #include <ctype.h>
00037 #include "commands.h"
00038 #include "empobj.h"
00039 #include "optlist.h"
00040 
00041 static void scuttle_land(struct lndstr *);
00042 
00043 int
00044 scut(void)
00045 {
00046     struct nstr_item ni;
00047     union empobj_storage item;
00048     int type;
00049     struct mchrstr *mp;
00050     char *p;
00051     char prompt[128];
00052     char buf[1024];
00053 
00054     if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
00055         return RET_SYN;
00056     switch (*p) {
00057     case 's':
00058         type = EF_SHIP;
00059         break;
00060     case 'p':
00061         type = EF_PLANE;
00062         break;
00063     case 'l':
00064         type = EF_LAND;
00065         break;
00066     default:
00067         pr("Ships, land units, or planes only! (s, l, p)\n");
00068         return RET_SYN;
00069     }
00070     sprintf(prompt, "%s(s)? ", ef_nameof(type));
00071     if ((p = getstarg(player->argp[2], prompt, buf)) == 0)
00072         return RET_SYN;
00073     if (!snxtitem(&ni, type, p))
00074         return RET_SYN;
00075     if (p && (isalpha(*p) || (*p == '*') || (*p == '~') || issector(p)
00076               || islist(p))) {
00077         char y_or_n[80], bbuf[80];
00078 
00079         if (type == EF_SHIP) {
00080             if (*p == '*')
00081                 sprintf(bbuf, "all ships");
00082             else if (*p == '~')
00083                 sprintf(bbuf, "all unassigned ships");
00084             else if (issector(p))
00085                 sprintf(bbuf, "all ships in %s", p);
00086             else if (isalpha(*p))
00087                 sprintf(bbuf, "fleet %c", *p);
00088             else
00089                 sprintf(bbuf, "ships %s", p);
00090         } else if (type == EF_LAND) {
00091             if (*p == '*')
00092                 sprintf(bbuf, "all land units");
00093             else if (*p == '~')
00094                 sprintf(bbuf, "all unassigned land units");
00095             else if (issector(p))
00096                 sprintf(bbuf, "all units in %s", p);
00097             else if (isalpha(*p))
00098                 sprintf(bbuf, "army %c", *p);
00099             else
00100                 sprintf(bbuf, "units %s", p);
00101         } else {
00102             if (*p == '*')
00103                 sprintf(bbuf, "all planes");
00104             else if (*p == '~')
00105                 sprintf(bbuf, "all unassigned planes");
00106             else if (issector(p))
00107                 sprintf(bbuf, "all planes in %s", p);
00108             else if (isalpha(*p))
00109                 sprintf(bbuf, "wing %c", *p);
00110             else
00111                 sprintf(bbuf, "planes %s", p);
00112         }
00113         sprintf(y_or_n, "Really scuttle %s? ", bbuf);
00114         if (!confirm(y_or_n))
00115             return RET_FAIL;
00116     }
00117     while (nxtitem(&ni, &item)) {
00118         if (!player->owner)
00119             continue;
00120         if (opt_MARKET) {
00121             if (ontradingblock(type, &item.ship)) {
00122                 pr("You cannot scuttle an item on the trading block!\n");
00123                 continue;
00124             }
00125         }
00126 
00127         if (type == EF_SHIP) {
00128             mp = &mchr[(int)item.ship.shp_type];
00129             if (opt_TRADESHIPS) {
00130                 if (mp->m_flags & M_TRADE)
00131                     if (!scuttle_tradeship(&item.ship, 1))
00132                         continue;
00133             }
00134             pr("%s", prship(&item.ship));
00135             scuttle_ship(&item.ship);
00136         } else if (type == EF_LAND) {
00137             if (item.land.lnd_ship >= 0) {
00138                 pr("%s is on a ship, and cannot be scuttled!\n",
00139                    prland(&item.land));
00140                 continue;
00141             }
00142             pr("%s", prland(&item.land));
00143             scuttle_land(&item.land);
00144         } else {
00145             pr("%s", prplane(&item.plane));
00146             if (item.plane.pln_ship >= 0) {
00147                 struct shpstr ship;
00148 
00149                 getship(item.plane.pln_ship, &ship);
00150                 take_plane_off_ship(&item.plane, &ship);
00151             }
00152             item.plane.pln_effic = 0;
00153             putplane(item.plane.pln_uid, &item.plane);
00154         }
00155         pr(" scuttled in %s\n",
00156            xyas(item.ship.shp_x, item.ship.shp_y, player->cnum));
00157     }
00158 
00159     return RET_OK;
00160 }
00161 
00162 int
00163 scuttle_tradeship(struct shpstr *sp, int interactive)
00164 {
00165     float cash = 0;
00166     float ally_cash = 0;
00167     int dist;
00168     struct sctstr sect;
00169     struct mchrstr *mp;
00170     struct natstr *np;
00171     char buf[512];
00172     struct natstr *natp;
00173 
00174     mp = &mchr[(int)sp->shp_type];
00175     getsect(sp->shp_x, sp->shp_y, &sect);
00176     if (sect.sct_own && sect.sct_type == SCT_HARBR) {
00177         dist = mapdist(sp->shp_x, sp->shp_y,
00178                        sp->shp_orig_x, sp->shp_orig_y);
00179         /* Don't disclose distance to to pirates */
00180         if (sp->shp_own == sp->shp_orig_own) {
00181             if (interactive)
00182                 pr("%s has gone %d sects\n", prship(sp), dist);
00183             else
00184                 wu(0, sp->shp_own, "%s has gone %d sects\n",
00185                    prship(sp), dist);
00186         }
00187         if (dist < trade_1_dist)
00188             cash = 0;
00189         else if (dist < trade_2_dist)
00190             cash = 1.0 + trade_1 * dist;
00191         else if (dist < trade_3_dist)
00192             cash = 1.0 + trade_2 * dist;
00193         else
00194             cash = 1.0 + trade_3 * dist;
00195         cash *= mp->m_cost;
00196         cash *= sp->shp_effic / 100.0;
00197 
00198         if (sect.sct_own != sp->shp_own) {
00199             ally_cash = cash * trade_ally_cut;
00200             cash *= (1.0 + trade_ally_bonus);
00201         }
00202     }
00203 
00204     if (!interactive && cash) {
00205         natp = getnatp(sp->shp_own);
00206         natp->nat_money += cash;
00207         putnat(natp);
00208         wu(0, sp->shp_own, "You just made $%d.\n", (int)cash);
00209     } else if (!cash && !interactive) {
00210         wu(0, sp->shp_own, "Unfortunately, you make $0 on this trade.\n");
00211     } else if (cash && interactive) {
00212         player->dolcost -= cash;
00213     } else if (interactive && sp->shp_own == sp->shp_orig_own) {
00214         pr("You won't get any money if you scuttle in %s!",
00215            xyas(sp->shp_x, sp->shp_y, player->cnum));
00216         sprintf(buf, "Are you sure you want to scuttle %s? ", prship(sp));
00217         return confirm(buf);
00218     }
00219 
00220     if (ally_cash) {
00221         np = getnatp(sect.sct_own);
00222         np->nat_money += ally_cash;
00223         putnat(np);
00224         wu(0, sect.sct_own,
00225            "Trade with %s nets you $%d at %s\n",
00226            cname(sp->shp_own),
00227            (int)ally_cash, xyas(sect.sct_x, sect.sct_y, sect.sct_own));
00228         if (sp->shp_own != sp->shp_orig_own)
00229             nreport(sp->shp_own, N_PIRATE_TRADE, sp->shp_orig_own, 1);
00230         else
00231             nreport(sp->shp_own, N_TRADE, sect.sct_own, 1);
00232     } else if (sp->shp_own != sp->shp_orig_own)
00233         nreport(sp->shp_own, N_PIRATE_KEEP, sp->shp_orig_own, 1);
00234 
00235     return 1;
00236 }
00237 
00238 void
00239 scuttle_ship(struct shpstr *sp)
00240 {
00241     struct nstr_item ni;
00242     struct sctstr sect;
00243     struct plnstr plane;
00244     struct lndstr land;
00245 
00246     getsect(sp->shp_x, sp->shp_y, &sect);
00247     snxtitem_all(&ni, EF_PLANE);
00248     while (nxtitem(&ni, &plane)) {
00249         if (plane.pln_own == 0)
00250             continue;
00251         if (plane.pln_ship == sp->shp_uid) {
00252             plane.pln_ship = -1;
00253             if (sect.sct_own != sp->shp_own) {
00254                 wu(0, plane.pln_own, "Plane %d scuttled in %s\n",
00255                    plane.pln_uid,
00256                    xyas(plane.pln_x, plane.pln_y, plane.pln_own));
00257                 plane.pln_effic = 0;
00258             } else {
00259                 wu(0, plane.pln_own,
00260                    "Plane %d transferred off ship %d to %s\n",
00261                    plane.pln_uid, sp->shp_uid,
00262                    xyas(plane.pln_x, plane.pln_y, plane.pln_own));
00263             }
00264             putplane(plane.pln_uid, &plane);
00265         }
00266     }
00267     snxtitem_all(&ni, EF_LAND);
00268     while (nxtitem(&ni, &land)) {
00269         if (land.lnd_own == 0)
00270             continue;
00271         if (land.lnd_ship == sp->shp_uid) {
00272             land.lnd_ship = -1;
00273             if (sect.sct_own == sp->shp_own) {
00274                 wu(0, land.lnd_own,
00275                    "Land unit %d transferred off ship %d to %s\n",
00276                    land.lnd_uid, sp->shp_uid,
00277                    xyas(land.lnd_x, land.lnd_y, land.lnd_own));
00278                 putland(land.lnd_uid, &land);
00279             } else
00280                 scuttle_land(&land);
00281         }
00282     }
00283     sp->shp_effic = 0;
00284     putship(sp->shp_uid, sp);
00285 }
00286 
00287 static void
00288 scuttle_land(struct lndstr *lp)
00289 {
00290     struct nstr_item ni;
00291     struct sctstr sect;
00292     struct plnstr plane;
00293     struct lndstr land;
00294 
00295     getsect(lp->lnd_x, lp->lnd_y, &sect);
00296     snxtitem_all(&ni, EF_PLANE);
00297     while (nxtitem(&ni, &plane)) {
00298         if (plane.pln_own == 0)
00299             continue;
00300         if (plane.pln_land == lp->lnd_uid) {
00301             plane.pln_land = -1;
00302             if (sect.sct_own != lp->lnd_own) {
00303                 wu(0, plane.pln_own, "Plane %d scuttled in %s\n",
00304                    plane.pln_uid,
00305                    xyas(plane.pln_x, plane.pln_y, plane.pln_own));
00306                 plane.pln_effic = 0;
00307             } else {
00308                 wu(0, plane.pln_own,
00309                    "Plane %d transferred off unit %d to %s\n",
00310                    plane.pln_uid, lp->lnd_uid,
00311                    xyas(plane.pln_x, plane.pln_y, plane.pln_own));
00312             }
00313             putplane(plane.pln_uid, &plane);
00314         }
00315     }
00316     snxtitem_all(&ni, EF_LAND);
00317     while (nxtitem(&ni, &land)) {
00318         if (land.lnd_own == 0)
00319             continue;
00320         if (land.lnd_land == lp->lnd_uid) {
00321             land.lnd_land = -1;
00322             if (sect.sct_own == lp->lnd_own) {
00323                 wu(0, land.lnd_own,
00324                    "Land unit %d transferred off unit %d to %s\n",
00325                    land.lnd_uid, lp->lnd_uid,
00326                    xyas(land.lnd_x, land.lnd_y, land.lnd_own));
00327                 putland(land.lnd_uid, &land);
00328             } else
00329                 scuttle_land(&land);
00330         }
00331     }
00332     lp->lnd_effic = 0;
00333     putland(lp->lnd_uid, lp);
00334 }

Generated on Fri Mar 28 11:01:13 2008 for empserver by  doxygen 1.5.2