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; }
/* * 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); } }
/* * 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); } } }
static void takeover_unit(struct empobj *unit, natid newown) { struct shpstr *sp; struct plnstr *pp; struct lndstr *lp; struct nukstr *np; int type; struct nstr_item ni; union empobj_storage cargo; unit->own = newown; if (opt_MARKET) trdswitchown(unit->ef_type, unit, newown); unit_wipe_orders(unit); switch (unit->ef_type) { case EF_SHIP: sp = (struct shpstr *)unit; sp->shp_off = 1; break; case EF_PLANE: pp = (struct plnstr *)unit; if (pp->pln_mobil > 0) pp->pln_mobil = 0; pp->pln_off = 1; break; case EF_LAND: lp = (struct lndstr *)unit; if (lp->lnd_mobil > 0) lp->lnd_mobil = 0; lp->lnd_off = 1; lp->lnd_harden = 0; break; case EF_NUKE: np = (struct nukstr *)unit; np->nuk_off = 1; break; default: CANT_REACH(); } 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)) { if (cargo.gen.own == newown) continue; if (type == EF_PLANE) cargo.plane.pln_effic = PLANE_MINEFF; takeover_unit(&cargo.gen, newown); } } }
/* * 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; }
/* * Describe an item up for sale. "tgp" is a union containing * the details of the generic item. * Return 1 on success, 0 on error */ int trade_desc(struct empobj *tgp) { i_type it; struct sctstr sect; struct nukstr *np; struct shpstr *sp; struct plnstr *pp; struct lndstr *lp; struct nstr_item ni; struct plnstr plane; struct lndstr land; struct nukstr nuke; switch (tgp->ef_type) { case EF_NUKE: np = (struct nukstr *)tgp; pr("(%3d) tech %d %d%% %s #%d", np->nuk_own, np->nuk_tech, np->nuk_effic, nchr[(int)np->nuk_type].n_name, np->nuk_uid); break; case EF_SHIP: sp = (struct shpstr *)tgp; pr("(%3d) tech %d %d%% %s [", sp->shp_own, sp->shp_tech, sp->shp_effic, prship(sp)); for (it = I_NONE + 1; it <= I_MAX; ++it) { if (sp->shp_item[it]) pr("%c:%d ", ichr[it].i_mnem, sp->shp_item[it]); } pr("] #%d", sp->shp_uid); snxtitem_cargo(&ni, EF_PLANE, EF_SHIP, sp->shp_uid); while (nxtitem(&ni, &plane)) { pr("\n\t\t\t\t tech %3d %3d%% %s #%d", plane.pln_tech, plane.pln_effic, plchr[(int)plane.pln_type].pl_name, plane.pln_uid); if (getnuke(nuk_on_plane(&plane), &nuke)) pr("(%s)", nchr[nuke.nuk_type].n_name); } snxtitem_cargo(&ni, EF_LAND, EF_SHIP, sp->shp_uid); while (nxtitem(&ni, &land)) { pr("\n\t\t\t\t tech %3d %3d%% %s #%d", land.lnd_tech, land.lnd_effic, lchr[(int)land.lnd_type].l_name, land.lnd_uid); if (pln_first_on_land(&land) >= 0) { snxtitem_cargo(&ni, EF_PLANE, EF_LAND, land.lnd_uid); while (nxtitem(&ni, &plane)) { pr("\n\t\t\t\t tech %3d %3d%% %s #%d", plane.pln_tech, plane.pln_effic, plchr[(int)plane.pln_type].pl_name, plane.pln_uid); if (getnuke(nuk_on_plane(&plane), &nuke)) pr("(%s)", nchr[nuke.nuk_type].n_name); } } } getsect(sp->shp_x, sp->shp_y, §); if (sect.sct_type != SCT_WATER) pr(" in a %s %s", cname(sect.sct_own), dchr[sect.sct_type].d_name); else pr(" at sea"); break; case EF_LAND: lp = (struct lndstr *)tgp; pr("(%3d) tech %d %d%% %s [", lp->lnd_own, lp->lnd_tech, lp->lnd_effic, lchr[(int)lp->lnd_type].l_name); for (it = I_NONE + 1; it <= I_MAX; ++it) { if (lp->lnd_item[it]) pr("%c:%d ", ichr[it].i_mnem, lp->lnd_item[it]); } pr("] #%d", lp->lnd_uid); break; case EF_PLANE: pp = (struct plnstr *)tgp; pr("(%3d) tech %d %d%% %s #%d", pp->pln_own, pp->pln_tech, pp->pln_effic, plchr[(int)pp->pln_type].pl_name, pp->pln_uid); if (getnuke(nuk_on_plane(pp), &nuke)) pr("(%s)", nchr[nuke.nuk_type].n_name); break; default: pr("flaky unit type %d", tgp->uid); break; } return 1; }