00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "mech.h"
00018 #include "mech.events.h"
00019 #include "p.map.conditions.h"
00020 #include "p.mech.utils.h"
00021 #include "p.mech.combat.h"
00022 #include "p.mech.combat.misc.h"
00023 #include "p.mech.damage.h"
00024 #include "p.artillery.h"
00025 #include "p.btechstats.h"
00026 #include "p.eject.h"
00027 #include "p.mech.sensor.h"
00028 #include "p.crit.h"
00029
00030 void alter_conditions(MAP * map)
00031 {
00032 int i;
00033 MECH *mech;
00034
00035 for(i = 0; i < map->first_free; i++)
00036 if((mech = FindObjectsData(map->mechsOnMap[i]))) {
00037 UpdateConditions(mech, map);
00038 #if 0
00039 mech_notify(mech, MECHALL,
00040 "You notice a great disturbance in the Force..");
00041 #endif
00042 }
00043 }
00044
00045 void map_setconditions(dbref player, MAP * map, char *buffer)
00046 {
00047 char *args[5];
00048 int vacuum = -1, underground = -1, grav, temp, argc;
00049 int fl;
00050
00051 DOCHECK((argc =
00052 mech_parseattributes(buffer, args, 4)) < 2,
00053 "(At least) 2 options required (gravity + temperature)");
00054 DOCHECK(argc > 4,
00055 "Too many options! Command accepts only 4 at max (gravity + temperature + vacuum-flag + underground-flag)");
00056 DOCHECK(Readnum(grav, args[0]),
00057 "Invalid gravity (must be integer in range of 0 to 255)");
00058 DOCHECK(grav < 0 ||
00059 grav > 255,
00060 "Invalid gravity (must be integer in range of 0 to 255)");
00061 DOCHECK(Readnum(temp, args[1]),
00062 "Invalid temperature (must be integer in range of -128 to 127");
00063 DOCHECK(temp < -128 ||
00064 temp > 127,
00065 "Invalid temperature (must be integer in range of -128 to 127");
00066 if(argc > 2) {
00067 DOCHECK(Readnum(vacuum, args[2]),
00068 "Invalid vacuum flag (must be integer, 0 or 1)");
00069 DOCHECK(vacuum < 0 ||
00070 vacuum > 1, "Invalid vacuum flag (must be integer, 0 or 1)");
00071 }
00072 if(argc > 3) {
00073 DOCHECK(Readnum(underground, args[3]),
00074 "Invalid underground flag (must be integer, 0 or 1)");
00075 DOCHECK(underground < 0 ||
00076 underground > 1,
00077 "Invalid underground flag (must be integer, 0 or 1)");
00078 }
00079 fl = (map->flags & (~(MAPFLAG_SPEC | MAPFLAG_VACUUM)));
00080 if(vacuum > 0)
00081 fl |= MAPFLAG_VACUUM;
00082 if(underground > 0)
00083 fl |= MAPFLAG_UNDERGROUND;
00084 if(fl & MAPFLAG_VACUUM)
00085 fl |= MAPFLAG_SPEC;
00086 if(temp < -30 || temp > 50 || grav != 100)
00087 fl |= MAPFLAG_SPEC;
00088 map->temp = temp;
00089 map->grav = grav;
00090 map->flags = fl;
00091 notify(player, "Conditions set!");
00092 alter_conditions(map);
00093 }
00094
00095 void UpdateConditions(MECH * mech, MAP * map)
00096 {
00097 if(!mech)
00098 return;
00099 MechStatus(mech) &= ~CONDITIONS;
00100 if(!map)
00101 return;
00102 if(!MapUnderSpecialRules(map))
00103 return;
00104 MechStatus(mech) |= UNDERSPECIAL;
00105 if(MapTemperature(map) < -30 || MapTemperature(map) > 50)
00106 MechStatus(mech) |= UNDERTEMPERATURE;
00107 if(MapGravity(map) != 100)
00108 MechStatus(mech) |= UNDERGRAVITY;
00109 if(MapIsVacuum(map))
00110 MechStatus(mech) |= UNDERVACUUM;
00111 }
00112
00113 void reactor_explosion(MECH * wounded, MECH * attacker)
00114 {
00115 int z = MechZ(wounded);
00116 MAP *map = getMap(wounded->mapindex);
00117 dbref wounded_pilot = MechPilot(wounded);
00118 int dam;
00119
00120 DestroySection(wounded, attacker, 0, CTORSO);
00121 DestroySection(wounded, attacker, 0, LTORSO);
00122 DestroySection(wounded, attacker, 0, RTORSO);
00123 DestroySection(wounded, attacker, 0, LLEG);
00124 DestroySection(wounded, attacker, 0, RLEG);
00125
00126
00127 if(!MapIsUnderground(map))
00128 autoeject(wounded_pilot, wounded, 0);
00129
00130 DestroySection(wounded, attacker, 0, HEAD);
00131 MechZ(wounded) += 6;
00132 dam = MAX(MechTons(wounded) / 5, MechEngineSize(wounded) / 10);
00133
00134 ScrambleInfraAndLiteAmp(wounded, 4, 0,
00135 "The searing blast of heat burns out your sensors!",
00136 "The blinding flash of light overloads your sensors!");
00137
00138 blast_hit_hexesf(map, dam, 3,
00139 MAX(MechTons(wounded) / 10,
00140 MechEngineSize(wounded) / 25),
00141 MechFX(wounded), MechFY(wounded),
00142 MechFX(wounded), MechFY(wounded),
00143 "%ch%crYou bear full brunt of the blast!%cn",
00144 "is hit badly by the blast!",
00145 "%ch%cyYou receive some damage from the blast!%cn",
00146 "is hit by the blast!",
00147 mudconf.btech_explode_reactor > 1, 3, 5, 1, 2);
00148 MechZ(wounded) = z;
00149 headhitmwdamage(wounded, attacker, 4);
00150 }
00151
00152 void DestroyParts(MECH * attacker, MECH * wounded, int hitloc, int breach,
00153 int IsDisable)
00154 {
00155 float oldjs;
00156 int i;
00157 int critType;
00158 int nhs = 0;
00159 int tDoAutoFall = 0;
00160 int tNormalizeAllCrits = 0;
00161 int tNormalizeLocCrits = 0;
00162 int tIsLeg = ((hitloc == RLEG || hitloc == LLEG) || ((hitloc == RARM
00163 || hitloc == LARM)
00164 &&
00165 (MechIsQuad
00166 (wounded))));
00167
00168 if(!(MechType(wounded) == CLASS_MECH || MechType(wounded) == CLASS_MW
00169 || MechType(wounded) == CLASS_BSUIT)) {
00170 for(i = 0; i < CritsInLoc(wounded, hitloc); i++)
00171 if(GetPartType(wounded, hitloc, i) &&
00172 !PartIsDestroyed(wounded, hitloc, i)) {
00173 if(IsDisable == 1)
00174 DisablePart(wounded, hitloc, i);
00175 else
00176 DestroyPart(wounded, hitloc, i);
00177 }
00178 return;
00179 }
00180 oldjs = MechJumpSpeed(wounded);
00181 for(i = 0; i < CritsInLoc(wounded, hitloc); i++)
00182 if(!PartIsDestroyed(wounded, hitloc, i)) {
00183 if(IsDisable == 1)
00184 DisablePart(wounded, hitloc, i);
00185 else if(PartIsDisabled(wounded, hitloc, i)) {
00186 DestroyPart(wounded, hitloc, i);
00187 continue;
00188 } else
00189 DestroyPart(wounded, hitloc, i);
00190
00191 critType = GetPartType(wounded, hitloc, i);
00192 if(IsAmmo(critType)) {
00193 GetPartData(wounded, hitloc, i) = 0;
00194 }
00195 if(IsSpecial(critType)) {
00196 switch (Special2I(critType)) {
00197 case UPPER_ACTUATOR:
00198 case LOWER_ACTUATOR:
00199 case HAND_OR_FOOT_ACTUATOR:
00200 tNormalizeLocCrits = 1;
00201 break;
00202 case SHOULDER_OR_HIP:
00203 if(tIsLeg) {
00204 if(!(MechCritStatus(wounded) & HIP_DAMAGED)) {
00205 MechCritStatus(wounded) |= HIP_DAMAGED;
00206 } else {
00207 if(!MechIsQuad(wounded))
00208 MechCritStatus(wounded) |= HIP_DESTROYED;
00209 }
00210 tNormalizeAllCrits = 1;
00211 }
00212 else
00213 tNormalizeLocCrits = 1;
00214 break;
00215 case HEAT_SINK:
00216 if(MechSpecials(wounded) & DOUBLE_HEAT_TECH) {
00217 if((nhs++) % 3 == 2)
00218 MechRealNumsinks(wounded)++;
00219 }
00220 MechRealNumsinks(wounded)--;
00221 break;
00222 case JUMP_JET:
00223 MechJumpSpeed(wounded) -= MP1;
00224 if(MechJumpSpeed(wounded) < 0)
00225 MechJumpSpeed(wounded) = 0;
00226 if(attacker && MechJumpSpeed(wounded) == 0 &&
00227 Jumping(wounded)) {
00228 mech_notify(wounded, MECHALL,
00229 "Losing your last Jump Jet you fall from the sky!!!!!");
00230 MechLOSBroadcast(wounded, "falls from the sky!");
00231 MechFalls(wounded, (int) (oldjs * MP_PER_KPH), 0);
00232 domino_space(wounded, 2);
00233 }
00234 break;
00235 case ENGINE:
00236 if(MechEngineHeat(wounded) < 10)
00237 MechEngineHeat(wounded) += 5;
00238 else if(MechEngineHeat(wounded) < 15) {
00239 MechEngineHeat(wounded) = 15;
00240 if(attacker) {
00241 mech_notify(wounded, MECHALL,
00242 "Your engine is destroyed!!");
00243 if(wounded != attacker)
00244 mech_notify(attacker, MECHALL,
00245 "You destroy the engine!!");
00246 }
00247
00248
00249 if(mudconf.btech_stackpole &&
00250 (MechBoomStart(wounded) + MAX_BOOM_TIME) >= muxevent_tick &&
00251 Roll() >= BOOM_BTH && (Started(wounded) || Starting(wounded))) {
00252
00253 HexLOSBroadcast(getMap(wounded->mapindex), MechX(wounded), MechY(wounded),
00254 "%ch%crThe hit destroys the last safety systems, "
00255 "releasing the fusion reaction!%cn");
00256
00257
00258 reactor_explosion(wounded, attacker);
00259 }
00260
00261
00262 DestroyMech(wounded, attacker, 1);
00263 }
00264 break;
00265 case TARGETING_COMPUTER:
00266 if(!MechCritStatus(wounded) & TC_DESTROYED) {
00267 if(attacker)
00268 mech_notify(wounded, MECHALL,
00269 "Your Targeting Computer is Destroyed");
00270 MechCritStatus(wounded) |= TC_DESTROYED;
00271 }
00272 break;
00273 }
00274 }
00275 }
00276 if(breach)
00277 if(MechType(wounded) == CLASS_VEH_GROUND ||
00278 MechType(wounded) == CLASS_VEH_NAVAL)
00279 DestroyMech(wounded, attacker, 0);
00280 if(MechType(wounded) == CLASS_MECH || MechType(wounded) == CLASS_MW) {
00281 if(breach && hitloc == HEAD) {
00282 if(InVacuum(wounded))
00283 mech_notify(wounded, MECHALL, "You are exposed to vacuum!");
00284 else
00285 mech_notify(wounded, MECHALL,
00286 "Water floods into your cockpit!");
00287
00288 KillMechContentsIfIC(wounded->mynum);
00289 DestroyMech(wounded, attacker, 0);
00290 return;
00291 }
00292 if(!MechIsQuad(wounded))
00293 if(hitloc == LARM || hitloc == RARM)
00294 return;
00295 if(hitloc == RLEG || hitloc == LLEG || hitloc == LARM ||
00296 hitloc == RARM) {
00297 tDoAutoFall = 1;
00298 StopStand(wounded);
00299 }
00300
00301 NormalizeAllActuatorCrits(wounded);
00302
00303
00304 if(tIsLeg && !Fallen(wounded) && !Jumping(wounded) &&
00305 !OODing(wounded) && attacker) {
00306 if(tDoAutoFall) {
00307 mech_notify(wounded, MECHALL,
00308 "You realize remaining standing is no longer an option and crash to the ground!");
00309 MechLOSBroadcast(wounded, "crashes to the ground!");
00310 MechFalls(wounded, 1, 0);
00311 } else if(!MadePilotSkillRoll(wounded, 0)) {
00312 mech_notify(wounded, MECHALL,
00313 "You lose your balance and fall down!");
00314 MechLOSBroadcast(wounded, "loses balance and falls down!");
00315 MechFalls(wounded, 1, 0);
00316 }
00317 }
00318 }
00319 }
00320
00321 int BreachLoc(MECH * attacker, MECH * mech, int hitloc)
00322 {
00323 char buf[SBUF_SIZE];
00324
00325 if(!InSpecial(mech))
00326 return 0;
00327 if(!InVacuum(mech))
00328 return 0;
00329 if(SectIsDestroyed(mech, hitloc) || SectIsBreached(mech, hitloc))
00330 return 0;
00331 ArmorStringFromIndex(hitloc, buf, MechType(mech), MechMove(mech));
00332 mech_notify(mech, MECHALL, tprintf("Your %s has been breached!", buf));
00333 SetSectBreached(mech, hitloc);
00334 DestroyParts(attacker, mech, hitloc, 1, 1);
00335 return 1;
00336 }
00337
00338 int PossiblyBreach(MECH * attacker, MECH * mech, int hitloc)
00339 {
00340 if(!InSpecial(mech))
00341 return 0;
00342 if(Roll() < 10)
00343 return 0;
00344 return BreachLoc(attacker, mech, hitloc);
00345 }