Пример #1
1
/*
 * Dump items of type @type selected by @arg to @xd.
 * Return RET_OK on success, RET_SYN on error.
 */
static int
xditem(struct xdstr *xd, int type, char *arg)
{
    struct castr *ca;
    struct nstr_item ni;
    int n;
    unsigned char buf[EF_WITH_CADEF_MAX_ENTRY_SIZE];

    ca = ef_cadef(type);
    if (!ca)
	return RET_SYN;

    if (!snxtitem(&ni, type, arg, NULL))
	return RET_SYN;

    xdhdr(xd, ef_nameof(type), 0);

    n = 0;
    while (nxtitem(&ni, buf)) {
	if (!xdvisible(type, buf))
	    continue;
	++n;
	xdflds(xd, ca, buf);
	xd->pr("\n");
    }

    xdftr(xd, n);

    return RET_OK;
}
Пример #2
0
/*
 * Get planes and escorts argument.
 * Read planes into *NI_BOMB, and (optional) escorts into *NI_ESC.
 * If INPUT_BOMB is not empty, use it, else prompt for more input.
 * Same for INPUT_ESC.
 * If we got a plane argument, initialize *NI_BOMB and *NI_ESC, and
 * return 0.
 * Else return -1 (*NI_BOMB and *NI_ESC may be modified).
 */
int
get_planes(struct nstr_item *ni_bomb, struct nstr_item *ni_esc,
	   char *input_bomb, char *input_esc)
{
    if (!snxtitem(ni_bomb, EF_PLANE, input_bomb, NULL))
	return -1;
    if (!snxtitem(ni_esc, EF_PLANE, input_esc, "escort(s)? ")) {
	if (player->aborted)
	    return -1;
	pr("No escorts...\n");
    }
    return 0;
}
Пример #3
0
int
wing(void)
{

    struct plnstr plane;
    int count;
    char *cp;
    char c;
    struct nstr_item nstr;
    char buf[1024];

    if (!(cp = getstarg(player->argp[1], "wing? ", buf)))
	return RET_SYN;
    c = *cp;
    if (!isalpha(c) && c != '~') {
	pr("Specify wing, (1 alpha char or '~')\n");
	return RET_SYN;
    }
    if (c == '~')
	c = 0;
    if (!snxtitem(&nstr, EF_PLANE, player->argp[2], NULL))
	return RET_SYN;
    count = 0;
    while (nxtitem(&nstr, &plane)) {
	if (plane.pln_own != player->cnum)
	    continue;
	if (plane.pln_wing == c)
	    continue;
	plane.pln_wing = c;
	putplane(plane.pln_uid, &plane);
	count++;
    }
    pr("%d plane%s added to wing `%1.1s'\n", count, splur(count), &c);
    return RET_OK;
}
Пример #4
0
int
reje(void)
{
    static char *what[] = { "teles", "annos", "loans" };
    char *p;
    enum rej_comm rej;
    int do_undo;
    struct natstr nat;
    struct nstr_item ni;
    char buf[1024];

    if (!(p = getstarg(player->argp[1], "reject or accept? ", buf)))
	return RET_SYN;
    switch (*p) {
    case 'r':
	do_undo = 1;
	break;
    case 'a':
	do_undo = 0;
	break;
    default:
	pr("That's not one of the choices!\n");
	return RET_SYN;
    }
    p = getstarg(player->argp[2],
		 "mail, loans, or announcements? ", buf);
    if (!p)
	return RET_SYN;
    switch (*p) {
    case 'a':
	rej = REJ_ANNO;
	break;
    case 'l':
	rej = REJ_LOAN;
	break;
    case 'm':
	rej = REJ_TELE;
	break;
    default:
	pr("That's not one of the choices!\n");
	return RET_SYN;
    }
    if (!snxtitem(&ni, EF_NATION, player->argp[3], NULL))
	return RET_SYN;
    while (nxtitem(&ni, &nat)) {
	if (nat.nat_stat == STAT_GOD) {
	    pr("You may not reject/accept stuff from %s\n"
	       "because they are a deity.\n",
	       nat.nat_cnam);
	    continue;
	}
	if (nat.nat_stat == STAT_UNUSED)
	    continue;
	pr("%s %s from %s\n",
	   (do_undo == 1 ? "Rejecting" : "Accepting"),
	   what[rej], nat.nat_cnam);
	setrej(player->cnum, (natid)ni.cur, do_undo, rej);
    }
    return RET_OK;
}
Пример #5
0
int
supp(void)
{
    int nunits;
    struct nstr_item ni;
    struct lndstr land;

    if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL))
	return RET_SYN;

    nunits = 0;
    while (nxtitem(&ni, &land)) {
	if (!player->owner || land.lnd_own == 0)
	    continue;
	nunits++;
	if (lnd_supply_all(&land))
	    pr("%s has supplies\n", prland(&land));
	else
	    pr("%s is out of supply\n", prland(&land));
    }
    if (nunits == 0) {
	if (player->argp[1])
	    pr("%s: No unit(s)\n", player->argp[1]);
	else
	    pr("%s: No unit(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d unit%s\n", nunits, splur(nunits));
    return RET_OK;
}
Пример #6
0
int
do_look(int type)
{
    int i;
    struct nstr_item ni;
    union empobj_storage unit;
    struct sctstr sect;
    int x, y;
    unsigned char *bitmap;
    int changed = 0;

    if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP))
	type = EF_SHIP;

    if (!snxtitem(&ni, type, player->argp[1], NULL))
	return RET_SYN;
    bitmap = calloc((WORLD_SZ() + 7) / 8, 1);
    if (!bitmap) {
	logerror("malloc failed in do_look\n");
	pr("Memory error.  Tell the deity.\n");
	return RET_FAIL;
    }
    while (nxtitem(&ni, &unit)) {
	if (!player->owner)
	    continue;
	if (type == EF_LAND) {
	    if (unit.land.lnd_ship >= 0)
		continue;
	    if (unit.land.lnd_land >= 0)
		continue;
	    /* Spies don't need military to do a "llook".  Other
	       units do */
	    if ((unit.land.lnd_item[I_MILIT] <= 0) &&
		!(lchr[(int)unit.land.lnd_type].l_flags & L_SPY))
		continue;
	    look_land(&unit.land);
	} else
	    look_ship(&unit.ship);
	for (i = 0; i <= 6; i++) {
	    x = diroff[i][0] + unit.gen.x;
	    y = diroff[i][1] + unit.gen.y;
	    if (emp_getbit(x, y, bitmap))
		continue;
	    emp_setbit(x, y, bitmap);
	    getsect(x, y, &sect);
	    if (sect.sct_type == SCT_WATER)
		continue;
	    look_at_sect(&sect, 10);
	    changed += map_set(player->cnum, x, y,
			       dchr[sect.sct_type].d_mnem, 0);
	    if (opt_HIDDEN) {
		setcont(player->cnum, sect.sct_own, FOUND_LOOK);
	    }
	}
    }
    if (changed)
	writemap(player->cnum);
    free(bitmap);
    return RET_OK;
}
Пример #7
0
int
range(void)
{
    struct nstr_item np;
    struct plnstr plane;
    int i, rmax;
    char *p;
    char buf[1024];

    if (!snxtitem(&np, EF_PLANE, player->argp[1], NULL))
	return RET_SYN;
    while (nxtitem(&np, &plane)) {
	if (!player->owner || plane.pln_own == 0)
	    continue;
	p = getstarg(player->argp[2], "New range? ", buf);
	if (!p)
	    return RET_FAIL;
	if (!check_plane_ok(&plane))
	    return RET_SYN;
	if ((i = atoi(p)) < 0)
	    continue;
	rmax = pln_range_max(&plane);
	plane.pln_range = MIN(rmax, i);
	pr("Plane %d range changed to %d\n",
	   plane.pln_uid, plane.pln_range);

	putplane(plane.pln_uid, &plane);
    }

    return RET_OK;
}
Пример #8
0
int
qorde(void)
{
    int nships = 0;
    int i;
    struct nstr_item nb;
    struct shpstr ship;

    if (!snxtitem(&nb, EF_SHIP, player->argp[1], NULL))
	return RET_SYN;
    while (nxtitem(&nb, (&ship))) {
	if (!player->owner || ship.shp_own == 0)
	    continue;
	if (!(ship.shp_autonav & AN_AUTONAV)
	    && (!opt_SAIL || !ship.shp_path[0]))
	    continue;

	if (!nships) {		/* 1st ship, print banner */
	    if (player->god)
		pr("own ");
	    pr("shp#     ship type    ");
	    pr("[Starting]       (Ending)    \n");
	}
	nships++;
	if (player->god)
	    pr("%3d ", ship.shp_own);
	pr("%4d", nb.cur);
	pr(" %-16.16s", mchr[(int)ship.shp_type].m_name);

	if (ship.shp_autonav & AN_AUTONAV) {
	    pr(" [");
	    for (i = 0; i < TMAX; i++)
		prhold(i, ship.shp_tend[i], ship.shp_lend[i]);
	    pr("] , (");
	    for (i = 0; i < TMAX; i++)
		prhold(i, ship.shp_tstart[i], ship.shp_lstart[i]);
	    pr(")");
	    if (ship.shp_autonav & AN_SCUTTLE)
		pr(" scuttling");
	    pr("\n");
	} else
	    pr(" has a sail path\n");

	if (ship.shp_name[0] != 0) {
	    if (player->god)
		pr("    ");
	    pr("       %s\n", ship.shp_name);
	}
    }
    if (!nships) {
	if (player->argp[1])
	    pr("%s: No ship(s)\n", player->argp[1]);
	else
	    pr("%s: No ship(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d ship%s\n", nships, splur(nships));
    return RET_OK;
}
Пример #9
0
int
nuke(void)
{
    int nnukes, noff;
    struct nstr_item nstr;
    struct nukstr nuk;
    struct plnstr plane;

    if (!snxtitem(&nstr, EF_NUKE, player->argp[1], NULL))
	return RET_SYN;
    nnukes = noff = 0;
    while (nxtitem(&nstr, &nuk)) {
	if (!player->owner || nuk.nuk_own == 0)
	    continue;
	if (nnukes++ == 0) {
	    if (player->god)
		pr("own ");
	    pr("   # nuke type              x,y    s   eff tech carry burst\n");
	}
	if (nuk.nuk_off)
	    noff++;
	if (player->god)
	    pr("%-3d ", nuk.nuk_own);
	pr("%4d %-19.19s ", nstr.cur, nchr[(int)nuk.nuk_type].n_name);
	prxy("%4d,%-4d", nuk.nuk_x, nuk.nuk_y);
	pr(" %1.1s %c%3d%% %4d",
	   &nuk.nuk_stockpile, nuk.nuk_off ? '!' : ' ', nuk.nuk_effic,
	   nuk.nuk_tech);
	if (nuk.nuk_plane >= 0) {
	    getplane(nuk.nuk_plane, &plane);
	    pr("%5dP %s",
	       nuk.nuk_plane,
	       plane.pln_flags & PLN_AIRBURST ? "  air" : "ground");
	}
	pr("\n");
    }

    if (nnukes == 0) {
	if (player->argp[1])
	    pr("%s: No nuke(s)\n", player->argp[1]);
	else
	    pr("%s: No nuke(s)\n", "");
	return RET_FAIL;
    } else {
	pr("%d nuke%s", nnukes, splur(nnukes));
	if (noff)
	    pr(", %d stopped (eff marked with !)", noff);
	pr("\n");
    }

    return RET_OK;
}
Пример #10
0
int
navi(void)
{
    struct nstr_item ni_ship;
    struct emp_qelem ship_list;

    if (!snxtitem(&ni_ship, EF_SHIP, player->argp[1], NULL))
	return RET_SYN;
    shp_sel(&ni_ship, &ship_list);
    if (QEMPTY(&ship_list)) {
	pr("No ships\n");
	return RET_FAIL;
    }
    return unit_move(&ship_list);
}
Пример #11
0
int
march(void)
{
    struct nstr_item ni_land;
    struct emp_qelem land_list;

    if (!snxtitem(&ni_land, EF_LAND, player->argp[1], NULL))
	return RET_SYN;
    lnd_sel(&ni_land, &land_list);
    if (QEMPTY(&land_list)) {
	pr("No lands\n");
	return RET_FAIL;
    }
    return unit_move(&land_list);
}
Пример #12
0
int
coun(void)
{
    struct nstr_item ni;
    struct natstr nat;

    if (!snxtitem(&ni, EF_NATION, player->argp[1], NULL))
	return RET_SYN;
    prdate();
    pr("  #   last access                         %sstatus     country name\n",
       player->god ? "BTU  " : "");
    while (nxtitem(&ni, &nat)) {
	if (nat.nat_stat == STAT_UNUSED)
	    continue;
	coun_list(&nat);
    }
    return RET_OK;
}
Пример #13
0
int
ndump(void)
{
    struct nstr_item nstr;
    struct nukstr nuk;
    time_t now;
    int nnukes;

    if (!snxtitem(&nstr, EF_NUKE, player->argp[1], NULL))
	return RET_SYN;
    prdate();
    if (player->god)
	pr("   ");
    time(&now);
    pr("DUMP NUKES %ld\n", (long)now);
    if (player->god)
	pr("own ");
    pr("id x y num type\n");
    nnukes = 0;
    while (nxtitem(&nstr, &nuk)) {
	if (!player->god && !player->owner)
	    continue;
	if (nuk.nuk_own == 0)
	    continue;
	nnukes++;
	if (player->god)
	    pr("%d ", nuk.nuk_own);
	pr("%d ", nuk.nuk_uid);
	prxy("%d %d", nuk.nuk_x, nuk.nuk_y);
	pr(" %d", 1);
	pr(" %.5s", nchr[(int)nuk.nuk_type].n_name);
	pr("\n");
    }
    if (nnukes == 0) {
	if (player->argp[1])
	    pr("%s: No nuke(s)\n", player->argp[1]);
	else
	    pr("%s: No nuke(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d nuke%s\n", nnukes, splur(nnukes));

    return RET_OK;
}
Пример #14
0
int
lsta(void)
{
    int nunits;
    struct nstr_item ni;
    struct lndstr land;
    struct lchrstr *lcp;

    if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL))
	return RET_SYN;

    nunits = 0;
    while (nxtitem(&ni, &land)) {
	if (!player->owner || land.lnd_own == 0)
	    continue;
	lcp = lchr + land.lnd_type;
	if (nunits++ == 0) {
	    pr("     %16.16s                                 s  v  s  r  r  a  f  a  a\n", "");
	    pr("     %16.16s                                 p  i  p  a  n  c  i  m  a\n", "");
	    pr("lnd# %16.16s    x,y    eff tech att def vul  d  s  y  d  g  c  r  m  f\n", "unit-type");
	}
	pr("%4d %-16.16s ", land.lnd_uid, lcp->l_name);
	prxy("%4d,%-4d", land.lnd_x, land.lnd_y);
	pr(" %3d%% %3d %1.1f %1.1f %3d ",
	   land.lnd_effic, land.lnd_tech, lnd_att(&land), lnd_def(&land),
	   lnd_vul(&land));
	pr("%2d %2d %2d %2d ",
	   lnd_spd(&land), lnd_vis(&land), lcp->l_spy, lcp->l_rad);
	pr("%2d %2d %2d %2d %2d ",
	   lnd_frg(&land), lnd_acc(&land), lnd_dam(&land),
	   lcp->l_ammo, lnd_aaf(&land));
	pr("\n");
    }
    if (nunits == 0) {
	if (player->argp[1])
	    pr("%s: No unit(s)\n", player->argp[1]);
	else
	    pr("%s: No unit(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d unit%s\n", nunits, splur(nunits));
    return RET_OK;
}
Пример #15
0
static void
starv_units(char *range)
{
    struct nstr_item ni;
    struct lndstr land;
    int nunit = 0;
    int s;

    if (!snxtitem(&ni, EF_LAND, range, NULL))
        return;

    while (nxtitem(&ni, &land)) {
        if (!player->owner || !land.lnd_own)
            continue;

        s = famine_victims(land.lnd_item, etu_per_update);
        if (s == 0)
            continue;
        if (nunit++ == 0)
            unit_hdr();
        if (player->god)
            pr("%3d ", land.lnd_own);
        pr("%5d ", land.lnd_uid);
        pr("%-16.16s ", lchr[(int)land.lnd_type].l_name);
        starv_people(land.lnd_item, s);
    }
    if (nunit == 0) {
        if (range)
            pr("%s: No unit(s)\n", range);
        else
            pr("%s: No unit(s)\n", "");
        return;
    } else
        pr("%d unit%s\n", nunit, splur(nunit));
    return;
}
Пример #16
0
/*
 * format: fina
 */
int
fina(void)
{
    struct lonstr loan;
    struct nstr_item ni;
    time_t now;

    if (!opt_LOANS) {
	pr("Loans are not enabled.\n");
	return RET_FAIL;
    }
    if (!snxtitem(&ni, EF_LOAN, "*", NULL))
	return RET_SYN;
    (void)time(&now);
    pr("\n");
    pr("             -= Empire Financial Status Report =-\n");
    pr("                  ");
    prdate();
    pr("Loan       From            To        Rate   Dur     Paid      Total\n");
    while (nxtitem(&ni, &loan)) {
	if (loan.l_status != LS_SIGNED)
	    continue;
	pr(" %-2d  (%3d) %-8.8s  (%3d) %-8.8s  ", ni.cur,
	   loan.l_loner, cname(loan.l_loner),
	   loan.l_lonee, cname(loan.l_lonee));
	pr("%3d%%   %3d    %5d    %7.0f",
	   loan.l_irate, loan.l_ldur, loan.l_amtpaid,
	   ceil(loan_owed(&loan, now)));
	if (now > loan.l_duedate)
	    pr(" (in arrears)\n");
	else
	    pr("\n");
    }
    pr("\n");
    return RET_OK;
}
Пример #17
0
static void
starv_ships(char *range)
{
    struct nstr_item ni;
    struct shpstr ship;
    int nship = 0;
    int s;

    if (!snxtitem(&ni, EF_SHIP, range, NULL))
        return;

    while (nxtitem(&ni, &ship)) {
        if (!player->owner || !ship.shp_own)
            continue;

        s = famine_victims(ship.shp_item, etu_per_update);
        if (s == 0)
            continue;
        if (nship++ == 0)
            ship_hdr();
        if (player->god)
            pr("%3d ", ship.shp_own);
        pr("%5d ", ship.shp_uid);
        pr("%-16.16s ", mchr[(int)ship.shp_type].m_name);
        starv_people(ship.shp_item, s);
    }
    if (nship == 0) {
        if (range)
            pr("%s: No ship(s)\n", range);
        else
            pr("%s: No ship(s)\n", "");
        return;
    } else
        pr("%d ship%s\n", nship, splur(nship));
    return;
}
Пример #18
0
static int
load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
	       int load_unload, int *nunitsp)
{
    struct nstr_item ni;
    struct lndstr land;
    int loaded = 0;
    char *p;
    char prompt[512];
    char buf[1024];

    if (load_unload == LOAD
	&& lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) {
	if (noisy) {
	    if (lchr[lp->lnd_type].l_nland)
		pr("%s doesn't have room for any more land units!\n",
		   prland(lp));
	    else
		pr("%s cannot carry land units!\n", prland(lp));
	}
	return 0;
    }
    sprintf(prompt, "Land unit(s) to %s %s? ",
	    load_unload == LOAD ? "load onto" : "unload from", prland(lp));
    p = getstarg(player->argp[3], prompt, buf);
    if (!p)
	return RET_SYN;
    if (!snxtitem(&ni, EF_LAND, p, NULL))
	return RET_SYN;

    if (!still_ok_land(sectp, lp))
	return RET_SYN;

    if (noisy && p && *p)
	noisy = isdigit(*p);

    while (nxtitem(&ni, &land)) {
	if (!player->owner)
	    continue;

	if (load_unload == LOAD) {
	    if (land.lnd_ship > -1) {
		if (noisy)
		    pr("%s is already on ship #%d!\n",
		       prland(&land), land.lnd_ship);
		continue;
	    }
	    if (land.lnd_land > -1) {
		if (noisy)
		    pr("%s is already on land #%d!\n",
		       prland(&land), land.lnd_land);
		continue;
	    }
	    if (lnd_first_on_land(&land) >= 0) {
		if (noisy)
		    pr("%s cannot be loaded since it is carrying units\n",
		       prland(&land));
		continue;
	    }
	    if (land.lnd_uid == lp->lnd_uid) {
		if (noisy)
		    pr("%s can't be loaded onto itself!\n", prland(&land));
		continue;
	    }
	    if (lchr[(int)land.lnd_type].l_flags & (L_HEAVY | L_TRAIN)) {
		if (noisy)
		    pr("%s is too heavy to load.\n", prland(&land));
		continue;
	    }
	}

	/* Unit sanity done */
	/* Find the right ship */
	if (load_unload == UNLOAD) {
	    if (land.lnd_land != lp->lnd_uid)
		continue;
	    if (land.lnd_ship > -1)
		continue;
	} else if (lp->lnd_x != land.lnd_x || lp->lnd_y != land.lnd_y)
	    continue;

	/* Fit unit on ship */
	if (load_unload == LOAD) {
	    if (lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) {
		if (noisy) {
		    if (lchr[lp->lnd_type].l_nland)
			pr("%s doesn't have room for any more land units!\n",
			   prland(lp));
		    else
			pr("%s cannot carry land units!\n", prland(lp));
		}
		break;
	    }
	    sprintf(buf, "loaded on your %s at %s",
		    prland(lp), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
	    gift(lp->lnd_own, player->cnum, &land, buf);
	    land.lnd_land = lp->lnd_uid;
	    land.lnd_harden = 0;
	    putland(land.lnd_uid, &land);
#if 0
	   /* FIXME same issue as in load_land_ship() */
	    if (!lnd_supply_all(&land))
		pr("WARNING: %s is out of supply!\n", prland(&land));
#else
	    if (!lnd_in_supply(&land))
		pr("WARNING: %s is out of supply!\n", prland(&land));
#endif
	} else {
	    sprintf(buf, "unloaded in your %s at %s",
		    dchr[sectp->sct_type].d_name,
		    xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
	    gift(sectp->sct_own, player->cnum, &land, buf);
	    land.lnd_land = -1;
	    putland(land.lnd_uid, &land);
	}
	pr("%s %s %s at %s.\n",
	   prland(&land),
	   (load_unload == UNLOAD) ?
	   "unloaded from" : "loaded onto",
	   prland(lp), xyas(lp->lnd_x, lp->lnd_y, player->cnum));
	loaded = 1;
    }
    *nunitsp += loaded;
    return 0;
}
Пример #19
0
static int
load_plane_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
		int load_unload, int *nunitsp)
{
    struct nstr_item ni;
    struct plnstr pln;
    int loaded = 0;
    char *p;
    char prompt[512];
    char buf[1024];
    struct lchrstr *lcp = lchr + lp->lnd_type;

    if (!lcp->l_nxlight) {
	if (noisy)
	    pr("%s cannot carry extra-light planes.\n", prland(lp));
	return 0;
    }
    if (load_unload == LOAD && lnd_nxlight(lp) >= lcp->l_nxlight) {
	if (noisy)
	    pr("%s doesn't have room for any more extra-light planes\n",
	       prland(lp));
	return 0;
    }
    sprintf(prompt, "Plane(s) to %s %s? ",
	    load_unload == LOAD ? "load onto" : "unload from", prland(lp));
    p = getstarg(player->argp[3], prompt, buf);
    if (!p)
	return RET_SYN;
    if (!snxtitem(&ni, EF_PLANE, p, NULL))
	return RET_SYN;

    if (!still_ok_land(sectp, lp))
	return RET_SYN;

    if (noisy && p && *p)
	noisy = isdigit(*p);

    while (nxtitem(&ni, &pln)) {
	if (!player->owner)
	    continue;

	if (!(plchr[(int)pln.pln_type].pl_flags & P_E)) {
	    if (noisy)
		pr("You can only load xlight planes onto units.\n");
	    continue;
	}

	if (load_unload == LOAD && pln.pln_ship > -1) {
	    if (noisy)
		pr("%s is already on ship #%d!\n",
		   prplane(&pln), pln.pln_ship);
	    continue;
	}
	if (load_unload == LOAD && pln.pln_land > -1) {
	    if (noisy)
		pr("%s is already on unit #%d!\n",
		   prplane(&pln), pln.pln_land);
	    continue;
	}
	if (pln.pln_harden != 0) {
	    if (noisy)
		pr("%s has been hardened and can't be loaded\n",
		   prplane(&pln));
	    continue;
	}

	/* Plane sanity done */
	/* Find the right unit */
	if (load_unload == UNLOAD) {
	    if (pln.pln_land != lp->lnd_uid)
		continue;
	} else if (lp->lnd_x != pln.pln_x || lp->lnd_y != pln.pln_y)
	    continue;

	/* Fit plane on unit */
	if (load_unload == LOAD) {
	    if (!put_plane_on_land(&pln, lp)) {
		if (noisy)
		    pr("Can't put plane %d on this unit!\n", pln.pln_uid);
		continue;
	    }
	    sprintf(buf, "loaded on %s at %s",
		    prland(lp), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
	    gift(lp->lnd_own, player->cnum, &pln, buf);
	    putplane(pln.pln_uid, &pln);
	} else {
	    pln.pln_land = -1;
	    sprintf(buf, "unloaded at your sector at %s",
		    xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
	    gift(sectp->sct_own, player->cnum, &pln, buf);
	    putplane(pln.pln_uid, &pln);
	}
	pr("%s %s %s at %s.\n",
	   prplane(&pln),
	   (load_unload == UNLOAD) ?
	   "unloaded from" : "loaded onto",
	   prland(lp), xyas(lp->lnd_x, lp->lnd_y, player->cnum));
	loaded = 1;
    }
    *nunitsp += loaded;
    return 0;
}
Пример #20
0
int
load(void)
{
    int noisy;
    int load_unload;
    int type;
    struct nstr_item nbst;
    struct ichrstr *ich;
    int nships;
    struct sctstr sect;
    struct shpstr ship;
    int retval;
    char *p;
    char buf[1024];

    p = getstarg(player->argp[1],
		 "What commodity (or 'plane' or 'land')? ", buf);
    if (!p || !*p)
	return RET_SYN;

    if (!strncmp(p, "plane", 5))
	type = EF_PLANE;
    else if (!strncmp(p, "land", 4))
	type = EF_LAND;
    else if (NULL != (ich = item_by_name(p)))
	type = EF_SECTOR;
    else {
	pr("Can't load '%s'\n", p);
	return RET_SYN;
    }

    p = getstarg(player->argp[2], "Ship(s): ", buf);
    if (!p || !*p)
	return RET_SYN;

    noisy = isdigit(*p);

    if (!snxtitem(&nbst, EF_SHIP, p, NULL))
	return RET_SYN;

    load_unload = **player->argp == 'l' ? LOAD : UNLOAD;

    nships = 0;
    while (nxtitem(&nbst, &ship)) {
	if (!ship.shp_own)
	    continue;
	if (!player->owner) {
	    if (load_unload == UNLOAD || !noisy)
		continue;
	    if (relations_with(ship.shp_own, player->cnum) < FRIENDLY)
		continue;
	}

	if (!getsect(ship.shp_x, ship.shp_y, &sect))	/* XXX */
	    continue;
	if (!sect.sct_own)
	    continue;
	if (!player->owner) {
	    if (ship.shp_own != player->cnum)
		continue;
	    if (!sect_has_dock(&sect))
		continue;
	    if (load_unload == LOAD) {
		if (noisy)
		    pr("You don't own %s\n",
		       xyas(sect.sct_x, sect.sct_y, player->cnum));
		continue;
	    }
	}
	if (!sect_has_dock(&sect)) {
	    if (noisy)
		pr("Sector %s is not a harbor or canal.\n",
		   xyas(sect.sct_x, sect.sct_y, player->cnum));
	    continue;
	}
	if (load_unload == UNLOAD
	    && !player->owner
	    && relations_with(sect.sct_own, player->cnum) < FRIENDLY) {
	    if (noisy)
		pr("You can't unload into an unfriendly %s\n",
		   dchr[sect.sct_type].d_name);
	    continue;
	}
	if (sect.sct_effic < 2) {
	    if (noisy)
		pr("The %s at %s is not 2%% efficient yet.\n",
		   dchr[sect.sct_type].d_name,
		   xyas(sect.sct_x, sect.sct_y, player->cnum));
	    continue;
	}

	if (opt_MARKET) {
	    if (ontradingblock(EF_SHIP, &ship)) {
		pr("You cannot load/unload an item on the trading block!\n");
		continue;
	    }
	}

	switch (type) {
	case EF_PLANE:
	    retval = load_plane_ship(&sect, &ship, noisy, load_unload,
				     &nships);
	    if (retval != 0)
		return retval;
	    break;
	case EF_LAND:
	    retval = load_land_ship(&sect, &ship, noisy, load_unload,
				    &nships);
	    if (retval != 0)
		return retval;
	    break;
	case EF_SECTOR:
	    retval = load_comm_ship(&sect, &ship, ich, load_unload,
				    &nships);
	    if (retval != 0)
		return retval;
	}
	/* load/unload plague */
	if (sect.sct_pstage == PLG_INFECT
	    && ship.shp_pstage == PLG_HEALTHY)
	    ship.shp_pstage = PLG_EXPOSED;
	if (ship.shp_pstage == PLG_INFECT
	    && sect.sct_pstage == PLG_HEALTHY)
	    sect.sct_pstage = PLG_EXPOSED;
	putsect(&sect);
	putship(ship.shp_uid, &ship);
    }
    if (!nships)
	pr("No ships affected\n");
    else
	pr("%d ship%s %sloaded\n", nships, splur(nships),
	   load_unload == UNLOAD ? "un" : "");
    return RET_OK;
}
Пример #21
0
static int
load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
	       int load_unload, int *nshipsp)
{
    struct nstr_item ni;
    struct lndstr land;
    int loaded = 0;
    char *p;
    char prompt[512];
    char buf[1024];
    int load_spy = 0;

    if (load_unload == LOAD) {
	if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
	    (mchr[(int)sp->shp_type].m_nland == 0)) {
	    if (shp_nland(sp) >= 2) {
		pr("Non-land unit carrying subs can only carry up to two spy units.\n");
		return 0;
	    }
	    /* Eh, let 'em load a spy only */
	    load_spy = 1;
	}
	if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) {
	    if (noisy) {
		if (mchr[(int)sp->shp_type].m_nland)
		    pr("%s doesn't have room for any more land units!\n",
		       prship(sp));
		else
		    pr("%s cannot carry land units!\n", prship(sp));
	    }
	    return 0;
	}
    }
    sprintf(prompt, "Land unit(s) to %s %s? ",
	    load_unload == LOAD ? "load onto" : "unload from", prship(sp));
    p = getstarg(player->argp[3], prompt, buf);
    if (!p)
	return RET_SYN;
    if (!snxtitem(&ni, EF_LAND, p, NULL))
	return RET_SYN;

    if (!still_ok_ship(sectp, sp))
	return RET_SYN;

    if (noisy && p && *p)
	noisy = isdigit(*p);

    while (nxtitem(&ni, &land)) {
	if (!player->owner)
	    continue;

	if (load_unload == LOAD) {
	    if (land.lnd_ship > -1) {
		if (noisy)
		    pr("%s is already on ship #%d!\n",
		       prland(&land), land.lnd_ship);
		continue;
	    }
	    if (land.lnd_land > -1) {
		if (noisy)
		    pr("%s is already on land #%d!\n",
		       prland(&land), land.lnd_land);
		continue;
	    }
	    if (lnd_first_on_land(&land) >= 0) {
		if (noisy)
		    pr("%s cannot be loaded since it is carrying units\n",
		       prland(&land));
		continue;
	    }
	    if (lchr[(int)land.lnd_type].l_flags & L_HEAVY) {
		if (noisy)
		    pr("%s is too heavy to load.\n", prland(&land));
		continue;
	    }
	    if (load_spy && !(lchr[(int)land.lnd_type].l_flags & L_SPY)) {
		if (noisy)
		    pr("Subs can only carry spy units.\n");
		continue;
	    }
	}

	/* Unit sanity done */
	/* Find the right ship */
	if (load_unload == UNLOAD) {
	    if (land.lnd_ship != sp->shp_uid)
		continue;
	    if (land.lnd_land > -1)
		continue;
	} else if (sp->shp_x != land.lnd_x || sp->shp_y != land.lnd_y)
	    continue;

	if ((!(lchr[(int)land.lnd_type].l_flags & L_LIGHT)) &&
	    (!((mchr[(int)sp->shp_type].m_flags & M_SUPPLY) &&
	       (!(mchr[(int)sp->shp_type].m_flags & M_SUB))))) {
	    if (noisy) {
		pr("You can only load light units onto ships,\n");
		pr("unless the ship is a non-sub supply ship\n");
		pr("%s not loaded\n", prland(&land));
	    }
	    continue;
	}
	/* Fit unit on ship */
	if (load_unload == LOAD) {
	    /* We have to check again, since it may have changed */
	    if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
		(mchr[(int)sp->shp_type].m_nland == 0)) {
		if (shp_nland(sp) >= 2) {
		    pr("Non-land unit carrying subs can only carry up to two spy units.\n");
		    return 0;
		}
		/* Eh, let 'em load a spy only */
		load_spy = 1;
	    }
	    if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) {
		if (noisy) {
		    if (mchr[(int)sp->shp_type].m_nland)
			pr("%s doesn't have room for any more land units!\n",
			   prship(sp));
		    else
			pr("%s cannot carry land units!\n", prship(sp));
		}
		return 0;
	    }
	    sprintf(buf, "loaded on your %s at %s",
		    prship(sp), xyas(sp->shp_x, sp->shp_y, sp->shp_own));
	    gift(sp->shp_own, player->cnum, &land, buf);
	    land.lnd_ship = sp->shp_uid;
	    land.lnd_harden = 0;
	    putland(land.lnd_uid, &land);
#if 0
	   /*
	    * FIXME if this supplies from the sector, the putsect in
	    * load() / lload() duplicates those supplies, causing a
	    * seqno mismatch
	    */
	    if (!lnd_supply_all(&land))
		pr("WARNING: %s is out of supply!\n", prland(&land));
#else
	    if (!lnd_in_supply(&land))
		pr("WARNING: %s is out of supply!\n", prland(&land));
#endif
	} else {
	    sprintf(buf, "unloaded in your %s at %s",
		    dchr[sectp->sct_type].d_name,
		    xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));

	    /* Spies are unloaded quietly, others aren't */
	    if (!(lchr[(int)land.lnd_type].l_flags & L_SPY))
		gift(sectp->sct_own, player->cnum, &land, buf);
	    land.lnd_ship = -1;
	    putland(land.lnd_uid, &land);
	}
	pr("%s %s %s at %s.\n",
	   prland(&land),
	   (load_unload == UNLOAD) ?
	   "unloaded from" : "loaded onto",
	   prship(sp), xyas(sp->shp_x, sp->shp_y, player->cnum));
	loaded = 1;
    }
    *nshipsp += loaded;
    return 0;
}
Пример #22
0
static int
load_plane_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
		int load_unload, int *nshipsp)
{
    struct nstr_item ni;
    struct plnstr pln;
    int loaded = 0;
    char buf[1024];
    char *p;
    char prompt[512];
    struct mchrstr *mcp = mchr + sp->shp_type;

    if (mcp->m_nplanes + mcp->m_nchoppers + mcp->m_nxlight == 0) {
	if (noisy)
	    pr("%s cannot carry planes\n", prship(sp));
	return 0;
    }
    if (load_unload == LOAD &&
	shp_nplane(sp, NULL, NULL, NULL)
		>= mcp->m_nchoppers + mcp->m_nxlight + mcp->m_nplanes) {
	if (noisy)
	    pr("%s doesn't have room for any more planes\n", prship(sp));
	return 0;
    }
    sprintf(prompt, "Plane(s) to %s %s? ",
	    load_unload == LOAD ? "load onto" : "unload from", prship(sp));
    p = getstarg(player->argp[3], prompt, buf);
    if (!p)
	return RET_SYN;
    if (!snxtitem(&ni, EF_PLANE, p, NULL))
	return RET_SYN;

    if (!still_ok_ship(sectp, sp))
	return RET_SYN;

    if (noisy && p && *p)
	noisy = isdigit(*p);

    while (nxtitem(&ni, &pln)) {
	if (!player->owner)
	    continue;
	if (!(plchr[(int)pln.pln_type].pl_flags & P_L)
	    && !(plchr[(int)pln.pln_type].pl_flags & P_E)
	    && !(plchr[(int)pln.pln_type].pl_flags & P_K)
	    && !(plchr[(int)pln.pln_type].pl_flags & P_M)
	    ) {
	    if (noisy)
		pr("You can only load light planes, helos, xtra-light, or missiles onto ships.\n");
	    continue;
	}
	if (load_unload == LOAD && pln.pln_ship > -1) {
	    if (noisy)
		pr("%s is already on ship #%d!\n",
		   prplane(&pln), pln.pln_ship);
	    continue;
	}
	if (load_unload == LOAD && pln.pln_land > -1) {
	    if (noisy)
		pr("%s is already on land unit #%d!\n",
		   prplane(&pln), pln.pln_land);
	    continue;
	}
	if (pln.pln_harden != 0) {
	    if (noisy)
		pr("%s has been hardened and can't be loaded\n",
		   prplane(&pln));
	    continue;
	}

	if (load_unload == UNLOAD) {
	    if (pln.pln_ship != sp->shp_uid)
		continue;
	} else if (sp->shp_x != pln.pln_x || sp->shp_y != pln.pln_y)
	    continue;

	if (!could_be_on_ship(&pln, sp)) {
	    if (noisy) {
		if (plchr[(int)pln.pln_type].pl_flags & P_K)
		    p = "choppers";
		else if (plchr[(int)pln.pln_type].pl_flags & P_E)
		    p = "extra light planes";
		else if (plchr[(int)pln.pln_type].pl_flags & P_M)
		    p = "missiles";
		else
		    p = "planes";
		pr("%s cannot carry %s.\n", prship(sp), p);
	    }
	    continue;
	}
	/* Fit plane on ship */
	if (load_unload == LOAD) {
	    if (!put_plane_on_ship(&pln, sp)) {
		if (noisy)
		    pr("Can't put plane %d on this ship!\n", pln.pln_uid);
		continue;
	    }
	    sprintf(buf, "loaded on your %s at %s",
		    prship(sp), xyas(sp->shp_x, sp->shp_y, sp->shp_own));
	    gift(sp->shp_own, player->cnum, &pln, buf);
	    putplane(pln.pln_uid, &pln);
	} else {
	    pln.pln_ship = -1;
	    sprintf(buf, "unloaded in your %s at %s",
		    dchr[sectp->sct_type].d_name,
		    xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
	    gift(sectp->sct_own, player->cnum, &pln, buf);
	    putplane(pln.pln_uid, &pln);
	}
	pr("%s %s %s at %s.\n",
	   prplane(&pln),
	   (load_unload == UNLOAD) ?
	   "unloaded from" : "loaded onto",
	   prship(sp), xyas(sp->shp_x, sp->shp_y, player->cnum));
	loaded = 1;
    }
    *nshipsp += loaded;
    return 0;
}
Пример #23
0
int
lload(void)
{
    int noisy;
    int load_unload;
    int type;
    struct nstr_item nbst;
    struct ichrstr *ich;
    int nunits;
    struct sctstr sect;
    struct lndstr land;
    int retval;
    char *p;
    char buf[1024];

    p = getstarg(player->argp[1],
		 "What commodity (or 'plane' or 'land')? ", buf);
    if (!p || !*p)
	return RET_SYN;
    if (!strncmp(p, "plane", 5))
	type = EF_PLANE;
    else if (!strncmp(p, "land", 4))
	type = EF_LAND;
    else if (NULL != (ich = item_by_name(p)))
	type = EF_SECTOR;
    else {
	pr("Can't load '%s'\n", p);
	return RET_SYN;
    }

    p = getstarg(player->argp[2], "Unit(s): ", buf);
    if (!p || !*p)
	return RET_SYN;

    noisy = isdigit(*p);

    if (!snxtitem(&nbst, EF_LAND, p, NULL))
	return RET_SYN;

    load_unload = player->argp[0][1] == 'l' ? LOAD : UNLOAD;

    nunits = 0;
    while (nxtitem(&nbst, &land)) {
	if (land.lnd_own == 0)
	    continue;
	if (!player->owner) {
	    if (load_unload == UNLOAD || !noisy)
		continue;
	    if (relations_with(land.lnd_own, player->cnum) != ALLIED)
		continue;
	}

	if (!getsect(land.lnd_x, land.lnd_y, &sect))	/* XXX */
	    continue;
	if (!player->owner) {
	    if (land.lnd_own != player->cnum)
		continue;
	    if (load_unload == LOAD) {
		if (noisy)
		    pr("Sector %s is not yours.\n",
		       xyas(sect.sct_x, sect.sct_y, player->cnum));
		continue;
	    }
	    if (relations_with(sect.sct_own, player->cnum) != ALLIED) {
		pr("Sector %s is not yours.\n",
		   xyas(sect.sct_x, sect.sct_y, player->cnum));
		continue;
	    }
	}

	if (opt_MARKET) {
	    if (ontradingblock(EF_LAND, &land)) {
		pr("You cannot load/unload an item on the trading block!\n");
		continue;
	    }
	}

	switch (type) {
	case EF_LAND:
	    retval = load_land_land(&sect, &land, noisy, load_unload,
				    &nunits);
	    if (retval != 0)
		return retval;
	    break;
	case EF_PLANE:
	    retval = load_plane_land(&sect, &land, noisy, load_unload,
				     &nunits);
	    if (retval != 0)
		return retval;
	    break;
	case EF_SECTOR:
	    retval = load_comm_land(&sect, &land, ich, load_unload,
				    &nunits);
	    if (retval != 0)
		return retval;
	}
	/* load/unload plague */
	if (sect.sct_pstage == PLG_INFECT
	    && land.lnd_pstage == PLG_HEALTHY)
	    land.lnd_pstage = PLG_EXPOSED;
	if (land.lnd_pstage == PLG_INFECT
	    && sect.sct_pstage == PLG_HEALTHY)
	    sect.sct_pstage = PLG_EXPOSED;

	putsect(&sect);
	putland(land.lnd_uid, &land);
    }
    if (nunits == 0)
	pr("No units affected\n");
    else
	pr("%d unit%s %sloaded\n", nunits, splur(nunits),
	   load_unload == UNLOAD ? "un" : "");
    return RET_OK;
}
Пример #24
0
/*
 * format: set <type> <SHIP/NUKE> <PRICE>
 */
int
set(void)
{
    static int ef_saleable[] = { EF_SHIP, EF_PLANE, EF_LAND, EF_NUKE, EF_BAD };
    char *p;
    int type;
    int price;
    char prompt[80];
    struct trdstr trade;
    struct nstr_item ni;
    struct nstr_item ni_trade;
    union empobj_storage item;
    struct sctstr sect;
    int freeslot;
    int foundslot;
    int id;
    time_t now;
    char buf[1024];

    if (!opt_MARKET) {
	pr("The market is disabled.\n");
	return RET_FAIL;
    }
    check_market();
    check_trade();

    p = getstarg(player->argp[1], "Ship, plane, land unit or nuke? ", buf);
    if (!p)
	return RET_SYN;
    if ((type = ef_byname_from(p, ef_saleable)) < 0) {
	pr("You can sell only ships, planes, land units or nukes\n");
	return RET_SYN;
    }
    if (!snxtitem(&ni, type, player->argp[2], NULL))
	return RET_SYN;
    while (nxtitem(&ni, &item)) {
	if (!player->owner && !player->god)
	    continue;
	getsect(item.gen.x, item.gen.y, &sect);
	if (!military_control(&sect)) {
	    pr("Military control required to sell goods.\n");
	    return RET_FAIL;
	}
	trade.trd_type = type;
	sprintf(prompt, "%s #%d; price? ",
		trade_nameof(&trade, &item.gen), ni.cur);
	if (!(p = getstarg(player->argp[3], prompt, buf)))
	    return RET_FAIL;
	if (!check_obj_ok(&item.gen))
	    return RET_FAIL;
	if ((price = atoi(p)) < 0)
	    continue;
	foundslot = -1;
	freeslot = -1;
	snxtitem_all(&ni_trade, EF_TRADE);
	while (nxtitem(&ni_trade, &trade)) {
	    if (trade.trd_owner == 0)
		freeslot = ni_trade.cur;
	    if (trade.trd_unitid == ni.cur && trade.trd_type == type) {
		foundslot = ni_trade.cur;
		break;
	    }
	}
	if (price <= 0) {
	    if (foundslot >= 0) {
		pr("%s #%d (lot #%d) removed from trading\n",
		   trade_nameof(&trade, &item.gen), ni.cur, foundslot);
		trade.trd_owner = 0;
		puttrade(ni_trade.cur, &trade);
	    }
	} else {
	    if (trade_has_unsalable_cargo(&item.gen, 1))
		return RET_FAIL;
	    if (foundslot >= 0)
		id = foundslot;
	    else if (freeslot >= 0)
		id = freeslot;
	    else
		id = ni_trade.cur;
	    ef_blank(EF_TRADE, id, &trade);
	    trade.trd_x = 1;
	    trade.trd_y = 0;
	    trade.trd_type = type;
	    trade.trd_owner = player->cnum;
	    trade.trd_unitid = ni.cur;
	    trade.trd_price = price;
	    (void)time(&now);
	    trade.trd_markettime = now;
	    trade.trd_maxbidder = player->cnum;
	    puttrade(id, &trade);
	    pr("%s #%d (lot #%d) price %s to $%d\n",
	       trade_nameof(&trade, &item.gen), ni.cur,
	       id, foundslot >= 0 ? "reset" : "set", price);
	}
    }
    return RET_OK;
}
Пример #25
0
int
tend(void)
{
    struct nstr_item targets;
    struct nstr_item tenders;
    struct shpstr tender;
    struct shpstr target;
    struct ichrstr *ip;
    struct mchrstr *vbase;
    int amt;
    int retval;
    int ontender;
    int ontarget;
    int maxtender;
    int maxtarget;
    int transfer;
    int total;
    int type;
    char *p;
    char prompt[512];
    char buf[1024];

    p = getstarg(player->argp[1], "Tend what commodity (or 'land')? ",
		 buf);
    if (!p || !*p)
	return RET_SYN;

    if (!strncmp(p, "land", 4))
	type = EF_LAND;
    else if (NULL != (ip = item_by_name(p)))
	type = EF_SECTOR;
    else {
	pr("Can't tend '%s'\n", p);
	return RET_SYN;
    }

    if (!snxtitem(&tenders, EF_SHIP, player->argp[2], "Tender(s)? "))
	return RET_SYN;

    while (nxtitem(&tenders, &tender)) {
	if (!player->owner)
	    continue;
	if (type == EF_LAND) {
	    sprintf(prompt, "Land unit(s) to tend from %s? ",
		    prship(&tender));
	    p = getstarg(player->argp[3], prompt, buf);
	    if (!p)
		return RET_FAIL;
	    if (!*p)
		continue;
	    if (!check_ship_ok(&tender))
		return RET_SYN;
	    if (0 != (retval = tend_land(&tender, p)))
		return retval;
	    continue;
	}
	sprintf(prompt, "Number of %s to tend from %s? ",
		ip->i_name, prship(&tender));
	p = getstarg(player->argp[3], prompt, buf);
	if (!p)
	    return RET_FAIL;
	if (!*p)
	    continue;
	if (!check_ship_ok(&tender))
	    return RET_SYN;
	if (!(amt = atoi(p))) {
	    pr("Amount must be non-zero!\n");
	    return RET_SYN;
	}
	ontender = tender.shp_item[ip->i_uid];
	if (ontender == 0 && amt > 0) {
	    pr("No %s on %s\n", ip->i_name, prship(&tender));
	    return RET_FAIL;
	}
	vbase = &mchr[(int)tender.shp_type];
	maxtender = vbase->m_item[ip->i_uid];
	if (maxtender == 0) {
	    pr("A %s cannot hold any %s\n",
	       mchr[(int)tender.shp_type].m_name, ip->i_name);
	    break;
	}
	if (!snxtitem(&targets, EF_SHIP,
		      player->argp[4], "Ships to be tended? "))
	    return RET_FAIL;
	if (!check_ship_ok(&tender))
	    return RET_SYN;
	total = 0;
	while (nxtitem(&targets, &target)) {
	    if (!player->owner
		&& relations_with(target.shp_own, player->cnum) < FRIENDLY)
		continue;
	    if (target.shp_uid == tender.shp_uid)
		continue;
	    if (tender.shp_x != target.shp_x ||
		tender.shp_y != target.shp_y)
		continue;
	    if (ip->i_uid == I_CIVIL && tender.shp_own != target.shp_own)
		continue;
	    ontarget = target.shp_item[ip->i_uid];
	    vbase = &mchr[(int)target.shp_type];
	    maxtarget = vbase->m_item[ip->i_uid];
	    if (amt < 0) {
		/* take from target and give to tender */
		if (!player->owner)
		    continue;
		if (ontarget == 0) {
		    pr("No %s on %s\n", ip->i_name, prship(&target));
		    continue;
		}
		transfer = MIN(ontarget, -amt);
		transfer = MIN(maxtender - ontender, transfer);
		if (transfer == 0)
		    continue;
		target.shp_item[ip->i_uid] = ontarget - transfer;
		ontender += transfer;
		total += transfer;
	    } else {
		/* give to target from tender */
		transfer = MIN(ontender, amt);
		transfer = MIN(transfer, maxtarget - ontarget);
		if (transfer == 0)
		    continue;
		target.shp_item[ip->i_uid] = ontarget + transfer;
		ontender -= transfer;
		total += transfer;
		if (transfer && target.shp_own != player->cnum) {
		    wu(0, target.shp_own, "%s tended %d %s to %s\n",
		       cname(player->cnum), total, ip->i_name,
		       prship(&target));
		}
	    }
	    expose_ship(&tender, &target);
	    putship(target.shp_uid, &target);
	    if (amt > 0 && ontender == 0) {
		pr("%s out of %s\n", prship(&tender), ip->i_name);
		break;
	    }
	}
	pr("%d total %s transferred %s %s\n",
	   total, ip->i_name, (amt > 0) ? "off of" : "to",
	   prship(&tender));
	tender.shp_item[ip->i_uid] = ontender;
	tender.shp_mission = 0;
	putship(tender.shp_uid, &tender);
    }
    return RET_OK;
}
Пример #26
0
int
sona(void)
{
    struct nstr_item ni, nit;
    struct sctstr sect;
    struct shpstr ship;
    struct shpstr targ;
    struct natstr *natp;
    struct mchrstr *mcp;
    struct mchrstr *tmcp;
    struct nstr_sect ns;
    int range;
    int visib, pingrange;
    int srange;
    int vrange;
    int dist;
    int x, y;
    int cx, cy;
    int changed = 0;
    int row;
    /* Where these are used are non-re-entrant, so we keep 'em around */
    static char **rad = NULL;
    static char *radbuf = NULL;
    static signed char **vis = NULL;
    static signed char *visbuf = NULL;

    if (!snxtitem(&ni, EF_SHIP, player->argp[1], NULL))
	return RET_SYN;
    if (!radbuf)
	radbuf = malloc(WORLD_Y * MAPWIDTH(1));
    if (!visbuf)
	visbuf = malloc(WORLD_Y * MAPWIDTH(1));
    if (!rad && radbuf) {
	rad = malloc(WORLD_Y * sizeof(char *));
	if (rad) {
	    for (x = 0; x < WORLD_Y; x++) {
		rad[x] = &radbuf[(WORLD_X + 1) * x];
	    }
	}
    }
    if (!vis && visbuf) {
	vis = malloc(WORLD_Y * sizeof(signed char *));
	if (vis) {
	    for (x = 0; x < WORLD_Y; x++) {
		vis[x] = &visbuf[(WORLD_X + 1) * x];
	    }
	}
    }
    if (!radbuf || !visbuf || !rad || !vis) {
	pr("Memory error, tell the deity.\n");
	logerror("malloc failed in sona\n");
	return RET_FAIL;
    }
    while (nxtitem(&ni, &ship)) {
	if (!player->owner)
	    continue;
	mcp = &mchr[(int)ship.shp_type];
	if (!(mcp->m_flags & M_SONAR))
	    continue;
	getsect(ship.shp_x, ship.shp_y, &sect);
	if (sect.sct_type != SCT_WATER)
	    continue;
	range = (int)techfact(ship.shp_tech, mcp->m_vrnge);
	srange = MIN(7, 7 * range * ship.shp_effic / 200);
	pr("%s at %s efficiency %d%%, max range %d\n",
	   prship(&ship),
	   xyas(ship.shp_x, ship.shp_y, player->cnum),
	   ship.shp_effic, srange);
	snxtsct_dist(&ns, ship.shp_x, ship.shp_y, srange);
	blankfill(radbuf, &ns.range, 1);
	while (nxtsct(&ns, &sect)) {
	    if (player->owner || sect.sct_type == SCT_WATER)
		rad[ns.dy][ns.dx] = dchr[sect.sct_type].d_mnem;
	    else {
		rad[ns.dy][ns.dx] = '?';
	    }
	}
	snxtsct_dist(&ns, ship.shp_x, ship.shp_y, srange);
	cx = deltx(&ns.range, ship.shp_x);
	cy = delty(&ns.range, ship.shp_y);
	while (nxtsct(&ns, &sect)) {
	    if (!line_of_sight(rad, cx, cy, ns.dx, ns.dy)) {
		rad[ns.dy][ns.dx] = ' ';
		continue;
	    }
	    if (ship.shp_tech >= 310 && sect.sct_type == SCT_WATER) {
		if (sect.sct_mines) {
		    pr("Sonar detects %d mines in %s!\n",
		       sect.sct_mines,
		       xyas(sect.sct_x, sect.sct_y, player->cnum));
		    rad[ns.dy][ns.dx] = 'X';
		}
	    }
	    changed |= map_set(player->cnum, sect.sct_x, sect.sct_y,
			       rad[ns.dy][ns.dx], 0);

	}
	memset(visbuf, 0, (WORLD_Y * (WORLD_X + 1)));
	snxtitem_dist(&nit, EF_SHIP, ship.shp_x, ship.shp_y, range);
	while (nxtitem(&nit, &targ)) {
	    if (targ.shp_own == player->cnum || targ.shp_own == 0)
		continue;
	    tmcp = &mchr[(int)targ.shp_type];
	    visib = shp_visib(&targ);
	    pingrange = MIN(7, MAX(visib, 10) * range / 10);
	    vrange = pingrange * ship.shp_effic / 200;
	    dist = mapdist(targ.shp_x, targ.shp_y, ship.shp_x, ship.shp_y);
	    pingrange = (MAX(pingrange, 2) * targ.shp_effic) / 100;
	    if (dist > pingrange)
		continue;
	    if (tmcp->m_flags & M_SONAR && targ.shp_own) {
		natp = getnatp(targ.shp_own);
		if (natp->nat_flags & NF_SONAR)
		    wu(0, targ.shp_own,
		       "Sonar ping from %s detected by %s!\n",
		       xyas(ship.shp_x, ship.shp_y,
			    targ.shp_own), prship(&targ));
		if (targ.shp_rflags & RET_SONARED)
		    retreat_ship(&targ, targ.shp_own, 's');
	    }
	    if (dist > vrange)
		continue;
	    x = deltx(&ns.range, (int)targ.shp_x);
	    y = delty(&ns.range, (int)targ.shp_y);
	    if (rad[y][x] != dchr[SCT_WATER].d_mnem && rad[y][x] != 'X')
		continue;
	    if (tmcp->m_flags & M_SUB &&
		relations_with(targ.shp_own, player->cnum) < FRIENDLY) {
		if (mcp->m_vrnge + visib < 8)
		    pr("Sonar detects sub #%d @ %s\n",
		       targ.shp_uid,
		       xyas(targ.shp_x, targ.shp_y, player->cnum));
		else if (mcp->m_vrnge + visib < 10)
		    pr("Sonar detects %s @ %s\n",
		       prship(&targ),
		       xyas(targ.shp_x, targ.shp_y, player->cnum));
		else
		    pr("Sonar detects %s %s @ %s\n",
		       cname(targ.shp_own), prship(&targ),
		       xyas(targ.shp_x, targ.shp_y, player->cnum));
	    } else
		pr("Sonar detects %s %s @ %s\n",
		   cname(targ.shp_own), prship(&targ),
		   xyas(targ.shp_x, targ.shp_y, player->cnum));

	    if (visib > vis[y][x]) {
		vis[y][x] = visib;
		/* &~0x20 makes it a cap letter */
		rad[y][x] = (*mchr[(int)targ.shp_type].m_name) & ~0x20;
	    }
	}
	if (!player->argp[2]) {
	    rad[cy][cx] = '0';
	    for (row = 0; row < ns.range.height; row++)
		if (!blankrow(rad[row]))
		    pr("%s\n", rad[row]);
	}
	pr("\n");

    }
    if (changed)
	writemap(player->cnum);
    return RET_OK;
}
Пример #27
0
int
work(void)
{
    int nunits;
    struct nstr_item ni;
    struct sctstr sect;
    struct lndstr land;
    int work_amt, eff_amt, w;
    char *p;
    char buf[1024];
    double cost;
    struct natstr *natp = getnatp(player->cnum);

    if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL))
	return RET_SYN;
    p = getstarg(player->argp[2], "Amount: ", buf);
    if (!p || !*p)
	return RET_SYN;
    work_amt = atoi(p);
    if ((work_amt < 0) || (work_amt > land_mob_max)) {
	pr("Mobility used must be from 0 to %d\n", land_mob_max);
	return RET_FAIL;
    }
    nunits = 0;
    while (nxtitem(&ni, &land)) {
	if (!player->owner || land.lnd_own == 0)
	    continue;
	if (!(lchr[(int)land.lnd_type].l_flags & L_ENGINEER))
	    continue;
	if (land.lnd_mobil <= 0) {
	    pr("%s has no mobility!\n", prland(&land));
	    continue;
	}
	getsect(land.lnd_x, land.lnd_y, &sect);
	if (sect.sct_effic >= 100 && sect.sct_type == sect.sct_newtype) {
	    pr("Nothing to do for %s in %s\n",
	       prland(&land), xyas(sect.sct_x, sect.sct_y, player->cnum));
	    continue;
	}
	eff_amt = MIN(land.lnd_mobil, work_amt);
	w = (eff_amt * land.lnd_effic) / 600;
	if (w < 1) {
	    pr("%s doesn't work enough to change efficiency (try increasing amount)\n",
	       prland(&land));
	    continue;
	}
	cost = 0.0;
	w = buildeff(&sect, w, &cost);
	if (w == 0) {
	    pr("%s can't change efficiency in %s\n",
	       prland(&land), xyas(land.lnd_x, land.lnd_y, player->cnum));
	    continue;
	}
	if (player->dolcost + cost > natp->nat_money) {
	    pr("You can't afford to work that much in %s!\n",
	       xyas(land.lnd_x, land.lnd_y, player->cnum));
	    break;
	}
	player->dolcost += cost;
	land.lnd_mission = 0;
	land.lnd_mobil -= roundavg(w * 600.0 / land.lnd_effic);
	nunits++;
	pr("%s %s efficiency at %s to %d\n",
	   prland(&land),
	   sect.sct_type == sect.sct_newtype ? "raised" : "lowered",
	   xyas(land.lnd_x, land.lnd_y, player->cnum),
	   sect.sct_effic);
	putland(land.lnd_uid, &land);
	putsect(&sect);
    }
    if (nunits == 0) {
	if (player->argp[1])
	    pr("%s: No unit(s)\n", player->argp[1]);
	else
	    pr("%s: No unit(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d unit%s\n", nunits, splur(nunits));
    return RET_OK;
}
Пример #28
0
int
sabo(void)
{
    struct nstr_item ni;
    struct lndstr land, tmp;
    struct sctstr sect;
    double odds;
    int dam;

    if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL))
	return RET_SYN;

    while (nxtitem(&ni, &land)) {
	if (!player->owner)
	    continue;
	if (!(lchr[(int)land.lnd_type].l_flags & L_SPY)) {
	    pr("%s is not a spy.\n", prland(&land));
	    continue;
	}
	if (land.lnd_ship >= 0) {
	    pr("%s is on ship %d.\n", prland(&land), land.lnd_ship);
	    continue;
	}
	if (land.lnd_land >= 0) {
	    pr("%s is on unit %d.\n", prland(&land), land.lnd_land);
	    continue;
	}
	if (!getsect(land.lnd_x, land.lnd_y, &sect))
	    continue;
	if (land.lnd_item[I_SHELL] == 0) {
	    pr("%s has no shells.\n", prland(&land));
	    continue;
	}

	odds = LND_SPY_DETECT_CHANCE(land.lnd_effic);
	if (chance(odds)) {
	    wu(0, sect.sct_own,
	       "%s spy shot in %s during sabotage attempt.\n",
	       cname(player->cnum),
	       xyas(sect.sct_x, sect.sct_y, sect.sct_own));
	    pr("%s was shot and killed.\n", prland(&land));
	    land.lnd_effic = 0;
	    putland(land.lnd_uid, &land);
	    continue;
	}

	dam = lnd_sabo(&land, sect.sct_item);
	if (dam < 0)
	    continue;

	pr("Explosion in %s causes %d damage.\n",
	   xyas(land.lnd_x, land.lnd_y, player->cnum), dam);
	if (sect.sct_own) {
	    wu(0, sect.sct_own,
	       "Sabotage in sector %s caused %d damage.\n",
	       xyas(sect.sct_x, sect.sct_y, sect.sct_own), dam);
	}

	/* hack: hide the spy so it don't gets blasted by sectdamage() */
	tmp = land;
	tmp.lnd_own = 0;
	putland(land.lnd_uid, &tmp);
	land.lnd_seqno = tmp.lnd_seqno;

	sectdamage(&sect, dam);
	putsect(&sect);

	if (chance(odds)) {
	    pr("%s dies in explosion.\n", prland(&land));
	    land.lnd_effic = 0;
	}
	putland(land.lnd_uid, &land);
    }
    return RET_OK;
}
Пример #29
0
int
pdump(void)
{
    int nplanes;
    struct nstr_item np;
    struct plnstr plane;
    struct nukstr nuke;
    int field[128];
    struct natstr *natp;
    int n, i;
    time_t now;

    if (!snxtitem(&np, EF_PLANE, player->argp[1], NULL))
	return RET_SYN;
    prdate();

    if (!player->argp[2]) {
	for (n = 1; n <= 32; n++)
	    field[n - 1] = n;
	field[n - 1] = 0;
    } else {
	n = 2;
	i = 0;
	while (player->argp[n]) {

	    if (!strcmp("type", player->argp[n])) {
		field[i++] = 1;
	    } else if (!strcmp("x", player->argp[n])) {
		field[i++] = 2;
	    } else if (!strcmp("y", player->argp[n])) {
		field[i++] = 3;
	    } else if (!strcmp("wing", player->argp[n])) {
		field[i++] = 4;
	    } else if (!strcmp("eff", player->argp[n])) {
		field[i++] = 5;
	    } else if (!strcmp("mob", player->argp[n])) {
		field[i++] = 6;
	    } else if (!strcmp("tech", player->argp[n])) {
		field[i++] = 7;
	    } else if (!strcmp("att", player->argp[n])) {
		field[i++] = 8;
	    } else if (!strcmp("def", player->argp[n])) {
		field[i++] = 9;
	    } else if (!strcmp("acc", player->argp[n])) {
		field[i++] = 10;
	    } else if (!strcmp("react", player->argp[n])) {
		field[i++] = 11;
	    } else if (!strcmp("range", player->argp[n])) {
		field[i++] = 12;
	    } else if (!strcmp("load", player->argp[n])) {
		field[i++] = 13;
	    } else if (!strcmp("fuel", player->argp[n])) {
		field[i++] = 14;
	    } else if (!strcmp("hard", player->argp[n])) {
		field[i++] = 15;
	    } else if (!strcmp("ship", player->argp[n])) {
		field[i++] = 16;
	    } else if (!strcmp("land", player->argp[n])) {
		field[i++] = 17;
	    } else if (!strcmp("laun", player->argp[n])) {
		field[i++] = 18;
	    } else if (!strcmp("orb", player->argp[n])) {
		field[i++] = 19;
	    } else if (!strcmp("nuke", player->argp[n])) {
		field[i++] = 20;
	    } else if (!strcmp("grd", player->argp[n])) {
		field[i++] = 21;
	    } else {
		pr("Unrecognized field %s\n", player->argp[n]);
	    }
	    if (n++ > 100) {
		pr("Too many fields\n");
		return RET_FAIL;
	    }
	}
	field[i] = 0;
    }

    if (player->god)
	pr("   ");
    time(&now);
    pr("DUMP PLANES %ld\n", (long)now);
    if (player->god)
	pr("own ");
    pr("id");
    n = 0;
    while (field[n]) {
	switch (field[n]) {
	case 1:
	    pr(" type");
	    break;
	case 2:
	    pr(" x");
	    break;
	case 3:
	    pr(" y");
	    break;
	case 4:
	    pr(" wing");
	    break;
	case 5:
	    pr(" eff");
	    break;
	case 6:
	    pr(" mob");
	    break;
	case 7:
	    pr(" tech");
	    break;
	case 8:
	    pr(" att");
	    break;
	case 9:
	    pr(" def");
	    break;
	case 10:
	    pr(" acc");
	    break;
	case 11:
	    pr(" react");
	    break;
	case 12:
	    pr(" range");
	    break;
	case 13:
	    pr(" load");
	    break;
	case 14:
	    pr(" fuel");
	    break;
	case 15:
	    pr(" hard");
	    break;
	case 16:
	    pr(" ship");
	    break;
	case 17:
	    pr(" land");
	    break;
	case 18:
	    pr(" laun");
	    break;
	case 19:
	    pr(" orb");
	    break;
	case 20:
	    pr(" nuke");
	    break;
	case 21:
	    pr(" grd");
	    break;
	}
	n++;
    }
    pr("\n");

    nplanes = 0;
    natp = getnatp(player->cnum);
    while (nxtitem(&np, &plane)) {
	if (!player->owner || plane.pln_own == 0)
	    continue;
	nplanes++;
	if (player->god)
	    pr("%d ", plane.pln_own);
	pr("%d", np.cur);
	n = 0;
	while (field[n]) {
	    switch (field[n++]) {
	    case 1:
		pr(" %.4s", plchr[(int)plane.pln_type].pl_name);
		break;
	    case 2:
		pr(" %d", xrel(natp, plane.pln_x));
		break;
	    case 3:
		pr(" %d", yrel(natp, plane.pln_y));
		break;
	    case 4:
		pr(" %c", plane.pln_wing ? plane.pln_wing : '~');
		break;
	    case 5:
		pr(" %d", plane.pln_effic);
		break;
	    case 6:
		pr(" %d", plane.pln_mobil);
		break;
	    case 7:
		pr(" %d", plane.pln_tech);
		break;
	    case 8:
		pr(" %d", pln_att(&plane));
		break;
	    case 9:
		pr(" %d", pln_def(&plane));
		break;
	    case 10:
		pr(" %d", pln_acc(&plane));
		break;
	    case 11:
		pr(" %d", plane.pln_range);
		break;
	    case 12:
		pr(" %d", pln_range_max(&plane));
		break;
	    case 13:
		pr(" %d", pln_load(&plane));
		break;
	    case 14:
		pr(" %d", plchr[(int)plane.pln_type].pl_fuel);
		break;
	    case 15:
		pr(" %d", plane.pln_harden);
		break;
	    case 16:
		pr(" %d", plane.pln_ship);
		break;
	    case 17:
		pr(" %d", plane.pln_land);
		break;
	    case 18:
		pr(pln_is_in_orbit(&plane) ? " Y" : " N");
		break;
	    case 19:
		pr(pln_is_in_orbit(&plane)
		   && (plane.pln_flags & PLN_SYNCHRONOUS)
		   ? " Y" : " N");
		break;
	    case 20:
		if (getnuke(nuk_on_plane(&plane), &nuke)) {
		    pr(" %.5s", nchr[nuke.nuk_type].n_name);
		    break;
		} else
		    pr(" N/A");
		break;
	    case 21:
		pr(" %c", plane.pln_flags & PLN_AIRBURST ? 'A' : 'G');
		break;
	    }
	}
	pr("\n");
    }
    if (nplanes == 0) {
	if (player->argp[1])
	    pr("%s: No plane(s)\n", player->argp[1]);
	else
	    pr("%s: No plane(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d plane%s\n", nplanes, splur(nplanes));

    return RET_OK;
}
Пример #30
0
static int
tend_land(struct shpstr *tenderp, char *units)
{
    struct nstr_item lni;
    struct nstr_item targets;
    struct shpstr target;
    struct lndstr land;
    char buf[1024];

    if (!snxtitem(&lni, EF_LAND, units, NULL))
	return RET_SYN;

    while (nxtitem(&lni, &land)) {
	if (!player->owner)
	    continue;
	if (land.lnd_ship != tenderp->shp_uid) {
	    pr("%s is not on %s!\n", prland(&land), prship(tenderp));
	    continue;
	}
	if (!(lchr[(int)land.lnd_type].l_flags & L_ASSAULT)) {
	    pr("%s does not have \"assault\" capability and can't be tended\n",
	       prland(&land));
	    continue;
	}
	if (!snxtitem(&targets, EF_SHIP,
		      player->argp[4], "Ship to be tended? "))
	    return RET_FAIL;
	if (!check_ship_ok(tenderp) || !check_land_ok(&land))
	    return RET_SYN;
	while (nxtitem(&targets, &target)) {
	    if (!player->owner
		&& relations_with(target.shp_own, player->cnum) < FRIENDLY)
		continue;
	    if (target.shp_uid == tenderp->shp_uid)
		continue;
	    if (tenderp->shp_x != target.shp_x ||
		tenderp->shp_y != target.shp_y)
		continue;

	    /* Fit unit on ship */
	    getship(target.shp_uid, &target);

	    if ((!(lchr[(int)land.lnd_type].l_flags & L_LIGHT)) &&
		(!((mchr[(int)target.shp_type].m_flags & M_SUPPLY) &&
		   (!(mchr[(int)target.shp_type].m_flags & M_SUB))))) {
		pr("You can only load light units onto ships,\n"
		   "unless the ship is a non-sub supply ship\n"
		   "%s not tended\n", prland(&land));
		continue;
	    }

	    if ((mchr[(int)target.shp_type].m_flags & M_SUB) &&
		(lchr[(int)land.lnd_type].l_flags & L_SPY) &&
		!mchr[(int)target.shp_type].m_nland) {
		if (shp_nland(&target) > 1) {
		    pr("%s doesn't have room for more than two spy units!\n",
		       prship(&target));
		    continue;
		}
	    } else if (shp_nland(&target) >= mchr[target.shp_type].m_nland) {
		if (mchr[(int)target.shp_type].m_nland)
		    pr("%s doesn't have room for any more land units!\n",
		       prship(&target));
		else
		    pr("%s doesn't carry land units!\n", prship(&target));
		continue;
	    }
	    pr("%s transferred from %s to %s\n",
	       prland(&land), prship(tenderp), prship(&target));
	    sprintf(buf, "loaded on your %s at %s",
		    prship(&target), xyas(target.shp_x, target.shp_y,
					  target.shp_own));
	    gift(target.shp_own, player->cnum, &land, buf);
	    land.lnd_ship = target.shp_uid;
	    land.lnd_harden = 0;
	    putland(land.lnd_uid, &land);
	    expose_ship(tenderp, &target);
	    putship(target.shp_uid, &target);
	    putship(tenderp->shp_uid, tenderp);
	}
    }
    return 0;
}