src/hcode/btech/failures.c

Go to the documentation of this file.
00001 
00002 /* This is the code that runs the parts failures.
00003    Written by: Nim
00004    9-28-96
00005    
00006    Parts copyright (c) 2000-2002 Thomas Wouters
00007    
00008  */
00009 
00010 /*
00011  * $Id: failures.c,v 1.1.1.1 2005/01/11 21:18:07 kstevens Exp $
00012  * Last modified: Sat Jun  6 21:43:52 1998 fingon
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;                                 /* ~1/5000 chance */
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 }

Generated on Mon May 28 04:25:21 2007 for BattletechMUX by  doxygen 1.4.7