/*
* $Id: eject.c,v 1.5 2005/08/10 14:09:34 av1-op Exp $
*
* Author: Markus Stenberg <fingon@iki.fi>
*
* Copyright (c) 1996 Markus Stenberg
* Copyright (c) 1998-2002 Thomas Wouters
* Copyright (c) 2000-2002 Cord Awtry
* Copyright (c) 1999-2005 Kevin Stevens
* All rights reserved
*
* Created: Mon Oct 7 01:09:08 1996 fingon
* Last modified: Sat Jun 6 20:45:29 1998 fingon
*
*/
#include "config.h"
/* Ejection code */
#include <math.h>
#include "mech.h"
#include "mech.events.h"
#include "p.btechstats.h"
#include "p.mechrep.h"
#include "p.mech.restrict.h"
#include "p.mech.update.h"
#include "p.bsuit.h"
#include "autopilot.h"
#include "p.mech.combat.h"
#include "p.mech.utils.h"
#include "p.btechstats.h"
#include "p.econ_cmds.h"
#include "p.mech.los.h"
#include "p.mech.ood.h"
#include "p.mech.pickup.h"
#include "p.bsuit.h"
#include "p.mech.tag.h"
#include "p.crit.h"
#include "p.mech.tech.h"
#include "p.mech.tech.commands.h"
int tele_contents(dbref from, dbref to, int flag)
{
dbref i, tmpnext;
int count = 0;
SAFE_DOLIST(i, tmpnext, Contents(from))
if ((flag & TELE_ALL) || !Wiz(i)) {
if ((flag & TELE_SLAVE) && !Wiz(i)) {
s_Slave(i);
silly_atr_set(i, A_LOCK, "");
}
if (flag & TELE_XP && !Wiz(i))
lower_xp(i, mudconf.btech_xploss);
if (flag & TELE_LOUD)
loud_teleport(i, to);
else
hush_teleport(i, to);
count++;
}
return count;
}
/* Delayed blast event, for various reasons */
static void mech_discard_event(MUXEVENT * e)
{
MECH *mech = (MECH *) e->data;
dbref i = mech->mynum;
c_Hardcode(i);
handle_xcode(GOD, i, 1, 0);
s_Going(i);
s_Dark(i);
s_Zombie(i);
hush_teleport(i, USED_MW_STORE);
}
void discard_mw(MECH * mech)
{
if (In_Character(mech->mynum))
MECHEVENT(mech, EVENT_NUKEMECH, mech_discard_event, 10, 0);
}
void enter_mw_bay(MECH * mech, dbref bay)
{
tele_contents(mech->mynum, bay, TELE_ALL); /* Even immortals must get going */
discard_mw(mech);
}
void pickup_mw(MECH * mech, MECH * target)
{
dbref mw;
mw = Contents(target->mynum);
DOCHECKMA((MechType(mech) != CLASS_MECH) &&
(MechType(mech) != CLASS_VEH_GROUND) &&
(MechType(mech) != CLASS_VTOL) &&
!(MechSpecials(mech) & SALVAGE_TECH),
"You can't pick up, period.") if (mw > 0)
notify(mw,
tprintf("%s scoops you up and brings you into the cockpit.",
GetMechToMechID(target, mech)));
/* Put the player in the picker uppper and clear him from the map */
MechLOSBroadcast(mech, tprintf("picks up %s.", GetMechID(target)));
mech_notify(mech, MECHALL,
tprintf("You pick up the stray mechwarrior from the field."));
if (MechTeam(target) != MechTeam(mech))
tele_contents(target->mynum, mech->mynum, TELE_ALL | TELE_SLAVE);
else
tele_contents(target->mynum, mech->mynum, TELE_ALL);
discard_mw(target);
}
static void char_eject(dbref player, MECH * mech)
{
MECH *m;
dbref suit;
char *d;
suit = create_object(tprintf("MechWarrior - %s", Name(player)));
silly_atr_set(suit, A_XTYPE, "MECH");
s_Hardcode(suit);
handle_xcode(GOD, suit, 0, 1);
d = silly_atr_get(player, A_MWTEMPLATE);
if (!(m = getMech(suit))) {
SendError(tprintf
("Unable to create special obj for #%d's ejection.", player));
destroy_object(suit);
notify(player,
"Sorry, something serious went wrong, contact a Wizard (can't create RS object)");
return;
}
if (!mech_loadnew(GOD, m, (!d || !*d ||
!strcmp(d, "#-1")) ? "MechWarrior" : d)) {
SendError(tprintf
("Unable to load mechwarrior template for #%d's ejection. (%s)",
player, (!d || !*d) ? "Default template" : d));
destroy_object(suit);
notify(player,
"Sorry, something serious went wrong, contact a Wizard (can't load MWTemplate)");
return;
}
silly_atr_set(suit, A_MECHNAME, "MechWarrior");
MechTeam(m) = MechTeam(mech);
mech_Rsetmapindex(GOD, (void *) m, tprintf("%d", mech->mapindex));
mech_Rsetxy(GOD, (void *) m, tprintf("%d %d", MechX(mech),
MechY(mech)));
mech_Rsetteam(GOD, (void *) m, tprintf("%d", MechTeam(mech)));
hush_teleport(suit, mech->mapindex);
hush_teleport(player, suit);
MechLOSBroadcast(m, tprintf("ejected from %s!", GetMechID(mech)));
s_In_Character(suit);
initialize_pc(player, m);
MechPilot(m) = player;
MechTeam(m) = MechTeam(mech);
#ifdef COPY_CHANS_ON_EJECT
memcpy(m->freq, mech->freq, FREQS * sizeof(m->freq[0]));
memcpy(m->freqmodes, mech->freqmodes, FREQS * sizeof(m->freqmodes[0]));
#else
#ifdef RANDOM_CHAN_ON_EJECT
m->freq[0] = random() % 1000000;
notify(player, tprintf("Emergency radio channel set to %d.", m->freq[0]));
#endif
#endif
notify(player, "You eject from the unit!");
if (MechType(mech) == CLASS_MECH) {
DestroyPart(mech, HEAD, 2);
}
if (!Destroyed(mech))
DestroyAndDump(mech);
}
void mech_eject(dbref player, void *data, char *buffer)
{
MECH *mech = (MECH *) data;
cch(MECH_USUALS);
DOCHECK(IsDS(mech), "Dropships do not support ejection.");
DOCHECK(!((MechType(mech) == CLASS_MECH) ||
(MechType(mech) == CLASS_VTOL) ||
(MechType(mech) == CLASS_VEH_GROUND)),
"This unit has no ejection seat!");
DOCHECK(FlyingT(mech) &&
!Landed(mech),
"Regrettably, right now you can only eject when landed, sorry - no parachute :P");
DOCHECK(!In_Character(mech->mynum), "This unit isn't in character!");
DOCHECK(!mudconf.btech_ic, "This MUX isn't in character!");
DOCHECK(!In_Character(Location(mech->mynum)),
"Your location isn't in character!");
DOCHECK(Started(mech) &&
MechPilot(mech) != player,
"You aren't in da pilot's seat - no ejection for you!");
if (!Started(mech)) {
DOCHECK((char_lookupplayer(GOD, GOD, 0, silly_atr_get(mech->mynum,
A_PILOTNUM))) != player,
"You aren't the official pilot of this thing. Try 'disembark'");
}
if (MechType(mech) == CLASS_MECH)
DOCHECK(PartIsNonfunctional(mech, HEAD, 2),
"The parts of cockpit that control ejection are already used. Try 'disembark'");
/* Ok.. time to eject ourselves */
char_eject(player, mech);
}
static void char_disembark(dbref player, MECH * mech)
{
MECH *m;
dbref suit;
char *d;
MAP *mymap;
int initial_speed;
suit = create_object(tprintf("MechWarrior - %s", Name(player)));
silly_atr_set(suit, A_XTYPE, "MECH");
s_Hardcode(suit);
handle_xcode(GOD, suit, 0, 1);
d = silly_atr_get(player, A_MWTEMPLATE);
if (!(m = getMech(suit))) {
SendError(tprintf
("Unable to create special obj for #%d's disembarkation.",
player));
destroy_object(suit);
notify(player,
"Sorry, something serious went wrong, contact a Wizard (can't create RS object)");
return;
}
if (!mech_loadnew(GOD, m, (!d || !*d ||
!strcmp(d, "#-1")) ? "MechWarrior" : d)) {
SendError(tprintf
("Unable to load mechwarrior template for #%d's disembarkation. (%s)",
player, (!d || !*d) ? "Default template" : d));
destroy_object(suit);
notify(player,
"Sorry, something serious went wrong, contact a Wizard (can't load MWTemplate)");
return;
}
silly_atr_set(suit, A_MECHNAME, "MechWarrior");
MechTeam(m) = MechTeam(mech);
mech_Rsetmapindex(GOD, (void *) m, tprintf("%d", mech->mapindex));
mech_Rsetxy(GOD, (void *) m, tprintf("%d %d", MechX(mech),
MechY(mech)));
MechZ(m) = MechZ(mech);
mech_Rsetteam(GOD, (void *) m, tprintf("%d", MechTeam(mech)));
hush_teleport(suit, mech->mapindex);
hush_teleport(player, suit);
s_In_Character(suit);
initialize_pc(player, m);
MechPilot(m) = player;
MechTeam(m) = MechTeam(mech);
#ifdef COPY_CHANS_ON_EJECT
memcpy(m->freq, mech->freq, FREQS * sizeof(m->freq[0]));
memcpy(m->freqmodes, mech->freqmodes, FREQS * sizeof(m->freqmodes[0]));
#else
#ifdef RANDOM_CHAN_ON_EJECT
m->freq[0] = random() % 1000000;
notify(player, tprintf("Emergency radio channel set to %d.", m->freq[0]));
#endif
#endif
mymap = getMap(m->mapindex);
if ((MechZ(m) > (Elevation(mymap, MechX(m), MechY(m)) + 1)) &&
(MechZ(m) > 0)) {
notify(player,
"You open the hatch and climb out of the unit. Maybe you should have done this while the thing was closer to the ground...");
MechLOSBroadcast(m, tprintf("jumps out of %s... in mid air !",
GetMechID(mech)));
initial_speed =
((MechSpeed(mech) + MechVerticalSpeed(mech)) / MP1) / 2 + 4;
MECHEVENT(m, EVENT_FALL, mech_fall_event, FALL_TICK,
-initial_speed);
} else {
MechLOSBroadcast(m, tprintf("climbs out of %s!", GetMechID(mech)));
notify(player, "You climb out of the unit.");
}
}
/**
* Handle the disembarking of pilots from units.
*/
void mech_disembark(dbref player, void *data, char *buffer)
{
MECH *mech = (MECH *) data;
cch(MECH_USUALS);
DOCHECK(!((MechType(mech) == CLASS_MECH) ||
(MechType(mech) == CLASS_VTOL) ||
(MechType(mech) == CLASS_VEH_GROUND)),
"The door ! The door ? The Door ?!? Where's the exit in this damned thing ?");
/* DOCHECK(FlyingT(mech) && !Landed(mech), "What, in the air ? Are you suicidal ?"); */
DOCHECK(!In_Character(mech->mynum), "This unit isn't in character!");
DOCHECK(!mudconf.btech_ic, "This MUX isn't in character!");
DOCHECK(!In_Character(Location(mech->mynum)),
"Your location isn't in character!");
DOCHECK(Started(mech) && (MechPilot(mech) == player),
"While it's running!? Don't be daft.");
DOCHECK(fabs(MechSpeed(mech)) > 25.,
"Are you suicidal ? That thing is moving too fast !");
/* Ok.. time to disembark ourselves */
char_disembark(player, mech);
}
/**
* Handle the disembarking of units from within carriers.
*/
void mech_udisembark(dbref player, void *data, char *buffer) {
MECH *mech = (MECH *) data; /* The disembarking unit */
MECH *target;
int newmech; /* The carrier. */
MAP *mymap; /* The map to disembark to */
int under_repairs; /* Is the unit still under repairs? */
int i; /* Used in section recycle for loop. */
/* Any IN_CHARACTER unit's pilot must match the invoker to disembark.
* A unit that is not IC can be disembarked by anyone.
*/
DOCHECK(In_Character(mech->mynum) && !Wiz(player) &&
(char_lookupplayer(GOD, GOD, 0,
silly_atr_get(mech->mynum, A_PILOTNUM)) != player),
"This isn't your mech!");
/* Find the carrier that the invoker's unit is in and check it for validity. */
newmech = Location(mech->mynum);
DOCHECK(!(Good_obj(newmech) &&
Hardcode(newmech)), "You're not being carried!");
DOCHECK(!(target = getMech(newmech)), "Not being carried!");
DOCHECK(target->mapindex == -1, "You are not on a map.");
/* Don't allow repairing units to disembark */
under_repairs = figure_latest_tech_event(mech);
DOCHECK(under_repairs,
"This 'Mech is still under repairs (see checkstatus for more info)");
DOCHECK(abs(MechSpeed(target)) > 0,
"You cannot leave while the carrier is moving!");
/* Carry out the disembarking. */
mech_Rsetmapindex(GOD, (void *) mech, tprintf("%d",
(int) target->mapindex));
mech_Rsetxy(GOD, (void *) mech, tprintf("%d %d", MechX(target),
MechY(target)));
MechZ(mech) = MechZ(target);
MechFZ(mech) = ZSCALE * MechZ(mech);
mymap = getMap(mech->mapindex);
DOCHECK(!mymap, "Major map error possible. Prolly should contact a wizard.");
/* Teleporting loudly in order to trigger @aenter's and whatnot. */
loud_teleport(mech->mynum, mech->mapindex);
/* If we make it safely, start the invoker's unit up once it's on the map. */
if (!Destroyed(mech) && Location(player) == mech->mynum) {
MechPilot(mech) = player;
Startup(mech);
}
MarkForLOSUpdate(mech);
SetCargoWeight(mech);
UnSetMechPKiller(mech);
MechLOSBroadcast(mech, "powers up!");
EvalBit(MechSpecials(mech), SS_ABILITY, ((MechPilot(mech) > 0 &&
isPlayer(MechPilot(mech))) ? char_getvalue(MechPilot(mech),
"Sixth_Sense") : 0));
MechComm(mech) = DEFAULT_COMM;
if (isPlayer(MechPilot(mech)) && !Quiet(mech->mynum)) {
MechComm(mech) =
char_getskilltarget(MechPilot(mech), "Comm-Conventional", 0);
MechPer(mech) =
char_getskilltarget(MechPilot(mech), "Perception", 0);
} else {
MechComm(mech) = 6;
MechPer(mech) = 6;
}
MechCommLast(mech) = 0;
UnZombifyMech(mech);
CargoSpace(target) += (MechTons(mech) * 100);
MarkForLOSUpdate(target);
/* A hidden carrier that is disembarked from loses its HIDDEN status */
if (MechCritStatus(target) & HIDDEN) {
MechCritStatus(target) &= ~HIDDEN;
MechLOSBroadcast(target, "becomes visible as it is disembarked from.");
}
/* Para-dropping out of units from elevations. */
if (!FlyingT(mech) &&
MechZ(mech) > Elevation(mymap, MechX(mech), MechY(mech)) &&
MechZ(mech) > 0) {
notify(player,
"You open the hatch and drop out of the unit....");
MechLOSBroadcast(mech, tprintf("drops out of %s and begins falling to the ground.",
GetMechID(target)));
initiate_ood(player, mech, tprintf("%d %d %d", MechX(mech), MechY(mech), MechZ(mech)));
} else {
if (MechType(mech) == CLASS_BSUIT) {
MechLOSBroadcast(mech, tprintf("climbs out of %s!", GetMechID(target)));
notify(player, "You climb out of the unit.");
} else {
/* If the carrier is destroyed, do damage to the disembarking unit. */
if (Destroyed(target) || !Started(target)) {
MechLOSBroadcast(mech, tprintf("smashes open the ramp door and emerges from %s!",
GetMechID(target)));
notify(player, "You smash open the door and break out.");
MechFalls(mech, 4, 0);
} else {
/* All is well. */
MechLOSBroadcast(mech, tprintf("emerges from the ramp out of %s!",
GetMechID(target)));
notify(player, "You emerge from the unit loading ramp.");
if (Landed(mech) && MechZ(mech) > Elevation(mymap, MechX(mech), MechY(mech))
&& FlyingT(mech))
MechStatus(mech) &= ~LANDED;
}
}
}
/* Recycle any weapons/sections they have to prevent munchkin behavior. */
if (MechType(mech) == CLASS_BSUIT) {
StartBSuitRecycle(mech, 20);
} else if (MechType(mech) == CLASS_MECH || MechType(mech) == CLASS_MW) {
for (i = 0; i < NUM_SECTIONS; i++)
SetRecycleLimb(mech, i, PHYSICAL_RECYCLE_TIME);
} else if (MechType(mech) == CLASS_VEH_GROUND || MechType(mech) == CLASS_VTOL) {
for (i = 0; i < NUM_SECTIONS; i++)
if (i == ROTOR)
continue;
else
SetRecycleLimb(mech, i, PHYSICAL_RECYCLE_TIME);
}
fix_pilotdamage(mech, MechPilot(mech));
correct_speed(target);
} /* end mech_udisembark */
void mech_embark(dbref player, void *data, char *buffer) {
MECH *mech = (MECH *) data;
MECH *target, *towee = NULL;
int tmp;
dbref target_num;
MAP *newmap;
int argc;
char *args[4];
char fail_mesg[SBUF_SIZE];
char enter_lock[LBUF_SIZE];
int i, j;
if (player != GOD)
cch(MECH_USUAL);
if (MechType(mech) == CLASS_MW) {
argc = mech_parseattributes(buffer, args, 1);
DOCHECK(argc != 1, "Invalid number of arguements.");
target_num = FindTargetDBREFFromMapNumber(mech, args[0]);
DOCHECK(target_num == -1,
"That target is not in your line of sight.");
target = getMech(target_num);
DOCHECK(!target ||
!InLineOfSight(mech, target, MechX(target), MechY(target),
FaMechRange(mech, target)),
"That target is not in your line of sight.");
DOCHECK(MechZ(mech) > (MechZ(target) + 1),
"You are too high above the target.");
DOCHECK(MechZ(mech) < (MechZ(target) - 1),
"You can't reach that high !");
DOCHECK(MechX(mech) != MechX(target) ||
MechY(mech) != MechY(target),
"You need to be in the same hex!");
DOCHECK((!In_Character(mech->mynum)) || (!In_Character(target->mynum)),
"You don't really see a way to get in there.");
DOCHECK((MechType(target) == CLASS_VEH_GROUND || MechType(target) == CLASS_VTOL) &&
!unit_is_fixable(target),
"You can't find and entrance amid the mass of twisted metal.");
if (!can_pass_lock(mech->mynum, target->mynum, A_LENTER)) {
/* Trigger FAIL & AFAIL */
memset(fail_mesg, 0, sizeof(fail_mesg));
snprintf(fail_mesg, LBUF_SIZE, "That unit's bay doors are locked.");
did_it(player, target->mynum, A_FAIL, fail_mesg, 0, NULL, A_AFAIL,
(char **) NULL, 0);
return;
}
/* They passed the lock but does that mean there was no lock? */
memset(enter_lock, 0, sizeof(enter_lock));
atr_get_str(enter_lock, target->mynum, A_LENTER, &i, &j);
if (*enter_lock == '\0') {
/* Check their teams */
DOCHECK(MechTeam(mech) != MechTeam(target), "Locked. Damn !");
}
DOCHECK(fabs(MechSpeed(target)) > 15.,
"Are you suicidal ? That thing is moving too fast !");
if (MechType(target) == CLASS_MECH) {
DOCHECK(!GetSectInt(target, HEAD),
"Okay, just climb up to-- Wait... where did the head go??");
DOCHECK(PartIsDestroyed(target, HEAD, 2),
"Okay, just climb up and open-- "
"WTF ? Someone stole the cockpit!");
DOCHECK(PartIsNonfunctional(target, HEAD, 2),
"Okay, just climb up and open-- hey, this door won't budge!");
}
mech_notify(mech, MECHALL, tprintf("You climb into %s.",
GetMechID(target)));
MechLOSBroadcast(mech, tprintf("climbs into %s.",
GetMechID(target)));
tele_contents(mech->mynum, target->mynum, TELE_ALL);
discard_mw(mech);
return;
}
/* What heppens with a Bsuit squad? */
/* Check if the vechile has cargo capacity, or is an Omni Mech */
argc = mech_parseattributes(buffer, args, 1);
DOCHECK(argc != 1, "Invalid number of arguements.");
target_num = FindTargetDBREFFromMapNumber(mech, args[0]);
DOCHECK(target_num == -1, "That target is not in your line of sight.");
target = getMech(target_num);
DOCHECK(!target ||
!InLineOfSight(mech, target, MechX(target), MechY(target),
FaMechRange(mech, target)),
"That target is not in your line of sight.");
DOCHECK(MechCarrying(mech) == target_num, "You cannot embark what your towing!");
DOCHECK(Fallen(mech) || Standing(mech), "Help! I've fallen and I can't get up!");
DOCHECK(!Started(mech) || Destroyed(mech), "Ha Ha Ha.");
DOCHECK(Jumping(mech), "You cannot do that while jumping!");
DOCHECK(Jumping(target), "You cannot do that while it is jumping!");
DOCHECK(MechSpecials2(mech) & CARRIER_TECH && (IsDS(target) ? IsDS(mech) : 1),
"You're a bit bulky to do that yourself.");
DOCHECK(MechCritStatus(mech) & HIDDEN, "You cannot embark while hidden.");
DOCHECK(MechTons(mech) > CarMaxTon(target), "You are too large for that class of carrier.");
DOCHECK(MechType(mech) != CLASS_BSUIT && !(MechSpecials2(target) & CARRIER_TECH),
"This unit can't handle your mass.");
DOCHECK(MMaxSpeed(mech) < MP1, "You are to overloaded to enter.");
DOCHECK(MechZ(mech) > (MechZ(target) + 1),
"You are too high above the target.");
DOCHECK(MechZ(mech) < (MechZ(target) - 1),
"You can't reach that high !");
DOCHECK(MechX(mech) != MechX(target) ||
MechY(mech) != MechY(target), "You need to be in the same hex!");
if (!can_pass_lock(mech->mynum, target->mynum, A_LENTER)) {
/* Trigger FAIL & AFAIL */
memset(fail_mesg, 0, sizeof(fail_mesg));
snprintf(fail_mesg, LBUF_SIZE, "That unit's bay doors are locked.");
did_it(player, target->mynum, A_FAIL, fail_mesg, 0, NULL, A_AFAIL,
(char **) NULL, 0);
return;
}
/* They passed the lock but does that mean there was no lock? */
memset(enter_lock, 0, sizeof(enter_lock));
atr_get_str(enter_lock, target->mynum, A_LENTER, &i, &j);
if (*enter_lock == '\0') {
/* Check their teams */
DOCHECK(MechTeam(mech) != MechTeam(target), "Locked. Damn !");
}
DOCHECK(fabs(MechSpeed(target)) > 0,
"Are you suicidal ? That thing is moving too fast !");
DOCHECK(!In_Character(mech->mynum) || !In_Character(target->mynum),
"You don't really see a way to get in there.");
/* New message system for when someone tries to embark
* but their sections are still cycling (or weapons) */
if ((tmp = MechFullNoRecycle(mech, CHECK_BOTH))) {
if (tmp == 1) {
notify(player, "You have weapons recycling!");
} else if (tmp == 2) {
notify(player, "You are still recovering from your previous action!");
} else {
notify(player, "error");
}
return;
}
DOCHECK((MechTons(mech) * 100) > CargoSpace(target),
"Not enough cargospace for you!");
if (MechCarrying(mech) > 0) {
DOCHECK(!(towee = getMech(MechCarrying(mech))),
"Internal error caused by towed unit! Contact a wizard!");
DOCHECK(MechTons(towee) > CarMaxTon(target),
"Your towed unit is too large for that class of carrier.");
DOCHECK(((MechTons(mech) + MechTons(towee)) * 100) > CargoSpace(target),
"Not enough cargospace for you and your towed unit!");
}
newmap = getMap(mech->mapindex);
if (MechType(mech) == CLASS_BSUIT) {
mech_notify(mech, MECHALL, tprintf("You climb into %s.", GetMechID(target)));
MechLOSBroadcast(mech, tprintf("climbs into %s.", GetMechID(target)));
} else {
mech_notify(mech, MECHALL, tprintf("You climb up the entry ramp into %s.",
GetMechID(target)));
MechLOSBroadcast(mech, tprintf("climbs up the entry ramp into %s.",
GetMechID(target)));
if (towee && MechCarrying(mech) > 0) {
mech_notify(towee, MECHALL, tprintf("You are drug up the entry ramp into %s.",
GetMechID(target)));
MechLOSBroadcast(towee, tprintf("is drug up the entry ramp into %s.",
GetMechID(target)));
}
}
MarkForLOSUpdate(mech);
MarkForLOSUpdate(target);
if (MechCritStatus(target) & HIDDEN) {
MechCritStatus(target) &= ~HIDDEN;
MechLOSBroadcast(target, "becomes visible as it is embarked into.");
}
mech_Rsetmapindex(GOD, (void *) mech, tprintf("%d", (int) -1));
mech_Rsetxy(GOD, (void *) mech, tprintf("%d %d", 0, 0));
loud_teleport(mech->mynum, target->mynum);
CargoSpace(target) -= (MechTons(mech) * 100);
Shutdown(mech);
if (towee && MechCarrying(mech) > 0) {
MarkForLOSUpdate(towee);
mech_Rsetmapindex(GOD, (void *) towee, tprintf("%d", (int) -1));
mech_Rsetxy(GOD, (void *) towee, tprintf("%d %d", 0, 0));
loud_teleport(towee->mynum, target->mynum);
CargoSpace(target) -= (MechTons(towee) * 100);
Shutdown(towee);
SetCarrying(mech, -1);
MechStatus(towee) &= ~TOWED;
}
correct_speed(target);
}
void autoeject(dbref player, MECH * mech, int tIsBSuit)
{
MECH *m;
dbref suit;
char *d;
/* If we're not IC, return */
if (!player || !In_Character(mech->mynum) || !mudconf.btech_ic ||
!In_Character(Location(mech->mynum)))
return;
/* Create the MW object */
suit = create_object(tprintf("MechWarrior - %s", Name(player)));
silly_atr_set(suit, A_XTYPE, "MECH");
s_Hardcode(suit);
handle_xcode(GOD, suit, 0, 1);
d = silly_atr_get(player, A_MWTEMPLATE);
if (!(m = getMech(suit))) {
SendError(tprintf
("Unable to create special obj for #%d's ejection.", player));
destroy_object(suit);
notify(player,
"Sorry, something serious went wrong, contact a Wizard (can't create RS object)");
return;
}
if (!mech_loadnew(GOD, m, (!d || !*d ||
!strcmp(d, "#-1")) ? "MechWarrior" : d)) {
SendError(tprintf
("Unable to load mechwarrior template for #%d's ejection. (%s)",
player, (!d || !*d) ? "Default template" : d));
destroy_object(suit);
notify(player,
"Sorry, something serious went wrong, contact a Wizard (can't load MWTemplate)");
return;
}
silly_atr_set(suit, A_MECHNAME, "MechWarrior");
MechTeam(m) = MechTeam(mech);
mech_Rsetmapindex(GOD, (void *) m, tprintf("%d", mech->mapindex));
mech_Rsetxy(GOD, (void *) m, tprintf("%d %d", MechX(mech),
MechY(mech)));
mech_Rsetteam(GOD, (void *) m, tprintf("%d", MechTeam(mech)));
/* Tele the MW to the map and player to the MW */
hush_teleport(suit, mech->mapindex);
hush_teleport(player, suit);
/* Init the sucker */
s_In_Character(suit);
initialize_pc(player, m);
MechPilot(m) = player;
MechTeam(m) = MechTeam(mech);
#ifdef COPY_CHANS_ON_EJECT
memcpy(m->freq, mech->freq, FREQS * sizeof(m->freq[0]));
memcpy(m->freqmodes, mech->freqmodes, FREQS * sizeof(m->freqmodes[0]));
#else
#ifdef RANDOM_CHAN_ON_EJECT
m->freq[0] = random() % 1000000;
notify(player, tprintf("Emergency radio channel set to %d.", m->freq[0]));
#endif
#endif
if (tIsBSuit) {
MechLOSBroadcast(m, "climbs out of one of the destroyed suits!");
notify(player, "You climb out of the unit!");
} else {
MechLOSBroadcast(m, tprintf("ejected from %s!", GetMechID(mech)));
initiate_ood(player, m, tprintf("%d %d %d", MechX(m), MechY(m),
150));
notify(player, "You eject from the unit!");
}
}