#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/file.h>
#include "mech.h"
#include "map.h"
#include "mech.events.h"
#include "mech.physical.h"
#include "p.mech.physical.h"
#include "p.mech.combat.h"
#include "p.mech.damage.h"
#include "p.mech.utils.h"
#include "p.mech.los.h"
#include "p.mech.hitloc.h"
#include "p.bsuit.h"
#include "p.btechstats.h"
#include "p.template.h"
#include "p.mech.bth.h"
Include dependency graph for mech.physical.c:
Go to the source code of this file.
Defines | |
#define | ARM_PHYS_CHECK(a) |
#define | GENERIC_CHECK(a, wDeadLegs) |
#define | QUAD_CHECK(a) |
#define | phys_message(txt) MechLOSBroadcasti(mech,target,txt) |
#define | MyDamageMech(a, b, c, d, e, f, g, h, i) |
#define | MyDamageMech2(a, b, c, d, e, f, g, h, i) |
#define | CHARGE_SECTIONS 6 |
#define | DFA_SECTIONS 6 |
Functions | |
int | all_limbs_recycled (MECH *mech) |
char * | phys_form (int AttackType, int add_s) |
void | phys_succeed (MECH *mech, MECH *target, int at) |
void | phys_fail (MECH *mech, MECH *target, int at) |
static int | have_punch (MECH *mech, int loc) |
int | have_axe (MECH *mech, int loc) |
int | have_saw (MECH *mech, int loc) |
int | have_sword (MECH *mech, int loc) |
int | have_mace (MECH *mech, int loc) |
int | phys_common_checks (MECH *mech) |
static int | get_arm_args (int *using, int *argc, char ***args, MECH *mech, int(*have_fn)(MECH *mech, int loc), char *weapon) |
int | punch_checkArm (MECH *mech, int arm) |
void | mech_punch (dbref player, void *data, char *buffer) |
void | mech_club (dbref player, void *data, char *buffer) |
int | axe_checkArm (MECH *mech, int arm) |
void | mech_axe (dbref player, void *data, char *buffer) |
int | saw_checkArm (MECH *mech, int arm) |
void | mech_saw (dbref player, void *data, char *buffer) |
int | mace_checkArm (MECH *mech, int arm) |
void | mech_mace (dbref player, void *data, char *buffer) |
int | sword_checkArm (MECH *mech, int arm) |
void | mech_sword (dbref player, void *data, char *buffer) |
void | mech_trip (dbref player, void *data, char *buffer) |
void | mech_kick (dbref player, void *data, char *buffer) |
void | mech_kickortrip (dbref player, void *data, char *buffer, int AttackType) |
void | mech_charge (dbref player, void *data, char *buffer) |
void | PhysicalAttack (MECH *mech, int damageweight, int baseToHit, int AttackType, int argc, char **args, MAP *mech_map, int sect) |
void | PhysicalTrip (MECH *mech, MECH *target) |
void | PhysicalDamage (MECH *mech, MECH *target, int weightdmg, int AttackType, int sect, int glance) |
int | DeathFromAbove (MECH *mech, MECH *target) |
void | ChargeMech (MECH *mech, MECH *target) |
int | checkGrabClubLocation (MECH *mech, int section, int emit) |
void | mech_grabclub (dbref player, void *data, char *buffer) |
Variables | |
int | global_physical_flag |
const int | resect [CHARGE_SECTIONS] |
#define ARM_PHYS_CHECK | ( | a | ) |
Value:
DOCHECK(MechType(mech) == CLASS_MW || MechType(mech) == CLASS_BSUIT, \ tprintf("You cannot %s without a 'mech!", a)); \ DOCHECK(MechType(mech) != CLASS_MECH, \ tprintf("You cannot %s with this vehicle!", a));
Definition at line 33 of file mech.physical.c.
Referenced by mech_axe(), mech_club(), mech_mace(), mech_punch(), mech_saw(), and mech_sword().
#define CHARGE_SECTIONS 6 |
#define DFA_SECTIONS 6 |
#define GENERIC_CHECK | ( | a, | |||
wDeadLegs | ) |
Value:
ARM_PHYS_CHECK(a);\ DOCHECK(!MechIsQuad(mech) && (wDeadLegs > 1), \ "Without legs? Are you kidding?");\ DOCHECK(!MechIsQuad(mech) && (wDeadLegs > 0),\ "With one leg? Are you kidding?");\ DOCHECK(wDeadLegs > 1,"It'd unbalance you too much in your condition..");\ DOCHECK(wDeadLegs > 2, "Exactly _what_ are you going to kick with?");
Definition at line 40 of file mech.physical.c.
Referenced by mech_kickortrip().
#define MyDamageMech | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i | ) |
Value:
global_physical_flag = 1 ; DamageMech(a,b,c,d,e,f,g,h,i,-1,0,-1,0,0); \ global_physical_flag = 0
Definition at line 1404 of file mech.physical.c.
Referenced by ChargeMech(), DeathFromAbove(), and PhysicalDamage().
#define MyDamageMech2 | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i | ) |
Value:
global_physical_flag = 2 ; DamageMech(a,b,c,d,e,f,g,h,i,-1,0,-1,0,0); \ global_physical_flag = 0
Definition at line 1407 of file mech.physical.c.
Referenced by ChargeMech(), and DeathFromAbove().
#define phys_message | ( | txt | ) | MechLOSBroadcasti(mech,target,txt) |
#define QUAD_CHECK | ( | a | ) |
Value:
DOCHECK(MechType(mech) == CLASS_MECH && MechIsQuad(mech), \ tprintf("What are you going to %s with, your front right leg?", a))
Definition at line 50 of file mech.physical.c.
Referenced by mech_axe(), mech_club(), mech_mace(), mech_punch(), mech_saw(), and mech_sword().
int all_limbs_recycled | ( | MECH * | mech | ) |
Checks to see if all limbs have recycled from any previous physical attacks.
Definition at line 57 of file mech.physical.c.
References LARM, LLEG, mech_notify(), MECHALL, MechSections, RARM, and RLEG.
Referenced by phys_common_checks().
00058 { 00059 if(MechSections(mech)[LARM].recycle || MechSections(mech)[RARM].recycle) { 00060 mech_notify(mech, MECHALL, 00061 "You still have arms recovering from another attack."); 00062 return 0; 00063 } 00064 00065 if(MechSections(mech)[RLEG].recycle || MechSections(mech)[LLEG].recycle) { 00066 mech_notify(mech, MECHALL, 00067 "Your legs are still recovering from your last attack."); 00068 return 0; 00069 } 00070 // Fall through to success. 00071 return 1; 00072 } // end all_limbs_recycled()
int axe_checkArm | ( | MECH * | mech, | |
int | arm | |||
) |
Check to see if the specified arm can be used to axe with.
Definition at line 437 of file mech.physical.c.
References HAND_OR_FOOT_ACTUATOR, mech_printf(), MECHALL, OkayCritSectS, RARM, SectIsDestroyed, and SHOULDER_OR_HIP.
Referenced by mech_axe().
00438 { 00439 char *arm_used = (arm == RARM ? "right" : "left"); 00440 00441 if(SectIsDestroyed(mech, arm)) { 00442 mech_printf(mech, MECHALL, 00443 "Your %s arm is destroyed, you can't axe with it", 00444 arm_used); 00445 return 0; 00446 } else if(!OkayCritSectS(arm, 0, SHOULDER_OR_HIP)) { 00447 mech_printf(mech, MECHALL, 00448 "Your %s shoulder is destroyed, you can't axe with that arm.", 00449 arm_used); 00450 return 0; 00451 } else if(!OkayCritSectS(arm, 3, HAND_OR_FOOT_ACTUATOR)) { 00452 mech_printf(mech, MECHALL, 00453 "Your left hand is destroyed, you can't axe with that arm.", 00454 arm_used); 00455 return 0; 00456 } 00457 // Fall through to success. 00458 return 1; 00459 } // end axe_checkArm()
Definition at line 1822 of file mech.physical.c.
References ArmorStringFromIndex(), AttackMovementMods(), BACK, Blinded, confdata::btech_newcharge, confdata::btech_tl3_charge, CHARGE_SECTIONS, CLASS_MECH, CLASS_VEH_GROUND, CrewStunned, DOCHECKMA, DOCHECKMP, Dodging, Fallen, FindAreaHitGroup(), FindHitLocation(), FindPilotPiloting(), FindSPilotPiloting(), FORWARDARC, FSIDE, GetMechToMechID(), HasBoolAdvantage(), InWeaponArc(), Jumping, LARM, LBUF_SIZE, LLEG, MadePilotSkillRoll(), mech_charge(), mech_damage(), mech_notify(), mech_printf(), MECHALL, MechChargeDistance, MechChargeTarget, MechChargeTimer, MechDesiredSpeed, MechFacing, MechFalls(), MechFX, MechFY, MechLOSBroadcasti(), MechMove, MechPilot, MECHPILOT, MechRealTons, MechSections, MechSpeed, MECHSTARTED, MechStatus, MechType, MIN, MP1, MP_PER_KPH, mudconf, MyDamageMech, MyDamageMech2, MECH::mynum, PHYSICAL_RECYCLE_TIME, RARM, RLEG, Roll(), SectHasBusyWeap(), SendDebug, SetRecycleLimb, Started, TargetMovementMods(), TORSO_LEFT, TORSO_RIGHT, tprintf(), TURRET, Uncon, and UnjammingTurret.
Referenced by move_mech().
01823 { 01824 int baseToHit = 5; 01825 int roll; 01826 int hitGroup; 01827 int hitloc; 01828 int isrear = 0; 01829 int iscritical = 0; 01830 int target_damage; 01831 int mech_damage; 01832 int received_damage; 01833 int inflicted_damage; 01834 int spread; 01835 int i; 01836 int mech_charge; 01837 int target_charge; 01838 int mech_baseToHit; 01839 int targ_baseToHit; 01840 int mech_roll; 01841 int targ_roll; 01842 int done = 0; 01843 char location[50]; 01844 int ts, iwa; 01845 char emit_buff[LBUF_SIZE]; 01846 01847 /* Are they both charging ? */ 01848 if(MechChargeTarget(target) == mech->mynum) { 01849 /* They are both charging each other */ 01850 mech_charge = 1; 01851 target_charge = 1; 01852 01853 /* Check the sections of the first unit for weapons that are cycling */ 01854 done = 0; 01855 for(i = 0; i < CHARGE_SECTIONS && !done; i++) { 01856 if(SectHasBusyWeap(mech, resect[i])) { 01857 ArmorStringFromIndex(resect[i], location, MechType(mech), 01858 MechMove(mech)); 01859 mech_printf(mech, MECHALL, 01860 "You have weapons recycling on your %s.", 01861 location); 01862 mech_charge = 0; 01863 done = 1; 01864 } 01865 } 01866 01867 /* Check the sections of the second unit for weapons that are cycling */ 01868 done = 0; 01869 for(i = 0; i < CHARGE_SECTIONS && !done; i++) { 01870 if(SectHasBusyWeap(target, resect[i])) { 01871 ArmorStringFromIndex(resect[i], location, MechType(target), 01872 MechMove(target)); 01873 mech_printf(target, MECHALL, 01874 "You have weapons recycling on your %s.", 01875 location); 01876 target_charge = 0; 01877 done = 1; 01878 } 01879 } 01880 01881 /* Is the second unit capable of charging */ 01882 if(!Started(target) || Uncon(target) || Blinded(target)) 01883 target_charge = 0; 01884 /* Is the first unit capable of charging */ 01885 if(!Started(mech) || Uncon(mech) || Blinded(mech)) 01886 mech_charge = 0; 01887 01888 /* Is the first unit moving fast enough to charge */ 01889 if(MechSpeed(mech) < MP1) { 01890 mech_notify(mech, MECHALL, 01891 "You aren't moving fast enough to charge."); 01892 mech_charge = 0; 01893 } 01894 01895 /* Is the second unit moving fast enough to charge */ 01896 if(MechSpeed(target) < MP1) { 01897 mech_notify(target, MECHALL, 01898 "You aren't moving fast enough to charge."); 01899 target_charge = 0; 01900 } 01901 01902 /* Check to see if any sections cycling from a previous attack */ 01903 if(MechType(mech) == CLASS_MECH) { 01904 /* Is the first unit's legs cycling */ 01905 if(MechSections(mech)[LLEG].recycle || 01906 MechSections(mech)[RLEG].recycle) { 01907 mech_notify(mech, MECHALL, 01908 "Your legs are still recovering from your last attack."); 01909 mech_charge = 0; 01910 } 01911 /* Is the first unit's arms cycling */ 01912 if(MechSections(mech)[RARM].recycle || 01913 MechSections(mech)[LARM].recycle) { 01914 mech_notify(mech, MECHALL, 01915 "Your arms are still recovering from your last attack."); 01916 mech_charge = 0; 01917 } 01918 } else { 01919 /* Is the first unit's front side cycling */ 01920 if(MechSections(mech)[FSIDE].recycle) { 01921 mech_notify(mech, MECHALL, 01922 "You are still recovering from your last attack!"); 01923 mech_charge = 0; 01924 } 01925 } 01926 01927 /* Check to see if any sections cycling from a previous attack */ 01928 if(MechType(target) == CLASS_MECH) { 01929 /* Is the second unit's legs cycling */ 01930 if(MechSections(target)[LLEG].recycle || 01931 MechSections(target)[RLEG].recycle) { 01932 mech_notify(target, MECHALL, 01933 "Your legs are still recovering from your last attack."); 01934 target_charge = 0; 01935 } 01936 /* Is the second unit's arms cycling */ 01937 if(MechSections(target)[RARM].recycle || 01938 MechSections(target)[LARM].recycle) { 01939 mech_notify(target, MECHALL, 01940 "Your arms are still recovering from your last attack."); 01941 target_charge = 0; 01942 } 01943 } else { 01944 /* Is the second unit's front side cycling */ 01945 if(MechSections(target)[FSIDE].recycle) { 01946 mech_notify(target, MECHALL, 01947 "You are still recovering from your last attack!"); 01948 target_charge = 0; 01949 } 01950 } 01951 01952 /* Is the second unit jumping */ 01953 if(Jumping(target)) { 01954 mech_notify(mech, MECHALL, 01955 "Your target is jumping, you charge underneath it."); 01956 mech_notify(target, MECHALL, 01957 "You can't charge while jumping, try death from above."); 01958 mech_charge = 0; 01959 target_charge = 0; 01960 } 01961 01962 /* Is the first unit jumping */ 01963 if(Jumping(mech)) { 01964 mech_notify(target, MECHALL, 01965 "Your target is jumping, you charge underneath it."); 01966 mech_notify(mech, MECHALL, 01967 "You can't charge while jumping, try death from above."); 01968 mech_charge = 0; 01969 target_charge = 0; 01970 } 01971 01972 /* Is the second unit fallen and the first unit not a tank */ 01973 if(Fallen(target) && (MechType(mech) != CLASS_VEH_GROUND)) { 01974 mech_notify(mech, MECHALL, 01975 "Your target's too low for you to charge it!"); 01976 mech_charge = 0; 01977 } 01978 01979 /* Not sure at the moment if I need this here, but I figured 01980 * couldn't hurt for now */ 01981 /* Is the first unit fallen and the second unit not a tank */ 01982 if(Fallen(mech) && (MechType(target) != CLASS_VEH_GROUND)) { 01983 mech_notify(target, MECHALL, 01984 "Your target's too low for you to charge it!"); 01985 target_charge = 0; 01986 } 01987 01988 /* If the second unit is a mech it can only charge mechs */ 01989 if((MechType(target) == CLASS_MECH) && (MechType(mech) != CLASS_MECH)) { 01990 mech_notify(target, MECHALL, "You can only charge mechs!"); 01991 target_charge = 0; 01992 } 01993 01994 /* If the first unit is a mech it can only charge mechs */ 01995 if((MechType(mech) == CLASS_MECH) && (MechType(target) != CLASS_MECH)) { 01996 mech_notify(mech, MECHALL, "You can only charge mechs!"); 01997 mech_charge = 0; 01998 } 01999 02000 /* If the second unit is a tank, it can only charge tanks and mechs */ 02001 if((MechType(target) == CLASS_VEH_GROUND) && 02002 ((MechType(mech) != CLASS_MECH) && 02003 (MechType(mech) != CLASS_VEH_GROUND))) { 02004 mech_notify(target, MECHALL, 02005 "You can only charge mechs and tanks!"); 02006 target_charge = 0; 02007 } 02008 02009 /* If the first unit is a tank, it can only charge tanks and mechs */ 02010 if((MechType(mech) == CLASS_VEH_GROUND) && 02011 ((MechType(target) != CLASS_MECH) && 02012 (MechType(target) != CLASS_VEH_GROUND))) { 02013 mech_notify(mech, MECHALL, 02014 "You can only charge mechs and tanks!"); 02015 mech_charge = 0; 02016 } 02017 02018 /* Are they stunned ? */ 02019 if(CrewStunned(mech)) { 02020 mech_notify(mech, MECHALL, "You are too stunned to ram!"); 02021 mech_charge = 0; 02022 } 02023 02024 if(CrewStunned(target)) { 02025 mech_notify(target, MECHALL, "You are too stunned to ram!"); 02026 target_charge = 0; 02027 } 02028 02029 /* Are they trying to unjam their turrets ? */ 02030 if(UnjammingTurret(mech)) { 02031 mech_notify(mech, MECHALL, 02032 "You are too busy unjamming your turret!"); 02033 mech_charge = 0; 02034 } 02035 02036 if(UnjammingTurret(target)) { 02037 mech_notify(mech, MECHALL, 02038 "You are too busy unjamming your turret!"); 02039 target_charge = 0; 02040 } 02041 02042 /* Check the arcs to make sure the target is in the front arc */ 02043 ts = MechStatus(mech) & (TORSO_LEFT | TORSO_RIGHT); 02044 MechStatus(mech) &= ~ts; 02045 if(!(InWeaponArc(mech, MechFX(target), MechFY(target)) & FORWARDARC)) { 02046 mech_notify(mech, MECHALL, 02047 "Your charge target is not in your forward arc and you are unable to charge it."); 02048 mech_charge = 0; 02049 } 02050 MechStatus(mech) |= ts; 02051 02052 ts = MechStatus(target) & (TORSO_LEFT | TORSO_RIGHT); 02053 MechStatus(mech) &= ~ts; 02054 if(!(InWeaponArc(target, MechFX(mech), MechFY(mech)) & FORWARDARC)) { 02055 mech_notify(target, MECHALL, 02056 "Your charge target is not in your forward arc and you are unable to charge it."); 02057 target_charge = 0; 02058 } 02059 MechStatus(mech) |= ts; 02060 02061 /* Now to calculate how much damage the first unit will do */ 02062 if(mudconf.btech_newcharge) 02063 target_damage = (((((float) 02064 MechChargeDistance(mech)) * MP1) - 02065 MechSpeed(target) * cos((MechFacing(mech) - 02066 MechFacing(target)) * 02067 (M_PI / 180.))) * 02068 MP_PER_KPH) * (MechRealTons(mech) + 5) / 10; 02069 else 02070 target_damage = 02071 ((MechSpeed(mech) - 02072 MechSpeed(target) * cos((MechFacing(mech) - 02073 MechFacing(target)) * (M_PI / 02074 180.))) * 02075 MP_PER_KPH) * (MechRealTons(mech) + 5) / 10; 02076 02077 if(HasBoolAdvantage(MechPilot(mech), "melee_specialist")) 02078 target_damage++; 02079 02080 /* Not able to do any damage */ 02081 if(target_damage <= 0) { 02082 mech_notify(mech, MECHPILOT, 02083 "Your target pulls away from you and you are unable to charge it."); 02084 mech_charge = 0; 02085 } 02086 02087 /* Now see how much damage the second unit will do */ 02088 if(mudconf.btech_newcharge) 02089 mech_damage = (((((float) 02090 MechChargeDistance(target)) * MP1) - 02091 MechSpeed(mech) * cos((MechFacing(target) - 02092 MechFacing(mech)) * (M_PI / 02093 180.))) 02094 * MP_PER_KPH) * (MechRealTons(target) + 5) / 10; 02095 else 02096 mech_damage = 02097 ((MechSpeed(target) - 02098 MechSpeed(mech) * cos((MechFacing(target) - 02099 MechFacing(mech)) * (M_PI / 180.))) * 02100 MP_PER_KPH) * (MechRealTons(target) + 5) / 10; 02101 02102 if(HasBoolAdvantage(MechPilot(target), "melee_specialist")) 02103 mech_damage++; 02104 02105 /* Not able to do any damage */ 02106 if(mech_damage <= 0) { 02107 mech_notify(target, MECHPILOT, 02108 "Your target pulls away from you and you are unable to charge it."); 02109 target_charge = 0; 02110 } 02111 02112 /* BTH for first unit */ 02113 mech_baseToHit = 5; 02114 mech_baseToHit += 02115 FindPilotPiloting(mech) - FindSPilotPiloting(target); 02116 02117 mech_baseToHit += 02118 (HasBoolAdvantage(MechPilot(mech), "melee_specialist") ? 02119 MIN(0, AttackMovementMods(mech) - 1) : AttackMovementMods(mech)); 02120 02121 mech_baseToHit += TargetMovementMods(mech, target, 0.0); 02122 02123 #ifdef BT_MOVEMENT_MODES 02124 if(Dodging(target)) 02125 mech_baseToHit += 2; 02126 #endif 02127 02128 /* BTH for second unit */ 02129 targ_baseToHit = 5; 02130 targ_baseToHit += 02131 FindPilotPiloting(target) - FindSPilotPiloting(mech); 02132 02133 targ_baseToHit += 02134 (HasBoolAdvantage(MechPilot(target), "melee_specialist") ? 02135 MIN(0, 02136 AttackMovementMods(target) - 02137 1) : AttackMovementMods(target)); 02138 02139 targ_baseToHit += TargetMovementMods(target, mech, 0.0); 02140 02141 #ifdef BT_MOVEMENT_MODES 02142 if(Dodging(mech)) 02143 targ_baseToHit += 2; 02144 #endif 02145 02146 /* Now check to see if its possible for them to even charge */ 02147 if(mech_charge) 02148 if(mech_baseToHit > 12) { 02149 mech_printf(mech, MECHALL, 02150 "Charge: BTH %d\tYou choose not to charge.", 02151 mech_baseToHit); 02152 mech_charge = 0; 02153 } 02154 02155 if(target_charge) 02156 if(targ_baseToHit > 12) { 02157 mech_printf(target, MECHALL, 02158 "Charge: BTH %d\tYou choose not to charge.", 02159 targ_baseToHit); 02160 target_charge = 0; 02161 } 02162 02163 /* Since neither can charge lets exit */ 02164 if(!mech_charge && !target_charge) { 02165 /* MechChargeTarget(mech) and the others are set 02166 after the return */ 02167 MechChargeTarget(target) = -1; 02168 MechChargeTimer(target) = 0; 02169 MechChargeDistance(target) = 0; 02170 return; 02171 } 02172 02173 /* Roll */ 02174 mech_roll = Roll(); 02175 targ_roll = Roll(); 02176 02177 if(mech_charge) 02178 mech_printf(mech, MECHALL, 02179 "Charge: BTH %d\tRoll: %d", mech_baseToHit, 02180 mech_roll); 02181 02182 if(target_charge) 02183 mech_printf(target, MECHALL, 02184 "Charge: BTH %d\tRoll: %d", targ_baseToHit, 02185 targ_roll); 02186 02187 /* Ok the first unit made its roll */ 02188 if(mech_charge && mech_roll >= mech_baseToHit) { 02189 /* OUCH */ 02190 mech_printf(target, MECHALL, 02191 "CRASH!!!\n%s charges into you!", 02192 GetMechToMechID(target, mech)); 02193 mech_notify(mech, MECHALL, 02194 "SMASH!!! You crash into your target!"); 02195 hitGroup = FindAreaHitGroup(mech, target); 02196 isrear = (hitGroup == BACK); 02197 02198 /* Record the damage for debugging then dish it out */ 02199 inflicted_damage = target_damage; 02200 spread = target_damage / 5; 02201 02202 for(i = 0; i < spread; i++) { 02203 hitloc = 02204 FindHitLocation(target, hitGroup, &iscritical, &isrear); 02205 MyDamageMech(target, mech, 1, MechPilot(mech), hitloc, 02206 isrear, iscritical, 5, 0); 02207 } 02208 02209 if(target_damage % 5) { 02210 hitloc = 02211 FindHitLocation(target, hitGroup, &iscritical, &isrear); 02212 MyDamageMech(target, mech, 1, MechPilot(mech), hitloc, 02213 isrear, iscritical, (target_damage % 5), 0); 02214 } 02215 02216 hitGroup = FindAreaHitGroup(target, mech); 02217 isrear = (hitGroup == BACK); 02218 02219 /* Ok now how much damage will the first unit take from 02220 * charging */ 02221 if(mudconf.btech_newcharge && mudconf.btech_tl3_charge) 02222 target_damage = 02223 (((((float) MechChargeDistance(mech)) * MP1) - 02224 MechSpeed(target) * 02225 cos((MechFacing(mech) - 02226 MechFacing(target)) * (M_PI / 180.))) * 02227 MP_PER_KPH) * (MechRealTons(mech) + 5) / 20; 02228 else 02229 target_damage = (MechRealTons(target) + 5) / 10; /* REUSED! */ 02230 02231 /* Record the damage for debugging then dish it out */ 02232 received_damage = target_damage; 02233 spread = target_damage / 5; 02234 02235 for(i = 0; i < spread; i++) { 02236 hitloc = 02237 FindHitLocation(mech, hitGroup, &iscritical, &isrear); 02238 MyDamageMech2(mech, mech, 0, -1, hitloc, isrear, 02239 iscritical, 5, 0); 02240 } 02241 02242 if(target_damage % 5) { 02243 hitloc = 02244 FindHitLocation(mech, hitGroup, &iscritical, &isrear); 02245 MyDamageMech2(mech, mech, 0, -1, hitloc, isrear, 02246 iscritical, (target_damage % 5), 0); 02247 } 02248 02249 /* Stop him */ 02250 MechSpeed(mech) = 0; 02251 MechDesiredSpeed(mech) = 0; 02252 02253 /* Emit the damage for debugging purposes */ 02254 snprintf(emit_buff, LBUF_SIZE, "#%i charges #%i (%i/%i) Distance:" 02255 " %.2f DI: %i DR: %i", mech->mynum, target->mynum, 02256 mech_baseToHit, mech_roll, MechChargeDistance(mech), 02257 inflicted_damage, received_damage); 02258 SendDebug(emit_buff); 02259 02260 /* Make the first unit roll for doing the charge if it is a mech */ 02261 if(MechType(mech) == CLASS_MECH && !MadePilotSkillRoll(mech, 2)) { 02262 mech_notify(mech, MECHALL, 02263 "Your piloting skill fails and you fall over!!"); 02264 MechFalls(mech, 1, 1); 02265 } 02266 /* Make the second unit roll for receiving the charge if it is a mech */ 02267 if(MechType(mech) == CLASS_MECH && !MadePilotSkillRoll(target, 2)) { 02268 mech_notify(target, MECHALL, 02269 "Your piloting skill fails and you fall over!!"); 02270 MechFalls(target, 1, 1); 02271 } 02272 } 02273 02274 /* Ok the second unit made its roll */ 02275 if(target_charge && targ_roll >= targ_baseToHit) { 02276 /* OUCH */ 02277 mech_printf(mech, MECHALL, 02278 "CRASH!!!\n%s charges into you!", 02279 GetMechToMechID(mech, target)); 02280 mech_notify(target, MECHALL, 02281 "SMASH!!! You crash into your target!"); 02282 hitGroup = FindAreaHitGroup(target, mech); 02283 isrear = (hitGroup == BACK); 02284 02285 /* Record the damage for debugging then dish it out */ 02286 inflicted_damage = mech_damage; 02287 spread = mech_damage / 5; 02288 02289 for(i = 0; i < spread; i++) { 02290 hitloc = 02291 FindHitLocation(mech, hitGroup, &iscritical, &isrear); 02292 MyDamageMech(mech, target, 1, MechPilot(target), hitloc, 02293 isrear, iscritical, 5, 0); 02294 } 02295 02296 if(mech_damage % 5) { 02297 hitloc = 02298 FindHitLocation(mech, hitGroup, &iscritical, &isrear); 02299 MyDamageMech(mech, target, 1, MechPilot(target), hitloc, 02300 isrear, iscritical, (mech_damage % 5), 0); 02301 } 02302 02303 hitGroup = FindAreaHitGroup(mech, target); 02304 isrear = (hitGroup == BACK); 02305 02306 /* Ok now how much damage will the second unit take from 02307 * charging */ 02308 if(mudconf.btech_newcharge && mudconf.btech_tl3_charge) 02309 target_damage = 02310 (((((float) MechChargeDistance(target)) * MP1) - 02311 MechSpeed(mech) * 02312 cos((MechFacing(target) - 02313 MechFacing(mech)) * (M_PI / 180.))) * MP_PER_KPH) * 02314 (MechRealTons(mech) + 5) / 20; 02315 else 02316 target_damage = (MechRealTons(mech) + 5) / 10; /* REUSED! */ 02317 02318 /* Record the damage for debugging then dish it out */ 02319 received_damage = target_damage; 02320 spread = target_damage / 5; 02321 02322 for(i = 0; i < spread; i++) { 02323 hitloc = 02324 FindHitLocation(target, hitGroup, &iscritical, &isrear); 02325 MyDamageMech2(target, target, 0, -1, hitloc, isrear, 02326 iscritical, 5, 0); 02327 } 02328 02329 if(mech_damage % 5) { 02330 hitloc = 02331 FindHitLocation(target, hitGroup, &iscritical, &isrear); 02332 MyDamageMech2(target, target, 0, -1, hitloc, isrear, 02333 iscritical, (mech_damage % 5), 0); 02334 } 02335 02336 /* Stop him */ 02337 MechSpeed(target) = 0; 02338 MechDesiredSpeed(target) = 0; 02339 02340 /* Emit the damage for debugging purposes */ 02341 snprintf(emit_buff, LBUF_SIZE, "#%i charges #%i (%i/%i) Distance:" 02342 " %.2f DI: %i DR: %i", target->mynum, mech->mynum, 02343 targ_baseToHit, targ_roll, MechChargeDistance(target), 02344 inflicted_damage, received_damage); 02345 SendDebug(emit_buff); 02346 02347 if(MechType(mech) == CLASS_MECH && !MadePilotSkillRoll(mech, 2)) { 02348 mech_notify(mech, MECHALL, 02349 "Your piloting skill fails and you fall over!!"); 02350 MechFalls(mech, 1, 1); 02351 } 02352 if(MechType(target) == CLASS_MECH 02353 && !MadePilotSkillRoll(target, 2)) { 02354 mech_notify(target, MECHALL, 02355 "Your piloting skill fails and you fall over!!"); 02356 MechFalls(target, 1, 1); 02357 } 02358 } 02359 02360 /* Cycle the sections so they can't make another attack for a while */ 02361 if(MechType(mech) == CLASS_MECH) { 02362 for(i = 0; i < CHARGE_SECTIONS; i++) 02363 SetRecycleLimb(mech, resect[i], PHYSICAL_RECYCLE_TIME); 02364 } else { 02365 SetRecycleLimb(mech, FSIDE, PHYSICAL_RECYCLE_TIME); 02366 SetRecycleLimb(mech, TURRET, PHYSICAL_RECYCLE_TIME); 02367 } 02368 02369 if(MechType(target) == CLASS_MECH) { 02370 for(i = 0; i < CHARGE_SECTIONS; i++) 02371 SetRecycleLimb(target, resect[i], PHYSICAL_RECYCLE_TIME); 02372 } else { 02373 SetRecycleLimb(target, FSIDE, PHYSICAL_RECYCLE_TIME); 02374 SetRecycleLimb(target, TURRET, PHYSICAL_RECYCLE_TIME); 02375 } 02376 02377 /* MechChargeTarget(mech) and the others are set 02378 after the return */ 02379 MechChargeTarget(target) = -1; 02380 MechChargeTimer(target) = 0; 02381 MechChargeDistance(target) = 0; 02382 return; 02383 } 02384 02385 /* Check to see if any weapons cycling in any of the sections */ 02386 for(i = 0; i < CHARGE_SECTIONS; i++) { 02387 if(SectHasBusyWeap(mech, i)) { 02388 ArmorStringFromIndex(i, location, MechType(mech), MechMove(mech)); 02389 mech_printf(mech, MECHALL, 02390 "You have weapons recycling on your %s.", location); 02391 return; 02392 } 02393 } 02394 02395 /* Check if they going fast enough to charge */ 02396 DOCHECKMA(MechSpeed(mech) < MP1, 02397 "You aren't moving fast enough to charge."); 02398 02399 /* Check to see if their sections cycling */ 02400 if(MechType(mech) == CLASS_MECH) { 02401 DOCHECKMA(MechSections(mech)[LLEG].recycle || 02402 MechSections(mech)[RLEG].recycle, 02403 "Your legs are still recovering from your last attack."); 02404 DOCHECKMA(MechSections(mech)[RARM].recycle || 02405 MechSections(mech)[LARM].recycle, 02406 "Your arms are still recovering from your last attack."); 02407 } else { 02408 DOCHECKMA(MechSections(mech)[FSIDE].recycle, 02409 "You are still recovering from your last attack!"); 02410 } 02411 02412 /* See if either the target or the attacker are jumping */ 02413 DOCHECKMA(Jumping(target), 02414 "Your target is jumping, you charge underneath it."); 02415 DOCHECKMA(Jumping(mech), 02416 "You can't charge while jumping, try death from above."); 02417 02418 /* If target is fallen make sure you in a tank */ 02419 DOCHECKMA(Fallen(target) && 02420 (MechType(mech) != CLASS_VEH_GROUND), 02421 "Your target's too low for you to charge it!"); 02422 02423 /* Only mechs can charge mechs */ 02424 DOCHECKMA((MechType(mech) == CLASS_MECH) && 02425 (MechType(target) != CLASS_MECH), "You can only charge mechs!"); 02426 02427 /* Only tanks can charge tanks and mechs */ 02428 DOCHECKMA((MechType(mech) == CLASS_VEH_GROUND) && 02429 ((MechType(target) != CLASS_MECH) && 02430 (MechType(target) != CLASS_VEH_GROUND)), 02431 "You can only charge mechs and tanks!"); 02432 02433 /* Check the arc make sure target is in front arc */ 02434 ts = MechStatus(mech) & (TORSO_LEFT | TORSO_RIGHT); 02435 MechStatus(mech) &= ~ts; 02436 iwa = InWeaponArc(mech, MechFX(target), MechFY(target)); 02437 MechStatus(mech) |= ts; 02438 DOCHECKMA(!(iwa & FORWARDARC), 02439 "Your charge target is not in your forward arc and you are unable to charge it."); 02440 02441 /* Damage inflicted by the charge */ 02442 if(mudconf.btech_newcharge) 02443 target_damage = (((((float) 02444 MechChargeDistance(mech)) * MP1) - 02445 MechSpeed(target) * cos((MechFacing(mech) - 02446 MechFacing(target)) * 02447 (M_PI / 180.))) * 02448 MP_PER_KPH) * (MechRealTons(mech) + 5) / 10 + 1; 02449 else 02450 target_damage = 02451 ((MechSpeed(mech) - MechSpeed(target) * cos((MechFacing(mech) - 02452 MechFacing(target)) * 02453 (M_PI / 180.))) * 02454 MP_PER_KPH) * (MechRealTons(mech) + 5) / 10 + 1; 02455 02456 if(HasBoolAdvantage(MechPilot(mech), "melee_specialist")) 02457 target_damage++; 02458 02459 /* Not enough damage done so no charge */ 02460 DOCHECKMP(target_damage <= 0, 02461 "Your target pulls away from you and you are unable to charge it."); 02462 02463 /* BTH */ 02464 baseToHit += FindPilotPiloting(mech) - FindSPilotPiloting(target); 02465 02466 baseToHit += (HasBoolAdvantage(MechPilot(mech), "melee_specialist") ? 02467 MIN(0, 02468 AttackMovementMods(mech) - 02469 1) : AttackMovementMods(mech)); 02470 02471 baseToHit += TargetMovementMods(mech, target, 0.0); 02472 02473 #ifdef BT_MOVEMENT_MODES 02474 if(Dodging(target)) 02475 baseToHit += 2; 02476 #endif 02477 02478 DOCHECKMA(baseToHit > 12, 02479 tprintf("Charge: BTH %d\tYou choose not to charge.", 02480 baseToHit)); 02481 02482 /* Roll */ 02483 roll = Roll(); 02484 mech_printf(mech, MECHALL, "Charge: BTH %d\tRoll: %d", baseToHit, roll); 02485 02486 /* Did the charge work ? */ 02487 if(roll >= baseToHit) { 02488 /* OUCH */ 02489 MechLOSBroadcasti(mech, target, tprintf("%ss %%s!", 02490 MechType(mech) == 02491 CLASS_MECH ? "charge" : 02492 "ram")); 02493 mech_printf(target, MECHSTARTED, "CRASH!!!\n%s %ss into you!", 02494 GetMechToMechID(target, mech), 02495 MechType(mech) == CLASS_MECH ? "charge" : "ram"); 02496 mech_notify(mech, MECHALL, "SMASH!!! You crash into your target!"); 02497 hitGroup = FindAreaHitGroup(mech, target); 02498 02499 if(hitGroup == BACK) 02500 isrear = 1; 02501 else 02502 isrear = 0; 02503 02504 /* Record the damage then dish it out */ 02505 inflicted_damage = target_damage; 02506 spread = target_damage / 5; 02507 02508 for(i = 0; i < spread; i++) { 02509 hitloc = FindHitLocation(target, hitGroup, &iscritical, &isrear); 02510 MyDamageMech(target, mech, 1, MechPilot(mech), hitloc, isrear, 02511 iscritical, 5, 0); 02512 } 02513 02514 if(target_damage % 5) { 02515 hitloc = FindHitLocation(target, hitGroup, &iscritical, &isrear); 02516 MyDamageMech(target, mech, 1, MechPilot(mech), hitloc, isrear, 02517 iscritical, (target_damage % 5), 0); 02518 } 02519 02520 hitGroup = FindAreaHitGroup(target, mech); 02521 isrear = (hitGroup == BACK); 02522 02523 /* Damage done to the attacker for the charge */ 02524 if(mudconf.btech_newcharge && mudconf.btech_tl3_charge) 02525 mech_damage = 02526 (((((float) MechChargeDistance(mech)) * MP1) - 02527 MechSpeed(target) * 02528 cos((MechFacing(mech) - 02529 MechFacing(target)) * (M_PI / 180.))) * MP_PER_KPH) * 02530 (MechRealTons(target) + 5) / 20; 02531 else 02532 mech_damage = (MechRealTons(target) + 5) / 10; 02533 02534 /* Record the damage then dish it out */ 02535 received_damage = mech_damage; 02536 spread = mech_damage / 5; 02537 02538 for(i = 0; i < spread; i++) { 02539 hitloc = FindHitLocation(mech, hitGroup, &iscritical, &isrear); 02540 MyDamageMech2(mech, mech, 0, -1, hitloc, isrear, iscritical, 5, 02541 0); 02542 } 02543 02544 if(mech_damage % 5) { 02545 hitloc = FindHitLocation(mech, hitGroup, &iscritical, &isrear); 02546 MyDamageMech2(mech, mech, 0, -1, hitloc, isrear, iscritical, 02547 (mech_damage % 5), 0); 02548 } 02549 02550 /* Force piloting roll for attacker if they are in a mech */ 02551 if(MechType(mech) == CLASS_MECH && !MadePilotSkillRoll(mech, 2)) { 02552 mech_notify(mech, MECHALL, 02553 "Your piloting skill fails and you fall over!!"); 02554 MechFalls(mech, 1, 1); 02555 } 02556 02557 /* Force piloting roll for target if they are in a mech */ 02558 if(MechType(target) == CLASS_MECH && !MadePilotSkillRoll(target, 2)) { 02559 mech_notify(target, MECHSTARTED, 02560 "Your piloting skill fails and you fall over!!"); 02561 MechFalls(target, 1, 1); 02562 } 02563 02564 /* Stop him */ 02565 MechSpeed(mech) = 0; 02566 MechDesiredSpeed(mech) = 0; 02567 02568 /* Emit the damage for debugging purposes */ 02569 snprintf(emit_buff, LBUF_SIZE, "#%i charges #%i (%i/%i) Distance:" 02570 " %.2f DI: %i DR: %i", mech->mynum, target->mynum, baseToHit, 02571 roll, MechChargeDistance(mech), inflicted_damage, 02572 received_damage); 02573 SendDebug(emit_buff); 02574 02575 } 02576 02577 /* Cycle the sections so they can't make another attack for a while */ 02578 if(MechType(mech) == CLASS_MECH) { 02579 for(i = 0; i < CHARGE_SECTIONS; i++) 02580 SetRecycleLimb(mech, resect[i], PHYSICAL_RECYCLE_TIME); 02581 } else { 02582 SetRecycleLimb(mech, FSIDE, PHYSICAL_RECYCLE_TIME); 02583 SetRecycleLimb(mech, TURRET, PHYSICAL_RECYCLE_TIME); 02584 } 02585 return; 02586 } // end ChargeMech()
int checkGrabClubLocation | ( | MECH * | mech, | |
int | section, | |||
int | emit | |||
) |
Definition at line 2591 of file mech.physical.c.
References ArmorStringFromIndex(), HAND_OR_FOOT_ACTUATOR, mech_notify(), MECHALL, MechMove, MechType, OkayCritSectS, SectHasBusyWeap(), SectIsDestroyed, and SHOULDER_OR_HIP.
Referenced by mech_grabclub().
02592 { 02593 int tCanGrab = 1; 02594 char buf[100]; 02595 char location[20]; 02596 02597 ArmorStringFromIndex(section, location, MechType(mech), MechMove(mech)); 02598 02599 if(SectIsDestroyed(mech, section)) { 02600 sprintf(buf, "Your %s is destroyed.", location); 02601 tCanGrab = 0; 02602 } else if(!OkayCritSectS(section, 3, HAND_OR_FOOT_ACTUATOR)) { 02603 sprintf(buf, "Your %s's hand actuator is destroyed or missing.", 02604 location); 02605 tCanGrab = 0; 02606 } else if(!OkayCritSectS(section, 0, SHOULDER_OR_HIP)) { 02607 sprintf(buf, 02608 "Your %s's shoulder actuator is destroyed or missing.", 02609 location); 02610 tCanGrab = 0; 02611 } else if(SectHasBusyWeap(mech, section)) { 02612 sprintf(buf, "Your %s is still recovering from it's last attack.", 02613 location); 02614 tCanGrab = 0; 02615 } 02616 02617 if(!tCanGrab && emit) 02618 mech_notify(mech, MECHALL, buf); 02619 02620 return tCanGrab; 02621 } // end checkGrabClubLocation()
Definition at line 1621 of file mech.physical.c.
References ArmorStringFromIndex(), AttackMovementMods(), BACK, confdata::btech_phys_use_pskill, CLASS_AERO, CLASS_BSUIT, CLASS_DS, CLASS_MECH, CLASS_VTOL, DFA_ATTACK, DFA_SECTIONS, DOCHECKMA0, Dodging, Fallen, FindAreaHitGroup(), FindHitLocation(), FindKickLocation(), FindPilotPiloting(), FindPunchLocation(), FRONT, getMap(), GetMechToMechID(), HasBoolAdvantage(), headhitmwdamage(), Jumping, JUMPING, Landed, LARM, LLEG, MadePilotSkillRoll(), MakeMechFall, MECH::mapindex, MapNoFriendlyFire, mech_damage(), mech_notify(), mech_printf(), MECHALL, MechDesiredSpeed, MechElevation, MechFalls(), MechFloods(), MechFZ, MechLOSBroadcast(), MechLOSBroadcasti(), MechMove, MechPilot, MechRealTons, MechSections, MechSpeed, MECHSTARTED, MechStatus, MechTeam, MechTons, MechType, MechZ, MIN, MoveModeLock, mudconf, MyDamageMech, MyDamageMech2, PHYSICAL_RECYCLE_TIME, RARM, RLEG, Roll(), SectHasBusyWeap(), SetRecycleLimb, TargetMovementMods(), tprintf(), and ZSCALE.
Referenced by LandMech().
01622 { 01623 int baseToHit = 5; 01624 int roll; 01625 int hitGroup; 01626 int hitloc; 01627 int isrear = 0; 01628 int iscritical = 0; 01629 int target_damage; 01630 int mech_damage; 01631 int spread; 01632 int i, tmpi; 01633 char location[50]; 01634 MAP *map = getMap(mech->mapindex); 01635 01636 /* Weapons recycling check on each major section */ 01637 for(i = 0; i < DFA_SECTIONS; i++) 01638 if(SectHasBusyWeap(mech, resect[i])) { 01639 ArmorStringFromIndex(resect[i], location, MechType(mech), 01640 MechMove(mech)); 01641 mech_printf(mech, MECHALL, 01642 "You have weapons recycling on your %s.", location); 01643 return 0; 01644 } 01645 // Our target is no longer on the map. 01646 DOCHECKMA0((mech->mapindex != target->mapindex), 01647 "Your target is no longer valid."); 01648 01649 #ifdef BT_MOVEMENT_MODES 01650 DOCHECKMA0(Dodging(mech) || MoveModeLock(mech), 01651 "You cannot use physicals while using a special movement mode."); 01652 #endif 01653 01654 DOCHECKMA0(MechSections(mech)[LLEG].recycle || 01655 MechSections(mech)[RLEG].recycle, 01656 "Your legs are still recovering from your last attack."); 01657 DOCHECKMA0(MechSections(mech)[RARM].recycle || 01658 MechSections(mech)[LARM].recycle, 01659 "Your arms are still recovering from your last attack."); 01660 01661 DOCHECKMA0(Jumping(target), 01662 "Your target is airborne, you cannot land on it."); 01663 01664 if((MechType(target) == CLASS_VTOL) || (MechType(target) == CLASS_AERO) || 01665 (MechType(target) == CLASS_DS)) 01666 DOCHECKMA0(!Landed(target), 01667 "Your target is airborne, you cannot land on it."); 01668 01669 DOCHECKMA0((MechTeam(mech) == MechTeam(target)) && MapNoFriendlyFire(map), 01670 "Friendly DFA? I don't think so...."); 01671 if(mudconf.btech_phys_use_pskill) 01672 baseToHit = FindPilotPiloting(mech); 01673 01674 baseToHit += (HasBoolAdvantage(MechPilot(mech), "melee_specialist") ? 01675 MIN(0, 01676 AttackMovementMods(mech)) - 01677 1 : AttackMovementMods(mech)); 01678 baseToHit += TargetMovementMods(mech, target, 0.0); 01679 baseToHit += MechType(target) == CLASS_BSUIT ? 1 : 0; 01680 01681 #ifdef BT_MOVEMENT_MODES 01682 if(Dodging(target)) 01683 baseToHit += 2; 01684 #endif 01685 01686 DOCHECKMA0(baseToHit > 12, 01687 tprintf 01688 ("DFA: BTH %d\tYou choose not to attack and land from your jump.", 01689 baseToHit)); 01690 01691 roll = Roll(); 01692 mech_printf(mech, MECHALL, "DFA: BTH %d\tRoll: %d", baseToHit, roll); 01693 01694 MechStatus(mech) &= ~JUMPING; 01695 MechStatus(mech) &= ~DFA_ATTACK; 01696 01697 if(roll >= baseToHit) { 01698 /* OUCH */ 01699 mech_printf(target, MECHSTARTED, 01700 "DEATH FROM ABOVE!!!\n%s lands on you from above!", 01701 GetMechToMechID(target, mech)); 01702 mech_notify(mech, MECHALL, "You land on your target legs first!"); 01703 MechLOSBroadcasti(mech, target, "lands on %s!"); 01704 01705 hitGroup = FindAreaHitGroup(mech, target); 01706 if(hitGroup == BACK) 01707 isrear = 1; 01708 01709 target_damage = (3 * MechRealTons(mech)) / 10; 01710 01711 if(MechTons(mech) % 10) 01712 target_damage++; 01713 01714 if(HasBoolAdvantage(MechPilot(mech), "melee_specialist")) 01715 target_damage++; 01716 01717 spread = target_damage / 5; 01718 01719 for(i = 0; i < spread; i++) { 01720 if(Fallen(target) || MechType(target) != CLASS_MECH) 01721 hitloc = 01722 FindHitLocation(target, hitGroup, &iscritical, &isrear); 01723 else 01724 hitloc = FindPunchLocation(target, hitGroup); 01725 01726 MyDamageMech(target, mech, 1, MechPilot(mech), hitloc, isrear, 01727 iscritical, 5, 0); 01728 } 01729 01730 if(target_damage % 5) { 01731 if(Fallen(target) || (MechType(target) != CLASS_MECH)) 01732 hitloc = 01733 FindHitLocation(target, hitGroup, &iscritical, &isrear); 01734 else 01735 hitloc = FindPunchLocation(target, hitGroup); 01736 01737 MyDamageMech(target, mech, 1, MechPilot(mech), hitloc, isrear, 01738 iscritical, (target_damage % 5), 0); 01739 } 01740 01741 mech_damage = MechTons(mech) / 5; 01742 01743 spread = mech_damage / 5; 01744 01745 for(i = 0; i < spread; i++) { 01746 hitloc = FindKickLocation(mech, FRONT); 01747 MyDamageMech2(mech, mech, 0, -1, hitloc, 0, 0, 5, 0); 01748 } 01749 01750 if(mech_damage % 5) { 01751 hitloc = FindKickLocation(mech, FRONT); 01752 MyDamageMech2(mech, mech, 0, -1, hitloc, 0, 0, 01753 (mech_damage % 5), 0); 01754 } 01755 01756 if(!Fallen(mech)) { 01757 if(!MadePilotSkillRoll(mech, 4)) { 01758 mech_notify(mech, MECHALL, 01759 "Your piloting skill fails and you fall over!!"); 01760 MechLOSBroadcast(mech, "stumbles and falls down!"); 01761 MechFalls(mech, 1, 0); 01762 } 01763 if(MechType(target) == CLASS_MECH && 01764 !MadePilotSkillRoll(target, 2)) { 01765 mech_notify(target, MECHSTARTED, 01766 "Your piloting skill fails and you fall over!!"); 01767 MechLOSBroadcast(target, "stumbles and falls down!"); 01768 MechFalls(target, 1, 0); 01769 } 01770 } 01771 01772 } else { 01773 /* Missed DFA attack */ 01774 if(!Fallen(mech)) { 01775 mech_notify(mech, MECHALL, 01776 "You miss your DFA attack and fall on your back!!"); 01777 MechLOSBroadcast(mech, "misses DFA and falls down!"); 01778 } 01779 01780 mech_damage = MechTons(mech) / 5; 01781 spread = mech_damage / 5; 01782 01783 for(i = 0; i < spread; i++) { 01784 hitloc = FindHitLocation(mech, BACK, &iscritical, &tmpi); 01785 MyDamageMech2(mech, mech, 0, -1, hitloc, 1, iscritical, 5, 0); 01786 } 01787 01788 if(mech_damage % 5) { 01789 hitloc = FindHitLocation(mech, BACK, &iscritical, &tmpi); 01790 MyDamageMech2(mech, mech, 0, -1, hitloc, 1, iscritical, 01791 (mech_damage % 5), 0); 01792 } 01793 01794 /* now damage pilot */ 01795 if(!MadePilotSkillRoll(mech, 2)) { 01796 mech_notify(mech, MECHALL, 01797 "You take personal injury from the fall!"); 01798 headhitmwdamage(mech, mech, 1); 01799 } 01800 01801 MechSpeed(mech) = 0.0; 01802 MechDesiredSpeed(mech) = 0.0; 01803 01804 MakeMechFall(mech); 01805 MechZ(mech) = MechElevation(mech); 01806 MechFZ(mech) = MechZ(mech) * ZSCALE; 01807 01808 if(MechZ(mech) < 0) 01809 MechFloods(mech); 01810 01811 } 01812 01813 for(i = 0; i < DFA_SECTIONS; i++) 01814 SetRecycleLimb(mech, resect[i], PHYSICAL_RECYCLE_TIME); 01815 01816 return 1; 01817 } // end DeathFromAbove()
static int get_arm_args | ( | int * | using, | |
int * | argc, | |||
char *** | args, | |||
MECH * | mech, | |||
int(*)(MECH *mech, int loc) | have_fn, | |||
char * | weapon | |||
) | [static] |
Definition at line 238 of file mech.physical.c.
References LARM, mech_printf(), MECHALL, P_LEFT, P_RIGHT, and RARM.
Referenced by mech_axe(), mech_kickortrip(), mech_mace(), mech_punch(), mech_saw(), and mech_sword().
00240 { 00241 00242 if(*argc != 0 && args[0][0][0] != '\0' && args[0][0][1] == '\0') { 00243 char arm = toupper(args[0][0][0]); 00244 00245 // Determine which flag we're dealing with (Both, Left, Right) 00246 switch (arm) { 00247 case 'B': 00248 *using = P_LEFT | P_RIGHT; 00249 --*argc; 00250 ++*args; 00251 break; 00252 00253 case 'L': 00254 *using = P_LEFT; 00255 --*argc; 00256 ++*args; 00257 break; 00258 00259 case 'R': 00260 *using = P_RIGHT; 00261 --*argc; 00262 ++*args; 00263 } // end switch() 00264 } // end if() 00265 00266 // Check for the presence of specified arms, or pick one. *using set in 00267 // the above switch statement. 00268 switch (*using) { 00269 case P_LEFT: 00270 if(!have_fn(mech, LARM)) { 00271 mech_printf(mech, MECHALL, 00272 "You don't have %s in your left arm!", weapon); 00273 return 1; 00274 } 00275 break; 00276 00277 case P_RIGHT: 00278 if(!have_fn(mech, RARM)) { 00279 mech_printf(mech, MECHALL, 00280 "You don't have %s in your right arm!", weapon); 00281 return 1; 00282 } 00283 break; 00284 00285 case P_LEFT | P_RIGHT: 00286 if(!have_fn(mech, LARM)) 00287 *using &= ~P_LEFT; 00288 if(!have_fn(mech, RARM)) 00289 *using &= ~P_RIGHT; 00290 break; 00291 } // end switch() 00292 00293 // Fall through to success. 00294 return 0; 00295 } // end get_arm_args()
int have_axe | ( | MECH * | mech, | |
int | loc | |||
) |
Does our unit have an axe?
Definition at line 174 of file mech.physical.c.
References AXE, FindObj(), I2Special, and MechTons.
Referenced by mech_axe(), and mech_grabclub().
int have_mace | ( | MECH * | mech, | |
int | loc | |||
) |
Does our unit have a mace?
Definition at line 199 of file mech.physical.c.
References FindObj(), I2Special, MACE, and MechTons.
Referenced by mech_grabclub(), and mech_mace().
static int have_punch | ( | MECH * | mech, | |
int | loc | |||
) | [static] |
int have_saw | ( | MECH * | mech, | |
int | loc | |||
) |
Does our unit have a dual_saw?
Definition at line 182 of file mech.physical.c.
References DUAL_SAW, FindObj(), and I2Special.
Referenced by mech_saw().
int have_sword | ( | MECH * | mech, | |
int | loc | |||
) |
Does our unit have a sword?
Definition at line 190 of file mech.physical.c.
References FindObj(), I2Special, MechTons, and SWORD.
Referenced by mech_grabclub(), and mech_sword().
00191 { 00192 return FindObj(mech, loc, 00193 I2Special(SWORD)) >= ((MechTons(mech) + 15) / 20); 00194 }
int mace_checkArm | ( | MECH * | mech, | |
int | arm | |||
) |
Check our arms to see if they can mace.
Definition at line 577 of file mech.physical.c.
References HAND_OR_FOOT_ACTUATOR, mech_printf(), MECHALL, OkayCritSectS, RARM, SectIsDestroyed, and SHOULDER_OR_HIP.
Referenced by mech_mace().
00578 { 00579 char *arm_used = (arm == RARM ? "right" : "left"); 00580 00581 if(SectIsDestroyed(mech, arm)) { 00582 mech_printf(mech, MECHALL, 00583 "Your %s arm is destroyed, you can't use a mace with it.", 00584 arm_used); 00585 return 0; 00586 } else if(!OkayCritSectS(arm, 0, SHOULDER_OR_HIP)) { 00587 mech_printf(mech, MECHALL, 00588 "Your %s shoulder is destroyed, you can't use a mace with that arm.", 00589 arm_used); 00590 return 0; 00591 } else if(!OkayCritSectS(arm, 3, HAND_OR_FOOT_ACTUATOR)) { 00592 mech_printf(mech, MECHALL, 00593 "Your %s hand is destroyed, you can't use a mace with that arm.", 00594 arm_used); 00595 return 0; 00596 } 00597 // Fall through to success. 00598 return 1; 00599 } // end mace_checkArm()
void mech_axe | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech axe routines.
Definition at line 464 of file mech.physical.c.
References ARM_PHYS_CHECK, axe_checkArm(), confdata::btech_phys_use_pskill, cch, DOCHECKMA, FindPilotPiloting(), get_arm_args(), getMap(), have_axe(), LARM, MECH::mapindex, mech_parseattributes(), MECH_USUALO, mudconf, P_LEFT, P_RIGHT, PA_AXE, PhysicalAttack(), QUAD_CHECK, and RARM.
00465 { 00466 MECH *mech = (MECH *) data; 00467 MAP *mech_map = getMap(mech->mapindex); 00468 char *argl[5]; 00469 char **args = argl; 00470 int argc, ltohit = 4, rtohit = 4; 00471 int using = P_LEFT | P_RIGHT; 00472 00473 // Make sure we're started, on a map, etc. 00474 cch(MECH_USUALO); 00475 // Do we have arms? 00476 ARM_PHYS_CHECK("axe"); 00477 // Make sure we're not a quad. 00478 QUAD_CHECK("axe"); 00479 00480 argc = mech_parseattributes(buffer, args, 5); 00481 00482 // If btech_phys_use_pskill is on, use the player's piloting skill. 00483 // If not, assume a skill level of 4. 00484 if(mudconf.btech_phys_use_pskill) 00485 ltohit = rtohit = FindPilotPiloting(mech) - 1; 00486 00487 // Figure out which arm to use. 00488 if(get_arm_args(&using, &argc, &args, mech, have_axe, "an axe")) { 00489 return; 00490 } 00491 00492 if(using & P_LEFT) { 00493 if(axe_checkArm(mech, LARM)) 00494 PhysicalAttack(mech, 5, ltohit, PA_AXE, argc, args, mech_map, 00495 LARM); 00496 } 00497 if(using & P_RIGHT) { 00498 if(axe_checkArm(mech, RARM)) 00499 PhysicalAttack(mech, 5, rtohit, PA_AXE, argc, args, mech_map, 00500 RARM); 00501 } 00502 // We don't have an axe. 00503 DOCHECKMA(!using, 00504 "You may lack the axe, but not the will! Try punch/club until you find one."); 00505 } // end mech_axe()
void mech_charge | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech/tank charge routines
Definition at line 798 of file mech.physical.c.
References cch, CLASS_BSUIT, CLASS_MECH, CLASS_MW, CLASS_VEH_GROUND, CountDestroyedLegs(), DOCHECK, DOCHECKMA, FaMechRange, FindTargetDBREFFromMapNumber(), getMap(), getMech(), GetMechToMechID(), InLineOfSight_NB(), MECH::mapindex, MapNoFriendlyFire, mech_notify(), mech_parseattributes(), mech_printf(), MECH_USUALO, MECHALL, MechChargeDistance, MechChargeTarget, MechChargeTimer, MechIsQuad, MECHPILOT, MechSpecials, MechTarget, MechTeam, MechType, MechX, MechY, notify, and SALVAGE_TECH.
Referenced by ChargeMech().
00799 { 00800 MECH *mech = (MECH *) data, *target; 00801 MAP *mech_map = getMap(mech->mapindex); 00802 int targetnum; 00803 char targetID[5]; 00804 char *args[5]; 00805 int argc; 00806 int wcDeadLegs = 0; 00807 00808 // Make sure we're started, on a map, etc. 00809 cch(MECH_USUALO); 00810 00811 // Mechwarriors can't chage. 00812 DOCHECK(MechType(mech) == CLASS_MW || 00813 MechType(mech) == CLASS_BSUIT, 00814 "You cannot charge without a 'mech!"); 00815 00816 // Salvage vehicles can't charge. 00817 DOCHECK(MechType(mech) != CLASS_MECH && 00818 (MechType(mech) != CLASS_VEH_GROUND || 00819 MechSpecials(mech) & SALVAGE_TECH), 00820 "You cannot charge with this vehicle!"); 00821 00822 // Figure out if we have enough legs to kick with. 00823 if(MechType(mech) == CLASS_MECH) { 00824 /* set the number of dead legs we have */ 00825 wcDeadLegs = CountDestroyedLegs(mech); 00826 00827 DOCHECK(!MechIsQuad(mech) && (wcDeadLegs > 0), 00828 "With one leg? Are you kidding?"); 00829 DOCHECK(!MechIsQuad(mech) && (wcDeadLegs > 1), 00830 "Without legs? Are you kidding?"); 00831 DOCHECK(wcDeadLegs > 1, 00832 "It'd unbalance you too much in your condition.."); 00833 DOCHECK(wcDeadLegs > 2, "Exactly _what_ are you going to kick with?"); 00834 } // end if() - Dead leg counting. 00835 00836 argc = mech_parseattributes(buffer, args, 2); 00837 00838 switch (argc) { 00839 // No arguments given with charge. Assume default target. 00840 case 0: 00841 DOCHECKMA(MechTarget(mech) == -1, 00842 "You do not have a default target set!"); 00843 00844 target = getMech(MechTarget(mech)); 00845 00846 if(!target) { 00847 mech_notify(mech, MECHALL, "Invalid default target!"); 00848 MechTarget(mech) = -1; 00849 return; 00850 } 00851 // Don't allow charging Mechwarriors. 00852 if(MechType(target) == CLASS_MW) { 00853 mech_notify(mech, MECHALL, 00854 "You can't charge THAT sack of bones and squishy bits!"); 00855 return; 00856 } 00857 00858 if(MapNoFriendlyFire(mech_map) && (MechTeam(mech) == MechTeam(target))) { 00859 mech_notify(mech, MECHALL, "You can't charge your own team!"); 00860 MechChargeTarget(mech) = -1; 00861 return; 00862 } 00863 00864 MechChargeTarget(mech) = MechTarget(mech); 00865 mech_notify(mech, MECHALL, "Charge target set to default target."); 00866 break; 00867 00868 // We've supplied an argument, either a '-' or an ID. 00869 case 1: 00870 if(args[0][0] == '-') { 00871 MechChargeTarget(mech) = -1; 00872 MechChargeTimer(mech) = 0; 00873 MechChargeDistance(mech) = 0; 00874 mech_notify(mech, MECHPILOT, "You are no longer charging."); 00875 return; 00876 } 00877 00878 targetID[0] = args[0][0]; 00879 targetID[1] = args[0][1]; 00880 targetnum = FindTargetDBREFFromMapNumber(mech, targetID); 00881 00882 DOCHECKMA(targetnum == -1, "Target is not in line of sight!"); 00883 00884 target = getMech(targetnum); 00885 DOCHECKMA(!InLineOfSight_NB(mech, target, MechX(target), 00886 MechY(target), FaMechRange(mech, target)), 00887 "Target is not in line of sight!"); 00888 00889 if(!target) { 00890 mech_notify(mech, MECHALL, "Invalid target data!"); 00891 return; 00892 } 00893 00894 if(MapNoFriendlyFire(mech_map) && (MechTeam(mech) == MechTeam(target))) { 00895 mech_notify(mech, MECHALL, "You can't charge your own team!"); 00896 MechChargeTarget(mech) = -1; 00897 return; 00898 } 00899 00900 // Don't allow charging mechwarriors. 00901 if(MechType(target) == CLASS_MW) { 00902 mech_notify(mech, MECHALL, 00903 "You can't charge THAT sack of bones and squishy bits!"); 00904 return; 00905 } 00906 00907 MechChargeTarget(mech) = targetnum; 00908 00909 mech_printf(mech, MECHALL, "%s target set to %s.", 00910 MechType(mech) == CLASS_MECH ? "Charge" : "Ram", 00911 GetMechToMechID(mech, target)); 00912 break; 00913 00914 // Something other than 0-1 arguments. 00915 default: 00916 notify(player, "Invalid number of arguments!"); 00917 } 00918 } // end mech_charge()
void mech_club | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech clubbing routines.
Definition at line 378 of file mech.physical.c.
References ARM_PHYS_CHECK, confdata::btech_phys_use_pskill, CARRYING_CLUB, cch, DOCHECKMA, FindPilotPiloting(), getMap(), HAND_OR_FOOT_ACTUATOR, HEAVY_FOREST, LARM, LIGHT_FOREST, MECH::mapindex, mech_parseattributes(), MECH_USUALO, MechRTerrain, MechSections, mudconf, OkayCritSectS, PA_CLUB, PhysicalAttack(), QUAD_CHECK, RARM, SectHasBusyWeap(), SectIsDestroyed, SHOULDER_OR_HIP, and specials.
00379 { 00380 MECH *mech = (MECH *) data; 00381 MAP *mech_map = getMap(mech->mapindex); 00382 char *args[5]; 00383 int argc; 00384 int clubLoc = -1; 00385 00386 // Make sure unit is started, on map, etc. 00387 cch(MECH_USUALO); 00388 // Make sure we're in a biped. 00389 ARM_PHYS_CHECK("club"); 00390 // Don't let quads club. 00391 QUAD_CHECK("club"); 00392 00393 if(MechSections(mech)[RARM].specials & CARRYING_CLUB) 00394 clubLoc = RARM; 00395 else if(MechSections(mech)[LARM].specials & CARRYING_CLUB) 00396 clubLoc = LARM; 00397 00398 if(clubLoc == -1) { 00399 DOCHECKMA(MechRTerrain(mech) != HEAVY_FOREST && 00400 MechRTerrain(mech) != LIGHT_FOREST, 00401 "You can not seem to find any trees around to club with."); 00402 // Since we have trees nearby, assume the club goes to right hand. 00403 clubLoc = RARM; 00404 } 00405 00406 argc = mech_parseattributes(buffer, args, 5); 00407 00408 DOCHECKMA(SectIsDestroyed(mech, LARM), 00409 "Your left arm is destroyed, you can't club."); 00410 DOCHECKMA(SectIsDestroyed(mech, RARM), 00411 "Your right arm is destroyed, you can't club."); 00412 DOCHECKMA(!OkayCritSectS(RARM, 0, SHOULDER_OR_HIP), 00413 "You can't club anyone with a destroyed or missing right shoulder."); 00414 DOCHECKMA(!OkayCritSectS(LARM, 0, SHOULDER_OR_HIP), 00415 "You can't club anyone with a destroyed or missing left shoulder."); 00416 DOCHECKMA(!OkayCritSectS(RARM, 3, HAND_OR_FOOT_ACTUATOR), 00417 "You can't club anyone with a destroyed or missing right hand."); 00418 DOCHECKMA(!OkayCritSectS(LARM, 3, HAND_OR_FOOT_ACTUATOR), 00419 "You can't club anyone with a destroyed or missing left hand."); 00420 00421 // Clubbing is usually done with the right arm but a club may be 00422 // grabbed by the left hand. Clubbing requires both arms to be cycled, 00423 // but only one is checked by PhysicalAttack(). So, we check both 00424 // here just in case. 00425 DOCHECKMA(SectHasBusyWeap(mech, LARM) || SectHasBusyWeap(mech, RARM), 00426 "You have weapons recycling on your arms."); 00427 00428 PhysicalAttack(mech, 5, 00429 (mudconf.btech_phys_use_pskill ? FindPilotPiloting(mech) - 1 00430 : 4), PA_CLUB, argc, 00431 args, mech_map, RARM); 00432 } // end mech_club()
void mech_grabclub | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Definition at line 2626 of file mech.physical.c.
References ArmorStringFromIndex(), CARRYING_CLUB, CarryingClub, cch, checkGrabClubLocation(), DOCHECKMA, DropClub, Fallen, have_axe(), have_mace(), have_sword(), HEAVY_FOREST, Jumping, LARM, LIGHT_FOREST, mech_notify(), mech_parseattributes(), mech_printf(), MECH_USUALO, MECHALL, MechIsQuad, MechLOSBroadcast(), MechMove, MechRTerrain, MechSections, MechType, OODing, PHYSICAL_RECYCLE_TIME, RARM, RemovingPods, SetRecycleLimb, specials, and UnJammingAmmo.
02627 { 02628 MECH *mech = (MECH *) data; 02629 int wcArgs = 0; 02630 int location = 0; 02631 char *args[1]; 02632 char locname[20]; 02633 02634 cch(MECH_USUALO); 02635 02636 wcArgs = mech_parseattributes(buffer, args, 1); 02637 02638 // If we grabclub -, we're attempting to drop it. 02639 if(wcArgs >= 1 && toupper(args[0][0]) == '-') { 02640 if((MechSections(mech)[LARM].specials & CARRYING_CLUB) || 02641 (MechSections(mech)[RARM].specials & CARRYING_CLUB)) { 02642 DropClub(mech); 02643 } else { 02644 mech_notify(mech, MECHALL, 02645 "You aren't currently carrying a club."); 02646 } 02647 return; 02648 } // end if() - Check to drop club. 02649 02650 DOCHECKMA(MechIsQuad(mech), "Quads can't carry a club."); 02651 DOCHECKMA(Fallen(mech), 02652 "You can't grab a club while lying flat on your face."); 02653 DOCHECKMA(Jumping(mech), "You can't grab a club while jumping!"); 02654 DOCHECKMA(OODing(mech), "Your rapid descent prevents that."); 02655 DOCHECKMA(UnJammingAmmo(mech), "You are too busy unjamming a weapon!"); 02656 DOCHECKMA(RemovingPods(mech), "You are too busy removing iNARC pods!"); 02657 02658 // If they already have a physical weapon, disallow the grabbing of a club. 02659 DOCHECKMA(have_axe(mech, LARM) || have_axe(mech, RARM), 02660 "You can not grab a club if you carry an axe."); 02661 DOCHECKMA(have_sword(mech, LARM) || have_sword(mech, RARM), 02662 "You can not grab a club if you carry a sword."); 02663 DOCHECKMA(have_mace(mech, LARM) || have_mace(mech, RARM), 02664 "You can not grab a club if you carry an mace."); 02665 02666 if(wcArgs == 0) { 02667 if(checkGrabClubLocation(mech, LARM, 0)) 02668 location = LARM; 02669 else if(checkGrabClubLocation(mech, RARM, 0)) 02670 location = RARM; 02671 else { 02672 mech_notify(mech, MECHALL, 02673 "You don't have a free arm with a working hand actuator!"); 02674 return; 02675 } 02676 } else { 02677 02678 // Figure out which arm to use. 02679 switch (toupper(args[0][0])) { 02680 case 'R': 02681 location = RARM; 02682 break; 02683 case 'L': 02684 location = LARM; 02685 break; 02686 default: 02687 mech_notify(mech, MECHALL, "Invalid option for 'grabclub'"); 02688 return; 02689 } // end switch() - Determine location. 02690 02691 // see if we have actuators and a working arm. 02692 if(!checkGrabClubLocation(mech, location, 1)) 02693 return; 02694 } 02695 02696 DOCHECKMA(CarryingClub(mech), "You're already carrying a club."); 02697 DOCHECKMA(MechRTerrain(mech) != HEAVY_FOREST && 02698 MechRTerrain(mech) != LIGHT_FOREST, 02699 "There don't appear to be any trees within grabbing distance."); 02700 02701 ArmorStringFromIndex(location, locname, MechType(mech), MechMove(mech)); 02702 02703 MechLOSBroadcast(mech, 02704 "reaches down and yanks a tree out of the ground!"); 02705 mech_printf(mech, MECHALL, 02706 "You reach down and yank a tree out of the ground with your %s.", 02707 locname); 02708 02709 // Grabbing a club sets a flag and recycles the arm used. 02710 MechSections(mech)[location].specials |= CARRYING_CLUB; 02711 SetRecycleLimb(mech, location, PHYSICAL_RECYCLE_TIME); 02712 } // end mech_grabclub()
void mech_kick | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech kick command hook.
Definition at line 730 of file mech.physical.c.
References mech_kickortrip(), and PA_KICK.
00731 { 00732 mech_kickortrip(player, data, buffer, PA_KICK); 00733 } // end mech_trip()
void mech_kickortrip | ( | dbref | player, | |
void * | data, | |||
char * | buffer, | |||
int | AttackType | |||
) |
Mech kick/trip routines.
Definition at line 738 of file mech.physical.c.
References confdata::btech_phys_use_pskill, cch, CountDestroyedLegs(), FindPilotPiloting(), GENERIC_CHECK, get_arm_args(), getMap(), have_punch(), HIP_DAMAGED, LARM, LLEG, MECH::mapindex, mech_notify(), mech_parseattributes(), mech_printf(), MECH_USUALO, MECHALL, MechCritStatus, MechIsQuad, mudconf, P_LEFT, P_RIGHT, phys_form(), PhysicalAttack(), RARM, and RLEG.
Referenced by mech_kick(), and mech_trip().
00739 { 00740 MECH *mech = (MECH *) data; 00741 MAP *mech_map = getMap(mech->mapindex); 00742 char *argl[5]; 00743 char **args = argl; 00744 int argc; 00745 int rl = RLEG, ll = LLEG; 00746 int leg; 00747 int using = P_RIGHT; 00748 00749 // Make sure we're started, on a map, etc. 00750 cch(MECH_USUALO); 00751 // If we're a quad, re-map front legs. 00752 if(MechIsQuad(mech)) { 00753 rl = RARM; 00754 ll = LARM; 00755 } 00756 // See if we have enough usable legs to kick/trip with. 00757 GENERIC_CHECK("kick", CountDestroyedLegs(mech)); 00758 00759 argc = mech_parseattributes(buffer, args, 5); 00760 00761 // Figure out which leg we're using. 00762 if(get_arm_args(&using, &argc, &args, mech, have_punch, "")) { 00763 return; 00764 } 00765 00766 switch (using) { 00767 case P_LEFT: 00768 leg = ll; 00769 break; 00770 00771 case P_RIGHT: 00772 leg = rl; 00773 break; 00774 00775 default: 00776 case P_LEFT | P_RIGHT: 00777 mech_notify(mech, MECHALL, 00778 "What, yer gonna LEVITATE? I Don't Think So."); 00779 return; 00780 } 00781 00782 if((MechCritStatus(mech) & HIP_DAMAGED)) 00783 { 00784 mech_printf(mech, MECHALL, 00785 "You can't %s with a destroyed hip.", 00786 phys_form(AttackType, 0)); 00787 return; 00788 } 00789 00790 PhysicalAttack(mech, 5, 00791 (mudconf.btech_phys_use_pskill ? FindPilotPiloting(mech) - 00792 2 : 3), AttackType, argc, args, mech_map, leg); 00793 } // end mech_kickortrip()
void mech_mace | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech mace routines.
Definition at line 604 of file mech.physical.c.
References ARM_PHYS_CHECK, confdata::btech_phys_use_pskill, cch, DOCHECKMA, FindPilotPiloting(), get_arm_args(), getMap(), have_mace(), LARM, mace_checkArm(), MECH::mapindex, mech_parseattributes(), MECH_USUALO, mudconf, P_LEFT, P_RIGHT, PA_MACE, PhysicalAttack(), QUAD_CHECK, and RARM.
00605 { 00606 MECH *mech = (MECH *) data; 00607 MAP *mech_map = getMap(mech->mapindex); 00608 char *argl[5]; 00609 char **args = argl; 00610 int argc, ltohit = 4, rtohit = 4; 00611 int using = P_LEFT | P_RIGHT; 00612 00613 // Make sure we're started, on a map, etc. 00614 cch(MECH_USUALO); 00615 // Do we have arms? 00616 ARM_PHYS_CHECK("mace"); 00617 // Make sure we're not a quad. 00618 QUAD_CHECK("mace"); 00619 00620 argc = mech_parseattributes(buffer, args, 5); 00621 00622 // If btech_phys_use_pskill is on, use the player's piloting skill. 00623 // If not, assume a skill level of 4. 00624 if(mudconf.btech_phys_use_pskill) 00625 ltohit = rtohit = FindPilotPiloting(mech) - 1; 00626 00627 // Figure out which arm to use. 00628 if(get_arm_args(&using, &argc, &args, mech, have_mace, "a mace")) { 00629 return; 00630 } 00631 00632 if(using & P_LEFT) { 00633 if(mace_checkArm(mech, LARM)) 00634 PhysicalAttack(mech, 4, ltohit, PA_MACE, argc, args, mech_map, 00635 LARM); 00636 } 00637 if(using & P_RIGHT) { 00638 if(mace_checkArm(mech, RARM)) 00639 PhysicalAttack(mech, 4, rtohit, PA_MACE, argc, args, mech_map, 00640 RARM); 00641 } 00642 // We don't have a mace. 00643 DOCHECKMA(!using, "You don't have a mace!"); 00644 } // end mech_mace()
void mech_punch | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech punch routines.
Definition at line 327 of file mech.physical.c.
References ARM_PHYS_CHECK, confdata::btech_phys_use_pskill, cch, FindPilotPiloting(), get_arm_args(), getMap(), have_punch(), LARM, MECH::mapindex, mech_parseattributes(), MECH_USUALO, mudconf, P_LEFT, P_RIGHT, PA_PUNCH, phys_common_checks(), PhysicalAttack(), punch_checkArm(), QUAD_CHECK, and RARM.
00328 { 00329 MECH *mech = (MECH *) data; 00330 MAP *mech_map = getMap(mech->mapindex); 00331 char *argl[5]; 00332 char **args = argl; 00333 int argc, ltohit = 4, rtohit = 4; 00334 int punching = P_LEFT | P_RIGHT; 00335 00336 // Carry out the common checks (started, on map, etc.) 00337 cch(MECH_USUALO); 00338 // Make sure we have arms to punch with. 00339 ARM_PHYS_CHECK("punch"); 00340 // Disallow quads from punching. 00341 QUAD_CHECK("punch"); 00342 00343 argc = mech_parseattributes(buffer, args, 5); 00344 00345 // If the directive is true, use the pilot's piloting skill. If not, we 00346 // use a constant BTH of 4. 00347 if(mudconf.btech_phys_use_pskill) 00348 ltohit = rtohit = FindPilotPiloting(mech) - 1; 00349 00350 // Manipulate punching var to contain only the arms we're punching with. 00351 if(get_arm_args(&punching, &argc, &args, mech, have_punch, "")) { 00352 return; 00353 } 00354 // Carry out our standard physical checks. This happens in PhysicalAttack 00355 // but the player gets double-spammed since PhysicalAttack can be called 00356 // twice in here. So, we add the check before. 00357 if(!phys_common_checks(mech)) 00358 return; 00359 00360 // For each arm we're using, check to make sure it's good to punch with 00361 // and carry out the roll if it is. 00362 if(punching & P_LEFT) { 00363 if(punch_checkArm(mech, LARM)) 00364 PhysicalAttack(mech, 10, ltohit, PA_PUNCH, argc, args, 00365 mech_map, LARM); 00366 } 00367 00368 if(punching & P_RIGHT) { 00369 if(punch_checkArm(mech, RARM)) 00370 PhysicalAttack(mech, 10, rtohit, PA_PUNCH, argc, args, 00371 mech_map, RARM); 00372 } 00373 } // end mech_punch()
void mech_saw | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech dual saw routines.
Definition at line 532 of file mech.physical.c.
References ARM_PHYS_CHECK, confdata::btech_phys_use_pskill, cch, DOCHECKMA, FindPilotPiloting(), get_arm_args(), getMap(), have_saw(), LARM, MECH::mapindex, mech_parseattributes(), MECH_USUALO, mudconf, P_LEFT, P_RIGHT, PA_SAW, PhysicalAttack(), QUAD_CHECK, RARM, and saw_checkArm().
00533 { 00534 MECH *mech = (MECH *) data; 00535 MAP *mech_map = getMap(mech->mapindex); 00536 char *argl[5]; 00537 char **args = argl; 00538 int argc, ltohit = 4, rtohit = 4; 00539 int using = P_LEFT | P_RIGHT; 00540 00541 // Make sure we're started, on a map, etc. 00542 cch(MECH_USUALO); 00543 // Do we have arms? 00544 ARM_PHYS_CHECK("saw"); 00545 // Make sure we're not a quad. 00546 QUAD_CHECK("saw"); 00547 00548 argc = mech_parseattributes(buffer, args, 5); 00549 00550 // If btech_phys_use_pskill is on, use the player's piloting skill. 00551 // If not, assume a skill level of 4. 00552 if(mudconf.btech_phys_use_pskill) 00553 ltohit = rtohit = FindPilotPiloting(mech) - 1; 00554 00555 // Figure out which arm to use. 00556 if(get_arm_args(&using, &argc, &args, mech, have_saw, "a saw")) { 00557 return; 00558 } 00559 00560 if(using & P_LEFT) { 00561 if(saw_checkArm(mech, LARM)) 00562 PhysicalAttack(mech, 7, ltohit, PA_SAW, argc, args, mech_map, 00563 LARM); 00564 } 00565 if(using & P_RIGHT) { 00566 if(saw_checkArm(mech, RARM)) 00567 PhysicalAttack(mech, 7, rtohit, PA_SAW, argc, args, mech_map, 00568 RARM); 00569 } 00570 // We don't have a saw. 00571 DOCHECKMA(!using, "You don't have a dual saw!"); 00572 } // end mech_saw()
void mech_sword | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech sword routines.
Definition at line 676 of file mech.physical.c.
References ARM_PHYS_CHECK, confdata::btech_phys_use_pskill, cch, DOCHECKMA, FindPilotPiloting(), get_arm_args(), getMap(), have_sword(), LARM, MECH::mapindex, mech_parseattributes(), MECH_USUALO, mudconf, P_LEFT, P_RIGHT, PA_SWORD, PhysicalAttack(), QUAD_CHECK, RARM, and sword_checkArm().
00677 { 00678 MECH *mech = (MECH *) data; 00679 MAP *mech_map = getMap(mech->mapindex); 00680 char *argl[5]; 00681 char **args = argl; 00682 int argc, ltohit = 3, rtohit = 3; 00683 int using = P_LEFT | P_RIGHT; 00684 00685 // Make sure we're started, on a map, etc. 00686 cch(MECH_USUALO); 00687 // Do we have arms to chop with? 00688 ARM_PHYS_CHECK("chop"); 00689 // Quads can't do it. 00690 QUAD_CHECK("chop"); 00691 00692 argc = mech_parseattributes(buffer, args, 5); 00693 00694 // If btech_phys_use_pskill is defined, use the pilot's piloting skill, 00695 // otherwise use a constant skill 3. 00696 if(mudconf.btech_phys_use_pskill) 00697 ltohit = rtohit = FindPilotPiloting(mech) - 2; 00698 00699 // Which arm(s) have sword crits? 00700 if(get_arm_args(&using, &argc, &args, mech, have_sword, "a sword")) { 00701 return; 00702 } 00703 00704 if(using & P_LEFT) { 00705 if(sword_checkArm(mech, LARM)) 00706 PhysicalAttack(mech, 10, ltohit, PA_SWORD, argc, args, mech_map, 00707 LARM); 00708 } 00709 00710 if(using & P_RIGHT) { 00711 if(sword_checkArm(mech, RARM)) 00712 PhysicalAttack(mech, 10, rtohit, PA_SWORD, argc, args, mech_map, 00713 RARM); 00714 } 00715 // Ninja what? 00716 DOCHECKMA(!using, "You have no sword to chop people with!"); 00717 } // end mech_sword()
void mech_trip | ( | dbref | player, | |
void * | data, | |||
char * | buffer | |||
) |
Mech tripping command hook.
Definition at line 722 of file mech.physical.c.
References mech_kickortrip(), and PA_TRIP.
00723 { 00724 mech_kickortrip(player, data, buffer, PA_TRIP); 00725 } // end mech_trip()
int phys_common_checks | ( | MECH * | mech | ) |
Definition at line 207 of file mech.physical.c.
References all_limbs_recycled(), Dodging, Jumping, mech_notify(), MECHALL, MoveModeLock, and Standing.
Referenced by mech_punch(), and PhysicalAttack().
00208 { 00209 if(Jumping(mech)) { 00210 mech_notify(mech, MECHALL, 00211 "You can't perform physical attacks while in the air!"); 00212 return 0; 00213 } 00214 00215 if(Standing(mech)) { 00216 mech_notify(mech, MECHALL, "You are still trying to stand up!"); 00217 return 0; 00218 } 00219 #ifdef BT_MOVEMENT_MODES 00220 if(Dodging(mech) || MoveModeLock(mech)) { 00221 mech_notify(mech, MECHALL, 00222 "You cannot use physicals while using a special movement mode."); 00223 return 0; 00224 } 00225 #endif 00226 00227 if(!all_limbs_recycled(mech)) { 00228 return 0; 00229 } 00230 // Fall through to success. 00231 return 1; 00232 } // end phys_common_checks()
Definition at line 158 of file mech.physical.c.
References phys_form(), phys_message, and tprintf().
Referenced by PhysicalAttack().
00159 { 00160 phys_message(tprintf("attempts to %s %%s!", phys_form(at, 0))); 00161 }
char* phys_form | ( | int | AttackType, | |
int | add_s | |||
) |
Returns the correct verb for each physical attack.
Definition at line 77 of file mech.physical.c.
References PA_AXE, PA_CLUB, PA_KICK, PA_MACE, PA_PUNCH, PA_SAW, PA_SWORD, and PA_TRIP.
Referenced by mech_kickortrip(), phys_fail(), phys_succeed(), and PhysicalAttack().
00078 { 00079 // Holds our attack verb. 00080 char *verb; 00081 00082 // See if we need the verb with an s on the end. 00083 if(add_s) { 00084 // With the S. 00085 switch (AttackType) { 00086 case PA_PUNCH: 00087 verb = "punchs"; 00088 break; 00089 case PA_CLUB: 00090 verb = "clubs"; 00091 break; 00092 case PA_MACE: 00093 verb = "maces"; 00094 break; 00095 case PA_SWORD: 00096 verb = "chops"; 00097 break; 00098 case PA_AXE: 00099 verb = "axes"; 00100 break; 00101 case PA_KICK: 00102 verb = "kicks"; 00103 break; 00104 case PA_TRIP: 00105 verb = "trips"; 00106 break; 00107 case PA_SAW: 00108 verb = "saws"; 00109 break; 00110 // Ohboy, we're using some funky, unknown physical. 00111 default: 00112 verb = "??bugs??"; 00113 } // end switch() 00114 } else { 00115 // Without the S. 00116 switch (AttackType) { 00117 case PA_PUNCH: 00118 verb = "punch"; 00119 break; 00120 case PA_CLUB: 00121 verb = "club"; 00122 break; 00123 case PA_MACE: 00124 verb = "maces"; 00125 break; 00126 case PA_SWORD: 00127 verb = "chop"; 00128 break; 00129 case PA_AXE: 00130 verb = "axe"; 00131 break; 00132 case PA_KICK: 00133 verb = "kick"; 00134 break; 00135 case PA_TRIP: 00136 verb = "trip"; 00137 break; 00138 case PA_SAW: 00139 verb = "saw"; 00140 break; 00141 // Ohboy, we're using some funky, unknown physical. 00142 default: 00143 verb = "??bugs??"; 00144 } // end switch() 00145 } // end if/else() 00146 00147 return verb; 00148 } // end phys_form
Definition at line 153 of file mech.physical.c.
References phys_form(), phys_message, and tprintf().
Referenced by PhysicalAttack().
00154 { 00155 phys_message(tprintf("%s %%s!", phys_form(at, 1))); 00156 }
void PhysicalAttack | ( | MECH * | mech, | |
int | damageweight, | |||
int | baseToHit, | |||
int | AttackType, | |||
int | argc, | |||
char ** | args, | |||
MAP * | mech_map, | |||
int | sect | |||
) |
Definition at line 927 of file mech.physical.c.
References ArmorStringFromIndex(), AttackMovementMods(), AXED, confdata::btech_glancing_blows, CARRYING_CLUB, CLASS_BSUIT, CLASS_MECH, CLASS_MW, CLASS_VEH_GROUND, DOCHECKMA, Dodging, Fallen, FaMechRange, FindTargetDBREFFromMapNumber(), FORWARDARC, getMech(), GetMechToMechID(), GetPartType, HAND_OR_FOOT_ACTUATOR, HasBoolAdvantage(), HEAVY_FOREST, I2Special, InLineOfSight_NB(), InWeaponArc(), IsDS, Jumping, LARM, LIGHT_FOREST, LOWER_ACTUATOR, LSIDEARC, MadePilotSkillRoll(), MapNoFriendlyFire, mech_notify(), mech_printf(), MECH_STUNNED, MECHALL, MechCritStatus, MechFalls(), MechFX, MechFY, MechLOSBroadcast(), MechMove, MechNoFriendlyFire, MechPilot, MechPKiller, MechRTerrain, MechSections, MECHSTARTED, MechStatus, MechSwarmTarget, MechTarget, MechTeam, MechTerrain, MechType, MechX, MechY, MechZ, MIN, MOVE_FLY, MOVE_VTOL, mudconf, MECH::mynum, PA_AXE, PA_CLUB, PA_KICK, PA_MACE, PA_PUNCH, PA_SAW, PA_SWORD, PA_TRIP, PartIsNonfunctional, phys_common_checks(), phys_fail(), phys_form(), phys_succeed(), PHYSICAL_RECYCLE_TIME, PhysicalDamage(), PhysicalTrip(), RARM, Roll(), RSIDEARC, SectHasBusyWeap(), SendAttacks, SetRecycleLimb, SMOKE, specials, Standing, TargetMovementMods(), TORSO_LEFT, TORSO_RIGHT, tprintf(), and UPPER_ACTUATOR.
Referenced by mech_axe(), mech_club(), mech_kickortrip(), mech_mace(), mech_punch(), mech_saw(), and mech_sword().
00930 { 00931 MECH *target; 00932 float range; 00933 float maxRange = 1; 00934 char targetID[2]; 00935 int targetnum, roll, swarmingUs; 00936 char location[20]; 00937 int ts = 0, iwa; 00938 int RbaseToHit, glance = 0; 00939 00940 00941 /* 00942 * Common Checks 00943 */ 00944 00945 // Since we can punch with two arms, often back to back, we want to run 00946 // these generic checks in mech_punch() -BEFORE- PhysicalAttack() is called 00947 // twice (if we have two working arms). 00948 if(AttackType != PA_PUNCH) 00949 if(!phys_common_checks(mech)) 00950 return; 00951 00952 /* BTH Adjustments for crits to limbs - seperate one for 00953 * club because it checks for both limbs */ 00954 if ((AttackType == PA_PUNCH) || (AttackType == PA_KICK) || 00955 (AttackType == PA_AXE) || (AttackType == PA_SWORD) || 00956 (AttackType == PA_MACE) || (AttackType == PA_SAW)) { 00957 00958 if (PartIsNonfunctional(mech, sect, 1) || 00959 GetPartType(mech, sect, 1) != I2Special(UPPER_ACTUATOR)) { 00960 baseToHit += 2; 00961 } 00962 00963 if (PartIsNonfunctional(mech, sect, 2) || 00964 GetPartType(mech, sect, 2) != I2Special(LOWER_ACTUATOR)) { 00965 baseToHit += 2; 00966 } 00967 00968 /* Hand/Foot crits only affect punch/kick since with the other attacks 00969 * are not allowed if they're broken */ 00970 if ((AttackType == PA_PUNCH) || (AttackType == PA_KICK)) { 00971 if (PartIsNonfunctional(mech, sect, 3) || 00972 GetPartType(mech, sect, 3) != I2Special(HAND_OR_FOOT_ACTUATOR)) { 00973 baseToHit += 1; 00974 } 00975 } 00976 00977 } else if (AttackType == PA_CLUB) { 00978 00979 /* Only check lower/upper acts since without shoulder or hand you can't 00980 * club */ 00981 if (PartIsNonfunctional(mech, RARM, 1) || 00982 GetPartType(mech, sect, 1) != I2Special(UPPER_ACTUATOR)) { 00983 baseToHit += 2; 00984 } 00985 if (PartIsNonfunctional(mech, RARM, 2) || 00986 GetPartType(mech, sect, 2) != I2Special(LOWER_ACTUATOR)) { 00987 baseToHit += 2; 00988 } 00989 if (PartIsNonfunctional(mech, LARM, 1) || 00990 GetPartType(mech, sect, 1) != I2Special(UPPER_ACTUATOR)) { 00991 baseToHit += 2; 00992 } 00993 if (PartIsNonfunctional(mech, LARM, 2) || 00994 GetPartType(mech, sect, 2) != I2Special(LOWER_ACTUATOR)) { 00995 baseToHit += 2; 00996 } 00997 } 00998 00999 // All weapons must be cycled in the target limb. 01000 if(SectHasBusyWeap(mech, sect)) { 01001 ArmorStringFromIndex(sect, location, MechType(mech), MechMove(mech)); 01002 mech_printf(mech, MECHALL, 01003 "You have weapons recycling on your %s.", location); 01004 return; 01005 } 01006 // Figure out what to do with the arguments provided with the physical 01007 // command. 01008 switch (argc) { 01009 case -1: 01010 case 0: 01011 // No argument 01012 DOCHECKMA(MechTarget(mech) == -1, "You do not have a target set!"); 01013 01014 // Populate target variable with current lock. 01015 target = getMech(MechTarget(mech)); 01016 DOCHECKMA(!target, "Invalid default target!"); 01017 01018 break; 01019 default: 01020 // In this case, default means user has specified an argument 01021 // with the physical attack. 01022 01023 // Populate target variable from user input. 01024 targetID[0] = args[0][0]; 01025 targetID[1] = args[0][1]; 01026 targetnum = FindTargetDBREFFromMapNumber(mech, targetID); 01027 target = getMech(targetnum); 01028 01029 DOCHECKMA(targetnum == -1, "Target is not in line of sight!"); 01030 DOCHECKMA(!target, "Invalid default target!"); 01031 } // end switch() - argc checking 01032 01033 // Is the target swarming us? 01034 swarmingUs = (MechSwarmTarget(target) == mech->mynum ? 1 : 0); 01035 01036 /* 01037 * Common checks. 01038 */ 01039 01040 // If we're attacking something while fallen that isn't swarming us, 01041 // no-go it. Kicks/trips are automatically stopped. 01042 if(Fallen(mech) && (AttackType == PA_KICK || AttackType == PA_TRIP)) { 01043 mech_printf(mech, MECHALL, "You can't %s from a prone position.", 01044 phys_form(AttackType, 0)); 01045 01046 return; 01047 // If we are fallen AND 01048 // The target is not a BSuit AND We're not punching 01049 } else if(Fallen(mech) && 01050 (MechType(target) != CLASS_VEH_GROUND && 01051 MechType(target) != CLASS_BSUIT)) { 01052 mech_printf(mech, MECHALL, 01053 "You can't %s from a prone position.", 01054 phys_form(AttackType, 0)); 01055 01056 return; 01057 } else if(Fallen(mech) && MechType(target) == CLASS_BSUIT && !swarmingUs) { 01058 mech_notify(mech, MECHALL, 01059 "You may only physical suits that are swarming you while prone."); 01060 return; 01061 } else if(Fallen(mech) && MechType(target) == CLASS_VEH_GROUND && 01062 AttackType != PA_PUNCH) { 01063 mech_notify(mech, MECHALL, 01064 "You may only punch vehicles while prone."); 01065 return; 01066 } // end if() - Physical while fallen. 01067 01068 range = FaMechRange(mech, target); 01069 01070 DOCHECKMA(!InLineOfSight_NB(mech, target, MechX(target), 01071 MechY(target), range), 01072 "Target is not in line of sight!"); 01073 01074 // BSuits have to be <= 0.5 hexes to attack units. 01075 if((MechType(target) == CLASS_BSUIT) || (MechType(target) == CLASS_MW)) 01076 maxRange = 0.5; 01077 01078 DOCHECKMA(range >= maxRange, "Target out of range!"); 01079 01080 DOCHECKMA(Jumping(target), 01081 "You can't perform physical attacks on airborne mechs!"); 01082 01083 DOCHECKMA(MechTeam(target) == MechTeam(mech) && 01084 MechNoFriendlyFire(mech), 01085 "You can't attack a teammate with FFSafeties on!"); 01086 01087 DOCHECKMA(MechTeam(target) == MechTeam(mech) && 01088 MapNoFriendlyFire(mech_map), 01089 "Friendly Fire? I don't think so..."); 01090 01091 DOCHECKMA(MechType(target) == CLASS_MW && !MechPKiller(mech), 01092 "That's a living, breathing person! Switch off the safety first, " 01093 "if you really want to assassinate the target."); 01094 01095 DOCHECKMA(MechCritStatus(mech) & MECH_STUNNED, 01096 "You are still recovering from your stunning experience!"); 01097 /* 01098 * Attack-Specific checks. 01099 */ 01100 DOCHECKMA(AttackType == PA_PUNCH && 01101 (MechType(target) == CLASS_VEH_GROUND) && 01102 !Fallen(mech), 01103 "You can't punch vehicles unless you are prone!"); 01104 01105 // As per BMR, can only trip mechs. 01106 DOCHECKMA(AttackType == PA_TRIP && MechType(target) != CLASS_MECH, 01107 "You can only trip mechs!"); 01108 01109 // Can't trip mechs that are fallen or in the process of standing. 01110 DOCHECKMA(AttackType == PA_TRIP && (Fallen(target) || Standing(target)), 01111 "Your target is already down!"); 01112 01113 // We're attacking a ground/naval unit. 01114 if(MechMove(target) != MOVE_VTOL && MechMove(target) != MOVE_FLY) { 01115 01116 if((AttackType != PA_KICK && AttackType != PA_TRIP) && 01117 (MechZ(mech) >= MechZ(target))) { 01118 int isTooLow = 0; // Track whether we're too low or not. 01119 01120 // If it's a fallen mech, too low. 01121 if(MechType(target) == CLASS_MECH && Fallen(target)) 01122 isTooLow = 1; 01123 01124 /* Target is to low to punch */ 01125 if ((MechType(target) == CLASS_MECH) && 01126 (MechZ(mech) > MechZ(target)) && 01127 (AttackType == PA_PUNCH)) { 01128 isTooLow = 1; 01129 } 01130 01131 // If it's not a mech, bsuit, or DS, too low. 01132 if(MechType(target) != CLASS_MECH && 01133 MechType(target) != CLASS_BSUIT && !IsDS(target)) 01134 isTooLow = 1; 01135 01136 // If it's a ground vehicle and we're fallen, then we can 01137 // punch as per BMR. 01138 if(AttackType == PA_PUNCH && 01139 MechType(target) == CLASS_VEH_GROUND && Fallen(mech)) 01140 isTooLow = 0; 01141 01142 // If it's a suit that's not on us, we can't physical it. 01143 if(MechType(target) == CLASS_BSUIT && MechSwarmTarget(target) > 0) { 01144 mech_printf(mech, MECHALL, 01145 "You can't directly physical suits that are swarmed or mounted on another mech!"); 01146 return; 01147 } // end if() - Disallow physicals on swarmed/mounted suits. 01148 01149 if(isTooLow == 1) { 01150 mech_printf(mech, MECHALL, 01151 "The target is too low in elevation for you to %s.", 01152 phys_form(AttackType, 0)); 01153 return; 01154 } // end if() - Check isTooLow 01155 } // end if() - Target is too low checks. 01156 01157 DOCHECKMA((AttackType == PA_KICK || AttackType == PA_TRIP) && 01158 MechZ(mech) < MechZ(target), 01159 "The target is too high in elevation for you to kick at."); 01160 01161 DOCHECKMA(MechZ(mech) - MechZ(target) > 1 || 01162 MechZ(target) - MechZ(mech) > 1, 01163 "You can't attack, the elevation difference is too large."); 01164 01165 DOCHECKMA((AttackType == PA_KICK || AttackType == PA_TRIP) && 01166 (MechZ(target) < MechZ(mech) && 01167 (((MechType(target) == CLASS_MECH) && Fallen(target)) || 01168 (MechType(target) == CLASS_VEH_GROUND) || 01169 (MechType(target) == CLASS_BSUIT) || 01170 (MechType(target) == CLASS_MW))), 01171 "The target is too low in elevation for you to kick.") 01172 01173 } else { // We're attacking a VTOL/Aero. 01174 01175 if((AttackType != PA_KICK) && MechZ(target) - MechZ(mech) > 3) { 01176 mech_printf(mech, MECHALL, 01177 "The target is too far away for you to %s.", 01178 phys_form(AttackType, 0)); 01179 } 01180 01181 if((AttackType == PA_KICK || AttackType == PA_TRIP) && 01182 MechZ(mech) != MechZ(target)) { 01183 mech_printf(mech, MECHALL, 01184 "The target is too far away for you to %s.", 01185 phys_form(AttackType, 0)); 01186 return; 01187 } 01188 01189 DOCHECKMA(!(MechZ(target) - MechZ(mech) > -1 && 01190 MechZ(target) - MechZ(mech) < 4), 01191 "You can't attack, the elevation difference is too large."); 01192 } // end if/else() - Ground/VTOL + Physical Z comparisons 01193 01194 /* Check weapon arc! */ 01195 /* Theoretically, physical attacks occur only to 'real' forward 01196 arc, not rottorsoed one, but we let it pass this time */ 01197 /* This is wrong according to BMR 01198 * 01199 * Which states that the Torso twist is taken into account 01200 * as well as punching/axing/swords can attack in their 01201 * respective arcs - Dany 01202 * 01203 * So I went and changed it according to FASA rules */ 01204 if(AttackType == PA_KICK || AttackType == PA_TRIP) { 01205 01206 ts = MechStatus(mech) & (TORSO_LEFT | TORSO_RIGHT); 01207 MechStatus(mech) &= ~ts; 01208 iwa = InWeaponArc(mech, MechFX(target), MechFY(target)); 01209 MechStatus(mech) |= ts; 01210 01211 DOCHECKMA(!(iwa & FORWARDARC), 01212 "Target is not in your 'real' forward arc!"); 01213 01214 } else { // We're punching, clubbing, or other sharp things. 01215 01216 iwa = InWeaponArc(mech, MechFX(target), MechFY(target)); 01217 01218 if(AttackType == PA_CLUB) { 01219 // Clubs are a frontal attack. Go off of the forward arc, don't 01220 // take arms into account. 01221 DOCHECKMA(!(iwa & FORWARDARC) && swarmingUs != 1, 01222 "Target is not in your forward arc!"); 01223 } else { 01224 // For other attacks, check on a per-arm basis. 01225 if(sect == RARM) { 01226 // We're attacking with right arm. Forward or right will do. 01227 DOCHECKMA(! 01228 ((iwa & FORWARDARC) || (iwa & RSIDEARC) 01229 || swarmingUs), 01230 "Target is not in your forward or right side arc!"); 01231 } else { 01232 // We're attacking with left arm. Forward or left will do. 01233 DOCHECKMA(!((iwa & FORWARDARC) || (iwa & LSIDEARC)) 01234 || swarmingUs, 01235 "Target is not in your forward or left side arc!"); 01236 01237 } // end 01238 01239 } // end if/else() - club/punch arc check 01240 01241 } // end if/else() - kick/punch arc check 01242 01247 // If we have melee_specialist advantage, knock -1 off the BTH. 01248 baseToHit += HasBoolAdvantage(MechPilot(mech), "melee_specialist") ? 01249 MIN(0, AttackMovementMods(mech) - 1) : AttackMovementMods(mech); 01250 01251 baseToHit += TargetMovementMods(mech, target, 0.0); 01252 01253 // BSuits get +1 BTH 01254 baseToHit += MechType(target) == CLASS_BSUIT ? 1 : 0; 01255 01256 // Kicking a BSuit is +3 BTH 01257 baseToHit += ((MechType(target) == CLASS_BSUIT) && 01258 (AttackType == PA_KICK)) ? 3 : 0; 01259 01260 #ifdef MOVEMENT_MODES 01261 // A dodging unit is +2, requires maneuvering_ace. 01262 if(Dodging(target)) 01263 baseToHit += 2; 01264 #endif 01265 01266 // Saws get a +1 BTH. 01267 if(AttackType == PA_SAW) 01268 baseToHit += 1; 01269 01270 // Maces get a +2 BTH. 01271 if(AttackType == PA_MACE) 01272 baseToHit += 2; 01273 01274 // If we're axing or chopping a bsuit, add +3 to BTH, else (punching) +5. 01275 if(AttackType != PA_PUNCH && 01276 MechType(target) == CLASS_BSUIT && MechSwarmTarget(target) > 0) 01277 baseToHit += (AttackType != PA_PUNCH) ? 3 : 5; 01278 01279 // As per BMR, can only physical bsuits with punches, axes, or swords. 01280 // Added saw since it's the same idea. 01281 DOCHECKMA(AttackType == PA_KICK && 01282 MechType(target) == CLASS_BSUIT && 01283 MechSwarmTarget(target) > 0, 01284 "You can't hit a swarmed suit with that, try a hand-held weapon!"); 01285 01286 // Terrain mods - Courtesy of RST 01287 // Heavy & Light are from Total Warfare and 01288 // Smoke from MaxTech old BMR 01289 // Check Smoke first since it can sit on top of other terrain 01290 // Might want to check for Fire also at some point? 01291 if (MechTerrain(target) == SMOKE) { 01292 baseToHit += 2; 01293 } else if (MechRTerrain(target) == HEAVY_FOREST) { 01294 baseToHit += 2; 01295 } else if (MechRTerrain(target) == LIGHT_FOREST) { 01296 baseToHit += 1; 01297 } 01298 01299 roll = Roll(); 01300 01301 // Carry out the attack. 01302 mech_printf(mech, MECHALL, 01303 "You try to %s %s. BTH: %d,\tRoll: %d", 01304 phys_form(AttackType, 0), 01305 GetMechToMechID(mech, target), baseToHit, roll); 01306 01307 mech_printf(target, MECHSTARTED, "%s tries to %s you!", 01308 GetMechToMechID(target, mech), phys_form(AttackType, 0)); 01309 01310 // We send to MechAttacks channel 01311 SendAttacks(tprintf("#%i attacks #%i (%s) (%i/%i)", 01312 mech->mynum, 01313 target->mynum, 01314 phys_form(AttackType, 0), baseToHit, roll)); 01315 01316 // Set the appropriate section(s) to recycle. 01317 SetRecycleLimb(mech, sect, PHYSICAL_RECYCLE_TIME); 01318 01319 /* 01320 * Attack-specific recycles and flags. 01321 */ 01322 if(AttackType == PA_AXE || AttackType == PA_SWORD || AttackType == PA_SAW 01323 || AttackType == PA_MACE) 01324 MechSections(mech)[sect].config |= AXED; 01325 01326 if(AttackType == PA_PUNCH) 01327 MechSections(mech)[sect].config &= ~AXED; 01328 01329 // Clubbing recycles both arms. 01330 if(AttackType == PA_CLUB) 01331 SetRecycleLimb(mech, LARM, PHYSICAL_RECYCLE_TIME); 01332 01333 RbaseToHit = baseToHit; 01334 if(mudconf.btech_glancing_blows == 2) 01335 RbaseToHit = baseToHit - 1; 01336 // We've successfully hit the target. 01337 if(roll >= RbaseToHit) { 01338 phys_succeed(mech, target, AttackType); 01339 if (mudconf.btech_glancing_blows && (roll == RbaseToHit)) { 01340 MechLOSBroadcast(target,"is nicked by a glancing blow!"); 01341 mech_notify(target, MECHALL, "You are nicked by a glancing blow!"); 01342 glance = 1 ; 01343 } 01344 if(AttackType == PA_CLUB) { 01345 int clubLoc = -1; 01346 01347 if(MechSections(mech)[RARM].specials & CARRYING_CLUB) 01348 clubLoc = RARM; 01349 else if(MechSections(mech)[LARM].specials & CARRYING_CLUB) 01350 clubLoc = LARM; 01351 01352 if(clubLoc > -1) { 01353 mech_notify(mech, MECHALL, "Your club shatters on contact."); 01354 MechLOSBroadcast(mech, 01355 "'s club shatters with a loud *CRACK*!"); 01356 01357 MechSections(mech)[clubLoc].specials &= ~CARRYING_CLUB; 01358 } 01359 } // End if() - Club shattering 01360 01361 // Do the deed - Damage the victim. If we're tripping, we don't do 01362 // damage but try to make a skill roll. 01363 if(AttackType != PA_TRIP) 01364 PhysicalDamage(mech, target, damageweight, AttackType, sect, glance); 01365 else 01366 PhysicalTrip(mech, target); 01367 01368 } else { // We have failed! 01369 phys_fail(mech, target, AttackType); 01370 01371 if(MechType(target) == CLASS_BSUIT && 01372 MechSwarmTarget(target) == mech->mynum) { 01373 01374 if(!MadePilotSkillRoll(mech, 4)) { 01375 mech_notify(mech, MECHALL, 01376 "Uh oh. You miss the little buggers, but hit yourself!"); 01377 MechLOSBroadcast(mech, "misses, and hits itself!"); 01378 01379 PhysicalDamage(mech, mech, damageweight, AttackType, sect, glance); 01380 } // If we really screw up against suits swarmed on ourselves, 01381 // nail us for damage. 01382 } // end if() - Suit + Swarmed + Physical + Self Damage checks 01383 01384 /* Removed fall check for clubs -- Power_Shaper 09/25/06 */ 01385 if(AttackType == PA_KICK || 01386 AttackType == PA_MACE) { 01387 int failRoll = (AttackType == PA_KICK ? 0 : 2); 01388 01389 mech_notify(mech, MECHALL, 01390 "You miss and try to remain standing!"); 01391 01392 // We fail the piloting skill roll and flop on our face. 01393 if(!MadePilotSkillRoll(mech, failRoll)) { 01394 mech_notify(mech, MECHALL, 01395 "You lose your balance and fall down!"); 01396 MechFalls(mech, 1, 1); 01397 } // end if() - Miss/fall. 01398 } // end if() - Miss kick/club and risk falling. 01399 } // end if() - Physical failure handling. 01400 } //end PhysicalAttack()
void PhysicalDamage | ( | MECH * | mech, | |
MECH * | target, | |||
int | weightdmg, | |||
int | AttackType, | |||
int | sect, | |||
int | glance | |||
) |
Definition at line 1437 of file mech.physical.c.
References BACK, CLASS_BSUIT, CLASS_MECH, Fallen, FindAreaHitGroup(), FindKickLocation(), FindPunchLocation(), FindTargetHitLoc(), HasBoolAdvantage(), LOWER_ACTUATOR, MadePilotSkillRoll(), mech_notify(), MechElevation, MechFalls(), MechHeat, MechLOSBroadcast(), MechPilot, MechSpecials, MECHSTARTED, MechSwarmTarget, MechTons, MechType, MyDamageMech, OkayCritSectS, PA_AXE, PA_CLUB, PA_KICK, PA_MACE, PA_PUNCH, PA_SAW, PA_SWORD, StopSwarming(), TRIPLE_MYOMER_TECH, and UPPER_ACTUATOR.
Referenced by PhysicalAttack().
01438 { 01439 01440 int hitloc = 0, damage, hitgroup = 0, isrear, iscritical, i; 01441 01442 isrear = 0; 01443 iscritical = 0; 01444 01445 /* Two types of physical attack weapons - Those affected by TSM 01446 * and those not - Right now just saw but can add more to the list via 01447 * || (AttackType == PA_BLAH) */ 01448 if (AttackType == PA_SAW) { 01449 01450 /* Saws do a constant 7 damage due to their mechanical nature. */ 01451 damage = 7; 01452 01453 } else { 01454 01455 /* Sword attack uses an odd weapon damage amount */ 01456 if (AttackType == PA_SWORD) { 01457 damage = (MechTons(mech) + 5) / weightdmg + 1; 01458 } else { 01459 damage = (MechTons(mech) + weightdmg / 2) / weightdmg; 01460 } 01461 01462 /* Calc in affect by TSM */ 01463 if ((MechHeat(mech) >= 9.) && (MechSpecials(mech) & TRIPLE_MYOMER_TECH)) { 01464 damage = damage * 2; 01465 } 01466 01467 } 01468 01469 /* If we have melee_specialist, add a point of damage. */ 01470 if (HasBoolAdvantage(MechPilot(mech), "melee_specialist")) { 01471 damage++; 01472 } 01473 01474 switch (AttackType) { 01475 case PA_PUNCH: 01476 01477 if (!OkayCritSectS(sect, 2, LOWER_ACTUATOR)) { 01478 damage = damage / 2; 01479 } 01480 01481 if (!OkayCritSectS(sect, 1, UPPER_ACTUATOR)) { 01482 damage = damage / 2; 01483 } 01484 01485 hitgroup = FindAreaHitGroup(mech, target); 01486 if (hitgroup == BACK) { 01487 isrear = 1; 01488 } 01489 01490 if (MechType(mech) == CLASS_MECH) { 01491 01492 if (Fallen(mech)) { 01493 01494 /* Total Warfare page 151 - Prone mechs can only make 01495 * two types of physical attacks - Punching (with one arm) 01496 * vehicles in same hex and thrashing - But for now including 01497 * this. - Dany 01/2007 */ 01498 if ((MechType(target) != CLASS_MECH) || (Fallen(target) && 01499 (MechElevation(mech) == MechElevation (target)))) { 01500 hitloc = FindTargetHitLoc(mech, target, &isrear, &iscritical); 01501 } else if (!Fallen(target) && 01502 (MechElevation(mech) > MechElevation(target))) { 01503 hitloc = FindPunchLocation(target, hitgroup); 01504 } else if (MechElevation(mech) == MechElevation(target)) { 01505 hitloc = FindKickLocation(target, hitgroup); 01506 } 01507 01508 } else if (MechElevation(mech) < MechElevation(target)) { 01509 01510 if (Fallen(target) || MechType(target) != CLASS_MECH) { 01511 hitloc = FindTargetHitLoc(mech, target, &isrear, &iscritical); 01512 } else { 01513 hitloc = FindKickLocation(target, hitgroup); 01514 } 01515 01516 } else { 01517 hitloc = FindPunchLocation(target, hitgroup); 01518 } 01519 01520 } else { 01521 hitloc = FindTargetHitLoc(mech, target, &isrear, &iscritical); 01522 } 01523 01524 break; 01525 01526 case PA_SWORD: 01527 case PA_AXE: 01528 case PA_MACE: 01529 case PA_CLUB: 01530 01531 hitgroup = FindAreaHitGroup(mech, target); 01532 if (hitgroup == BACK) { 01533 isrear = 1; 01534 } 01535 01536 if (MechType(mech) == CLASS_MECH) { 01537 01538 if (MechElevation(mech) < MechElevation(target)) { 01539 01540 if (Fallen(target) || MechType(target) != CLASS_MECH) { 01541 hitloc = FindTargetHitLoc(mech, target, &isrear, &iscritical); 01542 } else { 01543 hitloc = FindKickLocation(target, hitgroup); 01544 } 01545 01546 } else if (MechElevation(mech) > MechElevation(target)) { 01547 hitloc = FindPunchLocation(target, hitgroup); 01548 } else { 01549 hitloc = FindTargetHitLoc(mech, target, &isrear, &iscritical); 01550 } 01551 01552 } else { 01553 hitloc = FindTargetHitLoc(mech, target, &isrear, &iscritical); 01554 } 01555 break; 01556 01557 case PA_KICK: 01558 01559 if (!OkayCritSectS(sect, 2, LOWER_ACTUATOR)) 01560 damage = damage / 2; 01561 01562 if (!OkayCritSectS(sect, 1, UPPER_ACTUATOR)) 01563 damage = damage / 2; 01564 01565 if (Fallen(target) || MechType(target) != CLASS_MECH) { 01566 hitloc = FindTargetHitLoc(mech, target, &isrear, &iscritical); 01567 } else { 01568 01569 hitgroup = FindAreaHitGroup(mech, target); 01570 if (hitgroup == BACK) { 01571 isrear = 1; 01572 } 01573 01574 if (MechElevation(mech) > MechElevation(target)) { 01575 hitloc = FindPunchLocation(target, hitgroup); 01576 } else { 01577 hitloc = FindKickLocation(target, hitgroup); 01578 } 01579 } 01580 break; 01581 01582 } 01583 01584 if (glance) { 01585 damage = (damage + 1) / 2; 01586 } 01587 01588 // Damage the target. 01589 MyDamageMech(target, mech, 1, MechPilot(mech), hitloc, 01590 isrear, iscritical, damage, 0); 01591 01592 // If we've successfully hit a suit, knock him off. 01593 if (MechType(target) == CLASS_BSUIT && MechSwarmTarget(target) > 0 && 01594 AttackType != PA_KICK) { 01595 StopSwarming(target, 0); 01596 } 01597 01598 // If we kick our target (who is a mech), make a roll to see if he falls. 01599 if (MechType(target) == CLASS_MECH && AttackType == PA_KICK) { 01600 if (!MadePilotSkillRoll(target, 0) && !Fallen(target)) { 01601 mech_notify(target, MECHSTARTED, 01602 "The kick knocks you to the ground!"); 01603 MechLOSBroadcast(target, "stumbles and falls down!"); 01604 MechFalls(target, 1, 0); 01605 } 01606 } 01607 01608 } // end PhysicalDamage()
Definition at line 1414 of file mech.physical.c.
References Fallen, GetMechToMechID(), MadePilotSkillRoll(), mech_notify(), mech_printf(), MECHALL, MechFalls(), MechLOSBroadcast(), and MECHSTARTED.
Referenced by PhysicalAttack().
01415 { 01416 // If we trip our target (who is a mech), make a roll to see if he falls. 01417 if(!MadePilotSkillRoll(target, 0) && !Fallen(target)) { 01418 01419 // Emit to Attacker 01420 mech_printf(mech, MECHALL, 01421 "You trip %s!", GetMechToMechID(mech, target)); 01422 01423 // Emit to victim and LOS. 01424 mech_notify(target, MECHSTARTED, 01425 "You are tripped and fall to the ground!"); 01426 MechLOSBroadcast(target, "trips up and falls down!"); 01427 01428 MechFalls(target, 1, 0); 01429 } else { 01430 MechLOSBroadcast(target, "manages to stay upright!"); 01431 } 01432 } // end PhysicalTrip()
int punch_checkArm | ( | MECH * | mech, | |
int | arm | |||
) |
Performs some generic checks for arms to punch with.
Definition at line 300 of file mech.physical.c.
References CARRYING_CLUB, LARM, mech_printf(), MECHALL, MechSections, OkayCritSectS, SectIsDestroyed, SHOULDER_OR_HIP, and specials.
Referenced by mech_punch().
00301 { 00302 char *arm_used = (arm == LARM ? "left" : "right"); 00303 00304 if(SectIsDestroyed(mech, arm)) { 00305 mech_printf(mech, MECHALL, 00306 "Your %s arm is destroyed, you can't punch with it.", 00307 arm_used); 00308 return 0; 00309 } else if(!OkayCritSectS(arm, 0, SHOULDER_OR_HIP)) { 00310 mech_printf(mech, MECHALL, 00311 "Your %s shoulder is destroyed, you can't punch with that arm.", 00312 arm_used); 00313 return 0; 00314 } else if(MechSections(mech)[arm].specials & CARRYING_CLUB) { 00315 mech_printf(mech, MECHALL, 00316 "You're carrying a club in your %s arm and can't punch with it.", 00317 arm_used); 00318 return 0; 00319 } 00320 // Fall through to success. 00321 return 1; 00322 } // end checkArm()
int saw_checkArm | ( | MECH * | mech, | |
int | arm | |||
) |
Check to see if the specified arm can be used to saw with.
Definition at line 510 of file mech.physical.c.
References mech_printf(), MECHALL, OkayCritSectS, RARM, SectIsDestroyed, and SHOULDER_OR_HIP.
Referenced by mech_saw().
00511 { 00512 char *arm_used = (arm == RARM ? "right" : "left"); 00513 00514 if(SectIsDestroyed(mech, arm)) { 00515 mech_printf(mech, MECHALL, 00516 "Your %s arm is destroyed, you can't saw with it", 00517 arm_used); 00518 return 0; 00519 } else if(!OkayCritSectS(arm, 0, SHOULDER_OR_HIP)) { 00520 mech_printf(mech, MECHALL, 00521 "Your %s shoulder is destroyed, you can't saw with that arm.", 00522 arm_used); 00523 return 0; 00524 } 00525 // Fall through to success. 00526 return 1; 00527 } // end saw_checkArm()
int sword_checkArm | ( | MECH * | mech, | |
int | arm | |||
) |
Check our arms to see if they can chop.
Definition at line 649 of file mech.physical.c.
References HAND_OR_FOOT_ACTUATOR, mech_printf(), MECHALL, OkayCritSectS, RARM, SectIsDestroyed, and SHOULDER_OR_HIP.
Referenced by mech_sword().
00650 { 00651 char *arm_used = (arm == RARM ? "right" : "left"); 00652 00653 if(SectIsDestroyed(mech, arm)) { 00654 mech_printf(mech, MECHALL, 00655 "Your %s arm is destroyed, you can't use a sword with it.", 00656 arm_used); 00657 return 0; 00658 } else if(!OkayCritSectS(arm, 0, SHOULDER_OR_HIP)) { 00659 mech_printf(mech, MECHALL, 00660 "Your %s shoulder is destroyed, you can't use a sword with that arm.", 00661 arm_used); 00662 return 0; 00663 } else if(!OkayCritSectS(arm, 3, HAND_OR_FOOT_ACTUATOR)) { 00664 mech_printf(mech, MECHALL, 00665 "Your %s hand is destroyed, you can't use a sword with that arm.", 00666 arm_used); 00667 return 0; 00668 } 00669 // Fall through to success. 00670 return 1; 00671 } // end sword_checkArm()
const int resect[CHARGE_SECTIONS] |