Beispiel #1
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;
}
Beispiel #2
0
int
check_trade(void)
{
    int n;
    struct natstr *natp;
    struct trdstr trade;
    union empobj_storage tg;
    time_t now;
    int price;
    int saveid;
    natid seller;

    for (n = 0; gettrade(n, &trade); n++) {
	if (trade.trd_unitid < 0)
	    continue;
	if (!trade_getitem(&trade, &tg))
	    continue;
	if (tg.gen.own == 0) {
	    trade.trd_owner = 0;
	    trade.trd_unitid = -1;
	    puttrade(n, &trade);
	    continue;
	}
	if (tg.gen.own != trade.trd_owner) {
	    logerror("Something weird, tg.gen.own != trade.trd_owner!\n");
	    trade.trd_owner = 0;
	    trade.trd_unitid = -1;
	    puttrade(n, &trade);
	    continue;
	}

	if (trade.trd_owner == trade.trd_maxbidder)
	    continue;

	(void)time(&now);
	if (trade.trd_markettime + TRADE_DELAY > now)
	    continue;

	saveid = trade.trd_unitid;
	seller = trade.trd_owner;
	trade.trd_owner = 0;
	trade.trd_unitid = -1;
	if (!puttrade(n, &trade)) {
	    logerror("Couldn't save trade after purchase; get help!\n");
	    continue;
	}

	price = trade.trd_price;
	natp = getnatp(trade.trd_maxbidder);
	if (natp->nat_money < price) {
	    nreport(trade.trd_maxbidder, N_WELCH_DEAL, seller, 1);
	    wu(0, seller,
	       "%s tried to buy a %s #%d from you for $%.2f\n",
	       cname(trade.trd_maxbidder), trade_nameof(&trade, &tg.gen),
	       saveid, price * tradetax);
	    wu(0, seller, "   but couldn't afford it.\n");
	    wu(0, seller,
	       "   Your item was taken off the market.\n");
	    wu(0, trade.trd_maxbidder,
	       "You tried to buy %s #%d from %s for $%d\n",
	       trade_nameof(&trade, &tg.gen), saveid, cname(seller),
	       price);
	    wu(0, trade.trd_maxbidder, "but couldn't afford it.\n");
	    continue;
	}

/* If we get this far, the sale will go through. */

	natp->nat_money -= price;
	putnat(natp);

	natp = getnatp(seller);
	natp->nat_money += roundavg(price * tradetax);
	putnat(natp);

	switch (trade.trd_type) {
	case EF_NUKE:
	    tg.nuke.nuk_x = trade.trd_x;
	    tg.nuke.nuk_y = trade.trd_y;
	    tg.nuke.nuk_plane = -1;
	    break;
	case EF_PLANE:
	    if (!pln_is_in_orbit(&tg.plane)) {
		tg.plane.pln_x = trade.trd_x;
		tg.plane.pln_y = trade.trd_y;
	    }
	    if (opt_MOB_ACCESS) {
		tg.plane.pln_mobil = -(etu_per_update / sect_mob_neg_factor);
		game_tick_to_now(&tg.plane.pln_access);
	    } else {
		tg.plane.pln_mobil = 0;
	    }
	    tg.plane.pln_harden = 0;
	    tg.plane.pln_ship = -1;
	    tg.plane.pln_land = -1;
	    break;
	case EF_SHIP:
	    break;
	case EF_LAND:
	    tg.land.lnd_x = trade.trd_x;
	    tg.land.lnd_y = trade.trd_y;
	    if (opt_MOB_ACCESS) {
		tg.land.lnd_mobil = -(etu_per_update / sect_mob_neg_factor);
		game_tick_to_now(&tg.land.lnd_access);
	    } else {
		tg.land.lnd_mobil = 0;
	    }
	    tg.land.lnd_harden = 0;
	    unit_drop_cargo(&tg.gen, 0);
	    tg.land.lnd_ship = -1;
	    tg.land.lnd_land = -1;
	    break;
	default:
	    logerror("Bad trade type %d in trade\n", trade.trd_type);
	    break;
	}
	unit_give_away(&tg.gen, trade.trd_maxbidder, 0);
	put_empobj(trade.trd_type, saveid, &tg.gen);

	nreport(seller, N_MAKE_SALE, trade.trd_maxbidder, 1);
	wu(0, seller, "%s bought %s #%d from you for $%.2f\n",
	   cname(trade.trd_maxbidder), trade_nameof(&trade, &tg.gen),
	   saveid, price * tradetax);
	wu(0, trade.trd_maxbidder,
	   "The bidding is over & you bought %s #%d from %s for $%d\n",
	   trade_nameof(&trade, &tg.gen), saveid, cname(seller),
	   price);
    }
    return RET_OK;
}