src/hcode/btech/mech.tech.damages.c

Go to the documentation of this file.
00001 
00002 /*
00003  * $Id: mech.tech.damages.c,v 1.1.1.1 2005/01/11 21:18:25 kstevens Exp $
00004  *
00005  * Author: Markus Stenberg <fingon@iki.fi>
00006  *
00007  *  Copyright (c) 1996 Markus Stenberg
00008  *  Copyright (c) 1998-2002 Thomas Wouters
00009  *  Copyright (c) 2000-2002 Cord Awtry
00010  *       All rights reserved
00011  *
00012  * Created: Mon Dec  2 19:00:35 1996 fingon
00013  * Last modified: Thu Sep 10 09:55:13 1998 fingon
00014  *
00015  */
00016 
00017 #include "mech.h"
00018 #include "mech.events.h"
00019 #include "mech.tech.h"
00020 #include "mech.tech.damages.h"
00021 #include "coolmenu.h"
00022 #include "mycool.h"
00023 #include "failures.h"
00024 #include "p.mech.utils.h"
00025 #include "p.mech.tech.commands.h"
00026 #include "p.mech.status.h"
00027 #include "p.mech.build.h"
00028 
00029 /* 0 = type, 1 = loc, 2 = (pos/amnt), 3 = (val) */
00030 short damage_table[MAX_DAMAGES][3];
00031 int damage_last;
00032 
00033 const char *repair_need_msgs[] = {
00034         "Reattachment",
00035         "Repairs on %s",
00036         "Repairs on %s",
00037         "Repairs on %s",
00038         "Realign focus on %s",
00039         "Charging crystal repairs on %s",
00040         "Barrel repairs on %s",
00041         "Ammo feed repairs on %s",
00042         "Ranging system repairs on %s",
00043         "Ammo feed repairs on %s",
00044         "Replacement of %s",
00045         "Reload of %s (%d rounds)",
00046         "Repairs on armor (%d points)",
00047         "Repairs on rear armor (%d points)",
00048         "Repairs on internals (%d points)",
00049         "Removal of section",
00050         "Removal of %s",
00051         "Removal of %s",
00052         "Unload of %s (%d rounds)",
00053         "Reseal",
00054         "Replace suit",
00055 };
00056 
00057 #define CHECK(loc) check_for_damage(mech,loc)
00058 #define DAMAGE2(a,b) do {\
00059    damage_table[damage_last][0]=a;\
00060    damage_table[damage_last++][1]=b;\
00061  } while (0)
00062 #define DAMAGE3(a,b,c) do {\
00063    damage_table[damage_last][0]=a;\
00064    damage_table[damage_last][1]=b;\
00065    damage_table[damage_last++][2]=c;\
00066  } while (0)
00067 
00068 static int check_for_damage(MECH * mech, int loc)
00069 {
00070         int a, b, c, d;
00071 
00072         if(SectIsDestroyed(mech, loc)) {
00073                 if(MechType(mech) != CLASS_BSUIT)
00074                         DAMAGE2(REATTACH, loc);
00075                 else
00076                         DAMAGE2(REPLACESUIT, loc);
00077                 return 0;
00078         }
00079 
00080         /*
00081          * Added by Kipsta
00082          * 8/4/99
00083          */
00084 
00085         if(SectIsFlooded(mech, loc)) {
00086                 DAMAGE2(RESEAL, loc);
00087                 return 0;
00088         }
00089         if((a = GetSectInt(mech, loc)) != (b = GetSectOInt(mech, loc)))
00090                 DAMAGE3(FIXINTERNAL, loc, (b - a));
00091         else {
00092                 if((a = GetSectArmor(mech, loc)) != (b = GetSectOArmor(mech, loc)))
00093                         DAMAGE3(FIXARMOR, loc, (b - a));
00094                 if((a = GetSectRArmor(mech, loc)) != (b = GetSectORArmor(mech, loc)))
00095                         DAMAGE3(FIXARMOR_R, loc, (b - a));
00096         }
00097         for(a = 0; a < NUM_CRITICALS; a++) {
00098                 if(!(b = GetPartType(mech, loc, a)))
00099                         continue;
00100                 if(IsAmmo(b) && !PartIsDestroyed(mech, loc, a) &&
00101                    (c = GetPartData(mech, loc, a)) != (d = FullAmmo(mech, loc, a)))
00102                         DAMAGE3(RELOAD, loc, a);
00103                 if(!PartIsNonfunctional(mech, loc, a) &&
00104                    !PartTempNuke(mech, loc, a) && !PartIsDamaged(mech, loc, a))
00105                         continue;
00106                 if(IsCrap(b))
00107                         continue;
00108                 /* Destroyed / tempnuke'd part. Either case, it works for us :) */
00109 
00110                 if(PartIsDamaged(mech, loc, a)) {
00111                         if(GetPartDamageFlags(mech, loc, a) & WEAP_DAM_EN_FOCUS)
00112                                 DAMAGE3(ENHCRIT_FOCUS, loc, a);
00113                         else if(GetPartDamageFlags(mech, loc, a) & WEAP_DAM_EN_CRYSTAL)
00114                                 DAMAGE3(ENHCRIT_CRYSTAL, loc, a);
00115                         else if(GetPartDamageFlags(mech, loc, a) & WEAP_DAM_BALL_BARREL)
00116                                 DAMAGE3(ENHCRIT_BARREL, loc, a);
00117                         else if(GetPartDamageFlags(mech, loc, a) & WEAP_DAM_BALL_AMMO)
00118                                 DAMAGE3(ENHCRIT_AMMOB, loc, a);
00119                         else if(GetPartDamageFlags(mech, loc, a) & WEAP_DAM_MSL_RANGING)
00120                                 DAMAGE3(ENHCRIT_RANGING, loc, a);
00121                         else if(GetPartDamageFlags(mech, loc, a) & WEAP_DAM_MSL_AMMO)
00122                                 DAMAGE3(ENHCRIT_AMMOM, loc, a);
00123                         else
00124                                 DAMAGE3(ENHCRIT_MISC, loc, a);
00125 
00126                 } else if(IsWeapon(b) && GetWeaponCrits(mech, Weapon2I(b)) > 4 &&
00127                                   !PartIsDestroyed(mech, loc, a + 1))
00128                         DAMAGE3(REPAIRP_T, loc, a);
00129                 else
00130                         DAMAGE3(IsWeapon(b) ? REPAIRG : REPAIRP, loc, a);
00131 
00132                 if(IsWeapon(b))
00133                         a += GetWeaponCrits(mech, Weapon2I(b)) - 1;
00134         }
00135         return 1;
00136 }
00137 
00138 static int check_for_scrappage(MECH * mech, int loc)
00139 {
00140         int a, b;
00141         int ret = 1;
00142 
00143         if(SectIsDestroyed(mech, loc))
00144                 return 1;
00145 
00146         if(SomeoneScrappingLoc(mech, loc)) {
00147                 DAMAGE2(DETACH, loc);
00148                 return 1;
00149         }
00150         for(a = 0; a < NUM_CRITICALS; a++) {
00151                 if(!(b = GetPartType(mech, loc, a)))
00152                         continue;
00153                 if(PartIsBroken(mech, loc, a))
00154                         continue;
00155                 if(IsCrap(b))
00156                         continue;
00157                 if(IsAmmo(b) && GetPartData(mech, loc, a)) {
00158                         DAMAGE3(UNLOAD, loc, a);
00159                         if(ret && !SomeoneRepairing(mech, loc, a))
00160                                 ret = 0;
00161                         continue;
00162                 }
00163                 DAMAGE3(IsWeapon(b) ? SCRAPG : SCRAPP, loc, a);
00164                 if(ret && !SomeoneScrappingPart(mech, loc, a))
00165                         ret = 0;
00166                 if(IsWeapon(b))
00167                         a += GetWeaponCrits(mech, Weapon2I(b)) - 1;
00168         }
00169 
00170         if(ret && !Invalid_Scrap_Path(mech, loc))
00171                 DAMAGE2(DETACH, loc);
00172 
00173         return 0;
00174 }
00175 
00176 void make_scrap_table(MECH * mech)
00177 {
00178         int i = 4;
00179 
00180         damage_last = 0;
00181         if(MechType(mech) == CLASS_MECH) {
00182                 if(check_for_scrappage(mech, RARM))
00183                         i -= check_for_scrappage(mech, RTORSO);
00184                 if(check_for_scrappage(mech, LARM))
00185                         i -= check_for_scrappage(mech, LTORSO);
00186                 i -= check_for_scrappage(mech, RLEG);
00187                 i -= check_for_scrappage(mech, LLEG);
00188 
00189                 if(!i)
00190                         check_for_scrappage(mech, CTORSO);
00191 
00192                 check_for_scrappage(mech, HEAD);
00193         } else
00194                 for(i = 0; i < NUM_SECTIONS; i++)
00195                         if(GetSectOInt(mech, i))
00196                                 check_for_scrappage(mech, i);
00197 }
00198 
00199 void make_damage_table(MECH * mech)
00200 {
00201         int i;
00202 
00203         damage_last = 0;
00204         if(MechType(mech) == CLASS_MECH) {
00205                 if(check_for_damage(mech, CTORSO)) {
00206                         if(check_for_damage(mech, LTORSO)) {
00207                                 CHECK(LARM);
00208                         }
00209                         if(check_for_damage(mech, RTORSO)) {
00210                                 CHECK(RARM);
00211                         }
00212                         CHECK(LLEG);
00213                         CHECK(RLEG);
00214                         CHECK(HEAD);
00215                 }
00216         } else
00217                 for(i = 0; i < NUM_SECTIONS; i++)
00218                         if(GetSectOInt(mech, i))
00219                                 check_for_damage(mech, i);
00220 }
00221 
00222 int is_under_repair(MECH * mech, int i)
00223 {
00224         int v1 = damage_table[i][1];
00225         int v2 = damage_table[i][2];
00226 
00227         switch (damage_table[i][0]) {
00228         case RELOAD:
00229         case REPAIRP:
00230         case REPAIRP_T:
00231         case REPAIRG:
00232         case UNLOAD:
00233         case ENHCRIT_MISC:
00234         case ENHCRIT_FOCUS:
00235         case ENHCRIT_CRYSTAL:
00236         case ENHCRIT_BARREL:
00237         case ENHCRIT_AMMOB:
00238         case ENHCRIT_RANGING:
00239         case ENHCRIT_AMMOM:
00240                 return SomeoneRepairing(mech, v1, v2);
00241         case REATTACH:
00242                 return SomeoneAttaching(mech, v1);
00243         case RESEAL:
00244                 return SomeoneResealing(mech, v1);
00245         case FIXARMOR_R:
00246                 return SomeoneFixing(mech, v1 + 8);
00247         case FIXARMOR:
00248         case FIXINTERNAL:
00249                 return SomeoneFixing(mech, v1);
00250         case DETACH:
00251                 return SomeoneScrappingLoc(mech, v1);
00252         case SCRAPP:
00253         case SCRAPG:
00254                 return SomeoneScrappingPart(mech, v1, v2);
00255         case REPLACESUIT:
00256                 return SomeoneReplacingSuit(mech, v1);
00257         }
00258         return 0;
00259 }
00260 
00261 char *damages_func(MECH * mech)
00262 {
00263         static char buffer[MBUF_SIZE];
00264         int i;
00265 
00266         if(unit_is_fixable(mech))
00267                 make_damage_table(mech);
00268         else
00269                 make_scrap_table(mech);
00270 
00271         buffer[0] = '\0';
00272         if(!damage_last)
00273                 return "";
00274         for(i = 0; i < damage_last; i++) {
00275                 /* Ok... i think we want: */
00276                 /* repairnum|location|typenum|data|fixing? */
00277                 if(i)
00278                         sprintf(buffer, "%s,", buffer);
00279                 sprintf(buffer, "%s%d|%s|%d|", buffer, i + 1,
00280                                 ShortArmorSectionString(MechType(mech), MechMove(mech),
00281                                                                                 damage_table[i][1]),
00282                                 (int) damage_table[i][0]);
00283                 switch (damage_table[i][0]) {
00284                 case REPAIRP:
00285                 case REPAIRP_T:
00286                 case REPAIRG:
00287                 case ENHCRIT_MISC:
00288                 case ENHCRIT_FOCUS:
00289                 case ENHCRIT_CRYSTAL:
00290                 case ENHCRIT_BARREL:
00291                 case ENHCRIT_AMMOB:
00292                 case ENHCRIT_RANGING:
00293                 case ENHCRIT_AMMOM:
00294                 case SCRAPP:
00295                 case SCRAPG:
00296                         sprintf(buffer, "%s%s", buffer, pos_part_name(mech,
00297                                                                                                                   damage_table[i][1],
00298                                                                                                                   damage_table[i]
00299                                                                                                                   [2]));
00300                         break;
00301                 case RELOAD:
00302                         sprintf(buffer, "%s%s:%d", buffer, pos_part_name(mech,
00303                                                                                                                          damage_table[i]
00304                                                                                                                          [1],
00305                                                                                                                          damage_table[i]
00306                                                                                                                          [2]),
00307                                         FullAmmo(mech, damage_table[i][1],
00308                                                          damage_table[i][2]) - GetPartData(mech,
00309                                                                                                                            damage_table[i]
00310                                                                                                                            [1],
00311                                                                                                                            damage_table[i]
00312                                                                                                                            [2]));
00313                         break;
00314                 case UNLOAD:
00315                         sprintf(buffer, "%s%s:%d", buffer, pos_part_name(mech,
00316                                                                                                                          damage_table[i]
00317                                                                                                                          [1],
00318                                                                                                                          damage_table[i]
00319                                                                                                                          [2]),
00320                                         GetPartData(mech, damage_table[i][1], damage_table[i]
00321                                                                 [2]));
00322                         break;
00323                 case FIXARMOR:
00324                 case FIXARMOR_R:
00325                 case FIXINTERNAL:
00326                         sprintf(buffer, "%s%d", buffer, damage_table[i][2]);
00327                         break;
00328                 default:
00329                         sprintf(buffer, "%s-", buffer);
00330                 }
00331                 sprintf(buffer, "%s|%d", buffer, is_under_repair(mech, i));
00332         }
00333         return buffer;
00334 }
00335 
00336 void show_mechs_damage(dbref player, void *data, char *buffer)
00337 {
00338         MECH *mech = data;
00339         coolmenu *c = NULL;
00340         int i, j, v1, v2;
00341         char buf[MBUF_SIZE];
00342         char buf2[MBUF_SIZE];
00343         int isds;
00344 
00345         TECHCOMMANDD;
00346         if(unit_is_fixable(mech))
00347                 make_damage_table(mech);
00348         else
00349                 make_scrap_table(mech);
00350         DOCHECK(!damage_last &&
00351                         MechType(mech) == CLASS_MECH,
00352                         "The 'mech is in pristine condition!");
00353         DOCHECK(!damage_last, "It's in pristine condition!");
00354         addline();
00355         cent(tprintf("Damage for %s", GetMechID(mech)));
00356         addline();
00357         for(i = 0; i < damage_last; i++) {
00358                 v1 = damage_table[i][1];
00359                 v2 = damage_table[i][2];
00360                 switch (damage_table[i][0]) {
00361                 case REATTACH:
00362                 case DETACH:
00363                 case RESEAL:
00364                 case REPLACESUIT:
00365                         strcpy(buf, repair_need_msgs[(int) damage_table[i][0]]);
00366                         break;
00367                 case REPAIRP:
00368                 case REPAIRP_T:
00369                 case REPAIRG:
00370                 case ENHCRIT_MISC:
00371                 case ENHCRIT_FOCUS:
00372                 case ENHCRIT_CRYSTAL:
00373                 case ENHCRIT_BARREL:
00374                 case ENHCRIT_AMMOB:
00375                 case ENHCRIT_RANGING:
00376                 case ENHCRIT_AMMOM:
00377                 case SCRAPP:
00378                 case SCRAPG:
00379                         sprintf(buf, repair_need_msgs[(int) damage_table[i][0]],
00380                                         pos_part_name(mech, v1, v2));
00381                         break;
00382                 case RELOAD:
00383                         sprintf(buf, repair_need_msgs[(int) damage_table[i][0]],
00384                                         pos_part_name(mech, v1, v2), FullAmmo(mech, v1,
00385                                                                                                                   v2) -
00386                                         GetPartData(mech, v1, v2));
00387                         break;
00388                 case UNLOAD:
00389                         sprintf(buf, repair_need_msgs[(int) damage_table[i][0]],
00390                                         pos_part_name(mech, v1, v2), GetPartData(mech, v1, v2));
00391                         break;
00392                 case FIXARMOR:
00393                 case FIXARMOR_R:
00394                 case FIXINTERNAL:
00395                         sprintf(buf, repair_need_msgs[(int) damage_table[i][0]],
00396                                         damage_table[i][2]);
00397                         break;
00398                 }
00399                 j = is_under_repair(mech, i);
00400                 sprintf(buf2, "%%ch%s%-2d:%s %%cn%s%s", j ? "%cg" : "%cy", i + 1,
00401                                 ShortArmorSectionString(MechType(mech), MechMove(mech), v1),
00402                                 buf, j ? " (*)" : "");
00403                 vsi(buf2);
00404         }
00405         addline();
00406         vsi("(*) / %ch%cgGreen%cn = Job already done. %ch%cyYellow%cn = To be done.");
00407         addline();
00408         ShowCoolMenu(player, c);
00409         KillCoolMenu(c);
00410 }
00411 
00412 static void fix_entry(dbref player, MECH * mech, int n)
00413 {
00414         char buf[MBUF_SIZE];
00415         char *c;
00416 
00417         /* whee */
00418         n--;
00419         c = ShortArmorSectionString(MechType(mech), MechMove(mech),
00420                                                                 damage_table[n][1]);
00421         switch (damage_table[n][0]) {
00422         case REPAIRP_T:
00423                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00424                 tech_repairgun(player, mech, buf);
00425                 break;
00426         case ENHCRIT_MISC:
00427         case ENHCRIT_FOCUS:
00428         case ENHCRIT_CRYSTAL:
00429         case ENHCRIT_BARREL:
00430         case ENHCRIT_AMMOB:
00431         case ENHCRIT_RANGING:
00432         case ENHCRIT_AMMOM:
00433                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00434                 tech_fixenhcrit(player, mech, buf);
00435                 break;
00436         case REPAIRG:
00437                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00438                 tech_replacegun(player, mech, buf);
00439                 break;
00440         case REPAIRP:
00441                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00442                 tech_replacepart(player, mech, buf);
00443                 break;
00444         case RELOAD:
00445                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00446                 tech_reload(player, mech, buf);
00447                 break;
00448         case REATTACH:
00449                 sprintf(buf, "%s", c);
00450                 tech_reattach(player, mech, buf);
00451                 break;
00452         case RESEAL:
00453                 sprintf(buf, "%s", c);
00454                 tech_reseal(player, mech, buf);
00455                 break;
00456         case FIXARMOR:
00457                 sprintf(buf, "%s", c);
00458                 tech_fixarmor(player, mech, buf);
00459                 break;
00460         case FIXARMOR_R:
00461                 sprintf(buf, "%s r", c);
00462                 tech_fixarmor(player, mech, buf);
00463                 break;
00464         case FIXINTERNAL:
00465                 sprintf(buf, "%s", c);
00466                 tech_fixinternal(player, mech, buf);
00467                 break;
00468         case DETACH:
00469                 sprintf(buf, "%s", c);
00470                 tech_removesection(player, mech, buf);
00471                 break;
00472         case SCRAPP:
00473                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00474                 tech_removepart(player, mech, buf);
00475                 break;
00476         case SCRAPG:
00477                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00478                 tech_removegun(player, mech, buf);
00479                 break;
00480         case UNLOAD:
00481                 sprintf(buf, "%s %d", c, damage_table[n][2] + 1);
00482                 tech_unload(player, mech, buf);
00483                 break;
00484         case REPLACESUIT:
00485                 sprintf(buf, "%s", c);
00486                 tech_replacesuit(player, mech, buf);
00487                 break;
00488         }
00489 }
00490 
00491 void tech_fix(dbref player, void *data, char *buffer)
00492 {
00493         MECH *mech = data;
00494         int n = atoi(buffer);
00495         int low, high;
00496         int isds;
00497 
00498         skipws(buffer);
00499         TECHCOMMANDC;
00500         if(unit_is_fixable(mech))
00501                 make_damage_table(mech);
00502         else
00503                 make_scrap_table(mech);
00504         DOCHECK(!damage_last &&
00505                         MechType(mech) == CLASS_MECH,
00506                         "The 'mech is in pristine condition!");
00507         DOCHECK(!damage_last, "It's in pristine condition!");
00508         if(sscanf(buffer, "%d-%d", &low, &high) == 2) {
00509                 DOCHECK(low < 1 || low > damage_last, "Invalid low #!");
00510                 DOCHECK(high < 1 || high > damage_last, "Invalid high #!");
00511                 for(n = low; n <= high; n++)
00512                         fix_entry(player, mech, n);
00513                 return;
00514         }
00515         DOCHECK(n < 1 || n > damage_last, "Invalid #!");
00516         fix_entry(player, mech, n);
00517 }

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