00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "config.h"
00012
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <math.h>
00016 #include <sys/file.h>
00017
00018 #include "mech.h"
00019 #include "create.h"
00020 #include "mech.events.h"
00021 #include "map.los.h"
00022 #include "p.mech.utils.h"
00023 #include "p.mech.los.h"
00024 #include "p.eject.h"
00025 #include "p.mech.restrict.h"
00026 #include "p.mech.maps.h"
00027 #include "p.mech.notify.h"
00028 #include "p.ds.bay.h"
00029 #include "p.bsuit.h"
00030 #include "p.mech.utils.h"
00031 #include "autopilot.h"
00032
00033 void mech_findcenter(dbref player, void *data, char *buffer)
00034 {
00035 MECH *mech = (MECH *) data;
00036 float fx, fy;
00037 int x, y;
00038
00039 cch(MECH_USUAL);
00040 x = MechX(mech);
00041 y = MechY(mech);
00042 MapCoordToRealCoord(x, y, &fx, &fy);
00043 notify_printf(player, "Current hex: (%d,%d,%d)\tRange to center: %.2f\t"
00044 "Bearing to center: %d", x, y, MechZ(mech),
00045 FindHexRange(fx, fy, MechFX(mech), MechFY(mech)),
00046 FindBearing(MechFX(mech), MechFY(mech), fx, fy));
00047 }
00048
00049 static int parse_tacargs(dbref player, MECH * mech, char **args, int argc,
00050 int maxrange, short *x, short *y)
00051 {
00052 int bearing;
00053 float range, fx, fy;
00054 MECH *tempMech;
00055 MAP *map;
00056
00057 switch (argc) {
00058 case 2:
00059 bearing = atoi(args[0]);
00060 range = atof(args[1]);
00061 DOCHECK0(!MechIsObservator(mech) &&
00062 abs((int) range) > maxrange,
00063 "Those coordinates are out of sensor range!");
00064 FindXY(MechFX(mech), MechFY(mech), bearing, range, &fx, &fy);
00065 RealCoordToMapCoord(x, y, fx, fy);
00066 return 1;
00067 case 1:
00068 map = getMap(mech->mapindex);
00069 tempMech = getMech(FindMechOnMap(map, args[0]));
00070 DOCHECK0(!tempMech, "No such target.");
00071 range = FlMechRange(mech_map, mech, tempMech);
00072 DOCHECK0(!InLineOfSight(mech, tempMech, MechX(tempMech),
00073 MechY(tempMech), range), "No such target.");
00074 DOCHECK0(abs((int) range) > maxrange,
00075 "Target is out of scanner range.");
00076 *x = MechX(tempMech);
00077 *y = MechY(tempMech);
00078 return 1;
00079 case 0:
00080 *x = MechX(mech);
00081 *y = MechY(mech);
00082 return 1;
00083 default:
00084 notify(player, "Invalid number of parameters!");
00085 return 0;
00086 }
00087 }
00088
00089 const char *GetTerrainName_base(int t)
00090 {
00091 switch (t) {
00092 case GRASSLAND:
00093 case '_':
00094 return "Grassland";
00095 case HEAVY_FOREST:
00096 return "Heavy Forest";
00097 case LIGHT_FOREST:
00098 return "Light Forest";
00099 case ICE:
00100 return "Ice";
00101 case BRIDGE:
00102 return "Bridge";
00103 case HIGHWATER:
00104 case WATER:
00105 return "Water";
00106 case ROUGH:
00107 return "Rough";
00108 case MOUNTAINS:
00109 return "Mountains";
00110 case ROAD:
00111 return "Road";
00112 case BUILDING:
00113 return "Building";
00114 case FIRE:
00115 return "Fire";
00116 case SMOKE:
00117 return "Smoke";
00118 case WALL:
00119 return "Wall";
00120 }
00121 return "Unknown";
00122 }
00123
00124 const char *GetTerrainName(MAP * map, int x, int y)
00125 {
00126 return GetTerrainName_base(GetTerrain(map, x, y));
00127 }
00128
00129
00130
00131 enum { SWATER_IDX, DWATER_IDX, BUILDING_IDX, ROAD_IDX, ROUGH_IDX,
00132 MOUNTAIN_IDX,
00133 FIRE_IDX, ICE_IDX, WALL_IDX, SNOW_IDX, SMOKE_IDX, LWOOD_IDX, HWOOD_IDX,
00134 UNKNOWN_IDX, CLIFF_IDX, SELF_IDX, FRIEND_IDX, ENEMY_IDX, DS_IDX,
00135 GOODLZ_IDX, BADLZ_IDX, NUM_COLOR_IDX
00136 };
00137
00138
00139
00140
00141 #define DEFAULT_COLOR_STRING "BbWXYyRWWWXGgbRhYRnGR"
00142 #define DEFAULT_COLOR_SCHEME "BbWXYyRWWWXGgbRHYR\0GR"
00143
00144 static char custom_color_str[NUM_COLOR_IDX + 1] = DEFAULT_COLOR_SCHEME;
00145
00146 static void set_colorscheme(dbref player)
00147 {
00148 char *str = silly_atr_get(player, A_MAPCOLOR);
00149 int i;
00150
00151 if(*str && strlen(str) <= NUM_COLOR_IDX) {
00152 strncpy(custom_color_str, DEFAULT_COLOR_STRING, NUM_COLOR_IDX);
00153 strncpy(custom_color_str, str, strlen(str));
00154 for(i = 0; i < NUM_COLOR_IDX; i++) {
00155 switch (custom_color_str[i]) {
00156 case 'f':
00157 case 'F':
00158 case 'I':
00159 case 'i':
00160 case 'H':
00161 case 'x':
00162 case 'X':
00163 case 'r':
00164 case 'R':
00165 case 'g':
00166 case 'G':
00167 case 'y':
00168 case 'Y':
00169 case 'b':
00170 case 'B':
00171 case 'm':
00172 case 'M':
00173 case 'c':
00174 case 'C':
00175 case 'w':
00176 case 'W':
00177 break;
00178 case 'h':
00179 custom_color_str[i] = 'H';
00180 break;
00181 case 'n':
00182 custom_color_str[i] = '\0';
00183 break;
00184 default:
00185 notify_printf(player, "Invalid character '%c' in MAPCOLOR "
00186 "attribute!", custom_color_str[i]);
00187 notify(player, "Using default: " DEFAULT_COLOR_STRING);
00188 memcpy(custom_color_str, DEFAULT_COLOR_SCHEME, NUM_COLOR_IDX);
00189 return;
00190 }
00191 }
00192 return;
00193 } else if(*str) {
00194 notify(player, "Invalid MAPCOLOR attribute!");
00195 notify(player, "Using default: " DEFAULT_COLOR_STRING);
00196 }
00197 memcpy(custom_color_str, DEFAULT_COLOR_SCHEME, NUM_COLOR_IDX);
00198 }
00199
00200 void mech_navigate(dbref player, void *data, char *buffer)
00201 {
00202 MECH *mech = (MECH *) data;
00203 char mybuff[NAVIGATE_LINES][MBUF_SIZE];
00204 MAP *mech_map;
00205 char **maptext, *args[3];
00206 int i, dolos, argc;
00207 short x, y;
00208
00209 cch(MECH_USUAL);
00210
00211 mech_map = getMap(mech->mapindex);
00212
00213 dolos = MapIsDark(mech_map) || (MechType(mech) == CLASS_MW &&
00214 mudconf.btech_mw_losmap);
00215
00216 DOCHECK(mech_map->map_width <= 0 || mech_map->map_height <= 0,
00217 "Nothing to see on this map, move along.");
00218
00219 argc = mech_parseattributes(buffer, args, 3);
00220 if(!parse_tacargs(player, mech, args, argc, MechTacRange(mech), &x, &y))
00221 return;
00222
00223 set_colorscheme(player);
00224 maptext = MakeMapText(player, mech, mech_map, x, y, 5, 5, 4, dolos);
00225
00226 sprintf(mybuff[0],
00227 " 0 %.150s",
00228 maptext[0]);
00229 sprintf(mybuff[1],
00230 " ___________ %.150s",
00231 maptext[1]);
00232 sprintf(mybuff[2],
00233 " / \\ Location:%4d,%4d, %3d %.150s",
00234 MechX(mech), MechY(mech), MechZ(mech), maptext[2]);
00235 sprintf(mybuff[3],
00236 " 300 / \\ 60 Terrain: %14s %.150s",
00237 GetTerrainName(mech_map, MechX(mech), MechY(mech)), maptext[3]);
00238 sprintf(mybuff[4],
00239 " / \\ %.150s",
00240 maptext[4]);
00241 sprintf(mybuff[5],
00242 " / \\ %.150s",
00243 maptext[5]);
00244 sprintf(mybuff[6],
00245 "270 ( ) 90 Speed: %6.1f %.150s",
00246 MechSpeed(mech), maptext[6]);
00247 sprintf(mybuff[7],
00248 " \\ / Vertical Speed: %6.1f %.150s",
00249 MechVerticalSpeed(mech), maptext[7]);
00250 sprintf(mybuff[8],
00251 " \\ / Heading: %4d %.150s",
00252 MechFacing(mech), maptext[8]);
00253 sprintf(mybuff[9],
00254 " 240 \\ / 120 %.150s",
00255 maptext[9]);
00256 sprintf(mybuff[10],
00257 " \\___________/ %.150s",
00258 maptext[10]);
00259 sprintf(mybuff[11], " ");
00260 sprintf(mybuff[12], " 180");
00261
00262 navigate_sketch_mechs(mech, mech_map, x, y, mybuff);
00263 for(i = 0; i < NAVIGATE_LINES; i++)
00264 notify(player, mybuff[i]);
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 char GetLRSMechChar(MECH * mech, MECH * other)
00287 {
00288 char c = 'u';
00289
00290 if(mech == other)
00291 return '*';
00292 if(IsDS(other))
00293 c = 'd';
00294 switch (MechMove(other)) {
00295 case MOVE_FLY:
00296 c = 'a';
00297 case MOVE_BIPED:
00298 c = 'b';
00299 break;
00300 case MOVE_QUAD:
00301 c = 'q';
00302 break;
00303 case MOVE_TRACK:
00304 c = 't';
00305 break;
00306 case MOVE_WHEEL:
00307 c = 'w';
00308 break;
00309 case MOVE_HOVER:
00310 c = 'h';
00311 break;
00312 case MOVE_VTOL:
00313 c = 'v';
00314 break;
00315 case MOVE_HULL:
00316 c = 'n';
00317 break;
00318 case MOVE_SUB:
00319 c = 's';
00320 break;
00321 case MOVE_FOIL:
00322 c = 'f';
00323 break;
00324 }
00325 if(!MechSeemsFriend(mech, other))
00326 c = toupper(c);
00327 return c;
00328 }
00329
00330 static inline char TerrainColorChar(char terrain, int elev)
00331 {
00332 switch (terrain) {
00333 case HIGHWATER:
00334 return custom_color_str[DWATER_IDX];
00335 case WATER:
00336 if(elev < 2 || elev == '0' || elev == '1' || elev == '~')
00337 return custom_color_str[SWATER_IDX];
00338 return custom_color_str[DWATER_IDX];
00339 case BUILDING:
00340 return custom_color_str[BUILDING_IDX];
00341 case ROAD:
00342 return custom_color_str[ROAD_IDX];
00343 case ROUGH:
00344 return custom_color_str[ROUGH_IDX];
00345 case MOUNTAINS:
00346 return custom_color_str[MOUNTAIN_IDX];
00347 case FIRE:
00348 return custom_color_str[FIRE_IDX];
00349 case ICE:
00350 return custom_color_str[ICE_IDX];
00351 case WALL:
00352 return custom_color_str[WALL_IDX];
00353 case SNOW:
00354 return custom_color_str[SNOW_IDX];
00355 case SMOKE:
00356 return custom_color_str[SMOKE_IDX];
00357 case LIGHT_FOREST:
00358 return custom_color_str[LWOOD_IDX];
00359 case HEAVY_FOREST:
00360 return custom_color_str[HWOOD_IDX];
00361 case UNKNOWN_TERRAIN:
00362 return custom_color_str[UNKNOWN_IDX];
00363 }
00364 return '\0';
00365 }
00366
00367 static char *add_color(char newc, char *prevc, char c)
00368 {
00369 static char buf[10];
00370 buf[0] = '\0';
00371
00372 if(newc == *prevc) {
00373 buf[0] = c;
00374 buf[1] = '\0';
00375 return buf;
00376 }
00377
00378 if(!newc || ((isupper(*prevc)) && !isupper(newc)) ||
00379 (newc == 'H' && *prevc))
00380 strcpy(buf, "%cn");
00381 else if(isupper(newc) && !isupper(*prevc))
00382 strcpy(buf, "%ch");
00383
00384 if(!newc)
00385 sprintf(buf + strlen(buf), "%c", c);
00386 else
00387 sprintf(buf + strlen(buf), "%%c%c%c", tolower(newc), c);
00388 *prevc = newc;
00389 return buf;
00390 }
00391
00392 static char *GetLRSMech(MECH * mech, MECH * other, int docolor, char *prevc)
00393 {
00394 static char buf[2];
00395 char c = GetLRSMechChar(mech, other);
00396 char newc;
00397
00398 if(!docolor) {
00399 sprintf(buf, "%c", c);
00400 return buf;
00401 }
00402
00403 if(mech == other)
00404 newc = custom_color_str[SELF_IDX];
00405 else if(!MechSeemsFriend(mech, other))
00406 newc = custom_color_str[ENEMY_IDX];
00407 else
00408 newc = custom_color_str[FRIEND_IDX];
00409
00410 return add_color(newc, prevc, c);
00411
00412 }
00413
00414 static char *LRSTerrain(MAP * map, int x, int y, int docolor, char *prevc)
00415 {
00416 static char buf[2];
00417
00418 char c = GetTerrain(map, x, y);
00419 char newc;
00420
00421 if(!c || !docolor || c == ' ') {
00422 buf[0] = c;
00423 buf[1] = '\0';
00424 return buf;
00425 } else
00426 newc = TerrainColorChar(c, GetElev(map, x, y));
00427
00428 return add_color(newc, prevc, c);
00429 }
00430
00431 static char *LRSElevation(MAP * map, int x, int y, int docolor, char *prevc)
00432 {
00433 static char buf[2];
00434
00435 int e = GetElev(map, x, y);
00436 char c = (e || docolor) ? '0' + e : ' ';
00437 char newc;
00438
00439 if(!docolor) {
00440 buf[0] = c;
00441 buf[1] = '\0';
00442 return buf;
00443 } else
00444 newc = TerrainColorChar(GetTerrain(map, x, y), e);
00445
00446 return add_color(newc, prevc, c);
00447 }
00448
00449 #define LRS_TERRAINMODE 1
00450 #define LRS_ELEVMODE 2
00451 #define LRS_MECHMODE 4
00452 #define LRS_LOSMODE 8
00453 #define LRS_COLORMODE 16
00454 #define LRS_ELEVCOLORMODE 32
00455
00456 static char *get_lrshexstr(MECH * mech, MAP * map, int x, int y,
00457 char *prevc, int mode, MECH ** mechs, int lm,
00458 hexlosmap_info * losmap)
00459 {
00460 int losflag = MAPLOSHEX_SEE | MAPLOSHEX_SEEN;
00461
00462 if(mode & LRS_MECHMODE) {
00463 while (mechs[lm] && MechY(mechs[lm]) < y)
00464 lm++;
00465 while (mechs[lm] && MechY(mechs[lm]) == y && MechX(mechs[lm]) < x)
00466 lm++;
00467 if(mechs[lm] && MechY(mechs[lm]) == y && MechX(mechs[lm]) == x)
00468 return GetLRSMech(mech, mechs[lm], mode & LRS_COLORMODE, prevc);
00469 }
00470
00471 if(losmap)
00472 losflag = LOSMap_GetFlag(losmap, x, y);
00473
00474
00475
00476
00477 if(!(losflag & MAPLOSHEX_SEEN))
00478 return add_color('R', prevc, 'X');
00479
00480 if(((mode & LRS_TERRAINMODE) && !(losflag & MAPLOSHEX_SEETERRAIN)) ||
00481 ((mode & LRS_ELEVMODE) && !(losflag & MAPLOSHEX_SEEELEV)))
00482 return add_color(TerrainColorChar(UNKNOWN_TERRAIN, 0), prevc, '?');
00483
00484 if(mode & LRS_ELEVMODE)
00485 return LRSElevation(map, x, y, mode & LRS_ELEVCOLORMODE, prevc);
00486 if(mode & LRS_TERRAINMODE)
00487 return LRSTerrain(map, x, y, mode & LRS_COLORMODE, prevc);
00488
00489 SendError(tprintf("Unknown LRS mode, mech #%d mode 0x%x.",
00490 mech->mynum, mode));
00491 return add_color('R', prevc, 'Y');
00492
00493 }
00494
00495 static void show_lrs_map(dbref player, MECH * mech, MAP * map, int x,
00496 int y, int displayHeight, int mode)
00497 {
00498 int loop, b_width, e_width, b_height, e_height, i;
00499 MECH *oMech;
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 char topbuff[4 * LRS_DISPLAY_WIDTH + 30] = " ";
00512 char botbuff[4 * LRS_DISPLAY_WIDTH + 30] = " ";
00513 char midbuff[8 + LRS_DISPLAY_WIDTH] = " ";
00514 char trash1[5];
00515 short oddcol = 0;
00516 MECH *mechs[MAX_MECHS_PER_MAP];
00517 int last_mech = 0;
00518 char prevct = 0, prevcb = 0;
00519 hexlosmap_info *losmap = NULL;
00520
00521
00522 b_width = x - LRS_DISPLAY_WIDTH / 2;
00523 b_width = MAX(b_width, 0);
00524 e_width = b_width + LRS_DISPLAY_WIDTH;
00525 if(e_width >= map->map_width) {
00526 e_width = map->map_width - 1;
00527 b_width = e_width - LRS_DISPLAY_WIDTH;
00528 b_width = MAX(b_width, 0);
00529 }
00530
00531 if(b_width % 2)
00532 oddcol = 1;
00533
00534 b_height = y - displayHeight / 2;
00535 b_height = MAX(b_height, 0);
00536 e_height = b_height + displayHeight;
00537 if(e_height > map->map_height) {
00538 e_height = map->map_height;
00539 b_height = e_height - displayHeight;
00540 b_height = MAX(b_height, 0);
00541 }
00542
00543
00544 for(i = b_width; i <= e_width; i++) {
00545 sprintf(trash1, "%3d", i);
00546 sprintf(topbuff + strlen(topbuff), "%c", trash1[0]);
00547 sprintf(midbuff + strlen(midbuff), "%c", trash1[1]);
00548 sprintf(botbuff + strlen(botbuff), "%c", trash1[2]);
00549 }
00550 notify(player, topbuff);
00551 notify(player, midbuff);
00552 notify(player, botbuff);
00553
00554 if(mode & LRS_MECHMODE) {
00555 for(i = 0; i < map->first_free; i++) {
00556 if((oMech = getMech(map->mechsOnMap[i]))) {
00557 if((mech == oMech) ||
00558 (MechY(oMech) >= b_height && MechY(oMech) <= e_height &&
00559 MechX(oMech) >= b_width && MechX(oMech) <= e_width &&
00560 InLineOfSight(mech, oMech, MechX(oMech), MechY(oMech),
00561 FlMechRange(map, mech, oMech))))
00562 mechs[last_mech++] = oMech;
00563 }
00564 }
00565 for(i = 0; i < (last_mech - 1); i++)
00566
00567 for(loop = (i + 1); loop < last_mech; loop++) {
00568 if(MechY(mechs[i]) > MechY(mechs[loop])) {
00569 oMech = mechs[i];
00570 mechs[i] = mechs[loop];
00571 mechs[loop] = oMech;
00572 } else if(MechY(mechs[i]) == MechY(mechs[loop]) &&
00573 MechX(mechs[i]) > MechX(mechs[loop])) {
00574 oMech = mechs[i];
00575 mechs[i] = mechs[loop];
00576 mechs[loop] = oMech;
00577 }
00578 }
00579 mechs[last_mech] = NULL;
00580 last_mech = 0;
00581 }
00582
00583 if(mode & LRS_LOSMODE)
00584 losmap = CalculateLOSMap(map, mech, b_width, b_height,
00585 e_width - b_width, e_height - b_height);
00586
00587 for(loop = b_height; loop < e_height; loop++) {
00588 sprintf(topbuff, "%3d ", loop);
00589 strcpy(botbuff, " ");
00590 if(mode & LRS_MECHMODE)
00591 while (mechs[last_mech] && MechY(mechs[last_mech]) < loop)
00592 last_mech++;
00593
00594 for(i = b_width; i < e_width; i += 2) {
00595 sprintf(topbuff + strlen(topbuff), oddcol ? "%s " : " %s",
00596 get_lrshexstr(mech, map, i + !oddcol, loop, &prevct,
00597 mode, mechs, last_mech, losmap));
00598
00599 sprintf(botbuff + strlen(botbuff), oddcol ? " %s" : "%s ",
00600 get_lrshexstr(mech, map, i + oddcol, loop, &prevcb,
00601 mode, mechs, last_mech, losmap));
00602 }
00603 if(i == e_width && !oddcol) {
00604 sprintf(botbuff + strlen(botbuff), "%s",
00605 get_lrshexstr(mech, map, i, loop, &prevcb, mode,
00606 mechs, last_mech, losmap));
00607 } else if(i == e_width) {
00608 sprintf(topbuff + strlen(topbuff), "%s",
00609 get_lrshexstr(mech, map, i, loop, &prevct, mode,
00610 mechs, last_mech, losmap));
00611 strcat(botbuff, " ");
00612 }
00613
00614 if(mode & (LRS_COLORMODE | LRS_ELEVCOLORMODE)) {
00615 if(prevct) {
00616 strcat(topbuff, "%cn");
00617 prevct = 0;
00618 }
00619 if(prevcb) {
00620 strcat(botbuff, "%cn");
00621 prevcb = 0;
00622 }
00623 }
00624 sprintf(botbuff + strlen(botbuff), " %-3d", loop);
00625 notify(player, topbuff);
00626 notify(player, botbuff);
00627 }
00628 }
00629
00630 void mech_lrsmap(dbref player, void *data, char *buffer)
00631 {
00632 MECH *mech = (MECH *) data;
00633 MAP *map;
00634 int argc, mode = 0;
00635 short x, y;
00636 char *args[5], *str;
00637 int displayHeight = LRS_DISPLAY_HEIGHT;
00638
00639 cch(MECH_USUAL);
00640
00641 if(Ansimap(player))
00642 mode |= LRS_COLORMODE;
00643
00644 map = getMap(mech->mapindex);
00645
00646 argc = mech_parseattributes(buffer, args, 4);
00647 DOCHECK(!MechLRSRange(mech), "Your system seems to be inoperational.");
00648 if(!parse_tacargs(player, mech, &args[1], argc - 1,
00649 MechLRSRange(mech), &x, &y))
00650 return;
00651 switch (args[0][0]) {
00652 case 'M':
00653 case 'm':
00654 mode |= LRS_MECHMODE | LRS_TERRAINMODE;
00655 break;
00656 case 'E':
00657 case 'e':
00658 mode |= LRS_ELEVMODE;
00659 break;
00660 case 'C':
00661 case 'c':
00662 mode |= LRS_ELEVMODE | LRS_ELEVCOLORMODE;
00663 break;
00664 case 'T':
00665 case 't':
00666 mode |= LRS_TERRAINMODE;
00667 break;
00668 case 'L':
00669 case 'l':
00670 mode |= LRS_LOSMODE | LRS_TERRAINMODE;
00671 break;
00672 case 'H':
00673 case 'h':
00674 mode |= LRS_LOSMODE | LRS_ELEVMODE;
00675 break;
00676 case 'S':
00677 case 's':
00678 mode |= LRS_LOSMODE | LRS_MECHMODE | LRS_TERRAINMODE;
00679 break;
00680 default:
00681 notify_printf(player, "Unknown LRS sensor type '%s'!", args[0]);
00682 return;
00683 }
00684
00685 if(MapIsDark(map) || (MechType(mech) == CLASS_MW &&
00686 mudconf.btech_mw_losmap))
00687 mode |= LRS_LOSMODE;
00688
00689 str = silly_atr_get(player, A_LRSHEIGHT);
00690 if(*str) {
00691 displayHeight = atoi(str);
00692 if(displayHeight < 10 || displayHeight > 40) {
00693 notify(player,
00694 "Illegal LRSHeight attribute. Must be between 10 and 40");
00695 displayHeight = LRS_DISPLAY_HEIGHT;
00696 }
00697 }
00698
00699 displayHeight = MIN(displayHeight, 2 * MechLRSRange(mech));
00700 displayHeight = MIN(displayHeight, map->map_height);
00701
00702 if(!(displayHeight % 2))
00703 displayHeight++;
00704
00705 set_colorscheme(player);
00706
00707 show_lrs_map(player, mech, map, x, y, displayHeight, mode);
00708 }
00709
00710 static inline int is_oddcol(int col)
00711 {
00712
00713
00714
00715
00716 return (unsigned) col & 1;
00717 }
00718
00719 static inline int tac_dispcols(int hexcols)
00720 {
00721 return hexcols * 3 + 1;
00722 }
00723
00724 static inline int tac_hex_offset(int x, int y, int dispcols, int oddcol1)
00725 {
00726 int oddcolx = is_oddcol(x + oddcol1);
00727
00728 return (y * 2 + 1 - oddcolx) * dispcols + x * 3 + 1;
00729 }
00730
00731 static inline void sketch_tac_row(char *pos, int left_offset,
00732 char const *src, int len)
00733 {
00734 memset(pos, ' ', left_offset);
00735 memcpy(pos + left_offset, src, len);
00736 pos[left_offset + len] = '\0';
00737 }
00738
00739 static void sketch_tac_map(char *buf, MAP * map, MECH * mech, int sx,
00740 int sy, int wx, int wy, int dispcols,
00741 int top_offset, int left_offset, int docolour,
00742 int dohexlos)
00743 {
00744 #if 0
00745 static char const hexrow[2][76] = {
00746 "\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/",
00747 "/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\"
00748 };
00749 #else
00750 static char const hexrow[2][310] = {
00751 "\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/]["
00752 "\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/]["
00753 "\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/]["
00754 "\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/]["
00755 "\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/",
00756 "/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\]["
00757 "/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\]["
00758 "/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\]["
00759 "/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\]["
00760 "/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\][/][\\"
00761 };
00762 #endif
00763 int x, y;
00764 int oddcol1 = is_oddcol(sx);
00765 char *pos;
00766 int mapcols = tac_dispcols(wx);
00767 hexlosmap_info *losmap = NULL;
00768
00769
00770
00771
00772 pos = buf;
00773 for(y = 0; y < top_offset; y++) {
00774 memset(pos, ' ', dispcols - 1);
00775 pos[dispcols - 1] = '\0';
00776 pos += dispcols;
00777 }
00778 for(y = 0; y < wy; y++) {
00779 sketch_tac_row(pos, left_offset, hexrow[oddcol1], mapcols);
00780 pos += dispcols;
00781 sketch_tac_row(pos, left_offset, hexrow[!oddcol1], mapcols);
00782 pos += dispcols;
00783 }
00784 sketch_tac_row(pos, left_offset, hexrow[oddcol1], mapcols);
00785
00786
00787
00788
00789 pos = buf + top_offset * dispcols + left_offset;
00790 wx = MIN(wx, map->map_width - sx);
00791 wy = MIN(wy, map->map_height - sy);
00792
00793 if(dohexlos)
00794 losmap = CalculateLOSMap(map, mech, MAX(0, sx), MAX(0, sy), wx, wy);
00795
00796 for(y = MAX(0, -sy); y < wy; y++) {
00797 for(x = MAX(0, -sx); x < wx; x++) {
00798 int terr, elev, losflag = MAPLOSHEX_SEE | MAPLOSHEX_SEEN;
00799 char *base;
00800 char topchar, botchar;
00801
00802 if(losmap)
00803 losflag = LOSMap_GetFlag(losmap, sx + x, sy + y);
00804
00805 if(!(losflag & MAPLOSHEX_SEEN)) {
00806 terr = 'X';
00807 elev = 40;
00808 } else {
00809
00810 if(losflag & MAPLOSHEX_SEETERRAIN)
00811 terr = GetTerrain(map, sx + x, sy + y);
00812 else
00813 terr = UNKNOWN_TERRAIN;
00814
00815 if(losflag & MAPLOSHEX_SEEELEV)
00816 elev = GetElev(map, sx + x, sy + y);
00817 else
00818 elev = 15;
00819 }
00820 base = pos + tac_hex_offset(x, y, dispcols, oddcol1);
00821
00822 switch (terr) {
00823 case WATER:
00824
00825
00826
00827
00828
00829
00830 if(docolour && elev >= 2) {
00831 topchar = '\242';
00832 botchar = '\242';
00833 } else {
00834 topchar = '~';
00835 botchar = '~';
00836 }
00837 break;
00838
00839 case HIGHWATER:
00840 topchar = '~';
00841 botchar = '+';
00842 break;
00843
00844 case BRIDGE:
00845 topchar = '#';
00846 botchar = '+';
00847 break;
00848
00849 case ' ':
00850 topchar = ' ';
00851 botchar = '_';
00852 break;
00853
00854 case UNKNOWN_TERRAIN:
00855 topchar = '?';
00856 botchar = '?';
00857 break;
00858
00859 default:
00860 topchar = terr;
00861 botchar = terr;
00862 break;
00863 }
00864
00865 base[0] = topchar;
00866 base[1] = topchar;
00867 base[dispcols + 0] = botchar;
00868 if(elev > 0) {
00869 botchar = '0' + elev;
00870 }
00871 base[dispcols + 1] = botchar;
00872 }
00873 }
00874 }
00875
00876
00877
00878
00879 static void sketch_tac_ds(char *base, int dispcols, char terr)
00880 {
00881
00882
00883
00884 if(!isalpha(base[0]) && base[0] != '*') {
00885 base[0] = terr;
00886 base[1] = terr;
00887 }
00888 base[dispcols + 0] = terr;
00889 if(!isdigit((unsigned char) base[dispcols + 1])) {
00890 base[dispcols + 1] = terr;
00891 }
00892 }
00893
00894 extern int dirs[6][2];
00895
00896 static void sketch_tac_ownmech(char *buf, MAP * map, MECH * mech, int sx,
00897 int sy, int wx, int wy, int dispcols,
00898 int top_offset, int left_offset)
00899 {
00900
00901 int oddcol1 = is_oddcol(sx);
00902 char *pos = buf + top_offset * dispcols + left_offset;
00903 char *base;
00904 int x = MechX(mech) - sx;
00905 int y = MechY(mech) - sy;
00906
00907 if(x < 0 || x >= wx || y < 0 || y >= wy) {
00908 return;
00909 }
00910 base = pos + tac_hex_offset(x, y, dispcols, oddcol1);
00911 base[0] = '*';
00912 base[0] = '*';
00913 }
00914
00915 static void sketch_tac_mechs(char *buf, MAP * map, MECH * player_mech,
00916 int sx, int sy, int wx, int wy, int dispcols,
00917 int top_offset, int left_offset, int docolour,
00918 int labels)
00919 {
00920 int i;
00921 char *pos = buf + top_offset * dispcols + left_offset;
00922 int oddcol1 = is_oddcol(sx);
00923
00924
00925
00926
00927 for(i = 0; i < map->first_free; i++) {
00928 int x, y;
00929 char *base;
00930 MECH *mech;
00931
00932 if(map->mechsOnMap[i] == -1) {
00933 continue;
00934 }
00935
00936 mech = getMech(map->mechsOnMap[i]);
00937 if(mech == NULL) {
00938 continue;
00939 }
00940
00941
00942
00943
00944
00945 x = MechX(mech) - sx;
00946 y = MechY(mech) - sy;
00947 if(!IsDS(mech) && (x < 0 || x >= wx || y < 0 || y >= wy)) {
00948 continue;
00949 }
00950
00951 if(IsDS(mech) && (x < -1 || x > wx || y < -1 || y > wy)) {
00952 continue;
00953 }
00954
00955 if(mech != player_mech &&
00956 !InLineOfSight(player_mech, mech, MechX(mech), MechY(mech),
00957 FlMechRange(map, player_mech, mech))) {
00958 continue;
00959 }
00960
00961 base = pos + tac_hex_offset(x, y, dispcols, oddcol1);
00962 if(!(MechSpecials2(mech) & CARRIER_TECH) && IsDS(mech) &&
00963 ((MechZ(mech) >= ORBIT_Z && mech != player_mech) || Landed(mech)
00964 || !Started(mech))) {
00965 int ts = DSBearMod(mech);
00966 int dir;
00967
00968
00969
00970
00971
00972
00973
00974 for(dir = 0; dir < 6; dir++) {
00975 int tx = x + dirs[dir][0];
00976 int ty = y + dirs[dir][1];
00977
00978 if((tx + oddcol1) % 2 == 0 && dirs[dir][0] != 0) {
00979 ty--;
00980 }
00981 if(tx < 0 || tx >= wx || ty < 0 || ty >= wy) {
00982 continue;
00983 }
00984 base = pos + tac_hex_offset(tx, ty, dispcols, oddcol1);
00985 if(Find_DS_Bay_Number(mech, (dir - ts + 6) % 6)
00986 >= 0) {
00987 sketch_tac_ds(base, dispcols, '@');
00988 } else {
00989 sketch_tac_ds(base, dispcols, '=');
00990 }
00991 }
00992 if(x < 0 || x >= wx || y < 0 || y >= wy)
00993 continue;
00994
00995 base = pos + tac_hex_offset(x, y, dispcols, oddcol1);
00996 if(docolour) {
00997
00998
00999
01000
01001 sketch_tac_ds(base, dispcols, '$');
01002 } else {
01003 sketch_tac_ds(base, dispcols, 'X');
01004 }
01005
01006 if(isalpha(base[0]))
01007 continue;
01008
01009 if(mech == player_mech) {
01010 base[0] = '*';
01011 base[1] = '*';
01012 } else {
01013 char *id = MechIDS(mech, MechSeemsFriend(player_mech, mech));
01014 base[0] = id[0];
01015 base[1] = id[1];
01016 }
01017
01018 } else if(mech == player_mech) {
01019 if(isalpha(base[0]))
01020 continue;
01021 base[0] = '*';
01022 base[1] = '*';
01023 } else {
01024 char *id = MechIDS(mech, MechSeemsFriend(player_mech, mech));
01025 base[0] = id[0];
01026 base[1] = id[1];
01027 }
01028 }
01029 }
01030
01031 static void sketch_tac_cliffs(char *buf, MAP * map, int sx, int sy, int wx,
01032 int wy, int dispcols, int top_offset,
01033 int left_offset, int cliff_size)
01034 {
01035 char *pos = buf + top_offset * dispcols + left_offset;
01036 int y, x;
01037 int oddcol1 = is_oddcol(sx);
01038
01039 wx = MIN(wx, map->map_width - sx);
01040 wy = MIN(wy, map->map_height - sy);
01041 for(y = MAX(0, -sy); y < wy; y++) {
01042 int ty = sy + y;
01043
01044 for(x = MAX(0, -sx); x < wx; x++) {
01045 int tx = sx + x;
01046 int oddcolx = is_oddcol(tx);
01047 int elev = Elevation(map, tx, ty);
01048 char *base = pos + tac_hex_offset(x, y, dispcols,
01049 oddcol1);
01050 char c;
01051
01052
01053
01054
01055
01056 c = base[dispcols + 1];
01057 if(base[0] == '*') {
01058 base[0] = '*';
01059 base[1] = '*';
01060 } else if(isdigit((unsigned char) c)) {
01061 base[1] = c;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071 if(x != 0 && (y < wy - 1 || oddcolx)
01072 && abs(Elevation(map, tx - 1, ty + 1 - oddcolx)
01073 - elev) >= cliff_size) {
01074
01075 base[dispcols - 1] = '|';
01076 }
01077 if(y < wy - 1 && abs(Elevation(map, tx, ty + 1) - elev)
01078 >= cliff_size) {
01079 base[dispcols] = ',';
01080 base[dispcols + 1] = ',';
01081 } else {
01082 base[dispcols] = '_';
01083 base[dispcols + 1] = '_';
01084 }
01085 if(x < wx - 1 && (y < wy - 1 || oddcolx)
01086 && abs(Elevation(map, tx + 1, ty + 1 - oddcolx)
01087 - elev) >= cliff_size) {
01088 base[dispcols + 2] = '!';
01089 }
01090 }
01091 }
01092 }
01093 static void sketch_tac_dslz(char *buf, MAP * map, MECH * mech, int sx,
01094 int sy, int wx, int wy, int dispcols,
01095 int top_offset, int left_offset, int cliff_size,
01096 int docolour)
01097 {
01098 char *pos = buf + top_offset * dispcols + left_offset;
01099 int y, x;
01100 int oddcol1 = is_oddcol(sx);
01101
01102 wx = MIN(wx, map->map_width - sx);
01103 wy = MIN(wy, map->map_height - sy);
01104 for(y = MAX(0, -sy); y < wy; y++) {
01105 int ty = sy + y;
01106
01107 for(x = MAX(0, -sx); x < wx; x++) {
01108 int tx = sx + x;
01109 char *base = pos + tac_hex_offset(x, y, dispcols, oddcol1);
01110
01111 if(ImproperLZ(mech, tx, ty))
01112 base[dispcols] = docolour ? '\241' : 'X';
01113 else
01114 base[dispcols] = docolour ? '\240' : 'O';
01115 }
01116 }
01117 }
01118
01119
01120
01121
01122
01123 static char **colourize_tac_map(char const *sketch, int dispcols,
01124 int disprows)
01125 {
01126 static char *buf = NULL;
01127 static int buf_len = 5000;
01128 static char **lines = NULL;
01129 static int lines_len = 100;
01130 int pos = 0;
01131 int line = 0;
01132 unsigned char cur_colour = '\0';
01133 const char *line_start;
01134 char const *src = sketch;
01135
01136 if(buf == NULL) {
01137 Create(buf, char, buf_len);
01138 }
01139 if(lines == NULL) {
01140 Create(lines, char *, lines_len);
01141 }
01142
01143 line_start = (char *) src;
01144 lines[0] = buf;
01145 while (lines > 0) {
01146 unsigned char new_colour;
01147 unsigned char c = *src++;
01148
01149 if(c == '\0') {
01150
01151
01152
01153 if(cur_colour != '\0') {
01154 buf[pos++] = '%';
01155 buf[pos++] = 'c';
01156 buf[pos++] = 'n';
01157 }
01158 buf[pos++] = '\0';
01159 line++;
01160 if(line >= disprows) {
01161 break;
01162 }
01163 if(line + 1 >= lines_len) {
01164 lines_len *= 2;
01165 ReCreate(lines, char *, lines_len);
01166 }
01167 line_start += dispcols;
01168 src = line_start;
01169 lines[line] = buf + pos;
01170 continue;
01171 }
01172
01173 switch (c) {
01174 case (unsigned char) '\242':
01175 c = '~';
01176 new_colour = custom_color_str[DWATER_IDX];
01177 break;
01178
01179 case (unsigned char) '\241':
01180 c = 'X';
01181 new_colour = custom_color_str[BADLZ_IDX];
01182 break;
01183 case (unsigned char) '\240':
01184 c = 'O';
01185 new_colour = custom_color_str[GOODLZ_IDX];
01186 break;
01187 case '?':
01188 c = '?';
01189 new_colour = custom_color_str[UNKNOWN_IDX];
01190 break;
01191
01192 case '$':
01193 c = 'X';
01194 new_colour = custom_color_str[DS_IDX];
01195 break;
01196
01197 case '!':
01198 c = '/';
01199 new_colour = custom_color_str[CLIFF_IDX];
01200 break;
01201
01202 case '|':
01203 c = '\\';
01204 new_colour = custom_color_str[CLIFF_IDX];
01205 break;
01206
01207 case ',':
01208 c = '_';
01209 new_colour = custom_color_str[CLIFF_IDX];
01210 break;
01211 case '*':
01212 new_colour = custom_color_str[SELF_IDX];
01213 break;
01214
01215 default:
01216 if(islower(c)) {
01217 new_colour = custom_color_str[FRIEND_IDX];
01218 } else if(isupper(c)) {
01219 new_colour = custom_color_str[ENEMY_IDX];
01220 } else if(isdigit(c)) {
01221 new_colour = cur_colour;
01222 } else {
01223 new_colour = TerrainColorChar(c, 0);
01224 }
01225 break;
01226 }
01227
01228 if(isupper(new_colour) != isupper(cur_colour)) {
01229 if(isupper(new_colour)) {
01230 buf[pos++] = '%';
01231 buf[pos++] = 'c';
01232 buf[pos++] = 'h';
01233 } else {
01234 buf[pos++] = '%';
01235 buf[pos++] = 'c';
01236 buf[pos++] = 'n';
01237 cur_colour = '\0';
01238 }
01239 }
01240 if(tolower(new_colour) != tolower(cur_colour)) {
01241 buf[pos++] = '%';
01242 buf[pos++] = 'c';
01243 if(new_colour == '\0') {
01244 buf[pos++] = 'n';
01245 } else if(new_colour == 'H') {
01246 buf[pos++] = 'n';
01247 buf[pos++] = '%';
01248 buf[pos++] = 'c';
01249 buf[pos++] = tolower(new_colour);
01250 } else {
01251 buf[pos++] = tolower(new_colour);
01252 }
01253 cur_colour = new_colour;
01254 }
01255 buf[pos++] = c;
01256 if(pos + 11 > buf_len) {
01257
01258
01259
01260
01261
01262
01263 buf_len *= 2;
01264 free(buf);
01265 buf = NULL;
01266 return colourize_tac_map(sketch, dispcols, disprows);
01267 }
01268 }
01269 lines[line] = NULL;
01270 return lines;
01271 }
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302 char **MakeMapText(dbref player, MECH * mech, MAP * map, int cx, int cy,
01303 int wx, int wy, int labels, int dohexlos)
01304 {
01305 int docolour = Ansimap(player);
01306 int dispcols;
01307 int disprows;
01308 int mapcols;
01309 int left_offset = 0;
01310 int top_offset = 0;
01311 int navigate = 0;
01312 int sx, sy;
01313 int i;
01314 char *base;
01315 int oddcol1;
01316 enum {
01317 MAX_WIDTH = 40,
01318 MAX_HEIGHT = 24,
01319 TOP_LABEL = 3,
01320 LEFT_LABEL = 4,
01321 RIGHT_LABEL = 3
01322 };
01323 static char sketch_buf[((LEFT_LABEL + 1 + MAX_WIDTH * 3 + RIGHT_LABEL +
01324 1) * (TOP_LABEL + 1 + MAX_HEIGHT * 2) + 2) * 5];
01325 static char *lines[(TOP_LABEL + 1 + MAX_HEIGHT * 2 + 1) * 5];
01326
01327 if(labels & 4) {
01328 navigate = 1;
01329 labels = 0;
01330 }
01331
01332
01333
01334
01335 wx = MIN(MAX_WIDTH, wx);
01336 wy = MIN(MAX_HEIGHT, wy);
01337
01338 sx = cx - wx / 2;
01339 sy = cy - wy / 2;
01340 if(!navigate) {
01341
01342
01343
01344 sx = MAX(0, MIN(sx, map->map_width - wx));
01345 sy = MAX(0, MIN(sy, map->map_height - wy));
01346 wx = MIN(wx, map->map_width);
01347 wy = MIN(wy, map->map_height);
01348 }
01349
01350 mapcols = tac_dispcols(wx);
01351 dispcols = mapcols + 1;
01352 disprows = wy * 2 + 1;
01353 oddcol1 = is_oddcol(sx);
01354
01355 if(navigate) {
01356 if(oddcol1) {
01357
01358
01359
01360
01361 top_offset = 1;
01362 disprows++;
01363 }
01364 } else {
01365
01366
01367
01368 if(labels & 1) {
01369 left_offset = LEFT_LABEL;
01370 dispcols += LEFT_LABEL + RIGHT_LABEL;
01371 }
01372 if(labels & 2) {
01373 top_offset = TOP_LABEL;
01374 disprows += TOP_LABEL;
01375 }
01376 }
01377
01378
01379
01380
01381 sketch_tac_map(sketch_buf, map, mech, sx, sy, wx, wy, dispcols,
01382 top_offset, left_offset, docolour, dohexlos);
01383
01384
01385
01386
01387 if(labels & 1) {
01388 int x;
01389
01390 for(x = 0; x < wx; x++) {
01391 char scratch[4];
01392 int label = sx + x;
01393
01394 if(label < 0 || label > 999) {
01395 continue;
01396 }
01397 sprintf(scratch, "%3d", label);
01398 base = sketch_buf + left_offset + 1 + x * 3;
01399 base[0] = scratch[0];
01400 base[1 * dispcols] = scratch[1];
01401 base[2 * dispcols] = scratch[2];
01402 }
01403 }
01404
01405 if(labels & 2) {
01406 int y;
01407
01408 for(y = 0; y < wy; y++) {
01409 int label = sy + y;
01410
01411 base = sketch_buf + (top_offset + 1 + y * 2)
01412 * dispcols;
01413 if(label < 0 || label > 999) {
01414 continue;
01415 }
01416
01417 sprintf(base, "%3d", label);
01418 base[3] = ' ';
01419 sprintf(base + (dispcols - RIGHT_LABEL - 1), "%3d", label);
01420 }
01421 }
01422
01423 if(labels & 8) {
01424 if(mech != NULL) {
01425 sketch_tac_ownmech(sketch_buf, map, mech, sx, sy, wx, wy,
01426 dispcols, top_offset, left_offset);
01427 }
01428 sketch_tac_cliffs(sketch_buf, map, sx, sy, wx, wy, dispcols,
01429 top_offset, left_offset, 3);
01430 } else if(labels & 16) {
01431 if(mech != NULL) {
01432 sketch_tac_ownmech(sketch_buf, map, mech, sx, sy, wx, wy,
01433 dispcols, top_offset, left_offset);
01434 }
01435 sketch_tac_cliffs(sketch_buf, map, sx, sy, wx, wy, dispcols,
01436 top_offset, left_offset, 2);
01437 } else if(labels & 32) {
01438 if(mech != NULL) {
01439 sketch_tac_ownmech(sketch_buf, map, mech, sx, sy, wx, wy,
01440 dispcols, top_offset, left_offset);
01441 }
01442 sketch_tac_dslz(sketch_buf, map, mech, sx, sy, wx, wy, dispcols,
01443 top_offset, left_offset, 2, docolour);
01444 } else if(mech != NULL) {
01445 sketch_tac_mechs(sketch_buf, map, mech, sx, sy, wx, wy, dispcols,
01446 top_offset, left_offset, docolour, labels);
01447 }
01448
01449 if(navigate) {
01450 int n = wx / 2;
01451
01452
01453
01454
01455
01456 if(oddcol1) {
01457
01458
01459
01460 disprows--;
01461 }
01462
01463 for(i = 0; i < n; i++) {
01464 int len;
01465
01466 base = sketch_buf + (i + 1) * dispcols + left_offset;
01467 len = (n - i - 1) * 3 + 1;
01468 memset(base, ' ', len);
01469 base[len] = '_';
01470 base[len + 1] = '_';
01471 base[mapcols - len - 2] = '_';
01472 base[mapcols - len - 1] = '_';
01473 base[mapcols - len] = '\0';
01474
01475 base = sketch_buf + (disprows - i - 1) * dispcols + left_offset;
01476 len = (n - i) * 3;
01477 memset(base, ' ', len);
01478 base[mapcols - len] = '\0';
01479 }
01480
01481 memset(sketch_buf + left_offset, ' ', n * 3 + 1);
01482 sketch_buf[left_offset + n * 3 + 1] = '_';
01483 sketch_buf[left_offset + n * 3 + 2] = '_';
01484 sketch_buf[left_offset + n * 3 + 3] = '\0';
01485 }
01486
01487 if(docolour) {
01488
01489
01490
01491
01492 return colourize_tac_map(sketch_buf, dispcols, disprows);
01493 }
01494
01495
01496
01497
01498 for(i = 0; i < disprows; i++) {
01499 lines[i] = sketch_buf + dispcols * i;
01500 }
01501 lines[i] = NULL;
01502 return lines;
01503 }
01504
01505
01506
01507
01508 void mech_tacmap(dbref player, void *data, char *buffer)
01509 {
01510 MECH *mech = (MECH *) data;
01511 int argc, i;
01512 short x, y;
01513 int mapx, mapy;
01514 char *args_vec[4];
01515 char **args = args_vec;
01516 MAP *mech_map;
01517 int displayHeight = MAP_DISPLAY_HEIGHT, displayWidth = MAP_DISPLAY_WIDTH;
01518 char *str;
01519 char **maptext;
01520 int flags = 3, dohexlos = 0;
01521
01522
01523 cch(MECH_USUAL);
01524
01525
01526 mech_map = getMap(mech->mapindex);
01527 mapx = MechX(mech);
01528 mapy = MechY(mech);
01529
01530
01531 argc = mech_parseattributes(buffer, args, 4);
01532 DOCHECK(!MechTacRange(mech), "Your system seems to be inoperational.");
01533
01534 if(MapIsDark(mech_map) || (MechType(mech) == CLASS_MW &&
01535 mudconf.btech_mw_losmap))
01536 dohexlos = 1;
01537
01538
01539
01540 if(argc > 0 && isalpha((unsigned char) args[0][0])
01541 && args[0][1] == '\0') {
01542
01543 switch (tolower((unsigned char) args[0][0])) {
01544 case 'c':
01545 flags |= 8;
01546 break;
01547
01548 case 't':
01549 flags |= 16;
01550 break;
01551
01552 case 'l':
01553 dohexlos = 1;
01554 break;
01555
01556 case 'b':
01557 flags |= 32;
01558 break;
01559
01560 default:
01561 notify(player, "Invalid tactical map flag.");
01562 return;
01563 }
01564
01565 args++;
01566 argc--;
01567 }
01568
01569 DOCHECK(dohexlos
01570 && (flags & (8 | 16 | 32)), "You can't see that much here!");
01571
01572 if(!parse_tacargs(player, mech, args, argc, MechTacRange(mech), &x, &y))
01573 return;
01574
01575
01576
01577
01578
01579 str = silly_atr_get(player, A_TACSIZE);
01580 if(!*str) {
01581 displayHeight = MAP_DISPLAY_HEIGHT;
01582 displayWidth = MAP_DISPLAY_WIDTH;
01583 } else if(sscanf(str, "%d %d", &displayHeight, &displayWidth) != 2 ||
01584 displayHeight > 24 || displayHeight < 5 || displayWidth > 40 ||
01585 displayWidth < 5) {
01586
01587 notify(player,
01588 "Illegal Tacsize attribute. Must be in format "
01589 "'Height Width' . Height : 5-24 Width : 5-40");
01590 displayHeight = MAP_DISPLAY_HEIGHT;
01591 displayWidth = MAP_DISPLAY_WIDTH;
01592 }
01593
01594
01595
01596 displayHeight = (displayHeight <= 2 * MechTacRange(mech)
01597 ? displayHeight : 2 * MechTacRange(mech));
01598 displayWidth = (displayWidth <= 2 * MechTacRange(mech)
01599 ? displayWidth : 2 * MechTacRange(mech));
01600
01601 displayHeight = (displayHeight <= mech_map->map_height)
01602 ? displayHeight : mech_map->map_height;
01603 displayWidth = (displayWidth <= mech_map->map_width)
01604 ? displayWidth : mech_map->map_width;
01605
01606 set_colorscheme(player);
01607
01608
01609 maptext =
01610 MakeMapText(player, mech, mech_map, x, y, displayWidth,
01611 displayHeight, flags, dohexlos);
01612
01613
01614 for(i = 0; maptext[i]; i++)
01615 notify(player, maptext[i]);
01616 }
01617
01618
01619 static void mech_enter_event(MUXEVENT * e)
01620 {
01621 MECH *mech = (MECH *) e->data, *tmpm = NULL;
01622 mapobj *mapo;
01623 MAP *map = getMap(mech->mapindex), *newmap;
01624 int target = (int) e->data2;
01625 int x, y;
01626
01627 if(!(mapo = find_entrance_by_xy(map, MechX(mech), MechY(mech))))
01628 return;
01629 if(!Started(mech) || Uncon(mech) || Jumping(mech) ||
01630 (MechType(mech) == CLASS_MECH && (Fallen(mech) || Standing(mech)))
01631 || OODing(mech) || (fabs(MechSpeed(mech)) * 5 >= MMaxSpeed(mech) &&
01632 fabs(MMaxSpeed(mech)) >= MP1)
01633 || (MechType(mech) == CLASS_VTOL && AeroFuel(mech) <= 0))
01634 return;
01635 if(!(newmap = getMap(mapo->obj)))
01636 return;
01637 if(!find_entrance(newmap, target, &x, &y))
01638 return;
01639
01640 if(!can_pass_lock(mech->mynum, newmap->mynum, A_LENTER) &&
01641 (BuildIsSafe(newmap) || newmap->cf >= (newmap->cfmax / 2))) {
01642 char *msg = silly_atr_get(newmap->mynum, A_FAIL);
01643 if(!msg || !*msg)
01644 msg = "The hangar is locked.";
01645 mech_notify(mech, MECHALL, msg);
01646 return;
01647 }
01648
01649 StopBSuitSwarmers(FindObjectsData(mech->mapindex), mech, 1);
01650 mech_printf(mech, MECHALL, "You enter %s.", structure_name(mapo));
01651 MechLOSBroadcast(mech, tprintf("has entered %s at %d,%d.",
01652 structure_name(mapo), MechX(mech),
01653 MechY(mech)));
01654 MarkForLOSUpdate(mech);
01655 if(MechType(mech) == CLASS_MW && !In_Character(mapo->obj)) {
01656 enter_mw_bay(mech, mapo->obj);
01657 return;
01658 }
01659 if(MechCarrying(mech) > 0)
01660 tmpm = getMech(MechCarrying(mech));
01661 mech_Rsetmapindex(GOD, (void *) mech, tprintf("%d", (int) mapo->obj));
01662 mech_Rsetxy(GOD, (void *) mech, tprintf("%d %d", x, y));
01663 MechLOSBroadcast(mech, tprintf("has entered %s at %d,%d.",
01664 structure_name(mapo), MechX(mech),
01665 MechY(mech)));
01666 loud_teleport(mech->mynum, mapo->obj);
01667 if(tmpm) {
01668 mech_Rsetmapindex(GOD, (void *) tmpm, tprintf("%d", (int) mapo->obj));
01669 mech_Rsetxy(GOD, (void *) tmpm, tprintf("%d %d", x, y));
01670 loud_teleport(tmpm->mynum, mapo->obj);
01671 }
01672 auto_cal_mapindex(mech);
01673 }
01674
01675 void mech_enterbase(dbref player, void *data, char *buffer)
01676 {
01677 MECH *mech = (MECH *) data;
01678 MAP *map, *newmap;
01679 int x, y;
01680 mapobj *mapo;
01681 char target, *tmpc;
01682 char *args[2];
01683 int argc;
01684
01685 char fail_mesg[SBUF_SIZE];
01686
01687 argc = mech_parseattributes(buffer, args, 2);
01688 DOCHECK(argc > 1, "Invalid arguments to command!");
01689 tmpc = args[0];
01690 if(argc > 0 && *tmpc && !(*(tmpc + 1)))
01691 target = tolower(*tmpc);
01692 else
01693 target = 0;
01694 cch(MECH_USUAL);
01695 map = getMap(mech->mapindex);
01696
01697 DOCHECK(Jumping(mech), "While in mid-jump? No way.");
01698 DOCHECK(MechType(mech) == CLASS_MECH && (Fallen(mech) ||
01699 Standing(mech)),
01700 "Crawl inside? I think not. Stand first.");
01701 DOCHECK(OODing(mech), "While in mid-flight? No way.");
01702 DOCHECK(MechType(mech) == CLASS_VTOL &&
01703 AeroFuel(mech) <= 0, "You lack fuel to maneuver in!");
01704 DOCHECK(FlyingT(mech) &&
01705 !Landed(mech),
01706 "You need to land before you can enter the hangar.");
01707 DOCHECK(IsDS(mech),
01708 "Heh, you're trying to be funny, right, a DropShip entering hangar?");
01709 DOCHECK(fabs(MechSpeed(mech)) * 5 >= MMaxSpeed(mech) &&
01710 fabs(MMaxSpeed(mech)) >= MP1,
01711 "You are moving too fast to enter the hangar!");
01712 DOCHECK(!(mapo =
01713 find_entrance_by_xy(map, MechX(mech), MechY(mech))),
01714 "You see nothing to enter here!");
01715
01716 if(!(newmap = FindObjectsData(mapo->obj))) {
01717 mech_notify(mech, MECHALL,
01718 "You sense wrongness in fabric of space..");
01719 SendError(tprintf
01720 ("Error: No map existing for mapindex #%d (@ %d,%d of #%d)",
01721 (int) mapo->obj, mapo->x, mapo->y, mech->mapindex));
01722 return;
01723 }
01724 if(!find_entrance(newmap, target, &x, &y)) {
01725 mech_notify(mech, MECHALL,
01726 "You sense wrongness in fabric of space..");
01727 SendError(tprintf
01728 ("Error: No entrance existing for mapindex #%d (@ %d,%d of #%d)",
01729 (int) mapo->obj, mapo->x, mapo->y, mech->mapindex));
01730 return;
01731 }
01732
01733 if(!can_pass_lock(mech->mynum, newmap->mynum, A_LENTER) &&
01734 (BuildIsSafe(newmap) || newmap->cf >= (newmap->cfmax / 2))) {
01735
01736
01737 memset(fail_mesg, 0, sizeof(fail_mesg));
01738 snprintf(fail_mesg, LBUF_SIZE, "The hangar is locked.");
01739
01740 did_it(player, newmap->mynum, A_FAIL, fail_mesg, 0, NULL, A_AFAIL,
01741 (char **) NULL, 0);
01742
01743 return;
01744 }
01745
01746 DOCHECK(EnteringHangar(mech), "You are already entering the hangar!");
01747
01748 HexLOSBroadcast(map, MechX(mech), MechY(mech),
01749 "The doors at $h start to open..");
01750 MECHEVENT(mech, EVENT_ENTER_HANGAR, mech_enter_event, 18, (int) target);
01751 }