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 "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
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
00082
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
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
00276
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
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 }