src/hcode/btech/mech.physical.c File Reference

#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 Documentation

#define ARM_PHYS_CHECK (  ) 

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

Definition at line 1610 of file mech.physical.c.

Referenced by ChargeMech().

#define DFA_SECTIONS   6

Definition at line 1611 of file mech.physical.c.

Referenced by DeathFromAbove().

#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,
 ) 

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,
 ) 

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)

Definition at line 150 of file mech.physical.c.

Referenced by phys_fail(), and phys_succeed().

#define QUAD_CHECK (  ) 

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().


Function Documentation

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()

void ChargeMech ( MECH mech,
MECH target 
)

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()

int DeathFromAbove ( MECH mech,
MECH target 
)

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().

00175 {
00176         return FindObj(mech, loc, I2Special(AXE)) >= (MechTons(mech) / 15);
00177 }

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().

00200 {
00201         return FindObj(mech, loc, I2Special(MACE)) >= (MechTons(mech) / 10);
00202 }

static int have_punch ( MECH mech,
int  loc 
) [static]

Definition at line 166 of file mech.physical.c.

Referenced by mech_kickortrip(), and mech_punch().

00167 {
00168         return 1;
00169 }

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().

00183 {
00184         return FindObj(mech, loc, I2Special(DUAL_SAW)) >= 7;
00185 }

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()

void phys_fail ( MECH mech,
MECH target,
int  at 
)

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

void phys_succeed ( MECH mech,
MECH target,
int  at 
)

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()

void PhysicalTrip ( MECH mech,
MECH target 
)

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()


Variable Documentation

int global_physical_flag

Definition at line 331 of file mech.damage.c.

Referenced by DamageMech().

const int resect[CHARGE_SECTIONS]

Initial value:

Definition at line 1615 of file mech.physical.c.


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