/*
* $Id: mech.tech.commands.c,v 1.1.1.1 2005/01/11 21:18:25 kstevens Exp $
*
* Author: Markus Stenberg <fingon@iki.fi>
*
* Copyright (c) 1996 Markus Stenberg
* Copyright (c) 1998-2002 Thomas Wouters
* Copyright (c) 2000-2002 Cord Awtry
* All rights reserved
*
* Created: Sun Sep 1 16:06:40 1996 fingon
* Last modified: Thu Sep 10 07:37:29 1998 fingon
*
*/
#include <math.h>
#include <string.h>
#include "mech.h"
#include "muxevent.h"
#include "mech.events.h"
#include "mech.tech.h"
#include "failures.h"
#include "p.mech.utils.h"
#include "p.mech.tech.h"
#include "p.mech.consistency.h"
#include "p.mech.tech.do.h"
#include "p.bsuit.h"
#define my_parsepart(loc,part) \
switch (tech_parsepart(mech, buffer, loc, part,NULL)) \
{ case -1: notify(player, "Invalid section!");return; \
case -2: notify(player, "Invalid part!");return; }
#define my_parsepart2(loc,part,brand) \
switch (tech_parsepart(mech, buffer, loc, part,brand)) \
{ case -1: notify(player, "Invalid section!");return; \
case -2: notify(player, "Invalid part!");return; }
#define my_parsegun(loc,part,brand) \
switch (tech_parsegun(mech, buffer, loc, part, brand)) \
{ case -1: notify(player, "Invalid gun #!");return; \
case -2: notify(player, "Invalid object to replace with!");return; \
case -3: notify(player, "Invalid object type - not matching with original.");return; \
case -4: notify(player, "Invalid gun location - subscript out of range.");return; }
#define ClanMod(num) \
MAX(1, (((num) / ((MechSpecials(mech) & CLAN_TECH) ? 2 : 1))))
static int tmp_flag = 0;
static int tmp_loc;
static int tmp_part;
static void tech_check_locpart(MUXEVENT * e)
{
int loc, pos;
int l = (int) e->data2;
UNPACK_LOCPOS(l, loc, pos);
if (loc == tmp_loc && pos == tmp_part)
tmp_flag++;
}
static void tech_check_loc(MUXEVENT * e)
{
int loc;
loc = (((int) e->data2) % 16);
if (loc == tmp_loc)
tmp_flag++;
}
#define CHECK(t,fun) \
tmp_flag=0;tmp_loc=loc;tmp_part = part; \
muxevent_gothru_type_data(t, (void *) mech, fun); \
return tmp_flag
#define CHECKL(t,fun) \
tmp_flag=0;tmp_loc=loc; \
muxevent_gothru_type_data(t, (void *) mech, fun); \
return tmp_flag
#define CHECK2(t,t2,fun) \
tmp_flag=0;tmp_loc=loc;tmp_part = part; \
muxevent_gothru_type_data(t, (void *) mech, fun); \
muxevent_gothru_type_data(t2, (void *) mech, fun); \
return tmp_flag
/* Replace/reload */
int SomeoneRepairing_s(MECH * mech, int loc, int part, int t)
{
CHECK(t, tech_check_locpart);
}
#define DAT(t) \
if (SomeoneRepairing_s(mech, loc, part, t)) return 1
int SomeoneRepairing(MECH * mech, int loc, int part)
{
DAT(EVENT_REPAIR_RELO);
DAT(EVENT_REPAIR_REPL);
DAT(EVENT_REPAIR_REPLG);
DAT(EVENT_REPAIR_REPAP);
DAT(EVENT_REPAIR_REPAG);
DAT(EVENT_REPAIR_MOB);
DAT(EVENT_REPAIR_REPENHCRIT);
return 0;
}
/* Fixinternal/armor */
int SomeoneFixingA(MECH * mech, int loc)
{
CHECKL(EVENT_REPAIR_FIX, tech_check_loc);
}
int SomeoneFixingI(MECH * mech, int loc)
{
CHECKL(EVENT_REPAIR_FIXI, tech_check_loc);
}
int SomeoneFixing(MECH * mech, int loc)
{
return SomeoneFixingA(mech, loc) || SomeoneFixingI(mech, loc);
}
/* Reattach */
int SomeoneAttaching(MECH * mech, int loc)
{
CHECKL(EVENT_REPAIR_REAT, tech_check_loc);
}
int SomeoneReplacingSuit(MECH * mech, int loc)
{
CHECKL(EVENT_REPAIR_REPSUIT, tech_check_loc);
}
/* Reseal
*
* Added by Kipsta
* 8/4/99
*/
int SomeoneResealing(MECH * mech, int loc)
{
CHECKL(EVENT_REPAIR_RESE, tech_check_loc);
}
int SomeoneScrappingLoc(MECH * mech, int loc)
{
CHECKL(EVENT_REPAIR_SCRL, tech_check_loc);
}
int SomeoneScrappingPart(MECH * mech, int loc, int part)
{
DAT(EVENT_REPAIR_SCRP);
DAT(EVENT_REPAIR_SCRG);
DAT(EVENT_REPAIR_UMOB);
return 0;
}
#undef CHECK
#undef CHECK2
#undef DAT
int CanScrapLoc(MECH * mech, int loc)
{
tmp_flag = 0;
tmp_loc = loc % 8;
muxevent_gothru_type_data(EVENT_REPAIR_REPL, (void *) mech,
tech_check_loc);
muxevent_gothru_type_data(EVENT_REPAIR_RELO, (void *) mech,
tech_check_loc);
return !tmp_flag && !SomeoneFixing(mech, loc);
}
int CanScrapPart(MECH * mech, int loc, int part)
{
return !(SomeoneRepairing(mech, loc, part));
}
#define tech_gun_is_ok(a,b,c) !PartIsNonfunctional(a,b,c)
extern char *silly_get_uptime_to_string(int);
int ValidGunPos(MECH * mech, int loc, int pos)
{
unsigned char weaparray_f[MAX_WEAPS_SECTION];
unsigned char weapdata_f[MAX_WEAPS_SECTION];
int critical_f[MAX_WEAPS_SECTION];
int i, num_weaps_f;
if ((num_weaps_f =
FindWeapons_Advanced(mech, loc, weaparray_f, weapdata_f,
critical_f, 1)) < 0)
return 0;
for (i = 0; i < num_weaps_f; i++)
if (critical_f[i] == pos)
return 1;
return 0;
}
void tech_checkstatus(dbref player, void *data, char *buffer)
{
MECH *mech = (MECH *) data;
int i = figure_latest_tech_event(mech);
char *ms;
DOCHECK(!i, "The mech's ready to rock!");
ms = silly_get_uptime_to_string(game_lag_time(i));
notify(player, tprintf("The 'mech has approximately %s until done.",
ms));
}
TECHCOMMANDH(tech_removegun)
{
TECHCOMMANDB;
TECHCOMMANDC;
my_parsegun(&loc, &part, NULL);
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! You can assume the gun's gone too!");
DOCHECK(!IsWeapon(GetPartType(mech, loc, part)), "That's no gun!");
DOCHECK(PartIsDestroyed(mech, loc, part), "That gun's gone already!");
DOCHECK(!ValidGunPos(mech, loc, part),
"You can't remove middle of a gun!");
DOCHECK(SomeoneScrappingPart(mech, loc, part),
"Someone's scrapping it already!");
DOCHECK(!CanScrapPart(mech, loc, part),
"Someone's tinkering with it already!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no additional removals are possible!");
/* Ok.. Everything's valid (we hope). */
if (tech_weapon_roll(player, mech, REMOVEG_DIFFICULTY) < 0) {
START
("Ack! Your attempt is far from perfect, you try to recover the gun..");
if (tech_weapon_roll(player, mech, REMOVEG_DIFFICULTY) < 0) {
START("No good. Consider the part gone.");
FAKEREPAIR(REMOVEG_TIME * ClanMod(GetWeaponCrits(mech,
Weapon2I(GetPartType(mech, loc, part)))),
EVENT_REPAIR_SCRG, mech, PACK_LOCPOS_E(loc, part, mod));
mod = 3;
return;
}
}
START("You start removing the gun..");
STARTREPAIR(REMOVEG_TIME * ClanMod(GetWeaponCrits(mech,
Weapon2I(GetPartType(mech, loc, part)))), mech,
PACK_LOCPOS_E(loc, part, mod), muxevent_tickmech_removegun,
EVENT_REPAIR_SCRG);
}
TECHCOMMANDH(tech_removepart)
{
TECHCOMMANDB;
TECHCOMMANDC;
my_parsepart(&loc, &part);
DOCHECK((t =
GetPartType(mech, loc, part)) == EMPTY,
"That location is empty!");
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! You can assume the part's gone too!");
DOCHECK(IsWeapon(t), "That's a gun - use removegun instead!");
DOCHECK(PartIsDestroyed(mech, loc, part), "That part's gone already!");
DOCHECK(IsCrap(GetPartType(mech, loc, part)),
"That type isn't scrappable!");
DOCHECK(t == Special(ENDO_STEEL) ||
t == Special(FERRO_FIBROUS) || t == Special(STEALTH_ARMOR) ||
t == Special(HVY_FERRO_FIBROUS) || t == Special(LT_FERRO_FIBROUS),
"That type of item can't be removed!");
DOCHECK(SomeoneScrappingPart(mech, loc, part),
"Someone's scrapping it already!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no additional removals are possible!");
DOCHECK(!CanScrapPart(mech, loc, part),
"Someone's tinkering with it already!");
/* Ok.. Everything's valid (we hope). */
START("You start removing the part..");
if (tech_roll(player, mech, REMOVEP_DIFFICULTY) < 0) {
START
("Ack! Your attempt is far from perfect, you try to recover the part..");
if (tech_roll(player, mech, REMOVEP_DIFFICULTY) < 0) {
START("No good. Consider the part gone.");
mod = 3;
FAKEREPAIR(REMOVEP_TIME, EVENT_REPAIR_SCRP, mech,
PACK_LOCPOS_E(loc, part, mod));
return;
}
}
STARTREPAIR(REMOVEP_TIME, mech, PACK_LOCPOS_E(loc, part, mod),
muxevent_tickmech_removepart, EVENT_REPAIR_SCRP);
}
#define CHECK_S(nloc) \
if (!SectIsDestroyed(mech,nloc)) return 1; \
if (Invalid_Scrap_Path(mech,nloc)) return 1
#define CHECK(tloc,nloc) \
case tloc: CHECK_S(nloc)
int Invalid_Scrap_Path(MECH * mech, int loc)
{
if (loc < 0)
return 0;
if (MechType(mech) != CLASS_MECH)
return 0;
switch (loc) {
CHECK(CTORSO, HEAD);
CHECK_S(LTORSO);
CHECK_S(RTORSO);
break;
CHECK(LTORSO, LARM);
break;
CHECK(RTORSO, RARM);
break;
}
return 0;
}
#undef CHECK
#undef CHECK_S
TECHCOMMANDH(tech_removesection)
{
TECHCOMMANDB;
TECHCOMMANDC;
my_parsepart(&loc, NULL);
DOCHECK(SectIsDestroyed(mech, loc), "That section's gone already!");
DOCHECK(Invalid_Scrap_Path(mech, loc),
"You need to remove the outer sections first!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping it already!");
DOCHECK(!CanScrapLoc(mech, loc),
"Someone's tinkering with it already!");
/* Ok.. Everything's valid (we hope). */
if (tech_roll(player, mech, REMOVES_DIFFICULTY) < 0)
mod = 3;
START("You start removing the section..");
STARTREPAIR(REMOVES_TIME, mech, PACK_LOCPOS_E(loc, 0, mod),
muxevent_tickmech_removesection, EVENT_REPAIR_SCRL);
}
TECHCOMMANDH(tech_replacegun)
{
int brand = 0, ob = 0;
TECHCOMMANDB;
TECHCOMMANDC;
my_parsegun(&loc, &part, &brand);
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneRepairing(mech, loc, part),
"Someone's repairing that part already!");
DOCHECK(!IsWeapon(GetPartType(mech, loc, part)), "That's no gun!");
DOCHECK(!ValidGunPos(mech, loc, part),
"You can't replace middle of a gun!");
DOCHECK(!PartIsNonfunctional(mech, loc, part),
"That gun isn't hurtin'!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
if (brand) {
ob = GetPartBrand(mech, loc, part);
SetPartBrand(mech, loc, part, brand);
}
DOTECH_LOCPOS(REPLACE_DIFFICULTY +
WEAPTYPE_DIFFICULTY(GetPartType(mech, loc, part)), replaceg_fail,
replaceg_succ, replace_econ,
REPLACEGUN_TIME * ClanMod(GetWeaponCrits(mech,
Weapon2I(GetPartType(mech, loc, part)))), mech,
PACK_LOCPOS_E(loc, part, brand), muxevent_tickmech_replacegun,
EVENT_REPAIR_REPLG, "You start replacing the gun..", 1);
if (brand)
SetPartBrand(mech, loc, part, ob);
}
TECHCOMMANDH(tech_repairgun)
{
int extra_hard = 0;
TECHCOMMANDB;
TECHCOMMANDC;
/* Find the gun for us */
my_parsegun(&loc, &part, NULL);
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneRepairing(mech, loc, part),
"Someone's repairing that part already!");
DOCHECK(!IsWeapon(GetPartType(mech, loc, part)), "That's no gun!");
DOCHECK(!ValidGunPos(mech, loc, part),
"You can't repair middle of a gun!");
DOCHECK(SomeoneScrappingPart(mech, loc, part),
"Someone's scrapping it already!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
DOCHECK(PartIsDisabled(mech, loc, part),
"That gun can't be fixed yet!");
if (PartIsDestroyed(mech, loc, part)) {
if (GetWeaponCrits(mech, Weapon2I(GetPartType(mech, loc,
part))) < 5 ||
PartIsDestroyed(mech, loc, part + 1)) {
notify(player, "That gun is gone for good!");
return;
}
extra_hard = 1;
} else if (!PartTempNuke(mech, loc, part)) {
notify(player, "That gun isn't hurtin'!");
return;
}
DOTECH_LOCPOS(REPAIR_DIFFICULTY + WEAPTYPE_DIFFICULTY(GetPartType(mech,
loc, part)) + extra_hard, repairg_fail, repairg_succ,
repair_econ, REPAIRGUN_TIME, mech, PACK_LOCPOS(loc, part),
muxevent_tickmech_repairgun, EVENT_REPAIR_REPAP,
"You start repairing the weapon..", 1);
}
TECHCOMMANDH(tech_fixenhcrit)
{
int extra_hard = 0;
TECHCOMMANDB;
TECHCOMMANDC;
/* Find the gun for us */
my_parsegun(&loc, &part, NULL);
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneRepairing(mech, loc, part),
"Someone's repairing that part already!");
DOCHECK(!IsWeapon(GetPartType(mech, loc, part)), "That's no gun!");
DOCHECK(SomeoneScrappingPart(mech, loc, part),
"Someone's scrapping it already!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
DOCHECK(PartIsDisabled(mech, loc, part),
"That gun can't be fixed yet!");
if (!PartIsDamaged(mech, loc, part)) {
notify(player, "That gun isn't damaged!");
return;
}
DOTECH_LOCPOS(ENHCRIT_DIFFICULTY,
repairenhcrit_fail,
repairenhcrit_succ,
repairenhcrit_econ,
REPAIRENHCRIT_TIME,
mech,
PACK_LOCPOS(loc, part),
muxevent_tickmech_repairenhcrit,
EVENT_REPAIR_REPENHCRIT, "You start repairing the weapon...", 1);
}
TECHCOMMANDH(tech_replacepart)
{
TECHCOMMANDB;
TECHCOMMANDC;
my_parsepart(&loc, &part);
DOCHECK((t =
GetPartType(mech, loc, part)) == EMPTY,
"That location is empty!");
DOCHECK(!PartIsNonfunctional(mech, loc, part),
"That part looks ok to me..");
DOCHECK(IsCrap(GetPartType(mech, loc, part)),
"That part isn't hurtin'!");
DOCHECK(IsWeapon(t), "That's a weapon! Use replacegun instead.");
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneRepairing(mech, loc, part),
"Someone's repairing that part already!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
DOTECH_LOCPOS(REPLACE_DIFFICULTY +
PARTTYPE_DIFFICULTY(GetPartType(mech, loc, part)), replacep_fail,
replacep_succ, replace_econ, REPLACEPART_TIME, mech,
PACK_LOCPOS(loc, part), muxevent_tickmech_repairpart, EVENT_REPAIR_REPL,
"You start replacing the part..", 0);
}
TECHCOMMANDH(tech_repairpart)
{
TECHCOMMANDB;
TECHCOMMANDC;
my_parsepart(&loc, &part);
DOCHECK((t =
GetPartType(mech, loc, part)) == EMPTY,
"That location is empty!");
DOCHECK(PartIsDestroyed(mech, loc, part),
"That part is gone for good!");
DOCHECK(PartIsDisabled(mech, loc, part),
"That part can't be repaired yet!");
DOCHECK(!PartTempNuke(mech, loc, part), "That part isn't hurtin'!");
DOCHECK(IsCrap(GetPartType(mech, loc, part)),
"That part isn't hurtin'!");
DOCHECK(IsWeapon(t), "That's a weapon! Use repairgun instead.");
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneRepairing(mech, loc, part),
"Someone's repairing that part already!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
DOTECH_LOCPOS(REPAIR_DIFFICULTY + PARTTYPE_DIFFICULTY(GetPartType(mech,
loc, part)), repairp_fail, repairp_succ, repair_econ,
REPAIRPART_TIME, mech, PACK_LOCPOS(loc, part),
muxevent_tickmech_repairpart, EVENT_REPAIR_REPAP,
"You start repairing the part..", 0);
}
TECHCOMMANDH(tech_toggletype)
{
int atype;
TECHCOMMANDB;
DOCHECK((!Wizard(player)) && In_Character(mech->mynum),
"This command only works in simpods!");
my_parsepart2(&loc, &part, &atype);
DOCHECK(!IsAmmo((t =
GetPartType(mech, loc, part))), "That's no ammo!");
DOCHECK(PartIsNonfunctional(mech, loc, part) ||
PartIsDisabled(mech, loc, part),
"The ammo compartment is nonfunctional!");
DOCHECK(!atype,
"You need to give a type to toggle to (use - for normal)");
DOCHECK((t =
(valid_ammo_mode(mech, loc, part, atype))) < 0,
"That is invalid ammo type for this weapon!");
GetPartAmmoMode(mech, loc, part) &= ~(AMMO_MODES);
GetPartAmmoMode(mech, loc, part) |= t;
SetPartData(mech, loc, part, FullAmmo(mech, loc, part));
mech_notify(mech, MECHALL, "Ammo toggled.");
}
TECHCOMMANDH(tech_reload)
{
int atype;
TECHCOMMANDB;
TECHCOMMANDD;
my_parsepart2(&loc, &part, &atype);
DOCHECK(!IsAmmo((t =
GetPartType(mech, loc, part))), "That's no ammo!");
DOCHECK(PartIsNonfunctional(mech, loc, part),
"The ammo compartment is destroyed ; repair/replacepart it first.");
DOCHECK(PartIsDisabled(mech, loc, part),
"The ammo compartment is disabled ; repair/replacepart it first.");
DOCHECK((now = GetPartData(mech, loc, part)) == (full =
FullAmmo(mech, loc, part)),
"That particular ammo compartment doesn't need reloading.");
DOCHECK(SomeoneRepairing(mech, loc, part),
"Someone's playing with that part already!");
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
if (atype) {
DOCHECK((t =
(valid_ammo_mode(mech, loc, part, atype))) < 0,
"That is invalid ammo type for this weapon!");
SetPartData(mech, loc, part, 0);
GetPartAmmoMode(mech, loc, part) &= ~(AMMO_MODES);
GetPartAmmoMode(mech, loc, part) |= t;
}
change = 0;
DOTECH_LOCPOS_VAL(RELOAD_DIFFICULTY, reload_fail, reload_succ,
reload_econ, &change, RELOAD_TIME, mech, PACK_LOCPOS_E(loc, part,
change), muxevent_tickmech_reload, EVENT_REPAIR_RELO,
"You start reloading the ammo compartment..");
}
TECHCOMMANDH(tech_unload)
{
TECHCOMMANDB;
TECHCOMMANDD;
my_parsepart(&loc, &part);
DOCHECK(!IsAmmo((t =
GetPartType(mech, loc, part))), "That's no ammo!");
DOCHECK(PartIsNonfunctional(mech, loc, part),
"The ammo compartment is destroyed ; repair/replacepart it first.");
DOCHECK(PartIsDisabled(mech, loc, part),
"The ammo compartment is disabled ; repair/replacepart it first.");
DOCHECK(!(now =
GetPartData(mech, loc, part)),
"That particular ammo compartment is empty already.");
DOCHECK(SomeoneRepairing(mech, loc, part),
"Someone's playing with that part already!");
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
if ((full = FullAmmo(mech, loc, part)) == now)
change = 2;
else
change = 1;
if (tech_roll(player, mech, REMOVES_DIFFICULTY) < 0)
mod = 3;
START("You start unloading the ammo compartment..");
STARTREPAIR(RELOAD_TIME, mech, PACK_LOCPOS_E(loc, part, change),
muxevent_tickmech_reload, EVENT_REPAIR_RELO);
}
TECHCOMMANDH(tech_fixarmor)
{
int ochange;
TECHCOMMANDB;
TECHCOMMANDD;
DOCHECK(tech_parsepart_advanced(mech, buffer, &loc, NULL, NULL, 1) < 0,
"Invalid section!");
if (loc >= 8) {
from = GetSectRArmor(mech, loc % 8);
to = GetSectORArmor(mech, loc % 8);
} else {
from = GetSectArmor(mech, loc);
to = GetSectOArmor(mech, loc);
}
DOCHECK(SectIsDestroyed(mech, loc % 8),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc % 8),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneFixingA(mech, loc) ||
SomeoneFixingI(mech, loc % 8),
"Someone's repairing that section already!");
DOCHECK(GetSectInt(mech, loc % 8) != GetSectOInt(mech, loc % 8),
"The internals need to be fixed first!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
from = MIN(to, from);
DOCHECK(from == to, "The location doesn't need armor repair!");
change = to - from;
ochange = change;
DOTECH_LOC_VAL_S(FIXARMOR_DIFFICULTY, fixarmor_fail, fixarmor_succ,
fixarmor_econ, &change, FIXARMOR_TIME * ochange, loc,
EVENT_REPAIR_FIX, mech, "You start fixing the armor..");
STARTIREPAIR(FIXARMOR_TIME * change, mech, (change * 16 + loc),
muxevent_tickmech_repairarmor, EVENT_REPAIR_FIX, change);
}
TECHCOMMANDH(tech_fixinternal)
{
TECHCOMMANDB int ochange;
TECHCOMMANDC;
my_parsepart(&loc, NULL);
from = GetSectInt(mech, loc);
to = GetSectOInt(mech, loc);
DOCHECK(from == to, "The location doesn't need internals' repair!");
change = to - from;
DOCHECK(SectIsDestroyed(mech, loc),
"That part's blown off! Use reattach first!");
DOCHECK(SectIsFlooded(mech, loc),
"That location has been flooded! Use reseal first!");
DOCHECK(SomeoneFixing(mech, loc),
"Someone's repairing that section already!");
DOCHECK(SomeoneScrappingLoc(mech, loc),
"Someone's scrapping that section - no repairs are possible!");
ochange = change;
DOTECH_LOC_VAL_S(FIXINTERNAL_DIFFICULTY, fixinternal_fail,
fixinternal_succ, fixinternal_econ, &change,
FIXINTERNAL_TIME * ochange, loc, EVENT_REPAIR_FIX, mech,
"You start fixing the internals..");
STARTIREPAIR(FIXINTERNAL_TIME * change, mech, (change * 16 + loc),
muxevent_tickmech_repairinternal, EVENT_REPAIR_FIXI, change);
}
#define CHECK(tloc,nloc) \
case tloc:if (SectIsDestroyed(mech,nloc))return 1;break;
int Invalid_Repair_Path(MECH * mech, int loc)
{
if (MechType(mech) != CLASS_MECH)
return 0;
switch (loc) {
CHECK(HEAD, CTORSO);
CHECK(LTORSO, CTORSO);
CHECK(RTORSO, CTORSO);
CHECK(LARM, LTORSO);
CHECK(RARM, RTORSO);
CHECK(LLEG, CTORSO);
CHECK(RLEG, CTORSO);
}
return 0;
}
int unit_is_fixable(MECH * mech)
{
int i;
for (i = 0; i < NUM_SECTIONS; i++) {
if (!GetSectOInt(mech, i))
continue;
if (!SectIsDestroyed(mech, i))
continue;
if (MechType(mech) == CLASS_MECH)
if (i == CTORSO)
return 0;
if (MechType(mech) == CLASS_VTOL)
if (i != ROTOR)
return 0;
if (MechType(mech) == CLASS_VEH_GROUND)
if (i != TURRET)
return 0;
}
return 1;
};
TECHCOMMANDH(tech_reattach)
{
TECHCOMMANDB;
TECHCOMMANDC;
my_parsepart(&loc, NULL);
DOCHECK(MechType(mech) == CLASS_BSUIT,
"You can't reattach a Battlesuit! Use 'replacesuit'!");
DOCHECK(!SectIsDestroyed(mech, loc), "That section isn't destroyed!");
DOCHECK(Invalid_Repair_Path(mech, loc),
"You need to reattach adjacent locations first!");
DOCHECK(SomeoneAttaching(mech, loc),
"Someone's attaching that section already!");
DOCHECK(!unit_is_fixable(mech),
"You see nothing to reattach it to (read:unit is cored).");
DOTECH_LOC(REATTACH_DIFFICULTY, reattach_fail, reattach_succ,
reattach_econ, REATTACH_TIME, mech, loc, muxevent_tickmech_reattach,
EVENT_REPAIR_REAT, "You start replacing the section..");
}
TECHCOMMANDH(tech_replacesuit)
{
int wSuits = 0;
TECHCOMMANDB;
TECHCOMMANDC;
my_parsepart(&loc, NULL);
DOCHECK(MechType(mech) != CLASS_BSUIT,
"You can only use 'replacesuit' on a battlesuit unit!");
wSuits = CountBSuitMembers(mech);
DOCHECK(MechMaxSuits(mech) <= wSuits,
tprintf
("This %s is already full! This %s only consists of %d suits!",
GetLCaseBSuitName(mech), GetLCaseBSuitName(mech),
MechMaxSuits(mech)));
DOCHECK((loc >= MechMaxSuits(mech)) ||
(loc < 0),
tprintf("Invalid suit! This %s only consists of %d suits!",
GetLCaseBSuitName(mech), MechMaxSuits(mech)));
DOCHECK(!SectIsDestroyed(mech, loc), "That suit isn't destroyed!");
DOCHECK(SomeoneReplacingSuit(mech, loc),
"Someone's already rebuilding that suit!");
DOCHECK(wSuits <= 0,
"You are unable to replace the suits here! None of the buggers are still alive!");
DOTECH_LOC(REPLACESUIT_DIFFICULTY, replacesuit_fail, replacesuit_succ,
replacesuit_econ, REPLACESUIT_TIME, mech, loc,
muxevent_tickmech_replacesuit, EVENT_REPAIR_REPSUIT,
"You start replacing the missing suit.");
}
/*
* Reseal
* Added by Kipsta
* 8/4/99
*/
TECHCOMMANDH(tech_reseal)
{
TECHCOMMANDB;
TECHCOMMANDC;
my_parsepart(&loc, NULL);
DOCHECK(SectIsDestroyed(mech, loc), "That section is destroyed!");
DOCHECK(!SectIsFlooded(mech, loc), "That has not been flooded!");
DOCHECK(Invalid_Repair_Path(mech, loc),
"You need to reattach adjacent locations first!");
DOCHECK(SomeoneResealing(mech, loc),
"Someone's sealing that section already!");
DOTECH_LOC(RESEAL_DIFFICULTY, reseal_fail, reseal_succ, reseal_econ,
RESEAL_TIME, mech, loc, muxevent_tickmech_reseal, EVENT_REPAIR_RESE,
"You start resealing the section.");
}
TECHCOMMANDH(tech_magic)
{
TECHCOMMANDB;
TECHCOMMANDC;
notify(player, "Doing the magic..");
do_magic(mech);
mech_int_check(mech, 1);
notify(player, "Done!");
}