btmux/autom4te.cache/
btmux/doc/.svn/
btmux/event/.svn/
btmux/game/.svn/
btmux/game/bin/.svn/
btmux/game/data/.svn/
btmux/game/logs/.svn/
btmux/game/maps/
btmux/game/maps/.svn/
btmux/game/maps/.svn/prop-base/
btmux/game/maps/.svn/props/
btmux/game/maps/.svn/text-base/
btmux/game/maps/.svn/wcprops/
btmux/game/mechs/
btmux/game/mechs/.svn/
btmux/game/mechs/.svn/prop-base/
btmux/game/mechs/.svn/props/
btmux/game/mechs/.svn/text-base/
btmux/game/mechs/.svn/wcprops/
btmux/game/text/.svn/
btmux/include/.svn/
btmux/misc/
btmux/misc/.svn/
btmux/misc/.svn/prop-base/
btmux/misc/.svn/props/
btmux/misc/.svn/text-base/
btmux/misc/.svn/wcprops/
btmux/python/
btmux/python/.svn/
btmux/python/.svn/prop-base/
btmux/python/.svn/props/
btmux/python/.svn/text-base/
btmux/python/.svn/wcprops/
btmux/src/.svn/prop-base/
btmux/src/.svn/props/
btmux/src/.svn/text-base/
btmux/src/.svn/wcprops/
btmux/src/hcode/.svn/
btmux/src/hcode/btech/
btmux/src/hcode/btech/.svn/
btmux/src/hcode/btech/.svn/prop-base/
btmux/src/hcode/btech/.svn/props/
btmux/src/hcode/btech/.svn/text-base/
btmux/src/hcode/btech/.svn/wcprops/
btmux/src/hcode/include/.svn/
/* This is the code that runs the parts failures.
   Written by: Nim
   9-28-96
   
   Parts copyright (c) 2000-2002 Thomas Wouters
   
 */

/*
 * $Id: failures.c,v 1.1.1.1 2005/01/11 21:18:07 kstevens Exp $
 * Last modified: Sat Jun  6 21:43:52 1998 fingon
 */

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define _FAILURES_C
#include "mech.h"
#include "failures.h"
#include "mech.events.h"
#include "p.mech.startup.h"

extern int num_def_weapons;

int GetBrandIndex(int type)
{
    if (type == -1)
	return COMPUTER_INDEX;
    if (type == -2)
	return RADIO_INDEX;
    if (IsWeapon(type))
	if (type < I2Weapon(num_def_weapons)) {
	    type = Weapon2I(type);
	    if (MechWeapons[type].special & PCOMBAT)
		return -1;
	    if (IsFlamer(type))
		return FLAMMER_INDEX;
	    if (IsEnergy(type))
		return ENERGY_INDEX;
	    if (IsAutocannon(type))
		return AC_INDEX;
	    if (IsMissile(type))
		return MISSILE_INDEX;
	    return -1;
	}
    return -1;
}

char *GetPartBrandName(int type, int level)
{
    int i;

    if (!level)
	return NULL;
    i = GetBrandIndex(type);
    if (i < 0)
	return NULL;
    return brands[i * 5 / 6 + level - 1].name;
}

#define Conv(mech,section,critical) \
(GetBrandIndex(GetPartType(mech, section, critical)) - 1)


void FailureRadioStatic(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    int mod = failures[GetBrandIndex(-2) + roll - 1].data;

    *modifier = mod;
    *type = FAIL_STATIC;
}

static void mech_rrec_event(MUXEVENT * e)
{
    MECH *mech = (MECH *) e->data;
    int val = (int) e->data2;

    MechRadioRange(mech) += val;
    if (!Destroyed(mech) && val == MechRadioRange(mech))
	mech_notify(mech, MECHALL, "Your radio is now operational again.");
}

static void mech_srec_event(MUXEVENT * e)
{
    MECH *mech = (MECH *) e->data;
    int val = (int) e->data2;
    int vt = val / 256;

    switch (vt) {
    case 0:
	MechTacRange(mech) = val;
	if (!Destroyed(mech))
	    mech_notify(mech, MECHALL,
		"Your tactical scanners are operational again.");
	break;
    case 1:
	MechLRSRange(mech) = val;
	if (!Destroyed(mech))
	    mech_notify(mech, MECHALL,
		"Your long-range scanners are operational again.");
	break;
    case 2:
	MechScanRange(mech) = val;
	if (!Destroyed(mech))
	    mech_notify(mech, MECHALL,
		"Your scanners are operational again.");
	break;
    }
}

void FailureRadioShort(MECH * mech, int weapnum, int weaptype, int section,
    int critical, int roll, int *modifier, int *type)
{
    MECHEVENT(mech, EVENT_MRECOVERY, mech_rrec_event, Number(30, Number(40,
		200)), (int) MechRadioRange(mech));
    MechRadioRange(mech) = 0;
}

void FailureRadioRange(MECH * mech, int weapnum, int weaptype, int section,
    int critical, int roll, int *modifier, int *type)
{
    int mod = failures[GetBrandIndex(-2) + roll - 1].data;

    mod = MIN(MechRadioRange(mech) - 1, mod);
    MECHEVENT(mech, EVENT_MRECOVERY, mech_rrec_event, Number(30, Number(40,
		200)), (int) mod);
    MechRadioRange(mech) -= mod;
}

void FailureComputerShutdown(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    if (Started(mech))
	mech_shutdown(mech->mynum, mech, "");
}

void FailureComputerScanner(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    int tmp = failures[GetBrandIndex(-1) + roll - 1].data;

    switch (tmp) {
    case 1:
	MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
		Number(40, 200)), (int) MechTacRange(mech));
	MechTacRange(mech) = 0;
	break;
    case 2:
	MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
		Number(40, 200)), MechLRSRange(mech) + 256);
	MechLRSRange(mech) = 0;
	break;
    case 4:
	MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
		Number(40, 200)), MechScanRange(mech) + 512);
	MechScanRange(mech) = 0;
	break;
    case 7:
	MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
		Number(40, 200)), (int) MechTacRange(mech));
	MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
		Number(40, 200)), MechLRSRange(mech) + 256);
	MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
		Number(40, 200)), MechScanRange(mech) + 512);
	MechTacRange(mech) = 0;
	MechLRSRange(mech) = 0;
	MechScanRange(mech) = 0;
	break;
    }
}

void FailureComputerTarget(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    MechTarget(mech) = -1;
}

void FailureWeaponMissiles(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
		critical) + roll].type);
    *type = CRAZY_MISSILES;
    *modifier = failures[Conv(mech, section, critical) + roll].data;
}

void FailureWeaponDud(MECH * mech, int weapnum, int weaptype, int section,
    int critical, int roll, int *modifier, int *type)
{
    if (failures[Conv(mech, section, critical) + roll].type == FAIL_NONE) {
        SetRecyclePart(mech, section, critical,
            MechWeapons[weaptype].vrt);
	return;
    }
    SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
		critical) + roll].type);
    *type = WEAPON_DUD;
    if (roll == 6) {
	SetPartTempNuke(mech, section, critical, FAIL_DESTROYED);
    }
    SetRecyclePart(mech, section, critical, 30 + Number(1, 60));
}

void FailureWeaponJammed(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
		critical) + roll].type);
    *type = WEAPON_JAMMED;
    SetRecyclePart(mech, section, critical, Number(20, 40));
}

void FailureWeaponRange(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    *modifier =
	(int) (EGunRangeWithCheck(mech, section,
	    weaptype) * (failures[Conv(mech, section,
		    critical) + roll].data / 100.0));
    *type = RANGE;
}


void FailureWeaponDamage(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    *modifier =
	(int) (MechWeapons[weaptype].damage * (failures[Conv(mech, section,
		    critical) + roll].data / 100.0));
    *type = DAMAGE;
}

void FailureWeaponHeat(MECH * mech, int weapnum, int weaptype, int section,
    int critical, int roll, int *modifier, int *type)
{
    *modifier =
	(int) MechWeapons[weaptype].heat * (failures[Conv(mech, section,
		critical) + roll].data / 100.0);
    *type = HEAT;
}

void FailureWeaponSpike(MECH * mech, int weapnum, int weaptype,
    int section, int critical, int roll, int *modifier, int *type)
{
    SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
		critical) + roll].type);
    *type = POWER_SPIKE;
    if (roll == 6) {
	SetPartTempNuke(mech, section, critical, FAIL_DESTROYED);
	return;
    }
    SetRecyclePart(mech, section, critical, Number(20, 40));
}

void CheckGenericFail(MECH * mech, int type, int *result, int *mod)
{
    int i = GetBrandIndex(type);
    int l = type == -1 ? MechComputer(mech) : MechRadio(mech);
    int roll, in;

    if (result)
	*result = FAIL_NONE;
    if (i < 0)
	return;
    if (mudconf.btech_parts) {
	if (!l)
	    l = 5;
    } else
	return;
    if (Number(1, 5000) != 42)
	return;			/* ~1/5000 chance */
    if (Number(1, 100) <= brands[(i + l - 1) * 5 / 6].success)
	return;
    roll = Number(1, 6);
    if (roll == 6)
	roll = Number(1, 6);
    in = i + roll - 1;
    switch (failures[in].flag) {
    case REQ_TARGET:
	if (MechTarget(mech) <= 0)
	    return;
	break;
    case REQ_TAC:
	if (MechTacRange(mech) == 0)
	    return;
	break;
    case REQ_LRS:
	if (MechLRSRange(mech) == 0)
	    return;
	break;
    case REQ_SCANNERS:
	if (MechTacRange(mech) == 0 || MechLRSRange(mech) == 0 ||
	    MechScanRange(mech) == 0)
	    return;
	break;
    case REQ_COMPUTER:
	/* */
	break;
    case REQ_RADIO:
	if (MechRadioRange(mech) == 0)
	    return;
	break;
    }
    if (failures[in].message && strcmp(failures[in].message, "none"))
	mech_notify(mech, MECHALL, failures[in].message);
    failures[in].func(mech, -1, -1, -1, -1, roll, mod, result);
}

void CheckWeaponFailed(MECH * mech, int weapnum, int weaptype, int section,
    int critical, int *modifier, int *type)
{
    short roll;
    int l = GetPartBrand(mech, section, critical);
    int t = GetPartType(mech, section, critical);
    int i = GetBrandIndex(t), in;

    *type = FAIL_NONE;
    if (i < 0)
	return;
    if (mudconf.btech_parts) {
	if (!l)
	    l = 5;
	if (MechWeapons[Weapon2I(t)].special & PCOMBAT)
	    return;
    } else
	return;
    if (Number(1, 10) < 9)
	return;
    if (Number(1, 100) <= brands[(i + l - 1) * 5 / 6].success)
	return;
    roll = Number(1, 6);
    if (roll == 6)
	roll = Number(1, 6);
    in = i + roll - 1;
    if (failures[in].flag & REQ_HEAT)
	if (!MechWeapons[weaptype].heat)
	    return;
    if (failures[in].message && strcmp(failures[in].message, "none"))
	mech_notify(mech, MECHALL, failures[in].message);
    failures[in].func(mech, weapnum, weaptype, section, critical, roll,
	modifier, type);
}