00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "config.h"
00013 #include <math.h>
00014
00015 #include "mech.h"
00016 #include "mech.events.h"
00017 #include "muxevent.h"
00018 #include "p.event.h"
00019 #include "p.mech.utils.h"
00020 #include "p.mech.los.h"
00021 #include "p.eject.h"
00022 #include "p.mech.pickup.h"
00023 #include "p.mech.update.h"
00024 #include "p.crit.h"
00025 #include "p.mech.tag.h"
00026 #include "p.bsuit.h"
00027 #include "p.mech.ice.h"
00028
00029 void mech_pickup(dbref player, void *data, char *buffer)
00030 {
00031 MECH *mech = (MECH *) data;
00032 MECH *target;
00033 dbref target_num;
00034 MAP *newmap;
00035 int argc, through_ice;
00036 char *args[4];
00037
00038 if(player != GOD)
00039 cch(MECH_USUAL);
00040 argc = mech_parseattributes(buffer, args, 1);
00041 #ifdef BT_MOVEMENT_MODES
00042 DOCHECK(MoveModeLock(mech),
00043 "You cannot tow currently in this movement mode!");
00044 #endif
00045 DOCHECK(argc != 1, "Invalid number of arguments.");
00046 target_num = FindTargetDBREFFromMapNumber(mech, args[0]);
00047 DOCHECK(target_num == -1, "That target is not in your line of sight.");
00048 target = getMech(target_num);
00049 DOCHECK(!target ||
00050 !InLineOfSight(mech, target, MechX(target), MechY(target),
00051 FaMechRange(mech, target)),
00052 "That target is not in your line of sight.");
00053 DOCHECK(MechSpecials2(target) & CARRIER_TECH
00054 && !MechSpecials2(mech) & CARRIER_TECH,
00055 "You cannot handle the mass on that carrier.");
00056 DOCHECK(CarryingClub(mech),
00057 "You can't pickup while you're carrying a club!");
00058 DOCHECK(Jumping(mech), "You can't pickup while jumping!");
00059 DOCHECK(Jumping(target),
00060 "What are you going to do? Grab it from mid air?");
00061 DOCHECK(Fallen(mech), "You are in no position to pick anything up!");
00062 DOCHECK(MechZ(mech) > (MechZ(target) + 3),
00063 "You are too high above the target.");
00064 DOCHECK(MechZ(mech) < MechZ(target) - 2,
00065 "You are too far below the target.");
00066 DOCHECK(MechX(mech) != MechX(target) ||
00067 MechY(mech) != MechY(target), "You need to be in the same hex!");
00068 DOCHECK(((MechZ(target) <= 0) && (MechRTerrain(target) == BRIDGE) &&
00069 (MechZ(mech) > 0)),
00070 "You need to be under the bridge to pick up this unit.");
00071 DOCHECK(Towed(target), "That target's already being towed by someone!");
00072 DOCHECK(MechSwarmTarget(target) == mech->mynum, "You can't grab hold!");
00073 DOCHECK(MechTons(mech) < 5 || (!In_Character(target->mynum) &&
00074 !Towable(target)), "You can't tow that!");
00075 DOCHECK(MechCritStatus(target) & HIDDEN,
00076 "You cannot pickup hiding targets....");
00077 DOCHECK(Burning(target), "You can't tow a burning unit!");
00078 if(MechType(target) == CLASS_MW) {
00079 pickup_mw(mech, target);
00080 return;
00081 } else {
00082 if(MechType(mech) == CLASS_MECH) {
00083 DOCHECKMA(MechIsQuad(mech),
00084 "You've got four left feet, you can't tow!");
00085 DOCHECKMA(SectIsDestroyed(mech, LARM),
00086 "Your left arm is destroyed, you can't pick up anything.");
00087 DOCHECKMA(SectIsDestroyed(mech, RARM),
00088 "Your right arm is destroyed, you can't pick up anything.");
00089 DOCHECKMA(!(OkayCritSectS(RARM, 3, HAND_OR_FOOT_ACTUATOR) &&
00090 OkayCritSectS(RARM, 0, SHOULDER_OR_HIP)) &&
00091 !(OkayCritSectS(LARM, 3, HAND_OR_FOOT_ACTUATOR) &&
00092 OkayCritSectS(LARM, 0, SHOULDER_OR_HIP)),
00093 "You need functioning arm to pick things up!");
00094 } else
00095 DOCHECK(!(MechSpecials(mech) & SALVAGE_TECH),
00096 "You can't pick that up in this MECH/VEHICLE");
00097 }
00098 DOCHECK(MechCarrying(mech) > 0, "You are already carrying a Mech");
00099 DOCHECK(((fabs(MechSpeed(mech)) > 1.0) ||
00100 (fabs((float) MechVerticalSpeed(mech)) > 1.0)),
00101 "You are moving too fast to attempt a pickup.");
00102 DOCHECK(IsDS(target), "You can't pick that up!");
00103 DOCHECK(MechMove(target) == MOVE_NONE, "That's simply immobile!");
00104 DOCHECK(MechTeam(mech) != MechTeam(target) &&
00105 Started(target), "You can't pick that up!");
00106
00107 if(Moving(target) && !Falling(target) && !OODing(target))
00108 StopMoving(target);
00109
00110 DOCHECK(Moving(target), "You can't pick up a moving target!");
00111
00112 mech_printf(target, MECHALL,
00113 "%s attaches his tow lines to you.",
00114 GetMechToMechID(target, mech));
00115 mech_printf(mech, MECHALL, "You attach your tow lines to %s.",
00116 GetMechToMechID(mech, target));
00117 if(MechCarrying(target) > 0)
00118 mech_dropoff(GOD, target, "");
00119 if((newmap = getMap(target->mapindex)))
00120 MechLOSBroadcasti(mech, target, "picks up %s!");
00121 SetCarrying(mech, target->mynum);
00122 MechSwarmTarget(target) = -1;
00123 if(MechType(target) == CLASS_MECH) {
00124 MechStatus(target) |= FALLEN;
00125 FallCentersTorso(target);
00126 StopStand(target);
00127 }
00128 MechStatus(target) |= TOWED;
00129 MechStatus(target) &= ~HULLDOWN;
00130 MechTankCritStatus(target) &= ~DUG_IN;
00131
00132 through_ice = (MechRTerrain(target) == ICE && MechZ(mech) >= 0 &&
00133 MechZ(target) < 0);
00134 MirrorPosition(mech, target, 0);
00135 if(through_ice) {
00136 if(MechZ(mech) == 0 && MechMove(mech) != MOVE_HOVER)
00137 drop_thru_ice(mech);
00138 else
00139 break_thru_ice(mech);
00140 }
00141 if(!Destroyed(target))
00142 Shutdown(target);
00143
00144
00145 correct_speed(mech);
00146
00147
00148 SendDebug(tprintf("#%d has picked up #%d", mech->mynum, target->mynum));
00149 }
00150
00151 void mech_attachcables(dbref player, void *data, char *buffer)
00152 {
00153 MECH *mech = (MECH *) data;
00154 MECH *towMech;
00155 MECH *target;
00156 dbref towMech_num;
00157 dbref target_num;
00158 int argc;
00159 char *args[3];
00160 char mechName[SBUF_SIZE];
00161 char towMechName[SBUF_SIZE];
00162 char targetName[SBUF_SIZE];
00163
00164 if(player != GOD)
00165 cch(MECH_USUAL);
00166
00167 argc = mech_parseattributes(buffer, args, 2);
00168 DOCHECK(argc != 2, "Invalid number of arguments.");
00169
00170 DOCHECK(OODing(mech),
00171 "You can't attach cables while floating in the air!");
00172
00173
00174 towMech_num = FindTargetDBREFFromMapNumber(mech, args[0]);
00175 DOCHECK(towMech_num == -1,
00176 "That towing unit is not in your line of sight.");
00177 towMech = getMech(towMech_num);
00178 DOCHECK(!towMech ||
00179 !InLineOfSight(mech, towMech, MechX(towMech), MechY(towMech),
00180 FaMechRange(mech, towMech)),
00181 "That towing unit is not in your line of sight.");
00182 DOCHECK(MechX(mech) != MechX(towMech) ||
00183 MechY(mech) != MechY(towMech),
00184 "You need to be in the same hex as the towing unit!");
00185 DOCHECK(Jumping(towMech),
00186 "That towing unit is currently flying through the air!");
00187 DOCHECK(MechZ(mech) != MechZ(towMech),
00188 "You must be on the same elevation as the towing unit!");
00189 DOCHECK(MechCarrying(towMech) > 0,
00190 "That towing unit is towing someone else!");
00191 DOCHECK(Towed(towMech),
00192 "That towing unit is already being towed by someone!");
00193 DOCHECK((MechType(towMech) == CLASS_MW), "That unit can not tow!");
00194 DOCHECK(MechMove(towMech) == MOVE_NONE, "That unit can not tow!");
00195 DOCHECK(MechTons(towMech) < 5, "That unit can not tow!");
00196 DOCHECK(Destroyed(towMech), "Destroyed units can not tow!");
00197 DOCHECK((MechTons(towMech) < 5) ||
00198 (!In_Character(towMech->mynum)), "That unit can not tow!");
00199 DOCHECK(Burning(towMech),
00200 "You can not attach tow cables to a burning unit!");
00201 DOCHECK((MechSpecials(towMech) & SALVAGE_TECH),
00202 "That is a dedicated towing unit and can pick up the target itself!");
00203 DOCHECK(((fabs(MechSpeed(towMech)) > 0.0) ||
00204 (fabs((float) MechVerticalSpeed(towMech)) > 0.0)),
00205 "The towing unit is moving to fast for you to grab the tow cables!");
00206 DOCHECK((MechTeam(towMech) != MechTeam(mech)),
00207 "You can not grab the tow cables from that unit!");
00208 DOCHECK((MechType(towMech) != CLASS_MECH) &&
00209 (MechType(towMech) != CLASS_VEH_GROUND),
00210 "That unit can not tow!");
00211
00212
00213 target_num = FindTargetDBREFFromMapNumber(mech, args[1]);
00214 DOCHECK(target_num == -1, "That target is not in your line of sight.");
00215 target = getMech(target_num);
00216 DOCHECK(!target ||
00217 !InLineOfSight(mech, target, MechX(target), MechY(target),
00218 FaMechRange(mech, target)),
00219 "That target is not in your line of sight.");
00220 DOCHECK(MechX(mech) != MechX(target) ||
00221 MechY(mech) != MechY(target),
00222 "You need to be in the same hex as the target!");
00223 DOCHECK(Jumping(target),
00224 "That target is currently flying through the air!");
00225 DOCHECK(MechZ(mech) != MechZ(target),
00226 "You must be on the same elevation as the target!");
00227 DOCHECK(MechCarrying(target) > 0, "That target is towing someone else!");
00228 DOCHECK(Towed(target), "That target is already being towed by someone!");
00229 DOCHECK((!In_Character(target->mynum) &&
00230 !Towable(target)), "That unit can not be towed!");
00231 DOCHECK(MechType(target) == CLASS_MW, "That unit can not be towed!");
00232 DOCHECK(MechMove(target) == MOVE_NONE, "That unit can not be towed!");
00233 DOCHECK(IsDS(target), "That unit can not be towed!");
00234 DOCHECK(Burning(target),
00235 "You can not attach tow cables to a burning unit!");
00236 DOCHECK(((fabs(MechSpeed(target)) > 0.0) ||
00237 (fabs((float) MechVerticalSpeed(target)) > 0.0)),
00238 "The target is moving to fast for you to attach the tow cables!");
00239 DOCHECK((MechTeam(target) != MechTeam(mech)) &&
00240 Started(target), "That unit can not be towed!");
00241
00242 if(Moving(target) && !Falling(target) && !OODing(target))
00243 StopMoving(target);
00244
00245 DOCHECK(Moving(target),
00246 "The target is moving to fast for you to attach the tow cables!");
00247
00248 strcpy(mechName, GetMechID(mech));
00249 strcpy(towMechName, GetMechID(towMech));
00250 strcpy(targetName, GetMechID(target));
00251
00252 mech_printf(target, MECHALL,
00253 "%s attaches tow lines from %s to you.", mechName,
00254 towMechName);
00255 mech_printf(towMech, MECHALL,
00256 "%s attaches your tow lines to %s.", mechName, targetName);
00257 mech_printf(mech, MECHALL, "You attach %s's tow lines to %s.",
00258 towMechName, targetName);
00259
00260 MechLOSBroadcast(mech,
00261 tprintf("attaches tow cables from %s to %s!",
00262 towMechName, targetName));
00263
00264 SetCarrying(towMech, target->mynum);
00265 MechSwarmTarget(target) = -1;
00266
00267 if(MechType(target) == CLASS_MECH) {
00268 MechStatus(target) |= FALLEN;
00269 FallCentersTorso(target);
00270 StopStand(target);
00271 }
00272
00273 MechStatus(target) |= TOWED;
00274 MechStatus(target) &= ~HULLDOWN;
00275 MechTankCritStatus(target) &= ~DUG_IN;
00276
00277 if(!Destroyed(target))
00278 Shutdown(target);
00279
00280
00281 correct_speed(towMech);
00282 }
00283
00284 void mech_detachcables(dbref player, void *data, char *buffer)
00285 {
00286 MECH *mech = (MECH *) data;
00287 MECH *towMech;
00288 MECH *target;
00289 dbref towMech_num;
00290 MAP *newmap;
00291 dbref aRef;
00292 int argc;
00293 char *args[2];
00294 char mechName[SBUF_SIZE];
00295 char towMechName[SBUF_SIZE];
00296 char targetName[SBUF_SIZE];
00297
00298 cch(MECH_USUAL);
00299
00300 argc = mech_parseattributes(buffer, args, 1);
00301 DOCHECK(argc != 1, "Invalid number of arguments.");
00302
00303 towMech_num = FindTargetDBREFFromMapNumber(mech, args[0]);
00304 DOCHECK(towMech_num == -1,
00305 "That towing unit is not in your line of sight.");
00306 towMech = getMech(towMech_num);
00307 DOCHECK(!towMech ||
00308 !InLineOfSight(mech, towMech, MechX(towMech), MechY(towMech),
00309 FaMechRange(mech, towMech)),
00310 "That towing unit is not in your line of sight.");
00311 DOCHECK(MechX(mech) != MechX(towMech) ||
00312 MechY(mech) != MechY(towMech),
00313 "You need to be in the same hex as the towing unit!");
00314 DOCHECK(MechZ(mech) != MechZ(towMech),
00315 "You must be on the same elevation as the towing unit!");
00316 DOCHECK(MechCarrying(towMech) <= 0, "That unit is not towing anyone!");
00317
00318 aRef = MechCarrying(towMech);
00319 SetCarrying(towMech, -1);
00320 target = getMech(aRef);
00321 DOCHECK(!target, "The towed unit was invalid!");
00322 MechStatus(target) &= ~TOWED;
00323
00324 strcpy(mechName, GetMechID(mech));
00325 strcpy(towMechName, GetMechID(towMech));
00326 strcpy(targetName, GetMechID(target));
00327
00328 mech_printf(mech, MECHALL,
00329 "You detach %s's tow lines from %s.", towMechName,
00330 targetName);
00331 mech_printf(towMech, MECHALL,
00332 "%s detaches your tow lines from %s.", mechName, targetName);
00333 mech_notify(target, MECHALL, "You have been released from towing.");
00334
00335 StopMoving(target);
00336 MechSpeed(target) = 0;
00337 MechDesiredSpeed(target) = 0;
00338
00339 MechLOSBroadcast(mech, tprintf("detaches %s's tow cables from %s!",
00340 towMechName, targetName));
00341
00342 if((newmap = getMap(target->mapindex))) {
00343 MechZ(target) = Elevation(newmap, MechX(towMech), MechY(towMech));
00344 }
00345
00346 correct_speed(towMech);
00347 }
00348
00349 void mech_dropoff(dbref player, void *data, char *buffer)
00350 {
00351 MECH *mech = (MECH *) data;
00352 MECH *target;
00353 MAP *newmap;
00354 dbref aRef;
00355 int x, y;
00356
00357 if(player != GOD)
00358 cch(MECH_USUAL);
00359
00360 DOCHECK(MechCarrying(mech) <= 0, "You aren't carrying a mech!");
00361 aRef = MechCarrying(mech);
00362 SetCarrying(mech, -1);
00363 target = getMech(aRef);
00364 DOCHECK(!target, "You were towing invalid target!");
00365 MechStatus(target) &= ~TOWED;
00366 mech_notify(mech, MECHALL, "You drop the mech you were carrying.");
00367 mech_notify(target, MECHALL, "You have been released from towing.");
00368
00369 StopMoving(target);
00370 MechSpeed(target) = 0;
00371 MechDesiredSpeed(target) = 0;
00372
00373 if((newmap = getMap(target->mapindex))) {
00374 MechLOSBroadcasti(mech, target, "drops %s!");
00375 if((x = MechZ(target)) > ((y =
00376 Elevation(newmap, MechX(target),
00377 MechY(target))) + 2)) {
00378 mech_notify(mech, MECHALL,
00379 "Maybe you should have done this closer to the ground.");
00380 mech_notify(target, MECHALL,
00381 "You wish he had done that a might bit closer to the ground.");
00382 MechLOSBroadcast(target, "falls through the sky.");
00383 MECHEVENT(target, EVENT_FALL, mech_fall_event, FALL_TICK, -1);
00384 } else {
00385 MechZ(target) = Elevation(newmap, MechX(mech), MechY(mech));
00386 }
00387 }
00388 correct_speed(mech);
00389 SendDebug(tprintf("#%d has dropped off #%d", mech->mynum, target->mynum));
00390 }