src/hcode/btech/mech.advanced.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  *       All rights reserved
00008  *
00009  */
00010 
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <math.h>
00014 #include <sys/file.h>
00015 
00016 #include "mech.h"
00017 #include "mech.events.h"
00018 #include "coolmenu.h"
00019 #include "p.mech.ecm.h"
00020 #include "mech.ecm.h"
00021 #include "p.mech.utils.h"
00022 #include "p.mech.update.h"
00023 #include "p.mech.combat.h"
00024 #include "p.mech.damage.h"
00025 #include "p.artillery.h"
00026 #include "p.btechstats.h"
00027 #include "failures.h"
00028 #include "p.crit.h"
00029 #include "p.mech.build.h"
00030 #include "p.mech.hitloc.h"
00031 #include "p.mech.enhanced.criticals.h"
00032 #include "p.mech.combat.misc.h"
00033 
00034 #define SILLY_TOGGLE_MACRO(neededspecial,setstatus,msgon,msgoff,donthave) \
00035 if (MechSpecials(mech) & (neededspecial)) \
00036 { if (MechStatus(mech) & (setstatus)) { mech_notify(mech, MECHALL, msgoff); \
00037 MechStatus(mech) &= ~(setstatus); } else { mech_notify(mech,MECHALL, msgon); \
00038 MechStatus(mech) |= (setstatus); } } else notify(player, donthave)
00039 
00040 #define TOGGLE_SPECIALS_MACRO_CHECK(neededspecial,setstatus,offstatus,msgon,msgoff,donthave) \
00041 if (MechSpecials(mech) & (neededspecial)) \
00042 { if (MechStatus2(mech) & (setstatus)) { mech_notify(mech, MECHALL, msgoff); \
00043 MechStatus2(mech) &= ~(setstatus); } else { mech_notify(mech,MECHALL, msgon); \
00044 MechStatus2(mech) |= (setstatus); MechStatus2(mech) &= ~(offstatus); } } else notify(player, donthave)
00045 
00046 #define TOGGLE_SPECIALS_MACRO_CHECK2(neededspecial,setstatus,offstatus,msgon,msgoff,donthave) \
00047 if (MechSpecials2(mech) & (neededspecial)) \
00048 { if (MechStatus2(mech) & (setstatus)) { mech_notify(mech, MECHALL, msgoff); \
00049 MechStatus2(mech) &= ~(setstatus); } else { mech_notify(mech,MECHALL, msgon); \
00050 MechStatus2(mech) |= (setstatus); MechStatus2(mech) &= ~(offstatus); } } else notify(player, donthave)
00051 
00052 #define TOGGLE_INFANTRY_MACRO_CHECK(neededspecial,setstatus,offstatus,msgon,msgoff,donthave) \
00053 if (MechInfantrySpecials(mech) & (neededspecial)) \
00054 { if (MechStatus2(mech) & (setstatus)) { mech_notify(mech, MECHALL, msgoff); \
00055 MechStatus2(mech) &= ~(setstatus); } else { mech_notify(mech,MECHALL, msgon); \
00056 MechStatus2(mech) |= (setstatus); MechStatus2(mech) &= ~(offstatus); } } else notify(player, donthave)
00057 
00058 static void mech_toggle_mode_sub(dbref player, MECH * mech, char *buffer,
00059                                                                  int nspecisspec, int nspec, int mode,
00060                                                                  int tFireMode, char *onmsg, char *offmsg,
00061                                                                  char *cant);
00062 
00063 /* Toggles ECM on / off */
00064 void mech_ecm(dbref player, MECH * mech, char *buffer)
00065 {
00066         cch(MECH_USUALO);
00067         DOCHECK(MechCritStatus(mech) & ECM_DESTROYED,
00068                         "Your Guardian ECM has been destroyed already!");
00069         TOGGLE_SPECIALS_MACRO_CHECK(ECM_TECH, ECM_ENABLED, ECCM_ENABLED,
00070                                                                 "You turn your ECM suite online (ECM mode).",
00071                                                                 "You turn your ECM suite offline.",
00072                                                                 "This unit isn't equipped with an ECM suite!");
00073         MarkForLOSUpdate(mech);
00074 }
00075 
00076 void mech_eccm(dbref player, MECH * mech, char *buffer)
00077 {
00078         cch(MECH_USUALO);
00079         DOCHECK(MechCritStatus(mech) & ECM_DESTROYED,
00080                         "Your Guardian ECM has been destroyed already!");
00081         TOGGLE_SPECIALS_MACRO_CHECK(ECM_TECH, ECCM_ENABLED, ECM_ENABLED,
00082                                                                 "You turn your ECM suite online (ECCM mode).",
00083                                                                 "You turn your ECM suite offline.",
00084                                                                 "This unit isn't equipped with an ECM suite!");
00085         MarkForLOSUpdate(mech);
00086 }
00087 
00088 void mech_perecm(dbref player, MECH * mech, char *buffer)
00089 {
00090         cch(MECH_USUALO);
00091         TOGGLE_INFANTRY_MACRO_CHECK(FC_INFILTRATORII_STEALTH_TECH,
00092                                                                 PER_ECM_ENABLED, PER_ECCM_ENABLED,
00093                                                                 "You turn your Personal ECM suite online (ECM mode).",
00094                                                                 "You turn your Personal ECM suite offline.",
00095                                                                 "This unit isn't equipped with a Personal ECM suite!");
00096         MarkForLOSUpdate(mech);
00097 }
00098 
00099 void mech_pereccm(dbref player, MECH * mech, char *buffer)
00100 {
00101         cch(MECH_USUALO);
00102         TOGGLE_INFANTRY_MACRO_CHECK(FC_INFILTRATORII_STEALTH_TECH,
00103                                                                 PER_ECCM_ENABLED, PER_ECM_ENABLED,
00104                                                                 "You turn your Personal ECM suite online (ECCM mode).",
00105                                                                 "You turn your Personal ECM suite offline.",
00106                                                                 "This unit isn't equipped with a Personal ECM suite!");
00107         MarkForLOSUpdate(mech);
00108 }
00109 
00110 void mech_angelecm(dbref player, MECH * mech, char *buffer)
00111 {
00112         cch(MECH_USUALO);
00113         DOCHECK(MechCritStatus(mech) & ANGEL_ECM_DESTROYED,
00114                         "Your Angel ECM has been destroyed already!");
00115         TOGGLE_SPECIALS_MACRO_CHECK2(ANGEL_ECM_TECH, ANGEL_ECM_ENABLED,
00116                                                                  ANGEL_ECCM_ENABLED,
00117                                                                  "You turn your Angel ECM suite online (ECM mode).",
00118                                                                  "You turn your Angel ECM suite offline.",
00119                                                                  "This unit isn't equipped with an Angel ECM suite!");
00120         MarkForLOSUpdate(mech);
00121 }
00122 
00123 void mech_angeleccm(dbref player, MECH * mech, char *buffer)
00124 {
00125         cch(MECH_USUALO);
00126         DOCHECK(MechCritStatus(mech) & ANGEL_ECM_DESTROYED,
00127                         "Your Angel ECM has been destroyed already!");
00128         TOGGLE_SPECIALS_MACRO_CHECK2(ANGEL_ECM_TECH, ANGEL_ECCM_ENABLED,
00129                                                                  ANGEL_ECM_ENABLED,
00130                                                                  "You turn your Angel ECM suite online (ECCM mode).",
00131                                                                  "You turn your Angel ECM suite offline.",
00132                                                                  "This unit isn't equipped with an Angel ECM suite!");
00133         MarkForLOSUpdate(mech);
00134 }
00135 
00136 void MechSliteChangeEvent(MUXEVENT * e)
00137 {
00138         MECH *mech = (MECH *) e->data;
00139         int wType = (int) e->data2;
00140 
00141         if(MechCritStatus(mech) & SLITE_DEST)
00142                 return;
00143 
00144         if(!Started(mech))
00145                 return;
00146 
00147         if(!Started(mech)) {
00148                 MechStatus2(mech) &= ~SLITE_ON;
00149                 MechCritStatus(mech) &= ~SLITE_LIT;
00150                 return;
00151         }
00152 
00153         if(wType == 1) {
00154                 MechStatus2(mech) |= SLITE_ON;
00155                 MechCritStatus(mech) |= SLITE_LIT;
00156 
00157                 mech_notify(mech, MECHALL,
00158                                         "Your searchlight comes on to full power.");
00159                 MechLOSBroadcast(mech, "turns on a searchlight!");
00160         } else {
00161                 MechStatus2(mech) &= ~SLITE_ON;
00162                 MechCritStatus(mech) &= ~SLITE_LIT;
00163 
00164                 mech_notify(mech, MECHALL, "Your searchlight shuts off.");
00165                 MechLOSBroadcast(mech, "turns off a searchlight!");
00166         }
00167 
00168         MarkForLOSUpdate(mech);
00169 }
00170 
00171 void mech_slite(dbref player, MECH * mech, char *buffer)
00172 {
00173         cch(MECH_USUALO);
00174 
00175         if(!(MechSpecials(mech) & SLITE_TECH)) {
00176                 mech_notify(mech, MECHALL,
00177                                         "Your 'mech isn't equipped with searchlight!");
00178                 return;
00179         }
00180 
00181         DOCHECK(MechCritStatus(mech) & SLITE_DEST,
00182                         "Your searchlight has been destroyed already!");
00183 
00184         if(SearchlightChanging(mech)) {
00185                 if(MechStatus2(mech) & SLITE_ON)
00186                         mech_notify(mech, MECHALL,
00187                                                 "Your searchlight is already in the process of turning off.");
00188                 else
00189                         mech_notify(mech, MECHALL,
00190                                                 "Your searchlight is already in the process of turning on.");
00191 
00192                 return;
00193         }
00194 
00195         if(MechStatus2(mech) & SLITE_ON) {
00196                 mech_notify(mech, MECHALL, "Your searchlight starts to cool down.");
00197                 MECHEVENT(mech, EVENT_SLITECHANGING, MechSliteChangeEvent, 5, 0);
00198         } else {
00199                 mech_notify(mech, MECHALL, "Your searchlight starts to warm up.");
00200                 MECHEVENT(mech, EVENT_SLITECHANGING, MechSliteChangeEvent, 5, 1);
00201         }
00202 }
00203 
00204 void mech_ams(dbref player, void *data, char *buffer)
00205 {
00206         MECH *mech = (MECH *) data;
00207 
00208         cch(MECH_USUALMO);
00209 
00210         SILLY_TOGGLE_MACRO(IS_ANTI_MISSILE_TECH | CL_ANTI_MISSILE_TECH,
00211                                            AMS_ENABLED, "Anti-Missile System turned ON",
00212                                            "Anti-Missile System turned OFF",
00213                                            "This mech is not equipped with AMS");
00214 }
00215 
00216 void mech_fliparms(dbref player, void *data, char *buffer)
00217 {
00218         MECH *mech = (MECH *) data;
00219 
00220         cch(MECH_USUALMO);
00221         DOCHECK(Fallen(mech),
00222                         "You're using your arms to support yourself. Try flipping something else.");
00223         SILLY_TOGGLE_MACRO(FLIPABLE_ARMS, FLIPPED_ARMS,
00224                                            "Arms have been flipped to BACKWARD position",
00225                                            "Arms have been flipped to FORWARD position",
00226                                            "You cannot flip the arms in this mech");
00227 }
00228 
00229 /* Parameters:
00230    <player,mech,buffer> = parent's input
00231    nspecisspec, nspec
00232          5 = check that it's a TAMMO weapon and has the specified spec
00233    4 = check that weapon's SRM (or SSRM)
00234    3 = check that weapon's NARC beacon
00235    2 = check that weapon's LRM
00236    1 = compare nspec to weapon's special
00237    0 = compare nspec to weapon's type and ensure it isn't NARCbcn
00238    -1 = compare nspec to weapon's type & check for Artemis
00239    mode           = mode to set if nspec check is successful
00240    onmsg          = msg for turning mode on
00241    offmsg         = msg for turning mode off
00242    cant           = system lacks nspec
00243  */
00244 
00245 static int temp_nspecisspec, temp_nspec, temp_mode, temp_firemode;
00246 static char *temp_onmsg, *temp_offmsg, *temp_cant;
00247 
00248 static int mech_toggle_mode_sub_func(MECH * mech, dbref player, int index,
00249                                                                          int high)
00250 {
00251         int section, critical, weaptype;
00252 
00253         weaptype =
00254                 FindWeaponNumberOnMech_Advanced(mech, index, &section, &critical, 0);
00255 
00256         DOCHECK0(weaptype == -1,
00257                          "The weapons system chirps: 'Illegal Weapon Number!'");
00258         DOCHECK0(weaptype == -2,
00259                          "The weapons system chirps: 'That Weapon has been destroyed!'");
00260         DOCHECK0(weaptype == -3,
00261                          "The weapon system chirps: 'That weapon is still reloading!'");
00262         DOCHECK0(weaptype == -4,
00263                          "The weapon system chirps: 'That weapon is still recharging!'");
00264         DOCHECK0(PartTempNuke(mech, section, critical) == FAIL_AMMOJAMMED,
00265                           "The ammo feed mechanism for that weapon is jammed! Unable to change modes!");
00266         DOCHECK0(GetPartFireMode(mech, section, critical) & OS_MODE,
00267                          "One-shot weapons' mode cannot be altered!");
00268         DOCHECK0(isWeapAmmoFeedLocked(mech, section, critical),
00269                          "That weapon's ammo feed mechanism is damaged!");
00270 
00271         if(temp_nspec == -1)
00272                 DOCHECK0(!FindArtemisForWeapon(mech, section, critical),
00273                                  "You have no Artemis system for that weapon.");
00274 
00275         weaptype = Weapon2I(GetPartType(mech, section, critical));
00276 
00277         DOCHECK0(MechWeapons[weaptype].special & ROCKET,
00278                          "Rocket launchers' mode cannot be altered!");
00279 
00280         if((temp_nspecisspec == 5 && (MechWeapons[weaptype].type == TAMMO)
00281                 && !(MechWeapons[weaptype].special & temp_nspec)) ||
00282            (temp_nspecisspec == 4 && (MechWeapons[weaptype].type == TMISSILE)
00283                 && !(MechWeapons[weaptype].type & (IDF | DAR))) ||
00284            (temp_nspecisspec == 2 && (MechWeapons[weaptype].special & IDF) &&
00285                 !(MechWeapons[weaptype].special & DAR)) ||
00286            (temp_nspecisspec == 1 && temp_nspec &&
00287                 (MechWeapons[weaptype].special & temp_nspec)) ||
00288            (temp_nspecisspec <= 0 && temp_nspec &&
00289                 (MechWeapons[weaptype].type == temp_nspec &&
00290                  !(MechWeapons[weaptype].special & NARC)))) {
00291 
00292                 if(temp_nspecisspec == 0 && (temp_nspec & TARTILLERY))
00293                         DOCHECK0((GetPartAmmoMode(mech, section,
00294                                                                           critical) & ARTILLERY_MODES) &&
00295                                          !(GetPartAmmoMode(mech, section, critical) & temp_mode),
00296                                          "That weapon has already been set to fire special rounds!");
00297 
00298                 if(temp_firemode) {
00299                         if(GetPartFireMode(mech, section, critical) & temp_mode) {
00300                                 GetPartFireMode(mech, section, critical) &= ~temp_mode;
00301                                 mech_notify(mech, MECHALL, tprintf(temp_offmsg, index));
00302                                 return 0;
00303                         }
00304                 } else {
00305                         if(GetPartAmmoMode(mech, section, critical) & temp_mode) {
00306                                 GetPartAmmoMode(mech, section, critical) &= ~temp_mode;
00307                                 mech_notify(mech, MECHALL, tprintf(temp_offmsg, index));
00308                                 return 0;
00309                         }
00310                 }
00311 
00312                 if(temp_firemode) {
00313                         GetPartFireMode(mech, section, critical) &= ~FIRE_MODES;
00314                         GetPartFireMode(mech, section, critical) |= temp_mode;
00315                 } else {
00316                         GetPartAmmoMode(mech, section, critical) &= ~AMMO_MODES;
00317                         GetPartAmmoMode(mech, section, critical) |= temp_mode;
00318                 }
00319 
00320                 mech_notify(mech, MECHALL, tprintf(temp_onmsg, index));
00321 
00322                 return 0;
00323         }
00324 
00325         notify(player, temp_cant);
00326         return 0;
00327 }
00328 
00329 static void mech_toggle_mode_sub(dbref player, MECH * mech, char *buffer,
00330                                                                  int nspecisspec, int nspec, int mode,
00331                                                                  int tFireMode, char *onmsg, char *offmsg,
00332                                                                  char *cant)
00333 {
00334         char *args[1];
00335 
00336         DOCHECK(mech_parseattributes(buffer, args, 1) != 1,
00337                         "Please specify a weapon number.");
00338         temp_nspecisspec = nspecisspec;
00339         temp_nspec = nspec;
00340         temp_mode = mode;
00341         temp_onmsg = onmsg;
00342         temp_offmsg = offmsg;
00343         temp_cant = cant;
00344         temp_firemode = tFireMode;
00345         multi_weap_sel(mech, player, args[0], 1, mech_toggle_mode_sub_func);
00346 }
00347 
00348 void mech_flamerheat(dbref player, void *data, char *buffer)
00349 {
00350         MECH *mech = (MECH *) data;
00351 
00352         cch(MECH_USUALMO);
00353         mech_toggle_mode_sub(player, mech, buffer, 1, CHEAT, HEAT_MODE, 1,
00354                                                  "Weapon %d has been set to HEAT mode",
00355                                                  "Weapon %d has been set to normal mode",
00356                                                  "That weapon cannot be set HEAT!");
00357 }
00358 
00359 void mech_ultra(dbref player, void *data, char *buffer)
00360 {
00361         MECH *mech = (MECH *) data;
00362 
00363         cch(MECH_USUALMO);
00364         mech_toggle_mode_sub(player, mech, buffer, 1, ULTRA, ULTRA_MODE, 1,
00365                                                  "Weapon %d has been set to ultra fire mode",
00366                                                  "Weapon %d has been set to normal fire mode",
00367                                                  "That weapon cannot be set ULTRA!");
00368 }
00369 
00370 void mech_inarc_ammo_toggle(dbref player, void *data, char *buffer)
00371 {
00372         MECH *mech = (MECH *) data;
00373         int wSection, wCritSlot, wWeapType;
00374         int wWeapNum = 0;
00375         int wcArgs = 0;
00376         char *args[2];
00377         char strMode[30];
00378 
00379         cch(MECH_USUALO);
00380 
00381         wcArgs = mech_parseattributes(buffer, args, 2);
00382 
00383         DOCHECK(wcArgs < 1, "Please specify a weapon number.");
00384         DOCHECK(Readnum(wWeapNum, args[0]), tprintf("Invalid value: %s",
00385                                                                                                 args[0]));
00386 
00387         wWeapType = FindWeaponNumberOnMech(mech, wWeapNum, &wSection, &wCritSlot);
00388 
00389         DOCHECK(wWeapType == -1,
00390                         "The weapons system chirps: 'Illegal Weapon Number!'");
00391         DOCHECK(wWeapType == -2,
00392                         "The weapons system chirps: 'That Weapon has been destroyed!'");
00393         DOCHECK(wWeapType == -3,
00394                         "The weapon system chirps: 'That weapon is still reloading!'");
00395         DOCHECK(wWeapType == -4,
00396                         "The weapon system chirps: 'That weapon is still recharging!'");
00397         DOCHECK(!(MechWeapons[wWeapType].special & INARC),
00398                         "The weapon system chirps: 'That weapon is not an iNARC launcher!'");
00399         DOCHECK(isWeapAmmoFeedLocked(mech, wSection, wCritSlot),
00400                         "That weapon's ammo feed mechanism is damaged!");
00401 
00402         /* Change our modes... */
00403 
00404         GetPartAmmoMode(mech, wSection, wCritSlot) &= ~AMMO_MODES;
00405 
00406         if(wcArgs < 2)
00407                 strcpy(strMode, "Homing");
00408         else {
00409                 switch (toupper(args[1][0])) {
00410                 case 'X':
00411                         strcpy(strMode, "Explosive");
00412                         GetPartAmmoMode(mech, wSection, wCritSlot) |= INARC_EXPLO_MODE;
00413                         break;
00414                 case 'Y':
00415                         strcpy(strMode, "Haywire");
00416                         GetPartAmmoMode(mech, wSection, wCritSlot) |= INARC_HAYWIRE_MODE;
00417                         break;
00418                 case 'E':
00419                         strcpy(strMode, "ECM");
00420                         GetPartAmmoMode(mech, wSection, wCritSlot) |= INARC_ECM_MODE;
00421                         break;
00422                 case 'Z':
00423                         strcpy(strMode, "Nemesis");
00424                         GetPartAmmoMode(mech, wSection, wCritSlot) |= INARC_NEMESIS_MODE;
00425                         break;
00426                 default:
00427                         strcpy(strMode, "Homing");
00428                         break;
00429                 }
00430         }
00431 
00432         mech_printf(mech, MECHALL,
00433                                 "Weapon %d set to fire iNARC %s pods.", wWeapNum, strMode);
00434 }
00435 
00436 void mech_explosive(dbref player, void *data, char *buffer)
00437 {
00438         MECH *mech = (MECH *) data;
00439 
00440         cch(MECH_USUALMO);
00441 
00442         mech_toggle_mode_sub(player, mech, buffer, 1, NARC, NARC_MODE, 0,
00443                                                  "Weapon %d has been set to fire explosive rounds",
00444                                                  "Weapon %d has been set to fire NARC beacons",
00445                                                  "That weapon cannot be set to fire explosive rounds!");
00446 }
00447 
00448 void mech_lbx(dbref player, void *data, char *buffer)
00449 {
00450         MECH *mech = (MECH *) data;
00451 
00452         cch(MECH_USUALMO);
00453         mech_toggle_mode_sub(player, mech, buffer, 1, LBX, LBX_MODE, 0,
00454                                                  "Weapon %d has been set to LBX fire mode",
00455                                                  "Weapon %d has been set to normal fire mode",
00456                                                  "That weapon cannot be set LBX!");
00457 }
00458 
00459 void mech_armorpiercing(dbref player, void *data, char *buffer)
00460 {
00461         MECH *mech = (MECH *) data;
00462 
00463         cch(MECH_USUALMO);
00464         mech_toggle_mode_sub(player, mech, buffer, 1, RFAC, AC_AP_MODE, 0,
00465                                                  "Weapon %d has been set to fire AP rounds",
00466                                                  "Weapon %d has been set to fire normal rounds",
00467                                                  "That weapon cannot fire AP rounds!");
00468 }
00469 
00470 void mech_caseless(dbref player, void *data, char *buffer)
00471 {
00472         MECH *mech = (MECH *) data;
00473         cch(MECH_USUALMO);
00474         mech_toggle_mode_sub(player, mech, buffer, 1, RFAC, AC_CASELESS_MODE, 0,
00475                         "Weapon %d has been set to fire CASELESS rounds",
00476                         "Weapon %d has been set to fire normal rounds",
00477                         "That weapon cannot fire CASELESS rounds!");
00478 }
00479 
00480 void mech_flechette(dbref player, void *data, char *buffer)
00481 {
00482         MECH *mech = (MECH *) data;
00483 
00484         cch(MECH_USUALMO);
00485         mech_toggle_mode_sub(player, mech, buffer, 1, RFAC, AC_FLECHETTE_MODE,
00486                                                  0, "Weapon %d has been set to fire Flechette rounds",
00487                                                  "Weapon %d has been set to fire normal rounds",
00488                                                  "That weapon cannot fire Flechette rounds!");
00489 }
00490 
00491 void mech_incendiary(dbref player, void *data, char *buffer)
00492 {
00493         MECH *mech = (MECH *) data;
00494 
00495         cch(MECH_USUALMO);
00496         mech_toggle_mode_sub(player, mech, buffer, 1, RFAC, AC_INCENDIARY_MODE,
00497                                                  0,
00498                                                  "Weapon %d has been set to fire Incendiary rounds",
00499                                                  "Weapon %d has been set to fire normal rounds",
00500                                                  "That weapon cannot fire Incendiary rounds!");
00501 }
00502 
00503 void mech_precision(dbref player, void *data, char *buffer)
00504 {
00505         MECH *mech = (MECH *) data;
00506 
00507         cch(MECH_USUALMO);
00508         mech_toggle_mode_sub(player, mech, buffer, 1, RFAC, AC_PRECISION_MODE,
00509                                                  0, "Weapon %d has been set to fire Precision rounds",
00510                                                  "Weapon %d has been set to fire normal rounds",
00511                                                  "That weapon cannot fire Precision rounds!");
00512 }
00513 
00514 void mech_rapidfire(dbref player, void *data, char *buffer)
00515 {
00516         MECH *mech = (MECH *) data;
00517 
00518         cch(MECH_USUALMO);
00519         mech_toggle_mode_sub(player, mech, buffer, 1, RFAC, RFAC_MODE, 1,
00520                                                  "Weapon %d has been set to Rapid Fire mode",
00521                                                  "Weapon %d has been set to normal fire mode",
00522                                                  "That weapon cannot be set to do rapid fire!");
00523 }
00524 
00525 void mech_stinger(dbref player, void *data, char *buffer)
00526 {
00527         MECH *mech = (MECH *) data;
00528 
00529         cch(MECH_USUALMO);
00530         mech_toggle_mode_sub(player, mech, buffer, 2, 0, STINGER_MODE, 0,
00531                                                  "Weapon %d has been set to fire stinger missiles.",
00532                                                  "Weapon %d has been set to fire normal missiles",
00533                                                  "That weapon cannot be set STINGER!");
00534 }
00535 
00536 void mech_rac(dbref player, void *data, char *buffer)
00537 {
00538         MECH *mech = (MECH *) data;
00539         int wSection, wCritSlot, wWeapType;
00540         int wWeapNum = 0;
00541         int wcArgs = 0;
00542         char *args[2];
00543         char strMode[30];
00544 
00545         cch(MECH_USUALO);
00546 
00547         wcArgs = mech_parseattributes(buffer, args, 2);
00548 
00549         DOCHECK(wcArgs < 1, "Please specify a weapon number.");
00550         DOCHECK(Readnum(wWeapNum, args[0]), tprintf("Invalid value: %s",
00551                                                                                                 args[0]));
00552 
00553         wWeapType = FindWeaponNumberOnMech(mech, wWeapNum, &wSection, &wCritSlot);
00554 
00555         DOCHECK(wWeapType == -1,
00556                         "The weapons system chirps: 'Illegal Weapon Number!'");
00557         DOCHECK(wWeapType == -2,
00558                         "The weapons system chirps: 'That Weapon has been destroyed!'");
00559         DOCHECK(wWeapType == -3,
00560                         "The weapon system chirps: 'That weapon is still reloading!'");
00561         DOCHECK(wWeapType == -4,
00562                         "The weapon system chirps: 'That weapon is still recharging!'");
00563         DOCHECK(!(MechWeapons[wWeapType].special & RAC),
00564                         "The weapon system chirps: 'That weapon is not an Rotary AC!'");
00565 
00566         /* Change our modes... */
00567 
00568         GetPartFireMode(mech, wSection, wCritSlot) &= ~FIRE_MODES;
00569         GetPartFireMode(mech, wSection, wCritSlot) &=
00570                 ~(RAC_TWOSHOT_MODE | RAC_FOURSHOT_MODE | RAC_SIXSHOT_MODE);
00571 
00572         if(wcArgs < 2)
00573                 strcpy(strMode, "one shot");
00574         else {
00575                 switch (args[1][0]) {
00576                 case '2':
00577                         strcpy(strMode, "two shots");
00578                         GetPartFireMode(mech, wSection, wCritSlot) |= RAC_TWOSHOT_MODE;
00579                         break;
00580                 case '4':
00581                         strcpy(strMode, "four shots");
00582                         GetPartFireMode(mech, wSection, wCritSlot) |= RAC_FOURSHOT_MODE;
00583                         break;
00584                 case '6':
00585                         strcpy(strMode, "six shots");
00586                         GetPartFireMode(mech, wSection, wCritSlot) |= RAC_SIXSHOT_MODE;
00587                         break;
00588                 default:
00589                         strcpy(strMode, "one shot");
00590                         break;
00591                 }
00592         }
00593 
00594         mech_printf(mech, MECHALL,
00595                                 "Weapon %d set to fire %s at a time.", wWeapNum, strMode);
00596 }
00597 
00598 static int mech_unjamammo_func(MECH * mech, dbref player, int index, int high)
00599 {
00600         int section, critical, weaptype;
00601         int i;
00602         char location[50];
00603 
00604         weaptype = FindWeaponNumberOnMech(mech, index, &section, &critical);
00605         DOCHECK0(weaptype == -1,
00606                          "The weapons system chirps: 'Illegal Weapon Number!'");
00607         DOCHECK0(weaptype == -2,
00608                          "The weapons system chirps: 'That Weapon has been destroyed!'");
00609         DOCHECK0(PartTempNuke(mech, section, critical) != FAIL_AMMOJAMMED,
00610                          "The ammo feed mechanism for that weapon is not jammed.");
00611         DOCHECK0(Jumping(mech), "You can't unjam the ammo feed while jumping!");
00612         DOCHECK0(IsRunning(MechDesiredSpeed(mech), MMaxSpeed(mech)),
00613                          "You can't unjam the ammo feed while running!");
00614 
00615         for(i = 0; i < NUM_SECTIONS; i++) {
00616                 if(SectHasBusyWeap(mech, i)) {
00617                         ArmorStringFromIndex(i, location, MechType(mech), MechMove(mech));
00618                         mech_printf(mech, MECHALL,
00619                                                 "You have weapons recycling on your %s.", location);
00620                         return 0;
00621                 }
00622         }
00623 
00624         DOCHECK0(UnJammingAmmo(mech), "You are already unjamming a weapon!");
00625 
00626         MECHEVENT(mech, EVENT_UNJAM_AMMO, mech_unjam_ammo_event, 60, index);
00627         mech_printf(mech, MECHALL,
00628                                 "You begin to shake the jammed ammo loose on weapon #%d",
00629                                 index);
00630         return 0;
00631 }
00632 void mech_unjamammo(dbref player, void *data, char *buffer)
00633 {
00634         MECH *mech = (MECH *) data;
00635         char *args[1];
00636 
00637         cch(MECH_USUALMO);
00638         DOCHECK(mech_parseattributes(buffer, args, 1) != 1,
00639                         "Please specify a weapon number.");
00640         multi_weap_sel(mech, player, args[0], 1, mech_unjamammo_func);
00641 }
00642 
00643 void mech_gattling(dbref player, void *data, char *buffer)
00644 {
00645         MECH *mech = (MECH *) data;
00646 
00647         cch(MECH_USUALMO);
00648         mech_toggle_mode_sub(player, mech, buffer, 1, GMG, GATTLING_MODE, 1,
00649                                                  "Weapon %d has been set to Gattling mode",
00650                                                  "Weapon %d has been set to normal fire mode",
00651                                                  "That weapon cannot be set to do gattling fire!");
00652 }
00653 
00654 void mech_artemis(dbref player, void *data, char *buffer)
00655 {
00656         MECH *mech = (MECH *) data;
00657 
00658         cch(MECH_USUALMO);
00659         mech_toggle_mode_sub(player, mech, buffer, -1, TMISSILE, ARTEMIS_MODE,
00660                                                  0,
00661                                                  "Weapon %d has been set to fire Artemis IV compatible missiles.",
00662                                                  "Weapon %d has been set to fire normal missiles",
00663                                                  "That weapon cannot be set ARTEMIS!");
00664 }
00665 
00666 void mech_narc(dbref player, void *data, char *buffer)
00667 {
00668         MECH *mech = (MECH *) data;
00669 
00670         cch(MECH_USUALMO);
00671         mech_toggle_mode_sub(player, mech, buffer, 0, TMISSILE, NARC_MODE, 0,
00672                                                  "Weapon %d has been set to fire Narc Beacon compatible missiles.",
00673                                                  "Weapon %d has been set to fire normal missiles",
00674                                                  "That weapon cannot be set NARC!");
00675 }
00676 
00677 void mech_swarm(dbref player, void *data, char *buffer)
00678 {
00679         MECH *mech = (MECH *) data;
00680 
00681         cch(MECH_USUALMO);
00682         mech_toggle_mode_sub(player, mech, buffer, 2, 0, SWARM_MODE, 0,
00683                                                  "Weapon %d has been set to fire Swarm missiles.",
00684                                                  "Weapon %d has been set to fire normal missiles",
00685                                                  "That weapon cannot be set to fire Swarm missiles!");
00686 }
00687 
00688 void mech_sguided(dbref player, void *data, char *buffer)
00689 {
00690         MECH *mech = (MECH *) data;
00691 
00692         cch(MECH_USUALMO);
00693         mech_toggle_mode_sub(player, mech, buffer, 2, 0, SGUIDED_MODE, 0,
00694                                                 "Weapon %d has been set to fire Sguided missiles.",
00695                                                 "Weapon %d has been set to fire normal missiles",
00696                                                 "That weapon cannot be set to fire Sguided missiles!");
00697 }
00698 
00699 void mech_swarm1(dbref player, void *data, char *buffer)
00700 {
00701         MECH *mech = (MECH *) data;
00702 
00703         cch(MECH_USUALMO);
00704         mech_toggle_mode_sub(player, mech, buffer, 2, 0, SWARM1_MODE, 0,
00705                                                  "Weapon %d has been set to fire Swarm1 missiles.",
00706                                                  "Weapon %d has been set to fire normal missiles",
00707                                                  "That weapon cannot be set to fire Swarm1 missiles!");
00708 }
00709 
00710 void mech_inferno(dbref player, void *data, char *buffer)
00711 {
00712         MECH *mech = (MECH *) data;
00713 
00714         cch(MECH_USUALMO);
00715         mech_toggle_mode_sub(player, mech, buffer, 4, 0, INFERNO_MODE, 0,
00716                                                  "Weapon %d has been set to fire Inferno missiles.",
00717                                                  "Weapon %d has been set to fire normal missiles",
00718                                                  "That weapon cannot be set to fire Inferno missiles!");
00719 }
00720 
00721 void mech_hotload(dbref player, void *data, char *buffer)
00722 {
00723         MECH *mech = (MECH *) data;
00724         cch(MECH_USUALMO);
00725         mech_toggle_mode_sub(player, mech, buffer, 1, IDF, HOTLOAD_MODE, 1,
00726                                                  "Hotloading for weapon %d has been toggled on.",
00727                                                  "Hotloading for weapon %d has been toggled off.",
00728                                                  "That weapon can not be hotloaded!");
00729 }
00730 
00731 void mech_cluster(dbref player, void *data, char *buffer)
00732 {
00733         MECH *mech = (MECH *) data;
00734 
00735         cch(MECH_USUALMO);
00736         mech_toggle_mode_sub(player, mech, buffer, 0, TARTILLERY, CLUSTER_MODE,
00737                                                  0, "Weapon %d has been set to fire cluster rounds.",
00738                                                  "Weapon %d has been set to fire normal rounds",
00739                                                  "Invalid weapon type!");
00740 }
00741 
00742 void mech_smoke(dbref player, void *data, char *buffer)
00743 {
00744         MECH *mech = (MECH *) data;
00745 
00746         cch(MECH_USUALMO);
00747         mech_toggle_mode_sub(player, mech, buffer, 0, TARTILLERY, SMOKE_MODE,
00748                                                  0, "Weapon %d has been set to fire smoke rounds.",
00749                                                  "Weapon %d has been set to fire normal rounds",
00750                                                  "Invalid weapon type!");
00751 }
00752 
00753 void mech_mine(dbref player, void *data, char *buffer)
00754 {
00755         MECH *mech = (MECH *) data;
00756 
00757         cch(MECH_USUALMO);
00758         mech_toggle_mode_sub(player, mech, buffer, 0, TARTILLERY, MINE_MODE, 0,
00759                                                  "Weapon %d has been set to fire mine rounds.",
00760                                                  "Weapon %d has been set to fire normal rounds",
00761                                                  "Invalid weapon type!");
00762 }
00763 
00764 static void mech_mascr_event(MUXEVENT * e)
00765 {
00766         MECH *mech = (MECH *) e->data;
00767 
00768         if(MechMASCCounter(mech) > 0) {
00769                 MechMASCCounter(mech)--;
00770                 MECHEVENT(mech, EVENT_MASC_REGEN, mech_mascr_event, MASC_TICK, 0);
00771         }
00772 }
00773 
00774 static void mech_masc_event(MUXEVENT * e)
00775 {
00776         MECH *mech = (MECH *) e->data;
00777 #ifndef BT_MOVEMENT_MODES
00778         int needed = 2 * (1 + (MechMASCCounter(mech)++));
00779 #else
00780         int needed = (2 * (1 + (MechMASCCounter(mech)++))) +
00781                 ((MechStatus2(mech) & SCHARGE_ENABLED) ? 1 : 0) +
00782                 (MechStatus2(mech) & SPRINTING ? 2 : 0);
00783 #endif
00784         int roll = Roll();
00785 
00786         if(!Started(mech))
00787                 return;
00788         if(!(MechSpecials(mech) & MASC_TECH))
00789                 return;
00790         if(MechStatus(mech) & SCHARGE_ENABLED)
00791                 roll--;
00792         if(needed < 10 && Good_obj(MechPilot(mech)) && WizP(MechPilot(mech)))
00793                 roll = Number(needed + 1, 12);
00794         mech_printf(mech, MECHALL, "MASC: BTH %d+, Roll: %d", needed + 1, roll);
00795         if(roll > needed) {
00796                 MECHEVENT(mech, EVENT_MASC_FAIL, mech_masc_event, MASC_TICK, 0);
00797                 return;
00798         }
00799         MechSpecials(mech) &= ~MASC_TECH;
00800         MechStatus(mech) &= ~MASC_ENABLED;
00801         if(fabs(MechSpeed(mech)) > MP1) {
00802                 mech_notify(mech, MECHALL,
00803                                         "Your leg actuators freeze suddenly, and you fall!");
00804                 MechLOSBroadcast(mech, "stops and falls in mid-step!");
00805                 MechFalls(mech, 1, 0);
00806         } else {
00807                 mech_notify(mech, MECHALL, "Your leg actuators freeze suddenly!");
00808                 if(MechSpeed(mech) > 0.0)
00809                         MechLOSBroadcast(mech, "stops suddenly!");
00810         }
00811 
00812         /* Break the Hips - FASA canon rule about MASC */
00813         DestroyPart(mech, RLEG, 0);
00814         DestroyPart(mech, LLEG, 0);
00815         /* Don't forget to add in Hipped penalties (for landing, etc) */
00816         MechSections(mech)[RLEG].basetohit += 2;
00817         MechSections(mech)[LLEG].basetohit += 2;
00818         if(MechMove(mech) == MOVE_QUAD) {
00819                 DestroyPart(mech, RARM, 0);
00820                 DestroyPart(mech, LARM, 0);
00821         }
00822 
00823         /* Let the MUX know both hips gone */
00824         MechCritStatus(mech) |= HIP_DESTROYED;
00825 
00826         /* Reset the Speeds, this sets all 3 of them */
00827         SetMaxSpeed(mech, 0.0);
00828 }
00829 
00830 void mech_masc(dbref player, void *data, char *buffer)
00831 {
00832         MECH *mech = (MECH *) data;
00833 
00834         cch(MECH_USUALMO);
00835         DOCHECK(!(MechSpecials(mech) & MASC_TECH),
00836                         "Your toy ain't prepared for what you're askin' it!");
00837         DOCHECK(MMaxSpeed(mech) < MP1, "Uh huh.");
00838         if(MechStatus(mech) & MASC_ENABLED) {
00839                 mech_notify(mech, MECHALL, "MASC has been turned off.");
00840                 MechStatus(mech) &= ~MASC_ENABLED;
00841                 MechDesiredSpeed(mech) = MechDesiredSpeed(mech) * 3. / 4.;
00842                 StopMasc(mech);
00843                 MECHEVENT(mech, EVENT_MASC_REGEN, mech_mascr_event, MASC_TICK, 0);
00844                 return;
00845         }
00846         mech_notify(mech, MECHALL, "MASC has been turned on.");
00847         MechStatus(mech) |= MASC_ENABLED;
00848         StopMascR(mech);
00849         MechDesiredSpeed(mech) = MechDesiredSpeed(mech) * 4. / 3.;
00850         MECHEVENT(mech, EVENT_MASC_FAIL, mech_masc_event, 1, 0);
00851 }
00852 
00853 static void mech_scharger_event(MUXEVENT * e)
00854 {
00855         MECH *mech = (MECH *) e->data;
00856 
00857         if(MechSChargeCounter(mech) > 0) {
00858                 MechSChargeCounter(mech)--;
00859                 MECHEVENT(mech, EVENT_SCHARGE_REGEN, mech_scharger_event,
00860                                   SCHARGE_TICK, 0);
00861         }
00862 }
00863 
00864 static void mech_scharge_event(MUXEVENT * e)
00865 {
00866         MECH *mech = (MECH *) e->data;
00867 #ifndef BT_MOVEMENT_MODES
00868         int needed = 2 * (1 + (MechSChargeCounter(mech)++));
00869 #else
00870         int needed = (2 * (1 + (MechMASCCounter(mech)++))) +
00871                 ((MechStatus(mech) & MASC_ENABLED) ? 1 : 0) +
00872                 (MechStatus2(mech) & SPRINTING ? 2 : 0);
00873 #endif
00874         int roll = Roll();
00875         int j, count = 0;
00876         int maxspeed, newmaxspeed = 0;
00877         int critType;
00878         char msgbuf[MBUF_SIZE];
00879 
00880         if(!Started(mech))
00881                 return;
00882         if(!(MechSpecials2(mech) & SUPERCHARGER_TECH))
00883                 return;
00884         if(MechStatus(mech) & MASC_ENABLED)
00885                 roll = roll - 1;
00886         if(needed < 10 && Good_obj(MechPilot(mech)) && WizP(MechPilot(mech)))
00887                 roll = Number(needed + 1, 12);
00888         mech_printf(mech, MECHALL, "Supercharger: BTH %d, Roll: %d",
00889                                 needed + 1, roll);
00890         if(roll > needed) {
00891                 MECHEVENT(mech, EVENT_SCHARGE_FAIL, mech_scharge_event,
00892                                   SCHARGE_TICK, 0);
00893                 return;
00894         }
00895 
00896         MechSpecials2(mech) &= ~SUPERCHARGER_TECH;
00897         MechStatus(mech) &= ~SCHARGE_ENABLED;
00898 
00899         mech_notify(mech, MECHALL, "Your supercharger overloads and explodes!");
00900 
00901         if(MechType(mech) == CLASS_MECH) {
00902                 for(j = 0; j < CritsInLoc(mech, CTORSO); j++) {
00903                         critType = GetPartType(mech, CTORSO, j);
00904                         if(critType == Special(SUPERCHARGER)) {
00905                                 if(!PartIsDestroyed(mech, CTORSO, j))
00906                                         DestroyPart(mech, CTORSO, j);
00907                         }
00908                 }
00909 
00910                 count = Number(1, 4);
00911 
00912                 for(j = 0; count && j < CritsInLoc(mech, CTORSO); j++) {
00913                         critType = GetPartType(mech, CTORSO, j);
00914                         if(critType == Special(ENGINE) &&
00915                            !PartIsDestroyed(mech, CTORSO, j)) {
00916                                 DestroyPart(mech, CTORSO, j);
00917                                 if(!Destroyed(mech) && Started(mech)) {
00918                                         sprintf(msgbuf, "'s center torso spews black smoke!");
00919                                         MechLOSBroadcast(mech, msgbuf);
00920                                 }
00921                                 if(MechEngineHeat(mech) < 10) {
00922                                         MechEngineHeat(mech) += 5;
00923                                         mech_notify(mech, MECHALL,
00924                                                                 "Your engine shielding takes a hit!  It's getting hotter in here!!");
00925                                 } else if(MechEngineHeat(mech) < 15) {
00926                                         MechEngineHeat(mech) = 15;
00927                                         mech_notify(mech, MECHALL, "Your engine is destroyed!!");
00928                                         DestroyMech(mech, mech, 1);
00929                                 }
00930                                 count--;
00931                         }
00932                 }
00933         }
00934 
00935         if((MechType(mech) == CLASS_VTOL) || (MechType(mech) == CLASS_VEH_GROUND)) {
00936                 sprintf(msgbuf, " coughs think black smoke from its exhaust.");
00937                 MechLOSBroadcast(mech, msgbuf);
00938                 maxspeed = MechMaxSpeed(mech);
00939                 newmaxspeed = (maxspeed * .5);
00940                 SetMaxSpeed(mech, newmaxspeed);
00941         }
00942 }
00943 
00944 void mech_scharge(dbref player, void *data, char *buffer)
00945 {
00946         MECH *mech = (MECH *) data;
00947 
00948         cch(MECH_USUALMO);
00949         DOCHECK(!(MechSpecials2(mech) & SUPERCHARGER_TECH),
00950                         "Your toy ain't prepared for what you're askin' it!");
00951         DOCHECK(MMaxSpeed(mech) < MP1, "Uh huh.");
00952         if(MechStatus(mech) & SCHARGE_ENABLED) {
00953                 mech_notify(mech, MECHALL, "Supercharger has been turned off.");
00954                 MechStatus(mech) &= ~SCHARGE_ENABLED;
00955                 MechDesiredSpeed(mech) = MechDesiredSpeed(mech) * 3. / 4.;
00956                 StopSCharge(mech);
00957                 MECHEVENT(mech, EVENT_SCHARGE_REGEN, mech_scharger_event,
00958                                   SCHARGE_TICK, 0);
00959                 return;
00960         }
00961         mech_notify(mech, MECHALL, "Supercharger has been turned on.");
00962         MechStatus(mech) |= SCHARGE_ENABLED;
00963         StopSChargeR(mech);
00964         MechDesiredSpeed(mech) = MechDesiredSpeed(mech) * 4. / 3.;
00965         MECHEVENT(mech, EVENT_SCHARGE_FAIL, mech_scharge_event, 1, 0);
00966 }
00967 
00968 static void mech_explode_event(MUXEVENT * e) {
00969         MECH *mech = (MECH *) e->data;
00970         MAP *map;
00971         int extra = (int) e->data2;
00972         int i, j, k, damage;
00973         int z;
00974         int dam;
00975 
00976         if(Destroyed(mech) || !Started(mech))
00977                 return;
00978 
00979         if(extra > 256 && !FindDestructiveAmmo(mech, &i, &j))
00980                 return;
00981 
00982         if((--extra) % 256) {
00983                 mech_printf(mech, MECHALL,
00984                                 "Self-destruction in %d second%s..", extra % 256,
00985                                 extra > 1 ? "s" : "");
00986                 MECHEVENT(mech, EVENT_EXPLODE, mech_explode_event, 1, extra);
00987         } else {
00988                 SendDebug(tprintf("#%d explodes.", mech->mynum));
00989                 if(MechType(mech) == CLASS_BSUIT) {
00990                         mech_notify(mech, MECHALL, "Your batttle suit triggers it's self-destruction sequence.. you faint.. (and die)");
00991                         MechLOSBroadcast(mech, "suddenly explodes!");
00992                         headhitmwdamage(mech, mech, 4);
00993                         for (k = 0; k < NUM_BSUIT_MEMBERS; k++)
00994                                 DestroySection(mech,mech, -1, k);
00995                         MechZ(mech) += 6;
00996                 } else if(MechType(mech) != CLASS_MECH) {
00997                         mech_notify(mech, MECHALL, "Your life flashes before your eyes as your vehicle immolates itself... you faint.. (and die)");
00998                         MechLOSBroadcast(mech, "suddenly explodes!");
00999                         DestroySection(mech, mech, -1, 3); // This is the back side for vehicles
01000                         // and the aft for aero's.
01001                         headhitmwdamage(mech, mech, 4);
01002                         MechZ(mech) += 6;
01003 
01004                 } else if(extra >= 256) {
01005                         SendDebug(tprintf("#%d explodes [ammo]", mech->mynum));
01006                         mech_notify(mech, MECHALL, "All your ammo explodes!");
01007                         while ((damage = FindDestructiveAmmo(mech, &i, &j)))
01008                                 ammo_explosion(mech, mech, i, j, damage);
01009                 } else {
01010                         SendDebug(tprintf("#%d explodes [reactor]", mech->mynum));
01011                         MechLOSBroadcast(mech, "suddenly explodes!");
01012                         mech_notify(mech, MECHALL,
01013                                         "Suddenly you feel great heat overcoming your senses.. you faint.. (and die)");
01014                         reactor_explosion(mech, mech);
01015                 }
01016         }
01017 }
01018 
01019 void mech_explode(dbref player, void *data, char *buffer)
01020 {
01021         MECH *mech = (MECH *) data;
01022         char *args[3];
01023         int i;
01024         int ammoloc, ammocritnum;
01025         int time = mudconf.btech_explode_time;
01026         int ammo = 1;
01027         int argc;
01028         int override = 0;
01029 
01030         cch(MECH_USUALO);
01031         override = (strstr(buffer, "override") != NULL) && Wizard(player);
01032         argc = mech_parseattributes(buffer, args, 2);
01033         DOCHECK(argc < 1, "Invalid number of arguments!");
01034 
01035         /* Can't do any of the explosion routine if we're recycling! */
01036         if(!override) {
01037                 for(i = 0; i < NUM_SECTIONS; i++) {
01038                         if(!SectIsDestroyed(mech, i))
01039                                 DOCHECK(SectHasBusyWeap(mech, i), "You have weapons recycling!");
01040                         DOCHECK(MechSections(mech)[i].recycle,
01041                                         "You are still recovering from your last attack.");
01042                 }
01043         }
01044 
01045         if(!strcasecmp(buffer, "stop")) {
01046                 if(!override) {
01047                         DOCHECK(!mudconf.btech_explode_stop,
01048                                         "It's too late to turn back now!");
01049                 }
01050                 DOCHECK(!Exploding(mech),
01051                                 "Your mech isn't undergoing a self-destruct sequence!");
01052 
01053                 StopExploding(mech);
01054                 mech_notify(mech, MECHALL, "Self-destruction sequence aborted.");
01055                 SendDebug(tprintf
01056                                   ("#%d in #%d stopped the self-destruction sequence.",
01057                                    player, mech->mynum));
01058                 MechLOSBroadcast(mech, "regains control over itself.");
01059                 return;
01060         }
01061         DOCHECK(Exploding(mech),
01062                         "Your mech is already undergoing a self-destruct sequence!");
01063         if(!strcasecmp(buffer, "ammo")) {
01064                 /*
01065                    Find SOME ammo to explode ; if possible, we engage the 'boom' process
01066                  */
01067                 if(!override) {
01068                         DOCHECK(!mudconf.btech_explode_ammo,
01069                                         "You can't bring yourself to do it!");
01070                         DOCHECK(MechStatus(mech) & EXPLODE_SAFE,
01071                                         "That's not a possibility here.");
01072                 }
01073                 i = FindDestructiveAmmo(mech, &ammoloc, &ammocritnum);
01074                 DOCHECK(!i, "There is no 'damaging' ammo on your 'mech!");
01075                 /* Engage the boom-event */
01076                 SendDebug(tprintf
01077                                   ("#%d in #%d initiates the ammo explosion sequence.",
01078                                    player, mech->mynum));
01079                 MechLOSBroadcast(mech, "starts billowing smoke!");
01080                 time = time / 2;
01081         } else {
01082                 if(!override) {
01083                         DOCHECK(!mudconf.btech_explode_reactor,
01084                                         "You can't bring yourself to do it!");
01085                         DOCHECK(MechType(mech) != CLASS_MECH,
01086                                         "Only mechs can do the 'big boom' effect.");
01087                         DOCHECK(MechSpecials(mech) & ICE_TECH, "You need a fusion reactor.");
01088                 }
01089                 SendDebug(tprintf
01090                                   ("#%d in #%d initiates the reactor explosion sequence.",
01091                                    player, mech->mynum));
01092                 MechLOSBroadcast(mech, "loses reactions containment!");
01093                 ammo = 0;
01094         }
01095         if(override) time = 3;
01096         MECHEVENT(mech, EVENT_EXPLODE, mech_explode_event, 1, time);
01097         mech_notify(mech, MECHALL, "Self-destruction sequence engaged ; please stand by.");
01098         mech_printf(mech, MECHALL, "%s in %d seconds.", ammo ? "The ammunition will explode" :
01099                                 "The reactor will blow up", time);
01100         MechPilot(mech) = -1; /* Pilot gives up control */
01101 }
01102 
01103 static void mech_dig_event(MUXEVENT * e)
01104 {
01105         MECH *mech = (MECH *) e->data;
01106 
01107         if(!Digging(mech))
01108                 return;
01109 
01110         if(!Started(mech))
01111                 return;
01112 
01113         MechTankCritStatus(mech) &= ~DIGGING_IN;
01114         MechTankCritStatus(mech) |= DUG_IN;
01115         mech_notify(mech, MECHALL,
01116                                 "You finish burrowing for cover - only turret weapons are available now.");
01117 }
01118 
01119 void mech_dig(dbref player, void *data, char *buffer)
01120 {
01121         MECH *mech = (MECH *) data;
01122 
01123         cch(MECH_USUALO);
01124         DOCHECK(fabs(MechSpeed(mech)) > 0.0, "You are moving!");
01125         DOCHECK(MechFacing(mech) != MechDesiredFacing(mech), "You are turning!");
01126         DOCHECK(MechMove(mech) == MOVE_NONE, "You are stationary!");
01127         DOCHECK(MechDugIn(mech), "You are already dug in!");
01128         DOCHECK(Digging(mech), "You are already digging in!");
01129         DOCHECK(OODing(mech), "While dropping? I think not.");
01130         DOCHECK(MechRTerrain(mech) == ROAD ||
01131                         MechRTerrain(mech) == BRIDGE ||
01132                         MechRTerrain(mech) == BUILDING ||
01133                         MechRTerrain(mech) == WALL,
01134                         "The surface is slightly too hard for you to dig in.");
01135         DOCHECK(MechRTerrain(mech) == WATER, "In water? Who are you kidding?");
01136 
01137         MechTankCritStatus(mech) |= DIGGING_IN;
01138         MECHEVENT(mech, EVENT_DIG, mech_dig_event, 20, 0);
01139         mech_notify(mech, MECHALL, "You start digging yourself in a nice hole..");
01140 }
01141 
01142 static void mech_unjam_turret_event(MUXEVENT * e)
01143 {
01144         MECH *mech = (MECH *) e->data;
01145 
01146         if(Destroyed(mech))
01147                 return;
01148 
01149         if(Uncon(mech))
01150                 return;
01151 
01152         if(!GetSectInt(mech, TURRET))
01153                 return;
01154 
01155         if(!Started(mech))
01156                 return;
01157 
01158         if(MechTankCritStatus(mech) & TURRET_LOCKED) {
01159                 mech_notify(mech, MECHALL, "You are unable to unjam the turret!");
01160                 return;
01161         }
01162 
01163         MechTankCritStatus(mech) &= ~TURRET_JAMMED;
01164         mech_notify(mech, MECHALL, "You manage to unjam your turret!");
01165 }
01166 
01167 void mech_fixturret(dbref player, void *data, char *buffer)
01168 {
01169         MECH *mech = (MECH *) data;
01170 
01171         cch(MECH_USUALO);
01172         DOCHECK(MechTankCritStatus(mech) & TURRET_LOCKED,
01173                         "Your turret is locked! You need a repairbay to fix it!");
01174         DOCHECK(!(MechTankCritStatus(mech) & TURRET_JAMMED),
01175                         "Your turret is not jammed!");
01176         MECHEVENT(mech, EVENT_UNJAM_TURRET, mech_unjam_turret_event, 60, 0);
01177         mech_notify(mech, MECHALL, "You start to repair your jammed turret.");
01178 }
01179 
01180 static int mech_disableweap_func(MECH * mech, dbref player, int index,
01181                                                                  int high)
01182 {
01183         int section, critical, weaptype;
01184 
01185         weaptype =
01186                 FindWeaponNumberOnMech_Advanced(mech, index, &section, &critical, 1);
01187         DOCHECK0(weaptype == -1,
01188                          "The weapons system chirps: 'Illegal Weapon Number!'");
01189         DOCHECK0(weaptype == -2,
01190                          "The weapons system chirps: 'That Weapon has been destroyed!'");
01191         weaptype = Weapon2I(GetPartType(mech, section, critical));
01192         DOCHECK0(!(MechWeapons[weaptype].special & GAUSS),
01193                          "You can only disable Gauss weapons.");
01194         DOCHECK0(weaptype == -4,
01195                                   "The weapon system chirps: 'That weapon is still recharging!'");
01196 
01197         SetPartTempNuke(mech, section, critical, FAIL_DESTROYED);
01198         mech_printf(mech, MECHALL, "You power down weapon %d.", index);
01199         return 0;
01200 }
01201 
01202 void mech_disableweap(dbref player, void *data, char *buffer)
01203 {
01204         MECH *mech = (MECH *) data;
01205         char *args[1];
01206 
01207         cch(MECH_USUALO);
01208         DOCHECK(mech_parseattributes(buffer, args, 1) != 1,
01209                         "Please specify a weapon number.");
01210 
01211         multi_weap_sel(mech, player, args[0], 1, mech_disableweap_func);
01212 }
01213 
01214 int FindMainWeapon(MECH * mech, int (*callback) (MECH *, int, int, int, int))
01215 {
01216         unsigned char weaparray[MAX_WEAPS_SECTION];
01217         unsigned char weapdata[MAX_WEAPS_SECTION];
01218         int critical[MAX_WEAPS_SECTION];
01219         int count;
01220         int loop;
01221         int ii;
01222         int tempcrit;
01223         int maxcrit = 0;
01224         int maxloc = 0;
01225         int critfound = 0;
01226         int maxcount = 0;
01227 
01228         for(loop = 0; loop < NUM_SECTIONS; loop++) {
01229                 if(SectIsDestroyed(mech, loop))
01230                         continue;
01231                 count = FindWeapons(mech, loop, weaparray, weapdata, critical);
01232                 if(count > 0) {
01233                         for(ii = 0; ii < count; ii++) {
01234                                 if(!PartIsBroken(mech, loop, critical[ii])) {
01235                                         /* tempcrit = GetWeaponCrits(mech, weaparray[ii]); */
01236                                         tempcrit = rand();
01237                                         if(tempcrit > maxcrit) {
01238                                                 critfound = 1;
01239                                                 maxcrit = tempcrit;
01240                                                 maxloc = loop;
01241                                                 maxcount = ii;
01242                                         }
01243                                 }
01244                         }
01245                 }
01246         }
01247         if(critfound)
01248                 return callback(mech, maxloc, weaparray[maxcount], maxcount, maxcrit);
01249         else
01250                 return 0;
01251 }
01252 
01253 void changeStealthArmorEvent(MUXEVENT * e)
01254 {
01255         MECH *mech = (MECH *) e->data;
01256         int wType = (int) e->data2;
01257 
01258         if(!Started(mech))
01259                 return;
01260 
01261         if(!HasWorkingECMSuite(mech))
01262                 return;
01263 
01264         if(wType) {
01265                 mech_notify(mech, MECHALL, "Stealth Armor system engaged!");
01266 
01267                 EnableStealthArmor(mech);
01268                 checkECM(mech);
01269                 MarkForLOSUpdate(mech);
01270         } else {
01271                 mech_notify(mech, MECHALL, "Stealth Armor system disengaged!");
01272 
01273                 DisableStealthArmor(mech);
01274                 checkECM(mech);
01275                 MarkForLOSUpdate(mech);
01276         }
01277 }
01278 
01279 void mech_stealtharmor(dbref player, MECH * mech, char *buffer)
01280 {
01281         cch(MECH_USUALO);
01282 
01283         if(!(MechSpecials2(mech) & STEALTH_ARMOR_TECH)) {
01284                 mech_notify(mech, MECHALL,
01285                                         "Your 'mech isn't equipped with a Stealth Armor system!");
01286 
01287                 return;
01288         }
01289 
01290         if(!HasWorkingECMSuite(mech)) {
01291                 mech_notify(mech, MECHALL,
01292                                         "Your 'mech doesn't have a working Guardian ECM suite!");
01293 
01294                 return;
01295         }
01296 
01297         if(StealthArmorChanging(mech)) {
01298                 mech_notify(mech, MECHALL,
01299                                         "You are already changing the status of your Stealth Armor system!");
01300 
01301                 return;
01302         }
01303 
01304         if(!StealthArmorActive(mech)) {
01305                 mech_notify(mech, MECHALL,
01306                                         "Your Stealth Armor system begins to come online.");
01307 
01308                 MECHEVENT(mech, EVENT_STEALTH_ARMOR, changeStealthArmorEvent, 30, 1);
01309         } else {
01310                 mech_notify(mech, MECHALL,
01311                                         "Your Stealth Armor system begins to shutdown.");
01312 
01313                 MECHEVENT(mech, EVENT_STEALTH_ARMOR, changeStealthArmorEvent, 30, 0);
01314         }
01315 }
01316 
01317 void changeNullSigSysEvent(MUXEVENT * e)
01318 {
01319         MECH *mech = (MECH *) e->data;
01320         int wType = (int) e->data2;
01321 
01322         if(!Started(mech))
01323                 return;
01324 
01325         if(NullSigSysDest(mech))
01326                 return;
01327 
01328         if(wType) {
01329                 mech_notify(mech, MECHALL, "Null Signature System engaged!");
01330 
01331                 EnableNullSigSys(mech);
01332                 MarkForLOSUpdate(mech);
01333         } else {
01334                 mech_notify(mech, MECHALL, "Null Signature System disengaged!");
01335 
01336                 DisableNullSigSys(mech);
01337                 MarkForLOSUpdate(mech);
01338         }
01339 }
01340 
01341 void mech_nullsig(dbref player, MECH * mech, char *buffer)
01342 {
01343         cch(MECH_USUALO);
01344 
01345         if(!(MechSpecials2(mech) & NULLSIGSYS_TECH)) {
01346                 mech_notify(mech, MECHALL,
01347                                         "Your 'mech isn't equipped with a Null Signature System!");
01348 
01349                 return;
01350         }
01351 
01352         if(NullSigSysDest(mech)) {
01353                 mech_notify(mech, MECHALL,
01354                                         "Your Null Signature System is destroyed!");
01355 
01356                 return;
01357         }
01358 
01359         if(NullSigSysChanging(mech)) {
01360                 mech_notify(mech, MECHALL,
01361                                         "You are already changing the status of your Null Signature System!");
01362 
01363                 return;
01364         }
01365 
01366         if(!NullSigSysActive(mech)) {
01367                 mech_notify(mech, MECHALL,
01368                                         "Your Null Signature System begins to come online.");
01369 
01370                 MECHEVENT(mech, EVENT_NSS, changeNullSigSysEvent, 30, 1);
01371         } else {
01372                 mech_notify(mech, MECHALL,
01373                                         "Your Null Signature System begins to shutdown.");
01374 
01375                 MECHEVENT(mech, EVENT_NSS, changeNullSigSysEvent, 30, 0);
01376         }
01377 }
01378 
01379 void show_narc_pods(dbref player, MECH * mech, char *buffer)
01380 {
01381         char location[50];
01382         int i;
01383 
01384         cch(MECH_USUALO);
01385 
01386         if(!(checkAllSections(mech, NARC_ATTACHED) ||
01387                  checkAllSections(mech, INARC_HOMING_ATTACHED) ||
01388                  checkAllSections(mech, INARC_HAYWIRE_ATTACHED) ||
01389                  checkAllSections(mech, INARC_ECM_ATTACHED) ||
01390                  checkAllSections(mech, INARC_NEMESIS_ATTACHED))) {
01391 
01392                 notify(player,
01393                            "There are no NARC or iNARC pods attached to this unit.");
01394 
01395                 return;
01396         }
01397 
01398         notify(player,
01399                    "=========================Attached NARC and iNARC Pods========================");
01400         notify(player,
01401                    "-- Location ---||- NARC -||- iHoming -||- iHaywire -||- iECM -||- iNemesis --");
01402 
01403         for(i = 0; i < NUM_SECTIONS; i++) {
01404                 if(GetSectOInt(mech, i) > 0) {
01405                         ArmorStringFromIndex(i, location, MechType(mech), MechMove(mech));
01406 
01407                         if(SectIsDestroyed(mech, i)) {
01408                                 notify_printf(player,
01409                                                           " %-14.13s||********||***********||************||********||************* ",
01410                                                           location);
01411                         } else {
01412                                 notify_printf(player,
01413                                                           " %-14.13s||....%s...||.....%s.....||......%s.....||....%s...||......%s...... ",
01414                                                           location, checkSectionForSpecial(mech,
01415                                                                                                                            NARC_ATTACHED,
01416                                                                                                                            i) ? "X" : ".",
01417                                                           checkSectionForSpecial(mech,
01418                                                                                                          INARC_HOMING_ATTACHED,
01419                                                                                                          i) ? "X" : ".",
01420                                                           checkSectionForSpecial(mech,
01421                                                                                                          INARC_HAYWIRE_ATTACHED,
01422                                                                                                          i) ? "X" : ".",
01423                                                           checkSectionForSpecial(mech, INARC_ECM_ATTACHED,
01424                                                                                                          i) ? "X" : ".",
01425                                                           checkSectionForSpecial(mech,
01426                                                                                                          INARC_NEMESIS_ATTACHED,
01427                                                                                                          i) ? "X" : ".");
01428                         }
01429                 }
01430         }
01431 }
01432 
01433 int findArmBTHMod(MECH * mech, int wSec)
01434 {
01435         int wRet = 0;
01436 
01437         if(PartIsNonfunctional(mech, wSec, 1) ||
01438            GetPartType(mech, wSec, 1) != I2Special(UPPER_ACTUATOR))
01439                 wRet += 2;
01440         if(PartIsNonfunctional(mech, wSec, 2) ||
01441            GetPartType(mech, wSec, 2) != I2Special(LOWER_ACTUATOR))
01442                 wRet += 2;
01443         if(PartIsNonfunctional(mech, wSec, 3) ||
01444            GetPartType(mech, wSec, 3) != I2Special(HAND_OR_FOOT_ACTUATOR))
01445                 wRet += 1;
01446 
01447         return wRet;
01448 }
01449 
01450 void remove_inarc_pods_mech(dbref player, MECH * mech, char *buffer)
01451 {
01452         int wLoc;
01453         int wArmToUse = -1;
01454         char *args[2];
01455         char strLocation[50], strPunchWith[50];
01456         int wBTH = 0;
01457         int wBTHModLARM = 0;
01458         int wBTHModRARM = 0;
01459         int wRAAvail = 1;
01460         int wLAAvail = 1;
01461         int wRoll;
01462         int wSelfDamage;
01463         int wPodType = INARC_HOMING_ATTACHED;
01464         char strPodType[30];
01465 
01466         cch(MECH_USUALO);
01467 
01468         DOCHECK(MechIsQuad(mech), "Quads can not knock of iNARC pods!");
01469         DOCHECK(mech_parseattributes(buffer, args, 2) != 2,
01470                         "Invalid number of arguments!");
01471 
01472         wLoc = ArmorSectionFromString(MechType(mech), MechMove(mech), args[0]);
01473 
01474         DOCHECK(wLoc == -1, "Invalid section!");
01475         DOCHECK(!GetSectOInt(mech, wLoc), "Invalid section!");
01476         DOCHECK(!GetSectInt(mech, wLoc), "That section is destroyed!");
01477 
01478         ArmorStringFromIndex(wLoc, strLocation, MechType(mech), MechMove(mech));
01479 
01480         /* Figure out wot type of pods we want to remove */
01481         switch (toupper(args[1][0])) {
01482         case 'Y':
01483                 strcpy(strPodType, "Haywire");
01484                 wPodType = INARC_HAYWIRE_ATTACHED;
01485                 break;
01486 
01487         case 'E':
01488                 strcpy(strPodType, "ECM");
01489                 wPodType = INARC_ECM_ATTACHED;
01490                 break;
01491 
01492         default:
01493                 strcpy(strPodType, "Homing");
01494                 wPodType = INARC_HOMING_ATTACHED;
01495                 break;
01496         }
01497 
01498         DOCHECK(!checkSectionForSpecial(mech, wPodType, wLoc),
01499                         tprintf("There are no iNarc %s pods attached to your %s!",
01500                                         strPodType, strLocation));
01501 
01502         DOCHECK(((!GetSectInt(mech, RARM)) &&
01503                          (!GetSectInt(mech, LARM))),
01504                         "You need atleast one functioning arm to remove iNarc pods!");
01505 
01506         if(wLoc == RARM) {
01507                 DOCHECK(!GetSectInt(mech, LARM),
01508                                 "Your Left Arm needs to be intact to take iNarc pods off your right arm!");
01509                 DOCHECK(SectHasBusyWeap(mech, LARM),
01510                                 "You have weapons recycling on your Left Arm.");
01511                 DOCHECK(MechSections(mech)[LARM].recycle,
01512                                 "Your Left Arm is still recovering from your last attack.");
01513 
01514                 wArmToUse = LARM;
01515         }
01516 
01517         if(wLoc == LARM) {
01518                 DOCHECK(!GetSectInt(mech, RARM),
01519                                 "Your Right Arm needs to be intact to take iNarc pods off your Left Arm!");
01520                 DOCHECK(SectHasBusyWeap(mech, RARM),
01521                                 "You have weapons recycling on your Right Arm.");
01522                 DOCHECK(MechSections(mech)[RARM].recycle,
01523                                 "Your Right Arm is still recovering from your last attack.");
01524 
01525                 wArmToUse = RARM;
01526         }
01527 
01528         if(wArmToUse == -1) {
01529                 if(SectHasBusyWeap(mech, RARM) || MechSections(mech)[RARM].recycle
01530                    || (!GetSectInt(mech, RARM)))
01531                         wRAAvail = 0;
01532 
01533                 if(SectHasBusyWeap(mech, LARM) || MechSections(mech)[LARM].recycle
01534                    || (!GetSectInt(mech, LARM)))
01535                         wLAAvail = 0;
01536 
01537                 DOCHECK(!(wLAAvail ||
01538                                   wRAAvail),
01539                                 "You need atleast one arm that is not recycling and does not have weapons recycling in it!");
01540 
01541                 if(!wLAAvail)
01542                         wBTHModLARM = 1000;
01543                 else
01544                         wBTHModLARM = findArmBTHMod(mech, LARM);
01545 
01546                 if(!wRAAvail)
01547                         wBTHModRARM = 1000;
01548                 else
01549                         wBTHModRARM = findArmBTHMod(mech, RARM);
01550 
01551                 if(wBTHModRARM < wBTHModLARM) {
01552                         wBTH = wBTHModRARM;
01553                         wArmToUse = RARM;
01554                 } else {
01555                         wBTH = wBTHModLARM;
01556                         wArmToUse = LARM;
01557                 }
01558         } else {
01559                 wBTH = findArmBTHMod(mech, wArmToUse);
01560         }
01561 
01562         wBTH += FindPilotPiloting(mech) + 4;
01563         wRoll = Roll();
01564 
01565         ArmorStringFromIndex(wArmToUse, strPunchWith, MechType(mech),
01566                                                  MechMove(mech));
01567 
01568         mech_printf(mech, MECHALL,
01569                                 "You try to swat at the iNarc pods attached to your %s with your %s.  BTH:  %d,\tRoll:  %d",
01570                                 strLocation, strPunchWith, wBTH, wRoll);
01571 
01572         /* Oops, we failed! */
01573         if(wRoll < wBTH) {
01574                 mech_notify(mech, MECHALL,
01575                                         "Uh oh. You miss the pod and hit yourself!");
01576                 MechLOSBroadcast(mech,
01577                                                  "tries to swat off an iNarc pod, but misses and hits itself!");
01578 
01579                 wSelfDamage = (MechTons(mech) + 10 / 2) / 10;
01580 
01581                 if(!OkayCritSectS(wArmToUse, 2, LOWER_ACTUATOR))
01582                         wSelfDamage = wSelfDamage / 2;
01583 
01584                 if(!OkayCritSectS(wArmToUse, 1, UPPER_ACTUATOR))
01585                         wSelfDamage = wSelfDamage / 2;
01586 
01587                 DamageMech(mech, mech, 1, MechPilot(mech), wLoc, 0, 0, wSelfDamage,
01588                                    0, -1, 0, -1, 0, 0);
01589         } else {
01590                 MechSections(mech)[wLoc].specials &= ~wPodType;
01591 
01592                 mech_printf(mech, MECHALL,
01593                                         "You knock a %s pod off your %s!", strPodType,
01594                                         strLocation);
01595                 MechLOSBroadcast(mech, "knocks an iNarc pod off itself.");
01596         }
01597 
01598         SetRecycleLimb(mech, wArmToUse, PHYSICAL_RECYCLE_TIME);
01599 }
01600 
01601 void removeiNarcPodsTank(MUXEVENT * e)
01602 {
01603         MECH *mech = (MECH *) e->data;
01604         int i;
01605 
01606         if(Destroyed(mech))
01607                 return;
01608 
01609         mech_notify(mech, MECHALL,
01610                                 "You remove all the iNARC pods from your unit.");
01611 
01612         MechLOSBroadcast(mech,
01613                                          "'s crew climbs out and knocks off all the attached iNarc pods!");
01614 
01615         for(i = 0; i < NUM_SECTIONS; i++) {
01616                 if(GetSectOInt(mech, i) > 0) {
01617                         MechSections(mech)[i].specials &=
01618                                 ~(INARC_HOMING_ATTACHED | INARC_HAYWIRE_ATTACHED |
01619                                   INARC_ECM_ATTACHED | INARC_NEMESIS_ATTACHED);
01620                 }
01621         }
01622 
01623 }
01624 
01625 void remove_inarc_pods_tank(dbref player, MECH * mech, char *buffer)
01626 {
01627         cch(MECH_USUALSO);
01628 
01629         DOCHECK((MechDesiredSpeed(mech) > 0),
01630                         "You can not be moving when attempting to remove iNarc pods!");
01631         DOCHECK((MechSpeed(mech) > 0),
01632                         "You can not be moving when attempting to remove iNarc pods!");
01633 
01634         if(MechType(mech) == CLASS_VTOL)
01635                 DOCHECK(!Landed(mech),
01636                                 "You must land before attempting to remove iNarc pods!");
01637 
01638         DOCHECK(CrewStunned(mech), "You're too stunned to remove iNarc pods!");
01639         DOCHECK(UnjammingTurret(mech),
01640                         "You're too busy unjamming your turret to remove iNarc pods!");
01641         DOCHECK(UnJammingAmmo(mech),
01642                         "You're too busy unjamming a weapon to remove iNarc pods!");
01643 
01644         if(!(checkAllSections(mech, INARC_HOMING_ATTACHED) ||
01645                  checkAllSections(mech, INARC_HAYWIRE_ATTACHED) ||
01646                  checkAllSections(mech, INARC_ECM_ATTACHED) ||
01647                  checkAllSections(mech, INARC_NEMESIS_ATTACHED))) {
01648 
01649                 mech_notify(mech, MECHALL,
01650                                         "There are no iNarc pods attached to this unit.");
01651 
01652                 return;
01653         }
01654 
01655         mech_notify(mech, MECHALL,
01656                                 "You begin to systematically remove all the iNarc pods from your unit.");
01657 
01658         MECHEVENT(mech, EVENT_REMOVE_PODS, removeiNarcPodsTank, 60, 0);
01659 }
01660 
01661 void mech_auto_turret(dbref player, MECH * mech, char *buffer)
01662 {
01663         cch(MECH_USUALSO);
01664 
01665         DOCHECK(!GetSectInt(mech, TURRET), "You have no turret to autoturn!");
01666 
01667         mech_printf(mech, MECHALL,
01668                                 "Automatic turret turning is now %s",
01669                                 (MechStatus2(mech) & AUTOTURN_TURRET) ? "OFF" : "ON");
01670 
01671         if(MechStatus2(mech) & AUTOTURN_TURRET)
01672                 MechStatus2(mech) &= ~AUTOTURN_TURRET;
01673         else
01674                 MechStatus2(mech) |= AUTOTURN_TURRET;
01675 }
01676 
01677 void mech_usebin(dbref player, MECH * mech, char *buffer)
01678 {
01679         char strLocation[80];
01680         int wLoc, wCurLoc;
01681         int wSection, wCritSlot, wWeapNum, wWeapType;
01682         char *args[2];
01683 
01684         cch(MECH_USUALSO);
01685 
01686         DOCHECK(mech_parseattributes(buffer, args, 2) != 2,
01687                         "Invalid number of arguments!");
01688 
01689         DOCHECK(Readnum(wWeapNum, args[0]), tprintf("Invalid value: %s",
01690                                                                                                 args[0]));
01691         wWeapType = FindWeaponNumberOnMech(mech, wWeapNum, &wSection, &wCritSlot);
01692 
01693         DOCHECK(wWeapType == -1,
01694                         "The weapons system chirps: 'Illegal Weapon Number!'");
01695         DOCHECK(wWeapType == -2,
01696                         "The weapons system chirps: 'That Weapon has been destroyed!'");
01697         DOCHECK(wWeapType == -3,
01698                         "The weapon system chirps: 'That weapon is still reloading!'");
01699         DOCHECK(wWeapType == -4,
01700                         "The weapon system chirps: 'That weapon is still recharging!'");
01701         DOCHECK(IsEnergy(wWeapType), "Energy weapons do not use ammo!");
01702 
01703         if(args[1][0] == '-') {
01704                 mech_printf(mech, MECHALL,
01705                                         "Prefered ammo source reset for weapon #%d", wWeapNum);
01706                 SetPartDesiredAmmoLoc(mech, wSection, wCritSlot, -1);
01707                 return;
01708         }
01709 
01710         wLoc = ArmorSectionFromString(MechType(mech), MechMove(mech), args[1]);
01711 
01712         DOCHECK(wLoc == -1, "Invalid section!");
01713         DOCHECK(!GetSectOInt(mech, wLoc), "Invalid section!");
01714         DOCHECK(!GetSectInt(mech, wLoc), "That section is destroyed!");
01715 
01716         ArmorStringFromIndex(wLoc, strLocation, MechType(mech), MechMove(mech));
01717         wCurLoc = GetPartDesiredAmmoLoc(mech, wSection, wCritSlot);
01718 
01719         DOCHECK(wCurLoc == wLoc,
01720                         tprintf("Prefered ammo source already set to %s for weapon #%d",
01721                                         strLocation, wWeapNum));
01722 
01723         mech_printf(mech, MECHALL,
01724                                 "Prefered ammo source set to %s for weapon #%d",
01725                                 strLocation, wWeapNum);
01726         SetPartDesiredAmmoLoc(mech, wSection, wCritSlot, wLoc);
01727 }
01728 
01729 void mech_safety(dbref player, void *data, char *buffer)
01730 {
01731         MECH *mech = (MECH *) data;
01732 
01733         DOCHECK(MechType(mech) == CLASS_MW, "Your weapons dont have safeties.");
01734         if(buffer && !strcasecmp(buffer, "on")) {
01735                 UnSetMechPKiller(mech);
01736                 mech_notify(mech, MECHALL, "Safeties flipped %ch%cgON%cn.");
01737                 return;
01738         }
01739         if(buffer && !strcasecmp(buffer, "off")) {
01740                 SetMechPKiller(mech);
01741                 mech_notify(mech, MECHALL, "Safeties flipped %ch%crOFF%cn.");
01742                 return;
01743         }
01744 
01745         mech_printf(mech, MECHPILOT, "Weapon safeties are %%ch%s%%cn",
01746                                 MechPKiller(mech) ? "%crOFF" : "%cgON");
01747         return;
01748 }
01749 
01750 #define MECHPREF_FLAG_INVERTED  0x01
01751 #define MECHPREF_FLAG_NEGATIVE  0x02
01752 
01753 static struct mechpref_info {
01754         unsigned char bit;
01755         unsigned char flags;
01756         char *name;
01757         char *msg;
01758 } mech_preferences[] = {
01759         {
01760         MECHPREF_PKILL, MECHPREF_FLAG_INVERTED, "MWSafety",
01761                         "MechWarrior Safeties flipped"}, {
01762         MECHPREF_SLWARN, MECHPREF_FLAG_INVERTED, "SLWarn",
01763                         "The warning when lit by searchlight is now"}, {
01764         MECHPREF_AUTOFALL, MECHPREF_FLAG_NEGATIVE, "AutoFall",
01765                         "Suicidal jumps off cliffs toggled"}, {
01766         MECHPREF_NOARMORWARN, MECHPREF_FLAG_INVERTED, "ArmorWarn",
01767                         "Low-armor warnings turned"}, {
01768         MECHPREF_NOAMMOWARN, MECHPREF_FLAG_INVERTED, "AmmoWarn",
01769                         "Warning when running out of Ammunition switched"}, {
01770         MECHPREF_AUTOCON_SD, MECHPREF_FLAG_NEGATIVE, "AutoconShutdown",
01771                         "Autocon on shutdown units turned"}, {
01772         MECHPREF_NOFRIENDLYFIRE, 0, "FFSafety",
01773                         "Friendly Fire Safeties flipped"},};
01774 #define NUM_MECHPREFERENCES (sizeof(mech_preferences) / sizeof(struct mechpref_info))
01775 
01776 static MECH *target_mech;
01777 
01778 static char *display_mechpref(int i)
01779 {
01780         static char buf[256];
01781         struct mechpref_info info = mech_preferences[i];
01782         char *state;
01783 
01784         if(!target_mech) {
01785                 SendError("Invalid target_mech in display_mechpref!");
01786                 return "Unknown error; contact a Wizard.";
01787         }
01788 
01789         if(((MechPrefs(target_mech) & info.bit) &&
01790                 (info.flags & MECHPREF_FLAG_INVERTED)) ||
01791            (!(MechPrefs(target_mech) & info.bit) &&
01792                 !(info.flags & MECHPREF_FLAG_INVERTED))) {
01793                 if(info.flags & MECHPREF_FLAG_NEGATIVE)
01794                         state = "%ch%cgOFF%cn";
01795                 else
01796                         state = "%ch%crOFF%cn";
01797         } else {
01798                 if(info.flags & MECHPREF_FLAG_NEGATIVE)
01799                         state = "%ch%crON%cn";
01800                 else
01801                         state = "%ch%cgON%cn";
01802         }
01803 
01804         sprintf(buf, "        %-40s%s", info.name, state);
01805         return buf;
01806 }
01807 
01808 void mech_mechprefs(dbref player, void *data, char *buffer)
01809 {
01810         MECH *mech = (MECH *) data;
01811         int nargs;
01812         char *args[3];
01813         char buf[LBUF_SIZE];
01814         coolmenu *c;
01815 
01816         cch(MECH_USUALSMO);
01817         nargs = mech_parseattributes(buffer, args, 2);
01818 
01819         /* Default, no arguments passed */
01820         if(!nargs) {
01821 
01822                 /* Show mechprefs */
01823                 target_mech = mech;
01824                 c = SelCol_FunStringMenuK(1, "Mech Preferences", display_mechpref,
01825                                                                   NUM_MECHPREFERENCES);
01826                 ShowCoolMenu(player, c);
01827                 KillCoolMenu(c);
01828                 target_mech = NULL;
01829 
01830         } else {
01831 
01832                 int i;
01833                 struct mechpref_info info;
01834                 char *newstate;
01835 
01836                 /* Looking through the different mech preferences to find the
01837                  * one the user wants to change */
01838                 for(i = 0; i < NUM_MECHPREFERENCES; i++) {
01839                         if(strcasecmp(args[0], mech_preferences[i].name) == 0)
01840                                 break;
01841                 }
01842                 if(i == NUM_MECHPREFERENCES) {
01843                         snprintf(buf, LBUF_SIZE, "Unknown MechPreference: %s", args[0]);
01844                         notify(player, buf);
01845                         return;
01846                 }
01847 
01848                 /* Get the current setting */
01849                 info = mech_preferences[i];
01850 
01851                 /* Did they provide a ON or OFF flag */
01852                 if(nargs == 2) {
01853 
01854                         /* Check to make sure its either ON or OFF */
01855                         if((strcasecmp(args[1], "ON") != 0) &&
01856                            (strcasecmp(args[1], "OFF") != 0)) {
01857 
01858                                 /* Insert notify here */
01859                                 notify(player, "Only accept ON or OFF as valid extra "
01860                                            "parameter for mechprefs pref");
01861                                 return;
01862                         }
01863 
01864                         /* Set the value to what they want */
01865                         if(strcasecmp(args[1], "ON") == 0) {
01866 
01867                                 /* Set the bit */
01868                                 if(info.flags & MECHPREF_FLAG_INVERTED) {
01869                                         MechPrefs(mech) &= ~(info.bit);
01870                                 } else {
01871                                         MechPrefs(mech) |= (info.bit);
01872                                 }
01873 
01874                         } else {
01875 
01876                                 /* Unset the bit */
01877                                 if(info.flags & MECHPREF_FLAG_INVERTED) {
01878                                         MechPrefs(mech) |= (info.bit);
01879                                 } else {
01880                                         MechPrefs(mech) &= ~(info.bit);
01881                                 }
01882 
01883                         }
01884 
01885                 } else {
01886 
01887                         /* If set, unset it, otherwise set the preference */
01888                         if(MechPrefs(mech) & info.bit)
01889                                 MechPrefs(mech) &= ~(info.bit);
01890                         else
01891                                 MechPrefs(mech) |= (info.bit);
01892 
01893                 }
01894 
01895                 /* Which way did the preference get changed and
01896                  * is it the default or non-standard mode of
01897                  * the preference */
01898                 if(((MechPrefs(mech) & info.bit) &&
01899                         (info.flags & MECHPREF_FLAG_INVERTED)) ||
01900                    (!(MechPrefs(mech) & info.bit) &&
01901                         !(info.flags & MECHPREF_FLAG_INVERTED))) {
01902 
01903                         if(info.flags & MECHPREF_FLAG_NEGATIVE)
01904                                 newstate = "%ch%cgOFF%cn";
01905                         else
01906                                 newstate = "%ch%crOFF%cn";
01907 
01908                 } else {
01909 
01910                         if(info.flags & MECHPREF_FLAG_NEGATIVE)
01911                                 newstate = "%ch%crON%cn";
01912                         else
01913                                 newstate = "%ch%cgON%cn";
01914 
01915                 }
01916 
01917                 /* Tell them the preference has been changed */
01918                 snprintf(buf, LBUF_SIZE, "%s %s", info.msg, newstate);
01919                 notify(player, buf);
01920         }
01921 }

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