00001
00002
00003
00004
00005
00006
00007 #include "config.h"
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <math.h>
00012 #include <sys/file.h>
00013 #include <dirent.h>
00014 #include <sys/stat.h>
00015
00016 #define MECH_STAT_C
00017
00018 #include "externs.h"
00019 #include "mech.h"
00020 #include "mechrep.h"
00021 #include "create.h"
00022 #include "p.mech.build.h"
00023 #include "p.mech.status.h"
00024 #include "p.template.h"
00025 #include "p.mechrep.h"
00026 #include "p.mech.restrict.h"
00027 #include "p.mech.consistency.h"
00028 #include "p.mech.utils.h"
00029 #include "mech.events.h"
00030
00031
00032 #define SPECIAL_FREE 0
00033 #define SPECIAL_ALLOC 1
00034
00035 extern char *strtok(char *s, const char *ct);
00036
00037
00038 extern void *FindObjectsData(dbref key);
00039 dbref match_thing(dbref player, char *name);
00040 void muxevent_remove_data(void *data);
00041
00042 #define MECHREP_COMMON(a) \
00043 struct mechrep_data *rep = (struct mechrep_data *) data; \
00044 MECH *mech; \
00045 DOCHECK(!Template(player), "I'm sorry Dave, can't do that."); \
00046 if (!CheckData(player, rep)) return; \
00047 if (a) { DOCHECK(rep->current_target == -1, "You must set a target first!"); \
00048 mech = getMech (rep->current_target); \
00049 if (!CheckData(player, mech)) return; }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 void newfreemechrep(dbref key, void **data, int selector)
00062 {
00063 struct mechrep_data *new = *data;
00064
00065 switch (selector) {
00066 case SPECIAL_ALLOC:
00067 new->current_target = -1;
00068 break;
00069 }
00070 }
00071
00072
00073
00074 void mechrep_Rresetcrits(dbref player, void *data, char *buffer)
00075 {
00076 int i;
00077
00078 MECHREP_COMMON(1);
00079 notify(player, "Default criticals set!");
00080 for(i = 0; i < NUM_SECTIONS; i++)
00081 FillDefaultCriticals(mech, i);
00082 }
00083
00084 void mechrep_Rdisplaysection(dbref player, void *data, char *buffer)
00085 {
00086 char *args[1];
00087 int index;
00088
00089 MECHREP_COMMON(1);
00090 DOCHECK(mech_parseattributes(buffer, args, 1) != 1,
00091 "You must specify a section to list the criticals for!");
00092 index = ArmorSectionFromString(MechType(mech), MechMove(mech), args[0]);
00093 DOCHECK(index == -1, "Invalid section!");
00094 CriticalStatus(player, mech, index);
00095 }
00096
00097 #define MechComputersRadioRange(mech) \
00098 (DEFAULT_RADIORANGE * generic_radio_multiplier(mech))
00099
00100 void mechrep_Rsetradio(dbref player, void *data, char *buffer)
00101 {
00102 char *args[2];
00103 int i;
00104
00105 MECHREP_COMMON(1);
00106 switch (mech_parseattributes(buffer, args, 2)) {
00107 case 0:
00108 notify(player,
00109 "This remains to be done [showing of stuff when no args]");
00110 return;
00111 case 2:
00112 notify(player, "Too many args, unable to cope().");
00113 return;
00114 }
00115 i = BOUNDED(1, atoi(args[0]), 5);
00116 notify_printf(player, "Radio level set to %d.", i);
00117 MechRadio(mech) = i;
00118 MechRadioType(mech) = generic_radio_type(MechRadio(mech), 0);
00119 notify_printf(player, "Number of freqs: %d Extra stuff: %d",
00120 MechRadioType(mech) % 16, (MechRadioType(mech) / 16) * 16);
00121 MechRadioRange(mech) = MechComputersRadioRange(mech);
00122 notify_printf(player, "Radio range set to %d.",
00123 (int) MechRadioRange(mech));
00124 }
00125
00126 void mechrep_Rsettarget(dbref player, void *data, char *buffer)
00127 {
00128 char *args[2];
00129 int newmech;
00130
00131 MECHREP_COMMON(0);
00132 switch (mech_parseattributes(buffer, args, 2)) {
00133 case 1:
00134 newmech = match_thing(player, args[0]);
00135 DOCHECK(!(Good_obj(newmech) &&
00136 Hardcode(newmech)), "That is not a BattleMech or Vehicle!");
00137 rep->current_target = newmech;
00138 notify_printf(player, "Mech to repair changed to #%d", newmech);
00139 break;
00140 default:
00141 notify(player, "Too many arguments!");
00142 }
00143 }
00144
00145 void mechrep_Rsettype(dbref player, void *data, char *buffer)
00146 {
00147 char *args[1];
00148
00149 MECHREP_COMMON(1);
00150 DOCHECK(mech_parseattributes(buffer, args, 1) != 1,
00151 "Invalid number of arguments!");
00152 switch (toupper(args[0][0])) {
00153 case 'M':
00154 MechType(mech) = CLASS_MECH;
00155 MechMove(mech) = MOVE_BIPED;
00156 notify(player, "Type set to MECH");
00157 break;
00158 case 'Q':
00159 MechType(mech) = CLASS_MECH;
00160 MechMove(mech) = MOVE_QUAD;
00161 notify(player, "Type set to QUAD");
00162 break;
00163 case 'G':
00164 MechType(mech) = CLASS_VEH_GROUND;
00165 notify(player, "Type set to VEHICLE");
00166 break;
00167 case 'V':
00168 MechType(mech) = CLASS_VTOL;
00169 MechMove(mech) = MOVE_VTOL;
00170 notify(player, "Type set to VTOL");
00171 break;
00172 case 'N':
00173 MechType(mech) = CLASS_VEH_NAVAL;
00174 notify(player, "Type set to NAVAL");
00175 break;
00176 case 'A':
00177 MechType(mech) = CLASS_AERO;
00178 MechMove(mech) = MOVE_FLY;
00179 notify(player, "Type set to AeroSpace");
00180 break;
00181 case 'D':
00182 MechType(mech) = CLASS_DS;
00183 MechMove(mech) = MOVE_FLY;
00184 notify(player, "Type set to DropShip");
00185 break;
00186 case 'S':
00187 MechType(mech) = CLASS_SPHEROID_DS;
00188 MechMove(mech) = MOVE_FLY;
00189 notify(player, "Type set to SpheroidDropship");
00190 break;
00191 case 'B':
00192 MechType(mech) = CLASS_BSUIT;
00193 MechMove(mech) = MOVE_BIPED;
00194 notify(player, "Type set to BattleSuit");
00195 break;
00196 default:
00197 notify(player,
00198 "Types are: MECH, GROUND, VTOL, NAVAL, AERO, DROPSHIP and SPHEROIDDROPSHIP");
00199 break;
00200 }
00201 }
00202
00203 #define SETVALUE_FUNCTION_FLOAT(funcname,valname,valstring,modifier) \
00204 void funcname (dbref player, void *data, char *buffer) \
00205 { char *args[1]; float f; MECHREP_COMMON(1); \
00206 DOCHECK(mech_parseattributes (buffer, args, 1) != 1, \
00207 tprintf("Invalid number of arguments to Set%s!", valstring)); \
00208 f = atof(args[0]); \
00209 valname = f * modifier; \
00210 notify(player, tprintf("%s changed to %.2f.", valstring, valname)); \
00211 }
00212
00213 #define SETVALUE_FUNCTION_INT(funcname,valname,valstring,modifier) \
00214 void funcname (dbref player, void *data, char *buffer) \
00215 { char *args[1]; int f; MECHREP_COMMON(1); \
00216 DOCHECK(mech_parseattributes (buffer, args, 1) != 1, \
00217 tprintf("Invalid number of arguments to Set%s!", valstring)); \
00218 f = atoi(args[0]); \
00219 valname = f * modifier; \
00220 notify(player, tprintf("%s changed to %d.", valstring, valname)); \
00221 }
00222
00223 SETVALUE_FUNCTION_FLOAT(mechrep_Rsetspeed, MechMaxSpeed(mech), "Maxspeed",
00224 KPH_PER_MP);
00225 SETVALUE_FUNCTION_FLOAT(mechrep_Rsetjumpspeed, MechJumpSpeed(mech),
00226 "Jumpspeed", KPH_PER_MP);
00227 SETVALUE_FUNCTION_INT(mechrep_Rsetheatsinks, MechRealNumsinks(mech),
00228 "Heatsinks", 1);
00229 SETVALUE_FUNCTION_INT(mechrep_Rsetlrsrange, MechLRSRange(mech), "LRSrange",
00230 1);
00231 SETVALUE_FUNCTION_INT(mechrep_Rsettacrange, MechTacRange(mech), "TACrange",
00232 1);
00233 SETVALUE_FUNCTION_INT(mechrep_Rsetscanrange, MechScanRange(mech),
00234 "SCANrange", 1);
00235 SETVALUE_FUNCTION_INT(mechrep_Rsetradiorange, MechRadioRange(mech),
00236 "RADIOrange", 1);
00237 SETVALUE_FUNCTION_INT(mechrep_Rsettons, MechTons(mech), "Tons", 1);
00238
00239 void mechrep_Rsetmove(dbref player, void *data, char *buffer)
00240 {
00241 char *args[1];
00242
00243 MECHREP_COMMON(1);
00244 DOCHECK(mech_parseattributes(buffer, args, 1) != 1,
00245 "Invalid number of arguments!");
00246 switch (toupper(args[0][0])) {
00247 case 'T':
00248 MechMove(mech) = MOVE_TRACK;
00249 notify(player, "Movement set to TRACKED");
00250 break;
00251 case 'W':
00252 MechMove(mech) = MOVE_WHEEL;
00253 notify(player, "Movement set to WHEELED");
00254 break;
00255 case 'H':
00256 switch (toupper(args[0][1])) {
00257 case 'O':
00258 MechMove(mech) = MOVE_HOVER;
00259 notify(player, "Movement set to HOVER");
00260 break;
00261 case 'U':
00262 MechMove(mech) = MOVE_HULL;
00263 notify(player, "Movement set to HULL");
00264 break;
00265 }
00266 break;
00267 case 'V':
00268 MechMove(mech) = MOVE_VTOL;
00269 notify(player, "Movement set to VTOL");
00270 break;
00271 case 'Q':
00272 MechMove(mech) = MOVE_QUAD;
00273 notify(player, "Movement set to QUAD");
00274 break;
00275 case 'B':
00276 MechMove(mech) = MOVE_BIPED;
00277 notify(player, "Movement set to BIPED");
00278 break;
00279 case 'S':
00280 MechMove(mech) = MOVE_SUB;
00281 notify(player, "Movement set to SUB");
00282 break;
00283 case 'F':
00284 switch (toupper(args[0][1])) {
00285 case 'O':
00286 MechMove(mech) = MOVE_FOIL;
00287 notify(player, "Movement set to FOIL");
00288 break;
00289 case 'L':
00290 MechMove(mech) = MOVE_FLY;
00291 notify(player, "Movement set to FLY");
00292 break;
00293 }
00294 case 'N':
00295 MechMove(mech) = MOVE_NONE;
00296 notify(player, "Movement set to NONE");
00297 break;
00298 default:
00299 notify(player,
00300 "Types are: TRACK, WHEEL, VTOL, QUAD, BIPED, HOVER, HULL, FLY, SUB, FOIL and NONE");
00301 break;
00302 }
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 enum {
00324 CACHE_MAXNAME = 24,
00325 MECH_MAXREF = 14
00326 };
00327
00328 struct tmpldirent {
00329 char name[CACHE_MAXNAME + 1];
00330 char const *dir;
00331 };
00332
00333 struct tmpldir {
00334 char name[CACHE_MAXNAME + 1];
00335 struct tmpldir *next;
00336 };
00337
00338 struct tmpldirent *tmpl_list = NULL;
00339 int tmpl_pos = 0;
00340 int tmpl_len = 0;
00341
00342 struct tmpldir *tmpldir_list = NULL;
00343
00344
00345
00346
00347
00348 static int tmplcmp(void const *v1, void const *v2)
00349 {
00350 struct tmpldirent const *p1 = v1;
00351 struct tmpldirent const *p2 = v2;
00352
00353 return strncasecmp(p1->name, p2->name, MECH_MAXREF);
00354 }
00355
00356
00357
00358
00359 static int scan_template_dir(char const *dirname, char const *parent)
00360 {
00361 char buf[1000];
00362 int dirnamelen = strlen(dirname);
00363 DIR *dir = opendir(dirname);
00364
00365 if(dir == NULL) {
00366 return -1;
00367 }
00368
00369 while (1) {
00370 struct stat sb;
00371 struct dirent *ent = readdir(dir);
00372
00373 if(ent == NULL) {
00374 break;
00375 }
00376
00377 if(dirnamelen + 1 + strlen(ent->d_name) + 1 > sizeof buf) {
00378 continue;
00379 }
00380
00381 sprintf(buf, "%s/%s", dirname, ent->d_name);
00382 if(stat(buf, &sb) == -1) {
00383 continue;
00384 }
00385
00386 if(parent == NULL && S_ISDIR(sb.st_mode)
00387 && ent->d_name[0] != '.' && strlen(ent->d_name) <= CACHE_MAXNAME) {
00388 struct tmpldir *link;
00389
00390 Create(link, struct tmpldir, 1);
00391
00392 strcpy(link->name, ent->d_name);
00393 link->next = tmpldir_list;
00394 tmpldir_list = link;
00395 continue;
00396 }
00397
00398 if(!S_ISREG(sb.st_mode)) {
00399 continue;
00400 }
00401
00402 if(tmpl_pos == tmpl_len) {
00403 if(tmpl_len == 0) {
00404 tmpl_len = 4;
00405 Create(tmpl_list, struct tmpldirent, tmpl_len);
00406 } else {
00407 tmpl_len *= 2;
00408 ReCreate(tmpl_list, struct tmpldirent, tmpl_len);
00409 }
00410 }
00411
00412 strncpy(tmpl_list[tmpl_pos].name, ent->d_name, CACHE_MAXNAME);
00413 tmpl_list[tmpl_pos].name[CACHE_MAXNAME] = '\0';
00414 tmpl_list[tmpl_pos].dir = parent;
00415 tmpl_pos++;
00416 }
00417
00418 closedir(dir);
00419 return 0;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 static int scan_templates(char const *dir)
00429 {
00430 char buf[1000];
00431 struct tmpldir *p;
00432
00433 if(scan_template_dir(dir, NULL) == -1) {
00434 return -1;
00435 }
00436
00437 p = tmpldir_list;
00438 while (p != NULL) {
00439 sprintf(buf, "%s/%s", dir, p->name);
00440 scan_template_dir(buf, p->name);
00441 p = p->next;
00442 }
00443
00444 qsort(tmpl_list, tmpl_pos, sizeof tmpl_list[0], tmplcmp);
00445
00446 return 0;
00447 }
00448
00449
00450
00451
00452
00453 static void free_template_list()
00454 {
00455 struct tmpldir *p;
00456
00457 free(tmpl_list);
00458
00459 p = tmpldir_list;
00460 while (p != NULL) {
00461 struct tmpldir *np = p->next;
00462
00463 free(p);
00464 p = np;
00465 }
00466
00467 tmpl_list = NULL;
00468 tmpldir_list = NULL;
00469 tmpl_pos = 0;
00470 tmpl_len = 0;
00471
00472 return;
00473 }
00474
00475 char *subdirs[] = {
00476 "3025",
00477 "3050",
00478 "3055",
00479 "3058",
00480 "3060",
00481 "2750",
00482 "Aero",
00483 "MISC",
00484 "Clan",
00485 "ClanVehicles",
00486 "Clan2nd",
00487 "ClanAero",
00488 "Custom",
00489 "Solaris",
00490 "Vehicles",
00491 "MFNA",
00492 "Infantry",
00493 NULL
00494 };
00495
00496 void mechrep_Rloadnew(dbref player, void *data, char *buffer)
00497 {
00498 char *args[1];
00499
00500 MECHREP_COMMON(1);
00501 if(mech_parseattributes(buffer, args, 1) == 1)
00502 if(mech_loadnew(player, mech, args[0]) == 1) {
00503 muxevent_remove_data((void *) mech);
00504 clear_mech_from_LOS(mech);
00505 notify(player, "Template loaded.");
00506 return;
00507 }
00508 notify(player, "Unable to read that template.");
00509 }
00510
00511 void clear_mech(MECH * mech, int flag)
00512 {
00513 int i, j;
00514
00515 mech->brief = 1;
00516
00517 bzero(&mech->rd, sizeof(mech_rd));
00518 bzero(&mech->ud, sizeof(mech_ud));
00519
00520 MechSpotter(mech) = -1;
00521 MechTarget(mech) = -1;
00522 MechChargeTarget(mech) = -1;
00523 MechChargeTimer(mech) = 0;
00524 MechChargeDistance(mech) = 0;
00525 MechSwarmTarget(mech) = -1;
00526 MechSwarmer(mech) = -1;
00527 MechDFATarget(mech) = -1;
00528 MechTargX(mech) = -1;
00529 MechStatus(mech) = 0;
00530 MechTargY(mech) = -1;
00531 MechPilot(mech) = -1;
00532 MechAim(mech) = NUM_SECTIONS;
00533 StopBurning(mech);
00534 if(flag) {
00535 for(i = 0; i < NUM_TICS; i++)
00536 for(j = 0; j < TICLONGS; j++)
00537 mech->tic[i][j] = 0;
00538 for(i = 0; i < FREQS; i++) {
00539 mech->freq[i] = 0;
00540 mech->freqmodes[i] = 0;
00541 mech->chantitle[i][0] = 0;
00542 }
00543 }
00544 }
00545
00546 char *mechref_path(char *id)
00547 {
00548 static char openfile[1024];
00549 FILE *fp;
00550 int i = 0;
00551
00552
00553
00554
00555
00556 redo:
00557 if(strchr(id, '/') == NULL && (tmpl_list != NULL ||
00558 scan_templates(MECH_PATH) != -1)) {
00559 struct tmpldirent *ent;
00560 struct tmpldirent key;
00561
00562 strncpy(key.name, id, CACHE_MAXNAME);
00563 key.name[CACHE_MAXNAME] = '\0';
00564
00565 ent =
00566 bsearch(&key, tmpl_list, tmpl_pos, sizeof tmpl_list[0], tmplcmp);
00567 if(ent == NULL) {
00568 return NULL;
00569 }
00570 if(ent->dir == NULL) {
00571 sprintf(openfile, "%s/%s", MECH_PATH, ent->name);
00572 } else {
00573 sprintf(openfile, "%s/%s/%s", MECH_PATH, ent->dir, ent->name);
00574 }
00575 if(access(openfile, R_OK) != 0) {
00576
00577
00578
00579 if(!i) {
00580 i = 1;
00581 free_template_list();
00582 goto redo;
00583 } else
00584 goto oldstyle;
00585 }
00586 return openfile;
00587 }
00588 oldstyle:
00589
00590
00591
00592 sprintf(openfile, "%s/%s", MECH_PATH, id);
00593 fp = fopen(openfile, "r");
00594 for(i = 0; !fp && subdirs[i]; i++) {
00595 sprintf(openfile, "%s/%s/%s", MECH_PATH, subdirs[i], id);
00596 fp = fopen(openfile, "r");
00597 }
00598 if(fp) {
00599 fclose(fp);
00600 return openfile;
00601 }
00602 return NULL;
00603 }
00604
00605 int load_mechdata2(dbref player, MECH * mech, char *id)
00606 {
00607 FILE *fp = NULL;
00608 char *filename;
00609
00610 filename = mechref_path(id);
00611
00612 if(!filename)
00613 return 0;
00614 if(!(fp = fopen(filename, "r")))
00615 return 0;
00616 fclose(fp);
00617 return load_template(player, mech, filename) >= 0 ? 1 : 0;
00618 }
00619
00620 extern int num_def_weapons;
00621
00622 int unable_to_find_proper_type(int i)
00623 {
00624 if(!i)
00625 return 0;
00626 if(IsWeapon(i)) {
00627 if(i > (num_def_weapons))
00628 return 1;
00629 }
00630 if(IsAmmo(i)) {
00631 if((Ammo2Weapon(i) + 1) > (num_def_weapons))
00632 return 1;
00633 }
00634 if(IsSpecial(i))
00635 if(Special2I(i) >= count_special_items())
00636 return 1;
00637 return 0;
00638 }
00639
00640 int load_mechdata(MECH * mech, char *id)
00641 {
00642 FILE *fp = NULL;
00643 int i, j, k, t;
00644 int i1, i2, i3, i4, i5, i6;
00645 char *filename;
00646
00647 filename = mechref_path(id);
00648 TEMPLATE_GERR(filename == NULL, tprintf("No matching file for '%s'.",
00649 id));
00650 if(filename)
00651 fp = fopen(filename, "r");
00652 TEMPLATE_GERR(!fp, tprintf("Unable to open file %s (%s)!", filename, id));
00653 strncpy(MechType_Ref(mech), id, 15);
00654 MechType_Ref(mech)[14] = '\0';
00655 TEMPLATE_GERR(fscanf(fp, "%d %d %d %d %d %f %f %d\n", &i1, &i2, &i3,
00656 &i4, &i5, &MechMaxSpeed(mech), &MechJumpSpeed(mech),
00657 &i6) < 8,
00658 "Old template loading system: %s is invalid template file.",
00659 id);
00660 MechTons(mech) = i1;
00661 MechTacRange(mech) = i2;
00662 MechLRSRange(mech) = i3;
00663 MechScanRange(mech) = i4;
00664 MechRealNumsinks(mech) = i5;
00665 #define DROP(a) \
00666 if (i6 & a) i6 &= ~a
00667 DROP(32768);
00668 DROP(16384);
00669 DROP(8192);
00670 DROP(4196);
00671 MechSpecials(mech) = i6;
00672 for(k = 0; k < NUM_SECTIONS; k++) {
00673 i = k;
00674 if(MechType(mech) == 4) {
00675 switch (k) {
00676 case 3:
00677 i = 4;
00678 break;
00679 case 4:
00680 i = 5;
00681 break;
00682 case 5:
00683 i = 3;
00684 break;
00685 }
00686 }
00687 TEMPLATE_GERR(fscanf(fp, "%d %d %d %d\n", &i1, &i2, &i3, &i4) < 4,
00688 "Insufficient data reading section %d!", i);
00689 MechSections(mech)[i].recycle = 0;
00690 SetSectArmor(mech, i, i1);
00691 SetSectOArmor(mech, i, i1);
00692 SetSectInt(mech, i, i2);
00693 SetSectOInt(mech, i, i2);
00694 SetSectRArmor(mech, i, i3);
00695 SetSectORArmor(mech, i, i3);
00696
00697
00698 if(i4 & 4)
00699 i4 &= ~4;
00700 MechSections(mech)[i].config = i4;
00701 for(j = 0; j < NUM_CRITICALS; j++) {
00702 TEMPLATE_GERR(fscanf(fp, "%d %d %d\n", &i1, &i2, &i3) < 3,
00703 "Insufficient data reading critical %d/%d!", i, j);
00704 MechSections(mech)[i].criticals[j].type = i1;
00705 TEMPLATE_GERR(unable_to_find_proper_type(GetPartType(mech, i,
00706 j)),
00707 "Invalid datatype at %d/%d!", i, j);
00708 if(IsSpecial(i1))
00709 i1 += SPECIAL_BASE_INDEX - OSPECIAL_BASE_INDEX;
00710 if(IsWeapon(GetPartType(mech, i, j)) &&
00711 IsAMS((t = Weapon2I(GetPartType(mech, i, j))))) {
00712 if(MechWeapons[t].special & CLAT)
00713 MechSpecials(mech) |= CL_ANTI_MISSILE_TECH;
00714 else
00715 MechSpecials(mech) |= IS_ANTI_MISSILE_TECH;
00716 }
00717 MechSections(mech)[i].criticals[j].data = i2;
00718 MechSections(mech)[i].criticals[j].firemode = i3;
00719 }
00720 }
00721 if(fscanf(fp, "%d %d\n", &i1, &i2) == 2) {
00722 MechType(mech) = i1;
00723 TEMPLATE_GERR(MechType(mech) > CLASS_LAST, "Invalid 'mech type!");
00724 MechMove(mech) = i2;
00725 TEMPLATE_GERR(MechMove(mech) > MOVENEMENT_LAST,
00726 "Invalid movenement type!");
00727 }
00728 if(fscanf(fp, "%d\n", &i1) != 1)
00729 MechRadioRange(mech) = DEFAULT_RADIORANGE;
00730 else
00731 MechRadioRange(mech) = i1;
00732 fclose(fp);
00733 return 1;
00734 }
00735
00736 #undef LOADNEW_LOADS_OLD_IF_FAIL
00737 #define LOADNEW_LOADS_MUSE_FORMAT
00738
00739 int mech_loadnew(dbref player, MECH * mech, char *id)
00740 {
00741 char mech_origid[100];
00742
00743 strncpy(mech_origid, MechType_Ref(mech), 99);
00744 mech_origid[99] = '\0';
00745
00746 if(!strcmp(mech_origid, id)) {
00747 clear_mech(mech, 0);
00748 if(load_mechdata2(player, mech, id) <= 0)
00749 return load_mechdata(mech, id) > 0;
00750 return 1;
00751 } else {
00752 clear_mech(mech, 1);
00753 if(load_mechdata2(player, mech, id) < 1)
00754 #ifdef LOADNEW_LOADS_MUSE_FORMAT
00755 if(load_mechdata(mech, id) < 1)
00756 #endif
00757 #ifdef LOADNEW_LOADS_OLD_IF_FAIL
00758 if(load_mechdata2(player, mech, mech_origid) < 1)
00759 #ifdef LOADNEW_LOADS_MUSE_FORMAT
00760 if(load_mechdata(mech, mech_origid) < 1)
00761 #endif
00762 #endif
00763 return 0;
00764 }
00765 return 1;
00766 }
00767
00768 void mechrep_Rrestore(dbref player, void *data, char *buffer)
00769 {
00770 char *c;
00771
00772 MECHREP_COMMON(1);
00773 c = silly_atr_get(mech->mynum, A_MECHREF);
00774 DOCHECK(!c || !*c, "Sorry, I don't know what type of mech this is");
00775 DOCHECK(mech_loadnew(player, mech, c) == 1, "Restoration complete!");
00776 notify(player, "Unable to restore this mech!.");
00777 }
00778
00779 void mechrep_Rsavetemp(dbref player, void *data, char *buffer)
00780 {
00781 char *args[1];
00782 FILE *fp;
00783 char openfile[512];
00784 int i, j;
00785
00786 MECHREP_COMMON(1);
00787
00788 free_template_list();
00789
00790 DOCHECK(mech_parseattributes(buffer, args, 1) != 1,
00791 "You must specify a template name!");
00792 DOCHECK(strstr(args[0], "/"), "Invalid file name!");
00793 notify_printf(player, "Saving %s...", args[0]);
00794 sprintf(openfile, "%s/", MECH_PATH);
00795 strcat(openfile, args[0]);
00796 DOCHECK(!(fp =
00797 fopen(openfile, "w")),
00798 "Unable to open/create mech file! Sorry.");
00799 fprintf(fp, "%d %d %d %d %d %.2f %.2f %d\n", MechTons(mech),
00800 MechTacRange(mech), MechLRSRange(mech), MechScanRange(mech),
00801 MechRealNumsinks(mech), MechMaxSpeed(mech), MechJumpSpeed(mech),
00802 MechSpecials(mech));
00803 for(i = 0; i < NUM_SECTIONS; i++) {
00804 fprintf(fp, "%d %d %d %d\n", GetSectArmor(mech, i),
00805 GetSectInt(mech, i), GetSectRArmor(mech, i),
00806 MechSections(mech)[i].config);
00807 for(j = 0; j < NUM_CRITICALS; j++) {
00808 fprintf(fp, "%d %d %d\n",
00809 MechSections(mech)[i].criticals[j].type,
00810 MechSections(mech)[i].criticals[j].data,
00811 MechSections(mech)[i].criticals[j].firemode);
00812 }
00813 }
00814 fprintf(fp, "%d %d\n", MechType(mech), MechMove(mech));
00815 fprintf(fp, "%d\n", MechRadioRange(mech));
00816 fclose(fp);
00817 notify(player, "Saving complete!");
00818 }
00819
00820
00821
00822
00823 void mechrep_Rsavetemp2(dbref player, void *data, char *buffer)
00824 {
00825 char *args[1];
00826 char openfile[512];
00827
00828 MECHREP_COMMON(1);
00829
00830 free_template_list();
00831
00832
00833 if(mech_parseattributes(buffer, args, 1) != 1) {
00834 notify(player, "You must specify a template name!");
00835 return;
00836 }
00837
00838
00839 if(strstr(args[0], "/")) {
00840 notify(player, "Invalid file name!");
00841 return;
00842 }
00843
00844 notify_printf(player, "Saving %s", args[0]);
00845 sprintf(openfile, "%s/", MECH_PATH);
00846 strcat(openfile, args[0]);
00847
00848
00849 if(mech_weight_sub(GOD, mech, -1) > (MechTons(mech) * 1024))
00850 notify(player, "Warning: Template Overweight, see @weight.");
00851
00852
00853 if(save_template(player, mech, args[0], openfile) < 0) {
00854 notify(player, "Error saving the template file!");
00855 return ;
00856 }
00857
00858 notify(player, "Saving complete!");
00859 }
00860
00861
00862
00863
00864
00865 void invalid_section(dbref player, MECH * mech)
00866 {
00867 int mechtype = MechType(mech);
00868 int movetype = MechMove(mech);
00869
00870 notify(player, "Not a legal armor location, must be one of:");
00871
00872 switch(mechtype) {
00873 case CLASS_MW:
00874 case CLASS_MECH:
00875 notify(player, "HEAD (H), CTORSO (CT), LTORSO (LT), RTORSO (RT)");
00876
00877 if (movetype == MOVE_QUAD)
00878 notify(player, "LARM (LA), RARM (RA), LLEG (LL), RLEG (RL)");
00879 else
00880 notify(player, "FLLEG (FLL), FRLEG (FRL), RLLEG (RLL), RRLEG (RRL)");
00881
00882 break;
00883 case CLASS_VEH_NAVAL:
00884 case CLASS_VEH_GROUND:
00885 notify(player, "FSIDE (FS), RSIDE (RS), LSIDE (LS), ASIDE (AS), TURRET (TU)");
00886 break;
00887 case CLASS_VTOL:
00888 notify(player, "FSIDE (FS), RSIDE (RS), LSIDE (LS), ASIDE (AS), ROTOR (RO)");
00889 break;
00890 case CLASS_AERO:
00891 notify(player, "NOSE (N), LWING (LW), RWING (RW), ASIDE (AS)");
00892 break;
00893 case CLASS_DS:
00894 notify(player, "NOSE (N), LWING (LW), RWING (RW), LRWING (LR), RRWING (RR), ASIDE (AS)");
00895 break;
00896 case CLASS_SPHEROID_DS:
00897 notify(player, "NOSE (N), FRSIDE (FR), FLSIDE (FL), RLSIDE (RL), RRSIDE (RR), ASIDE (AS)");
00898 break;
00899 case CLASS_BSUIT:
00900 notify(player, "S1, S2, S3, S4, S5, S6, S7, S8");
00901 break;
00902 default:
00903 notify(player, "Invalid or unknown unit type!");
00904 }
00905 }
00906
00907
00908
00909
00910 void mechrep_Rsetarmor(dbref player, void *data, char *buffer)
00911 {
00912 char *args[4];
00913 int argc;
00914 int index;
00915 int temp;
00916
00917 MECHREP_COMMON(1);
00918 argc = mech_parseattributes(buffer, args, 4);
00919 DOCHECK(!argc, "Invalid number of arguments!");
00920 index = ArmorSectionFromString(MechType(mech), MechMove(mech), args[0]);
00921
00922 if(index == -1) {
00923
00924 invalid_section(player, mech);
00925 return;
00926 }
00927
00928 argc--;
00929
00930 if(argc) {
00931
00932 temp = atoi(args[1]);
00933 if(temp < 0)
00934 notify(player, "Invalid armor value!");
00935 else {
00936 notify_printf(player, "Front armor set to : %d", temp);
00937 SetSectArmor(mech, index, temp);
00938 SetSectOArmor(mech, index, temp);
00939 }
00940 argc--;
00941 }
00942 if(argc) {
00943
00944 temp = atoi(args[2]);
00945 if(temp < 0)
00946 notify(player, "Invalid Internal armor value!");
00947 else {
00948 notify_printf(player, "Internal armor set to : %d", temp);
00949 SetSectInt(mech, index, temp);
00950 SetSectOInt(mech, index, temp);
00951 }
00952 argc--;
00953 }
00954 if(argc) {
00955
00956 temp = atoi(args[3]);
00957 if(index == CTORSO || index == RTORSO || index == LTORSO) {
00958 if(temp < 0)
00959 notify(player, "Invalid Rear armor value!");
00960 else {
00961 notify_printf(player, "Rear armor set to : %d", temp);
00962 SetSectRArmor(mech, index, temp);
00963 SetSectORArmor(mech, index, temp);
00964 }
00965 } else
00966 notify(player, "Only the torso can have rear armor.");
00967 }
00968 }
00969
00970
00971
00972
00973
00974
00975 void mechrep_Raddweap(dbref player, void *data, char *buffer)
00976 {
00977 char *args[20];
00978 int argc;
00979 int index;
00980 int weapindex;
00981 int weapnumcrits;
00982 int weaptype;
00983 int loop, temp;
00984 int isrear = 0;
00985 int istc = 0;
00986 int isoneshot = 0;
00987 int isrocket = 0;
00988 int argstoiter;
00989 char flagholder;
00990
00991 MECHREP_COMMON(1);
00992
00993 argc = mech_parseattributes(buffer, args, 20);
00994 DOCHECK(argc < 3, "Invalid number of arguments!")
00995
00996 index = ArmorSectionFromString(MechType(mech), MechMove(mech), args[1]);
00997
00998 if(index == -1) {
00999
01000 invalid_section(player, mech);
01001 return;
01002 }
01003
01004 weapindex = WeaponIndexFromString(args[0]);
01005
01006 if(weapindex == -1) {
01007 notify_printf(player, "That is not a valid weapon!");
01008 DumpWeapons(player);
01009 return;
01010 }
01011
01012
01013
01014
01015
01016
01017
01018 argstoiter = argc - 3;
01019
01020
01021
01022
01023
01024
01025 for(loop = 0; loop < argstoiter; loop++) {
01026 flagholder = toupper(args[3 + loop][0]);
01027
01028 if(flagholder == 'T') {
01029
01030 istc = 1;
01031 } else if(flagholder == 'R') {
01032
01033 isrear = 1;
01034 } else if(flagholder == 'O') {
01035
01036 isoneshot = 1;
01037 }
01038
01039
01040
01041
01042
01043
01044
01045 if(isalpha(flagholder))
01046 argc--;
01047
01048 }
01049
01050
01051 argc -= 2;
01052
01053 weapnumcrits = GetWeaponCrits(mech, weapindex);
01054
01055
01056 if(argc < weapnumcrits) {
01057 notify_printf(player,
01058 "Not enough critical slots specified! (Given: %i, Needed: %i)",
01059 argc, weapnumcrits);
01060 } else if(argc > weapnumcrits) {
01061 notify_printf(player,
01062 "Too many critical slots specified! (Given: %i, Needed: %i)",
01063 argc, weapnumcrits);
01064 } else {
01065 for(loop = 0; loop < GetWeaponCrits(mech, weapindex); loop++) {
01066 temp = atoi(args[2 + loop]);
01067 temp--;
01068 DOCHECK(temp < 0 ||
01069 temp > NUM_CRITICALS, "Bad critical location!");
01070 MechSections(mech)[index].criticals[temp].type =
01071 (I2Weapon(weapindex));
01072 MechSections(mech)[index].criticals[temp].firemode = 0;
01073 MechSections(mech)[index].criticals[temp].ammomode = 0;
01074
01075
01076 if(MechWeapons[weapindex].special & ROCKET)
01077 isrocket = 1;
01078
01079 if(isrear)
01080 MechSections(mech)[index].criticals[temp].firemode |=
01081 REAR_MOUNT;
01082
01083 if(istc)
01084 MechSections(mech)[index].criticals[temp].firemode |= ON_TC;
01085
01086
01087 if(isoneshot || isrocket)
01088 MechSections(mech)[index].criticals[temp].firemode |= OS_MODE;
01089 }
01090 if(IsAMS(weapindex)) {
01091 if(MechWeapons[weapindex].special & CLAT)
01092 MechSpecials(mech) |= CL_ANTI_MISSILE_TECH;
01093 else
01094 MechSpecials(mech) |= IS_ANTI_MISSILE_TECH;
01095 }
01096 notify_printf(player, "Weapon added.");
01097 }
01098 }
01099
01100 void mechrep_Rfiremode(dbref player, void *data, char *buffer)
01101 {
01102 char *args[4];
01103 int argc;
01104 int section, critical, weaptype;
01105
01106 MECHREP_COMMON(1);
01107 argc = mech_parseattributes(buffer, args, 2);
01108 DOCHECK(argc <2, "MECHREP: Invalid Syntax. Try FireMode <Weapon#> <Mode>");
01109
01110 weaptype = FindWeaponNumberOnMech_Advanced(mech, atoi(args[0]), §ion, &critical, 0);
01111
01112 if(MechWeapons[weaptype].ammoperton == 0) {
01113 notify(player, "That weapon doesn't require ammo!");
01114 return;
01115 }
01116
01117 if(MechSections(mech)[section].criticals[critical].firemode & OS_MODE) {
01118 notify(player,"Keeping One Shot Mode!");
01119 MechSections(mech)[section].criticals[critical].ammomode = 0;
01120 }
01121 else
01122 if(!(MechSections(mech)[section].criticals[critical].firemode & HALFTON_MODE)) {
01123
01124 MechSections(mech)[section].criticals[critical].firemode = 0;
01125 MechSections(mech)[section].criticals[critical].ammomode = 0;
01126 }
01127
01128
01129
01130
01131 switch (toupper(args[1][0])) {
01132 case 'W':
01133 MechSections(mech)[section].criticals[critical].ammomode |=
01134 SWARM_MODE;
01135 break;
01136 case '1':
01137 MechSections(mech)[section].criticals[critical].ammomode |=
01138 SWARM1_MODE;
01139 break;
01140 case 'I':
01141 MechSections(mech)[section].criticals[critical].ammomode |=
01142 INFERNO_MODE;
01143 break;
01144 case 'L':
01145 MechSections(mech)[section].criticals[critical].ammomode |=
01146 LBX_MODE;
01147 break;
01148 case 'A':
01149 MechSections(mech)[section].criticals[critical].ammomode |=
01150 ARTEMIS_MODE;
01151 break;
01152 case 'N':
01153 MechSections(mech)[section].criticals[critical].ammomode |=
01154 NARC_MODE;
01155 break;
01156 case 'C':
01157 MechSections(mech)[section].criticals[critical].ammomode |=
01158 CLUSTER_MODE;
01159 break;
01160 case 'M':
01161 MechSections(mech)[section].criticals[critical].ammomode |=
01162 MINE_MODE;
01163 break;
01164 case 'S':
01165 MechSections(mech)[section].criticals[critical].ammomode |=
01166 SMOKE_MODE;
01167 break;
01168 case 'X':
01169 MechSections(mech)[section].criticals[critical].ammomode |=
01170 INARC_EXPLO_MODE;
01171 break;
01172 case 'Y':
01173 MechSections(mech)[section].criticals[critical].ammomode |=
01174 INARC_HAYWIRE_MODE;
01175 break;
01176 case 'E':
01177 MechSections(mech)[section].criticals[critical].ammomode |=
01178 INARC_ECM_MODE;
01179 break;
01180 case 'R':
01181 MechSections(mech)[section].criticals[critical].ammomode |=
01182 AC_AP_MODE;
01183 break;
01184 case 'F':
01185 MechSections(mech)[section].criticals[critical].ammomode |=
01186 AC_FLECHETTE_MODE;
01187 break;
01188 case 'D':
01189 MechSections(mech)[section].criticals[critical].ammomode |=
01190 AC_INCENDIARY_MODE;
01191 break;
01192 case 'P':
01193 MechSections(mech)[section].criticals[critical].ammomode |=
01194 AC_PRECISION_MODE;
01195 break;
01196 case 'T':
01197 MechSections(mech)[section].criticals[critical].ammomode |=
01198 STINGER_MODE;
01199 break;
01200 case 'U':
01201 MechSections(mech)[section].criticals[critical].ammomode |=
01202 AC_CASELESS_MODE;
01203 break;
01204 case 'J':
01205 MechSections(mech)[section].criticals[critical].firemode |= WILL_JETTISON_MODE;
01206 break;
01207 case 'G':
01208 MechSections(mech)[section].criticals[critical].ammomode |=
01209 SGUIDED_MODE;
01210 break;
01211 case '-':
01212 MechSections(mech)[section].criticals[critical].ammomode = 0;
01213 MechSections(mech)[section].criticals[critical].firemode = 0;
01214 }
01215
01216 notify(player,"Firemode changed!");
01217
01218 }
01219
01220
01221
01222 void mechrep_Rreload(dbref player, void *data, char *buffer)
01223 {
01224 char *args[4];
01225 int argc;
01226 int index;
01227 int weapindex;
01228 int subsect;
01229
01230 MECHREP_COMMON(1);
01231 argc = mech_parseattributes(buffer, args, 4);
01232 DOCHECK(argc <= 2, "Invalid number of arguments!");
01233 weapindex = WeaponIndexFromString(args[0]);
01234
01235 if(weapindex == -1) {
01236 notify(player, "That is not a valid weapon!");
01237 DumpWeapons(player);
01238 return;
01239 }
01240
01241 index = ArmorSectionFromString(MechType(mech), MechMove(mech), args[1]);
01242
01243 if(index == -1) {
01244
01245 invalid_section(player, mech);
01246 return;
01247 }
01248
01249 subsect = atoi(args[2]);
01250 subsect--;
01251 DOCHECK(subsect < 0 ||
01252 subsect >= CritsInLoc(mech, index), "Critslot out of range!");
01253 if(MechWeapons[weapindex].ammoperton == 0)
01254 notify(player, "That weapon doesn't require ammo!");
01255 else {
01256 MechSections(mech)[index].criticals[subsect].type = I2Ammo(weapindex);
01257 if(!(MechSections(mech)[index].criticals[subsect].firemode & HALFTON_MODE)) {
01258 MechSections(mech)[index].criticals[subsect].firemode = 0;
01259 MechSections(mech)[index].criticals[subsect].ammomode = 0;
01260 }
01261
01262 if(argc > 3)
01263 switch (toupper(args[3][0])) {
01264 case '+':
01265 MechSections(mech)[index].criticals[subsect].firemode |=
01266 HALFTON_MODE;
01267 break;
01268 case 'W':
01269 MechSections(mech)[index].criticals[subsect].ammomode |=
01270 SWARM_MODE;
01271 break;
01272 case '1':
01273 MechSections(mech)[index].criticals[subsect].ammomode |=
01274 SWARM1_MODE;
01275 break;
01276 case 'I':
01277 MechSections(mech)[index].criticals[subsect].ammomode |=
01278 INFERNO_MODE;
01279 break;
01280 case 'L':
01281 MechSections(mech)[index].criticals[subsect].ammomode |=
01282 LBX_MODE;
01283 break;
01284 case 'A':
01285 MechSections(mech)[index].criticals[subsect].ammomode |=
01286 ARTEMIS_MODE;
01287 break;
01288 case 'N':
01289 MechSections(mech)[index].criticals[subsect].ammomode |=
01290 NARC_MODE;
01291 break;
01292 case 'C':
01293 MechSections(mech)[index].criticals[subsect].ammomode |=
01294 CLUSTER_MODE;
01295 break;
01296 case 'M':
01297 MechSections(mech)[index].criticals[subsect].ammomode |=
01298 MINE_MODE;
01299 break;
01300 case 'S':
01301 MechSections(mech)[index].criticals[subsect].ammomode |=
01302 SMOKE_MODE;
01303 break;
01304 case 'X':
01305 MechSections(mech)[index].criticals[subsect].ammomode |=
01306 INARC_EXPLO_MODE;
01307 break;
01308 case 'Y':
01309 MechSections(mech)[index].criticals[subsect].ammomode |=
01310 INARC_HAYWIRE_MODE;
01311 break;
01312 case 'E':
01313 MechSections(mech)[index].criticals[subsect].ammomode |=
01314 INARC_ECM_MODE;
01315 break;
01316 case 'R':
01317 MechSections(mech)[index].criticals[subsect].ammomode |=
01318 AC_AP_MODE;
01319 break;
01320 case 'F':
01321 MechSections(mech)[index].criticals[subsect].ammomode |=
01322 AC_FLECHETTE_MODE;
01323 break;
01324 case 'D':
01325 MechSections(mech)[index].criticals[subsect].ammomode |=
01326 AC_INCENDIARY_MODE;
01327 break;
01328 case 'P':
01329 MechSections(mech)[index].criticals[subsect].ammomode |=
01330 AC_PRECISION_MODE;
01331 break;
01332 case 'T':
01333 MechSections(mech)[index].criticals[subsect].ammomode |=
01334 STINGER_MODE;
01335 break;
01336 case 'U':
01337 MechSections(mech)[index].criticals[subsect].ammomode |=
01338 AC_CASELESS_MODE;
01339 break;
01340 case 'G':
01341 MechSections(mech)[index].criticals[subsect].ammomode |=
01342 SGUIDED_MODE;
01343 break;
01344 case '-':
01345 MechSections(mech)[index].criticals[subsect].ammomode = 0;
01346 MechSections(mech)[index].criticals[subsect].firemode = 0;
01347 }
01348
01349 MechSections(mech)[index].criticals[subsect].data =
01350 FullAmmo(mech, index, subsect);
01351 notify(player, "Weapon loaded!");
01352 }
01353 }
01354
01355
01356
01357
01358 void mechrep_Rrepair(dbref player, void *data, char *buffer)
01359 {
01360 char *args[4];
01361 int argc;
01362 int index;
01363 int temp;
01364
01365 MECHREP_COMMON(1);
01366 argc = mech_parseattributes(buffer, args, 4);
01367 DOCHECK(argc <= 2, "Invalid number of arguments!");
01368 index = ArmorSectionFromString(MechType(mech), MechMove(mech), args[0]);
01369
01370 if(index == -1) {
01371
01372 invalid_section(player, mech);
01373 return;
01374 }
01375
01376 temp = atoi(args[2]);
01377 DOCHECK(temp < 0, "Illegal value for armor!");
01378
01379 switch (args[1][0]) {
01380 case 'A':
01381 case 'a':
01382
01383 SetSectArmor(mech, index, temp);
01384 notify(player, "Armor repaired!");
01385 break;
01386 case 'I':
01387 case 'i':
01388
01389 SetSectInt(mech, index, temp);
01390 notify(player, "Internal structure repaired!");
01391 break;
01392 case 'C':
01393 case 'c':
01394
01395 temp--;
01396 if(temp >= 0 && temp < NUM_CRITICALS) {
01397 MechSections(mech)[index].criticals[temp].data = 0;
01398 notify(player, "Critical location repaired!");
01399 } else {
01400 notify(player, "Critical Location out of range!");
01401 }
01402 break;
01403 case 'R':
01404 case 'r':
01405
01406 if(index == CTORSO || index == LTORSO || index == RTORSO) {
01407 SetSectRArmor(mech, index, temp);
01408 notify(player, "Rear armor repaired!");
01409 } else {
01410 notify(player,
01411 "Only the center, rear and left torso have rear armor!");
01412 }
01413 break;
01414 default:
01415 notify(player, "Illegal Type-> must be ARMOR, INTERNAL, CRIT, REAR");
01416 return;
01417 }
01418 }
01419
01420
01421
01422
01423 void mechrep_Raddspecial(dbref player, void *data, char *buffer)
01424 {
01425 char *args[4];
01426 int argc;
01427 int index;
01428 int itemcode;
01429 int subsect;
01430 int newdata;
01431 int max;
01432
01433 MECHREP_COMMON(1);
01434 argc = mech_parseattributes(buffer, args, 4);
01435 DOCHECK(argc <= 2, "Invalid number of arguments!");
01436 itemcode = FindSpecialItemCodeFromString(args[0]);
01437
01438 if(itemcode == -1)
01439 if(strcasecmp(args[0], "empty")) {
01440 notify(player, "That is not a valid special object!");
01441 DumpMechSpecialObjects(player);
01442 return;
01443 }
01444 index = ArmorSectionFromString(MechType(mech), MechMove(mech), args[1]);
01445
01446 if(index == -1) {
01447
01448 invalid_section(player, mech);
01449 return;
01450 }
01451 subsect = atoi(args[2]);
01452 subsect--;
01453 max = CritsInLoc(mech, index);
01454 DOCHECK(subsect < 0 || subsect >= max, "Critslot out of range!");
01455 if(argc == 4)
01456 newdata = atoi(args[3]);
01457 else
01458 newdata = 0;
01459 MechSections(mech)[index].criticals[subsect].type =
01460 itemcode < 0 ? 0 : I2Special(itemcode);
01461 MechSections(mech)[index].criticals[subsect].data = newdata;
01462 switch (itemcode) {
01463 case CASE:
01464 MechSections(mech)[(MechType(mech) ==
01465 CLASS_VEH_GROUND) ? BSIDE : index].config |=
01466 CASE_TECH;
01467 notify(player, "CASE Technology added to section.");
01468 break;
01469 case TRIPLE_STRENGTH_MYOMER:
01470 MechSpecials(mech) |= TRIPLE_MYOMER_TECH;
01471 notify(player, "Triple Strength Myomer Technology added to 'Mech.");
01472 break;
01473 case MASC:
01474 MechSpecials(mech) |= MASC_TECH;
01475 notify(player, "Myomer Accelerator Signal Circuitry added to 'Mech.");
01476 break;
01477 case C3_MASTER:
01478 MechSpecials(mech) |= C3_MASTER_TECH;
01479 notify(player, "C3 Command Unit added to 'Mech.");
01480 break;
01481 case C3_SLAVE:
01482 MechSpecials(mech) |= C3_SLAVE_TECH;
01483 notify(player, "C3 Slave Unit added to 'Mech.");
01484 break;
01485 case ARTEMIS_IV:
01486 MechSections(mech)[index].criticals[subsect].data--;
01487 MechSpecials(mech) |= ARTEMIS_IV_TECH;
01488 notify(player, "Artemis IV Fire-Control System added to 'Mech.");
01489 notify_printf(player,
01490 "System will control the weapon which starts at slot %d.",
01491 newdata);
01492 break;
01493 case ECM:
01494 MechSpecials(mech) |= ECM_TECH;
01495 notify(player, "Guardian ECM Suite added to 'Mech.");
01496 break;
01497 case ANGELECM:
01498 MechSpecials2(mech) |= ANGEL_ECM_TECH;
01499 notify(player, "Angel ECM Suite added to 'Mech.");
01500 break;
01501 case BEAGLE_PROBE:
01502 MechSpecials(mech) |= BEAGLE_PROBE_TECH;
01503 notify(player, "Beagle Active Probe added to 'Mech.");
01504 break;
01505 case TAG:
01506 MechSpecials2(mech) |= TAG_TECH;
01507 notify(player, "TAG added to 'Mech.");
01508 break;
01509 case C3I:
01510 MechSpecials2(mech) |= C3I_TECH;
01511 notify(player, "Improved C3 added to 'Mech.");
01512 break;
01513 case BLOODHOUND_PROBE:
01514 MechSpecials2(mech) |= BLOODHOUND_PROBE_TECH;
01515 notify(player, "Bloodhound Active Probe added to 'Mech.");
01516 break;
01517 case TARGETING_COMPUTER:
01518 MechSpecials2(mech) |= TCOMP_TECH;
01519 notify(player, "Targeting Computer added to 'Mech.");
01520 break;
01521 }
01522 notify(player, "Critical slot filled.");
01523 }
01524
01525 extern char *specials[];
01526 extern char *specials2[];
01527 extern char *infantry_specials[];
01528
01529 char *techstatus_func(MECH * mech)
01530 {
01531 return (MechSpecials(mech) ||
01532 MechSpecials2(mech)) ? BuildBitStringwdelim2(specials, specials2,
01533 MechSpecials(mech),
01534 MechSpecials2(mech)) : "";
01535 }
01536
01537 void mechrep_Rshowtech(dbref player, void *data, char *buffer)
01538 {
01539 int i;
01540 char *techstring;
01541 char location[20];
01542
01543 MECHREP_COMMON(1);
01544 notify(player, "--------Advanced Technology--------");
01545 if(MechSpecials(mech) & TRIPLE_MYOMER_TECH)
01546 notify(player, "Triple Strength Myomer");
01547 if(MechSpecials(mech) & MASC_TECH)
01548 notify(player, "Myomer Accelerator Signal Circuitry");
01549 for(i = 0; i < NUM_SECTIONS; i++)
01550 if(MechSections(mech)[i].config & CASE_TECH) {
01551 ArmorStringFromIndex(i, location, MechType(mech), MechMove(mech));
01552 notify_printf(player,
01553 "Cellular Ammunition Storage Equipment in %s",
01554 location);
01555 }
01556 if(MechSpecials(mech) & CLAN_TECH) {
01557 notify(player, "Mech is set to Clan Tech. This means:");
01558 notify(player, " Mech automatically has Double Heat Sink Tech");
01559 notify(player, " Mech automatically has CASE in all sections");
01560 }
01561 if(MechSpecials(mech) & DOUBLE_HEAT_TECH)
01562 notify(player, "Mech uses Double Heat Sinks");
01563 if(MechSpecials(mech) & CL_ANTI_MISSILE_TECH)
01564 notify(player, "Clan style Anti-Missile System");
01565 if(MechSpecials(mech) & IS_ANTI_MISSILE_TECH)
01566 notify(player, "Inner Sphere style Anti-Missile System");
01567 if(MechSpecials(mech) & FLIPABLE_ARMS)
01568 notify(player, "The arms may be flipped into the rear firing arc");
01569 if(MechSpecials(mech) & C3_MASTER_TECH)
01570 notify(player, "C3 Command Computer");
01571 if(MechSpecials(mech) & C3_SLAVE_TECH)
01572 notify(player, "C3 Slave Computer");
01573 if(MechSpecials(mech) & ARTEMIS_IV_TECH)
01574 notify(player, "Artemis IV Fire-Control System");
01575 if(MechSpecials(mech) & ECM_TECH)
01576 notify(player, "Guardian ECM Suite");
01577 if(MechSpecials2(mech) & ANGEL_ECM_TECH)
01578 notify(player, "Angel ECM Suite");
01579 if(MechSpecials(mech) & BEAGLE_PROBE_TECH)
01580 notify(player, "Beagle Active Probe");
01581 if(MechSpecials2(mech) & TAG_TECH)
01582 notify(player, "Target Aquisition Gear");
01583 if(MechSpecials2(mech) & C3I_TECH)
01584 notify(player, "Improved C3");
01585 if(MechSpecials2(mech) & BLOODHOUND_PROBE_TECH)
01586 notify(player, "Bloodhound Active Probe");
01587 if(MechSpecials(mech) & ICE_TECH)
01588 notify(player, "It has ICE engine");
01589
01590
01591 if(MechInfantrySpecials(mech) & INF_SWARM_TECH)
01592 notify(player, "Can swarm enemy units");
01593 if(MechInfantrySpecials(mech) & INF_MOUNT_TECH)
01594 notify(player, "Can mount friendly units");
01595 if(MechInfantrySpecials(mech) & INF_ANTILEG_TECH)
01596 notify(player, "Can do anti-leg attacks");
01597 if(MechInfantrySpecials(mech) & CS_PURIFIER_STEALTH_TECH)
01598 notify(player, "Has CS Purifier Stealth");
01599 if(MechInfantrySpecials(mech) & DC_KAGE_STEALTH_TECH)
01600 notify(player, "Has DC Kage Stealth");
01601 if(MechInfantrySpecials(mech) & FWL_ACHILEUS_STEALTH_TECH)
01602 notify(player, "Has FWL Achileus Stealth");
01603 if(MechInfantrySpecials(mech) & FC_INFILTRATOR_STEALTH_TECH)
01604 notify(player, "Has FC Infiltrator Stealth");
01605 if(MechInfantrySpecials(mech) & FC_INFILTRATORII_STEALTH_TECH)
01606 notify(player, "Has FC InfiltratorII Stealth");
01607 if(MechInfantrySpecials(mech) & MUST_JETTISON_TECH)
01608 notify(player,
01609 "Must jettison backpack before jumping/using specials");
01610 if(MechInfantrySpecials(mech) & CAN_JETTISON_TECH)
01611 notify(player, "Can jettison backpack");
01612
01613 notify(player, "Brief version (May have something previous hadn't):");
01614 techstring = mechrep_gettechstring(mech);
01615 if(techstring && techstring[0])
01616 notify(player, techstring);
01617 else
01618 notify(player, "-");
01619 }
01620
01621 char *mechrep_gettechstring(MECH * mech)
01622 {
01623 return BuildBitString3(specials, specials2, infantry_specials,
01624 MechSpecials(mech), MechSpecials2(mech),
01625 MechInfantrySpecials(mech));
01626 }
01627
01628 void mechrep_Rdeltech(dbref player, void *data, char *buffer)
01629 {
01630 int i, j;
01631 int Type;
01632 int nv, nv2;
01633
01634 MECHREP_COMMON(1);
01635
01636 nv = BuildBitVector(specials, buffer);
01637 nv2 = BuildBitVector(specials2, buffer);
01638
01639
01640 if(((nv < 0) && (nv2 < 0)) && (strcasecmp(buffer, "all") != 0) &&
01641 (strcasecmp(buffer, "Case") != 0)) {
01642 notify(player, "Invalid tech: Available techs:");
01643 notify(player, "\tAll");
01644 notify(player, "\tCase");
01645
01646 for(nv = 0; specials[nv]; nv++)
01647 notify_printf(player, "\t%s", specials[nv]);
01648
01649 for(nv = 0; specials2[nv]; nv++)
01650 notify_printf(player, "\t%s", specials2[nv]);
01651
01652 return;
01653 }
01654
01655
01656 if(((!nv) && (!nv2)) && (strcasecmp(buffer, "all") != 0) &&
01657 (strcasecmp(buffer, "Case") != 0)) {
01658 notify(player, "Nothing specified");
01659 return;
01660 }
01661
01662
01663 if(strcasecmp(buffer, "all") == 0) {
01664
01665 for(i = 0; i < NUM_SECTIONS; i++) {
01666
01667 if((MechSections(mech)[i].config & CASE_TECH)
01668 || (MechSpecials(mech) & TRIPLE_MYOMER_TECH)
01669 || (MechSpecials(mech) & MASC_TECH)) {
01670
01671 for(j = 0; j < NUM_CRITICALS; j++) {
01672 Type = MechSections(mech)[i].criticals[j].type;
01673
01674 if(Type == I2Special((CASE))
01675 || Type == I2Special((TRIPLE_STRENGTH_MYOMER))
01676 || Type == I2Special((MASC))) {
01677 MechSections(mech)[i].criticals[j].type = EMPTY;
01678 }
01679 }
01680 MechSections(mech)[i].config &= ~CASE_TECH;
01681
01682 }
01683 }
01684
01685 MechSpecials(mech) = 0;
01686 MechSpecials2(mech) = 0;
01687 notify(player, "All Advanced Technology Removed");
01688 return;
01689 }
01690
01691 if(strcasecmp(buffer, "Case") == 0) {
01692 for(i = 0; i < NUM_SECTIONS; i++) {
01693 if(MechSections(mech)[i].config & CASE_TECH) {
01694 for(j = 0; j < NUM_CRITICALS; j++) {
01695 Type = MechSections(mech)[i].criticals[j].type;
01696
01697 if(Type == I2Special((CASE))) {
01698 MechSections(mech)[i].criticals[j].type = EMPTY;
01699 }
01700 }
01701 MechSections(mech)[i].config &= ~CASE_TECH;
01702 }
01703 }
01704 notify(player, "Case Technology Removed");
01705 return;
01706 }
01707
01708 if(nv > 0) {
01709
01710 if(strcasecmp(buffer, "TripleMyomerTech") == 0) {
01711 if(MechSpecials(mech) & TRIPLE_MYOMER_TECH) {
01712 for(i = 0; i < NUM_SECTIONS; i++) {
01713 for(j = 0; j < NUM_CRITICALS; j++) {
01714 Type = MechSections(mech)[i].criticals[j].type;
01715
01716 if(Type == I2Special((TRIPLE_STRENGTH_MYOMER))) {
01717 MechSections(mech)[i].criticals[j].type = EMPTY;
01718 }
01719 }
01720 }
01721 }
01722 } else if(strcasecmp(buffer, "Masc") == 0) {
01723 if(MechSpecials(mech) & MASC_TECH) {
01724 for(i = 0; i < NUM_SECTIONS; i++) {
01725 for(j = 0; j < NUM_CRITICALS; j++) {
01726 Type = MechSections(mech)[i].criticals[j].type;
01727
01728 if(Type == I2Special((MASC))) {
01729 MechSections(mech)[i].criticals[j].type = EMPTY;
01730 }
01731 }
01732 }
01733 }
01734 }
01735
01736 MechSpecials(mech) &= ~nv;
01737 notify_printf(player, "%s Technology Removed", buffer);
01738
01739 } else {
01740
01741 MechSpecials2(mech) &= ~nv2;
01742 notify_printf(player, "%s Technology Removed", buffer);
01743
01744 }
01745 return;
01746 }
01747
01748 void mechrep_Raddtech(dbref player, void *data, char *buffer)
01749 {
01750 int nv, nv2;
01751
01752 MECHREP_COMMON(1);
01753 nv = BuildBitVector(specials, buffer);
01754 nv2 = BuildBitVector(specials2, buffer);
01755
01756 if((nv < 0) && (nv2 < 0)) {
01757 notify(player, "Invalid tech: Available techs:");
01758
01759 for(nv = 0; specials[nv]; nv++)
01760 notify_printf(player, "\t%s", specials[nv]);
01761
01762 for(nv = 0; specials2[nv]; nv++)
01763 notify_printf(player, "\t%s", specials2[nv]);
01764
01765 return;
01766 }
01767
01768 if((!nv) && (!nv2)) {
01769 notify(player, "Nothing set!");
01770 return;
01771 }
01772
01773 if(nv > 0) {
01774 MechSpecials(mech) |= nv;
01775 notify_printf(player, "Set: %s", BuildBitString(specials, nv));
01776 } else {
01777 MechSpecials2(mech) |= nv2;
01778 notify_printf(player, "Set: %s", BuildBitString(specials2, nv2));
01779 }
01780
01781 }
01782
01783 void mechrep_Rdelinftech(dbref player, void *data, char *buffer)
01784 {
01785 MECH *mech = (MECH *) data;
01786
01787 MechInfantrySpecials(mech) = 0;
01788 notify(player, "Advanced Infantry Technology Deleted");
01789 }
01790
01791 void mechrep_Raddinftech(dbref player, void *data, char *buffer)
01792 {
01793 int nv;
01794
01795 MECHREP_COMMON(1);
01796 nv = BuildBitVector(infantry_specials, buffer);
01797
01798 if(MechType(mech) != CLASS_BSUIT) {
01799 notify(player, "That is not a valid target for infantry technologies. Try a Suit!");
01800 return;
01801 }
01802
01803 if(nv < 0) {
01804 notify(player, "Invalid infantry tech: Available techs:");
01805
01806 for(nv = 0; infantry_specials[nv]; nv++)
01807 notify_printf(player, "\t%s", infantry_specials[nv]);
01808 return;
01809 }
01810
01811 if(!nv) {
01812 notify(player, "Nothing set!");
01813 return;
01814 }
01815
01816 if(nv > 0) {
01817 MechInfantrySpecials(mech) |= nv;
01818 notify_printf(player, "Set: %s", BuildBitString(infantry_specials,
01819 nv));
01820 }
01821
01822 }
01823
01824 void mechrep_setcargospace(dbref player, void *data, char *buffer)
01825 {
01826 char *args[2];
01827 int argc;
01828 int cargo;
01829 int max;
01830
01831 MECHREP_COMMON(1);
01832 argc = mech_parseattributes(buffer, args, 2);
01833 DOCHECK(argc != 2, "Invalid number of arguements!");
01834
01835 cargo = (atoi(args[0]) * 50);
01836 DOCHECK(cargo < 0 || cargo > 100000, "Doesn't that seem excessive?");
01837 CargoSpace(mech) = cargo;
01838
01839 max = (atoi(args[1]));
01840 max = (BOUNDED(1, max, 100));
01841 CarMaxTon(mech) = (char) max;
01842
01843 notify_printf(player, "%3.2f cargospace and %d tons of maxton space set.",
01844 (float) ((float) cargo / 100), (int) max);
01845
01846 }
01847
01848 MECH *load_refmech(char *reference)
01849 {
01850 static MECH cachemech;
01851 static char cacheref[1024];
01852
01853 if(!strcmp(cacheref, reference))
01854 return &cachemech;
01855 if(mech_loadnew(GOD, &cachemech, reference) < 1) {
01856 cacheref[0] = '\0';
01857 return NULL;
01858 }
01859 strncpy(cacheref, reference, 1023);
01860 cacheref[1023] = '\0';
01861 return &cachemech;
01862 }