src/hcode/btech/mech.combat.misc.c

Go to the documentation of this file.
00001 /*
00002 * Author: Cord Awtry <kipsta@mediaone.net>
00003 *  Copyright (c) 2000-2002 Cord Awtry
00004 *       All rights reserved
00005 *
00006 * Based on work that was:
00007 *  Copyright (c) 1997 Markus Stenberg
00008 *  Copyright (c) 1998-2000 Thomas Wouters
00009 */
00010 
00011 #include "mech.h"
00012 #include "mech.events.h"
00013 #include "p.bsuit.h"
00014 #include "p.crit.h"
00015 #include "p.eject.h"
00016 #include "p.mech.combat.misc.h"
00017 #include "p.mech.fire.h"
00018 #include "p.mech.partnames.h"
00019 #include "p.mech.pickup.h"
00020 #include "p.mech.tag.h"
00021 #include "p.mech.update.h"
00022 #include "p.mech.utils.h"
00023 
00024 void decrement_ammunition(MECH * mech,
00025                                                   int weapindx,
00026                                                   int section,
00027                                                   int critical,
00028                                                   int ammoLoc,
00029                                                   int ammoCrit, int ammoLoc1, int ammoCrit1,
00030                                                   int wGattlingShots)
00031 {
00032         int wGatSec = 0, wGatCrit = 0;
00033         int wShotsLeft = 0;
00034         int wCurShots = 0;
00035         int i = 0;
00036         int weapSize = 0;
00037         int firstCrit = 0;
00038 
00039         /* If we're an energy weapon or a PC weapon, return */
00040         if(!(MechWeapons[weapindx].type != TBEAM &&
00041                  MechWeapons[weapindx].type != THAND))
00042                 return;
00043 
00044         /* If we're a rocket launcher, fire our load and return */
00045         if(MechWeapons[weapindx].special == ROCKET) {
00046                 weapSize = GetWeaponCrits(mech, weapindx);
00047                 firstCrit = FindFirstWeaponCrit(mech, section, critical, 0,
00048                                                                                 GetPartType(mech, section, critical),
00049                                                                                 weapSize);
00050 
00051                 for(i = firstCrit; i < (firstCrit + weapSize); i++) {
00052                         GetPartFireMode(mech, section, i) |= ROCKET_FIRED;
00053                 }
00054 
00055                 return;
00056         }
00057 
00058         /* If we're a one-shot, set us used and return */
00059         if(GetPartFireMode(mech, section, critical) & OS_MODE) {
00060                 GetPartFireMode(mech, section, critical) |= OS_USED;
00061                 return;
00062         }
00063         /* Check the state of our weapon bins */
00064         ammo_expedinture_check(mech, weapindx, MAX(wGattlingShots,
00065                                                                                            ((GetPartFireMode
00066                                                                                                  (mech, section,
00067                                                                                                   critical) & ULTRA_MODE)
00068                                                                                                 ||
00069                                                                                                 (GetPartFireMode
00070                                                                                                  (mech, section,
00071                                                                                                   critical) & RFAC_MODE))));
00072 
00073         if((GetPartFireMode(mech, section, critical) & GATTLING_MODE) ||
00074            (MechWeapons[weapindx].special & RAC)) {
00075                 if(GetPartFireMode(mech, section, critical) & GATTLING_MODE)
00076                         wShotsLeft = wGattlingShots * 3;
00077                 else {
00078                         if(GetPartFireMode(mech, section, critical) & RAC_TWOSHOT_MODE)
00079                                 wShotsLeft = 2;
00080                         else if(GetPartFireMode(mech, section, critical) &
00081                                         RAC_FOURSHOT_MODE)
00082                                 wShotsLeft = 4;
00083                         else if(GetPartFireMode(mech, section, critical) &
00084                                         RAC_SIXSHOT_MODE)
00085                                 wShotsLeft = 6;
00086                         else
00087                                 wShotsLeft = 1;
00088                 }
00089 
00090                 while (wShotsLeft > 0) {
00091                         FindAmmoForWeapon_sub(mech, section, critical, weapindx,
00092                                                                   section, &wGatSec, &wGatCrit, AMMO_MODES,
00093                                                                   0);
00094                         wCurShots = GetPartData(mech, wGatSec, wGatCrit);
00095 
00096                         if(wCurShots) {
00097                                 if(wCurShots >= wShotsLeft) {
00098                                         SetPartData(mech, wGatSec, wGatCrit,
00099                                                                 wCurShots - wShotsLeft);
00100                                         wShotsLeft = 0;
00101                                 } else {
00102                                         SetPartData(mech, wGatSec, wGatCrit, 0);
00103                                         wShotsLeft -= wCurShots;
00104                                 }
00105                         }
00106 
00107                         if(CountAmmoForWeapon(mech, weapindx) <= 0)
00108                                 break;
00109                 }
00110         } else {                                        /* Non-RAC/Gattling */
00111                 /* Decrement our ammo one shot */
00112                 if(GetPartData(mech, ammoLoc, ammoCrit))
00113                         GetPartData(mech, ammoLoc, ammoCrit)--;
00114 
00115                 /* If we're ultra or rfac, decrement it again */
00116                 if((GetPartFireMode(mech, section, critical) & ULTRA_MODE) ||
00117                    (GetPartFireMode(mech, section, critical) & RFAC_MODE))
00118                         if(GetPartData(mech, ammoLoc1, ammoCrit1))
00119                                 GetPartData(mech, ammoLoc1, ammoCrit1)--;
00120         }
00121 }
00122 
00123 void ammo_expedinture_check(MECH * mech, int weapindx, int ns)
00124 {
00125         int targ = I2Ammo(weapindx);
00126         int cnt = 0, slots = 0;
00127         int t, t2;
00128         int i, j, cl;
00129         int sev = 0;
00130 
00131         SetWCheck(mech);
00132 
00133         if(!MechAmmoWarn(mech))
00134                 return;
00135 
00136         for(i = 0; i < NUM_SECTIONS; i++) {
00137                 cl = CritsInLoc(mech, i);
00138                 for(j = 0; j < cl; j++)
00139                         if(GetPartType(mech, i, j) == targ) {
00140                                 cnt += GetPartData(mech, i, j);
00141                                 slots += AmmoMod(mech, i, j);
00142                         }
00143         }
00144         t = BOUNDED(3, (slots * MechWeapons[weapindx].ammoperton) / 8, 30);
00145         t2 = 2 * t;
00146         if((cnt == (t + ns)) || (ns && cnt >= t && cnt < (t + ns)))
00147                 sev = 1;
00148         else if((cnt == (t2 + ns)) || (ns && cnt >= t2 && cnt < (t2 + ns)))
00149                 sev = 0;
00150         else
00151                 return;
00152         /* Okay, we have case of warning here */
00153         if(Started(mech))
00154                 if ((sev * 65536 + weapindx) % 65536)
00155                         mech_printf(mech, MECHALL,"%sWARNING: Ammo for %s is running low.%%c",sev? "%ch%cr" : "%ch%cy",
00156                                         get_parts_long_name(I2Weapon(weapindx), 0));
00157 }
00158 
00159 void heat_effect(MECH * mech, MECH * tempMech, int heatdam, int fromInferno)
00160 {
00161         if(MechType(tempMech) != CLASS_MECH && MechType(tempMech) != CLASS_MW
00162            && MechType(tempMech) != CLASS_BSUIT && !IsDS(tempMech) &&
00163            MechMove(tempMech) != MOVE_NONE) {
00164 
00165                 if(((MechType(tempMech) == CLASS_VEH_GROUND) ||
00166                         (MechType(tempMech) == CLASS_VTOL)) &&
00167                    mudconf.btech_fasaadvvhlfire) {
00168                         if(fromInferno)
00169                                 vehicle_start_burn(tempMech, mech);
00170                         else
00171                                 checkVehicleInFire(tempMech, 0);
00172                 } else {
00173                         if(Roll() > 8) {
00174                                 MechLOSBroadcast(tempMech, "explodes!");
00175                                 mech_notify(tempMech, MECHALL,
00176                                                         "The heat's too much for your vehicle! It blows up!");
00177                                 Destroy(tempMech);
00178                                 ChannelEmitKill(tempMech, mech);
00179                                 explode_unit(tempMech, mech ? mech : tempMech);
00180                         }
00181                 }
00182         } else {
00183 
00184                 if(heatdam)
00185                         inferno_burn(tempMech, heatdam * 6);
00186         }
00187 }
00188 
00189 /* Burn.. burn in hell! ;> */
00190 void Inferno_Hit(MECH * mech, MECH * hitMech, int missiles, int LOS)
00191 {
00192         int hmod = (missiles + 1) / 2;
00193 
00194         if(Jellied(hitMech) || Burning(hitMech)) {
00195                 MechLOSBroadcast(hitMech, "burns a bit more brightly.");
00196                 mech_notify(hitMech, MECHALL,
00197                                         "%ch%crMore burning jelly joins the flames!%cn");
00198         } else {
00199                 MechLOSBroadcast(hitMech, "suddenly bursts into flames!");
00200                 mech_notify(hitMech, MECHALL,
00201                                         "%ch%crYou are sprayed with burning jelly!%cn");
00202         }
00203         heat_effect(mech, hitMech, hmod * 30, 1);       /* 3min for _each_ missile */
00204         water_extinguish_inferno(hitMech); /* They could be in -2 standing or -1 prone.. Shooter just wastes his missiles! */
00205 }
00206 
00207 //extern int global_kill_cheat;
00208 void KillMechContentsIfIC(dbref aRef)
00209 {
00210         //global_kill_cheat = 1;
00211         if(!In_Character(aRef))
00212                 return;
00213         if(!mudconf.btech_ic || mudconf.btech_xploss >= 1000)
00214                 tele_contents(aRef, AFTERLIFE_DBREF, TELE_LOUD);
00215         else
00216                 tele_contents(aRef, AFTERLIFE_DBREF, TELE_XP | TELE_LOUD);
00217 }
00218 
00219 #define BOOMLENGTH 24
00220 char BOOM[BOOMLENGTH][80] = {
00221         "                              ________________",
00222         "                         ____/ (  (    )   )  \\___",
00223         "                        /( (  (  )   _    ))  )   )\\",
00224         "                      ((     (   )(    )  )   (   )  )",
00225         "                    ((/  ( _(   )   (   _) ) (  () )  )",
00226         "                   ( (  ( (_)   ((    (   )  .((_ ) .  )_",
00227         "                  ( (  )    (      (  )    )   ) . ) (   )",
00228         "                 (  (   (  (   ) (  _  ( _) ).  ) . ) ) ( )",
00229         "                 ( (  (   ) (  )   (  ))     ) _)(   )  )  )",
00230         "                ( (  ( \\ ) (    (_  ( ) ( )  )   ) )  )) ( )",
00231         "                 (  (   (  (   (_ ( ) ( _    )  ) (  )  )   )",
00232         "                ( (  ( (  (  )     (_  )  ) )  _)   ) _( ( )",
00233         "                 ((  (   )(    (     _    )   _) _(_ (  (_ )",
00234         "                  (_((__(_(__(( ( ( |  ) ) ) )_))__))_)___)",
00235         "                  ((__)        \\\\||lll|l||///          \\_))",
00236         "                           (   /(/ (  )  ) )\\   )",
00237         "                         (    ( ( ( | | ) ) )\\   )",
00238         "                          (   /(| / ( )) ) ) )) )",
00239         "                        (     ( ((((_(|)_)))))     )",
00240         "                         (      ||\\(|(|)|/||     )",
00241         "                       (        |(||(||)||||        )",
00242         "                         (     //|/l|||)|\\\\ \\     )",
00243         "                       (/ / //  /|//||||\\\\  \\ \\  \\ _)",
00244         "----------------------------------------------------------------------------"
00245 };
00246 
00247 void DestroyMech(MECH * target, MECH * mech, int bc)
00248 {
00249         int loop;
00250         MAP *mech_map;
00251         MECH *ttarget;
00252         MECH *ctarget;
00253 
00254         dbref a,b;
00255 
00256         if(Destroyed(target)) {
00257                 return;
00258         }
00259         //global_kill_cheat = 1;
00260         if(mech && target)
00261                 ChannelEmitKill(target, mech);
00262         else
00263                 ChannelEmitKill(target, target);
00264         if(mech) {
00265                 if(bc) {
00266                         if(mech != target) {
00267                                 mech_notify(mech, MECHALL, "You destroyed the target!");
00268                                 MechLOSBroadcasti(target, mech, "has been destroyed by %s!");
00269                         } else
00270                                 MechLOSBroadcast(target, "has been destroyed!");
00271                 }
00272                 for(loop = 0; loop < BOOMLENGTH; loop++)
00273                         mech_notify(target, MECHALL, BOOM[loop]);
00274                 switch (MechType(target)) {
00275                 case CLASS_MW:
00276                 case CLASS_BSUIT:
00277                         mech_notify(target, MECHALL, "You have been killed!");
00278                         break;
00279                 default:
00280                         mech_notify(target, MECHALL, "You have been destroyed!");
00281                         break;
00282                 }
00283                 mech_map = getMap(target->mapindex);
00284                 if((mudconf.btech_vtol_ice_causes_fire)
00285                    && (MechSpecials(target) & ICE_TECH)
00286                    && (MechType(target) == CLASS_VTOL)) {
00287                         MechLOSBroadcast(target, "explodes in a ball of flames!");
00288                         add_decoration(mech_map, MechX(target), MechY(target), TYPE_FIRE,
00289                                                    FIRE, FIRE_DURATION);
00290                 }
00291 
00292                 if(MechCarrying(target) > 0) {
00293                         if((ttarget = getMech(MechCarrying(target)))) {
00294                                 mech_notify(ttarget, MECHALL,
00295                                                         "Your tow lines go suddenly slack!");
00296                                 mech_dropoff(GOD, target, "");
00297                         }
00298                 }
00299         }
00300 
00301         /* destroy contents if they are units and the containter is IC*/
00302         SAFE_DOLIST(a,b,Contents(target->mynum))
00303                 if(IsMech(a) && In_Character(a)) {
00304                         ctarget = getMech(a);
00305                         mech_notify(ctarget, MECHALL, "Due to your transports destruction, your unit is destroyed!");
00306                         mech_udisembark(a, ctarget, "");
00307                         DestroyMech(ctarget,mech,0);
00308                 }
00309         
00310         /* shut it down */
00311         if(mech) {
00312                 DestroyAndDump(target);
00313         } else {
00314                 Destroy(target);
00315         }
00316         if(MechType(target) == CLASS_MW) {
00317                 if(In_Character(target->mynum)) {
00318                         KillMechContentsIfIC(target->mynum);
00319                         discard_mw(target);
00320                 }
00321         }
00322 }
00323 
00324 char *short_hextarget(MECH * mech)
00325 {
00326 
00327         if(MechStatus(mech) & LOCK_HEX_IGN)
00328                 return "ign";
00329         if(MechStatus(mech) & LOCK_HEX_CLR)
00330                 return "clr";
00331         if(MechStatus(mech) & LOCK_HEX)
00332                 return "hex";
00333         if(MechStatus(mech) & LOCK_BUILDING)
00334                 return "bld";
00335         return "reg";
00336 }

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