+++ /dev/null
-/*
- * Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2011, Dave Pare, Jeff Bailey, Thomas Ruschak,
- * Ken Stevens, Steve McClure, Markus Armbruster
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * ---
- *
- * See files README, COPYING and CREDITS in the root of the source
- * tree for related information and legal notices. It is expected
- * that future projects/authors will amend these files as needed.
- *
- * ---
- *
- * cede.c: Give a sector to a neighbor
- *
- * Known contributors to this file:
- * Dave Pare
- * Thomas Ruschak
- */
-
-#include <config.h>
-
-#include "commands.h"
-#include "land.h"
-#include "lost.h"
-#include "nuke.h"
-#include "path.h"
-#include "plane.h"
-#include "ship.h"
-
-static int has_units_with_mob(coord, coord, natid);
-static void cede_hdr(void);
-static int cede_sect(struct nstr_sect *, natid);
-static int cede_ship(struct nstr_item *, natid);
-static void grab_sect(struct sctstr *, natid);
-static void grab_ship(struct shpstr *, natid);
-
-int
-cede(void)
-{
- static int sct_or_shp[] = { EF_SECTOR, EF_SHIP, EF_BAD };
- natid to;
- int n;
- int is_sector = 0, is_ship = 0;
- char *p;
- struct nstr_sect ns;
- struct nstr_item ni;
- struct natstr *natp;
- char buf[1024];
-
- p = getstarg(player->argp[1], "Cede what? ", buf);
- if (!p || !*p)
- return RET_SYN;
- if (snxtsct(&ns, p))
- is_sector = 1;
- if (snxtitem(&ni, EF_SHIP, p, NULL))
- is_ship = 1;
- if (!is_sector && !is_ship)
- return RET_SYN;
- if ((n = natarg(player->argp[2], "to which country? ")) < 0)
- return RET_SYN;
- if (is_sector && is_ship) {
- int type;
-
- p = getstarg(player->argp[3], "Cede sectors or ships (se, sh)? ",
- buf);
- if (!p)
- return RET_FAIL;
- if (strlen(p) > 4)
- p[2] = 0;
- type = ef_byname_from(p, sct_or_shp);
- if (type < 0) {
- pr("Please type 'se' or 'sh'!\n");
- return RET_FAIL;
- }
- }
-
-
- if (n == player->cnum) {
- pr("Giving something to yourself?\n");
- return RET_FAIL;
- }
- natp = getnatp(n);
- if (natp->nat_stat != STAT_ACTIVE) {
- pr("You can only give to normal countries...\n");
- return RET_FAIL;
- }
- if (relations_with(n, player->cnum) < FRIENDLY) {
- pr("You can only cede to a country that is friendly towards you...\n");
- return RET_FAIL;
- }
- to = n;
-
- if (is_sector)
- return cede_sect(&ns, to);
- else
- return cede_ship(&ni, to);
-}
-
-static int
-cede_sect(struct nstr_sect *ns, natid to)
-{
- struct sctstr sect, osect;
- int nsect;
- int n, bad;
- int off_x, off_y;
- struct nstr_item ni;
- struct shpstr ship;
-
- prdate();
- nsect = 0;
- while (nxtsct(ns, §)) {
- if (!player->owner)
- continue;
- if (sect.sct_mobil == 0) {
- pr("%s has no mobility and cannot be ceded\n",
- xyas(sect.sct_x, sect.sct_y, player->cnum));
- continue;
- }
-
- bad = 1;
- for (n = 1; n <= 6; n++) { /* Directions */
- off_x = sect.sct_x + diroff[n][0];
- off_y = sect.sct_y + diroff[n][1];
-
- if (!getsect(off_x, off_y, &osect))
- continue;
- if ((osect.sct_own == to) && (osect.sct_mobil))
- bad = 0;
- if ((osect.sct_own == to) &&
- has_units_with_mob(osect.sct_x, osect.sct_y, to))
- bad = 0;
- }
- snxtitem_all(&ni, EF_SHIP);
- while (nxtitem(&ni, &ship)) {
- if ((ship.shp_own == to) &&
- ((ship.shp_x == sect.sct_x) && (ship.shp_y == sect.sct_y)))
- bad = 0;
- }
- if (bad) {
- pr("%s has no sector with mobility adjacent to or ship in %s!\n",
- cname(to), xyas(sect.sct_x, sect.sct_y, player->cnum));
- continue;
- }
-
- if (nsect++ == 0)
- cede_hdr();
-
- grab_sect(§, to);
- putsect(§);
- pr(" %s %d%% ceded\n", xyas(sect.sct_x, sect.sct_y, player->cnum),
- (int)sect.sct_effic);
- wu(0, to, "%s ceded to you by %s\n",
- xyas(sect.sct_x, sect.sct_y, to), cname(player->cnum));
- }
- pr("%d sector%s\n", nsect, splur(nsect));
- return RET_OK;
-}
-
-static int
-has_units_with_mob(coord x, coord y, natid cn)
-{
- struct nstr_item ni;
- struct lndstr land;
-
- snxtitem_xy(&ni, EF_LAND, x, y);
- while (nxtitem(&ni, &land)) {
- if (land.lnd_own != cn)
- continue;
- if (land.lnd_mobil > 0)
- return 1;
- }
-
- return 0;
-}
-
-static void
-cede_hdr(void)
-{
- if (player->god)
- pr("own ");
- pr(" sect eff\n");
-}
-
-
-
-static void
-grab_sect(struct sctstr *sp, natid to)
-{
- struct plnstr *pp;
- struct lndstr *lp;
- struct nukstr *np;
- struct nstr_item ni;
- struct plnstr p;
- struct lndstr l;
- struct nukstr nuk;
-
- /* Wipe all the distribution info */
- memset(sp->sct_dist, 0, sizeof(sp->sct_dist));
- memset(sp->sct_del, 0, sizeof(sp->sct_del));
- sp->sct_dist_x = sp->sct_x;
- sp->sct_dist_y = sp->sct_y;
-
- pp = &p;
- snxtitem_xy(&ni, EF_PLANE, sp->sct_x, sp->sct_y);
- while (nxtitem(&ni, pp)) {
- if (pp->pln_own == 0)
- continue;
- if (pp->pln_ship >= 0)
- continue;
- if (pp->pln_own != player->cnum)
- continue;
- if (pp->pln_flags & PLN_LAUNCHED)
- continue;
-
- wu(0, to, "\t%s ceded to you by %s\n",
- prplane(pp), cname(player->cnum));
- pp->pln_own = to;
- pp->pln_mobil = 0;
- pp->pln_mission = 0;
- putplane(pp->pln_uid, pp);
- }
-
- np = &nuk;
- snxtitem_xy(&ni, EF_NUKE, sp->sct_x, sp->sct_y);
- while (nxtitem(&ni, np)) {
- if (np->nuk_own == 0)
- continue;
-
- wu(0, to, "\t%s ceded to you by %s\n",
- prnuke(np), cname(player->cnum));
- np->nuk_own = to;
- putnuke(ni.cur, np);
- }
-
- lp = &l;
- snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
- while (nxtitem(&ni, lp)) {
- if (lp->lnd_own == 0)
- continue;
- if (lp->lnd_ship == 0)
- continue;
- if (lp->lnd_own != player->cnum)
- continue;
-
- wu(0, to, "\t%s ceded to you by %s\n",
- prland(lp), cname(player->cnum));
- lp->lnd_own = to;
- lp->lnd_mobil = 0;
- lp->lnd_mission = 0;
- putland(ni.cur, lp);
- }
-
- sp->sct_avail = 0;
-
- if (sp->sct_oldown == to) {
- sp->sct_che = 0; /* FIXME where do these guys go? */
- sp->sct_che_target = 0;
- sp->sct_loyal = 0;
- }
-
- if (sp->sct_oldown == to)
- sp->sct_loyal = 0;
- else /* people don't like being given away */
- sp->sct_loyal = 50;
-
- sp->sct_dist_x = sp->sct_x;
- sp->sct_dist_y = sp->sct_y;
- if (sp->sct_oldown == sp->sct_own)
- sp->sct_oldown = to;
- sp->sct_own = to;
- sp->sct_mobil = 0;
-}
-
-static int
-cede_ship(struct nstr_item *ni, natid to)
-{
- struct shpstr ship;
- struct shpstr tship;
- struct sctstr sect;
- struct nstr_item tni;
- int nships = 0;
- int bad = 0;
-
- while (nxtitem(ni, &ship)) {
-
- if (!player->owner || ship.shp_own == 0)
- continue;
-
- bad = 1;
- snxtitem_xy(&tni, EF_SHIP, ship.shp_x, ship.shp_y);
- while (nxtitem(&tni, &tship) && bad)
- if (tship.shp_own == to)
- bad = 0;
-
- getsect(ship.shp_x, ship.shp_y, §);
- if (bad && (sect.sct_own != to)) {
- pr("%s isn't in a %s sector, and is not with a %s ship!\n",
- prship(&ship), cname(to), cname(to));
- continue;
- }
- grab_ship(&ship, to);
- putship(ship.shp_uid, &ship);
- nships++;
- wu(0, to, "%s ceded to you by %s\n",
- prship(&ship), cname(player->cnum));
- pr("%s ceded to %s\n", prship(&ship), cname(to));
- }
- pr(" %d ship%s\n", nships, splur(nships));
-
- return RET_OK;
-}
-
-static void
-grab_ship(struct shpstr *sp, natid to)
-{
- struct plnstr *pp;
- struct lndstr *lp;
- struct nstr_item ni;
- struct plnstr p;
- struct lndstr l;
-
- pp = &p;
- snxtitem_xy(&ni, EF_PLANE, sp->shp_x, sp->shp_y);
- while (nxtitem(&ni, pp)) {
- if (pp->pln_own == 0)
- continue;
- if (pp->pln_flags & PLN_LAUNCHED)
- continue;
- if (pp->pln_ship != sp->shp_uid)
- continue;
- if (pp->pln_own != player->cnum)
- continue;
-
- wu(0, to, "\t%s ceded to you by %s\n",
- prplane(pp), cname(player->cnum));
- pp->pln_own = to;
- pp->pln_mobil = 0;
- pp->pln_mission = 0;
- putplane(pp->pln_uid, pp);
- }
-
- lp = &l;
- snxtitem_xy(&ni, EF_LAND, sp->shp_x, sp->shp_y);
- while (nxtitem(&ni, lp)) {
- if (lp->lnd_own == 0)
- continue;
- if (lp->lnd_ship != sp->shp_uid)
- continue;
- if (lp->lnd_own != player->cnum)
- continue;
-
- wu(0, to, "\t%s ceded to you by %s\n",
- prland(lp), cname(player->cnum));
- lp->lnd_own = to;
- lp->lnd_mobil = 0;
- lp->lnd_mission = 0;
- putland(ni.cur, lp);
- }
-
- sp->shp_own = to;
-}