src/hcode/btech/econ_cmds.c

Go to the documentation of this file.
00001 /*
00002  * Author: Markus Stenberg <fingon@iki.fi>
00003  *
00004  *  Copyright (c) 1996 Markus Stenberg
00005  *  Copyright (c) 1998-2002 Thomas Wouters
00006  *  Copyright (c) 2000-2002 Cord Awtry
00007  *  Copyright (c) 1999-2005 Kevin Stevens
00008  *       All rights reserved
00009  *
00010  */
00011 
00012 /* This is the place for
00013    - loadcargo
00014    - unloadcargo
00015    - manifest
00016    - stores
00017  */
00018 
00019 #include <stdio.h>
00020 #include "mech.h"
00021 #include "coolmenu.h"
00022 #include "math.h"
00023 #include "mech.partnames.h"
00024 #include "p.aero.bomb.h"
00025 #include "p.econ.h"
00026 #include "p.mech.partnames.h"
00027 #include "p.crit.h"
00028 #include "p.mech.status.h"
00029 #include "p.mech.utils.h"
00030 
00031 #ifdef BT_PART_WEIGHTS
00032 /* From template.c */
00033 
00034 extern int internalsweight[];
00035 extern int cargoweight[];
00036 #endif /* BT_PART_WEIGHTS */
00037 
00038 /* Also sets the fuel we have ; but I digress */
00039 
00040 void SetCargoWeight(MECH * mech)
00041 {
00042         int pile[NUM_ITEMS];
00043         int sw, weight = 0;                     /* in 1/10 tons */
00044         int i, j, k;
00045         char *t;
00046         int i1, i2, i3;
00047 
00048         t = silly_atr_get(mech->mynum, A_ECONPARTS);
00049         bzero(pile, sizeof(pile));
00050         while (*t) {
00051                 if(*t == '[')
00052                         if((sscanf(t, "[%d,%d,%d]", &i1, &i2, &i3)) == 3)
00053                                 pile[i1] += ((IsBomb(i1)) ? 4 : 1) * i3;
00054                 t++;
00055         }
00056         if(FlyingT(mech))
00057                 for(i = 0; i < NUM_SECTIONS; i++)
00058                         for(j = 0; j < NUM_CRITICALS; j++) {
00059                                 if(IsBomb((k = GetPartType(mech, i, j))))
00060                                         pile[k]++;
00061                                 else if(IsSpecial(k))
00062                                         if(Special2I(k) == FUELTANK)
00063                                                 pile[I2Special(FUELTANK)]++;
00064                         }
00065         /* We've 'so-called' pile now */
00066         for(i = 0; i < NUM_ITEMS; i++)
00067                 if(pile[i]) {
00068                         sw = GetPartWeight(i);
00069                         weight += sw * pile[i];
00070                 }
00071         if(FlyingT(mech)) {
00072                 AeroFuelMax(mech) =
00073                         AeroFuelOrig(mech) + 2000 * pile[I2Special(FUELTANK)];
00074                 if(AeroFuel(mech) > AeroFuelOrig(mech))
00075                         weight += AeroFuel(mech) - AeroFuelOrig(mech);
00076         }
00077         SetCarriedCargo(mech, weight);
00078 }
00079 
00080 /* Returns 1 if calling function should return */
00081 
00082 int loading_bay_whine(dbref player, dbref cargobay, MECH * mech)
00083 {
00084         char *c;
00085         int i1, i2, i3 = 0;
00086 
00087         c = silly_atr_get(cargobay, A_MECHSKILLS);
00088         if(c && *c)
00089                 if(sscanf(c, "%d %d %d", &i1, &i2, &i3) >= 2)
00090                         if(MechX(mech) != i1 || MechY(mech) != i2) {
00091                                 notify(player, "You're not where the cargo is!");
00092                                 if(i3)
00093                                         notify_printf(player,
00094                                                                   "Try looking around %d,%d instead.", i1,
00095                                                                   i2);
00096                                 return 1;
00097                         }
00098         return 0;
00099 }
00100 
00101 void mech_Rfixstuff(dbref player, void *data, char *buffer)
00102 {
00103         int loc = Location(player);
00104         int pile[BRANDCOUNT + 1][NUM_ITEMS];
00105         char *t;
00106         int ol, nl, items = 0, kinds = 0;
00107         int i1, i2, i3, id, brand;
00108 
00109         if(!data)
00110                 loc = atoi(buffer);
00111         bzero(pile, sizeof(pile));
00112         t = silly_atr_get(loc, A_ECONPARTS);
00113         ol = strlen(t);
00114         while (*t) {
00115                 if(*t == '[')
00116                         if((sscanf(t, "[%d,%d,%d]", &i1, &i2, &i3)) == 3)
00117                                 if(!IsCrap(i1))
00118                                         pile[i2][i1] += i3;
00119                 t++;
00120         }
00121         silly_atr_set(loc, A_ECONPARTS, "");
00122         for(id = 0; id < NUM_ITEMS; id++)
00123                 for(brand = 0; brand <= BRANDCOUNT; brand++)
00124                         if(pile[brand][id] > 0 && get_parts_long_name(id, brand)) {
00125                                 econ_change_items(loc, id, brand, pile[brand][id]);
00126                                 kinds++;
00127                                 items += pile[brand][id];
00128                         }
00129         t = silly_atr_get(loc, A_ECONPARTS);
00130         nl = strlen(t);
00131         notify_printf(player,
00132                                   "Fixing done. Original length: %d. New length: %d.", ol,
00133                                   nl);
00134         notify_printf(player, "Items in new: %d. Unique items in new: %d.",
00135                                   items, kinds);
00136 }
00137 
00138 void list_matching(dbref player, char *header, dbref loc, char *buf)
00139 {
00140         int pile[BRANDCOUNT + 1][NUM_ITEMS];
00141         int pile2[BRANDCOUNT + 1][NUM_ITEMS];
00142         char *t, *ch;
00143         int i1, i2, i3, id, brand;
00144         int x, i;
00145 
00146 #ifdef BT_PART_WEIGHTS
00147         char tmpstr[LBUF_SIZE];
00148         int sw = 0;
00149 #endif /* BT_PART_WEIGHTS */
00150         coolmenu *c = NULL;
00151         int found = 0;
00152 
00153         bzero(pile, sizeof(pile));
00154         bzero(pile2, sizeof(pile2));
00155         CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00156         CreateMenuEntry_Simple(&c, header, CM_ONE | CM_CENTER);
00157         CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00158         /* Then, we go on a mad rampage ;-) */
00159         t = silly_atr_get(loc, A_ECONPARTS);
00160         while (*t) {
00161                 if(*t == '[')
00162                         if((sscanf(t, "[%d,%d,%d]", &i1, &i2, &i3)) == 3)
00163                                 pile[i2][i1] += i3;
00164                 t++;
00165         }
00166         i = 0;
00167         if(buf)
00168                 while (find_matching_long_part(buf, &i, &id, &brand))
00169                         pile2[brand][id] = pile[brand][id];
00170         for(i = 0; i < object_count; i++) {
00171                 UNPACK_PART(short_sorted[i]->index, id, brand);
00172                 if((buf && (x = pile2[brand][id])) || ((!buf &&
00173                                                                                                 (x = pile[brand][id])))) {
00174 #ifndef BT_PART_WEIGHTS
00175                         ch = part_name_long(id, brand);
00176 #else
00177                         sw = GetPartWeight(id);
00178                         sprintf(tmpstr, "%s (%.1ft)", part_name_long(id, brand),
00179                                         (sw * x) / 1024.0);
00180                         ch = tmpstr;
00181 #endif /* BT_PART_WEIGHTS */
00182                         if(!ch) {
00183                                 SendError(tprintf
00184                                                   ("#%d in %d encountered odd thing: %d %d/%d's.",
00185                                                    player, loc, pile[brand][id], id, brand));
00186                                 continue;
00187                         }
00188                         /* x = amount of things */
00189                         CreateMenuEntry_Killer(&c, ch, CM_TWO | CM_NUMBER | CM_NOTOG,
00190                                                                    0, x, x);
00191                         found++;
00192                 }
00193         }
00194         if(!found)
00195                 CreateMenuEntry_Simple(&c, "None", CM_ONE);
00196         CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00197         ShowCoolMenu(player, c);
00198         KillCoolMenu(c);
00199 }
00200 
00201 #define MY_DO_LIST(t) \
00202 if (*buffer) \
00203   list_matching(player, tprintf("Part listing for %s matching %s", Name(t), buffer), t, buffer); \
00204 else \
00205   list_matching(player, tprintf("Part listing for %s", Name(t)), t, NULL)
00206 
00207 void mech_manifest(dbref player, void *data, char *buffer)
00208 {
00209         while (isspace(*buffer))
00210                 buffer++;
00211         MY_DO_LIST(Location(player));
00212 }
00213 
00214 void mech_stores(dbref player, void *data, char *buffer)
00215 {
00216         MECH *mech = (MECH *) data;
00217 
00218         cch(MECH_USUAL);
00219         DOCHECK(Location(mech->mynum) != mech->mapindex ||
00220                         In_Character(Location(mech->mynum)),
00221                         "You aren't inside a hangar!");
00222         if(loading_bay_whine(player, Location(mech->mynum), mech))
00223                 return;
00224         while (isspace(*buffer))
00225                 buffer++;
00226         MY_DO_LIST(Location(mech->mynum));
00227 }
00228 
00229 #ifdef ECON_ALLOW_MULTIPLE_LOAD_UNLOAD
00230 #define silly_search(func) \
00231   if (!count) {  \
00232     i = -1 ; while (func(args[0], &i, &id, &brand)) \
00233       count++; \
00234     if (count > 0) sfun = func; }
00235 #else
00236 #define silly_search(func) \
00237   if (!count) {  \
00238     i = -1 ; while (func(args[0], &i, &id, &brand)) \
00239       count++; \
00240     DOCHECK(count > 1, "Too many matches!"); \
00241     if (count > 0) sfun = func; }
00242 #endif
00243 
00244 /* Handles adding or removing parts/commods from a map or unit's manifest.
00245  * btaddstores(), addstuff, and removestuff use this.
00246  */
00247 static void stuff_change_sub(dbref player, char *buffer, dbref loc1,
00248                                                          dbref loc2, int mod, int mort)
00249 {
00250         int i = -1, id, brand;
00251         int count = 0;
00252         int argc;
00253         char *args[2];
00254         char *c;
00255         int num;
00256         int (*sfun) (char *, int *i, int *id, int *brand) = NULL;
00257         int foo = 0;
00258 
00259         argc = mech_parseattributes(buffer, args, 2);
00260         DOCHECK(argc < 2, "Invalid number of arguments!");
00261 
00262         /* 
00263          * If we hit the max amount of parts addable at once, set quantity
00264          * to add to max.
00265          */
00266         num = atoi(args[1]);
00267         if(num > ADDSTORES_MAX) {
00268                 num = ADDSTORES_MAX;
00269         }
00270 
00271         DOCHECK(num <= 0, "Invalid amount!");
00272         silly_search(find_matching_short_part);
00273         silly_search(find_matching_vlong_part);
00274         silly_search(find_matching_long_part);
00275         DOCHECK(count == 0, tprintf("Nothing matches '%s'!", args[0]));
00276         DOCHECK(!mort && count > 20 &&
00277                         player != GOD,
00278                         tprintf
00279                         ("Wizards can't add more than 20 different objtypes at a time. ('%s' matches: %d)",
00280                          args[0], count));
00281         if(mort) {
00282                 DOCHECK(Location(player) != loc1, "You ain't in your 'mech!");
00283                 DOCHECK(Location(loc1) != loc2, "You ain't in hangar!");
00284         }
00285         i = -1;
00286 #define MY_ECON_MODIFY(loc,num) \
00287       econ_change_items(loc, id, brand, num); \
00288       SendEcon(tprintf("#%d %s %d %s %s #%d.", \
00289                             player, num>0 ? "added": "removed",  \
00290                             abs(num), (c=get_parts_long_name(id,brand)), \
00291                             num>0 ? "to": "from", \
00292                             loc))
00293         while (sfun(args[0], &i, &id, &brand)) {
00294                 if(mort) {
00295                         if(mod < 0)
00296                                 count = MIN(num, econ_find_items(loc1, id, brand));
00297                         else
00298                                 count = MIN(num, econ_find_items(loc2, id, brand));
00299                 } else
00300                         count = num;
00301                 foo += count;
00302                 if(!count)
00303                         continue;
00304                 MY_ECON_MODIFY(loc1, mod * count);
00305                 if(count)
00306                         switch (mort) {
00307                         case 0:
00308                                 notify_printf(player, "You %s %d %s%s.",
00309                                                           mod > 0 ? "add" : "remove", count, c,
00310                                                           count > 1 ? "s" : "");
00311                                 break;
00312                         case 1:
00313                                 MY_ECON_MODIFY(loc2, (0 - mod) * count);
00314                                 notify_printf(player, "You %s %d %s%s.",
00315                                                           mod > 0 ? "load" : "unload", count, c,
00316                                                           count > 1 ? "s" : "");
00317                                 break;
00318                         }
00319         }
00320         DOCHECK(!foo, "Nothing matching that criteria was found!");
00321 }
00322 
00323 void mech_Raddstuff(dbref player, void *data, char *buffer)
00324 {
00325         stuff_change_sub(player, buffer, Location(player), -1, 1, 0);
00326 }
00327 
00328 void mech_Rremovestuff(dbref player, void *data, char *buffer)
00329 {
00330         stuff_change_sub(player, buffer, Location(player), -1, -1, 0);
00331 }
00332 
00333 void mech_loadcargo(dbref player, void *data, char *buffer)
00334 {
00335         MECH *mech = (MECH *) data;
00336 
00337         cch(MECH_USUALO);
00338         DOCHECK(!(MechSpecials(mech) & CARGO_TECH),
00339                         "This unit cannot haul cargo!");
00340         DOCHECK(fabs(MechSpeed(mech)) > 0.0, "You're moving too fast!");
00341         DOCHECK(Location(mech->mynum) != mech->mapindex ||
00342                         In_Character(Location(mech->mynum)), "You aren't inside hangar!");
00343         if(loading_bay_whine(player, Location(mech->mynum), mech))
00344                 return;
00345         stuff_change_sub(player, buffer, mech->mynum, mech->mapindex, 1, 1);
00346         correct_speed(mech);
00347 }
00348 
00349 void mech_unloadcargo(dbref player, void *data, char *buffer)
00350 {
00351         MECH *mech = (MECH *) data;
00352 
00353         cch(MECH_USUALSO);
00354         DOCHECK(!(MechSpecials(mech) & CARGO_TECH),
00355                         "This unit cannot haul cargo!");
00356         stuff_change_sub(player, buffer, mech->mynum, mech->mapindex, -1, 1);
00357         correct_speed(mech);
00358 }
00359 
00360 void mech_Rresetstuff(dbref player, void *data, char *buffer)
00361 {
00362         notify(player, "Inventory cleaned!");
00363         silly_atr_set(Location(player), A_ECONPARTS, "");
00364         SendEcon(tprintf("#%d reset #%d's stuff.", player, Location(player)));
00365 }

Generated on Mon May 28 04:25:21 2007 for BattletechMUX by  doxygen 1.4.7