This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
Functions | |
void | mech_target (dbref player, void *data, char *buffer) |
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) |
char * | hex_target_id (MECH *mech) |
int | canClearOrIgnite (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) |
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 | 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) |
int canClearOrIgnite | ( | int | weapindx | ) |
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, MAP::mynum, MECH::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 }
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 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 }