Exemplo n.º 1
0
/*
 * Give @unit and its cargo to @recipient.
 * No action if @recipient already owns @unit.
 * If @giver is non-zero, inform @recipient and @giver of the transaction.
 * Clears mission and group on the units given away.
 */
void
unit_give_away(struct empobj *unit, natid recipient, natid giver)
{
    int type;
    struct nstr_item ni;
    union empobj_storage cargo;

    if (unit->own == recipient)
	return;

    if (giver) {
	mpr(unit->own, "%s given to %s\n",
	    unit_nameof(unit), cname(recipient));
	mpr(recipient, "%s given to you by %s\n",
	    unit_nameof(unit), cname(giver));
    }

    unit->own = recipient;
    unit_wipe_orders(unit);
    put_empobj(unit->ef_type, unit->uid, unit);

    for (type = EF_PLANE; type <= EF_NUKE; type++) {
	snxtitem_cargo(&ni, type, unit->ef_type, unit->uid);
	while (nxtitem(&ni, &cargo))
	    unit_give_away(&cargo.gen, recipient, giver);
    }
}
Exemplo n.º 2
0
static void
divine_load_unload(struct empobj *unit, int type, int uid, char *act)
{
    if (uid < 0)
	return;

    pr("%s %s %s #%d\n",
       unit_nameof(unit), act, ef_nameof(type), uid);
    if (unit->own && unit->own != player->cnum)
	wu(0, unit->own,
	   "%s %s %s #%d by an act of %s!\n",
	   unit_nameof(unit), act, ef_nameof(type), uid,
	   cname(player->cnum));
    /* carrier owner could differ; can't be bothered to report to him */
}
Exemplo n.º 3
0
int
trade_has_unsalable_cargo(struct empobj *tgp, int noisy)
{
    int ret, i, type;
    short *item;
    struct nstr_item ni;
    union empobj_storage cargo;

    ret = 0;
    if (tgp->ef_type == EF_SHIP || tgp->ef_type == EF_LAND) {
	item = tgp->ef_type == EF_SHIP
	    ? ((struct shpstr *)tgp)->shp_item
	    : ((struct lndstr *)tgp)->lnd_item;
	for (i = I_NONE + 1; i <= I_MAX; i++) {
	    if (item[i] && !ichr[i].i_sell) {
		if (noisy)
		    pr("%s carries %s, which you can't sell.\n",
		       unit_nameof(tgp), ichr[i].i_name);
		ret = 1;
	    }
	}
    }

    for (type = EF_PLANE; type <= EF_NUKE; type++) {
	snxtitem_cargo(&ni, type, tgp->ef_type, tgp->uid);
	while (nxtitem(&ni, &cargo))
	    ret |= trade_has_unsalable_cargo(&cargo.gen, noisy);
    }

    return ret;
}
Exemplo n.º 4
0
void
gift(natid givee, natid giver, void *ptr, char *mesg)
{
    if (giver != givee)
	wu(0, givee, "%s %s %s\n", cname(giver), unit_nameof(ptr), mesg);
    unit_give_away(ptr, givee, 0);
}
Exemplo n.º 5
0
/*
 * Drop cargo of @unit.
 * Give it to @newown, unless it's zero.
 */
void
unit_drop_cargo(struct empobj *unit, natid newown)
{
    int type;
    struct nstr_item ni;
    union empobj_storage cargo;

    for (type = EF_PLANE; type <= EF_NUKE; type++) {
	snxtitem_cargo(&ni, type, unit->ef_type, unit->uid);
	while (nxtitem(&ni, &cargo)) {
	    switch (type) {
	    case EF_PLANE:
		cargo.plane.pln_ship = cargo.plane.pln_land = -1;
		break;
	    case EF_LAND:
		cargo.land.lnd_ship = cargo.land.lnd_land = -1;
		break;
	    case EF_NUKE:
		cargo.nuke.nuk_plane = -1;
		break;
	    }
	    mpr(cargo.gen.own, "%s transferred off %s %d to %s\n",
		unit_nameof(&cargo.gen),
		ef_nameof(unit->ef_type), unit->uid,
		xyas(cargo.gen.x, cargo.gen.y, cargo.gen.own));
	    if (newown)
		unit_give_away(&cargo.gen, newown, cargo.gen.own);
	    put_empobj(type, cargo.gen.uid, &cargo.gen);
	}
    }
}
Exemplo n.º 6
0
static void
unit_view(struct emp_qelem *list)
{
    struct sctstr sect;
    struct emp_qelem *qp;
    struct emp_qelem *next;
    struct ulist *ulp;

    for (qp = list->q_back; qp != list; qp = next) {
	next = qp->q_back;
	ulp = (struct ulist *)qp;
	if (CANT_HAPPEN(!(ef_flags(ulp->unit.gen.ef_type) & EFF_XY)))
	    continue;
	getsect(ulp->unit.gen.x, ulp->unit.gen.y, &sect);
	if (ulp->unit.gen.ef_type == EF_SHIP) {
	    if (mchr[ulp->unit.ship.shp_type].m_flags & M_FOOD)
		pr("[fert:%d] ", sect.sct_fertil);
	    if (mchr[ulp->unit.ship.shp_type].m_flags & M_OIL)
		pr("[oil:%d] ", sect.sct_oil);
	}
	pr("%s @ %s %d%% %s\n", unit_nameof(&ulp->unit.gen),
	   xyas(ulp->unit.gen.x, ulp->unit.gen.y, player->cnum),
	   sect.sct_effic, dchr[sect.sct_type].d_name);
    }
}
Exemplo n.º 7
0
void
divine_load(struct empobj *unit, int type, int uid)
{
    union empobj_storage carrier;

    divine_load_unload(unit, type, uid, "loaded onto");
    if (get_empobj(type, uid, &carrier)
	&& (unit->x != carrier.gen.x || unit->y != carrier.gen.y)) {
	pr("%s teleported from %s to %s!",
	   unit_nameof(unit), xyas(unit->x, unit->y, player->cnum),
	   xyas(carrier.gen.x, carrier.gen.y, player->cnum));
	unit_teleport(unit, carrier.gen.x, carrier.gen.y);
    }
}
Exemplo n.º 8
0
/*
 * Report deity meddling with @unit.
 * Just like divine_sct_change(), only for ships, planes, land units,
 * nukes.
 */
void
divine_unit_change(struct empobj *unit, char *name,
		   int change, int goodness, char *fmt, ...)
{
    va_list ap;
    char buf[4096];

    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

    if (!change) {
	pr("%s of %s unchanged\n", name, unit_nameof(unit));
	return;
    }

    pr("%s of %s changed %s\n", name, unit_nameof(unit), buf);
    if (change > 0 && unit->own && unit->own != player->cnum) {
	wu(0, unit->own, "%s of %s changed %s by an act of %s\n",
	   name, unit_nameof(unit), buf, cname(player->cnum));
	nreport_divine_aid(unit->own, goodness);
    }
}
Exemplo n.º 9
0
/*
 * Update cargo of @carrier for movement or destruction.
 * If the carrier is destroyed, destroy its cargo (planes, land units,
 * nukes).
 * Else update their location to the carrier's.  Any op sectors equal
 * to location get updated, too.
 * Return number of units updated.
 */
int
unit_update_cargo(struct empobj *carrier)
{
    int cargo_type;
    struct nstr_item ni;
    union empobj_storage obj;
    int n = 0;

    for (cargo_type = EF_PLANE; cargo_type <= EF_NUKE; cargo_type++) {
	snxtitem_cargo(&ni, cargo_type, carrier->ef_type, carrier->uid);
	while (nxtitem(&ni, &obj)) {
	    if (carrier->own)
		unit_teleport(&obj.gen, carrier->x, carrier->y);
	    else {
		mpr(obj.gen.own, "%s lost!\n", unit_nameof(&obj.gen));
		obj.gen.effic = 0;
	    }
	    put_empobj(cargo_type, obj.gen.uid, &obj);
	    n++;
	}
    }
    return n;
}
Exemplo n.º 10
0
int
scra(void)
{
    struct nstr_item ni;
    union empobj_storage item;
    int type, n;
    struct sctstr sect;
    struct mchrstr *mp;
    struct plchrstr *pp;
    struct lchrstr *lp;
    char *p;
    i_type i;
    char prompt[128];
    char buf[1024];
    float eff;
    short *mvec;
    int amt;

    if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
	return RET_SYN;
    switch (*p) {
    case 's':
	type = EF_SHIP;
	break;
    case 'p':
	type = EF_PLANE;
	break;
    case 'l':
	type = EF_LAND;
	break;
    default:
	pr("Ships, land units, or planes only! (s, l, p)\n");
	return RET_SYN;
    }

    if (!snxtitem(&ni, type, player->argp[2], NULL))
	return RET_SYN;
    n = 0;
    while (nxtitem(&ni, &item)) {
	if (!player->owner)
	    continue;
	n++;
    }
    snprintf(prompt, sizeof(prompt), "Really scrap %d %s%s [n]? ",
			    n, ef_nameof(type), splur(n));
    if (!confirm(prompt))
	return RET_FAIL;

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

	if (opt_MARKET) {
	    if (ontradingblock(type, &item.ship)) {
		pr("You cannot scrap an item on the trading block!\n");
		continue;
	    }
	}

	getsect(item.gen.x, item.gen.y, &sect);
	if (type == EF_SHIP) {
	    if (!player->owner
		&& relations_with(sect.sct_own, player->cnum) < FRIENDLY) {
		pr("%s is not in a friendly harbor!\n",
		   prship(&item.ship));
		continue;
	    }
	    if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60) {
		pr("%s is not in a 60%% efficient harbor!\n",
		   prship(&item.ship));
		continue;
	    }
	    if (mchr[item.ship.shp_type].m_flags & M_TRADE) {
		pr("WARNING: You only collect money from trade ships if you \"scuttle\" them!\n");
		sprintf(prompt,
			"Are you really sure that you want to scrap %s (n)? ",
			prship(&item.ship));
		if (!confirm(prompt)) {
		    pr("%s not scrapped\n", prship(&item.ship));
		    continue;
		}
	    }
	} else {
	    if (!player->owner
		&& relations_with(sect.sct_own, player->cnum) != ALLIED) {
		pr("%s is not in an allied sector!\n",
		   unit_nameof(&item.gen));
		continue;
	    }
	    if (type == EF_PLANE
		&& (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)) {
		pr("%s is not in a 60%% efficient airfield!\n",
		   prplane(&item.plane));
		continue;
	    }
	}

	pr("%s scrapped in %s\n",
	   unit_nameof(&item.gen),
	   xyas(item.gen.x, item.gen.y, player->cnum));
	unit_drop_cargo(&item.gen, sect.sct_own);
	if (type == EF_SHIP) {
	    eff = item.ship.shp_effic / 100.0;
	    mp = &mchr[(int)item.ship.shp_type];
	    for (i = I_NONE + 1; i <= I_MAX; i++) {
		if (load_comm_ok(&sect, item.ship.shp_own, i,
				 -item.ship.shp_item[i]))
		    sect.sct_item[i] += item.ship.shp_item[i];
	    }
	    mvec = mp->m_mat;
	    if (item.ship.shp_pstage == PLG_INFECT
		&& sect.sct_pstage == PLG_HEALTHY)
		sect.sct_pstage = PLG_EXPOSED;
	} else if (type == EF_LAND) {
	    eff = item.land.lnd_effic / 100.0;
	    lp = &lchr[(int)item.land.lnd_type];
	    for (i = I_NONE + 1; i <= I_MAX; i++) {
		if (load_comm_ok(&sect, item.land.lnd_own, i,
				 -item.land.lnd_item[i]))
		    sect.sct_item[i] += item.land.lnd_item[i];
	    }
	    mvec = lp->l_mat;
	    if (item.land.lnd_pstage == PLG_INFECT
		&& sect.sct_pstage == PLG_HEALTHY)
		sect.sct_pstage = PLG_EXPOSED;
	} else {
	    eff = item.land.lnd_effic / 100.0;
	    pp = &plchr[(int)item.plane.pln_type];
	    mvec = pp->pl_mat;
	}
	item.gen.effic = 0;
	put_empobj(type, item.gen.uid, &item.gen);
	for (i = I_NONE + 1; i <= I_MAX; i++) {
	    if (i == I_CIVIL || i == I_MILIT || i == I_UW)
		amt = sect.sct_item[i] + mvec[i] * eff;
	    else
		amt = sect.sct_item[i] + mvec[i] * 2 / 3 * eff;
	    if (amt > ITEM_MAX)
		amt = ITEM_MAX;
	    sect.sct_item[i] = amt;
	}
	putsect(&sect);
    }
    return RET_OK;
}
Exemplo n.º 11
0
int
unit_move(struct emp_qelem *list)
{
    struct empobj *leader = get_leader(list);
    int leader_uid = leader->uid;
    int type = leader->ef_type;
    int moved, suppress_map, dir, stopping;
    char *cp;
    char path[1024];

    unit_rad_map_set(list);

    pr("%s is %s\n",
	type == EF_SHIP ? "Flagship" : "Leader",
	unit_nameof(leader));

    cp = "";
    if (player->argp[2]) {
	strcpy(path, player->argp[2]);
	cp = unit_move_route(leader, path, sizeof(path));
	if (!cp)
	    cp = "";
    }

    moved = suppress_map = 0;
    for (;;) {
	/*
	 * Invariants:
	 * - shp_may_nav() true for all ships
	 * - lnd_may_mar() true for all land units
	 * - leader is up-to-date
	 * Implies all are in the same sector
	 */
	if (!*cp) {
	    cp = unit_move_getpath(list, suppress_map, path);
	    if (!cp) {
		if (type == EF_SHIP) {
		    shp_nav_stay_behind(list, player->cnum);
		    shp_nav_put(list, player->cnum);
		} else {
		    lnd_mar_stay_behind(list, player->cnum);
		    lnd_mar_put(list, player->cnum);
		}
		return RET_FAIL;
	    }
	    cp = unit_move_route(leader, path, sizeof(path));
	    if (!cp || !*cp)
		cp = "h";
	    suppress_map = 0;
	} else if ((dir = chkdir(*cp, DIR_STOP, DIR_LAST)) >= 0) {
	    cp++;
	    if (type == EF_SHIP)
		stopping = shp_nav_dir(list, dir, player->cnum)
		    || shp_nav_gauntlet(list, 1, player->cnum);
	    else {
		if (!moved && !lnd_abandon_askyn(list)) {
		    lnd_mar_put(list, player->cnum);
		    return RET_FAIL;
		}
		stopping = lnd_mar_dir(list, dir, player->cnum)
		    || lnd_mar_gauntlet(list, 1, player->cnum);
	    }
	    if (dir == DIR_STOP) {
		CANT_HAPPEN(!QEMPTY(list));
		return RET_OK;
	    }
	    moved = 1;
	    if (stopping)
		cp = "";
	} else {
	    cp = unit_move_non_dir(list, cp, &suppress_map);
	    if (!cp) {
		direrr("`%c' to stop", ", `%c' to view", NULL);
		pr(", `i' to list %s, `f' to change %s,\n",
		   type == EF_SHIP ? "ships" : "units",
		   type == EF_SHIP ? "flagship" : "leader");
		pr("`r' to radar, %s`l' to look, `M' to map, `B' to bmap,\n",
		   type == EF_SHIP ? "`s' to sonar, " : "");
		pr("`d' to drop mines, and `m' to minesweep\n");
		cp = "";
	    }
	}

	if (type == EF_SHIP)
	    shp_nav_stay_behind(list, player->cnum);
	else
	    lnd_mar_stay_behind(list, player->cnum);

	if (QEMPTY(list)) {
	    pr("No %s left\n", type == EF_SHIP ? "ships" : "lands");
	    return RET_OK;
	}

	leader = get_leader(list);
	if (leader->uid != leader_uid) {
	    leader_uid = leader->uid;
	    pr("Changing %s to %s\n",
	       leader->ef_type == EF_SHIP ? "flagship" : "leader",
	       unit_nameof(leader));
	}
	unit_rad_map_set(list);
    }
}