/* * 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, §); if (!military_control(§)) { 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; }
int trade_check_ok(struct trdstr *tp, struct empobj *tgp) { return check_trade_ok(tp) && check_obj_ok(tgp); }
int edit(void) { union empobj_storage item; char *what; struct nstr_item ni; char *key, *ptr; struct natstr *np; int type, arg_index, ret; char buf[1024]; what = getstarg(player->argp[1], "Edit what (country, land, ship, plane, nuke, unit)? ", buf); if (!what) return RET_SYN; switch (what[0]) { case 'l': type = EF_SECTOR; break; case 'p': type = EF_PLANE; break; case 's': type = EF_SHIP; break; case 'u': type = EF_LAND; break; case 'n': type = EF_NUKE; break; case 'c': type = EF_NATION; break; default: pr("huh?\n"); return RET_SYN; } if (!snxtitem(&ni, type, player->argp[2], NULL)) return RET_SYN; while (nxtitem(&ni, &item)) { if (!player->argp[3]) { switch (type) { case EF_SECTOR: print_sect(&item.sect); break; case EF_SHIP: print_ship(&item.ship); break; case EF_PLANE: print_plane(&item.plane); break; case EF_LAND: print_land(&item.land); break; case EF_NUKE: print_nuke(&item.nuke); break; case EF_NATION: print_nat(&item.nat); break; default: CANT_REACH(); } } arg_index = 3; for (;;) { if (player->argp[arg_index]) { if (player->argp[arg_index+1]) { key = player->argp[arg_index++]; ptr = player->argp[arg_index++]; } else return RET_SYN; } else if (arg_index == 3) { key = getin(buf, &ptr); if (!key) return RET_SYN; if (!*key) break; } else break; if (!check_obj_ok(&item.gen)) return RET_FAIL; switch (type) { case EF_NATION: /* * edit_nat() may update the edited country by sending * it bulletins. Writing back item.nat would trigger * a seqno mismatch oops. Workaround: edit in-place. */ np = getnatp(item.nat.nat_cnum); ret = edit_nat(np, key, ptr); if (ret != RET_OK) return ret; if (!putnat(np)) return RET_FAIL; item.nat = *np; continue; case EF_SECTOR: ret = edit_sect(&item.sect, key, ptr); break; case EF_SHIP: ret = edit_ship(&item.ship, key, ptr); break; case EF_LAND: ret = edit_land(&item.land, key, ptr); break; case EF_PLANE: ret = edit_plane(&item.plane, key, ptr); break; case EF_NUKE: ret = edit_nuke(&item.nuke, key, ptr); break; default: CANT_REACH(); } if (ret != RET_OK) return ret; if (!put_empobj(type, item.gen.uid, &item.gen)) return RET_FAIL; } } return RET_OK; }