00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <math.h>
00014 #include <sys/file.h>
00015
00016 #include "mech.h"
00017 #include "failures.h"
00018 #include "mech.events.h"
00019 #include "mech.ice.h"
00020 #include "p.mech.ecm.h"
00021 #include "p.mech.tag.h"
00022 #include "p.mech.combat.h"
00023 #include "p.mech.combat.misc.h"
00024 #include "p.mech.damage.h"
00025 #include "p.mech.fire.h"
00026 #include "p.mech.startup.h"
00027 #include "p.mech.utils.h"
00028 #include "p.mech.update.h"
00029 #include "p.btechstats.h"
00030 #include "p.mech.physical.h"
00031 #include "p.bsuit.h"
00032 #include "p.mine.h"
00033 #include "p.mech.lite.h"
00034 #include "p.mech.pickup.h"
00035
00036 extern int arc_override;
00037
00038 int fiery_death(MECH * mech)
00039 {
00040 if(MechTerrain(mech) == FIRE) {
00041 if(is_aero(mech))
00042 return 0;
00043 if(MechMove(mech) == MOVE_VTOL)
00044 return 0;
00045 if(Destroyed(mech))
00046 return 0;
00047
00048
00049
00050 if(MechType(mech) == CLASS_MW) {
00051 mech_notify(mech, MECHALL, "You feel a tad bit too warm..");
00052 mech_notify(mech, MECHALL, "You faint.");
00053 DestroyMech(mech, mech, 0);
00054 return 1;
00055 }
00056
00057
00058 return 0;
00059 heat_effect(NULL, mech, 0, 0);
00060 if(Destroyed(mech))
00061 return 1;
00062 }
00063 return 0;
00064 }
00065
00066 int bridge_w_elevation(MECH * mech)
00067 {
00068 return -1;
00069 }
00070
00071 void bridge_set_elevation(MECH * mech)
00072 {
00073 if(MechZ(mech) < (MechUpperElevation(mech) - MoveMod(mech))) {
00074 if(Overwater(mech))
00075 MechZ(mech) = 0;
00076 else
00077 MechZ(mech) = bridge_w_elevation(mech);
00078 return;
00079 }
00080 MechZ(mech) = MechUpperElevation(mech);
00081 }
00082
00083 int DSOkToNotify(MECH * mech)
00084 {
00085 if(DSLastMsg(mech) > muxevent_tick ||
00086 (muxevent_tick - DSLastMsg(mech)) >= DS_SPAM_TIME) {
00087 DSLastMsg(mech) = muxevent_tick;
00088 return 1;
00089 }
00090 return 0;
00091 }
00092
00093 enum {
00094 JUMP, WALK_WALL, WALK_DROP, HIT_UNDER_BRIDGE, WALK_BACK
00095 };
00096
00097 int collision_check(MECH * mech, int mode, int le, int lt)
00098 {
00099 int e;
00100 MAP *mech_map = getMap(mech->mapindex);
00101
00102 if(Overwater(mech) && le < 0)
00103 le = 0;
00104 e = MechElevation(mech);
00105 if(MechRTerrain(mech) == ICE)
00106 if(le >= 0)
00107 e = 0;
00108 if(le < (MechUpperElevation(mech) - MoveMod(mech)) && lt == BRIDGE) {
00109 if(Overwater(mech))
00110 le = 0;
00111 else
00112 le = bridge_w_elevation(mech);
00113 }
00114 if(e < 0 && Overwater(mech))
00115 e = 0;
00116 switch (mode) {
00117 case JUMP:
00118 if(MechRTerrain(mech) == BRIDGE) {
00119 if(MechZ(mech) < 0)
00120 return 1;
00121 if(MechZ(mech) == (e - 1))
00122 return 1;
00123 return 0;
00124 } else
00125 return (MechZ(mech) < e);
00126 case WALK_DROP:
00127 return (le - e) > MoveMod(mech);
00128 case WALK_WALL:
00129 if((MechMove(mech) == MOVE_HOVER) &&
00130 (MechRTerrain(mech) == BRIDGE) && (((lt == ICE) ||
00131 (lt == WATER)) || ((le == 0)
00132 && (lt ==
00133 BRIDGE))))
00134 {
00135 return 0;
00136 } else {
00137 return (e - le) > MoveMod(mech);
00138 }
00139 case WALK_BACK:
00140 if(MechMove(mech) != MOVE_TRACK && MechType(mech) != CLASS_VTOL)
00141 return (MechSpeed(mech) < 0 ? abs((le - e)) : 0);
00142 case HIT_UNDER_BRIDGE:
00143 if((lt == BRIDGE) && (MechRTerrain(mech) == BRIDGE) && (le == 0)
00144 && (Elevation(mech_map, MechLastX(mech), MechLastY(mech)) != 0)
00145 && (Elevation(mech_map, MechX(mech), MechY(mech)) == 1))
00146 return 1;
00147 else
00148 return 0;
00149 }
00150 return 0;
00151 }
00152
00153 void CheckNavalHeight(MECH * mech, int oz);
00154
00155 void move_mech(MECH * mech)
00156 {
00157 float newx = 0.0, newy = 0.0, dax, day;
00158 float xy_charge_dist, xscale;
00159 float jump_pos;
00160
00161 #ifdef ODDJUMP
00162 float rjump_pos, midmod;
00163 #endif
00164 int x, y, upd_z = 0;
00165 int last_z = 0;
00166 MECH *target;
00167 MAP *mech_map;
00168 int oi, oz;
00169 int iced = 0;
00170
00171
00172
00173 char message_buffer[MBUF_SIZE];
00174
00175 oz = MechZ(mech);
00176 mech_map = getMap(mech->mapindex);
00177
00178 if(!mech_map && MechPilot(mech) >= 0)
00179 mech_map = ValidMap(MechPilot(mech), mech->mapindex);
00180
00181
00182
00183 if(!mech_map) {
00184
00185 mech_notify(mech, MECHALL,
00186 "You are on an invalid map! Map index reset!");
00187 MechCocoon(mech) = 0;
00188
00189 if(Jumping(mech))
00190 mech_land(MechPilot(mech), (void *) mech, "");
00191
00192 mech_shutdown(MechPilot(mech), (void *) mech, "");
00193
00194 snprintf(message_buffer, MBUF_SIZE,
00195 "move_mech:invalid map:Mech: %d Index: %d", mech->mynum,
00196 mech->mapindex);
00197 SendError(message_buffer);
00198 mech->mapindex = -1;
00199 return;
00200 }
00201
00202
00203 if(MechX(mech) < 0 || MechX(mech) >= mech_map->map_width ||
00204 MechLastX(mech) < 0 || MechLastX(mech) >= mech_map->map_width ||
00205 MechY(mech) < 0 || MechY(mech) >= mech_map->map_height ||
00206 MechLastY(mech) < 0 || MechLastY(mech) >= mech_map->map_height) {
00207
00208 mech_notify(mech, MECHALL,
00209 "You are at an invalid map location! Map index reset!");
00210 MechCocoon(mech) = 0;
00211
00212 if(Jumping(mech))
00213 mech_land(MechPilot(mech), (void *) mech, "");
00214
00215 mech_shutdown(MechPilot(mech), (void *) mech, "");
00216
00217 snprintf(message_buffer, MBUF_SIZE,
00218 "move_mech:invalid map:Mech: %d Index: %d", mech->mynum,
00219 mech->mapindex);
00220 SendError(message_buffer);
00221
00222 mech->mapindex = -1;
00223 return;
00224 }
00225
00226
00227 if(mudconf.btech_newcharge && MechChargeTarget(mech) > 0) {
00228 if(MechChargeTimer(mech)++ > CHARGE_TIMER_LIMIT) {
00229 mech_notify(mech, MECHALL, "Charge timed out, charge reset.");
00230 MechChargeTarget(mech) = -1;
00231 MechChargeTimer(mech) = 0;
00232 MechChargeDistance(mech) = 0;
00233 }
00234 }
00235
00239
00240 switch (MechMove(mech)) {
00241 case MOVE_BIPED:
00242 case MOVE_QUAD:
00243
00244
00245 if(Jumping(mech)) {
00246 MarkForLOSUpdate(mech);
00247 FindComponents(JumpSpeed(mech, mech_map) * MOVE_MOD *
00248 MAPMOVEMOD(mech_map), MechJumpHeading(mech), &newx,
00249 &newy);
00250 MechFX(mech) += newx;
00251 MechFY(mech) += newy;
00252 jump_pos = length_hypotenuse((MechFX(mech) - MechStartFX(mech)),
00253 (MechFY(mech) - MechStartFY(mech)));
00254
00257 #ifndef ODDJUMP
00258 MechFZ(mech) = ((4 * JumpSpeedMP(mech, mech_map) * ZSCALE)
00259 / (MechJumpLength(mech) * MechJumpLength(mech))) *
00260 jump_pos * (MechJumpLength(mech) - jump_pos) +
00261 MechStartFZ(mech) + jump_pos * (MechEndFZ(mech)
00262 -
00263 MechStartFZ(mech)) /
00264 (MechJumpLength(mech) * HEXLEVEL);
00265 #else
00266 rjump_pos = MechJumpLength(mech) - jump_pos;
00267 if(rjump_pos < 0.0)
00268 rjump_pos = 0.0;
00269
00270
00271
00272
00273
00274 midmod = jump_pos / MechJumpLength(mech);
00275 midmod = (midmod - 0.5) * 2;
00276 if(MechJumpTop(mech) >= (1 + JumpSpeedMP(mech, mech_map))) {
00277 midmod = (1.0 - (midmod * midmod)) * MechJumpTop(mech);
00278 } else {
00279 midmod = (1.0 - (midmod * midmod * midmod * midmod)) *
00280 MechJumpTop(mech);
00281 }
00282
00283 MechFZ(mech) = (rjump_pos * MechStartFZ(mech) +
00284 jump_pos * MechEndFZ(mech)) /
00285 MechJumpLength(mech) + midmod * ZSCALE;
00286 #endif
00287
00288 MechZ(mech) = (int) (MechFZ(mech) / ZSCALE + 0.5);
00289
00290 #ifdef JUMPDEBUG
00291 snprintf(message_buffer, MBUF_SIZE,
00292 "#%d: %d, %d, %d (%d, %d, %d)",
00293 mech->mynum, MechX(mech), MechY(mech), MechZ(mech),
00294 (int) MechFX(mech), (int) MechFY(mech),
00295 (int) MechFZ(mech));
00296 SendDebug(message_buffer);
00297 #endif
00298
00299
00302 if(MechRTerrain(mech) == BRIDGE &&
00303 collision_check(mech, JUMP, 0, 0) && MechZ(mech) > 0) {
00304
00305 mech_notify(mech, MECHALL,
00306 "CRASH! You crash into the bridge!");
00307 MechLOSBroadcast(mech, "crashes into the bridge!");
00308 MechFalls(mech, 1, 0);
00309 return;
00310 }
00311
00312
00313 if((MechX(mech) == MechGoingX(mech)) &&
00314 (MechY(mech) == MechGoingY(mech))) {
00315
00316
00317
00318 MapCoordToRealCoord(MechX(mech), MechY(mech), &dax, &day);
00319
00321
00322
00323 #ifdef ODDJUMP
00324 if(length_hypotenuse(dax - MechStartFX(mech),
00325 day - MechStartFY(mech)) <=
00326 length_hypotenuse(MechFX(mech) - MechStartFX(mech),
00327 MechFY(mech) - MechStartFY(mech))) {
00328
00329 LandMech(mech);
00330 MechFX(mech) = (float) dax;
00331 MechFY(mech) = (float) day;
00332 }
00333 #else
00334 LandMech(mech);
00335 MechFX(mech) = (float) dax;
00336 MechFY(mech) = (float) day;
00337 #endif
00338 }
00339
00340
00341 if(MechRTerrain(mech) == ICE) {
00342 if(oz < -1 && MechZ(mech) >= -1)
00343 break_thru_ice(mech);
00344 else if(oz >= -1 && MechZ(mech) < -1)
00345 drop_thru_ice(mech);
00346 }
00347
00348 } else if(fabs(MechSpeed(mech)) > 0.0) {
00349
00350
00351 FindComponents(MechSpeed(mech) * MOVE_MOD *
00352 MAPMOVEMOD(mech_map),
00353 MechLateral(mech) + MechFacing(mech), &newx,
00354 &newy);
00355 MechFX(mech) += newx;
00356 MechFY(mech) += newy;
00357
00358 upd_z = 1;
00359
00360
00361 if(MechChargeTarget(mech) > 0 && mudconf.btech_newcharge) {
00362 xscale = 1.0 / SCALEMAP;
00363 xscale = xscale * xscale;
00364 xy_charge_dist =
00365 sqrt(xscale * newx * newx + YSCALE2 * newy * newy);
00366 MechChargeDistance(mech) += xy_charge_dist;
00367 }
00368
00369 } else {
00370
00371
00372 return;
00373 }
00374 break;
00375
00376 case MOVE_TRACK:
00377 case MOVE_WHEEL:
00378
00381
00382 if(fabs(MechSpeed(mech)) > 0.0) {
00383
00386 #ifndef BT_MOVEMENT_MODES
00387 FindComponents(MechSpeed(mech) * MOVE_MOD *
00388 MAPMOVEMOD(mech_map), MechFacing(mech), &newx,
00389 &newy);
00390 #else
00391 FindComponents(MechSpeed(mech) * MOVE_MOD *
00392 MAPMOVEMOD(mech_map),
00393 MechLateral(mech) + MechFacing(mech), &newx,
00394 &newy);
00395 #endif
00396 MechFX(mech) += newx;
00397 MechFY(mech) += newy;
00398 upd_z = 1;
00399
00400
00401 if(MechChargeTarget(mech) > 0 && mudconf.btech_newcharge) {
00402 xscale = 1.0 / SCALEMAP;
00403 xscale = xscale * xscale;
00404 xy_charge_dist =
00405 sqrt(xscale * newx * newx + YSCALE2 * newy * newy);
00406 MechChargeDistance(mech) += xy_charge_dist;
00407 }
00408
00409 } else {
00410
00411
00412 return;
00413 }
00414 break;
00415
00416 case MOVE_HOVER:
00417
00418
00419 if(fabs(MechSpeed(mech)) > 0.0) {
00420
00422 #ifndef BT_MOVEMENT_MODES
00423 FindComponents(MechSpeed(mech) * MOVE_MOD *
00424 MAPMOVEMOD(mech_map), MechFacing(mech), &newx,
00425 &newy);
00426 #else
00427 FindComponents(MechSpeed(mech) * MOVE_MOD *
00428 MAPMOVEMOD(mech_map),
00429 MechLateral(mech) + MechFacing(mech), &newx,
00430 &newy);
00431 #endif
00432 MechFX(mech) += newx;
00433 MechFY(mech) += newy;
00434 upd_z = 1;
00435
00436
00437 if(MechChargeTarget(mech) > 0 && mudconf.btech_newcharge) {
00438 xscale = 1.0 / SCALEMAP;
00439 xscale = xscale * xscale;
00440 xy_charge_dist =
00441 sqrt(xscale * newx * newx + YSCALE2 * newy * newy);
00442 MechChargeDistance(mech) += xy_charge_dist;
00443 }
00444
00445 } else {
00446
00447
00448 return;
00449 }
00450 break;
00451
00452 case MOVE_VTOL:
00453
00454
00455 if(Landed(mech))
00456 return;
00457
00458
00461 case MOVE_SUB:
00462
00463 MarkForLOSUpdate(mech);
00464 FindComponents(MechSpeed(mech) * MOVE_MOD * MAPMOVEMOD(mech_map),
00465 MechFacing(mech), &newx, &newy);
00466 MechFX(mech) += newx;
00467 MechFY(mech) += newy;
00468 MechFZ(mech) += MechVerticalSpeed(mech) * MOVE_MOD;
00469 MechZ(mech) = MechFZ(mech) / ZSCALE;
00470 break;
00471
00472 case MOVE_FLY:
00473
00474
00475 if(!Landed(mech)) {
00476
00477 MarkForLOSUpdate(mech);
00478 MechFZ(mech) += MechStartFZ(mech) * MOVE_MOD;
00479 MechZ(mech) = MechFZ(mech) / ZSCALE;
00480 MechFX(mech) += MechStartFX(mech) * MOVE_MOD;
00481 MechFY(mech) += MechStartFY(mech) * MOVE_MOD;
00482
00486 if(IsDS(mech)) {
00487
00488
00489 if(MechZ(mech) < 10 && oz >= 10)
00490 DS_LandWarning(mech, 1);
00491 else if(MechZ(mech) < 50 && oz >= 50)
00492 DS_LandWarning(mech, 0);
00493 else if(MechZ(mech) < 100 && oz >= 100) {
00494
00495 if(abs(MechDesiredAngle(mech)) != 90) {
00496 if(DSOkToNotify(mech)) {
00497 mech_notify(mech, MECHALL, "As the craft enters "
00498 "the lower atmosphere, its nose rises up "
00499 "for a clean landing..");
00500 snprintf(message_buffer, MBUF_SIZE,
00501 "starts descending towards %d, %d..",
00502 MechX(mech), MechY(mech));
00503 MechLOSBroadcast(mech, message_buffer);
00504 } else {
00505 mech_notify(mech, MECHALL, "Due to low altitude, "
00506 "climbing angle set to 90 degrees.");
00507 }
00508 MechDesiredAngle(mech) = 90;
00509 }
00510 MechStartFX(mech) = 0.0;
00511 MechStartFY(mech) = 0.0;
00512 DS_LandWarning(mech, -1);
00513 }
00514 }
00515
00516 } else {
00517
00518
00519 if(!(fabs(MechSpeed(mech)) > 0.0))
00520 return;
00521
00522 FindComponents(MechSpeed(mech) * MOVE_MOD *
00523 MAPMOVEMOD(mech_map), MechFacing(mech), &newx,
00524 &newy);
00525 MechFX(mech) += newx;
00526 MechFY(mech) += newy;
00527 upd_z = 1;
00528 }
00529 break;
00530
00531 case MOVE_HULL:
00532 case MOVE_FOIL:
00533
00534 if(fabs(MechSpeed(mech)) > 0.0) {
00535
00536 FindComponents(MechSpeed(mech) * MOVE_MOD *
00537 MAPMOVEMOD(mech_map), MechFacing(mech), &newx,
00538 &newy);
00539 MechFX(mech) += newx;
00540 MechFY(mech) += newy;
00541 MechZ(mech) = 0;
00542 MechFZ(mech) = 0.0;
00543
00544 } else {
00545
00546
00547 return;
00548 }
00549 break;
00550 }
00551
00552
00553
00554 MechLastX(mech) = MechX(mech);
00555 MechLastY(mech) = MechY(mech);
00556 last_z = MechZ(mech);
00557
00558 RealCoordToMapCoord(&MechX(mech), &MechY(mech), MechFX(mech),
00559 MechFY(mech));
00560
00562
00563 #ifdef ODDJUMP
00564 if(Jumping(mech) && MechLastX(mech) == MechGoingX(mech) &&
00565 MechLastY(mech) == MechGoingY(mech) &&
00566 (MechX(mech) != MechLastX(mech) || MechY(mech) != MechLastY(mech))) {
00567
00568 LandMech(mech);
00569 MechFX(mech) -= newx;
00570 MechFY(mech) -= newy;
00571 MechFZ(mech) = MechEndFZ(mech);
00572 MechX(mech) = MechGoingX(mech);
00573 MechY(mech) = MechGoingY(mech);
00574 MapCoordToRealCoord(MechX(mech), MechY(mech), &MechFX(mech),
00575 &MechFY(mech));
00576 MechZ(mech) = MechFZ(mech) / ZSCALE;
00577 }
00578 #endif
00579
00580
00581 oi = mech->mapindex;
00582
00583
00584 CheckEdgeOfMap(mech);
00585
00586
00587 if(mech->mapindex != oi)
00588 mech_map = getMap(mech->mapindex);
00589
00590
00591 if(oi != mech->mapindex || MechLastX(mech) != MechX(mech) ||
00592 MechLastY(mech) != MechY(mech)) {
00593
00594
00595 if(!mech || !mech_map) {
00596
00597 snprintf(message_buffer, MBUF_SIZE,
00598 "Invalide pointer (%s) in move_mech()",
00599 (!mech ? "mech" : !mech_map ? "mech_map" : "weird...."));
00600 SendError(message_buffer);
00601
00602 if(mech) {
00603
00604
00605 mech_notify(mech, MECHALL,
00606 "You are on an invalid map! Map index reset!");
00607 MechCocoon(mech) = 0;
00608
00609 if(Jumping(mech))
00610 mech_land(MechPilot(mech), (void *) mech, "");
00611
00612 mech_shutdown(MechPilot(mech), (void *) mech, "");
00613 snprintf(message_buffer, MBUF_SIZE,
00614 "move_mech:invalid map:Mech: %d Index: %d",
00615 mech->mynum, mech->mapindex);
00616 SendError(message_buffer);
00617 mech->mapindex = -1;
00618 }
00619 return;
00620 }
00621
00622
00623 if(MechCritStatus(mech) & HIDDEN) {
00624 mech_notify(mech, MECHALL,
00625 "You move too much and break your cover!");
00626 MechLOSBroadcast(mech, "breaks from its cover.");
00627 MechCritStatus(mech) &= ~(HIDDEN);
00628 }
00629
00630 StopHiding(mech);
00631
00632 x = MechX(mech);
00633 y = MechY(mech);
00634 MechTerrain(mech) = GetTerrain(mech_map, x, y);
00635 MechElev(mech) = GetElev(mech_map, x, y);
00636
00637
00638 if(upd_z) {
00639
00640
00641 if(MechRTerrain(mech) == ICE) {
00642 if(oz < -1 && MechZ(mech) >= -1)
00643 break_thru_ice(mech);
00644 else if(MechZ(mech) == 0)
00645 if(possibly_drop_thru_ice(mech))
00646 iced = 1;
00647 }
00648
00649
00650 DropSetElevation(mech, 0);
00651
00652
00653 if(MechType(mech) == CLASS_MECH && MechRTerrain(mech) == ICE
00654 && oz == -1 && MechZ(mech) == -1) {
00655
00656 MechZ(mech) = 0;
00657 MechFZ(mech) = MechZ(mech) * ZSCALE;
00658 }
00659 }
00660
00661 if(!iced)
00662 NewHexEntered(mech, mech_map, newx, newy, last_z);
00663
00664 if(MechX(mech) == x && MechY(mech) == y) {
00665
00666 MarkForLOSUpdate(mech);
00667 MechFloods(mech);
00668 water_extinguish_inferno(mech);
00669 steppable_base_check(mech, x, y);
00670
00671
00672 if(In_Character(mech->mynum)) {
00673 MechHexes(mech)++;
00674 if(!(MechHexes(mech) % PIL_XP_EVERY_N_STEPS))
00675 if(RGotPilot(mech))
00676 AccumulatePilXP(MechPilot(mech), mech, 1, 0);
00677 }
00678
00679
00680 domino_space(mech, 0);
00681 }
00682 }
00683
00684
00685 if((MechMove(mech) == MOVE_VTOL || is_aero(mech)) && !Landed(mech))
00686 CheckVTOLHeight(mech);
00687
00688
00689 if(MechType(mech) == CLASS_VEH_NAVAL)
00690 CheckNavalHeight(mech, oz);
00691
00692
00693 if(MechChargeTarget(mech) != -1) {
00694
00695
00696 target = getMech(MechChargeTarget(mech));
00697 if(target) {
00698
00699 if(FaMechRange(mech, target) < CHARGE_DIST_TRIGGER) {
00700 ChargeMech(mech, target);
00701 MechChargeTarget(mech) = -1;
00702 MechChargeTimer(mech) = 0;
00703 MechChargeDistance(mech) = 0;
00704 }
00705
00706 } else {
00707 mech_notify(mech, MECHPILOT, "Invalid CHARGE target!");
00708 MechChargeTarget(mech) = -1;
00709 MechChargeDistance(mech) = 0;
00710 MechChargeTimer(mech) = 0;
00711 }
00712 }
00713
00714
00715 if(MechCarrying(mech) > 0) {
00716 target = getMech(MechCarrying(mech));
00717 if(target && target->mapindex == mech->mapindex) {
00718 MirrorPosition(mech, target, 0);
00719 SetRFacing(target, MechRFacing(mech));
00720 }
00721 }
00722
00723
00724
00725 BSuitMirrorSwarmedTarget(mech_map, mech);
00726
00727
00728
00729 fiery_death(mech);
00730 }
00731
00732 void CheckNavalHeight(MECH * mech, int oz)
00733 {
00734 if(MechRTerrain(mech) != WATER && MechRTerrain(mech) != ICE &&
00735 MechRTerrain(mech) != BRIDGE) {
00736 MechSpeed(mech) = 0.0;
00737 MechVerticalSpeed(mech) = 0;
00738 MechDesiredSpeed(mech) = 0.0;
00739 SetFacing(mech, 0);
00740 MechDesiredFacing(mech) = 0;
00741 return;
00742 }
00743 if(!oz && MechZ(mech) && MechElev(mech) > 1) {
00744 MarkForLOSUpdate(mech);
00745 MechZ(mech) = 0;
00746 MechLOSBroadcast(mech, "dives!");
00747 MechZ(mech) = -1;
00748 }
00749 if(MechFZ(mech) > 0.0) {
00750 if(MechVerticalSpeed(mech) > 0 && !MechZ(mech) && oz < 0) {
00751 mech_notify(mech, MECHALL,
00752 "Your sub has reached surface and stops rising.");
00753 MechLOSBroadcast(mech, tprintf("surfaces at %d,%d!",
00754 MechX(mech), MechY(mech)));
00755
00756 }
00757 MechZ(mech) = 0;
00758 MechFZ(mech) = 0.0;
00759 if(MechVerticalSpeed(mech) > 0)
00760 MechVerticalSpeed(mech) = 0;
00761 return;
00762 }
00763 if(MechZ(mech) <= (MechLowerElevation(mech))) {
00764 MechZ(mech) = MIN(0, MechLowerElevation(mech) + 1);
00765 if(MechElevation(mech) > 0)
00766 SendError(tprintf
00767 ("Oddity: #%d managed to wind up on '%c' (%d elev.)",
00768 mech->mynum, MechTerrain(mech), MechElev(mech)));
00769 MechFZ(mech) = ((5.0 * MechZ(mech) - 4) * ZSCALE) / 5.0;
00770 if(MechMove(mech) == MOVE_SUB) {
00771 if(MechVerticalSpeed(mech) < 0) {
00772 MechVerticalSpeed(mech) = 0;
00773 mech_notify(mech, MECHALL,
00774 "The sub has reached bottom and stops diving.");
00775 }
00776 #if 0
00777 else
00778 mech_notify(mech, MECHALL, "The sub has reached bottom.");
00779 #endif
00780 }
00781 }
00782 }
00783
00784 void CheckVTOLHeight(MECH * mech)
00785 {
00786 if(InWater(mech) && MechZ(mech) <= 0) {
00787 mech_notify(mech, MECHALL, "You crash your vehicle into the water!");
00788 mech_notify(mech, MECHALL, "Water pours into the cockpit....glub glub!");
00789 MechLOSBroadcast(mech, "splashes into the water!");
00790 DestroyMech(mech, mech, 0);
00791 return;
00792 }
00793
00794 if((MechZ(mech) >= ORBIT_Z) && !is_aero(mech)) {
00795 mech_notify(mech, MECHALL, "You cannot achieve orbit! Vertical movement halted!");
00796 MechZ(mech) = ORBIT_Z - 1;
00797 MechFZ(mech) = ZSCALE * MechZ(mech);
00798 MechVerticalSpeed(mech) = 0.0;
00799 return;
00800 }
00801
00802 if(MechZ(mech) >= MechElevation(mech))
00803 return;
00804 if(MechRTerrain(mech) == BRIDGE)
00805 if(MechZ(mech) != (MechElevation(mech) - 1))
00806 return;
00807 aero_land(MechPilot(mech), mech, "");
00808 if(Landed(mech))
00809 return;
00810 mech_notify(mech, MECHALL,
00811 "CRASH! You smash your toy into the ground!");
00812 MechLOSBroadcast(mech, "crashes into the ground!");
00813 MechFalls(mech, 1 + fabs(MechVerticalSpeed(mech) / MP1), 0);
00814
00815
00816 MechZ(mech) = MechElevation(mech);
00817 MechFZ(mech) = ZSCALE * MechZ(mech);
00818 MechSpeed(mech) = 0.0;
00819 MechVerticalSpeed(mech) = 0.0;
00820 MechStatus(mech) |= LANDED;
00821
00822
00823 }
00824
00825 void UpdateHeading(MECH * mech)
00826 {
00827 int offset;
00828 int normangle;
00829 int mw_mod = 1;
00830 float maxspeed, omaxspeed;
00831 MAP *mech_map;
00832
00833 if(MechFacing(mech) == MechDesiredFacing(mech))
00834 return;
00835 maxspeed = MMaxSpeed(mech);
00836 if(is_aero(mech))
00837 maxspeed = maxspeed * ACCEL_MOD;
00838 if((MechHeat(mech) >= 9.) && (MechSpecials(mech) & TRIPLE_MYOMER_TECH))
00839 maxspeed += 1.5 * MP1;
00840 omaxspeed = maxspeed;
00841 normangle = MechRFacing(mech) - SHO2FSIM(MechDesiredFacing(mech));
00842 if(MechType(mech) == CLASS_MW || MechType(mech) == CLASS_BSUIT)
00843 mw_mod = 60;
00844 else if(MechIsQuad(mech))
00845 mw_mod = 2;
00846 if(mudconf.btech_fasaturn) {
00847 #define FASA_TURN_MOD 3/2
00848 if(Jumping(mech))
00849 offset = 2 * SHO2FSIM(1) * 2 * 360 * FASA_TURN_MOD / 60;
00850 else {
00851 float ts = MechSpeed(mech);
00852
00853 if(ts < 0) {
00854 maxspeed = maxspeed * 2.0 / 3.0;
00855 ts = -ts;
00856 }
00857 if(ts > maxspeed || maxspeed < 0.1)
00858 offset = 0;
00859 else {
00860 offset = SHO2FSIM(1) * 2 * 360 * FASA_TURN_MOD / 60 * (maxspeed - ts) * (omaxspeed / maxspeed) * mw_mod * MP_PER_KPH / 6;
00861 }
00862 }
00863 } else {
00864 if(Jumping(mech)) {
00865 mech_map = FindObjectsData(mech->mapindex);
00866 offset = SHO2FSIM(1) * 6 * JumpSpeedMP(mech, mech_map) * mw_mod;
00867 } else if(fabs(MechSpeed(mech)) < 1.0)
00868 offset = SHO2FSIM(1) * 3 * maxspeed * MP_PER_KPH * mw_mod;
00869 else {
00870 offset = SHO2FSIM(1) * 2 * maxspeed * MP_PER_KPH * mw_mod;
00871 if((SHO2FSIM(abs(normangle)) > offset) &&
00872 IsRunning(MechSpeed(mech), maxspeed)) {
00873 if(MechSpeed(mech) > maxspeed)
00874 offset -= offset / 2 * maxspeed / MechSpeed(mech);
00875 else
00876 offset -=
00877 offset / 2 * (3.0 * MechSpeed(mech) / maxspeed - 2.0);
00878 }
00879 }
00880 }
00881
00882 offset = offset * MOVE_MOD;
00883 #ifdef BT_MOVEMENT_MODES
00884 if(GetTurnMode(mech)
00885 && HasBoolAdvantage(MechPilot(mech), "maneuvering_ace"))
00886 offset = (offset * 3) / 2;
00887 if(MechStatus2(mech) & (SPRINTING | EVADING)
00888 && !HasBoolAdvantage(MechPilot(mech), "maneuvering_ace")) {
00889 if(HasBoolAdvantage(MechPilot(mech), "speed_demon"))
00890 offset = (offset * 2) / 3;
00891 else
00892 offset = (offset / 2);
00893 }
00894 #endif
00895 if(normangle < 0)
00896 normangle += SHO2FSIM(360);
00897 if(IsDS(mech) && offset >= SHO2FSIM(10))
00898 offset = SHO2FSIM(10);
00899 if(normangle > SHO2FSIM(180)) {
00900 AddRFacing(mech, offset);
00901 if(MechFacing(mech) >= 360)
00902 AddFacing(mech, -360);
00903 normangle += offset;
00904 if(normangle >= SHO2FSIM(360))
00905 SetRFacing(mech, SHO2FSIM(MechDesiredFacing(mech)));
00906 } else {
00907 AddRFacing(mech, -offset);
00908 if(MechRFacing(mech) < 0)
00909 AddFacing(mech, 360);
00910 normangle -= offset;
00911 if(normangle < 0)
00912 SetRFacing(mech, SHO2FSIM(MechDesiredFacing(mech)));
00913 }
00914 MechCritStatus(mech) |= CHEAD;
00915 MarkForLOSUpdate(mech);
00916 }
00917
00918
00919 #define DECREASE_HEAT(spd) \
00920 tempspeed *= (ceil((rint((maxspeed / 1.5) / MP1) - (spd/MP1) ) * 1.5) * MP1) / maxspeed
00921
00922 #define DECREASE_OLD(spd) \
00923 tempspeed *= (maxspeed - (spd)) / maxspeed
00924 #define INCREASE_OLD(spd) DECREASE_OLD(-(spd))
00925
00926 #define DECREASE_NEW(spd) \
00927 tempspeed *= MP1 / (MP1 + spd)
00928 #define INCREASE_NEW(spd) \
00929 tempspeed *= (MP1 + spd/2) / MP1
00930
00931 #define DECREASE(s) DECREASE_NEW(s)
00932 #define INCREASE(s) INCREASE_NEW(s)
00933
00934
00935
00936 float terrain_speed(MECH * mech, float tempspeed, float maxspeed,
00937 int terrain, int elev)
00938 {
00939 switch (terrain) {
00940 case SNOW:
00941 case ROUGH:
00942 DECREASE(MP1);
00943 break;
00944 case MOUNTAINS:
00945 DECREASE(MP2);
00946 break;
00947 case LIGHT_FOREST:
00948 if(MechType(mech) != CLASS_BSUIT)
00949 DECREASE(MP1);
00950 break;
00951 case HEAVY_FOREST:
00952 if(MechType(mech) != CLASS_BSUIT)
00953 DECREASE(MP2);
00954 break;
00955 case BRIDGE:
00956 case ROAD:
00957
00958 #ifndef BT_MOVEMENT_MODES
00959 if(MechMove(mech) == MOVE_TRACK || MechMove(mech) == MOVE_WHEEL)
00960 #else
00961 if(!(MechStatus2(mech) & SPRINTING) &&
00962 (MechMove(mech) == MOVE_TRACK || MechMove(mech) == MOVE_WHEEL))
00963 #endif
00964 INCREASE_OLD(MP1);
00965 case ICE:
00966 if(MechZ(mech) >= 0)
00967 break;
00968
00969
00970 case WATER:
00971 if(MechIsBiped(mech) || MechIsQuad(mech)) {
00972 if(elev <= -2)
00973 DECREASE(MP3);
00974 else if(elev == -1)
00975 DECREASE(MP1);
00976 }
00977 break;
00978 }
00979 return tempspeed;
00980 }
00981
00982 void UpdateSpeed(MECH * mech)
00983 {
00984 float acc, tempspeed, maxspeed;
00985 MECH *target;
00986
00987 if(!(!Fallen(mech) && !Jumping(mech) && (MechMaxSpeed(mech) > 0.0)))
00988 return;
00989 tempspeed = fabs(MechDesiredSpeed(mech));
00990 maxspeed = MMaxSpeed(mech);
00991 if(maxspeed < 0.0)
00992 maxspeed = 0.0;
00993
00994 if((MechStatus(mech) & MASC_ENABLED) &&
00995 (MechStatus(mech) & SCHARGE_ENABLED))
00996 maxspeed = ceil((rint(maxspeed / 1.5) / MP1) * 2.5) * MP1;
00997 else if(MechStatus(mech) & MASC_ENABLED)
00998 maxspeed = (4. / 3.) * maxspeed;
00999 else if(MechStatus(mech) & SCHARGE_ENABLED)
01000 maxspeed = (4. / 3.) * maxspeed;
01001
01002 if(MechSpecials(mech) & TRIPLE_MYOMER_TECH) {
01003 if(MechHeat(mech) >= 9.)
01004 maxspeed =
01005 ceil((rint((MMaxSpeed(mech) / 1.5) / MP1) + 1) * 1.5) * MP1;
01006
01007 if(MechDesiredSpeed(mech) >= maxspeed)
01008 MechDesiredSpeed(mech) = maxspeed;
01009 }
01010
01011 if(MechHeat(mech) >= 5.) {
01012
01013
01014
01015
01016
01017 if(MechHeat(mech) >= 25.)
01018 DECREASE_HEAT(MP5);
01019 else if(MechHeat(mech) >= 20.)
01020 DECREASE_HEAT(MP4);
01021 else if(MechHeat(mech) >= 15.)
01022 DECREASE_HEAT(MP3);
01023 else if(MechHeat(mech) >= 10.)
01024 DECREASE_HEAT(MP2);
01025 else if(!((MechSpecials(mech) & TRIPLE_MYOMER_TECH) &&
01026 MechHeat(mech) >= 9))
01027 DECREASE_HEAT(MP1);
01028 }
01029 if(MechType(mech) != CLASS_MW && MechMove(mech) != MOVE_VTOL &&
01030 (MechMove(mech) != MOVE_FLY || Landed(mech)))
01031 tempspeed =
01032 terrain_speed(mech, tempspeed, maxspeed, MechRTerrain(mech),
01033 MechElevation(mech));
01034 if(MechCritStatus(mech) & CHEAD) {
01035 if(mudconf.btech_slowdown == 2) {
01036
01037 int dif = MechFacing(mech) - MechDesiredFacing(mech);
01038
01039 if(dif < 0)
01040 dif = -dif;
01041 if(dif > 180)
01042 dif = 360 - dif;
01043 if(dif) {
01044 dif = (dif - 1) / 30;
01045 dif = (dif + 2);
01046
01047 tempspeed = tempspeed * (10 - dif) / 10;
01048 }
01049 } else if(mudconf.btech_slowdown == 1) {
01050 if(MechFacing(mech) != MechDesiredFacing(mech))
01051 tempspeed = tempspeed * 2.0 / 3.0;
01052 else
01053 tempspeed = tempspeed * 3.0 / 4.0;
01054 }
01055 #ifdef BT_MOVEMENT_MODES
01056 if((Sprinting(mech) || Evading(mech))
01057 && !(HasBoolAdvantage(MechPilot(mech), "speed_demon")
01058 || HasBoolAdvantage(MechPilot(mech), "maneuvering_ace")))
01059 tempspeed = (tempspeed * 2) / 3;
01060 #endif
01061 MechCritStatus(mech) &= ~CHEAD;
01062 }
01063 if(MechIsQuad(mech) && MechLateral(mech))
01064 DECREASE_OLD(MP1);
01065 #ifdef BT_MOVEMENT_MODES
01066 else if(MechLateral(mech)) {
01067 if(HasBoolAdvantage(MechPilot(mech), "maneuvering_ace"))
01068 DECREASE_OLD(MP2);
01069 else
01070 DECREASE_OLD(MP3);
01071 }
01072 #endif
01073 if(tempspeed <= 0.0)
01074 tempspeed = 0.0;
01075 if(MechDesiredSpeed(mech) < 0.)
01076 tempspeed = -tempspeed;
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 if(tempspeed != MechSpeed(mech)) {
01088 if(MechIsQuad(mech))
01089 acc = maxspeed / 10.;
01090 else
01091 acc = maxspeed / 20.;
01092 if(HasBoolAdvantage(MechPilot(mech), "speed_demon"))
01093 acc *= 1.25;
01094
01095 if(tempspeed < MechSpeed(mech)) {
01096
01097 MechSpeed(mech) -= acc;
01098 if(tempspeed > MechSpeed(mech))
01099 MechSpeed(mech) = tempspeed;
01100 } else {
01101
01102 MechSpeed(mech) += acc;
01103 if(tempspeed < MechSpeed(mech))
01104 MechSpeed(mech) = tempspeed;
01105 }
01106 }
01107 if(MechCarrying(mech) > 0) {
01108 target = getMech(MechCarrying(mech));
01109 if(target)
01110 MechSpeed(target) = MechSpeed(mech);
01111 }
01112 }
01113
01114 int OverheatMods(MECH * mech)
01115 {
01116 int returnValue;
01117
01118 if(MechHeat(mech) >= 24.) {
01119
01120 returnValue = 4;
01121 } else if(MechHeat(mech) >= 17.) {
01122
01123 returnValue = 3;
01124 } else if(MechHeat(mech) >= 13.) {
01125
01126 returnValue = 2;
01127 } else if(MechHeat(mech) >= 8.) {
01128
01129 returnValue = 1;
01130 } else {
01131 returnValue = 0;
01132 }
01133 return (returnValue);
01134 }
01135
01136 void ammo_explosion(MECH * attacker, MECH * mech, int ammoloc,
01137 int ammocritnum, int damage)
01138 {
01139 if(MechType(mech) == CLASS_MW) {
01140 mech_notify(mech, MECHALL, "Your weapon's ammo explodes!");
01141 MechLOSBroadcast(mech, "'s weapon's ammo explodes!");
01142 } else {
01143 mech_notify(mech, MECHALL, "Ammunition explosion!");
01144 if(GetPartAmmoMode(mech, ammoloc, ammocritnum) & INFERNO_MODE)
01145 MechLOSBroadcast(mech,
01146 "is suddenly enveloped by a brilliant fireball!");
01147 else
01148 MechLOSBroadcast(mech, "has an internal ammo explosion!");
01149 }
01150 DestroyPart(mech, ammoloc, ammocritnum);
01151 if(!attacker)
01152 return;
01153 if(GetPartAmmoMode(mech, ammoloc, ammocritnum) & INFERNO_MODE) {
01154 Inferno_Hit(mech, mech, damage / 4, 0);
01155 if(mudconf.btech_inferno_penalty)
01156 MechWeapHeat(mech) += 30.0;
01157 damage = damage / 2;
01158 }
01159 if(MechType(mech) == CLASS_BSUIT)
01160 DamageMech(mech, attacker, 0, -1, ammoloc, 0, 0, damage, 0, -1, 0,
01161 -1, 0, 0);
01162 else
01163 DamageMech(mech, attacker, 0, -1, ammoloc, 0, 0, -1, damage, -1, 0,
01164 -1, 0, 0);
01165
01166 if(MechType(mech) != CLASS_BSUIT) {
01167 mech_notify(mech, MECHPILOT,
01168 "You take personal injury from the ammunition explosion!");
01169 if(HasBoolAdvantage(MechPilot(mech), "pain_resistance"))
01170 headhitmwdamage(mech, mech, 1);
01171 else
01172 headhitmwdamage(mech, mech, 2);
01173 }
01174 }
01175
01176 void HandleOverheat(MECH * mech)
01177 {
01178 int avoided = 0, hasinferno = 0;
01179 MAP *mech_map;
01180 int ammoloc, ammocritnum, damage = 0;
01181
01182 if(MechHeat(mech) < 10.)
01183 return;
01184
01185 if((MechHeatLast(mech) + TURN) > muxevent_tick)
01186 return;
01187 MechHeatLast(mech) = muxevent_tick;
01188
01189
01190 if(MechHeat(mech) >= 10.) {
01191 if(mudconf.btech_inferno_penalty)
01192 hasinferno = FindInfernoAmmo(mech, &ammoloc, &ammocritnum);
01193 if(MechHeat(mech) >= 28.) {
01194
01195 if(hasinferno) {
01196 if(Roll() >= 12)
01197 avoided = 1;
01198 } else {
01199 if(Roll() >= 8)
01200 avoided = 1;
01201 }
01202 } else if(MechHeat(mech) >= 23.) {
01203
01204 if(hasinferno) {
01205 if(Roll() >= 10)
01206 avoided = 1;
01207 } else {
01208 if(Roll() >= 6)
01209 avoided = 1;
01210 }
01211 } else if(MechHeat(mech) >= 19.) {
01212
01213 if(hasinferno) {
01214 if(Roll() >= 8)
01215 avoided = 1;
01216 } else {
01217 if(Roll() >= 4)
01218 avoided = 1;
01219 }
01220
01221 } else if((MechHeat(mech) >= 14.) && (hasinferno)) {
01222 if(Roll() >= 6)
01223 avoided = 1;
01224 } else if((MechHeat(mech) >= 10.) && (hasinferno)) {
01225 if(Roll() >= 4)
01226 avoided = 1;
01227 } else if((MechHeat(mech) < 19.) && (!hasinferno)) {
01228 avoided = 1;
01229 }
01230
01231 if(!(avoided)) {
01232 if(!hasinferno)
01233 damage = FindDestructiveAmmo(mech, &ammoloc, &ammocritnum);
01234 else
01235 damage = hasinferno;
01236 if(damage) {
01237
01238
01239 ammo_explosion(mech, mech, ammoloc, ammocritnum, damage);
01240 } else
01241 mech_notify(mech, MECHALL,
01242 "You have no ammunition, lucky you!");
01243 }
01244 }
01245
01246 avoided = 0;
01247 #ifdef BT_EXILE_MW3STATS
01248 if(!isPlayer(MechPilot(mech))) {
01249 #endif
01250 if(MechHeat(mech) >= 30.) {
01251
01252 } else if(MechHeat(mech) >= 26.) {
01253
01254 if(Roll() >= 10)
01255 avoided = 1;
01256 } else if(MechHeat(mech) >= 22.) {
01257
01258 if(Roll() >= 8)
01259 avoided = 1;
01260 } else if(MechHeat(mech) >= 18.) {
01261
01262 if(Roll() >= 6)
01263 avoided = 1;
01264 } else if(MechHeat(mech) >= 14.) {
01265
01266 if(Roll() >= 4)
01267 avoided = 1;
01268 }
01269 #ifdef BT_EXILE_MW3STATS
01270 } else {
01271 avoided = 1;
01272 if(MechHeat(mech) >= 14.) {
01273 mech_notify(mech, MECHALL,
01274 "You frantically attempt to override the shutdown process!");
01275 avoided =
01276 char_getskillsuccess(MechPilot(mech), "computer",
01277 (MechHeat(mech) >=
01278 30. ? 8 : MechHeat(mech) >=
01279 26. ? 6 : MechHeat(mech) >=
01280 22. ? 4 : MechHeat(mech) >=
01281 18. ? 2 : 0), 1);
01282 if(avoided)
01283 AccumulateComputerXP(MechPilot(mech), mech, 1);
01284 }
01285 }
01286 #endif
01287 if(!(avoided) && Started(mech)) {
01288 if(MechStatus(mech) & STARTED)
01289 mech_notify(mech, MECHALL, "%ci%crReactor shutting down...%c");
01290 if(MechStatus2(mech) & SLITE_ON) {
01291 mech_notify(mech, MECHALL, "Your searchlight shuts off.");
01292 MechStatus2(mech) &= ~SLITE_ON;
01293 MechCritStatus(mech) &= ~SLITE_LIT;
01294 }
01295 if(Jumping(mech) || OODing(mech) || (is_aero(mech) && !Landed(mech))) {
01296 mech_notify(mech, MECHALL, "%chYou fall from the sky!%c");
01297 MechLOSBroadcast(mech, "falls from the sky!");
01298 mech_map = getMap(mech->mapindex);
01299 MechFalls(mech, JumpSpeedMP(mech, mech_map), 0);
01300 domino_space(mech, 2);
01301 } else {
01302 MechLOSBroadcast(mech, "stops in mid-motion!");
01303 if((fabs(MechSpeed(mech) > MP1)) && !Fallen(mech) &&
01304 (!MadePilotSkillRoll(mech, 3)))
01305 MechFalls(mech, 0, 1);
01306 }
01307 Shutdown(mech);
01308 StopMoving(mech);
01309 StopStand(mech);
01310 }
01311 }
01312
01313 static int EnableSomeHS(MECH * mech, int numsinks)
01314 {
01315
01316 numsinks = MIN(numsinks,
01317 (MechSpecials(mech) & (DOUBLE_HEAT_TECH | CLAN_TECH)) ? 4 :
01318 2);
01319 numsinks = MIN(numsinks, MechDisabledHS(mech));
01320
01321 if(!numsinks)
01322 return 0;
01323
01324 MechDisabledHS(mech) -= numsinks;
01325 MechMinusHeat(mech) += numsinks;
01326
01327 #ifdef HEATCUTOFF_DEBUG
01328 mech_printf(mech, MECHALL,
01329 "%%cg%d heatsink%s kick%s into action.%%c", numsinks,
01330 numsinks == 1 ? "" : "s", numsinks == 1 ? "s" : "");
01331 #endif
01332
01333 return numsinks;
01334 }
01335
01336 static int DisableSomeHS(MECH * mech, int numsinks)
01337 {
01338
01339 numsinks = MIN(numsinks,
01340 (MechSpecials(mech) & (DOUBLE_HEAT_TECH | CLAN_TECH)) ? 4 :
01341 2);
01342 numsinks = MIN(numsinks, MechActiveNumsinks(mech));
01343
01344 if(!numsinks)
01345 return 0;
01346
01347 MechDisabledHS(mech) += numsinks;
01348 MechMinusHeat(mech) -= numsinks;
01349
01350 #ifdef HEATCUTOFF_DEBUG
01351 mech_printf(mech, MECHALL,
01352 "%%cy%d heatsink%s hum%s into silence.%%c", numsinks,
01353 numsinks == 1 ? "" : "s", numsinks == 1 ? "s" : "");
01354 #endif
01355
01356 return numsinks;
01357 }
01358
01359
01360
01361 void UpdateHeat(MECH * mech)
01362 {
01363
01364 int legsinks;
01365 float maxspeed;
01366 float intheat;
01367 float inheat;
01368 MAP *map;
01369
01370
01371 if(!MechHasHeat(mech))
01372 return;
01373
01374 inheat = MechHeat(mech);
01375 maxspeed = MMaxSpeed(mech);
01376 MechPlusHeat(mech) = 0.;
01377
01378 if(MechTerrain(mech) == FIRE && MechType(mech) == CLASS_MECH)
01379 MechPlusHeat(mech) += 5.;
01380
01381
01382
01383
01384 if(MechSpecials(mech) & TRIPLE_MYOMER_TECH) {
01385 if(inheat >= 9.)
01386 maxspeed =
01387 ceil((rint((MMaxSpeed(mech) / 1.5) / MP1) + 1) * 1.5) * MP1;
01388 }
01389
01390 if(fabs(MechSpeed(mech)) > 0.0) {
01391 #ifndef BT_MOVEMENT_MODES
01392 if(IsRunning(MechDesiredSpeed(mech), maxspeed))
01393 MechPlusHeat(mech) += 2.;
01394 #else
01395 if(Sprinting(mech) || Evading(mech))
01396 MechPlusHeat(mech) += 3.;
01397 else if(IsRunning(MechDesiredSpeed(mech), maxspeed))
01398 MechPlusHeat(mech) += 2.;
01399 #endif
01400 else
01401 MechPlusHeat(mech) += 1.;
01402 }
01403
01404 if(Jumping(mech))
01405 MechPlusHeat(mech) += (MechJumpSpeed(mech) * MP_PER_KPH > 3.) ?
01406 MechJumpSpeed(mech) * MP_PER_KPH : 3.;
01407
01408 if(Started(mech))
01409 MechPlusHeat(mech) += (float) MechEngineHeat(mech);
01410
01411 if(StealthArmorActive(mech))
01412 MechPlusHeat(mech) += 10;
01413
01414 if(NullSigSysActive(mech))
01415 MechPlusHeat(mech) += 10;
01416
01417 intheat = MechPlusHeat(mech);
01418
01419 MechPlusHeat(mech) += MechWeapHeat(mech);
01420
01421
01422 if(InWater(mech) && MechZ(mech) <= -1) {
01423 legsinks = FindLegHeatSinks(mech);
01424 legsinks = (legsinks > 4) ? 4 : legsinks;
01425 if(MechZ(mech) == -1 && !Fallen(mech)) {
01426 MechMinusHeat(mech) = MIN(2 * MechActiveNumsinks(mech),
01427 legsinks + MechActiveNumsinks(mech));
01428 } else {
01429 MechMinusHeat(mech) = MIN(2 * MechActiveNumsinks(mech),
01430 6 + MechActiveNumsinks(mech));
01431 }
01432 } else {
01433 MechMinusHeat(mech) = (float) (MechActiveNumsinks(mech));
01434 }
01435
01436
01437 if(Jellied(mech)) {
01438 MechMinusHeat(mech) = MechMinusHeat(mech) - 6;
01439 if(MechMinusHeat(mech) < 0)
01440 MechMinusHeat(mech) = 0;
01441 }
01442
01443 if(InSpecial(mech))
01444 if((map = FindObjectsData(mech->mapindex)))
01445 if(MapUnderSpecialRules(map))
01446 if(MapTemperature(map) < -30 || MapTemperature(map) > 50) {
01447 if(MapTemperature(map) < -30)
01448 MechMinusHeat(mech) +=
01449 (-30 - MapTemperature(map) + 9) / 10;
01450 else
01451 MechMinusHeat(mech) -=
01452 (MapTemperature(map) - 50 + 9) / 10;
01453 }
01454
01455
01456
01457
01458 if(Heatcutoff(mech)) {
01459 float overheat = MechPlusHeat(mech) - MechMinusHeat(mech);
01460
01461 if(overheat >= 10.)
01462 EnableSomeHS(mech, floor(overheat - 10.) + 1);
01463 else if(overheat < 9.)
01464 DisableSomeHS(mech, floor(9. - overheat) + 1);
01465
01466 } else if(MechDisabledHS(mech)) {
01467 EnableSomeHS(mech, 100);
01468 }
01469
01470 MechHeat(mech) = MechPlusHeat(mech) - MechMinusHeat(mech);
01471
01472
01473 MechWeapHeat(mech) -=
01474 (MechMinusHeat(mech) - intheat) / WEAPON_RECYCLE_TIME;
01475
01476 if(MechWeapHeat(mech) < 0.0)
01477 MechWeapHeat(mech) = 0.0;
01478
01479 if(MechHeat(mech) < 0.0)
01480 MechHeat(mech) = 0.0;
01481
01482 if((muxevent_tick % TURN) == 0)
01483 if(MechCritStatus(mech) & LIFE_SUPPORT_DESTROYED ||
01484 (MechHeat(mech) > 30. && Number(0, 1) == 0)) {
01485 if(MechHeat(mech) > 25.) {
01486 mech_notify(mech, MECHPILOT,
01487 "You take personal injury from heat!");
01488 headhitmwdamage(mech, mech,
01489 MechCritStatus(mech) & LIFE_SUPPORT_DESTROYED
01490 ? 2 : 1);
01491 } else if(MechHeat(mech) >= 15.) {
01492 mech_notify(mech, MECHPILOT,
01493 "You take personal injury from heat!");
01494 headhitmwdamage(mech, mech, 1);
01495 }
01496 }
01497
01498 if(MechHeat(mech) >= 19) {
01499 if(inheat < 19) {
01500 mech_notify(mech, MECHALL,
01501 "%ch%cr=====================================");
01502 mech_notify(mech, MECHALL,
01503 "Your Excess Heat indicator turns RED!");
01504 mech_notify(mech, MECHALL,
01505 "=====================================%c");
01506 }
01507 } else if(MechHeat(mech) >= 14) {
01508 if(inheat >= 19 || inheat < 14) {
01509 mech_notify(mech, MECHALL,
01510 "%ch%cy=======================================");
01511 mech_notify(mech, MECHALL,
01512 "Your Excess Heat indicator turns YELLOW");
01513 mech_notify(mech, MECHALL,
01514 "=======================================%c");
01515 }
01516 } else {
01517 if(inheat >= 14) {
01518 mech_notify(mech, MECHALL,
01519 "%cg======================================");
01520 mech_notify(mech, MECHALL,
01521 "Your Excess Heat indicator turns GREEN");
01522 mech_notify(mech, MECHALL,
01523 "======================================%c");
01524 }
01525 }
01526 HandleOverheat(mech);
01527 }
01528
01529 int recycle_weaponry(MECH * mech)
01530 {
01531
01532 int loop;
01533 int count, i;
01534 int crit[MAX_WEAPS_SECTION];
01535 unsigned char weaptype[MAX_WEAPS_SECTION];
01536 unsigned char weapdata[MAX_WEAPS_SECTION];
01537 char location[20];
01538
01539 int diff = (muxevent_tick - MechLWRT(mech));
01540 int lowest = 0;
01541
01542 if(diff < 1) {
01543 if(diff < 0)
01544 MechLWRT(mech) = muxevent_tick;
01545 return 1;
01546 }
01547 MechLWRT(mech) = muxevent_tick;
01548
01549 if(!Started(mech) || Destroyed(mech))
01550 return 0;
01551
01552 arc_override = 1;
01553 for(loop = 0; loop < NUM_SECTIONS; loop++) {
01554 count = FindWeapons(mech, loop, weaptype, weapdata, crit);
01555 for(i = 0; i < count; i++) {
01556 if(WpnIsRecycling(mech, loop, crit[i])) {
01557
01558 if(PartTempNuke(mech, loop, crit[i]) == FAIL_DESTROYED)
01559 GetPartData(mech, loop, crit[i]) = 0;
01560 if(diff >= GetPartData(mech, loop, crit[i])) {
01561 GetPartData(mech, loop, crit[i]) = 0;
01562 mech_printf(mech, MECHSTARTED,
01563 MechType(mech) ==
01564 CLASS_MW ?
01565 "%%cgYou are ready to attack again with %s.%%c"
01566 : PartTempNuke(mech, loop,
01567 crit[i]) !=
01568 0 ? "%%cg%s is operational again.%%c" :
01569 (GetPartFireMode(mech, loop,
01570 crit[i]) & ROCKET_FIRED) ? ""
01571 : "%%cg%s finished recycling.%%c",
01572 &MechWeapons[weaptype[i]].name[3]);
01573 SetPartTempNuke(mech, loop, crit[i], 0);
01574 } else {
01575 if(PartTempNuke(mech, loop, crit[i]) != FAIL_DESTROYED) {
01576 GetPartData(mech, loop, crit[i]) -= diff;
01577 if(GetPartData(mech, loop, crit[i]) < lowest ||
01578 !lowest)
01579 lowest = GetPartData(mech, loop, crit[i]);
01580 }
01581 }
01582 }
01583 }
01584
01585
01586 if(MechSections(mech)[loop].recycle && ((MechType(mech) == CLASS_MECH)
01587 || (MechType(mech) ==
01588 CLASS_BSUIT)
01589 || (MechType(mech) ==
01590 CLASS_VEH_GROUND)
01591 || (MechType(mech) ==
01592 CLASS_VTOL))) {
01593
01594
01595 if(diff >= MechSections(mech)[loop].recycle &&
01596 !SectIsDestroyed(mech, loop)) {
01597
01598 MechSections(mech)[loop].recycle = 0;
01599 ArmorStringFromIndex(loop, location, MechType(mech),
01600 MechMove(mech));
01601
01602 mech_printf(mech, MECHSTARTED,
01603 "%%cg%s%s has finished its previous action.%%c",
01604 MechType(mech) == CLASS_BSUIT ? "" : "Your ",
01605 location);
01606
01607 } else {
01608
01609 MechSections(mech)[loop].recycle -= diff;
01610 if(MechSections(mech)[loop].recycle < lowest || !lowest)
01611 lowest = MechSections(mech)[loop].recycle;
01612
01613 }
01614
01615 }
01616
01617 }
01618 arc_override = 0;
01619 return lowest;
01620 }
01621
01622 int SkidMod(float Speed)
01623 {
01624 if(Speed < 2.1)
01625 return -1;
01626 if(Speed < 4.1)
01627 return 0;
01628 if(Speed < 7.1)
01629 return 1;
01630 if(Speed < 10.1)
01631 return 2;
01632 return 4;
01633 }
01634
01635
01636
01637
01638 void move_unit_back(MECH * mech, float deltax, float deltay,
01639 int lastelevation, int ot, int le)
01640 {
01641
01642 MechFX(mech) -= deltax;
01643 MechFY(mech) -= deltay;
01644 MechX(mech) = MechLastX(mech);
01645 MechY(mech) = MechLastY(mech);
01646 MechZ(mech) = lastelevation;
01647 MechFZ(mech) = MechZ(mech) * ZSCALE;
01648 MechTerrain(mech) = ot;
01649 MechElev(mech) = le;
01650
01651 }
01652
01653
01654
01655
01656 void NewHexEntered(MECH * mech, MAP * mech_map, float deltax, float deltay,
01657 int last_z)
01658 {
01659 int elevation, lastelevation;
01660 int oldterrain;
01661 int ot, le, ed, done = 0, tt, avoidbth;
01662 int isunder = 0;
01663 float f;
01664
01665
01667 ot = oldterrain = GetTerrain(mech_map, MechLastX(mech), MechLastY(mech));
01668
01669 if((MechMove(mech) == MOVE_HOVER) &&
01670 (oldterrain == WATER || oldterrain == ICE ||
01671 ((oldterrain == BRIDGE) && (last_z == 0)))) {
01672
01673 le = lastelevation = elevation = 0;
01674
01675 } else {
01676
01677 le = lastelevation =
01678 Elevation(mech_map, MechLastX(mech), MechLastY(mech));
01679 elevation = MechElevation(mech);
01680
01681 if(MechMove(mech) == MOVE_HOVER && elevation < 0)
01682 elevation = 0;
01683
01684 if(ot == ICE && MechZ(mech) >= 0) {
01685 le = lastelevation = 0;
01686 }
01687
01688
01689
01690
01691 }
01692
01693 switch (MechMove(mech)) {
01694 case MOVE_BIPED:
01695 case MOVE_QUAD:
01696
01697 if(Jumping(mech)) {
01698
01699 if(MechRTerrain(mech) == WATER)
01700 return;
01701
01702 #define MOVE_BACK \
01703 MechFX(mech) -= deltax;\
01704 MechFY(mech) -= deltay;\
01705 MechX(mech) = MechLastX(mech);\
01706 MechY(mech) = MechLastY(mech);\
01707 MechZ(mech) = lastelevation;\
01708 MechFZ(mech) = MechZ(mech) * ZSCALE;\
01709 MechTerrain(mech) = ot;\
01710 MechElev(mech) = le;
01711
01712
01713 if(collision_check(mech, JUMP, 0, 0)) {
01714
01715 ed = MAX(1, 1 + MechZ(mech) - Elevation(mech_map,
01716 MechX(mech),
01717 MechY(mech)));
01718 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
01719 mech_notify(mech, MECHALL,
01720 "%chYou attempt to jump over elevation that is too high!%c");
01721 if(RGotPilot(mech) &&
01722 MadePilotSkillRoll(mech,
01723 (int) (MechFZ(mech)) / ZSCALE / 3)) {
01724
01725 mech_notify(mech, MECHALL, "%chYou land safely.%c");
01726 LandMech(mech);
01727
01728 } else {
01729
01730 mech_notify(mech, MECHALL,
01731 "%chYou crash into the obstacle and fall from the sky!%c");
01732 MechLOSBroadcast(mech,
01733 "crashes into an obstacle and falls from the sky!");
01734 MechFalls(mech, ed, 0);
01735 domino_space(mech, 2);
01736 }
01737 }
01738 return;
01739 }
01740
01741
01742 if(collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {
01743
01744 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
01745 mech_notify(mech, MECHALL,
01746 "You attempt to climb a hill too steep for you.");
01747
01748 if(MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
01749 MadePilotSkillRoll_NoXP(mech,
01750 (int) (fabs((MechSpeed (mech)) + MP1) / MP1) / 3, 1))
01751 || (mudconf.btech_skidcliff &&
01752 MadePilotSkillRoll_NoXP(mech,
01753 SkidMod(fabs(MechSpeed(mech)) / MP1), 1))) {
01754
01755 mech_notify(mech, MECHALL,
01756 "You manage to stop before crashing.");
01757 MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");
01758
01759 } else {
01760
01761 mech_notify(mech, MECHALL,
01762 "You run headlong into the cliff and fall down!");
01763 MechLOSBroadcast(mech,
01764 "runs headlong into a cliff and falls down!");
01765 if(!mudconf.btech_skidcliff)
01766 MechFalls(mech,
01767 (int) (1 + (MechSpeed(mech)) * MP_PER_KPH) / 4,
01768 0);
01769 else
01770 MechFalls(mech, 1, 0);
01771 }
01772 MechDesiredSpeed(mech) = 0;
01773 MechSpeed(mech) = 0;
01774 MechZ(mech) = lastelevation;
01775 return;
01776
01777 } else if(collision_check(mech, WALK_DROP, lastelevation, oldterrain)) {
01778
01779
01780 mech_notify(mech, MECHALL,
01781 "You notice a large drop in front of you");
01782 avoidbth = mudconf.btech_skidcliff ?
01783 SkidMod(fabs(MechSpeed(mech)) / MP1) :
01784 ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);
01785
01786 if(MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
01787 MadePilotSkillRoll_NoXP(mech,
01788 avoidbth,1))) {
01789
01790 mech_notify(mech, MECHALL,
01791 "You manage to stop before falling off.");
01792 MechLOSBroadcast(mech,
01793 "stops suddenly to avoid falling off a cliff!");
01794 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
01795
01796 } else {
01797
01798 mech_notify(mech, MECHALL,
01799 "You run off the cliff and fall to the ground below.");
01800 MechLOSBroadcast(mech,
01801 "runs off a cliff and falls to the ground below!");
01802 MechFalls(mech, lastelevation - elevation, 0);
01803 MechDesiredSpeed(mech) = 0;
01804 MechSpeed(mech) = 0;
01805 }
01806 MechDesiredSpeed(mech) = 0;
01807 MechSpeed(mech) = 0;
01808 return;
01809
01810 } else if(mudconf.btech_roll_on_backwalk &&
01811 (MechSpeed(mech) < 0) &&
01812 (collision_check
01813 (mech, WALK_BACK, lastelevation, oldterrain))) {
01814
01815 mech_printf(mech, MECHALL, "You notice a %s behind you!",
01816 (elevation >
01817 lastelevation ? "small incline" : "small drop"));
01818
01819 if(MechPilot(mech) == -1
01820 || (MadePilotSkillRoll(mech,
01821 collision_check(mech, WALK_BACK,
01822 lastelevation,
01823 oldterrain)
01824 - 1))) {
01825
01826 mech_notify(mech, MECHALL,
01827 "You manage to overcome the obstacle.");
01828
01829 } else {
01830
01831 mech_printf(mech, MECHALL, "%s",
01832 (elevation > lastelevation ?
01833 "You stumble on your rear and fall down." :
01834 "You fall on your rear off the small incline."));
01835
01837 MechLOSBroadcast(mech,
01838 tprintf("%s",
01839 (elevation >
01840 lastelevation ?
01841 "falls on its back walking up an incline."
01842 :
01843 "falls off the back of a small incline.")));
01844 MechFalls(mech, abs(lastelevation - elevation), 1);
01845 MechDesiredSpeed(mech) = 0;
01846 MechSpeed(mech) = 0;
01847 if(elevation > lastelevation) {
01848 move_unit_back(mech, deltax, deltay, lastelevation, ot,
01849 le);
01850 }
01851 }
01852 return;
01853 }
01854
01855
01856 le = elevation - lastelevation;
01857 le = (le < 0) ? -le : le;
01858 if(MechZ(mech) != elevation)
01859 le = 0;
01860 if(le > 0) {
01861 deltax = (le == 1) ? MP1 : MP2;
01862 if(MechSpeed(mech) > 0) {
01863 MechSpeed(mech) -= deltax;
01864 if(MechSpeed(mech) < 0)
01865 MechSpeed(mech) = 0;
01866 } else if(MechSpeed(mech) < 0) {
01867 MechSpeed(mech) += deltax;
01868 if(MechSpeed(mech) > 0)
01869 MechSpeed(mech) = 0;
01870 }
01871 }
01872
01873 if(MechType(mech) == CLASS_BSUIT) {
01874
01875
01876 if(!(MechSpecials2(mech) & WATERPROOF_TECH) &&
01877 (MechRTerrain(mech) == WATER ||
01878 (MechRTerrain(mech) == BRIDGE &&
01879 (lastelevation < (elevation - 1)))) && elevation < 0) {
01880
01881 mech_notify(mech, MECHALL,
01882 "You notice a body of water in front of you");
01883
01884 if(MechPilot(mech) == -1 ||
01885 MadePilotSkillRoll(mech,
01886 (int) (fabs((MechSpeed(mech)) + MP1) /
01887 MP1) / 3)) {
01888
01889 mech_notify(mech, MECHALL,
01890 "You manage to stop before falling in.");
01891 MechLOSBroadcast(mech,
01892 "stops suddenly to avoid going for a swim!");
01893 } else {
01894
01895 mech_notify(mech, MECHALL,
01896 "You trip at the edge of the water and plunge in...");
01897 MechFloods(mech);
01898 return;
01899 }
01900 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
01901 MechDesiredSpeed(mech) = 0;
01902 MechSpeed(mech) = 0;
01903 return;
01904 }
01905
01906 } else if(!(MechSpecials2(mech) & WATERPROOF_TECH) &&
01907 ((MechRTerrain(mech) == WATER && MechZ(mech) < 0) ||
01908 (MechRTerrain(mech) == BRIDGE && MechZ(mech) < 0) ||
01909 (MechRTerrain(mech) == ICE && MechZ(mech) < 0) ||
01910 MechRTerrain(mech) == HIGHWATER) &&
01911 MechType(mech) != CLASS_MW) {
01912
01913 int skillmod, dammod;
01914 MechDesiredSpeed(mech) = MIN(MechDesiredSpeed(mech),
01915 WalkingSpeed(MMaxSpeed(mech)));
01916 #ifdef BT_MOVEMENT_MODES
01917 if(MechStatus2(mech) & SPRINTING) {
01918 MechLOSBroadcast(mech,
01919 "breaks out of its sprint as it enters water!");
01920 mech_notify(mech, MECHALL,
01921 "You lose your sprinting momentum as you "
01922 "enter water!");
01923 if(!MoveModeChange(mech))
01924 MECHEVENT(mech, EVENT_MOVEMODE, mech_movemode_event, TURN,
01925 MODE_OFF | MODE_SPRINT);
01926 }
01927 #endif
01928 if(IsRunning(MechSpeed(mech), MMaxSpeed(mech))) {
01929 mech_notify(mech, MECHPILOT,
01930 "You struggle to keep control as you run into the water!");
01931 skillmod = 2;
01932 dammod = 2;
01933 } else {
01934 mech_notify(mech, MECHPILOT, "You use your piloting skill "
01935 "to maneuver through the water.");
01936 skillmod = 0;
01937 dammod = 0;
01938 }
01939 skillmod += (MechRTerrain(mech) == HIGHWATER ? -2 :
01940 MechRTerrain(mech) ==
01941 BRIDGE ? bridge_w_elevation(mech) : MechElev(mech) >
01942 3 ? 1 : (MechElev(mech) - 2));
01943
01944 if(!MadePilotSkillRoll(mech, skillmod)) {
01945 mech_notify(mech, MECHALL,
01946 "You slip in the water and fall down");
01947 MechLOSBroadcast(mech, "slips in the water and falls down!");
01948 MechFalls(mech, 1, dammod);
01949 done = 1;
01950 }
01951 }
01952 break;
01953
01954 case MOVE_TRACK:
01955
01956 if(collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {
01957 mech_notify(mech, MECHALL,
01958 "You attempt to climb a hill too steep for you.");
01959
01960 if(MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
01961 MadePilotSkillRoll_NoXP(mech,
01962 (int) (fabs((MechSpeed (mech)) + MP1) / MP1) / 3, 1))
01963 || (mudconf.btech_skidcliff &&
01964 MadePilotSkillRoll_NoXP(mech,
01965 SkidMod(fabs(MechSpeed(mech)) / MP1), 1))) {
01966
01967 mech_notify(mech, MECHALL,
01968 "You manage to stop before crashing.");
01969 MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");
01970
01971 } else {
01972
01973 if(!mudconf.btech_skidcliff) {
01974 mech_notify(mech, MECHALL, "You smash into a cliff!");
01975 MechLOSBroadcast(mech, "crashes to a cliff!");
01976 MechFalls(mech, (int) (MechSpeed(mech) * MP_PER_KPH / 4),
01977 0);
01978 } else {
01979 mech_notify(mech, MECHALL,
01980 "You skid to a violent halt!");
01981 MechLOSBroadcast(mech, "goes into a skid!");
01982 MechFalls(mech, 0, 0);
01983 }
01984 }
01985 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
01986 MechDesiredSpeed(mech) = 0;
01987 MechSpeed(mech) = 0;
01988 return;
01989
01990 } else if(collision_check(mech, WALK_DROP, lastelevation, oldterrain)) {
01991
01992 mech_notify(mech, MECHALL,
01993 "You notice a large drop in front of you");
01994 avoidbth = mudconf.btech_skidcliff ?
01995 SkidMod(fabs(MechSpeed(mech)) / MP1) :
01996 ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);
01997 if(MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
01998 MadePilotSkillRoll_NoXP(mech,
01999 avoidbth,1))) {
02000 mech_notify(mech, MECHALL,
02001 "You manage to stop before falling off.");
02002 MechLOSBroadcast(mech,
02003 "stops suddenly to avoid falling off a cliff!");
02004 } else {
02005 mech_notify(mech, MECHALL,
02006 "You drive off the cliff and fall to the ground below.");
02007 MechLOSBroadcast(mech,
02008 "drives off a cliff and falls to the ground below.");
02009 MechFalls(mech, lastelevation - elevation, 0);
02010 domino_space(mech, 2);
02011
02012 if(MechRTerrain(mech) == WATER &&
02013 !(MechSpecials2(mech) & WATERPROOF_TECH)) {
02014
02015 mech_notify(mech, MECHALL,
02016 "You drive into the water and your vehicle becomes inoperable.");
02017 Destroy(mech);
02018 ChannelEmitKill(mech, mech);
02019 }
02020
02021 return;
02022 }
02023 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02024 MechDesiredSpeed(mech) = 0;
02025 MechSpeed(mech) = 0;
02026 return;
02027
02028 } else if(mudconf.btech_roll_on_backwalk && (MechSpeed(mech) < 0) &&
02029 (collision_check
02030 (mech, WALK_BACK, lastelevation, oldterrain))) {
02031
02032 mech_printf(mech, MECHALL, "You notice a %s behind you!",
02033 (elevation >
02034 lastelevation ? "small incline" : "small drop"));
02035
02036 if(MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
02037 collision_check
02038 (mech, WALK_BACK,
02039 lastelevation,
02040 oldterrain)
02041 - 1))) {
02042
02043 mech_notify(mech, MECHALL,
02044 "You manage to overcome the obstacle.");
02045 } else {
02046 mech_printf(mech, MECHALL, "%s",
02047 (elevation > lastelevation ?
02048 "You stumble on your rear and fall down." :
02049 "You fall on your rear off the small incline."));
02050 MechLOSBroadcast(mech,
02051 tprintf("%s",
02052 (elevation >
02053 lastelevation ?
02054 "falls on its back walking up an incline."
02055 :
02056 "falls off the back of a small incline.")));
02057 MechFalls(mech, abs(lastelevation - elevation), 1);
02058 MechDesiredSpeed(mech) = 0;
02059 MechSpeed(mech) = 0;
02060 if(elevation > lastelevation) {
02061 move_unit_back(mech, deltax, deltay, lastelevation, ot,
02062 le);
02063 }
02064 }
02065 return;
02066 }
02067
02068 if(!(MechSpecials2(mech) & WATERPROOF_TECH) &&
02069 (MechRTerrain(mech) == WATER ||
02070 (MechRTerrain(mech) == BRIDGE
02071 && (lastelevation < (elevation - 1)))) && elevation < 0) {
02072
02073 mech_notify(mech, MECHALL,
02074 "You notice a body of water in front of you");
02075 if(MechPilot(mech) == -1 ||
02076 MadePilotSkillRoll(mech,
02077 (int) (fabs((MechSpeed(mech)) + MP1) /
02078 MP1) / 3)) {
02079 mech_notify(mech, MECHALL,
02080 "You manage to stop before falling in.");
02081 MechLOSBroadcast(mech,
02082 "stops suddenly to avoid driving into the water!");
02083 } else {
02084 mech_notify(mech, MECHALL,
02085 "You drive into the water and your vehicle becomes inoperable.");
02086 Destroy(mech);
02087 ChannelEmitKill(mech, mech);
02088 return;
02089 }
02090 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02091 MechDesiredSpeed(mech) = 0;
02092 MechSpeed(mech) = 0;
02093 return;
02094 }
02095
02096
02097 if(mudconf.btech_newterrain) {
02098 tt = MechRTerrain(mech);
02099 if((tt == HEAVY_FOREST) && fabs(MechSpeed(mech)) > MP1) {
02100
02101 #if 0
02102 mech_notify(mech, MECHALL, "You cruise at a bunch of trees!");
02103 #endif
02104 mech_notify(mech, MECHALL,
02105 "You try to dodge the larger trees..");
02106
02107 if(MechPilot(mech) == -1 || MadePilotSkillRoll(mech,
02108 (int) (fabs
02109 (MechSpeed
02110 (mech))
02111 / MP1 /
02112 6))) {
02113
02114 mech_notify(mech, MECHALL, "You manage to dodge 'em!");
02115 } else {
02116 mech_notify(mech, MECHALL,
02117 "You swerve, but not enough! This'll hurt!");
02118 MechLOSBroadcast(mech, "cruises headlong at a tree!");
02119 f = fabs(MechSpeed(mech));
02120 MechSpeed(mech) = MechSpeed(mech) / 2.0;
02121 MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
02122 }
02123 }
02124 }
02125
02126
02127 le = elevation - lastelevation;
02128 le = (le < 0) ? -le : le;
02129 if(le > 0) {
02130 deltax = (le == 1) ? MP2 : MP3;
02131 if(MechSpeed(mech) > 0) {
02132 MechSpeed(mech) -= deltax;
02133 if(MechSpeed(mech) < 0)
02134 MechSpeed(mech) = 0;
02135 } else if(MechSpeed(mech) < 0) {
02136 MechSpeed(mech) += deltax;
02137 if(MechSpeed(mech) > 0)
02138 MechSpeed(mech) = 0;
02139 }
02140 }
02141 break;
02142
02143 case MOVE_WHEEL:
02144
02145
02146 if(collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {
02147
02148 mech_notify(mech, MECHALL,
02149 "You attempt to climb a hill too steep for you.");
02150
02151 if(MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
02152 MadePilotSkillRoll_NoXP(mech,
02153 (int) (fabs((MechSpeed (mech)) + MP1) / MP1) / 3, 1))
02154 || (mudconf.btech_skidcliff &&
02155 MadePilotSkillRoll_NoXP(mech,
02156 SkidMod(fabs(MechSpeed(mech)) / MP1), 1))) {
02157
02158 mech_notify(mech, MECHALL,
02159 "You manage to stop before crashing.");
02160 MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");
02161
02162 } else {
02163
02164 if(!mudconf.btech_skidcliff) {
02165 mech_notify(mech, MECHALL, "You smash into a cliff!");
02166 MechLOSBroadcast(mech, "crashes to a cliff!");
02167 MechFalls(mech, (int) (MechSpeed(mech) * MP_PER_KPH / 4),
02168 0);
02169 } else {
02170 mech_notify(mech, MECHALL, "You skid to a violent halt!");
02171 MechLOSBroadcast(mech, "skids to a halt!");
02172 MechFalls(mech, 0, 0);
02173 }
02174 }
02175
02176 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02177 MechDesiredSpeed(mech) = 0;
02178 MechSpeed(mech) = 0;
02179 return;
02180
02181 } else if(collision_check(mech, WALK_DROP, lastelevation, oldterrain)) {
02182
02183 mech_notify(mech, MECHALL,
02184 "You notice a large drop in front of you");
02185 avoidbth = mudconf.btech_skidcliff ?
02186 SkidMod(fabs(MechSpeed(mech)) / MP1) :
02187 ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);
02188
02189 if(MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
02190 MadePilotSkillRoll_NoXP(mech,
02191 avoidbth,1))) {
02192
02193 mech_notify(mech, MECHALL,
02194 "You manage to stop before falling off.");
02195 MechLOSBroadcast(mech,
02196 "stops suddenly to avoid driving off a cliff!");
02197 } else {
02198 mech_notify(mech, MECHALL,
02199 "You drive off the cliff and fall to the ground below.");
02200 MechLOSBroadcast(mech,
02201 "drives off a cliff and falls to the ground below.");
02202 MechFalls(mech, lastelevation - elevation, 0);
02203 domino_space(mech, 2);
02204
02205 if(MechRTerrain(mech) == WATER &&
02206 !(MechSpecials2(mech) & WATERPROOF_TECH)) {
02207
02208 mech_notify(mech, MECHALL,
02209 "You drive into the water and your vehicle becomes inoperable.");
02210 Destroy(mech);
02211 ChannelEmitKill(mech, mech);
02212 }
02213
02214 return;
02215 }
02216 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02217 MechDesiredSpeed(mech) = 0;
02218 MechSpeed(mech) = 0;
02219 return;
02220
02221 } else if(mudconf.btech_roll_on_backwalk &&
02222 (MechSpeed(mech) < 0) &&
02223 (collision_check
02224 (mech, WALK_BACK, lastelevation, oldterrain))) {
02225
02226 mech_printf(mech, MECHALL, "You notice a %s behind you!",
02227 (elevation >
02228 lastelevation ? "small incline" : "small drop"));
02229
02230 if(MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
02231 collision_check
02232 (mech, WALK_BACK,
02233 lastelevation,
02234 oldterrain)
02235 - 1))) {
02236 mech_notify(mech, MECHALL,
02237 "You manage to overcome the obstacle.");
02238 } else {
02239 mech_printf(mech, MECHALL, "%s",
02240 (elevation > lastelevation ?
02241 "You stumble on your rear and fall down." :
02242 "You fall on your rear off the small incline."));
02243 MechLOSBroadcast(mech,
02244 tprintf("%s", (elevation > lastelevation ?
02245 "falls on its back walking up an incline."
02246 :
02247 "falls off the back of a small incline.")));
02248 MechFalls(mech, abs(lastelevation - elevation), 1);
02249 MechDesiredSpeed(mech) = 0;
02250 MechSpeed(mech) = 0;
02251 if(elevation > lastelevation) {
02252 move_unit_back(mech, deltax, deltay, lastelevation, ot,
02253 le);
02254 }
02255 }
02256 return;
02257 }
02258
02259 if(!(MechSpecials2(mech) & WATERPROOF_TECH) &&
02260 (MechRTerrain(mech) == WATER ||
02261 (MechRTerrain(mech) == BRIDGE
02262 && (lastelevation < (elevation - 1)))) && elevation < 0) {
02263
02264 mech_notify(mech, MECHALL,
02265 "You notice a body of water in front of you");
02266
02267 if(MechPilot(mech) == -1 ||
02268 MadePilotSkillRoll(mech,
02269 (int) (fabs((MechSpeed(mech)) + MP1) /
02270 MP1) / 3)) {
02271
02272 mech_notify(mech, MECHALL,
02273 "You manage to stop before falling in.");
02274 MechLOSBroadcast(mech,
02275 "stops suddenly to driving into the water!");
02276 } else {
02277 mech_notify(mech, MECHALL,
02278 "You drive into the water and your vehicle becomes inoperable.");
02279 Destroy(mech);
02280 ChannelEmitKill(mech, mech);
02281 return;
02282 }
02283 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02284 MechDesiredSpeed(mech) = 0;
02285 MechSpeed(mech) = 0;
02286 return;
02287 }
02288
02289
02290 if(mudconf.btech_newterrain) {
02291 tt = MechRTerrain(mech);
02292 if((tt == HEAVY_FOREST || tt == LIGHT_FOREST) &&
02293 fabs(MechSpeed(mech)) > MP1) {
02294
02295 #if 0
02296 mech_notify(mech, MECHALL, "You cruise at a bunch of trees!");
02297 #endif
02298 mech_notify(mech, MECHALL,
02299 "You try to dodge the larger trees..");
02300 if(MechPilot(mech) == -1 ||
02301 MadePilotSkillRoll(mech,
02302 (tt == HEAVY_FOREST ? 3 : 0) +
02303 (fabs(MechSpeed(mech)) / MP1 / 6))) {
02304
02305 mech_notify(mech, MECHALL, "You manage to dodge 'em!");
02306
02307 } else {
02308 mech_notify(mech, MECHALL,
02309 "You swerve, but not enough! This'll hurt!");
02310 MechLOSBroadcast(mech, "cruises headlong at a tree!");
02311 f = fabs(MechSpeed(mech));
02312 MechSpeed(mech) = MechSpeed(mech) / 2.0;
02313 MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
02314 }
02315
02316 } else if((tt == ROUGH) && fabs(MechSpeed(mech)) > MP1) {
02317 #if 0
02318 mech_notify(mech, MECHALL,
02319 "You cruise at some rough terrain!");
02320 #endif
02321 mech_notify(mech, MECHALL, "You try to avoid the rocks..");
02322 if(MechPilot(mech) == -1 || MadePilotSkillRoll(mech,
02323 (int) (fabs
02324 (MechSpeed
02325 (mech))
02326 / MP1 /
02327 6))) {
02328 mech_notify(mech, MECHALL, "You manage to dodge 'em!");
02329 } else {
02330 mech_notify(mech, MECHALL,
02331 "You swerve, but not enough! This'll hurt!");
02332 MechLOSBroadcast(mech, "cruises headlong at a rock!");
02333 f = fabs(MechSpeed(mech));
02334 MechSpeed(mech) = MechSpeed(mech) / 2.0;
02335 MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
02336 }
02337 }
02338 }
02339
02340
02341 le = elevation - lastelevation;
02342 le = (le < 0) ? -le : le;
02343 if(le > 0) {
02344 deltax = (le == 1) ? MP2 : MP3;
02345 if(MechSpeed(mech) > 0) {
02346 MechSpeed(mech) -= deltax;
02347 if(MechSpeed(mech) < 0)
02348 MechSpeed(mech) = 0;
02349 } else if(MechSpeed(mech) < 0) {
02350 MechSpeed(mech) += deltax;
02351 if(MechSpeed(mech) > 0)
02352 MechSpeed(mech) = 0;
02353 }
02354 }
02355 break;
02356
02357 case MOVE_HULL:
02358 case MOVE_FOIL:
02359 case MOVE_SUB:
02360
02361 if((MechRTerrain(mech) != WATER && MechRTerrain(mech) != BRIDGE)
02362 || abs(MechElev(mech)) < (abs(MechZ(mech)) + (MechMove(mech) ==
02363 MOVE_FOIL ? -1 : 0)))
02364 {
02365
02366 MechElev(mech) = le;
02367 MechTerrain(mech) = ot;
02368 mech_notify(mech, MECHALL,
02369 "You attempt to get too close with ground!");
02370 if(MechPilot(mech) == -1 ||
02371 MadePilotSkillRoll(mech,
02372 (int) (fabs((MechSpeed(mech)) + MP1) /
02373 MP1) / 3)) {
02374 mech_notify(mech, MECHALL,
02375 "You manage to stop before crashing.");
02376 MechLOSBroadcast(mech,
02377 "stops suddenly to avoid running aground!");
02378 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02379 } else {
02380 mech_notify(mech, MECHALL, "You smash into the ground!");
02381 MechLOSBroadcast(mech, "smashes aground!");
02382 MechFalls(mech, (int) (MechSpeed(mech) * MP_PER_KPH / 4), 0);
02383 }
02384 MechSpeed(mech) = 0;
02385 MechDesiredSpeed(mech) = 0;
02386 MechVerticalSpeed(mech) = 0;
02387 return;
02388 }
02389 if(elevation > 0)
02390 elevation = 0;
02391 break;
02392
02393 case MOVE_HOVER:
02394
02395 if(collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {
02396 MechElev(mech) = le;
02397 MechTerrain(mech) = ot;
02398 mech_notify(mech, MECHALL,
02399 "You attempt to climb a hill too steep for you.");
02400 if(MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
02401 MadePilotSkillRoll_NoXP(mech,
02402 (int) (fabs((MechSpeed (mech)) + MP1) / MP1) / 3, 1))
02403 || (mudconf.btech_skidcliff &&
02404 MadePilotSkillRoll_NoXP(mech,
02405 SkidMod(fabs(MechSpeed(mech)) / MP1), 1))) {
02406
02407 mech_notify(mech, MECHALL,
02408 "You manage to stop before crashing.");
02409 MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");
02410
02411 } else {
02412
02413 if(!mudconf.btech_skidcliff) {
02414 mech_notify(mech, MECHALL, "You smash into a cliff!");
02415 MechLOSBroadcast(mech, "smashes into a cliff!");
02416 MechFalls(mech,
02417 (int) (MechSpeed(mech) * MP_PER_KPH / 4), 0);
02418 } else {
02419 mech_notify(mech, MECHALL, "You skid to a violent halt!");
02420 MechLOSBroadcast(mech, "skids to a halt!");
02421 MechFalls(mech, 0, 0);
02422 }
02423 }
02424 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02425 MechDesiredSpeed(mech) = 0;
02426 MechSpeed(mech) = 0;
02427 return;
02428
02429 } else if(collision_check(mech, WALK_DROP, lastelevation, oldterrain)) {
02430
02431 mech_notify(mech, MECHALL,
02432 "You notice a large drop in front of you");
02433
02434 avoidbth = mudconf.btech_skidcliff ?
02435 SkidMod(fabs(MechSpeed(mech)) / MP1) :
02436 ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);
02437
02438 if(MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
02439 MadePilotSkillRoll_NoXP(mech,
02440 avoidbth,1))) {
02441
02442 mech_notify(mech, MECHALL,
02443 "You manage to stop before falling off.");
02444 MechLOSBroadcast(mech,
02445 "stops suddenly to avoid falling off a cliff!");
02446
02447 } else {
02448
02449 mech_notify(mech, MECHALL,
02450 "You drive off the cliff and fall to the ground below.");
02451 MechLOSBroadcast(mech,
02452 "drives off a cliff and falls to the ground below.");
02453 MechFalls(mech, lastelevation - elevation, 0);
02454 return;
02455 }
02456
02457 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02458 MechDesiredSpeed(mech) = 0;
02459 MechSpeed(mech) = 0;
02460 return;
02461
02462 } else if(collision_check(mech, HIT_UNDER_BRIDGE, lastelevation,
02463 oldterrain)) {
02464
02465 mech_notify(mech, MECHALL,
02466 "You notice the underside of the bridge in front of you!");
02467
02468 if(MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
02469 MadePilotSkillRoll(mech,
02470 (int) (fabs
02471 ((MechSpeed
02472 (mech)) +
02473 MP1) /
02474 MP1) / 3))
02475 || (mudconf.btech_skidcliff
02476 && MadePilotSkillRoll(mech,
02477 SkidMod(fabs(MechSpeed(mech)) /
02478 MP1)))) {
02479
02480 mech_notify(mech, MECHALL,
02481 "You manage to stop before slamming into the bridge.");
02482 MechLOSBroadcast(mech,
02483 "stops suddenly to avoid slamming into the bridge!");
02484 } else {
02485 mech_notify(mech, MECHALL,
02486 "You drive right into the underside of the bridge.");
02487 MechLOSBroadcast(mech,
02488 "drives right into the underside of the bridge.");
02489 MechFalls(mech, 1, 0);
02490 }
02491 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02492 MechDesiredSpeed(mech) = 0;
02493 MechSpeed(mech) = 0;
02494 return;
02495
02496 } else if(mudconf.btech_roll_on_backwalk &&
02497 (MechSpeed(mech) < 0) &&
02498 (collision_check
02499 (mech, WALK_BACK, lastelevation, oldterrain))
02500 && !isunder) {
02501
02502 mech_printf(mech, MECHALL, "You notice a %s behind you!",
02503 (elevation >
02504 lastelevation ? "small incline" : "small drop"));
02505
02506 if(MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
02507 collision_check
02508 (mech, WALK_BACK,
02509 lastelevation,
02510 oldterrain)
02511 - 1))) {
02512
02513 mech_notify(mech, MECHALL,
02514 "You manage to overcome the obstacle.");
02515
02516 } else {
02517
02518 mech_printf(mech, MECHALL, "%s",
02519 (elevation > lastelevation ?
02520 "You stumble on your rear and fall down." :
02521 "You fall on your rear off the small incline."));
02522 MechLOSBroadcast(mech,
02523 tprintf("%s", (elevation > lastelevation ?
02524 "falls on its back walking up an incline."
02525 :
02526 "falls off the back of a small incline.")));
02527 MechFalls(mech, abs(lastelevation - elevation), 1);
02528 MechDesiredSpeed(mech) = 0;
02529 MechSpeed(mech) = 0;
02530 if(elevation > lastelevation) {
02531 move_unit_back(mech, deltax, deltay, lastelevation, ot,
02532 le);
02533 }
02534 }
02535 return;
02536 }
02537
02538 tt = MechRTerrain(mech);
02539 if((tt == HEAVY_FOREST || tt == LIGHT_FOREST) &&
02540 fabs(MechSpeed(mech)) > MP1) {
02541 #if 0
02542 mech_notify(mech, MECHALL, "You cruise at a bunch of trees!");
02543 #endif
02544 mech_notify(mech, MECHALL, "You try to dodge the larger trees..");
02545
02546 if(MechPilot(mech) == -1 ||
02547 MadePilotSkillRoll(mech,
02548 (tt == HEAVY_FOREST ? 3 : 0) +
02549 (fabs(MechSpeed(mech)) / MP1 / 6))) {
02550
02551 mech_notify(mech, MECHALL, "You manage to dodge 'em!");
02552
02553 } else {
02554 mech_notify(mech, MECHALL,
02555 "You swerve, but not enough! This'll hurt!");
02556 MechLOSBroadcast(mech, "cruises headlong at a tree!");
02557 f = fabs(MechSpeed(mech));
02558 MechSpeed(mech) = MechSpeed(mech) / 2.0;
02559 MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
02560 }
02561 }
02562
02563
02564 le = elevation - lastelevation;
02565 le = (le < 0) ? -le : le;
02566 if(le > 0) {
02567 deltax = (le == 1) ? MP2 : MP3;
02568 if(MechSpeed(mech) > 0) {
02569 MechSpeed(mech) -= deltax;
02570 if(MechSpeed(mech) < 0)
02571 MechSpeed(mech) = 0;
02572 } else if(MechSpeed(mech) < 0) {
02573 MechSpeed(mech) += deltax;
02574 if(MechSpeed(mech) > 0)
02575 MechSpeed(mech) = 0;
02576 }
02577 }
02578 break;
02579
02580 case MOVE_VTOL:
02581 case MOVE_FLY:
02582
02583 if((Landed(mech) && MechRTerrain(mech) != ROAD &&
02584 MechRTerrain(mech) != BRIDGE && MechRTerrain(mech) != GRASSLAND
02585 && MechRTerrain(mech) != BUILDING) ||
02586 (IsForest(MechRTerrain(mech)) && MechZ(mech) < (MechElevation(mech)+2))) {
02587
02588 mech_notify(mech, MECHALL,
02589 "You go where no flying thing has ever gone before..");
02590 if(RGotPilot(mech) && MadePilotSkillRoll(mech, 5)) {
02591 mech_notify(mech, MECHALL, "You stop in time!");
02592 move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
02593 } else {
02594 mech_notify(mech, MECHALL,
02595 "Eww.. You've a bad feeling about this.");
02596 MechLOSBroadcast(mech, "crashes!");
02597 MechFalls(mech, 1, 0);
02598 }
02599 MechDesiredSpeed(mech) = 0;
02600 MechSpeed(mech) = 0;
02601 return;
02602
02603 } else if(Landed(mech) && mudconf.btech_roll_on_backwalk &&
02604 (MechSpeed(mech) < 0) &&
02605 (collision_check
02606 (mech, WALK_BACK, lastelevation, oldterrain))) {
02607
02608 mech_printf(mech, MECHALL, "You notice a %s behind you!",
02609 (elevation >
02610 lastelevation ? "small incline" : "small drop"));
02611
02612 if(MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
02613 collision_check
02614 (mech, WALK_BACK,
02615 lastelevation,
02616 oldterrain)
02617 - 1))) {
02618
02619 mech_notify(mech, MECHALL,
02620 "You manage to overcome the obstacle.");
02621
02622 } else {
02623
02624 mech_printf(mech, MECHALL, "%s", (elevation > lastelevation ?
02625 "You stumble on your rear and fall down."
02626 :
02627 "You fall on your rear off the small incline."));
02628 MechLOSBroadcast(mech,
02629 tprintf("%s",
02630 (elevation >
02631 lastelevation ?
02632 "falls on its back walking up an incline."
02633 :
02634 "falls off the back of a small incline.")));
02635 MechFalls(mech, (abs(lastelevation - elevation) + 1000), 1);
02636 MechDesiredSpeed(mech) = 0;
02637 MechSpeed(mech) = 0;
02638 if(elevation > lastelevation) {
02639 move_unit_back(mech, deltax, deltay, lastelevation, ot,
02640 le);
02641 }
02642 }
02643 return;
02644 }
02645
02646 if(MechRTerrain(mech) == WATER)
02647 return;
02648
02649 if(MechRTerrain(mech) == LIGHT_FOREST ||
02650 MechRTerrain(mech) == HEAVY_FOREST)
02651 elevation = MechElevation(mech) + 2;
02652 else
02653 elevation = MechElevation(mech);
02654
02655 if(collision_check(mech, JUMP, 0, 0)) {
02656 MechFX(mech) -= deltax;
02657 MechFY(mech) -= deltay;
02658 MechX(mech) = MechLastX(mech);
02659 MechY(mech) = MechLastY(mech);
02660 MechZ(mech) = lastelevation;
02661 MechFZ(mech) = MechZ(mech) * ZSCALE;
02662 MechElev(mech) = le;
02663 MechTerrain(mech) = ot;
02664 mech_notify(mech, MECHALL,
02665 "You attempt to fly over elevation that is too high!");
02666
02667 if(MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
02668 (int) (MechFZ
02669 (mech) /
02670 ZSCALE /
02671 3))
02672 && (ot == GRASSLAND || ot == ROAD
02673 || ot == BUILDING))) {
02674
02675 mech_notify(mech, MECHALL, "You land safely.");
02676 MechStatus(mech) |= LANDED;
02677 MechSpeed(mech) = 0.0;
02678 MechVerticalSpeed(mech) = 0.0;
02679
02680 } else {
02681 mech_notify(mech, MECHALL,
02682 "You crash into the obstacle and fall from the sky!");
02683 MechLOSBroadcast(mech,
02684 "crashes into an obstacle and falls from the sky!");
02685 MechFalls(mech, MechsElevation(mech) + 1, 0);
02686 domino_space(mech, 2);
02687 }
02688 }
02689 break;
02690 }
02691
02692 if(!done) {
02693 possible_mine_poof(mech, MINE_STEP);
02694 if(mudconf.btech_fasaadvvhlfire &&
02695 (MechType(mech) == CLASS_VEH_GROUND) &&
02696 (MechTerrain(mech) == FIRE))
02697 checkVehicleInFire(mech, 1);
02698 }
02699 }
02700
02701 void CheckDamage(MECH * wounded)
02702 {
02703
02704
02705 int now = muxevent_tick % TURN;
02706 int staggerLevel = 0;
02707 int headingChange = 0;
02708
02709 if(mudconf.btech_newstagger) {
02710
02711
02712 if(StaggerDamage(wounded) < 0) {
02713 StaggerDamage(wounded) += 1;
02714 return;
02715 }
02716 if(StaggerDamage(wounded) == 0) {
02717 return;
02718 }
02719
02720 staggerLevel = StaggerLevel(wounded);
02721
02722 if(Fallen(wounded) || (MechType(wounded) != CLASS_MECH)) {
02723 if(CheckingStaggerDamage(wounded) || (StaggerDamage(wounded) > 0))
02724 StopStaggerCheck(wounded);
02725
02726 return;
02727 }
02728
02729 if(!CheckingStaggerDamage(wounded)) {
02730 if((Jumping(wounded) && (staggerLevel < 1)) || !Jumping(wounded))
02731 StartStaggerCheck(wounded);
02732 }
02733
02734 if(staggerLevel < 1) {
02735 return;
02736 }
02737
02738 SendDebug(tprintf("For %d. StaggerDamage: %d. StaggerLevel: %d.",
02739 wounded->mynum, StaggerDamage(wounded),
02740 StaggerLevel(wounded)));
02741
02742 if(LastStaggerNotify(wounded) < staggerLevel) {
02743 LastStaggerNotify(wounded) = staggerLevel;
02744
02745 if(Jumping(wounded) || OODing(wounded)) {
02746 switch (staggerLevel) {
02747 case 1:
02748 mech_notify(wounded, MECHALL,
02749 "%cy%chThe damage causes you to spin a little in your flight path.%cn");
02750 headingChange = 15;
02751 break;
02752
02753 case 2:
02754 mech_notify(wounded, MECHALL,
02755 "%crThe damage spins you but you maintain your flight!%cn");
02756 MechLOSBroadcast(wounded,
02757 "turns slightly from the damage!");
02758 headingChange = 45;
02759 break;
02760
02761 default:
02762 mech_notify(wounded, MECHALL,
02763 "%cr%chThe damage causes you to spin completely around!%cn");
02764 MechLOSBroadcast(wounded,
02765 "spins around from the damage!");
02766 headingChange = 180;
02767 break;
02768 }
02769
02770 SetFacing(wounded,
02771 AcceptableDegree((MechFacing(wounded) +
02772 headingChange) * (Roll() >=
02773 6 ? 1 : -1)));
02774 } else {
02775 switch (staggerLevel) {
02776 case 1:
02777 mech_notify(wounded, MECHALL,
02778 "%cy%chThe damage causes you to stagger a little.%cn");
02779 break;
02780
02781 case 2:
02782 mech_notify(wounded, MECHALL,
02783 "%crThe damage causes you to stagger even more!%cn");
02784 MechLOSBroadcast(wounded,
02785 "starts to stagger from the damage!");
02786 break;
02787
02788 default:
02789 mech_notify(wounded, MECHALL,
02790 "%cr%chThe damage causes you to stagger violently while attempting to keep your footing!%cn");
02791 MechLOSBroadcast(wounded,
02792 "staggers back and forth attempting to keep its footing!");
02793 break;
02794 }
02795 }
02796 }
02797 } else {
02798 if(!IsDS(wounded) && MechTurnDamage(wounded) >= 20 &&
02799 (!MechStaggeredLastTurn(wounded) ||
02800 MechStaggerStamp(wounded) == now)) {
02801
02802 if(!Jumping(wounded) && !Fallen(wounded) && !OODing(wounded)) {
02803 mech_notify(wounded, MECHALL, "You stagger from the damage!");
02804 if(!MadePilotSkillRoll(wounded, 1)) {
02805 mech_notify(wounded, MECHALL,
02806 "You fall over from all the damage!");
02807 MechLOSBroadcast(wounded,
02808 "falls down, staggered by the damage!");
02809 MechFalls(wounded, 1, 0);
02810 }
02811 }
02812 MechTurnDamage(wounded) = 0;
02813 SetMechStaggerStamp(wounded, now);
02814 return;
02815 }
02816 if((MechStaggeredLastTurn(wounded) &&
02817 MechStaggerStamp(wounded) == now) ||
02818 (!MechStaggeredLastTurn(wounded) && !now)) {
02819 MechTurnDamage(wounded) = 0;
02820 SetMechStaggerStamp(wounded, -1);
02821 }
02822 }
02823 }
02824
02825 void UpdatePilotSkillRolls(MECH * mech)
02826 {
02827 int makeroll = 0, grav = 0;
02828 float maxspeed;
02829
02830 if(((muxevent_tick % TURN) == 0) && !Fallen(mech) && !Jumping(mech) &&
02831 !OODing(mech))
02832
02833 {
02834 maxspeed = MMaxSpeed(mech);
02835
02836 if(!Started(mech))
02837 makeroll = 4;
02838
02839 if((MechHeat(mech) >= 9.) &&
02840 (MechSpecials(mech) & TRIPLE_MYOMER_TECH))
02841 maxspeed =
02842 ceil((rint((MMaxSpeed(mech) / 1.5) / MP1) + 1) * 1.5) * MP1;
02843
02844 #ifndef BT_MOVEMENT_MODES
02845 if(InSpecial(mech) && InGravity(mech))
02846 #else
02847 if(InSpecial(mech) && InGravity(mech) && !MoveModeChange(mech))
02848 #endif
02849 if(MechSpeed(mech) > MechMaxSpeed(mech) &&
02850 MechType(mech) == CLASS_MECH) {
02851 grav = 1;
02852 makeroll = 1;
02853 }
02854 if(IsRunning(MechSpeed(mech), maxspeed) &&
02855 ((MechCritStatus(mech) & GYRO_DAMAGED) ||
02856 (MechCritStatus(mech) & HIP_DAMAGED)))
02857 makeroll = 1;
02858
02859 if(makeroll) {
02860 if(!MadePilotSkillRoll(mech, (makeroll - 1))) {
02861 if(grav) {
02862 int dam =
02863 (MechSpeed(mech) - MechMaxSpeed(mech)) / MP1 + 1;
02864 mech_notify(mech, MECHALL, "Your legs take some damage!");
02865 if(MechIsQuad(mech)) {
02866 if(!SectIsDestroyed(mech, LARM))
02867 DamageMech(mech, mech, 0, -1, LARM, 0, 0, 0,
02868 dam, 0, 0, -1, 0, 1);
02869 if(!SectIsDestroyed(mech, RARM))
02870 DamageMech(mech, mech, 0, -1, RARM, 0, 0, 0,
02871 dam, 0, 0, -1, 0, 1);
02872
02873 }
02874 if(!SectIsDestroyed(mech, LLEG))
02875 DamageMech(mech, mech, 0, -1, LLEG, 0, 0, 0,
02876 dam, 0, 0, -1, 0, 1);
02877 if(!SectIsDestroyed(mech, RLEG))
02878 DamageMech(mech, mech, 0, -1, RLEG, 0, 0, 0,
02879 dam, 0, 0, -1, 0, 1);
02880 } else {
02881 mech_notify(mech, MECHALL,
02882 "Your damaged mech falls as you try to run!");
02883 MechLOSBroadcast(mech, "falls down.");
02884 MechFalls(mech, 1, 0);
02885 }
02886 }
02887 }
02888 }
02889 if(MechType(mech) == CLASS_MECH)
02890 CheckDamage(mech);
02891 else
02892 MechTurnDamage(mech) = 0;
02893 if((muxevent_tick % TURN) == 0) {
02894 if(Started(mech) && MechMove(mech) != MOVE_NONE)
02895 CheckGenericFail(mech, -1, NULL, NULL);
02896 }
02897 }
02898
02899 void updateAutoturnTurret(MECH * mech)
02900 {
02901 MECH *target;
02902 int bearing;
02903 float fx, fy;
02904
02905 if(!Started(mech) || Uncon(mech) || Blinded(mech))
02906 return;
02907
02908 if((MechTankCritStatus(mech) & TURRET_JAMMED) ||
02909 (MechTankCritStatus(mech) & TURRET_LOCKED))
02910 return;
02911
02912 if(!GetSectInt(mech, TURRET))
02913 return;
02914
02915 if(MechTarget(mech) == -1 && (MechTargY(mech) == -1 ||
02916 MechTargX(mech) == -1))
02917 return;
02918
02919 if(MechTarget(mech) != -1) {
02920 target = getMech(MechTarget(mech));
02921 fx = MechFX(target);
02922 fy = MechFY(target);
02923 } else {
02924 MapCoordToRealCoord(MechTargX(mech), MechTargY(mech), &fx, &fy);
02925 }
02926
02927 bearing =
02928 AcceptableDegree(FindBearing(MechFX(mech), MechFY(mech), fx,
02929 fy) - MechFacing(mech));
02930 MechTurretFacing(mech) = bearing;
02931 MarkForLOSUpdate(mech);
02932 }
02933
02934
02935 void mech_update(dbref key, void *data)
02936 {
02937 MECH *mech = (MECH *) data;
02938
02939 if(!mech)
02940 return;
02941 MechStatus(mech) &= ~FIRED;
02942 if(is_aero(mech)) {
02943 aero_update(mech);
02944 return;
02945 }
02946 if(Started(mech) || Uncon(mech))
02947 UpdatePilotSkillRolls(mech);
02948 if(Started(mech) || MechPlusHeat(mech) > 0.1)
02949 UpdateHeat(mech);
02950 if(Started(mech))
02951 MechVisMod(mech) =
02952 BOUNDED(0, MechVisMod(mech) + Number(-40, 40), 100);
02953 checkECM(mech);
02954 checkTAG(mech);
02955 end_lite_check(mech);
02956
02957 if(MechStatus2(mech) & AUTOTURN_TURRET)
02958 updateAutoturnTurret(mech);
02959 }