00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <config.h>
00037
00038 #include "commands.h"
00039 #include "commodity.h"
00040 #include "item.h"
00041 #include "land.h"
00042 #include "loan.h"
00043 #include "news.h"
00044 #include "optlist.h"
00045 #include "plane.h"
00046 #include "ship.h"
00047 #include "trade.h"
00048
00049
00050
00051
00052
00053 int
00054 buy(void)
00055 {
00056 struct sctstr sect;
00057 struct natstr *natp;
00058 struct comstr comm;
00059 struct comstr ncomm;
00060 struct comstr comt;
00061 struct trdstr tmpt;
00062 struct ichrstr *ip;
00063 int qty;
00064 int o, n, q;
00065 coord x, y;
00066 char *p;
00067 float bid;
00068 time_t now;
00069 double tally;
00070 double canspend;
00071 char buf[1024];
00072
00073 if (!opt_MARKET) {
00074 pr("The market is disabled.\n");
00075 return RET_FAIL;
00076 }
00077 natp = getnatp(player->cnum);
00078 ip = whatitem(player->argp[1], "Commodity you want to buy: ");
00079 if (!ip)
00080 return RET_SYN;
00081 display_mark(ip->i_uid, 0);
00082 pr("\n");
00083 p = getstarg(player->argp[2], "Which lot are you bidding on: ", buf);
00084 if (p == 0)
00085 return RET_SYN;
00086 if (*p == 0)
00087 return RET_SYN;
00088 o = atoi(p);
00089 if (o < 0)
00090 return RET_SYN;
00091 if (!getcomm(o, &comm) || comm.com_owner == 0) {
00092 pr("Invalid lot number.\n");
00093 return RET_OK;
00094 }
00095 if (comm.com_type != ip->i_uid) {
00096 pr("That lot is not of the type you specified.\n");
00097 return RET_OK;
00098 }
00099 if (comm.com_owner == player->cnum) {
00100 pr("You can't bid on your own lot.\n");
00101 return RET_OK;
00102 }
00103 if ((p = getstarg(player->argp[3], "How much per unit: ", buf)) == 0)
00104 return RET_SYN;
00105 bid = atof(p);
00106 if (bid <= 0)
00107 return RET_FAIL;
00108 if (natp->nat_money < bid * comm.com_amount * buytax) {
00109 pr("This purchase would cost %.2f, %.2f more than you have.\n",
00110 bid * comm.com_amount * buytax,
00111 bid * comm.com_amount * buytax - natp->nat_money);
00112 return RET_FAIL;
00113 }
00114
00115
00116
00117 tally = 0.0;
00118 for (q = 0; gettrade(q, &tmpt); q++) {
00119 if (tmpt.trd_maxbidder == player->cnum &&
00120 tmpt.trd_unitid >= 0 && tmpt.trd_owner != player->cnum) {
00121 tally += tmpt.trd_price * tradetax;
00122 }
00123 }
00124 for (q = 0; getcomm(q, &comt); q++) {
00125 if (comt.com_maxbidder == player->cnum &&
00126 comt.com_owner != 0 && comt.com_owner != player->cnum) {
00127 tally += comt.com_price * comt.com_amount * buytax;
00128 }
00129 }
00130 canspend = natp->nat_money - tally;
00131 getcomm(o, &comm);
00132 if (bid * comm.com_amount * buytax > canspend) {
00133 pr("You have overextended yourself in the market\n");
00134 pr("You can not bid on the current items at that price.\n");
00135 return RET_OK;
00136 }
00137 if (!(p = getstarg(player->argp[4], "destination sector : ", buf)))
00138 return RET_SYN;
00139 if (!sarg_xy(p, &x, &y))
00140 return RET_SYN;
00141 if (!getsect(x, y, §)) {
00142 pr("Could not access sector");
00143 return RET_FAIL;
00144 }
00145 if ((sect.sct_type != SCT_WAREH && sect.sct_type != SCT_HARBR) ||
00146 sect.sct_own != player->cnum) {
00147 pr("The destination sector is not one of your warehouses.\n");
00148 return RET_FAIL;
00149 }
00150 if (sect.sct_effic < 60) {
00151 pr("That sector is under construction.\n");
00152 return RET_FAIL;
00153 }
00154 n = sect.sct_item[ip->i_uid];
00155 qty = comm.com_amount;
00156 if (qty + n > ITEM_MAX) {
00157 pr("That sector cannot hold %d more %s. It currently holds %d.\n",
00158 qty, ip->i_name, n);
00159 return RET_FAIL;
00160 }
00161 if (bid * comm.com_amount > natp->nat_money) {
00162 pr("You don't have that much to spend!\n");
00163 return RET_FAIL;
00164 }
00165 getcomm(o, &ncomm);
00166 if (!ncomm.com_owner) {
00167 pr("That lot has been taken off the market.\n");
00168 return RET_FAIL;
00169 }
00170 if (bid > 0.04 + comm.com_price) {
00171 comm.com_price = bid;
00172
00173 time(&now);
00174 if (((MARK_DELAY - (now - comm.com_markettime)) < 300) &&
00175 comm.com_maxbidder != player->cnum) {
00176 comm.com_markettime += 300;
00177
00178
00179 if ((MARK_DELAY - (now - comm.com_markettime)) < 0)
00180 comm.com_markettime = (now - (MARK_DELAY - 300));
00181 }
00182 comm.com_maxbidder = player->cnum;
00183 comm.com_x = x;
00184 comm.com_y = y;
00185 putcomm(o, &comm);
00186 pr("Your bid is being considered.\n");
00187 } else {
00188 pr("Your bid wasn't high enough (you need to bid at least $0.05 higher\n");
00189 pr("than the last bid.\n");
00190 return RET_OK;
00191 }
00192
00193 check_market();
00194
00195 return RET_OK;
00196 }
00197
00198 int
00199 check_market(void)
00200 {
00201 struct comstr comm;
00202 struct sctstr *sect;
00203 struct natstr *natp;
00204 int m;
00205 int n;
00206 time_t now;
00207 double tleft;
00208 double gain;
00209 double price;
00210
00211
00212 for (n = 0; getcomm(n, &comm); n++) {
00213 if (comm.com_maxbidder == comm.com_owner || comm.com_owner == 0)
00214 continue;
00215 (void)time(&now);
00216 tleft = MARK_DELAY / 3600.0 - (now - comm.com_markettime) / 3600.0;
00217 if (tleft < 0)
00218 tleft = 0;
00219 if (tleft > 0.0)
00220 continue;
00221 if (CANT_HAPPEN(comm.com_type <= I_NONE || comm.com_type > I_MAX))
00222 continue;
00223 sect = getsectp(comm.com_x, comm.com_y);
00224 m = sect->sct_item[comm.com_type];
00225
00226 price = comm.com_price * comm.com_amount * buytax;
00227 gain = comm.com_price * comm.com_amount;
00228
00229 natp = getnatp(comm.com_maxbidder);
00230 if (natp->nat_money < price) {
00231 nreport(comm.com_maxbidder, N_WELCH_DEAL, comm.com_owner, 1);
00232 wu(0, comm.com_maxbidder,
00233 "You didn't have enough cash to cover the cost.\n");
00234 wu(0, comm.com_owner,
00235 "Sale #%d fell through. Goods remain on the market.\n", n);
00236 comm.com_maxbidder = comm.com_owner;
00237 } else if (sect->sct_type != SCT_WAREH
00238 && sect->sct_type != SCT_HARBR) {
00239 wu(0, comm.com_maxbidder,
00240 "Sector not a warehouse now, sale #%d fell though.\n", n);
00241 wu(0, comm.com_owner,
00242 "Sale #%d fell through. Goods remain on the market.\n", n);
00243 comm.com_maxbidder = comm.com_owner;
00244 } else if (m + comm.com_amount > ITEM_MAX) {
00245 wu(0, comm.com_maxbidder,
00246 "Warehouse full, sale #%d fell though.\n", n);
00247 wu(0, comm.com_owner,
00248 "Sale #%d fell through. Goods remain on the market.\n", n);
00249 comm.com_maxbidder = comm.com_owner;
00250 } else {
00251 sect->sct_item[comm.com_type] = m + comm.com_amount;
00252 putsect(sect);
00253 nreport(comm.com_owner, N_MAKE_SALE, comm.com_maxbidder, 1);
00254 wu(0, comm.com_owner, "%s bought %d %s from you for $%.2f\n",
00255 cname(comm.com_maxbidder), comm.com_amount,
00256 ichr[comm.com_type].i_name, gain);
00257 wu(0, comm.com_maxbidder,
00258 "You just bought %d %s from %s for $%.2f\n",
00259 comm.com_amount, ichr[comm.com_type].i_name,
00260 cname(comm.com_owner), price);
00261 natp->nat_money -= roundavg(price);
00262 putnat(natp);
00263 natp = getnatp(comm.com_owner);
00264 natp->nat_money += roundavg(gain);
00265 putnat(natp);
00266 comm.com_owner = 0;
00267 }
00268 comm.com_owner = 0;
00269 putcomm(n, &comm);
00270 }
00271
00272 return RET_OK;
00273 }