#include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <zlib.h> #include "merc.h" #include "world.h" #include "recycle.h" #define MOVE_AMMOUNT 10 /* * wilderness_table() * * Contains all sectors, their internal name, color/symbol, their * save number, the RGB colors, if its passable, and if you can * see 'through' it. */ struct wilderness_type wilderness_table[] = { /*# Red Grn Blu */ {"Grass", "{g.", 0, 0, 255, 0, TRUE, TRUE }, /* 0 */ {"Mountain", "{D^", 1, 0, 0, 0, TRUE, TRUE }, /* 1 */ {"River", "{C~", 2, 0, 255, 255, TRUE, TRUE }, /* 2 */ {"Ocean", "{b~", 3, 0, 0, 255, TRUE, TRUE }, /* 3 */ {"Beach", "{y.", 4, 1, 1, 1, TRUE, TRUE }, /* 4 */ {"Desert", "{y^", 5, 255, 255, 0, TRUE, TRUE }, /* 5 */ {"Hills", "{w^", 6, 128, 128, 128, TRUE, TRUE }, /* 6 */ {"Tree", "{G*", 7, 0, 128, 0, TRUE, TRUE }, /* 7 */ {"Swamp", "{g&", 8, 128, 255, 128, TRUE, TRUE }, /* 8 */ {"City ", "{W|", 9, 255, 128, 64, FALSE, TRUE }, /* 9 */ {"City ", "{W-", 10, 128, 64, 0, FALSE, TRUE }, /*10 */ {"Door", "{y+", 11, 2, 2, 2, TRUE, TRUE }, /*11 */ {"V", "{wV", 12, 10, 10, 10, TRUE, TRUE }, /*12 */ {"a", "{wa", 13, 10, 10, 11, TRUE, TRUE }, /*13 */ {"n", "{wn", 14, 10, 10, 12, TRUE, TRUE }, /*14 */ {"d", "{wd", 15, 10, 10, 13, TRUE, TRUE }, /*15 */ {"a", "{wa", 16, 10, 10, 14, TRUE, TRUE }, /*16 */ {"g", "{wg", 17, 10, 10, 15, TRUE, TRUE }, /*17 */ {"a", "{wa", 18, 10, 10, 16, TRUE, TRUE }, /*18 */ {"r", "{wr", 19, 10, 10, 17, TRUE, TRUE }, /*19 */ {"d", "{wd", 20, 10, 10, 18, TRUE, TRUE }, /*20 */ {"empty", "{x ", 21, 240, 240, 240, TRUE, TRUE }, /*21 */ {"T", "{wT", 22, 10, 10, 19, TRUE, TRUE }, /*22 */ {"h", "{wh", 23, 10, 10, 20, TRUE, TRUE }, /*23 */ {"e", "{we", 24, 10, 10, 21, TRUE, TRUE }, /*24 */ {"C", "{wC", 25, 10, 10, 22, TRUE, TRUE }, /*25 */ {"i", "{wi", 26, 10, 10, 23, TRUE, TRUE }, /*26 */ {"t", "{wt", 27, 10, 10, 24, TRUE, TRUE }, /*27 */ {"y", "{wy", 28, 10, 10, 25, TRUE, TRUE }, /*28 */ {"o", "{wo", 29, 10, 10, 26, TRUE, TRUE }, /*29 */ {"f", "{wf", 30, 10, 10, 27, TRUE, TRUE }, /*30 */ {"nothing", "{x ", 98, -1, -1, -1, FALSE, FALSE}, /*31 */ {NULL, "{R+", 99, -1, -1, -1, TRUE, TRUE}, /*END*/ }; /* Called in load_muddata * Just to load the world on starup/copyover */ void load_world_data() { /* save_zworld(); log_string(" WORLD *** Saved World.\n\r"); */ load_zworld(); log_string("*** WORLD ******* Loaded ZWorld."); load_wexit(); } /* cmd to forcefuly save the world */ void cmd_save_world(D_MOBILE * ch, char *arg) { stc("Saving zworld structure...\n\r", ch); save_zworld(); stc("Save zworld complete!\n\r", ch); } /* cmd to forcerful reload the world */ void cmd_load_world(D_MOBILE * ch, char *arg) { stc("Reverting zworld structure...\n\r", ch); load_zworld(); stc("Revert zworld complete!\n\r", ch); } /* * save_zworld() * * Saves the world! */ void save_zworld() { gzFile *fp; fp = gzopen(WORLD_FILE,"wb9"); gzwrite(fp,map,sizeof(map)); gzclose(fp); } /* * load_zworld() * * Loads the world! */ void load_zworld() { gzFile *fp; fp = gzopen(WORLD_FILE,"rb9"); gzread(fp,map,sizeof(map)); gzclose(fp); } /* * cmd_wiz_world() * * Some basic load/save/export functions for the world. */ void cmd_wiz_world(D_MOBILE * ch, char *argument) { char arg1[MSL]; argument = one_argument (argument, arg1); if (arg1[0] == '\0') { stc("Syntax: wset <function>\n", ch); stc("wset loadimage - Loads default image\n", ch); stc("wset save - Saves the world data file\n", ch); stc("wset export - Exports the world image to a raw image\n", ch); stc("wset saveexit - Saves the exit list\n", ch); return; } if (!str_prefix (arg1, "loadimage")) { stc("Attempting to load image into the game world..\n", ch); cmd_load_image(ch, ""); stc("Check console for results.\n", ch); return; } if (!str_prefix (arg1, "save")) { stc("Saving the world image file.\n", ch); save_zworld(); return; } if (!str_prefix (arg1, "export")) { stc("Thri is lazy. Export not finished yet.\n", ch); return; } if (!str_prefix (arg1, "saveexit")) { stc("Forcefuly saving wilderness exit data\n", ch); save_wexit(); return; } else { cmd_wiz_world(ch, ""); return; } return; } /* * cmd_look() * * The all purpose display command while on the * wilderness. Its simple right now, i need to * keep it that way. */ void cmd_look(D_MOBILE * ch, char *arg) { int x, y; int viewx = 31; int viewy = 15; int start_x = (ch->x - (viewx / 2)); int start_y = (ch->y - (viewy / 2)); BUFFER *output = new_buf (); char buf[MSL]; add_buf(output, "{D.---- {wThe World of {RS{roulblight{D ----.{x\n\r"); add_buf(output, "{D| |{x\n\r"); for (y = start_y; y != (start_y + viewy); y++) { add_buf(output, "{D|{x "); for (x = start_x; x != (start_x + viewx); x++) { if (y == ch->y && x == ch->x) { sprintf(buf, "{R@"); add_buf (output, buf); } else { /* Fixing crashes as a result of edge of map */ if (x <= 0 || y <= 0) { sprintf(buf, " "); add_buf (output, buf); } else if (x >= MAX_WIDTH || y <= 0) { sprintf(buf, " "); add_buf (output, buf); } else if (x <= 0 || y >= MAX_HEIGHT) { sprintf(buf, " "); add_buf (output, buf); } else if (x >= MAX_WIDTH || y >= MAX_HEIGHT) { sprintf(buf, " "); add_buf (output, buf); } else { sprintf(buf, "%s", return_symbol(map[y][x])); add_buf (output, buf); } } } sprintf(buf, "{D |{x\n"); add_buf (output, buf); } add_buf(output, "{D| |{x\n\r"); add_buf(output, "{D'---------------------------------'{x\n\r"); page_to_char (buf_string (output), ch); free_buf (output); stc("\n{x", ch); check_wexit(ch); return; } /* * return_symbol() * * Returns sector symbol from sector_table * used in cmd_look() */ char * return_symbol(int location) { int i = 0; static char buf[1024]; if (location == -5) { sprintf(buf, "{x "); return buf; } for (i = 0; i <= MAX_WILD_SECTOR; i++) { if (wilderness_table[i].sector == location) { sprintf(buf, "%s", wilderness_table[i].char_sm); break; } else sprintf(buf, "{R+"); } return buf; } /* * can_see_to() * * This ugly piece of code determines if * you can 'see' to the given sector, checks * for blocking terrain. */ int can_see_to (D_M * ch, int target_x, int target_y) { int x = ch->x; int y = ch->y; if (y < target_y && x < target_x) { for (y = ch->y; y != target_y; y++) { for (x = ch->x; x != target_x; x++) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } } else if (y > target_y && x > target_x) { for (y = ch->y; y != target_y; y--) { for (x = ch->x; x != target_x; x--) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } } else if (y < target_y && x > target_x) { for (y = ch->y; y != target_y; y++) { for (x = ch->x; x != target_x; x--) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } } else if (y > target_y && x < target_x) { for (y = ch->y; y != target_y; y--) { for (x = ch->x; x != target_x; x++) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } } else if (target_y == y && x > target_x) { for (x = ch->x; x != target_x; x--) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } else if (target_y == y && x < target_x) { for (x = ch->x; x != target_x; x++) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } else if (target_x == x && y < target_y) { for (y = ch->y; y != target_y; y++) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } else if (target_x == x && y > target_y) { for (y = ch->y; y != target_y; y--) { if (wilderness_table[map[y][x]].can_see_through != TRUE) return FALSE; } } else return TRUE; return TRUE; } /* * cmd_north() * * Moves the player 1 square north * on the world map. */ void cmd_north (D_MOBILE * ch, char *arg) { if (ch->y <= 0) { stc("You'll fall off the world if you go any further north!\n\r", ch); return; } ch->y -= MOVE_AMMOUNT; cmd_look(ch, ""); return; } /* * cmd_south() * * Moves the player 1 square south * on the world map. */ void cmd_south (D_MOBILE * ch, char *arg) { if (ch->y >= MAX_HEIGHT) { stc("You'll fall off the world if you go any further south!\n\r", ch); return; } ch->y += MOVE_AMMOUNT; cmd_look(ch, ""); return; } /* * cmd_west() * * Moves the player 1 square west * on the world map. */ void cmd_west (D_MOBILE * ch, char *arg) { if (ch->x <= 0) { stc("You'll fall off the world if you go any further west!\n\r", ch); return; } ch->x -= MOVE_AMMOUNT; cmd_look(ch, ""); return; } /* * cmd_east() * * Moves the player 1 square east * on the world map. */ void cmd_east (D_MOBILE * ch, char *arg) { if (ch->x >= MAX_WIDTH) { stc("You'll fall off the world if you go any further east!\n\r", ch); return; } ch->x += MOVE_AMMOUNT; cmd_look(ch, ""); return; } /* * check_move_ok() * * Checks to see if the next sector is ok to move to.. */ bool check_move_ok (D_M * ch, int direction) { bool can_move = TRUE; int next_x = (ch->x); int next_y = (ch->y); switch(direction) { default: stc("*** BUG *** check_move_ok: Invalid direction\n\r", ch); break; case DIR_NORTH: if (ch->y != 20) can_move = FALSE; next_y--; break; case DIR_SOUTH: if (ch->y != (MAX_HEIGHT - 20)) can_move = FALSE; next_y++; break; case DIR_WEST: if (ch->x != 20) can_move = FALSE; next_x--; break; case DIR_EAST: if (ch->x != (MAX_WIDTH - 20)) can_move = FALSE; next_x++; break; } /* Pass door for imms if (!IS_SET (ch->immortal_flags, IMMORTAL_PASS_DOOR)) { */ if (wilderness_table[map[next_y][next_x]].passable == FALSE) { stc("{xYou cannot move that way!\n\r", ch); return FALSE; } else { return TRUE; } return TRUE; } /* * cmd_load_image() * * Loads the image from file to the world. */ void cmd_load_image(D_MOBILE * ch, char *arg) { FILE * fp; int x, y, graph1, graph2, graph3; if( !( fp = fopen( IMAGE_FILE, "rb" ) ) ) { log_string("Error: Cannot open file."); return; } log_string("Loaded file, trying to create map"); for (y = 0; y < MAX_WIDTH; y++) { for (x = 0; x < MAX_HEIGHT; x++) { graph1 = fgetc(fp); graph2 = fgetc(fp); graph3 = fgetc(fp); map[y][x] = return_sector_number(graph1, graph2, graph3); } } log_string("Sucess!"); fclose( fp ); return; } /* * return_sector_number() * * Returns sector number from wilderness_table * based on given RGB values. */ int return_sector_number(int r, int g, int b) { int i; int final; for (i = 0; i < MAX_WILD_SECTOR - 1; i++) { if (wilderness_table[i].red == r && wilderness_table[i].green == g && wilderness_table[i].blue == b) { final = wilderness_table[i].sector; break; } else final = MAX_WILD_SECTOR; } return final; } /* * show_wild_chars() * * Displays all charaters/mobiles within range of the player on * the world map. For fun, the size of the player determines how * far they can see them away. So a giant can be seen from say, 6 squares * away, but a tiny sprite can only be seen on the same square */ void show_wild_chars(CHAR_DATA * list, CHAR_DATA * ch) { CHAR_DATA *rch; int range; for (rch = list; rch != NULL; rch = rch->next_in_room) { if (rch == ch) continue; if (get_trust (ch) < rch->invis_level) continue; switch(rch->size) { default: case SIZE_TINY: range = 10; break; case SIZE_SMALL: range = 20; break; case SIZE_MEDIUM: range = 30; break; case SIZE_LARGE: range = 40; break; case SIZE_HUGE: range = 50; break; case SIZE_GIANT: range = 60; break; } if (can_see (ch, rch)) { if (return_distance(ch, rch) <= range) show_char_to_char_0 (rch, ch); } } return; } void show_wild_objects(CHAR_DATA * ch) { show_list_to_char (ch->in_room->contents, ch, FALSE, FALSE, TRUE); return; }