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 "map.h"
00018 #include "btmacros.h"
00019 #include "mech.events.h"
00020 #include "create.h"
00021 #include "failures.h"
00022 #include "mech.combat.h"
00023 #include "mech.partnames.h"
00024 #include "p.mech.ice.h"
00025 #include "p.pcombat.h"
00026 #include "p.mech.utils.h"
00027 #include "p.mech.los.h"
00028 #include "p.mech.build.h"
00029 #include "p.map.obj.h"
00030 #include "p.mech.combat.h"
00031 #include "p.btechstats.h"
00032 #include "p.mech.update.h"
00033 #include "p.bsuit.h"
00034 #include "p.artillery.h"
00035 #include "p.mech.fire.h"
00036 #include "p.mech.c3.h"
00037 #include "p.mech.c3i.h"
00038 #include "p.mech.c3.misc.h"
00039 #include "p.mine.h"
00040 #include "p.mech.hitloc.h"
00041 #include "p.eject.h"
00042 #include "p.crit.h"
00043 #include "p.mech.ood.h"
00044 #include "p.map.conditions.h"
00045 #include "p.template.h"
00046 #include "p.mech.pickup.h"
00047 #include "p.event.h"
00048 #include "p.mech.tag.h"
00049 #include "p.mech.ecm.h"
00050 #include "mech.ecm.h"
00051 #include "p.mech.enhanced.criticals.h"
00052 #include "p.mech.spot.h"
00053 #include "p.mech.combat.misc.h"
00054 #include "p.mech.combat.missile.h"
00055 #include "p.mech.bth.h"
00056 #include "p.mech.damage.h"
00057
00058 extern int arc_override;
00059 extern dbref pilot_override;
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 void mech_target(dbref player, void *data, char *buffer)
00096 {
00097 MECH *mech = (MECH *) data;
00098 MECH *target;
00099 char *args[5];
00100 int argc;
00101 char section[50];
00102 char type, move, index;
00103
00104 cch(MECH_USUALO);
00105 argc = mech_parseattributes(buffer, args, 5);
00106 DOCHECK(argc != 1, "Invalid number of arguments to function!");
00107 if(!strcmp(args[0], "-")) {
00108 MechAim(mech) = NUM_SECTIONS;
00109 notify(player, "Targetting disabled.");
00110 return;
00111 }
00112 DOCHECK(MechTarget(mech) < 0 ||
00113 !(target =
00114 FindObjectsData(MechTarget(mech))),
00115 "Error: You need to be locked onto something to target its part!");
00116 type = MechType(target);
00117 move = MechMove(target);
00118 DOCHECK((index =
00119 ArmorSectionFromString(type, move, args[0])) < 0,
00120 "Invalid location!");
00121 MechAim(mech) = index;
00122 MechAimType(mech) = type;
00123 ArmorStringFromIndex(index, section, type, move);
00124 notify_printf(player, "%s targetted.", section);
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 char *ss_messages[] = {
00136 "You feel you'll have your hands full before too long..",
00137 "You have a bad feeling about this..",
00138 "You feel a homicidal maniac is about to pounce on you!",
00139
00140 "You think something is amiss..",
00141 "You have a slightly bad feeling about this..",
00142 "You think someone thinks ill of you..",
00143
00144 "Something makes you somewhat feel uneasy..",
00145 "Something makes you definitely feel uneasy..",
00146 "Something makes you feel out of your element.."
00147 };
00148
00149 #define SSDistMod(r) ((r < 9) ? 0 : ((r < 20) ? 1 : 2))
00150 #define SSTonMod(d) ((d <= -20) ? 0 : (d >= 20) ? 2 : 1)
00151
00152 static void mech_ss_event(MUXEVENT * ev)
00153 {
00154 MECH *mech = (MECH *) ev->data;
00155 int i = (int) ev->data2;
00156
00157 if(Uncon(mech))
00158 return;
00159 if(!RGotPilot(mech))
00160 return;
00161 mech_notify(mech, MECHPILOT, ss_messages[BOUNDED(0, i, 8)]);
00162 }
00163
00164 void sixth_sense_check(MECH * mech, MECH * target)
00165 {
00166 float r;
00167 int d;
00168
00169 if(!(MechSpecials(target) & SS_ABILITY) || MechIsObservator(mech))
00170 return;
00171 if(Destroyed(target))
00172 return;
00173 if(Roll() > 8)
00174 return;
00175 r = FaMechRange(mech, target);
00176 d = (MechRTonsV(mech) - MechRTonsV(target)) / 1024;
00177 MECHEVENT(target, EVENT_SS, mech_ss_event, Number(1, 3),
00178 ((3 * (SSDistMod(r))) + (SSTonMod(d))));
00179 }
00180
00181 void mech_settarget(dbref player, void *data, char *buffer)
00182 {
00183 MECH *mech = (MECH *) data, *target;
00184 MAP *mech_map;
00185 char *args[5];
00186 char targetID[2];
00187 int argc;
00188 int LOS = 1;
00189 int newx, newy;
00190 dbref targetref;
00191 int mode;
00192
00193 cch(MECH_USUALO);
00194
00195 argc = mech_parseattributes(buffer, args, 5);
00196 switch (argc) {
00197 case 1:
00198 mech_map = getMap(mech->mapindex);
00199 if(args[0][0] == '-') {
00200 MechTarget(mech) = -1;
00201 MechTargX(mech) = -1;
00202 MechTargY(mech) = -1;
00203 mech_notify(mech, MECHALL, "All locks cleared.");
00204 StopLock(mech);
00205 if(MechSpotter(mech) == mech->mynum)
00206 ClearFireAdjustments(mech_map, mech->mynum);
00207 return;
00208 }
00209 targetID[0] = args[0][0];
00210 targetID[1] = args[0][1];
00211 targetref = FindTargetDBREFFromMapNumber(mech, targetID);
00212 target = getMech(targetref);
00213 if(target)
00214 LOS =
00215 InLineOfSight(mech, target, MechX(target), MechY(target),
00216 FlMechRange(mech_map, mech, target));
00217 else
00218 targetref = -1;
00219 DOCHECK(targetref == -1 ||
00220 !LOS, "That is not a valid targetID. Try again.");
00221
00222 if(MechSwarmTarget(mech) > 0) {
00223 if(MechSwarmTarget(mech) != target->mynum) {
00224 mech_notify(mech, MECHALL,
00225 "You're a bit too busy holding on for dear life to lock a target!");
00226 return;
00227 }
00228 }
00229
00230 mech_printf(mech, MECHALL, "Target set to %s.",
00231 GetMechToMechID(mech, target));
00232 StopLock(mech);
00233 MechTarget(mech) = targetref;
00234 MechStatus(mech) |= LOCK_TARGET;
00235 sixth_sense_check(mech, target);
00236 #if LOCK_TICK > 0
00237 if(!arc_override)
00238 MECHEVENT(mech, EVENT_LOCK, mech_lock_event, LOCK_TICK, 0);
00239 #endif
00240 break;
00241 case 2:
00242
00243 if(MechSwarmTarget(mech) > 0) {
00244 mech_notify(mech, MECHALL,
00245 "You're a bit too busy holding on for dear life to lock a target!");
00246 return;
00247 }
00248
00249 mech_map = getMap(mech->mapindex);
00250 newx = atoi(args[0]);
00251 newy = atoi(args[1]);
00252 ValidCoord(mech_map, newx, newy);
00253 MechTarget(mech) = -1;
00254 MechTargX(mech) = newx;
00255 MechTargY(mech) = newy;
00256 MechFireAdjustment(mech) = 0;
00257 if(MechSpotter(mech) == mech->mynum)
00258 ClearFireAdjustments(mech_map, mech->mynum);
00259 MechTargZ(mech) = Elevation(mech_map, newx, newy);
00260 notify_printf(player, "Target coordinates set at (X,Y) %d, %d",
00261 newx, newy);
00262 StopLock(mech);
00263 MechStatus(mech) |= LOCK_TARGET;
00264 #if LOCK_TICK > 0
00265 if(!arc_override)
00266 MECHEVENT(mech, EVENT_LOCK, mech_lock_event, LOCK_TICK, 0);
00267 #endif
00268 break;
00269 case 3:
00270
00271 if(MechSwarmTarget(mech) > 0) {
00272 mech_notify(mech, MECHALL,
00273 "You're a bit too busy holding on for dear life to lock a target!");
00274 return;
00275 }
00276
00277 DOCHECK(strlen(args[2]) > 1, "Invalid lock mode!");
00278 switch (toupper(args[2][0])) {
00279 case 'B':
00280 mode = LOCK_BUILDING;
00281 break;
00282 case 'I':
00283 mode = LOCK_HEX_IGN;
00284 break;
00285 case 'C':
00286 mode = LOCK_HEX_CLR;
00287 break;
00288 case 'H':
00289 mode = LOCK_HEX;
00290 break;
00291 default:
00292 notify(player, "Invalid mode selected!");
00293 return;
00294 }
00295 mech_map = getMap(mech->mapindex);
00296 newx = atoi(args[0]);
00297 newy = atoi(args[1]);
00298 ValidCoord(mech_map, newx, newy);
00299 MechTarget(mech) = -1;
00300 MechTargX(mech) = newx;
00301 MechTargY(mech) = newy;
00302 MechFireAdjustment(mech) = 0;
00303 if(MechSpotter(mech) == mech->mynum)
00304 ClearFireAdjustments(mech_map, mech->mynum);
00305 MechTargZ(mech) = Elevation(mech_map, newx, newy);
00306 switch (mode) {
00307 case LOCK_HEX:
00308 notify_printf(player,
00309 "Target coordinates set to hex at (X,Y) %d, %d",
00310 newx, newy);
00311 break;
00312 case LOCK_HEX_CLR:
00313 notify_printf(player,
00314 "Target coordinates set to clearing hex at (X,Y) %d, %d",
00315 newx, newy);
00316 break;
00317 case LOCK_HEX_IGN:
00318 notify_printf(player,
00319 "Target coordinates set to igniting hex at (X,Y) %d, %d",
00320 newx, newy);
00321 break;
00322 default:
00323 notify_printf(player,
00324 "Target coordinates set to building at (X,Y) %d, %d",
00325 newx, newy);
00326 break;
00327 }
00328
00329 StopLock(mech);
00330 MechStatus(mech) |= mode;
00331 #if LOCK_TICK > 0
00332 if(!arc_override)
00333 MECHEVENT(mech, EVENT_LOCK, mech_lock_event, LOCK_TICK, 0);
00334 #endif
00335 }
00336 }
00337
00338
00339
00340
00341 void mech_fireweapon(dbref player, void *data, char *buffer)
00342 {
00343 MECH *mech = (MECH *) data;
00344 MAP *mech_map;
00345 char *args[5];
00346 int argc;
00347 int weapnum;
00348
00349 mech_map = getMap(mech->mapindex);
00350 cch(MECH_USUALO);
00351 argc = mech_parseattributes(buffer, args, 5);
00352 DOCHECK(argc < 1, "Not enough arguments to the function");
00353 weapnum = atoi(args[0]);
00354 FireWeaponNumber(player, mech, mech_map, weapnum, argc, args, 0);
00355 }
00356
00357 #define ARCCHECK(mech,ex,ey,sec,crit,msg) \
00358 if (AeroUnusableArcs(mech)) \
00359 { int ar; ar = InWeaponArc(mech, ex, ey); \
00360 DOCHECK0((!arc_override && (AeroUnusableArcs(mech) & ar)) || \
00361 (arc_override && !(arc_override & ar)), \
00362 "That arc's weapons aren't under your control!"); \
00363 }; \
00364 DOCHECK0(!IsInWeaponArc (mech, ex, ey, sec, crit), \
00365 msg);
00366
00367
00368
00369
00370 int FireWeaponNumber(dbref player,
00371 MECH * mech,
00372 MAP * mech_map, int weapnum, int argc, char **args,
00373 int sight)
00374 {
00375 int weaptype;
00376 dbref target;
00377 char targetID[2];
00378 int mapx = 0, mapy = 0, LOS = 0;
00379 MECH *tempMech = NULL;
00380 int section, critical;
00381 float range = 0;
00382 float enemyX, enemyY, enemyZ;
00383 int ishex = 0;
00384 int wcDeadLegs = 0;
00385 char location[20];
00386 int mode;
00387 int i;
00388
00389 if(MechType(mech) == CLASS_BSUIT) {
00390 for(i = 0; i < NUM_BSUIT_MEMBERS; i++) {
00391 DOCHECK1(!SectIsDestroyed(mech, i) &&
00392 MechSections(mech)[i].recycle,
00393 tprintf("Suit %d is still recovering from attack.",
00394 i + 1));
00395 }
00396 }
00397
00398
00399 if(!sight && (MechCritStatus(mech) & HIDDEN)) {
00400 mech_notify(mech, MECHALL,
00401 "You break out of your cover to initiate weapons fire!");
00402 MechLOSBroadcast(mech,
00403 "breaks out of its cover and begins firing rabidly!");
00404 MechCritStatus(mech) &= ~HIDDEN;
00405 }
00406
00407
00408 if(!sight) {
00409 StopHiding(mech);
00410 }
00411 #ifdef BT_MOVEMENT_MODES
00412 DOCHECK0(MoveModeLock(mech),
00413 "You cannot fire while using a special movement mode.");
00414 #endif
00415 DOCHECK0(MechSpotter(mech) > 0
00416 && MechSpotter(mech) == mech->mynum,
00417 "You cannot fire while spotting.");
00418 DOCHECK0(weapnum < 0,
00419 "The weapons system chirps: 'Illegal Weapon Number!'");
00420
00421 weaptype =
00422 FindWeaponNumberOnMech_Advanced(mech, weapnum, §ion, &critical,
00423 sight);
00424
00425 DOCHECK0(weaptype == -1,
00426 "The weapons system chirps: 'Illegal Weapon Number!'");
00427
00428 mode = GetPartFireMode(mech, section, critical);
00429
00430 if(!sight) {
00431
00432
00433 DOCHECK0((MechCritStatus(mech) & MECH_STUNNED),
00434 "You cannot take actions while stunned! That includes finding the trigger.");
00435
00436 DOCHECK0(PartTempNuke(mech, section, critical),
00437 "The weapons system chirps: 'That weapon is still unusable - please stand by.'");
00438 DOCHECK0(weaptype == -3,
00439 "The weapons system chirps: 'That weapon is still reloading!'");
00440 DOCHECK0(weaptype == -4,
00441 "The weapons system chirps: 'That weapon is still recharging!'");
00442
00443
00444
00445 if(weaptype == -5) {
00446
00447
00448 ArmorStringFromIndex(section, location, MechType(mech),
00449 MechMove(mech));
00450 notify_printf(player, "%s%s is still recovering from a "
00451 "previous action!",
00452 MechType(mech) == CLASS_BSUIT ? "" : "Your ",
00453 location);
00454 return 0;
00455 }
00456
00457 DOCHECK0(MechSections(mech)[section].specials & CARRYING_CLUB,
00458 "You're carrying a club in that arm.");
00459
00460 if(Fallen(mech) && MechType(mech) == CLASS_MECH) {
00461
00462
00463 wcDeadLegs = CountDestroyedLegs(mech);
00464 if(MechIsQuad(mech))
00465 DOCHECK0(wcDeadLegs > 2,
00466 "Quads need at least 3 legs to fire while prone.");
00467
00468
00469 if(!MechIsQuad(mech) || (MechIsQuad(mech) && wcDeadLegs > 0)) {
00470 DOCHECK0(section == RLEG || section == LLEG,
00471 "You cannot fire leg mounted weapons when prone.");
00472 switch (section) {
00473 case RARM:
00474 DOCHECK0(SectHasBusyWeap(mech, LARM) ||
00475 MechSections(mech)[LARM].recycle ||
00476 SectIsDestroyed(mech, LARM),
00477 "You currently can't use your Left Arm to prop yourself up.");
00478 break;
00479 case LARM:
00480 DOCHECK0(SectHasBusyWeap(mech, RARM) ||
00481 MechSections(mech)[RARM].recycle ||
00482 SectIsDestroyed(mech, RARM),
00483 "Your currently can't use your Right Arm to prop yourself up.");
00484 break;
00485 default:
00486 DOCHECK0((SectHasBusyWeap(mech, RARM) ||
00487 MechSections(mech)[RARM].recycle ||
00488 SectIsDestroyed(mech, RARM))
00489 && (SectHasBusyWeap(mech, LARM) ||
00490 MechSections(mech)[LARM].recycle ||
00491 SectIsDestroyed(mech, LARM)),
00492 "You currently don't have any arms to spare to prop yourself up.");
00493 }
00494 }
00495 }
00496 }
00497
00498 if(IsMechMounted(mech)) {
00499 DOCHECK0(((section == CTORSO) || (section == RTORSO) ||
00500 (section == LTORSO)),
00501 "You cannot fire torso-mounted weapons while you have battlesuits on you!");
00502 }
00503
00504 DOCHECK0((MechDugIn(mech)) && section != TURRET,
00505 "Only turret weapons are available while in cover.");
00506 DOCHECK0(weaptype == -2 ||
00507 (PartTempNuke(mech, section, critical) == FAIL_DESTROYED),
00508 "The weapons system chirps: 'That weapon has been destroyed!'");
00509 DOCHECK0(IsAMS(weaptype), "That weapon is defensive only!");
00510 DOCHECK0(argc > 3, "Invalid number of arguments!");
00511
00512 if((MechWeapons[weaptype].special & IDF) && MechSpotter(mech) != -1 &&
00513 MechTarget(mech) == -1 && MechTargY(mech) == -1 &&
00514 MechTargX(mech) == -1)
00515 if(FireSpot(player, mech, mech_map, weapnum, weaptype, sight,
00516 section, critical))
00517 return 1;
00518
00519 switch (argc) {
00520
00521
00522 case 1:
00523
00524
00525 if(IsCoolant(weaptype) && (mode & HEAT_MODE)) {
00526
00527
00528
00529 tempMech = mech;
00530 DOCHECK0(!tempMech, "Error in FireWeaponNumber routine");
00531 mapx = MechX(tempMech);
00532 mapy = MechY(tempMech);
00533 range = 0.2;
00534 LOS = 1;
00535
00536 } else {
00537
00538 DOCHECK0(!FindTargetXY(mech, &enemyX, &enemyY, &enemyZ),
00539 "You do not have a default target set!");
00540
00541 if(MechTarget(mech) != -1) {
00542
00543 tempMech = getMech(MechTarget(mech));
00544 DOCHECK0(!tempMech, "Error in FireWeaponNumber routine");
00545 mapx = MechX(tempMech);
00546 mapy = MechY(tempMech);
00547 range = FaMechRange(mech, tempMech);
00548 LOS = LOS_NB(mech, tempMech, mapx, mapy, range);
00549
00550 if(!(MechWeapons[weaptype].special & IDF)) {
00551 DOCHECK0(!LOS,
00552 "That target is not in your line of sight!");
00553 } else if(MapIsUnderground(mech_map)) {
00554 DOCHECK0(!LOS,
00555 "That target is not in your direct line of sight, and "
00556 "you cannot fire your IDF weapons underground!");
00557 }
00558 if(mudconf.btech_idf_requires_spotter
00559 && (MechWeapons[weaptype].special & IDF)
00560 && (MechSpotter(mech) == -1))
00561 DOCHECK0(!LOS,
00562 "That target is not in your direct line of sight"
00563 " and you do not have a spotter set!!");
00564 } else {
00565
00566
00567 ishex = 1;
00568 if(!sight && !IsArtillery(weaptype) && MechLockFire(mech)) {
00569
00570
00571 if((tempMech =
00572 find_mech_in_hex(mech, mech_map, MechTargX(mech),
00573 MechTargY(mech), 0))) {
00574
00575 enemyX = MechFX(tempMech);
00576 enemyY = MechFY(tempMech);
00577 enemyZ = MechFZ(tempMech);
00578 mapx = MechX(tempMech);
00579 mapy = MechY(tempMech);
00580 }
00581
00582 }
00583
00584 if(!tempMech) {
00585 mapx = MechTargX(mech);
00586 mapy = MechTargY(mech);
00587 MechTargZ(mech) = Elevation(mech_map, mapx, mapy);
00588 enemyZ = ZSCALE * MechTargZ(mech);
00589 MapCoordToRealCoord(mapx, mapy, &enemyX, &enemyY);
00590 }
00591
00592
00593 range =
00594 FindRange(MechFX(mech), MechFY(mech), MechFZ(mech),
00595 enemyX, enemyY, enemyZ);
00596 LOS = LOS_NB(mech, tempMech, mapx, mapy, range);
00597
00598
00599 if(mudconf.btech_idf_requires_spotter &&
00600 (MechWeapons[weaptype].special & IDF)
00601 && (MechSpotter(mech) == -1))
00602 DOCHECK0(!LOS,
00603 "That hex target is not in your direct line of sight"
00604 " and you do not have a spotter set!!");
00605
00606 if(!
00607 (IsArtillery(weaptype)
00608 || (MechWeapons[weaptype].special & IDF))) {
00609 DOCHECK0(!LOS,
00610 "That hex target is not in your line of sight!");
00611 } else if(MapIsUnderground(mech_map)) {
00612 DOCHECK0(!LOS,
00613 "That target is not in your direct line of sight, and "
00614 "you cannot fire your IDF weapons underground!");
00615 }
00616 }
00617
00618 if(MechType(mech) != CLASS_BSUIT) {
00619 ARCCHECK(mech, enemyX, enemyY, section, critical,
00620 "Default target is not in your weapons arc!");
00621 }
00622 }
00623 break;
00624
00625 case 2:
00626
00627 targetID[0] = args[1][0];
00628 targetID[1] = args[1][1];
00629 target = FindTargetDBREFFromMapNumber(mech, targetID);
00630 DOCHECK0(target == -1, "That target is not in your line of sight!");
00631 tempMech = getMech(target);
00632 DOCHECK0(!tempMech, "Error in FireWeaponNumber routine!");
00633 enemyX = MechFX(tempMech);
00634 enemyY = MechFY(tempMech);
00635 enemyZ = MechFZ(tempMech);
00636 mapx = MechX(tempMech);
00637 mapy = MechY(tempMech);
00638
00639 range = FindRange(MechFX(mech), MechFY(mech), MechFZ(mech), enemyX,
00640 enemyY, enemyZ);
00641 LOS = LOS_NB(mech, tempMech, MechX(tempMech), MechY(tempMech), range);
00642
00643 DOCHECK0(!LOS, "That target is not in your line of sight!");
00644
00645 if(MechType(mech) != CLASS_BSUIT) {
00646 ARCCHECK(mech, enemyX, enemyY, section, critical,
00647 "That target is not in your weapons arc!");
00648 }
00649 break;
00650
00651 case 3:
00652
00653
00654 mapx = atoi(args[1]);
00655 mapy = atoi(args[2]);
00656 ishex = 1;
00657 DOCHECK0(mapx < 0 || mapx >= mech_map->map_width || mapy < 0 ||
00658 mapy >= mech_map->map_height,
00659 "Map coordinates out of range!");
00660
00661 if(!sight && !IsArtillery(weaptype))
00662
00663
00664 if((tempMech = find_mech_in_hex(mech, mech_map, MechTargX(mech),
00665 MechTargY(mech), 0))) {
00666 enemyX = MechFX(tempMech);
00667 enemyY = MechFY(tempMech);
00668 enemyZ = MechFZ(tempMech);
00669 }
00670
00671 if(!tempMech) {
00672 MapCoordToRealCoord(mapx, mapy, &enemyX, &enemyY);
00673 MechTargZ(mech) = Elevation(mech_map, mapx, mapy);
00674 enemyZ = ZSCALE * MechTargZ(mech);
00675 }
00676
00677 if(MechType(mech) != CLASS_BSUIT) {
00678 ARCCHECK(mech, enemyX, enemyY, section, critical,
00679 "That hex target is not in your weapons arc!");
00680 }
00681
00682
00683 range = FindRange(MechFX(mech), MechFY(mech), MechFZ(mech), enemyX,
00684 enemyY, enemyZ);
00685 LOS = LOS_NB(mech, tempMech, mapx, mapy, range);
00686
00687 if(!IsArtillery(weaptype))
00688 DOCHECK0(!LOS, "That hex target is not in your line of sight!");
00689 }
00690
00691 if(tempMech) {
00692 DOCHECK0(IsArtillery(weaptype),
00693 "You can only target hexes with this kind of artillery.");
00694 DOCHECK0(MechSwarmTarget(tempMech) == mech->mynum,
00695 "You are unable to use your weapons against a 'swarmer!");
00696 DOCHECK0(StealthArmorActive(tempMech) &&
00697 ((MechTarget(mech) != tempMech->mynum) || Locking(mech)),
00698 "You need a stable lock to fire on that target!");
00699 DOCHECK0(!IsCoolant(weaptype) && MechTeam(tempMech) == MechTeam(mech)
00700 && MechNoFriendlyFire(mech),
00701 "You can't fire on a teammate with FFSafeties on!");
00702 DOCHECK0(!IsCoolant(weaptype) && MechTeam(tempMech) == MechTeam(mech)
00703 && MapNoFriendlyFire(mech_map),
00704 "Friendly Fire? I don't think so...");
00705 DOCHECK0(MechType(tempMech) == CLASS_MW && MechType(mech) != CLASS_MW
00706 && !MechPKiller(mech),
00707 "That's a living, breathing person! Switch off the safety first, "
00708 "if you really want to assassinate the target.");
00709 }
00710
00711 FireWeapon(mech, mech_map, tempMech, LOS, weaptype, weapnum, section,
00712 critical, enemyX, enemyY, mapx, mapy, range, 1000, sight,
00713 ishex);
00714 return (1);
00715 }
00716
00717 int weapon_failure_stuff(MECH * mech,
00718 int *weapnum,
00719 int *weapindx,
00720 int *section,
00721 int *critical,
00722 int *ammoLoc,
00723 int *ammoCrit,
00724 int *ammoLoc1,
00725 int *ammoCrit1,
00726 int *modifier,
00727 int *type, float range, int *range_ok,
00728 int wGattlingShots)
00729 {
00730 CheckWeaponFailed(mech, *weapnum, *weapindx, *section, *critical,
00731 modifier, type);
00732 if(*type == POWER_SPIKE)
00733 return 1;
00734 if(*type == WEAPON_JAMMED || *type == WEAPON_DUD) {
00735
00736 decrement_ammunition(mech, *weapindx, *section, *critical,
00737 *ammoLoc, *ammoCrit, *ammoLoc1, *ammoCrit1,
00738 wGattlingShots);
00739 return 1;
00740 }
00741 if(*type == RANGE)
00742 if((EGunRangeWithCheck(mech, *section,
00743 *weapindx) - *modifier) < range) {
00744 mech_notify(mech, MECHALL,
00745 "Due to weapons failure your shot falls short of its target!");
00746 *range_ok = 0;
00747 }
00748 return 0;
00749 }
00750
00751 void sendC3TrackEmit(MECH * mech, dbref c3Ref, MECH * c3Mech)
00752 {
00753 if(c3Mech && (c3Mech->mynum != mech->mynum)) {
00754 mech_printf(mech, MECHALL,
00755 "Using range data from %s [%s]",
00756 silly_atr_get(c3Mech->mynum,
00757 A_MECHNAME), MechIDS(c3Mech, 1));
00758 }
00759 }
00760
00761 void FireWeapon(MECH * mech,
00762 MAP * mech_map,
00763 MECH * target,
00764 int LOS,
00765 int weapindx,
00766 int weapnum,
00767 int section,
00768 int critical,
00769 float enemyX,
00770 float enemyY,
00771 int mapx,
00772 int mapy, float range, int indirectFire, int sight, int ishex)
00773 {
00774 MECH *altTarget;
00775 int baseToHit,RbaseToHit;
00776 int ammoLoc;
00777 int ammoCrit;
00778 int ammoLoc1;
00779 int ammoCrit1;
00780 int roll;
00781 int r1, r2, r3, rtmp;
00782 int type = -1, modifier;
00783 int isarty = (IsArtillery(weapindx));
00784 int range_ok = 1;
00785 int wGattlingShots = 0;
00786 char buf[SBUF_SIZE];
00787 char buf3[SBUF_SIZE];
00788 char buf2[LBUF_SIZE];
00789 int wRACHeat = 0;
00790 int wHGRPSkillMod = 0;
00791 int tIsSwarmAttack = 0;
00792 dbref c3Ref = -1;
00793 MECH *c3Mech = NULL;
00794 int firstCrit = 0;
00795 int mode = GetPartFireMode(mech, section, critical);
00796 int wAmmoMode = GetPartAmmoMode(mech, section, critical);
00797
00798 DOCHECKMA((wAmmoMode & STINGER_MODE)
00799 && ishex, "Stinger missiles cannot shoot hexes!");
00800 DOCHECKMA((wAmmoMode & STINGER_MODE) && target
00801 && !(Jumping(target) || OODing(target)
00802 || (FlyingT(target)
00803 && !Landed(target))),
00804 "Stinger missiles can only engage airborne targets!");
00805
00806
00807
00808 if(IsCoolant(weapindx) && mode & HEAT_MODE)
00809 target = mech;
00810
00811 DOCHECKMA((SectionUnderwater(mech, section) &&
00812 (MechWeapons[weapindx].shortrange_water <= 0)),
00813 "This weapon may not be fired underwater.");
00814 DOCHECKMA(CrewStunned(mech), "You are too stunned to fire a weapon!");
00815 DOCHECKMA(UnjammingTurret(mech),
00816 "You are too busy unjamming your turret!");
00817 DOCHECKMA(UnJammingAmmo(mech), "You are too busy unjamming a weapon!");
00818 DOCHECKMA(RemovingPods(mech), "You are too busy removing iNARC pods!");
00819
00820 DOCHECKMA((MechSwarmTarget(mech) > 0) && ((!target) ||
00821 (MechSwarmTarget(mech) !=
00822 target->mynum)),
00823 "You're too busy holding on for dear life!");
00824
00825 if(MechSwarmTarget(mech) > 0) {
00826 if(target && (MechSwarmTarget(mech) == target->mynum))
00827 tIsSwarmAttack = 1;
00828 }
00829
00830
00831
00832
00833
00834 if(GetPartFireMode(mech, section, critical) & GATTLING_MODE)
00835 wGattlingShots = Number(1, 6);
00836
00837
00838 if(!sight)
00839 if(!FindAndCheckAmmo(mech, weapindx, section, critical, &ammoLoc,
00840 &ammoCrit, &ammoLoc1, &ammoCrit1,
00841 &wGattlingShots))
00842 return;
00843
00844
00845
00846
00847 if(!isarty) {
00848 baseToHit =
00849 FindNormalBTH(mech, mech_map, section, critical, weapindx,
00850 range, target, indirectFire, &c3Ref);
00851
00852 if(c3Ref) {
00853 c3Mech = getMech(c3Ref);
00854
00855 if(c3Mech && ((MechTeam(c3Mech) != MechTeam(mech)) ||
00856 (c3Ref == mech->mynum))) {
00857 c3Mech = NULL;
00858 }
00859 }
00860
00861 } else
00862 baseToHit = FindArtilleryBTH(mech, section, weapindx, !LOS, range);
00863
00864
00865 if(tIsSwarmAttack)
00866 baseToHit = 0;
00867
00868
00869 if((MechWeapons[weapindx].special & DFM) ||
00870 ((MechWeapons[weapindx].special & ELRM) &&
00871 range < MechWeapons[weapindx].min)) {
00872 r1 = Number(1, 6);
00873 r2 = Number(1, 6);
00874 r3 = Number(1, 6);
00875
00876 if(r1 > r2)
00877 Swap(r1, r2);
00878 if(r2 > r3)
00879 Swap(r2, r3);
00880 roll = r1 + r2;
00881 } else {
00882 if(target)
00883 roll = Roll();
00884 else
00885 roll = Roll();
00886 }
00887 buf[0] = 0;
00888 if(LOS)
00889 sprintf(buf, "Roll: %d ", roll);
00890
00891
00892
00893
00894
00895
00896
00897
00898 if(target && !ishex) {
00899 range = FaMechRange(mech, target);
00900 strcpy(buf2, "");
00901 if(MechAim(mech) != NUM_SECTIONS &&
00902 MechAimType(mech) == MechType(target) && !IsMissile(weapindx)) {
00903 ArmorStringFromIndex(MechAim(mech), buf3, MechType(target),
00904 MechMove(target));
00905 sprintf(buf2, "'s %s", buf3);
00906 }
00907
00908 if(sight) {
00909 DOCHECKMA(baseToHit >= 900,
00910 tprintf("You aim %s at %s%s - Out of range.",
00911 &MechWeapons[weapindx].name[3],
00912 GetMechToMechID(mech, target), buf2));
00913
00914 sendC3TrackEmit(mech, c3Ref, c3Mech);
00915
00916 mech_printf(mech, MECHALL,
00917 "You aim %s at %s%s - BTH: %d %s",
00918 &MechWeapons[weapindx].name[3],
00919 GetMechToMechID(mech, target), buf2,
00920 baseToHit,
00921 MechStatus(target) & PARTIAL_COVER ?
00922 "(Partial cover)" : "");
00923 return;
00924 }
00925 if(baseToHit > 12) {
00926 DOCHECKMA(baseToHit >= 900,
00927 tprintf("Fire %s at %s%s - Out of range.",
00928 &MechWeapons[weapindx].name[3],
00929 GetMechToMechID(mech, target), buf2));
00930 mech_printf(mech, MECHALL,
00931 "Fire %s at %s%s - BTH: %d Roll: Impossible! %s",
00932 &MechWeapons[weapindx].name[3],
00933 GetMechToMechID(mech, target), buf2, baseToHit,
00934 MechStatus(target) & PARTIAL_COVER ?
00935 "(Partial cover)" : "");
00936 return;
00937 }
00938 } else {
00939
00940 if(sight) {
00941 if(baseToHit > 900)
00942 mech_printf(mech, MECHPILOT,
00943 "You aim your %s at (%d,%d) - Out of Range.",
00944 &MechWeapons[weapindx].name[3], mapx, mapy);
00945 else {
00946 sendC3TrackEmit(mech, c3Ref, c3Mech);
00947
00948 mech_printf(mech, MECHPILOT,
00949 "You aim your %s at (%d,%d) - BTH: %d",
00950 &MechWeapons[weapindx].name[3], mapx,
00951 mapy, baseToHit);
00952 }
00953
00954 return;
00955 }
00956 if(!isarty && baseToHit > 12) {
00957 mech_printf(mech, MECHALL,
00958 "Fire %s at (%d,%d) - BTH: %d Roll: Impossible!",
00959 &MechWeapons[weapindx].name[3], mapx, mapy,
00960 baseToHit);
00961 return;
00962 }
00963 }
00964
00965 if(target && !ishex) {
00966 sendC3TrackEmit(mech, c3Ref, c3Mech);
00967
00968 mech_printf(mech, MECHALL,
00969 "You fire %s at %s%s - BTH: %d %s%s",
00970 &MechWeapons[weapindx].name[3],
00971 GetMechToMechID(mech, target), buf2, baseToHit,
00972 buf,
00973 MechStatus(target) & PARTIAL_COVER ?
00974 "(Partial cover)" : "");
00975
00976
00977
00978
00979
00980 SendAttacks(tprintf("#%i attacks #%i (weapon) (%i/%i)",
00981 mech->mynum, target->mynum, baseToHit, roll));
00982
00983
00984
00985
00986
00987
00988
00989 if(MechStatus2(target) & ATTACKEMIT_MECH)
00990 SendAttackEmits(tprintf("#%i attacks #%i (weapon) (%i/%i)",
00991 mech->mynum, target->mynum, baseToHit,
00992 roll));
00993
00994 } else {
00995 sendC3TrackEmit(mech, c3Ref, c3Mech);
00996
00997 mech_printf(mech, MECHALL,
00998 "You fire %s %s (%d,%d) - BTH: %d %s",
00999 &MechWeapons[weapindx].name[3],
01000 hex_target_id(mech), mapx, mapy, baseToHit, buf);
01001
01002
01003
01004
01005
01006 SendAttacks(tprintf("#%i attacks %d,%d (%s) (weapon) (%i/%i)",
01007 mech->mynum, mapx, mapy, short_hextarget(mech),
01008 baseToHit, roll));
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 {
01020 MECH *tmpmech;
01021 int foo;
01022
01023 for(foo = 0; foo < mech_map->first_free; foo++) {
01024
01025 if(mech_map->mechsOnMap[foo] >= 0) {
01026
01027 if(!(tmpmech = getMech(mech_map->mechsOnMap[foo])))
01028 continue;
01029 if(mech->mynum == tmpmech->mynum)
01030 continue;
01031 if(MechX(tmpmech) != mapx && MechY(tmpmech) != mapy)
01032 continue;
01033 if(MechStatus2(tmpmech) & ATTACKEMIT_MECH)
01034 SendAttackEmits(tprintf
01035 ("#%i attacks %d,%d (%s) (weapon)"
01036 " (%i/%i)", mech->mynum, mapx, mapy,
01037 short_hextarget(mech), baseToHit,
01038 roll));
01039 }
01040
01041 }
01042
01043 }
01044
01045 }
01046
01047
01048
01049
01050
01051
01052 if(weapon_failure_stuff(mech, &weapnum, &weapindx, §ion,
01053 &critical, &ammoLoc, &ammoCrit, &ammoLoc1,
01054 &ammoCrit1, &modifier, &type, range,
01055 &range_ok, wGattlingShots))
01056 return;
01057
01058
01059 if(MechWeapons[weapindx].special & STREAK) {
01060 if(target && (AngelECMDisturbed(mech) || AngelECMProtected(target)))
01061 mech_notify(mech, MECHALL,
01062 "The ECM confuses your streak homing system!");
01063 else if(roll < baseToHit) {
01064 SetRecyclePart(mech, section, critical,
01065 WEAPON_TICK * MechWeapons[weapindx].vrt);
01066 mech_notify(mech, MECHALL, "Your streak fails to lock on.");
01067 return;
01068 }
01069 }
01070
01071
01072 if(GetPartFireMode(mech, section, critical) & HOTLOAD_MODE) {
01073 if(roll == 2 || roll == 3) {
01074 mech_printf(mech, MECHALL,
01075 "%%ch%%crThe ammo loading mechanism jams on your %s!%%cn",
01076 &(MechWeapons[weapindx].name[3]));
01077 SetPartTempNuke(mech, section, critical, FAIL_AMMOJAMMED);
01078 return;
01079 }
01080 }
01081
01082
01083 if(GetPartAmmoMode(mech, section, critical) & AC_CASELESS_MODE) {
01084 if(roll == 2 || roll == 3) {
01085 mech_printf(mech, MECHALL,
01086 "%%ch%%crThe ammo loading mechanism jams on your %s!%%cn",
01087 &(MechWeapons[weapindx].name[3]));
01088 SetPartTempNuke(mech, section, critical, FAIL_AMMOJAMMED);
01089
01090 if(Roll() > 7 ) {
01091
01092 mech_printf(mech, MECHALL,
01093 "%%ch%%crPropellant from your %s ignites and destroys it!%%cn",
01094 &(MechWeapons[weapindx].name[3]));
01095 firstCrit = FindFirstWeaponCrit(mech, section, -1, 0, I2Weapon(weapindx), GetWeaponCrits(mech,weapindx));
01096 DestroyWeapon(mech, section, I2Weapon(weapindx), firstCrit,
01097 GetWeaponCrits(mech, weapindx), GetWeaponCrits(mech,weapindx));
01098 MechLOSBroadcast(mech, "shudders from an internal explosion!");
01099
01100
01101 DamageMech(mech, mech, 0, -1, section, 0, 1, 0,
01102 MechWeapons[weapindx].damage, -1, 0, -1, 0,1);
01103 decrement_ammunition(mech, weapindx, section, critical, ammoLoc, ammoCrit,
01104 ammoLoc1, ammoCrit1, wGattlingShots);
01105
01106
01107 }
01108
01109 return;
01110 }
01111 }
01112
01113
01114 if(GetPartFireMode(mech, section, critical) & RFAC_MODE) {
01115 if(roll == 2) {
01116 mech_printf(mech, MECHALL,
01117 "%%ch%%crA catastrophic misload on your %s destroys it and causes an internal explosion!%%cn",
01118 &(MechWeapons[weapindx].name[3]));
01119 firstCrit =
01120 FindFirstWeaponCrit(mech, section, -1, 0,
01121 I2Weapon(weapindx), GetWeaponCrits(mech,
01122 weapindx));
01123 DestroyWeapon(mech, section, I2Weapon(weapindx), firstCrit,
01124 GetWeaponCrits(mech, weapindx), GetWeaponCrits(mech,
01125 weapindx));
01126 MechLOSBroadcast(mech, "shudders from an internal explosion!");
01127 DamageMech(mech, mech, 0, -1, section, 0, 0, 0,
01128 MechWeapons[weapindx].damage, -1, 0, -1, 0, 1);
01129 decrement_ammunition(mech, weapindx, section, critical,
01130 ammoLoc, ammoCrit, ammoLoc1, ammoCrit1,
01131 wGattlingShots);
01132 return;
01133 } else if(roll < 5) {
01134 mech_printf(mech, MECHALL,
01135 "%%ch%%crThe ammo loader mechanism jams on your %s!%%cn",
01136 &(MechWeapons[weapindx].name[3]));
01137 SetPartTempNuke(mech, section, critical, FAIL_AMMOJAMMED);
01138 return;
01139 }
01140 }
01141
01142
01143 if(MechWeapons[weapindx].special & RAC) {
01144 if(((GetPartFireMode(mech, section, critical) & RAC_TWOSHOT_MODE)
01145 && (roll == 2)) ||
01146 ((GetPartFireMode(mech, section, critical) & RAC_FOURSHOT_MODE)
01147 && (roll <= 3)) ||
01148 ((GetPartFireMode(mech, section, critical) & RAC_SIXSHOT_MODE)
01149 && (roll <= 4))) {
01150 mech_printf(mech, MECHALL,
01151 "%%ch%%crThe ammo loader mechanism jams on your %s!%%cn",
01152 &(MechWeapons[weapindx].name[3]));
01153 SetPartTempNuke(mech, section, critical, FAIL_AMMOJAMMED);
01154 return;
01155 }
01156 }
01157
01158
01159 if(GetPartFireMode(mech, section, critical) & ULTRA_MODE) {
01160 if(roll == 2) {
01161 mech_printf(mech, MECHALL,
01162 "The loader jams on your %s, destroying it!",
01163 &(MechWeapons[weapindx].name[3]));
01164 firstCrit =
01165 FindFirstWeaponCrit(mech, section, -1, 0,
01166 I2Weapon(weapindx), GetWeaponCrits(mech,
01167 weapindx));
01168 DestroyWeapon(mech, section, I2Weapon(weapindx), firstCrit,
01169 GetWeaponCrits(mech, weapindx), GetWeaponCrits(mech,
01170 weapindx));
01171 return;
01172 }
01173 }
01174
01175
01176 if(canWeapExplodeFromDamage(mech, section, critical, roll)) {
01177 if(IsEnergy(weapindx)) {
01178 mech_printf(mech, MECHALL,
01179 "%%ch%%crThe damaged charging crystal on your %s overloads!%%cn",
01180 &(MechWeapons[weapindx].name[3]));
01181 } else {
01182 mech_printf(mech, MECHALL,
01183 "%%ch%%crThe damaged ammo feed on your %s triggers an internal explosion!%%cn",
01184 &(MechWeapons[weapindx].name[3]));
01185 decrement_ammunition(mech, weapindx, section, critical,
01186 ammoLoc, ammoCrit, ammoLoc1, ammoCrit1,
01187 wGattlingShots);
01188 }
01189
01190 MechLOSBroadcast(mech, "shudders from an internal explosion!");
01191 firstCrit =
01192 FindFirstWeaponCrit(mech, section, -1, 0, I2Weapon(weapindx),
01193 GetWeaponCrits(mech, weapindx));
01194 DestroyWeapon(mech, section, I2Weapon(weapindx), firstCrit,
01195 GetWeaponCrits(mech, weapindx), GetWeaponCrits(mech,
01196 weapindx));
01197 DamageMech(mech, mech, 0, -1, section, 0, 0, 0,
01198 MechWeapons[weapindx].damage, -1, 0, -1, 0, 1);
01199
01200 return;
01201 }
01202
01203
01204 if(canWeapJamFromDamage(mech, section, critical, roll)) {
01205 mech_printf(mech, MECHALL,
01206 "%%ch%%crThe ammo loader mechanism jams on your %s!%%cn",
01207 &(MechWeapons[weapindx].name[3]));
01208 SetPartTempNuke(mech, section, critical, FAIL_AMMOCRITJAMMED);
01209
01210 return;
01211 }
01212
01213
01214 if(OODing(mech)) {
01215 if(MechZ(mech) > MechElevation(mech)) {
01216 if(MechJumpSpeed(mech) >= MP1) {
01217 mech_notify(mech, MECHALL,
01218 "You initiate your jumpjets to compensate for the opened cocoon!");
01219 MechCocoon(mech) = -1;
01220 } else {
01221 mech_notify(mech, MECHALL,
01222 "Your action splits open the cocoon - have a nice fall!");
01223 MechLOSBroadcast(mech,
01224 "starts plummeting down, as the cocoon opens!.");
01225 MechCocoon(mech) = 0;
01226 StopOOD(mech);
01227 MECHEVENT(mech, EVENT_FALL, mech_fall_event, FALL_TICK, -1);
01228 }
01229 }
01230 }
01231
01232
01233
01234
01235
01236
01237
01238 RbaseToHit = baseToHit;
01239 if(mudconf.btech_glancing_blows == 2)
01240 RbaseToHit = baseToHit - 1;
01241
01242 if(!isarty)
01243 MechFireBroadcast(mech, ishex ? NULL : target, mapx, mapy,
01244 mech_map, &MechWeapons[weapindx].name[3],
01245 (roll >= RbaseToHit) && range_ok);
01246
01247
01248 if(target) {
01249 if(InLineOfSight(target, mech, MechX(mech), MechY(mech), range))
01250 mech_printf(target, MECHALL,
01251 "%s has fired a %s at you!",
01252 GetMechToMechID(target, mech),
01253 &MechWeapons[weapindx].name[3]);
01254 else
01255 mech_printf(target, MECHALL,
01256 "Something has fired a %s at you from bearing %d!",
01257 &MechWeapons[weapindx].name[3],
01258 FindBearing(MechFX(target), MechFY(target),
01259 MechFX(mech), MechFY(mech)));
01260 }
01261
01262
01263 MechStatus(mech) |= FIRED;
01264
01265 if(isarty) {
01266 artillery_shoot(mech, mapx, mapy, weapindx,
01267 GetPartAmmoMode(mech, section, critical),
01268 baseToHit <= roll);
01269 } else if(range_ok) {
01270 if(IsMissile(weapindx)) {
01271 HitTarget(mech, weapindx, section, critical, target, mapx,
01272 mapy, LOS, type, modifier,
01273 (roll >= RbaseToHit) && range_ok, baseToHit, wGattlingShots, tIsSwarmAttack,
01274 roll);
01275 } else {
01276 if(roll >= RbaseToHit) {
01277 HitTarget(mech, weapindx, section, critical, target, mapx,
01278 mapy, LOS, type, modifier, 1, RbaseToHit,
01279 wGattlingShots, tIsSwarmAttack, roll);
01280 } else {
01281 int tTryClear = 1;
01282
01283 if(target) {
01284 if((MechType(target) == CLASS_BSUIT) &&
01285 (MechSwarmTarget(target) > -1) &&
01286 (altTarget = getMech(MechSwarmTarget(target)))) {
01287
01288 baseToHit =
01289 FindNormalBTH(mech, mech_map, section,
01290 critical, weapindx, range,
01291 altTarget, indirectFire, &c3Ref);
01292
01293 if(roll >= baseToHit) {
01294 mech_notify(altTarget, MECHALL,
01295 "The shot hits you instead!");
01296 MechLOSBroadcast(altTarget,
01297 "manages to get in the way of the shot instead!");
01298 HitTarget(mech, weapindx, section, critical,
01299 altTarget, mapx, mapy, LOS, type,
01300 modifier, 1, baseToHit, wGattlingShots,
01301 tIsSwarmAttack, roll);
01302
01303 tTryClear = 0;
01304 } else {
01305 if(Elevation(mech_map, MechX(target),
01306 MechY(target)) < (MechZ(target) - 2))
01307 tTryClear = 0;
01308 }
01309 }
01310 }
01311
01312 if(tTryClear) {
01313 int tempDamage =
01314 determineDamageFromHit(mech, section, critical,
01315 target, mapx,
01316 mapy, weapindx, wGattlingShots,
01317 MechWeapons[weapindx].damage,
01318 GetPartAmmoMode(mech, section,
01319 critical),
01320 type,
01321 modifier, 1);
01322
01323 possibly_ignite_or_clear(mech, weapindx,
01324 GetPartAmmoMode(mech, section,
01325 critical),
01326 tempDamage, mapx, mapy, 0);
01327 }
01328 }
01329 }
01330 }
01331
01332
01333 SetRecyclePart(mech, section, critical,
01334 WEAPON_TICK * MechWeapons[weapindx].vrt);
01335
01336
01337
01338
01339 if(type == HEAT)
01340 MechWeapHeat(mech) += (float) modifier;
01341
01342 if(GetPartFireMode(mech, section, critical) & GATTLING_MODE) {
01343 MechWeapHeat(mech) += wGattlingShots;
01344 } else if(MechWeapons[weapindx].special & RAC) {
01345 if(GetPartFireMode(mech, section, critical) & RAC_TWOSHOT_MODE)
01346 wRACHeat = 2;
01347 else if(GetPartFireMode(mech, section, critical) & RAC_FOURSHOT_MODE)
01348 wRACHeat = 4;
01349 else if(GetPartFireMode(mech, section, critical) & RAC_SIXSHOT_MODE)
01350 wRACHeat = 6;
01351 else
01352 wRACHeat = 1;
01353
01354 MechWeapHeat(mech) += (float) (MechWeapons[weapindx].heat * wRACHeat);
01355
01356 if(type == HEAT)
01357 MechWeapHeat(mech) += (float) (modifier * wRACHeat);
01358 } else {
01359 MechWeapHeat(mech) += (float) MechWeapons[weapindx].heat;
01360
01361 if(IsEnergy(weapindx))
01362 MechWeapHeat(mech) +=
01363 (float) getCritAddedHeat(mech, section, critical);
01364
01365 if((GetPartFireMode(mech, section, critical) & ULTRA_MODE) ||
01366 (GetPartFireMode(mech, section, critical) & RFAC_MODE)) {
01367
01368 if(type == HEAT)
01369 MechWeapHeat(mech) += (float) modifier;
01370
01371 MechWeapHeat(mech) += (float) MechWeapons[weapindx].heat;
01372 }
01373 }
01374
01375
01376
01377
01378
01379
01380 decrement_ammunition(mech, weapindx, section, critical, ammoLoc,
01381 ammoCrit, ammoLoc1, ammoCrit1, wGattlingShots);
01382
01383
01384 if((MechWeapons[weapindx].special & HVYGAUSS) &&
01385 (MechType(mech) == CLASS_MECH)) {
01386 if(abs(MechSpeed(mech)) > 0.0) {
01387 mech_notify(mech, MECHALL,
01388 "You realize that moving while firing this weapon may not be a good idea after all.");
01389 if(MechTons(mech) <= 35)
01390 wHGRPSkillMod = 2;
01391 else if(MechTons(mech) <= 55)
01392 wHGRPSkillMod = 1;
01393 else if(MechTons(mech) <= 75)
01394 wHGRPSkillMod = 0;
01395 else
01396 wHGRPSkillMod = -1;
01397 if(!MadePilotSkillRoll(mech, wHGRPSkillMod)) {
01398 mech_notify(mech, MECHALL,
01399 "The weapon's recoil knocks you to the ground!");
01400 MechLOSBroadcast(mech,
01401 tprintf("topples over from the %s's recoil!",
01402 &MechWeapons[weapindx].name[3]));
01403 MechFalls(mech, 1, 0);
01404 }
01405 }
01406 }
01407 }
01408
01409 int determineDamageFromHit(MECH * mech,
01410 int wSection,
01411 int wCritSlot,
01412 MECH * hitMech,
01413 int hitX,
01414 int hitY,
01415 int weapindx,
01416 int wGattlingShots,
01417 int wBaseWeapDamage,
01418 int wAmmoMode, int type, int modifier,
01419 int isTempCalc)
01420 {
01421 MAP *mech_map;
01422 float fRange = 0.0;
01423 int wWeapDamage = wBaseWeapDamage;
01424 int wClearDamage = 0;
01425
01426
01427 if(hitMech)
01428 fRange = FaMechRange(mech, hitMech);
01429 else {
01430 float fx, fy;
01431 MapCoordToRealCoord(hitX, hitY, &fx, &fy);
01432 fRange = FindHexRange(MechFX(mech), MechFY(mech), fx, fy);
01433 }
01434
01435
01436 if(wGattlingShots > 0)
01437 wWeapDamage = wGattlingShots;
01438
01439
01440 if(MechWeapons[weapindx].special & HVYGAUSS) {
01441 if(fRange > MechWeapons[weapindx].medrange)
01442 wWeapDamage = 10;
01443 else if(fRange > MechWeapons[weapindx].shortrange)
01444 wWeapDamage = 20;
01445 }
01446
01447 wWeapDamage -= getCritSubDamage(mech, wSection, wCritSlot);
01448
01449
01450 if(hitMech) {
01451 if(wAmmoMode & AC_FLECHETTE_MODE) {
01452 if(MechType(hitMech) == CLASS_MW) {
01453 if(MechRTerrain(hitMech) == GRASSLAND)
01454 wWeapDamage *= 4;
01455 else
01456 wWeapDamage *= 2;
01457 } else if(MechType(hitMech) != CLASS_BSUIT)
01458 wWeapDamage /= 2;
01459 }
01460
01461 if(wAmmoMode & AC_INCENDIARY_MODE) {
01462 if(MechType(hitMech) == CLASS_MW)
01463 wWeapDamage += 2;
01464 }
01465 }
01466
01467
01468 if(mudconf.btech_moddamagewithrange && IsEnergy(weapindx)) {
01469 if(fRange <= 1.0)
01470 wWeapDamage++;
01471 else {
01472 if(SectionUnderwater(mech, wSection)) {
01473 if(fRange > MechWeapons[weapindx].longrange_water)
01474 wWeapDamage = (wWeapDamage / 2);
01475 else if(fRange > MechWeapons[weapindx].medrange_water)
01476 wWeapDamage--;
01477 } else {
01478 if(fRange > MechWeapons[weapindx].longrange)
01479 wWeapDamage = (wWeapDamage / 2);
01480 else if(fRange > MechWeapons[weapindx].medrange)
01481 wWeapDamage--;
01482 }
01483 }
01484 }
01485
01486
01487 mech_map = getMap(mech->mapindex);
01488
01489
01490 if(type == DAMAGE)
01491 wWeapDamage -= modifier;
01492
01493 if(hitMech && !isTempCalc) {
01494 if(mudconf.btech_moddamagewithwoods &&
01495 IsForestHex(mech_map, MechX(hitMech), MechY(hitMech)) &&
01496 ((MechZ(hitMech) - 2) <= Elevation(mech_map, MechX(hitMech),
01497 MechY(hitMech)))) {
01498 wClearDamage = wWeapDamage;
01499
01500 if(GetRTerrain(mech_map, MechX(hitMech),
01501 MechY(hitMech)) == LIGHT_FOREST)
01502 wWeapDamage -= 2;
01503 else if(GetRTerrain(mech_map, MechX(hitMech),
01504 MechY(hitMech)) == HEAVY_FOREST)
01505 wWeapDamage -= 4;
01506
01507 mech_notify(mech, MECHALL, "The woods absorb some of your shot!");
01508 mech_notify(hitMech, MECHALL,
01509 "The woods absorb some of the damage!");
01510
01511 possibly_ignite_or_clear(mech, weapindx, wAmmoMode,
01512 wClearDamage, MechX(hitMech),
01513 MechY(hitMech), 1);
01514 }
01515 }
01516
01517 if(wWeapDamage <= 0)
01518 wWeapDamage = 1;
01519
01520 return wWeapDamage;
01521 }
01522
01523 void HitTarget(MECH * mech,
01524 int weapindx,
01525 int wSection,
01526 int wCritSlot,
01527 MECH * hitMech,
01528 int hitX,
01529 int hitY,
01530 int LOS,
01531 int type,
01532 int modifier,
01533 int reallyhit, int bth, int wGattlingShots, int tIsSwarmAttack,
01534 int player_roll)
01535 {
01536 int isrear = 0, iscritical = 0;
01537 int hitloc = 0;
01538 int loop;
01539 int roll;
01540 int aim_hit = 0;
01541 int wBaseWeapDamage = MechWeapons[weapindx].damage;
01542 int wWeapDamage = 0;
01543 int num_missiles_hit;
01544 int wFireMode = GetPartFireMode(mech, wSection, wCritSlot);
01545 int wAmmoMode = GetPartAmmoMode(mech, wSection, wCritSlot);
01546 int tIsUltra = ((wFireMode & ULTRA_MODE) || (wFireMode & RFAC_MODE));
01547 int tIsRAC = (wFireMode & RAC_MODES);
01548 int tIsLBX = (wAmmoMode & LBX_MODE);
01549 int tIsSwarm = ((wAmmoMode & SWARM_MODE) || (wAmmoMode & SWARM1_MODE));
01550 char strMissileFakeName[30];
01551 int tFoundRACFake = 0;
01552 int tUsingTC = ((wFireMode & ON_TC) && !IsArtillery(weapindx) &&
01553 !IsMissile(weapindx) &&
01554 (!(MechCritStatus(mech) & TC_DESTROYED)) &&
01555 ((MechAim(mech) != NUM_SECTIONS) && hitMech &&
01556 (MechAimType(mech) == MechType(hitMech))));
01557 int missileindex = 0;
01558
01559 if(hitMech) {
01560
01561
01562 if((MechAim(mech) != NUM_SECTIONS) && hitMech && Immobile(hitMech)
01563 && !tIsSwarmAttack) {
01564
01565 roll = Roll();
01566
01567 if(roll == 6 || roll == 7 || roll == 8)
01568 aim_hit = 1;
01569 }
01570
01571 }
01572
01573 if(!IsMissile(weapindx)) {
01574 wWeapDamage =
01575 determineDamageFromHit(mech, wSection, wCritSlot, hitMech, hitX,
01576 hitY, weapindx, wGattlingShots,
01577 wBaseWeapDamage, wAmmoMode, type, modifier,
01578 0);
01579
01580
01581 if((mudconf.btech_glancing_blows) && (player_roll == bth) && hitMech) {
01582
01583
01584
01585 MechLOSBroadcast(hitMech, "is nicked by a glancing blow!");
01586 mech_notify(hitMech, MECHALL,
01587 "You are nicked by a glancing blow!");
01588 wWeapDamage = (int ) (wWeapDamage +1) / 2 ;
01589 if(wWeapDamage < 1 )
01590 wWeapDamage = 1;
01591 }
01592 }
01593
01594
01595
01596
01597
01598 if(!IsArtillery(weapindx) && !IsMissile(weapindx) && !tIsUltra &&
01599 !tIsLBX && !tIsRAC) {
01600
01601 if(hitMech) {
01602
01603
01604 if((IsFlamer(weapindx)) && (wFireMode & HEAT_MODE)) {
01605
01606 mech_notify(hitMech, MECHALL,
01607 "%cy%chThe flaming plasma sprays all over you!%cn");
01608 mech_notify(mech, MECHALL,
01609 "%cgYou cover your target in flaming plasma!%cn");
01610 MechWeapHeat(hitMech) += (float) wBaseWeapDamage;
01611 return;
01612
01613 } else if((IsCoolant(weapindx))
01614 && (MechType(hitMech) != CLASS_MW)) {
01615
01616
01617
01618
01619
01620 if(wFireMode & HEAT_MODE) {
01621
01622
01623 mech_notify(mech, MECHALL,
01624 "%ccCoolant washes over your systems!!%c");
01625 MechWeapHeat(mech) -= (float) wBaseWeapDamage;
01626
01627 } else {
01628
01629
01630 mech_notify(mech, MECHALL,
01631 "%ccYou hit with the stream of coolant!!%c");
01632 mech_notify(hitMech, MECHALL,
01633 "%ccCoolant washes over your systems!!%c");
01634 MechWeapHeat(hitMech) -= (float) wBaseWeapDamage;
01635
01636 }
01637
01638
01639 return;
01640
01641 }
01642
01643 if(aim_hit)
01644 hitloc = FindAimHitLoc(mech, hitMech, &isrear, &iscritical);
01645 else if(tUsingTC)
01646 hitloc = FindTCHitLoc(mech, hitMech, &isrear, &iscritical);
01647 else
01648 hitloc =
01649 FindTargetHitLoc(mech, hitMech, &isrear, &iscritical);
01650
01651 DamageMech(hitMech, mech, LOS, GunPilot(mech), hitloc, isrear,
01652 iscritical, pc_to_dam_conversion(hitMech, weapindx,
01653 wWeapDamage), 0,
01654 weapindx, bth, weapindx, wAmmoMode, tIsSwarmAttack);
01655
01656 } else {
01657 hex_hit(mech, hitX, hitY, weapindx, wAmmoMode, wWeapDamage, 1);
01658 }
01659
01660 return;
01661 }
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677 if(tIsRAC) {
01678 if(GetPartFireMode(mech, wSection, wCritSlot) & RAC_TWOSHOT_MODE)
01679 strcpy(strMissileFakeName, "IS.SRM-2");
01680 else if(GetPartFireMode(mech, wSection,
01681 wCritSlot) & RAC_FOURSHOT_MODE)
01682 strcpy(strMissileFakeName, "IS.SRM-4");
01683 else if(GetPartFireMode(mech, wSection, wCritSlot) & RAC_SIXSHOT_MODE)
01684 strcpy(strMissileFakeName, "IS.SRM-6");
01685 for(loop = 0; MissileHitTable[loop].key != -1; loop++) {
01686 if(!strcmp(MissileHitTable[loop].name, strMissileFakeName)) {
01687 tFoundRACFake = 1;
01688 break;
01689 }
01690 }
01691
01692 if(!tFoundRACFake)
01693 return;
01694 } else {
01695 for(loop = 0; MissileHitTable[loop].key != -1; loop++)
01696 if(MissileHitTable[loop].key == weapindx)
01697 break;
01698 if(!(MissileHitTable[loop].key == weapindx))
01699 return;
01700 }
01701
01702 if(IsMissile(weapindx)) {
01703 if(player_roll < bth )
01704 {
01705 return;
01706 }
01707 else
01708
01709 if(tIsSwarm && hitMech)
01710 SwarmHitTarget(mech, weapindx, wSection, wCritSlot, hitMech,
01711 LOS, bth, reallyhit ? bth + 1 : bth - 1,
01712 (type ==
01713 CRAZY_MISSILES) ? MissileHitTable[loop].
01714 num_missiles[10] * modifier /
01715 100 : MissileHitTable[loop].num_missiles[10],
01716 (GetPartAmmoMode(mech, wSection, wCritSlot) &
01717 SWARM1_MODE), tIsSwarmAttack, player_roll);
01718 else
01719 MissileHitTarget(mech, weapindx, wSection, wCritSlot, hitMech,
01720 hitX, hitY, LOS ? 1 : 0, bth,
01721 reallyhit ? bth + 1 : bth - 1,
01722 (type ==
01723 CRAZY_MISSILES) ? MissileHitTable[loop].
01724 num_missiles[10] * modifier /
01725 100 : MissileHitTable[loop].num_missiles[10],
01726 tIsSwarmAttack, player_roll);
01727
01728 return;
01729 }
01730
01731 missileindex = MissileHitIndex(mech, hitMech,weapindx, wSection, wCritSlot, (mudconf.btech_glancing_blows) && (player_roll == bth) ? 1: 0);
01732
01733 if (missileindex == -1)
01734 num_missiles_hit = 1;
01735 else
01736 num_missiles_hit = MissileHitTable[loop].num_missiles[missileindex];
01737
01738
01739
01740
01741 if(LOS)
01742 mech_printf(mech, MECHALL,
01743 "%%cgYou hit with %d %s%s!%%c",
01744 num_missiles_hit, (tIsUltra ||
01745 tIsRAC ? "slug" : tIsLBX ? "pellet" :
01746 "missile"),
01747 (num_missiles_hit > 1 ? "s" : ""));
01748
01749 if(tIsLBX)
01750 Missile_Hit(mech, hitMech, hitX, hitY, isrear, iscritical,
01751 weapindx, wFireMode, wAmmoMode, num_missiles_hit,
01752 tIsLBX ? 1 : wWeapDamage, Clustersize(weapindx), LOS, bth,
01753 tIsSwarmAttack);
01754 else {
01755 while (num_missiles_hit) {
01756 if(hitMech) {
01757 if(aim_hit)
01758 hitloc =
01759 FindAimHitLoc(mech, hitMech, &isrear, &iscritical);
01760 if(tUsingTC)
01761 hitloc =
01762 FindTCHitLoc(mech, hitMech, &isrear, &iscritical);
01763 else
01764 hitloc =
01765 FindTargetHitLoc(mech, hitMech, &isrear, &iscritical);
01766 DamageMech(hitMech, mech, LOS, GunPilot(mech), hitloc,
01767 isrear, iscritical, pc_to_dam_conversion(hitMech,
01768 weapindx,
01769 wWeapDamage),
01770 0, weapindx, bth, weapindx, wAmmoMode,
01771 tIsSwarmAttack);
01772 } else
01773 hex_hit(mech, hitX, hitY, weapindx, wAmmoMode, wWeapDamage,
01774 1);
01775
01776 num_missiles_hit--;
01777 }
01778 }
01779
01780 }
01781
01782
01783
01784
01785
01786 char *hex_target_id(MECH * mech)
01787 {
01788 if(MechStatus(mech) & LOCK_HEX_IGN)
01789 return "at the hex, trying to ignite it";
01790 if(MechStatus(mech) & LOCK_HEX_CLR)
01791 return "at the hex, trying to clear it";
01792 if(MechStatus(mech) & LOCK_HEX)
01793 return "at the hex";
01794 if(MechStatus(mech) & LOCK_BUILDING)
01795 return "at the building at";
01796 return "at";
01797 }
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825 int canWeaponIgnite(int weapindx)
01826 {
01827 if(strcmp(&MechWeapons[weapindx].name[3], "ERSmallLaser") &&
01828 strcmp(&MechWeapons[weapindx].name[3], "SmallLaser") &&
01829 strcmp(&MechWeapons[weapindx].name[3], "SmallPulseLaser") &&
01830 strcmp(&MechWeapons[weapindx].name[3], "X-SmallPulseLaser") &&
01831 strcmp(&MechWeapons[weapindx].name[3], "ERSmallPulseLaser") &&
01832 strcmp(&MechWeapons[weapindx].name[3], "HeavySmallLaser") &&
01833 strcmp(&MechWeapons[weapindx].name[3], "GaussRifle") &&
01834 strcmp(&MechWeapons[weapindx].name[3], "LightGaussRifle") &&
01835 strcmp(&MechWeapons[weapindx].name[3], "HeavyGaussRifle") &&
01836 strcmp(&MechWeapons[weapindx].name[3], "MagshotGaussRifle") &&
01837 strcmp(&MechWeapons[weapindx].name[3], "MachineGun") &&
01838 strcmp(&MechWeapons[weapindx].name[3], "LightMachineGun") &&
01839 strcmp(&MechWeapons[weapindx].name[3], "HeavyMachineGun") &&
01840 strcmp(&MechWeapons[weapindx].name[3], "StreakSRM-2") &&
01841 strcmp(&MechWeapons[weapindx].name[3], "SRM-2") &&
01842 strcmp(&MechWeapons[weapindx].name[3], "NarcBeacon") &&
01843 strcmp(&MechWeapons[weapindx].name[3], "iNarcBeacon"))
01844 return 1;
01845
01846 return 0;
01847 }
01848
01849 int canWeaponClear(int weapindx)
01850 {
01851 if(strcmp(&MechWeapons[weapindx].name[3], "ERSmallLaser") &&
01852 strcmp(&MechWeapons[weapindx].name[3], "SmallLaser") &&
01853 strcmp(&MechWeapons[weapindx].name[3], "SmallPulseLaser") &&
01854 strcmp(&MechWeapons[weapindx].name[3], "X-SmallPulseLaser") &&
01855 strcmp(&MechWeapons[weapindx].name[3], "ERSmallPulseLaser") &&
01856 strcmp(&MechWeapons[weapindx].name[3], "HeavySmallLaser") &&
01857 strcmp(&MechWeapons[weapindx].name[3], "MachineGun") &&
01858 strcmp(&MechWeapons[weapindx].name[3], "LightMachineGun") &&
01859 strcmp(&MechWeapons[weapindx].name[3], "HeavyMachineGun") &&
01860 strcmp(&MechWeapons[weapindx].name[3], "AC/2") &&
01861 strcmp(&MechWeapons[weapindx].name[3], "UltraAC/2") &&
01862 strcmp(&MechWeapons[weapindx].name[3], "CaselessAC/2") &&
01863 strcmp(&MechWeapons[weapindx].name[3], "HyperAC/2") &&
01864 strcmp(&MechWeapons[weapindx].name[3], "LightAC/2") &&
01865 strcmp(&MechWeapons[weapindx].name[3], "RotaryAC/2") &&
01866 strcmp(&MechWeapons[weapindx].name[3], "LB2-XAC") &&
01867 strcmp(&MechWeapons[weapindx].name[3], "AC/5") &&
01868 strcmp(&MechWeapons[weapindx].name[3], "UltraAC/5") &&
01869 strcmp(&MechWeapons[weapindx].name[3], "CaselessAC/5") &&
01870 strcmp(&MechWeapons[weapindx].name[3], "HyperAC/5") &&
01871 strcmp(&MechWeapons[weapindx].name[3], "LightAC/5") &&
01872 strcmp(&MechWeapons[weapindx].name[3], "RotaryAC/5") &&
01873 strcmp(&MechWeapons[weapindx].name[3], "LB5-XAC") &&
01874 strcmp(&MechWeapons[weapindx].name[3], "StreakSRM-2") &&
01875 strcmp(&MechWeapons[weapindx].name[3], "SRM-2"))
01876 return 1;
01877
01878 return 0;
01879 }
01880
01881 void possibly_ignite(MECH * mech, MAP * map, int weapindx, int ammoMode,
01882 int x, int y, int intentional)
01883 {
01884 char terrain = GetTerrain(map, x, y);
01885 int roll = Roll();
01886 int bth = 13;
01887
01888 if(MechWeapons[weapindx].special & PCOMBAT)
01889 return;
01890
01891 if((terrain != LIGHT_FOREST) && (terrain != HEAVY_FOREST))
01892 return;
01893
01894 if(!strcmp(&MechWeapons[weapindx].name[3], "Flamer") ||
01895 !strcmp(&MechWeapons[weapindx].name[3], "HeavyFlamer"))
01896 bth = 4;
01897 else if(IsMissile(weapindx) && (ammoMode & INFERNO_MODE))
01898 bth = 5;
01899 else if(IsBallistic(weapindx) && (ammoMode & AC_FLECHETTE_MODE))
01900 bth = 5;
01901 else if(IsEnergy(weapindx) && canWeaponIgnite(weapindx))
01902 bth = 5;
01903 else if((IsMissile(weapindx) || IsBallistic(weapindx)) &&
01904 canWeaponIgnite(weapindx))
01905 bth = 9;
01906
01907 if(roll >= bth)
01908 fire_hex(mech, x, y, intentional);
01909 }
01910
01911 void possibly_clear(MECH * mech, MAP * map, int weapindx, int ammoMode,
01912 int damage, int x, int y, int intentional)
01913 {
01914 int igniteBTH = 5;
01915 int igniteRoll = Roll();
01916 int clearRoll = Roll();
01917
01918 if(MechWeapons[weapindx].special & PCOMBAT)
01919 return;
01920
01921 if(!intentional)
01922 igniteBTH = 3;
01923
01924 if(igniteRoll <= igniteBTH) {
01925 possibly_ignite(mech, map, weapindx, ammoMode, x, y, intentional);
01926 return;
01927 }
01928
01929 if(!canWeaponClear(weapindx))
01930 return;
01931
01932 if(clearRoll > damage)
01933 return;
01934
01935 clear_hex(mech, x, y, intentional);
01936 possibly_remove_mines(mech, x, y);
01937 }
01938
01939 void possibly_ignite_or_clear(MECH * mech, int weapindx, int ammoMode,
01940 int damage, int x, int y, int intentional)
01941 {
01942 int r;
01943 MAP *map;
01944
01945 r = Roll();
01946 map = FindObjectsData(mech->mapindex);
01947
01948 if(!map)
01949 return;
01950
01951 if(MechStatus(mech) & LOCK_HEX_IGN) {
01952 possibly_ignite(mech, map, weapindx, ammoMode, x, y, 1);
01953 return;
01954 }
01955
01956 if(MechStatus(mech) & LOCK_HEX_CLR) {
01957 possibly_clear(mech, map, weapindx, ammoMode, damage, x, y, 1);
01958 return;
01959 }
01960
01961 possibly_clear(mech, map, weapindx, ammoMode, damage, x, y, intentional);
01962 }
01963
01964 void hex_hit(MECH * mech, int x, int y, int weapindx,
01965 int ammoMode, int damage, int ishit)
01966 {
01967 if(!(MechStatus(mech) & (LOCK_BUILDING | LOCK_HEX | LOCK_HEX_IGN |
01968 LOCK_HEX_CLR)))
01969 return;
01970
01971
01972 if(MechStatus(mech) & LOCK_BUILDING) {
01973 if(ishit > 0)
01974 hit_building(mech, x, y, weapindx, damage);
01975 } else {
01976 possibly_ignite_or_clear(mech, weapindx, ammoMode, damage, x, y, 1);
01977
01978 if(MechStatus(mech) & LOCK_HEX) {
01979 possibly_blow_ice(mech, weapindx, x, y);
01980 possibly_blow_bridge(mech, weapindx, x, y);
01981 }
01982 }
01983 }
01984
01985
01986
01987