/* * $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!"); }