00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <ctype.h>
00016 #include <string.h>
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019
00020 #define _FAILURES_C
00021 #include "mech.h"
00022 #include "failures.h"
00023 #include "mech.events.h"
00024 #include "p.mech.startup.h"
00025
00026 extern int num_def_weapons;
00027
00028 int GetBrandIndex(int type)
00029 {
00030 if(type == -1)
00031 return COMPUTER_INDEX;
00032 if(type == -2)
00033 return RADIO_INDEX;
00034 if(IsWeapon(type))
00035 if(type < I2Weapon(num_def_weapons)) {
00036 type = Weapon2I(type);
00037 if(MechWeapons[type].special & PCOMBAT)
00038 return -1;
00039 if(IsFlamer(type))
00040 return FLAMMER_INDEX;
00041 if(IsEnergy(type))
00042 return ENERGY_INDEX;
00043 if(IsAutocannon(type))
00044 return AC_INDEX;
00045 if(IsMissile(type))
00046 return MISSILE_INDEX;
00047 return -1;
00048 }
00049 return -1;
00050 }
00051
00052 char *GetPartBrandName(int type, int level)
00053 {
00054 int i;
00055
00056 if(!level)
00057 return NULL;
00058 i = GetBrandIndex(type);
00059 if(i < 0)
00060 return NULL;
00061 return brands[i * 5 / 6 + level - 1].name;
00062 }
00063
00064 #define Conv(mech,section,critical) \
00065 (GetBrandIndex(GetPartType(mech, section, critical)) - 1)
00066
00067 void FailureRadioStatic(MECH * mech, int weapnum, int weaptype,
00068 int section, int critical, int roll, int *modifier,
00069 int *type)
00070 {
00071 int mod = failures[GetBrandIndex(-2) + roll - 1].data;
00072
00073 *modifier = mod;
00074 *type = FAIL_STATIC;
00075 }
00076
00077 static void mech_rrec_event(MUXEVENT * e)
00078 {
00079 MECH *mech = (MECH *) e->data;
00080 int val = (int) e->data2;
00081
00082 MechRadioRange(mech) += val;
00083 if(!Destroyed(mech) && val == MechRadioRange(mech))
00084 mech_notify(mech, MECHALL, "Your radio is now operational again.");
00085 }
00086
00087 static void mech_srec_event(MUXEVENT * e)
00088 {
00089 MECH *mech = (MECH *) e->data;
00090 int val = (int) e->data2;
00091 int vt = val / 256;
00092
00093 switch (vt) {
00094 case 0:
00095 MechTacRange(mech) = val;
00096 if(!Destroyed(mech))
00097 mech_notify(mech, MECHALL,
00098 "Your tactical scanners are operational again.");
00099 break;
00100 case 1:
00101 MechLRSRange(mech) = val;
00102 if(!Destroyed(mech))
00103 mech_notify(mech, MECHALL,
00104 "Your long-range scanners are operational again.");
00105 break;
00106 case 2:
00107 MechScanRange(mech) = val;
00108 if(!Destroyed(mech))
00109 mech_notify(mech, MECHALL,
00110 "Your scanners are operational again.");
00111 break;
00112 }
00113 }
00114
00115 void FailureRadioShort(MECH * mech, int weapnum, int weaptype, int section,
00116 int critical, int roll, int *modifier, int *type)
00117 {
00118 MECHEVENT(mech, EVENT_MRECOVERY, mech_rrec_event, Number(30, Number(40,
00119 200)),
00120 (int) MechRadioRange(mech));
00121 MechRadioRange(mech) = 0;
00122 }
00123
00124 void FailureRadioRange(MECH * mech, int weapnum, int weaptype, int section,
00125 int critical, int roll, int *modifier, int *type)
00126 {
00127 int mod = failures[GetBrandIndex(-2) + roll - 1].data;
00128
00129 mod = MIN(MechRadioRange(mech) - 1, mod);
00130 MECHEVENT(mech, EVENT_MRECOVERY, mech_rrec_event, Number(30, Number(40,
00131 200)),
00132 (int) mod);
00133 MechRadioRange(mech) -= mod;
00134 }
00135
00136 void FailureComputerShutdown(MECH * mech, int weapnum, int weaptype,
00137 int section, int critical, int roll,
00138 int *modifier, int *type)
00139 {
00140 if(Started(mech))
00141 mech_shutdown(mech->mynum, mech, "");
00142 }
00143
00144 void FailureComputerScanner(MECH * mech, int weapnum, int weaptype,
00145 int section, int critical, int roll,
00146 int *modifier, int *type)
00147 {
00148 int tmp = failures[GetBrandIndex(-1) + roll - 1].data;
00149
00150 switch (tmp) {
00151 case 1:
00152 MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
00153 Number(40,
00154 200)),
00155 (int) MechTacRange(mech));
00156 MechTacRange(mech) = 0;
00157 break;
00158 case 2:
00159 MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
00160 Number(40,
00161 200)),
00162 MechLRSRange(mech) + 256);
00163 MechLRSRange(mech) = 0;
00164 break;
00165 case 4:
00166 MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
00167 Number(40,
00168 200)),
00169 MechScanRange(mech) + 512);
00170 MechScanRange(mech) = 0;
00171 break;
00172 case 7:
00173 MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event, Number(30,
00174 Number(40,
00175 200)),
00176 (int) MechTacRange(mech));
00177 MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event,
00178 Number(30, Number(40, 200)), MechLRSRange(mech) + 256);
00179 MECHEVENT(mech, EVENT_MRECOVERY, mech_srec_event,
00180 Number(30, Number(40, 200)), MechScanRange(mech) + 512);
00181 MechTacRange(mech) = 0;
00182 MechLRSRange(mech) = 0;
00183 MechScanRange(mech) = 0;
00184 break;
00185 }
00186 }
00187
00188 void FailureComputerTarget(MECH * mech, int weapnum, int weaptype,
00189 int section, int critical, int roll, int *modifier,
00190 int *type)
00191 {
00192 MechTarget(mech) = -1;
00193 }
00194
00195 void FailureWeaponMissiles(MECH * mech, int weapnum, int weaptype,
00196 int section, int critical, int roll, int *modifier,
00197 int *type)
00198 {
00199 SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
00200 critical) +
00201 roll].type);
00202 *type = CRAZY_MISSILES;
00203 *modifier = failures[Conv(mech, section, critical) + roll].data;
00204 }
00205
00206 void FailureWeaponDud(MECH * mech, int weapnum, int weaptype, int section,
00207 int critical, int roll, int *modifier, int *type)
00208 {
00209 if(failures[Conv(mech, section, critical) + roll].type == FAIL_NONE) {
00210 SetRecyclePart(mech, section, critical, MechWeapons[weaptype].vrt);
00211 return;
00212 }
00213 SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
00214 critical) +
00215 roll].type);
00216 *type = WEAPON_DUD;
00217 if(roll == 6) {
00218 SetPartTempNuke(mech, section, critical, FAIL_DESTROYED);
00219 }
00220 SetRecyclePart(mech, section, critical, 30 + Number(1, 60));
00221 }
00222
00223 void FailureWeaponJammed(MECH * mech, int weapnum, int weaptype,
00224 int section, int critical, int roll, int *modifier,
00225 int *type)
00226 {
00227 SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
00228 critical) +
00229 roll].type);
00230 *type = WEAPON_JAMMED;
00231 SetRecyclePart(mech, section, critical, Number(20, 40));
00232 }
00233
00234 void FailureWeaponRange(MECH * mech, int weapnum, int weaptype,
00235 int section, int critical, int roll, int *modifier,
00236 int *type)
00237 {
00238 *modifier =
00239 (int) (EGunRangeWithCheck(mech, section,
00240 weaptype) * (failures[Conv(mech, section,
00241 critical) +
00242 roll].data / 100.0));
00243 *type = RANGE;
00244 }
00245
00246 void FailureWeaponDamage(MECH * mech, int weapnum, int weaptype,
00247 int section, int critical, int roll, int *modifier,
00248 int *type)
00249 {
00250 *modifier =
00251 (int) (MechWeapons[weaptype].damage * (failures[Conv(mech, section,
00252 critical) +
00253 roll].data / 100.0));
00254 *type = DAMAGE;
00255 }
00256
00257 void FailureWeaponHeat(MECH * mech, int weapnum, int weaptype, int section,
00258 int critical, int roll, int *modifier, int *type)
00259 {
00260 *modifier =
00261 (int) MechWeapons[weaptype].heat * (failures[Conv(mech, section,
00262 critical) +
00263 roll].data / 100.0);
00264 *type = HEAT;
00265 }
00266
00267 void FailureWeaponSpike(MECH * mech, int weapnum, int weaptype,
00268 int section, int critical, int roll, int *modifier,
00269 int *type)
00270 {
00271 SetPartTempNuke(mech, section, critical, failures[Conv(mech, section,
00272 critical) +
00273 roll].type);
00274 *type = POWER_SPIKE;
00275 if(roll == 6) {
00276 SetPartTempNuke(mech, section, critical, FAIL_DESTROYED);
00277 return;
00278 }
00279 SetRecyclePart(mech, section, critical, Number(20, 40));
00280 }
00281
00282 void CheckGenericFail(MECH * mech, int type, int *result, int *mod)
00283 {
00284 int i = GetBrandIndex(type);
00285 int l = type == -1 ? MechComputer(mech) : MechRadio(mech);
00286 int roll, in;
00287
00288 if(result)
00289 *result = FAIL_NONE;
00290 if(i < 0)
00291 return;
00292 if(mudconf.btech_parts) {
00293 if(!l)
00294 l = 5;
00295 } else
00296 return;
00297 if(Number(1, 5000) != 42)
00298 return;
00299 if(Number(1, 100) <= brands[(i + l - 1) * 5 / 6].success)
00300 return;
00301 roll = Number(1, 6);
00302 if(roll == 6)
00303 roll = Number(1, 6);
00304 in = i + roll - 1;
00305 switch (failures[in].flag) {
00306 case REQ_TARGET:
00307 if(MechTarget(mech) <= 0)
00308 return;
00309 break;
00310 case REQ_TAC:
00311 if(MechTacRange(mech) == 0)
00312 return;
00313 break;
00314 case REQ_LRS:
00315 if(MechLRSRange(mech) == 0)
00316 return;
00317 break;
00318 case REQ_SCANNERS:
00319 if(MechTacRange(mech) == 0 || MechLRSRange(mech) == 0 ||
00320 MechScanRange(mech) == 0)
00321 return;
00322 break;
00323 case REQ_COMPUTER:
00324
00325 break;
00326 case REQ_RADIO:
00327 if(MechRadioRange(mech) == 0)
00328 return;
00329 break;
00330 }
00331 if(failures[in].message && strcmp(failures[in].message, "none"))
00332 mech_notify(mech, MECHALL, failures[in].message);
00333 failures[in].func(mech, -1, -1, -1, -1, roll, mod, result);
00334 }
00335
00336 void CheckWeaponFailed(MECH * mech, int weapnum, int weaptype, int section,
00337 int critical, int *modifier, int *type)
00338 {
00339 short roll;
00340 int l = GetPartBrand(mech, section, critical);
00341 int t = GetPartType(mech, section, critical);
00342 int i = GetBrandIndex(t), in;
00343
00344 *type = FAIL_NONE;
00345 if(i < 0)
00346 return;
00347 if(mudconf.btech_parts) {
00348 if(!l)
00349 l = 5;
00350 if(MechWeapons[Weapon2I(t)].special & PCOMBAT)
00351 return;
00352 } else
00353 return;
00354 if(Number(1, 10) < 9)
00355 return;
00356 if(Number(1, 100) <= brands[(i + l - 1) * 5 / 6].success)
00357 return;
00358 roll = Number(1, 6);
00359 if(roll == 6)
00360 roll = Number(1, 6);
00361 in = i + roll - 1;
00362 if(failures[in].flag & REQ_HEAT)
00363 if(!MechWeapons[weaptype].heat)
00364 return;
00365 if(failures[in].message && strcmp(failures[in].message, "none"))
00366 mech_notify(mech, MECHALL, failures[in].message);
00367 failures[in].func(mech, weapnum, weaptype, section, critical, roll,
00368 modifier, type);
00369 }