/* * Author: Markus Stenberg <fingon@iki.fi> * * Copyright (c) 1997 Markus Stenberg * Copyright (c) 1998-2002 Thomas Wouters * Copyright (c) 2000-2002 Cord Awtry * All rights reserved */ #include "mech.h" #include "mech.events.h" #include "p.mech.utils.h" #include "p.mech.update.h" #include "p.mech.restrict.h" #include "p.mech.combat.h" #include "p.mech.damage.h" #include "p.template.h" #include "p.btechstats.h" #include "p.mech.combat.misc.h" void mech_ood_damage(MECH * wounded, MECH * attacker, int damage) { mech_printf(attacker, MECHALL, "%%cgYou hit the cocoon for %d points of damage!%%cn", damage); mech_printf(wounded, MECHALL, "%%ch%%cyYour cocoon has been hit for %d points of damage!%%cn", damage); MechCocoon(wounded) = MAX(0, MechCocoon(wounded) - damage); if(MechCocoon(wounded)) return; /* Abort the OOD and initiate falling */ if(MechZ(wounded) > MechElevation(wounded)) { if(MechJumpSpeed(wounded) >= MP1) { mech_notify(wounded, MECHALL, "You initiate your jumpjets to compensate for the breached cocoon!"); MechCocoon(wounded) = -1; return; } mech_notify(wounded, MECHALL, "Your cocoon has been destroyed - have a nice fall!"); MechLOSBroadcast(wounded, "starts plummeting down, as the final blast blows the cocoon apart!"); StopOOD(wounded); MECHEVENT(wounded, EVENT_FALL, mech_fall_event, FALL_TICK, -1); } } void mech_ood_event(MUXEVENT * e) { MECH *mech = (MECH *) e->data; int mof = 0, roll, roll_needed, para = 0; if(!OODing(mech)) return; MarkForLOSUpdate(mech); if((MechsElevation(mech) - DropGetElevation(mech)) > OOD_SPEED) { MechZ(mech) -= OOD_SPEED; MechFZ(mech) = MechZ(mech) * ZSCALE; MECHEVENT(mech, EVENT_OOD, mech_ood_event, OOD_TICK, 0); return; } /* Time to hit da ground */ mech_notify(mech, MECHALL, "Your unit touches down!"); if(MechStatus(mech) & COMBAT_SAFE) { /* If we're combat safe, we land regardless, since we're not gonna take any damage */ MechCocoon(mech) = 0; MechLOSBroadcast(mech, "touches down safely!"); DropSetElevation(mech, 1); MaybeMove(mech); return; } if(Fallen(mech)) mof = -10; if(Uncon(mech) || !Started(mech) || Blinded(mech)) mof = -20; roll = Roll(); roll_needed = MechType(mech) == CLASS_BSUIT || MechType(mech) == CLASS_MW ? FindPilotPiloting(mech) - 1 : FindSPilotPiloting(mech) + MechPilotSkillBase(mech); if(!Started(mech)) roll_needed += 10; if(MechCocoon(mech) == 1) { para = 1; } else if(MechCocoon(mech) < 0) { roll_needed += 4; } else if(MechCocoon(mech) == 0) { roll_needed += 10; } if(MechRTerrain(mech) != GRASSLAND && MechRTerrain(mech) != ROAD) { if(MechRTerrain(mech) == WATER || MechRTerrain(mech) == HIGHWATER) roll_needed += 2; else roll_needed += 3; } MechCocoon(mech) = 0; if(In_Character(mech->mynum) && Location(MechPilot(mech)) != mech->mynum) roll_needed += 99; mech_notify(mech, MECHPILOT, "You make a piloting skill roll!"); mech_notify(mech, MECHPILOT, tprintf("Modified Pilot Skill: BTH %d\tRoll: %d", roll_needed, roll)); mof += (roll - roll_needed); if(roll >= roll_needed) { if(roll_needed > 2) AccumulatePilXP(MechPilot(mech), mech, BOUNDED(1, (abs(mof) + 1) * 2, 20), 1); } mof += (roll - roll_needed); if(mof < 0) { if(MechType(mech) == CLASS_MECH) { mech_notify(mech, MECHALL, "You are unable to control your momentum and fall on your face!"); MechLOSBroadcast(mech, "touches down on the ground, twists, and falls down!"); MechFalls(mech, (abs(mof) * (para ? 1 : 2)), 1); } else if(MechType(mech) == CLASS_BSUIT) { int i, ii, dam; mech_notify(mech, MECHALL, "You are unable to control your momentum and crash!"); MechLOSBroadcast(mech, "crashes to the ground!"); for(i = 0; i < NUM_SECTIONS; i++) { dam = 0; if(GetSectOInt(mech, i) > 0) { for(ii = mof; ii < 0; ii++) dam += Number(1, 4); DamageMech(mech, mech, 0, -1, i, 0, 0, dam, -1, -1, 0, 0, 0, 0); MechFloods(mech); } } MechFalls(mech, 0, 1); } else { mech_notify(mech, MECHALL, "You are unable to control your momentum and crash!"); MechLOSBroadcast(mech, "crashes at the ground!"); MechFalls(mech, (abs(mof) * (para ? 1 : 3)), 1); } } else if(!para) { MechLOSBroadcast(mech, "touches down!"); } else if(para) { MechLOSBroadcast(mech, "touches down and rolls on the ground!"); /* mech_notify(mech, MECHALL, "As you hit the ground you roll and sponge some damage!"); MechFalls(mech, (MechTons(mech) / 25), 0); */ } DropSetElevation(mech, 1); if(!Fallen(mech)) domino_space(mech, 2); if(WaterBeast(mech) && NotInWater(mech)) MechDesiredSpeed(mech) = 0.0; MaybeMove(mech); /* Lets handle dropping right into the water. Anything but a mech/hover goes glub */ if(InWater(mech) && (MechType(mech) == CLASS_VEH_GROUND || MechType(mech) == CLASS_VTOL || MechType(mech) == CLASS_BSUIT || MechType(mech) == CLASS_AERO || MechType(mech) == CLASS_DS) && !(MechSpecials2(mech) & WATERPROOF_TECH)) { mech_notify(mech, MECHALL, "Water floods your engine and your unit " "becomes unoperable."); if(MechType(mech) == CLASS_BSUIT) MechLOSBroadcast(mech,"emits some bubbles and flails their arms around as they sink to the bottom!"); else MechLOSBroadcast(mech,"emits some bubbles as its engines are flooded."); DestroyMech(mech, mech, 0); } } void initiate_ood(dbref player, MECH * mech, char *buffer) { char *args[4]; int x, y, z = ORBIT_Z, argc; DOCHECK((argc = mech_parseattributes(buffer, args, 3)) < 2, "Invalid attributes!"); DOCHECK(Readnum(x, args[0]), "Invalid number! (x)"); DOCHECK(Readnum(y, args[1]), "Invalid number! (y)"); if(argc == 3) DOCHECK(Readnum(z, args[2]), "Invalid number! (z)"); DOCHECK(OODing(mech), "OOD already in progress!"); mech_Rsetxy(GOD, (void *) mech, tprintf("%d %d", x, y)); DOCHECK(MechX(mech) != x || MechY(mech) != y, "Invalid co-ordinates!"); DOCHECK(Fallen(mech), "You'll have to get up first."); DOCHECK(Digging(mech), "You're too busy digging in."); MechZ(mech) = z; MechFZ(mech) = ZSCALE * MechZ(mech); MarkForLOSUpdate(mech); notify(player, "OOD initiated."); if(FlyingT(mech)) { MechStatus(mech) &= ~LANDED; MechDesiredSpeed(mech) = MechMaxSpeed(mech) / 2; if(is_aero(mech)) MechDesiredAngle(mech) = 0; MaybeMove(mech); } else { MechCocoon(mech) = MechRTons(mech) / 5 / 1024 + 1; StopMoving(mech); MECHEVENT(mech, EVENT_OOD, mech_ood_event, OOD_TICK, 0); } }