]> git.pond.sub.org Git - empserver/blob - src/lib/commands/fuel.c
Remove a bunch of redundant casts.
[empserver] / src / lib / commands / fuel.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2005, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  fuel.c: fuel ships/land units
29  * 
30  *  Known contributors to this file:
31  *     
32  */
33
34 #include "misc.h"
35 #include "player.h"
36 #include "plague.h"
37 #include "xy.h"
38 #include "ship.h"
39 #include "plane.h"
40 #include "land.h"
41 #include "nat.h"
42 #include "nsc.h"
43 #include "file.h"
44 #include "sect.h"
45 #include "optlist.h"
46 #include "commands.h"
47
48
49 union item_u {
50     struct shpstr ship;
51     struct lndstr land;
52 };
53
54 int
55 fuel(void)
56 {
57     struct nstr_item ni;
58     union item_u item, item2;
59     int type;
60     struct mchrstr *mp;
61     struct lchrstr *lcp;
62     s_char *p;
63     int fueled;
64     int land_fuel, ship_fuel;
65     int oil_amt, pet_amt, fuel_amt, tot_fuel, max_amt;
66     int move_amt;
67     float extra;
68     struct sctstr sect;
69     struct natstr *natp;
70     int harbor, sector;
71     int fuelled_ship = -1;
72     struct nstr_item tender, ltender;
73     s_char prompt[128];
74     s_char buf[1024];
75
76     if (opt_FUEL == 0) {
77         pr("Option 'FUEL' not enabled\n");
78         return RET_SYN;
79     }
80     if ((p =
81          getstarg(player->argp[1], "Ship or land unit (s,l)? ", buf)) == 0)
82         return RET_SYN;
83     type = ef_byname(p);
84     if (type == EF_SECTOR)
85         type = EF_SHIP;
86     if (type != EF_SHIP && type != EF_LAND) {
87         pr("Ships or land units only! (s, l)\n");
88         return RET_SYN;
89     }
90     sprintf(prompt, "%s(s)? ", ef_nameof(type));
91     p = getstarg(player->argp[2], prompt, buf);
92     if (!snxtitem(&ni, type, p))
93         return RET_SYN;
94     if (isdigit(*p))
95         fuelled_ship = atoi(p);
96     p = getstarg(player->argp[3], "Amount: ", buf);
97     if (p == 0 || *p == 0)
98         return RET_SYN;
99     fuel_amt = atoi(p);
100     if (fuel_amt <= 0) {
101         pr("Fuel amount must be positive!\n");
102         return RET_FAIL;
103     }
104
105     while (nxtitem(&ni, &item)) {
106         fueled = 0;
107         if (type == EF_SHIP) {
108             if (item.ship.shp_own != player->cnum) {
109                 int rel;
110
111                 if (item.ship.shp_uid != fuelled_ship)
112                     continue;
113                 natp = getnatp(player->cnum);
114                 rel = getrel(natp, item.ship.shp_own);
115                 if (rel < FRIENDLY)
116                     continue;
117             }
118             if (!getsect(item.ship.shp_x, item.ship.shp_y, &sect))
119                 continue;
120             if (!item.ship.shp_own)
121                 continue;
122
123             if ((sect.sct_type != SCT_HARBR)
124                 && (sect.sct_type != SCT_WATER)
125                 && (sect.sct_type != SCT_BSPAN) && (!opt_BIG_CITY
126                                                     || sect.sct_type !=
127                                                     SCT_CAPIT)) {
128                 pr("Sector %s is not a harbor, bridge span, or sea.\n",
129                    xyas(item.ship.shp_x, item.ship.shp_y,
130                         item.ship.shp_own));
131                 continue;
132             }
133
134             mp = &mchr[(int)item.ship.shp_type];
135
136             harbor = 0;
137             if (sect.sct_type == SCT_HARBR
138                 || (opt_BIG_CITY && sect.sct_type == SCT_CAPIT)) {
139                 harbor = 1;
140                 oil_amt = sect.sct_item[I_OIL];
141                 pet_amt = sect.sct_item[I_PETROL];
142                 if ((oil_amt + pet_amt) == 0)
143                     harbor = 0;
144
145                 if (sect.sct_effic < 2) {
146                     pr("The harbor at %s is not 2%% efficient yet.\n",
147                        xyas(item.ship.shp_x,
148                             item.ship.shp_y, player->cnum));
149                     harbor = 0;
150                 }
151                 if ((sect.sct_own != player->cnum) && sect.sct_own)
152                     harbor = 0;
153             }
154
155             if ((mp->m_fuelu == 0) && (item.ship.shp_own == player->cnum)) {
156                 pr("%s does not use fuel!\n", prship(&item.ship));
157                 continue;
158             }
159
160             if (harbor) {
161                 ship_fuel = item.ship.shp_fuel;
162                 oil_amt = sect.sct_item[I_OIL];
163                 pet_amt = sect.sct_item[I_PETROL];
164                 max_amt = mp->m_fuelc - ship_fuel;
165
166                 if (max_amt == 0) {
167                     pr("%s already has a full fuel load.\n",
168                        prship(&item.ship));
169                     continue;
170                 }
171                 tot_fuel = (oil_amt * 50 + pet_amt * 5);
172                 if (tot_fuel == 0) {
173                     pr("No fuel in the harbor at %s!\n",
174                        xyas(sect.sct_x, sect.sct_y, player->cnum));
175                     continue;
176                 }
177                 move_amt = min(tot_fuel, fuel_amt);
178                 move_amt = min(move_amt, max_amt);
179
180                 if (move_amt == 0)
181                     continue;
182
183                 item.ship.shp_fuel += move_amt;
184
185                 fueled = 1;
186                 if ((pet_amt * 5) >= move_amt) {
187                     extra = ((float)move_amt / 5.0) - (move_amt / 5);
188                     if (extra > 0.0)
189                         sect.sct_item[I_PETROL]
190                             = max((pet_amt - move_amt / 5) - 1, 0);
191                     else
192                         sect.sct_item[I_PETROL]
193                             = max((pet_amt - move_amt / 5), 0);
194                 } else {
195                     sect.sct_item[I_PETROL] = 0;
196                     move_amt -= pet_amt * 5;
197                     extra = ((float)move_amt / 50.0) - (move_amt / 50);
198                     sect.sct_item[I_OIL] = max(oil_amt - move_amt / 50, 0);
199                     if (extra > 0.0)
200                         sect.sct_item[I_OIL]
201                             = max((oil_amt - move_amt / 50) - 1, 0);
202                     else
203                         sect.sct_item[I_OIL]
204                             = max((oil_amt - move_amt / 50), 0);
205                 }
206
207                 /* load plague */
208                 if (sect.sct_pstage == PLG_INFECT
209                     && item.ship.shp_pstage == PLG_HEALTHY)
210                     item.ship.shp_pstage = PLG_EXPOSED;
211
212                 putsect(&sect);
213                 putship(item.ship.shp_uid, &item.ship);
214             } else {            /* not in a harbor */
215                 if (!player->argp[4])
216                     pr("%s is not in a supplied, efficient harbor\n",
217                        prship(&item.ship));
218                 if (!snxtitem (&tender, EF_SHIP,
219                                getstarg(player->argp[4], "Oiler? ", buf)))
220                     continue;
221
222                 if (!check_ship_ok(&item.ship))
223                     continue;
224
225                 if (!nxtitem(&tender, &item2))
226                     continue;
227
228                 if (!(mchr[(int)item2.ship.shp_type].m_flags & M_OILER)) {
229                     pr("%s is not an oiler!\n", prship(&item2.ship));
230                     continue;
231                 }
232                 if (item2.ship.shp_own != player->cnum) {
233                     pr("You don't own that oiler!\n");
234                     continue;
235                 }
236
237                 if ((item2.ship.shp_x != item.ship.shp_x) ||
238                     (item2.ship.shp_y != item.ship.shp_y)) {
239                     pr("Not in the same sector!\n");
240                     continue;
241                 }
242                 ship_fuel = item.ship.shp_fuel;
243                 oil_amt = item2.ship.shp_item[I_OIL];
244                 pet_amt = item2.ship.shp_item[I_PETROL];
245                 max_amt = mp->m_fuelc - ship_fuel;
246
247                 if (max_amt == 0) {
248                     pr("%s already has a full fuel load.\n",
249                        prship(&item.ship));
250                     continue;
251                 }
252                 tot_fuel = oil_amt * 50 + pet_amt * 5;
253                 move_amt = min(tot_fuel, fuel_amt);
254                 move_amt = min(move_amt, max_amt);
255
256                 if (move_amt == 0)
257                     continue;
258
259                 item.ship.shp_fuel += move_amt;
260
261                 fueled = 1;
262                 if ((pet_amt * 5) >= move_amt) {
263                     extra = ((float)move_amt / 5.0) - (move_amt / 5);
264                     if (extra > 0.0)
265                         item2.ship.shp_item[I_PETROL]
266                             = max((pet_amt - move_amt / 5) - 1, 0);
267                     else
268                         item2.ship.shp_item[I_PETROL]
269                             = max((pet_amt - move_amt / 5), 0);
270                 } else {
271                     item2.ship.shp_item[I_PETROL] = 0;
272                     move_amt -= pet_amt * 5;
273                     extra = ((float)move_amt / 50.0) - (move_amt / 50);
274                     item2.ship.shp_item[I_OIL]
275                         = max(oil_amt - (move_amt / 50), 0);
276                     if (extra > 0.0)
277                         item2.ship.shp_item[I_OIL]
278                             = max((oil_amt - move_amt / 50) - 1, 0);
279                     else
280                         item2.ship.shp_item[I_OIL]
281                             = max((oil_amt - move_amt / 50), 0);
282                 }
283
284                 /* load plague */
285                 if (item2.ship.shp_pstage == PLG_INFECT
286                     && item.ship.shp_pstage == PLG_HEALTHY)
287                     item.ship.shp_pstage = PLG_EXPOSED;
288
289                 putship(item.ship.shp_uid, &item.ship);
290                 /* quick hack -KHS */
291                 if (item.ship.shp_uid == item2.ship.shp_uid)
292                     item2.ship.shp_fuel = item.ship.shp_fuel;
293                 putship(item2.ship.shp_uid, &item2.ship);
294             }
295             pr("%s", prship(&item.ship));
296         } else {
297             if (item.land.lnd_own != player->cnum)
298                 continue;
299
300             if (!getsect(item.land.lnd_x, item.land.lnd_y, &sect))
301                 continue;
302
303             if (!player->owner)
304                 continue;
305
306             lcp = &lchr[(int)item.land.lnd_type];
307
308             sector = 1;
309             oil_amt = sect.sct_item[I_OIL];
310             pet_amt = sect.sct_item[I_PETROL];
311
312             if ((oil_amt + pet_amt) == 0)
313                 sector = 0;
314
315             if ((item.land.lnd_fuelu == 0)
316                 && (item.land.lnd_own == player->cnum)) {
317                 pr("%s does not use fuel!\n", prland(&item.land));
318                 continue;
319             }
320
321             if (sector) {
322                 land_fuel = item.land.lnd_fuel;
323                 oil_amt = sect.sct_item[I_OIL];
324                 pet_amt = sect.sct_item[I_PETROL];
325                 max_amt = item.land.lnd_fuelc - land_fuel;
326
327                 if (max_amt == 0) {
328                     pr("%s already has a full fuel load.\n",
329                        prland(&item.land));
330                     continue;
331                 }
332                 tot_fuel = (oil_amt * 50 + pet_amt * 5);
333                 if (tot_fuel == 0) {
334                     pr("No fuel in the sector at %s!\n",
335                        xyas(sect.sct_x, sect.sct_y, player->cnum));
336                     continue;
337                 }
338                 move_amt = min(tot_fuel, fuel_amt);
339                 move_amt = min(move_amt, max_amt);
340
341                 if (move_amt == 0)
342                     continue;
343
344                 item.land.lnd_fuel += move_amt;
345
346                 fueled = 1;
347                 if ((pet_amt * 5) >= move_amt) {
348                     extra = ((float)move_amt / 5.0) - (move_amt / 5);
349                     if (extra > 0.0)
350                         sect.sct_item[I_PETROL]
351                             = max((pet_amt - move_amt / 5) - 1, 0);
352                     else
353                         sect.sct_item[I_PETROL]
354                             = max((pet_amt - move_amt / 5), 0);
355                 } else {
356                     sect.sct_item[I_PETROL] = 0;
357                     move_amt -= pet_amt * 5;
358                     extra = ((float)move_amt / 50.0) - (move_amt / 50);
359                     sect.sct_item[I_OIL] = max(oil_amt - move_amt / 50, 0);
360                     if (extra > 0.0)
361                         sect.sct_item[I_OIL]
362                             = max((oil_amt - move_amt / 50) - 1, 0);
363                     else
364                         sect.sct_item[I_OIL]
365                             = max((oil_amt - move_amt / 50), 0);
366                 }
367
368                 /* load plague */
369                 if (sect.sct_pstage == PLG_INFECT
370                     && item.land.lnd_pstage == PLG_HEALTHY)
371                     item.land.lnd_pstage = PLG_EXPOSED;
372
373                 putsect(&sect);
374                 putland(item.land.lnd_uid, &item.land);
375             } else {            /* not in a sector */
376                 if (!player->argp[4])
377                     pr("%s is not in a supplied sector\n",
378                        prland(&item.land));
379                 if (!snxtitem(&ltender, EF_LAND,
380                               getstarg(player->argp[4], "Supply unit? ",
381                                        buf)))
382                     continue;
383
384                 if (!check_land_ok(&item.land))
385                     continue;
386
387                 if (!nxtitem(&ltender, &item2))
388                     continue;
389
390                 if (!(lchr[(int)item2.land.lnd_type].l_flags & L_SUPPLY)) {
391                     pr("%s is not a supply unit!\n", prland(&item2.land));
392                     continue;
393                 }
394                 if (item2.land.lnd_own != player->cnum) {
395                     pr("You don't own that unit!\n");
396                     continue;
397                 }
398
399                 if ((item2.land.lnd_x != item.land.lnd_x) ||
400                     (item2.land.lnd_y != item.land.lnd_y)) {
401                     pr("Not in the same sector!\n");
402                     continue;
403                 }
404                 land_fuel = item.land.lnd_fuel;
405                 oil_amt = item2.land.lnd_item[I_OIL];
406                 pet_amt = item2.land.lnd_item[I_PETROL];
407                 max_amt = item.land.lnd_fuelc - land_fuel;
408
409                 if (max_amt == 0) {
410                     pr("%s already has a full fuel load.\n",
411                        prland(&item.land));
412                     continue;
413                 }
414                 tot_fuel = oil_amt * 50 + pet_amt * 5;
415                 move_amt = min(tot_fuel, fuel_amt);
416                 move_amt = min(move_amt, max_amt);
417
418                 if (move_amt == 0)
419                     continue;
420
421                 item.land.lnd_fuel += move_amt;
422
423                 fueled = 1;
424                 if ((pet_amt * 5) >= move_amt) {
425                     extra = ((float)move_amt / 5.0) - (move_amt / 5);
426                     if (extra > 0.0)
427                         item2.land.lnd_item[I_PETROL]
428                             = max((pet_amt - move_amt / 5) - 1, 0);
429                     else
430                         item2.land.lnd_item[I_PETROL]
431                             = max((pet_amt - move_amt / 5), 0);
432                 } else {
433                     item2.land.lnd_item[I_PETROL] = 0;
434                     move_amt -= pet_amt * 5;
435                     extra = ((float)move_amt / 50.0) - (move_amt / 50);
436                     item2.land.lnd_item[I_OIL]
437                         = max(oil_amt - move_amt / 50, 0);
438                     if (extra > 0.0)
439                         item2.land.lnd_item[I_OIL]
440                             = max((oil_amt - move_amt / 50) - 1, 0);
441                     else
442                         item2.land.lnd_item[I_OIL]
443                             = max((oil_amt - move_amt / 50), 0);
444                 }
445
446                 /* load plague */
447                 if (item2.land.lnd_pstage == PLG_INFECT
448                     && item.land.lnd_pstage == PLG_HEALTHY)
449                     item.land.lnd_pstage = PLG_EXPOSED;
450
451                 putland(item.land.lnd_uid, &item.land);
452                 /* quick hack -KHS */
453                 if (item2.land.lnd_uid == item.land.lnd_uid)
454                     item2.land.lnd_fuel = item.land.lnd_fuel;
455                 putland(item2.land.lnd_uid, &item2.land);
456             }
457             pr("%s", prland(&item.land));
458         }
459         if (fueled) {
460             pr(" takes on %d fuel in %s\n",
461                move_amt,
462                xyas(item.ship.shp_x, item.ship.shp_y, player->cnum));
463             if (player->cnum != item.ship.shp_own)
464                 wu(0, item.ship.shp_own,
465                    "%s takes on %d fuel in %s courtesy of %s\n",
466                    prship(&item.ship),
467                    move_amt,
468                    xyas(item.ship.shp_x, item.ship.shp_y,
469                         item.ship.shp_own), cname(player->cnum));
470         }
471     }
472     return RET_OK;
473 }