/* * $Id: mech.combat.misc.c,v 1.2 2005/01/15 16:57:14 kstevens Exp $ * * Author: Cord Awtry <kipsta@mediaone.net> * Copyright (c) 2000-2002 Cord Awtry * All rights reserved * * Based on work that was: * Copyright (c) 1997 Markus Stenberg * Copyright (c) 1998-2000 Thomas Wouters */ #include "mech.h" #include "mech.events.h" #include "p.bsuit.h" #include "p.crit.h" #include "p.eject.h" #include "p.mech.combat.misc.h" #include "p.mech.fire.h" #include "p.mech.partnames.h" #include "p.mech.pickup.h" #include "p.mech.tag.h" #include "p.mech.update.h" #include "p.mech.utils.h" void decrement_ammunition(MECH * mech, int weapindx, int section, int critical, int ammoLoc, int ammoCrit, int ammoLoc1, int ammoCrit1, int wGattlingShots) { int wGatSec = 0, wGatCrit = 0; int wShotsLeft = 0; int wCurShots = 0; int i = 0; int weapSize = 0; int firstCrit = 0; /* If we're an energy weapon or a PC weapon, return */ if (!(MechWeapons[weapindx].type != TBEAM && MechWeapons[weapindx].type != THAND)) return; /* If we're a rocket launcher, fire our load and return */ if (MechWeapons[weapindx].special == ROCKET) { weapSize = GetWeaponCrits(mech, weapindx); firstCrit = FindFirstWeaponCrit(mech, section, critical, 0, GetPartType(mech, section, critical), weapSize); for (i = firstCrit; i < (firstCrit + weapSize); i++) { GetPartFireMode(mech, section, i) |= ROCKET_FIRED; } return; } /* If we're a one-shot, set us used and return */ if (GetPartFireMode(mech, section, critical) & OS_MODE) { GetPartFireMode(mech, section, critical) |= OS_USED; return; } /* Check the state of our weapon bins */ ammo_expedinture_check(mech, weapindx, MAX(wGattlingShots, ((GetPartFireMode(mech, section, critical) & ULTRA_MODE) || (GetPartFireMode(mech, section, critical) & RFAC_MODE)))); if ((GetPartFireMode(mech, section, critical) & GATTLING_MODE) || (MechWeapons[weapindx].special & RAC)) { if (GetPartFireMode(mech, section, critical) & GATTLING_MODE) wShotsLeft = wGattlingShots * 3; else { if (GetPartFireMode(mech, section, critical) & RAC_TWOSHOT_MODE) wShotsLeft = 2; else if (GetPartFireMode(mech, section, critical) & RAC_FOURSHOT_MODE) wShotsLeft = 4; else if (GetPartFireMode(mech, section, critical) & RAC_SIXSHOT_MODE) wShotsLeft = 6; else wShotsLeft = 1; } while (wShotsLeft > 0) { FindAmmoForWeapon_sub(mech, section, critical, weapindx, section, &wGatSec, &wGatCrit, AMMO_MODES, 0); wCurShots = GetPartData(mech, wGatSec, wGatCrit); if (wCurShots) { if (wCurShots >= wShotsLeft) { SetPartData(mech, wGatSec, wGatCrit, wCurShots - wShotsLeft); wShotsLeft = 0; } else { SetPartData(mech, wGatSec, wGatCrit, 0); wShotsLeft -= wCurShots; } } if (CountAmmoForWeapon(mech, weapindx) <= 0) break; } } else { /* Non-RAC/Gattling */ /* Decrement our ammo one shot */ if (GetPartData(mech, ammoLoc, ammoCrit)) GetPartData(mech, ammoLoc, ammoCrit)--; /* If we're ultra or rfac, decrement it again */ if ((GetPartFireMode(mech, section, critical) & ULTRA_MODE) || (GetPartFireMode(mech, section, critical) & RFAC_MODE)) if (GetPartData(mech, ammoLoc1, ammoCrit1)) GetPartData(mech, ammoLoc1, ammoCrit1)--; } } void mech_ammowarn_event(MUXEVENT * e) { MECH *mech = (MECH *) e->data; int data = (int) e->data2; int sev = data / 65536; int weapindx = data % 65536; if (!Started(mech)) return; if (weapindx < 0) return; mech_notify(mech, MECHALL, tprintf("%sWARNING: Ammo for %s is running low.%%c", sev ? "%ch%cr" : "%ch%cy", get_parts_long_name(I2Weapon(weapindx), 0))); } void ammo_expedinture_check(MECH * mech, int weapindx, int ns) { int targ = I2Ammo(weapindx); int cnt = 0, slots = 0; int t, t2; int i, j, cl; int sev = 0; SetWCheck(mech); if (!MechAmmoWarn(mech)) return; for (i = 0; i < NUM_SECTIONS; i++) { cl = CritsInLoc(mech, i); for (j = 0; j < cl; j++) if (GetPartType(mech, i, j) == targ) { cnt += GetPartData(mech, i, j); slots += AmmoMod(mech, i, j); } } t = BOUNDED(3, (slots * MechWeapons[weapindx].ammoperton) / 8, 30); t2 = 2 * t; if ((cnt == (t + ns)) || (ns && cnt >= t && cnt < (t + ns))) sev = 1; else if ((cnt == (t2 + ns)) || (ns && cnt >= t2 && cnt < (t2 + ns))) sev = 0; else return; /* Okay, we have case of warning here */ MECHEVENT(mech, EVENT_AMMOWARN, mech_ammowarn_event, 1, (sev * 65536 + weapindx)); } void heat_effect(MECH * mech, MECH * tempMech, int heatdam, int fromInferno) { if (MechType(tempMech) != CLASS_MECH && MechType(tempMech) != CLASS_MW && MechType(tempMech) != CLASS_BSUIT && !IsDS(tempMech) && MechMove(tempMech) != MOVE_NONE) { if (((MechType(tempMech) == CLASS_VEH_GROUND) || (MechType(tempMech) == CLASS_VTOL)) && mudconf.btech_fasaadvvhlfire) { if (fromInferno) vehicle_start_burn(tempMech, mech); else checkVehicleInFire(tempMech, 0); } else { if (Roll() > 8) { MechLOSBroadcast(tempMech, "explodes!"); mech_notify(tempMech, MECHALL, "The heat's too much for your vehicle! It blows up!"); Destroy(tempMech); ChannelEmitKill(tempMech, mech); explode_unit(tempMech, mech ? mech : tempMech); } } } else { if (heatdam) inferno_burn(tempMech, heatdam * 6); } } /* Burn.. burn in hell! ;> */ void Inferno_Hit(MECH * mech, MECH * hitMech, int missiles, int LOS) { int hmod = (missiles + 1) / 2; if (Jellied(hitMech) || Burning(hitMech)) { MechLOSBroadcast(hitMech, "burns a bit more brightly."); mech_notify(hitMech, MECHALL, "%ch%crMore burning jelly joins the flames!%cn"); } else { MechLOSBroadcast(hitMech, "suddenly bursts into flames!"); mech_notify(hitMech, MECHALL, "%ch%crYou are sprayed with burning jelly!%cn"); } heat_effect(mech, hitMech, hmod * 30, 1); /* 3min for _each_ missile */ } //extern int global_kill_cheat; void KillMechContentsIfIC(dbref aRef) { //global_kill_cheat = 1; if (!In_Character(aRef)) return; if (!mudconf.btech_ic || mudconf.btech_xploss >= 1000) tele_contents(aRef, AFTERLIFE_DBREF, TELE_LOUD); else tele_contents(aRef, AFTERLIFE_DBREF, TELE_XP | TELE_LOUD); } #define BOOMLENGTH 24 char BOOM[BOOMLENGTH][80] = { " ________________", " ____/ ( ( ) ) \\___", " /( ( ( ) _ )) ) )\\", " (( ( )( ) ) ( ) )", " ((/ ( _( ) ( _) ) ( () ) )", " ( ( ( (_) (( ( ) .((_ ) . )_", " ( ( ) ( ( ) ) ) . ) ( )", " ( ( ( ( ) ( _ ( _) ). ) . ) ) ( )", " ( ( ( ) ( ) ( )) ) _)( ) ) )", " ( ( ( \\ ) ( (_ ( ) ( ) ) ) ) )) ( )", " ( ( ( ( (_ ( ) ( _ ) ) ( ) ) )", " ( ( ( ( ( ) (_ ) ) ) _) ) _( ( )", " (( ( )( ( _ ) _) _(_ ( (_ )", " (_((__(_(__(( ( ( | ) ) ) )_))__))_)___)", " ((__) \\\\||lll|l||/// \\_))", " ( /(/ ( ) ) )\\ )", " ( ( ( ( | | ) ) )\\ )", " ( /(| / ( )) ) ) )) )", " ( ( ((((_(|)_))))) )", " ( ||\\(|(|)|/|| )", " ( |(||(||)|||| )", " ( //|/l|||)|\\\\ \\ )", " (/ / // /|//||||\\\\ \\ \\ \\ _)", "----------------------------------------------------------------------------" }; void DestroyMech(MECH * target, MECH * mech, int bc) { int loop; MAP *mech_map; MECH *ttarget; if (Destroyed(target)) return; //global_kill_cheat = 1; if (mech && target) ChannelEmitKill(target, mech); if (mech) { if (bc) { if (mech != target) { mech_notify(mech, MECHALL, "You destroyed the target!"); MechLOSBroadcasti(target, mech, "has been destroyed by %s!"); } else MechLOSBroadcast(target, "has been destroyed!"); } for (loop = 0; loop < BOOMLENGTH; loop++) mech_notify(target, MECHALL, BOOM[loop]); switch (MechType(target)) { case CLASS_MW: case CLASS_BSUIT: mech_notify(target, MECHALL, "You have been killed!"); break; default: mech_notify(target, MECHALL, "You have been destroyed!"); break; } mech_map = getMap(target->mapindex); if((mudconf.btech_vtol_ice_causes_fire) && (MechSpecials(target) & ICE_TECH) && (MechType(target) == CLASS_VTOL)) { MechLOSBroadcast(target, "explodes in a ball of flames!"); add_decoration(mech_map, MechX(target), MechY(target), TYPE_FIRE, FIRE, FIRE_DURATION); } if (MechCarrying(target) > 0) { if ((ttarget = getMech(MechCarrying(target)))) { mech_notify(ttarget, MECHALL, "Your tow lines go suddenly slack!"); mech_dropoff(GOD, target, ""); } } } /* shut it down */ if (mech) { DestroyAndDump(target); } else { Destroy(target); } if (MechType(target) == CLASS_MW) { if (In_Character(target->mynum)) { KillMechContentsIfIC(target->mynum); discard_mw(target); } } } char *short_hextarget(MECH * mech) { if (MechStatus(mech) & LOCK_HEX_IGN) return "ign"; if (MechStatus(mech) & LOCK_HEX_CLR) return "clr"; if (MechStatus(mech) & LOCK_HEX) return "hex"; if (MechStatus(mech) & LOCK_BUILDING) return "bld"; return "reg"; }