btmux-0.6-rc4/doc/
btmux-0.6-rc4/event/
btmux-0.6-rc4/game/
btmux-0.6-rc4/game/maps/
btmux-0.6-rc4/game/mechs/
btmux-0.6-rc4/game/text/help/
btmux-0.6-rc4/game/text/help/cat_faction/
btmux-0.6-rc4/game/text/help/cat_inform/
btmux-0.6-rc4/game/text/help/cat_misc/
btmux-0.6-rc4/game/text/help/cat_mux/
btmux-0.6-rc4/game/text/help/cat_mux/cat_commands/
btmux-0.6-rc4/game/text/help/cat_mux/cat_functions/
btmux-0.6-rc4/game/text/help/cat_templates/
btmux-0.6-rc4/game/text/wizhelp/
btmux-0.6-rc4/include/
btmux-0.6-rc4/misc/
btmux-0.6-rc4/python/
btmux-0.6-rc4/src/hcode/btech/
btmux-0.6-rc4/tree/
/*
 * 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);
	}
}