00001
00002
00003
00004
00005
00006
00007
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
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
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
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, §ion, &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
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
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, §ion, &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
00813 DestroyPart(mech, RLEG, 0);
00814 DestroyPart(mech, LLEG, 0);
00815
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
00824 MechCritStatus(mech) |= HIP_DESTROYED;
00825
00826
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);
01000
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
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
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
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;
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, §ion, &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
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
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
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
01820 if(!nargs) {
01821
01822
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
01837
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
01849 info = mech_preferences[i];
01850
01851
01852 if(nargs == 2) {
01853
01854
01855 if((strcasecmp(args[1], "ON") != 0) &&
01856 (strcasecmp(args[1], "OFF") != 0)) {
01857
01858
01859 notify(player, "Only accept ON or OFF as valid extra "
01860 "parameter for mechprefs pref");
01861 return;
01862 }
01863
01864
01865 if(strcasecmp(args[1], "ON") == 0) {
01866
01867
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
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
01888 if(MechPrefs(mech) & info.bit)
01889 MechPrefs(mech) &= ~(info.bit);
01890 else
01891 MechPrefs(mech) |= (info.bit);
01892
01893 }
01894
01895
01896
01897
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
01918 snprintf(buf, LBUF_SIZE, "%s %s", info.msg, newstate);
01919 notify(player, buf);
01920 }
01921 }