#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/file.h>
#include "mech.h"
#include "map.h"
#include "btmacros.h"
#include "mech.events.h"
#include "create.h"
#include "failures.h"
#include "mech.combat.h"
#include "mech.partnames.h"
#include "p.mech.ice.h"
#include "p.pcombat.h"
#include "p.mech.utils.h"
#include "p.mech.los.h"
#include "p.mech.build.h"
#include "p.map.obj.h"
#include "p.mech.combat.h"
#include "p.btechstats.h"
#include "p.mech.update.h"
#include "p.bsuit.h"
#include "p.artillery.h"
#include "p.mech.fire.h"
#include "p.mech.c3.h"
#include "p.mech.c3i.h"
#include "p.mech.c3.misc.h"
#include "p.mine.h"
#include "p.mech.hitloc.h"
#include "p.eject.h"
#include "p.crit.h"
#include "p.mech.ood.h"
#include "p.map.conditions.h"
#include "p.template.h"
#include "p.mech.pickup.h"
#include "p.event.h"
#include "p.mech.tag.h"
#include "p.mech.ecm.h"
#include "mech.ecm.h"
#include "p.mech.enhanced.criticals.h"
#include "p.mech.spot.h"
#include "p.mech.combat.misc.h"
#include "p.mech.combat.missile.h"
#include "p.mech.bth.h"
#include "p.mech.damage.h"
Include dependency graph for mech.combat.c:
Go to the source code of this file.
Defines | |
#define | SSDistMod(r) ((r < 9) ? 0 : ((r < 20) ? 1 : 2)) |
#define | SSTonMod(d) ((d <= -20) ? 0 : (d >= 20) ? 2 : 1) |
#define | ARCCHECK(mech, ex, ey, sec, crit, msg) |
Functions | |
void | mech_target (dbref player, void *data, char *buffer) |
static void | mech_ss_event (MUXEVENT *ev) |
void | sixth_sense_check (MECH *mech, MECH *target) |
void | mech_settarget (dbref player, void *data, char *buffer) |
void | mech_fireweapon (dbref player, void *data, char *buffer) |
int | FireWeaponNumber (dbref player, MECH *mech, MAP *mech_map, int weapnum, int argc, char **args, int sight) |
int | weapon_failure_stuff (MECH *mech, int *weapnum, int *weapindx, int *section, int *critical, int *ammoLoc, int *ammoCrit, int *ammoLoc1, int *ammoCrit1, int *modifier, int *type, float range, int *range_ok, int wGattlingShots) |
void | sendC3TrackEmit (MECH *mech, dbref c3Ref, MECH *c3Mech) |
void | FireWeapon (MECH *mech, MAP *mech_map, MECH *target, int LOS, int weapindx, int weapnum, int section, int critical, float enemyX, float enemyY, int mapx, int mapy, float range, int indirectFire, int sight, int ishex) |
int | determineDamageFromHit (MECH *mech, int wSection, int wCritSlot, MECH *hitMech, int hitX, int hitY, int weapindx, int wGattlingShots, int wBaseWeapDamage, int wAmmoMode, int type, int modifier, int isTempCalc) |
void | HitTarget (MECH *mech, int weapindx, int wSection, int wCritSlot, MECH *hitMech, int hitX, int hitY, int LOS, int type, int modifier, int reallyhit, int bth, int wGattlingShots, int tIsSwarmAttack, int player_roll) |
char * | hex_target_id (MECH *mech) |
int | canWeaponIgnite (int weapindx) |
int | canWeaponClear (int weapindx) |
void | possibly_ignite (MECH *mech, MAP *map, int weapindx, int ammoMode, int x, int y, int intentional) |
void | possibly_clear (MECH *mech, MAP *map, int weapindx, int ammoMode, int damage, int x, int y, int intentional) |
void | possibly_ignite_or_clear (MECH *mech, int weapindx, int ammoMode, int damage, int x, int y, int intentional) |
void | hex_hit (MECH *mech, int x, int y, int weapindx, int ammoMode, int damage, int ishit) |
Variables | |
int | arc_override |
dbref | pilot_override |
char * | ss_messages [] |
#define ARCCHECK | ( | mech, | |||
ex, | |||||
ey, | |||||
sec, | |||||
crit, | |||||
msg | ) |
Value:
if (AeroUnusableArcs(mech)) \ { int ar; ar = InWeaponArc(mech, ex, ey); \ DOCHECK0((!arc_override && (AeroUnusableArcs(mech) & ar)) || \ (arc_override && !(arc_override & ar)), \ "That arc's weapons aren't under your control!"); \ }; \ DOCHECK0(!IsInWeaponArc (mech, ex, ey, sec, crit), \ msg);
Definition at line 357 of file mech.combat.c.
Referenced by FireWeaponNumber().
#define SSDistMod | ( | r | ) | ((r < 9) ? 0 : ((r < 20) ? 1 : 2)) |
#define SSTonMod | ( | d | ) | ((d <= -20) ? 0 : (d >= 20) ? 2 : 1) |
int canWeaponClear | ( | int | weapindx | ) |
Definition at line 1849 of file mech.combat.c.
References MechWeapons.
Referenced by possibly_clear().
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 }
int canWeaponIgnite | ( | int | weapindx | ) |
Definition at line 1825 of file mech.combat.c.
References MechWeapons.
Referenced by possibly_ignite().
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 }
int determineDamageFromHit | ( | MECH * | mech, | |
int | wSection, | |||
int | wCritSlot, | |||
MECH * | hitMech, | |||
int | hitX, | |||
int | hitY, | |||
int | weapindx, | |||
int | wGattlingShots, | |||
int | wBaseWeapDamage, | |||
int | wAmmoMode, | |||
int | type, | |||
int | modifier, | |||
int | isTempCalc | |||
) |
Definition at line 1409 of file mech.combat.c.
References AC_FLECHETTE_MODE, AC_INCENDIARY_MODE, confdata::btech_moddamagewithrange, confdata::btech_moddamagewithwoods, CLASS_BSUIT, CLASS_MW, DAMAGE, Elevation, FaMechRange, FindHexRange(), getCritSubDamage(), getMap(), GetRTerrain, GRASSLAND, HEAVY_FOREST, IsEnergy, IsForestHex, LIGHT_FOREST, MapCoordToRealCoord(), MECH::mapindex, mech_notify(), MECHALL, MechFX, MechFY, MechRTerrain, MechType, MechWeapons, MechX, MechY, MechZ, mudconf, possibly_ignite_or_clear(), and SectionUnderwater.
Referenced by HitTarget().
01420 { 01421 MAP *mech_map; 01422 float fRange = 0.0; 01423 int wWeapDamage = wBaseWeapDamage; 01424 int wClearDamage = 0; 01425 01426 /* Find the range to our target */ 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 /* If our Gattling shots are greater then 0, use that as the damage. */ 01436 if(wGattlingShots > 0) 01437 wWeapDamage = wGattlingShots; 01438 01439 /* If we're a heavy gauss rifle, damage gets altered by range. */ 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 /* See if we're using flechette ammo */ 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 /* Check to see if we have an energy weapon and we're modding the damage based on range */ 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 /* Check to see if we're modding the damage based on woods cover */ 01487 mech_map = getMap(mech->mapindex); 01488 01489 /* If there was a damage type failure, mod the damage */ 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 }
void FireWeapon | ( | MECH * | mech, | |
MAP * | mech_map, | |||
MECH * | target, | |||
int | LOS, | |||
int | weapindx, | |||
int | weapnum, | |||
int | section, | |||
int | critical, | |||
float | enemyX, | |||
float | enemyY, | |||
int | mapx, | |||
int | mapy, | |||
float | range, | |||
int | indirectFire, | |||
int | sight, | |||
int | ishex | |||
) |
Definition at line 761 of file mech.combat.c.
References ArmorStringFromIndex(), ATTACKEMIT_MECH, CrewStunned, DFM, DOCHECKMA, ELRM, FaMechRange, FindAndCheckAmmo(), FindArtilleryBTH(), FindNormalBTH(), MAP::first_free, FlyingT, GATTLING_MODE, getMech(), GetMechToMechID(), GetPartAmmoMode, GetPartFireMode, HEAT_MODE, hex_target_id(), IsArtillery, IsCoolant, IsMissile, Jumping, Landed, LBUF_SIZE, mech_printf(), MechAim, MechAimType, MECHALL, MechMove, MECHPILOT, MAP::mechsOnMap, MechStatus, MechStatus2, MechSwarmTarget, MechTeam, MechType, MechWeapons, MechX, MechY, MECH::mynum, name, NUM_SECTIONS, Number, OODing, PARTIAL_COVER, RemovingPods, Roll(), SBUF_SIZE, SectionUnderwater, SendAttackEmits, SendAttacks, sendC3TrackEmit(), short_hextarget(), STINGER_MODE, Swap, tprintf(), UnJammingAmmo, and UnjammingTurret.
Referenced by FireSpot(), and FireWeaponNumber().
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; /* If we're a gattling MG, then we need to figure out how many shots */ 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 /* If its a coolant gun set to heat, set the target 00807 * to the mech (ie it shoots itself with coolant gun) */ 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 * Gattling MGs do d6 damage (all as one hit), causing the same in heat 00832 * and using 3 * damage in ammo. 00833 */ 00834 if(GetPartFireMode(mech, section, critical) & GATTLING_MODE) 00835 wGattlingShots = Number(1, 6); 00836 00837 /* Find and check Ammunition */ 00838 if(!sight) 00839 if(!FindAndCheckAmmo(mech, weapindx, section, critical, &ammoLoc, 00840 &ammoCrit, &ammoLoc1, &ammoCrit1, 00841 &wGattlingShots)) 00842 return; 00843 00844 /**************************************** 00845 * START: Calc BTH and Roll 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 /* If it's a swarm attack, make the BTH 0 'cause they always hit */ 00865 if(tIsSwarmAttack) 00866 baseToHit = 0; 00867 00868 /* Mod the roll for DFMs and ELRMS */ 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 /* Sort 'em to ascending order */ 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 * END: Calc BTH and Roll 00893 ****************************************/ 00894 00895 /**************************************** 00896 * START: Do all the necessary emits for sighting and firing 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 /* Hex target sight info */ 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 /* Switching to Exile method of tracking xp, where we split 00977 * Attacking and Piloting xp into two different channels 00978 * And since this is neither it goes to its own channel 00979 */ 00980 SendAttacks(tprintf("#%i attacks #%i (weapon) (%i/%i)", 00981 mech->mynum, target->mynum, baseToHit, roll)); 00982 /* 00983 SendXP(tprintf("#%i attacks #%i (weapon) (%i/%i)", mech->mynum, 00984 target->mynum, baseToHit, roll)); 00985 */ 00986 /* If the target has the ATTACKEMIT_MECH flag on have it 00987 * output this info as well 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 /* Switching to Exile method of tracking xp, where we split 01003 * Attacking and Piloting xp into two different channels 01004 * And since this is neither it goes to its own channel 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 SendXP(tprintf("#%i attacks %d,%d (%s) (weapon) (%i/%i)", 01011 mech->mynum, mapx, mapy, short_hextarget(mech), 01012 baseToHit, roll)); 01013 */ 01014 01015 /* Big Block of code here. Basicly it checks all the targets 01016 * in the hex the attacker is firing at. For each one that 01017 * has ATTACKEMIT_MECH set, it broadcasts that info 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 * END: Do all the necessary emits for sighting and firing 01049 ****************************************/ 01050 01051 /* Check for weapon failures */ 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 /* See if our streaks work */ 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 /* Hotload LRM jams on 2 or 3 */ 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 /* Caseless jams on a 2. Next internal roll of 8+ explodes */ 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 /* do 8+ explosion check. Per tac handbook, the launcher explodes on failure*/ 01090 if(Roll() > 7 ) { 01091 /* Rut roh shaggy. Time to cause some damage! */ 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 /* Apply damage equal to one shot, follow crits as well */ 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 /* Check for RFAC explosion/jams */ 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 /* Check for RAC explosion/jams */ 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 /* Check for Ultra explosion/jams */ 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 /* See if the sucker will explode from damage taken */ 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 /* See if the sucker will jam from damage taken */ 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 /* Trash our cocoon if we're OODing */ 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 /* Better setup some glancing stuff. There will be 3 ways to get hit.. 01233 * Glancing_Blows = 0: NO Glancing. ROLL>=BTH=Normal 01234 * Glancing_Blows = 1: MaxTech Glancing. ROLL=BTH=Glance, ROLL>BTH=Normal 01235 * Glancing_Blows = 2: Exile Glancing. ROLL=BTH-1=Glance, ROLL>=BTH=Normal 01236 * We need to do a little handling here. The rest happens over it HitTarget 01237 */ 01238 RbaseToHit = baseToHit; 01239 if(mudconf.btech_glancing_blows == 2) 01240 RbaseToHit = baseToHit - 1; /* only time we modify it */ 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 /* Tell our target they were just shot at... */ 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 /* Time to decide if we've really hit them and wot to do */ 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 /* Recycle the weapon */ 01333 SetRecyclePart(mech, section, critical, 01334 WEAPON_TICK * MechWeapons[weapindx].vrt); 01335 01336 /**************************************** 01337 * START: Set the heat after firing 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 * END: Set the heat after firing 01377 ****************************************/ 01378 01379 /* Decrement Ammunition */ 01380 decrement_ammunition(mech, weapindx, section, critical, ammoLoc, 01381 ammoCrit, ammoLoc1, ammoCrit1, wGattlingShots); 01382 01383 /* Special for Heavy Gauss Rifles */ 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 }
int FireWeaponNumber | ( | dbref | player, | |
MECH * | mech, | |||
MAP * | mech_map, | |||
int | weapnum, | |||
int | argc, | |||
char ** | args, | |||
int | sight | |||
) |
Definition at line 370 of file mech.combat.c.
References ARCCHECK, ArmorStringFromIndex(), confdata::btech_idf_requires_spotter, CARRYING_CLUB, CLASS_BSUIT, CLASS_MECH, CLASS_MW, CountDestroyedLegs(), CTORSO, DOCHECK0, DOCHECK1, Elevation, FAIL_DESTROYED, Fallen, FaMechRange, find_mech_in_hex(), FindRange(), FindTargetDBREFFromMapNumber(), FindTargetXY(), FindWeaponNumberOnMech_Advanced(), FireSpot(), FireWeapon(), getMech(), GetPartFireMode, HEAT_MODE, HIDDEN, IDF, IsAMS, IsArtillery, IsCoolant, IsMechMounted(), LARM, LLEG, Locking, LOS_NB, LTORSO, MAP::map_height, MAP::map_width, MapCoordToRealCoord(), MapIsUnderground, MapNoFriendlyFire, mech_notify(), MECH_STUNNED, MECHALL, MechCritStatus, MechDugIn, MechFX, MechFY, MechFZ, MechIsQuad, MechLockFire, MechLOSBroadcast(), MechMove, MechNoFriendlyFire, MechPKiller, MechSections, MechSpotter, MechSwarmTarget, MechTarget, MechTargX, MechTargY, MechTargZ, MechTeam, MechType, MechWeapons, MechX, MechY, MoveModeLock, mudconf, MECH::mynum, notify_printf(), NUM_BSUIT_MEMBERS, PartTempNuke, RARM, RLEG, RTORSO, SectHasBusyWeap(), SectIsDestroyed, weapon_struct::special, specials, StealthArmorActive, StopHiding, tprintf(), TURRET, and ZSCALE.
Referenced by firetic_sub_func(), mech_fireweapon(), and mech_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 /* If they fire their weapon while hidden, they should appear */ 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 /* If they fire a weapon while trying to hide stop them from hiding */ 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 /* Exile Stun Code Check */ 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 /* New fancy message for when they try and fire a weapon and the section 00444 * is busy */ 00445 if(weaptype == -5) { 00446 00447 /* Get the section name and print the message */ 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 /* if a quad has 3 of 4 legs dead, it can't fire at all while prone */ 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 /* quads with all 4 legs can fire all weapons while prone. They do not need to prop. */ 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 /* Fire at default target */ 00522 case 1: 00523 00524 /* If its a coolant gun in heat mode we should shot our mech */ 00525 if(IsCoolant(weaptype) && (mode & HEAT_MODE)) { 00526 00527 /* Setting our mech as the target and the other parameters 00528 * as well */ 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 /* default target is a hex */ 00567 ishex = 1; 00568 if(!sight && !IsArtillery(weaptype) && MechLockFire(mech)) { 00569 00570 /* look for enemies in the default hex cause they may have moved */ 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 /* don't check LOS for missile weapons firing at hex number */ 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 /* Check for Spotter here */ 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 /* Fire at the numbered target */ 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 /* Fire at the Map X Y */ 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 /* look for enemies in that hex... */ 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 /* Don't check LOS for missile weapons */ 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 }
void hex_hit | ( | MECH * | mech, | |
int | x, | |||
int | y, | |||
int | weapindx, | |||
int | ammoMode, | |||
int | damage, | |||
int | ishit | |||
) |
Definition at line 1964 of file mech.combat.c.
References hit_building(), LOCK_BUILDING, LOCK_HEX, LOCK_HEX_CLR, LOCK_HEX_IGN, MechStatus, possibly_blow_bridge(), possibly_blow_ice(), and possibly_ignite_or_clear().
Referenced by HitTarget(), Missile_Hit(), and MissileHitTarget().
01966 { 01967 if(!(MechStatus(mech) & (LOCK_BUILDING | LOCK_HEX | LOCK_HEX_IGN | 01968 LOCK_HEX_CLR))) 01969 return; 01970 01971 /* Ok.. we either try to clear/ignite the hex, or alternatively we try to hit building in it */ 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 }
char* hex_target_id | ( | MECH * | mech | ) |
Definition at line 1786 of file mech.combat.c.
References LOCK_BUILDING, LOCK_HEX, LOCK_HEX_CLR, LOCK_HEX_IGN, and MechStatus.
Referenced by FireWeapon().
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 }
void HitTarget | ( | MECH * | mech, | |
int | weapindx, | |||
int | wSection, | |||
int | wCritSlot, | |||
MECH * | hitMech, | |||
int | hitX, | |||
int | hitY, | |||
int | LOS, | |||
int | type, | |||
int | modifier, | |||
int | reallyhit, | |||
int | bth, | |||
int | wGattlingShots, | |||
int | tIsSwarmAttack, | |||
int | player_roll | |||
) |
Definition at line 1523 of file mech.combat.c.
References confdata::btech_glancing_blows, CLASS_MW, Clustersize, CRAZY_MISSILES, weapon_struct::damage, DamageMech(), determineDamageFromHit(), FindAimHitLoc(), FindTargetHitLoc(), FindTCHitLoc(), GetPartAmmoMode, GetPartFireMode, GunPilot, HEAT_MODE, hex_hit(), Immobile, IsArtillery, IsCoolant, IsFlamer, IsMissile, missile_hit_table_struct::key, LBX_MODE, mech_notify(), mech_printf(), MechAim, MechAimType, MECHALL, MechCritStatus, MechLOSBroadcast(), MechType, MechWeapHeat, MechWeapons, Missile_Hit(), MissileHitIndex(), MissileHitTable, MissileHitTarget(), mudconf, missile_hit_table_struct::num_missiles, NUM_SECTIONS, ON_TC, pc_to_dam_conversion(), RAC_MODES, Roll(), SWARM1_MODE, SWARM_MODE, SwarmHitTarget(), and TC_DESTROYED.
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 /* Check to see if we're aiming at a particular location. Swarm attacks can't aim. */ 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 /* Check if it is a glancing blow, if so, make an emit */ 01581 if((mudconf.btech_glancing_blows) && (player_roll == bth) && hitMech) { 01582 /* Yes, even though we have two different glance modes, the above is correct 01583 * because we modified the bth in FireWeapon. Nothing to see here. move along 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; /* very rare case */ 01591 } 01592 } 01593 01594 /* 01595 * Ok, if we're not an artillery weapon or missile and we're not in 01596 * LBX, RAC, Ultra or RFAC mode... 01597 */ 01598 if(!IsArtillery(weapindx) && !IsMissile(weapindx) && !tIsUltra && 01599 !tIsLBX && !tIsRAC) { 01600 01601 if(hitMech) { 01602 01603 /* Flamers - if in heat mode don't do damage */ 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 /* Its a Coolant Gun */ 01617 /* So now we figure out if we want to hit our unit with it 01618 * or a target */ 01619 01620 if(wFireMode & HEAT_MODE) { 01621 01622 /* Hit our own unit with the coolant gun */ 01623 mech_notify(mech, MECHALL, 01624 "%ccCoolant washes over your systems!!%c"); 01625 MechWeapHeat(mech) -= (float) wBaseWeapDamage; 01626 01627 } else { 01628 01629 /* Hit the target with the coolant gun */ 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 /* Never does damage so return */ 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 * Since we're here, we're either 01665 * - A missile weapon 01666 * - An artillery weapon 01667 * - An AC in Ultra, RF or LBX mode 01668 * - A RAC in RAC mode 01669 */ 01670 01671 /* 01672 * Do special case for RACs since they don't have an entry in the MissileHitTable. 01673 * 01674 * We're gonna fake it by pretending we're either an SRM-2, SRM-4 or SRM-6, depending 01675 * upon the mode 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) /* No swarms on hex hits */ 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 /* This is how we'll handle glancing. Any roll < 2 is considering just one missile hit, full damage */ 01733 if (missileindex == -1) 01734 num_missiles_hit = 1; 01735 else 01736 num_missiles_hit = MissileHitTable[loop].num_missiles[missileindex]; 01737 01738 /* 01739 * Check for non-missile, multiple hit weapons, like LBXs, RACs, RFACs and Ultras 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 }
void mech_fireweapon | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Definition at line 341 of file mech.combat.c.
References args, cch, DOCHECK, FireWeaponNumber(), getMap(), MECH::mapindex, mech_parseattributes(), and MECH_USUALO.
Referenced by mech_snipe_func(), and turret_fireweapon().
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 }
void mech_settarget | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Definition at line 181 of file mech.combat.c.
References arc_override, args, cch, ClearFireAdjustments(), DOCHECK, Elevation, EVENT_LOCK, FindTargetDBREFFromMapNumber(), FlMechRange, getMap(), getMech(), GetMechToMechID(), InLineOfSight(), LOCK_BUILDING, LOCK_HEX, LOCK_HEX_CLR, LOCK_HEX_IGN, LOCK_TARGET, LOCK_TICK, MECH::mapindex, mech_lock_event(), mech_notify(), mech_parseattributes(), mech_printf(), MECH_USUALO, MECHALL, MECHEVENT, MechFireAdjustment, MechSpotter, MechStatus, MechSwarmTarget, MechTarget, MechTargX, MechTargY, MechTargZ, MechX, MechY, MECH::mynum, MAP::mynum, notify, notify_printf(), sixth_sense_check(), StopLock, and ValidCoord.
Referenced by mech_snipe_func(), and turret_settarget().
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 /* Targetted a square */ 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 /* Targetted a square w/ special mode (hex / building) */ 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 }
static void mech_ss_event | ( | MUXEVENT * | ev | ) | [static] |
Definition at line 152 of file mech.combat.c.
References BOUNDED(), my_event_type::data, my_event_type::data2, mech_notify(), MECHPILOT, RGotPilot, ss_messages, and Uncon.
Referenced by sixth_sense_check().
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 }
void mech_target | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Definition at line 95 of file mech.combat.c.
References args, ArmorSectionFromString(), ArmorStringFromIndex(), cch, DOCHECK, FindObjectsData(), mech_parseattributes(), MECH_USUALO, MechAim, MechAimType, MechMove, MechTarget, MechType, notify, notify_printf(), and NUM_SECTIONS.
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 }
void possibly_clear | ( | MECH * | mech, | |
MAP * | map, | |||
int | weapindx, | |||
int | ammoMode, | |||
int | damage, | |||
int | x, | |||
int | y, | |||
int | intentional | |||
) |
Definition at line 1911 of file mech.combat.c.
References canWeaponClear(), clear_hex(), MechWeapons, PCOMBAT, possibly_ignite(), possibly_remove_mines(), and Roll().
Referenced by possibly_ignite_or_clear().
01913 { 01914 int igniteBTH = 5; /* This is for intentional clearing */ 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 }
void possibly_ignite | ( | MECH * | mech, | |
MAP * | map, | |||
int | weapindx, | |||
int | ammoMode, | |||
int | x, | |||
int | y, | |||
int | intentional | |||
) |
Definition at line 1881 of file mech.combat.c.
References AC_FLECHETTE_MODE, canWeaponIgnite(), fire_hex(), GetTerrain, HEAVY_FOREST, INFERNO_MODE, IsBallistic, IsEnergy, IsMissile, LIGHT_FOREST, MechWeapons, PCOMBAT, and Roll().
Referenced by possibly_clear(), and possibly_ignite_or_clear().
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 }
void possibly_ignite_or_clear | ( | MECH * | mech, | |
int | weapindx, | |||
int | ammoMode, | |||
int | damage, | |||
int | x, | |||
int | y, | |||
int | intentional | |||
) |
Definition at line 1939 of file mech.combat.c.
References FindObjectsData(), LOCK_HEX_CLR, LOCK_HEX_IGN, MECH::mapindex, MechStatus, possibly_clear(), possibly_ignite(), and Roll().
Referenced by determineDamageFromHit(), hex_hit(), and Missile_Hit().
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 }
Definition at line 751 of file mech.combat.c.
References A_MECHNAME, mech_printf(), MECHALL, MechIDS(), MECH::mynum, and silly_atr_get().
Referenced by FireWeapon().
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 }
Definition at line 164 of file mech.combat.c.
References Destroyed, EVENT_SS, FaMechRange, mech_ss_event(), MECHEVENT, MechIsObservator, MechRTonsV, MechSpecials, Number, Roll(), SS_ABILITY, SSDistMod, and SSTonMod.
Referenced by mech_settarget().
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 }
int weapon_failure_stuff | ( | MECH * | mech, | |
int * | weapnum, | |||
int * | weapindx, | |||
int * | section, | |||
int * | critical, | |||
int * | ammoLoc, | |||
int * | ammoCrit, | |||
int * | ammoLoc1, | |||
int * | ammoCrit1, | |||
int * | modifier, | |||
int * | type, | |||
float | range, | |||
int * | range_ok, | |||
int | wGattlingShots | |||
) |
Definition at line 717 of file mech.combat.c.
References CheckWeaponFailed(), decrement_ammunition(), EGunRangeWithCheck, mech_notify(), MECHALL, POWER_SPIKE, RANGE, WEAPON_DUD, and WEAPON_JAMMED.
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 /* Just decrement ammunition */ 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 }
int arc_override |
Definition at line 21 of file ds.turret.c.
Definition at line 22 of file ds.turret.c.
char* ss_messages[] |
Initial value:
{ "You feel you'll have your hands full before too long..", "You have a bad feeling about this..", "You feel a homicidal maniac is about to pounce on you!", "You think something is amiss..", "You have a slightly bad feeling about this..", "You think someone thinks ill of you..", "Something makes you somewhat feel uneasy..", "Something makes you definitely feel uneasy..", "Something makes you feel out of your element.." }
Definition at line 135 of file mech.combat.c.
Referenced by mech_ss_event().