/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * Win32 port by Nick Gammon * * ------------------------------------------------------------------------ * * Overland Map Display and Support Code * ****************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <time.h> #include <string.h> #include "mud.h" unsigned char map_sector[MAP_MAX][MAX_X + 1][MAX_Y + 1]; /* Initializes the sector array */ char weather_sector[MAP_MAX][MAX_X + 1][MAX_Y + 1]; /* Initializes the weather array */ short resource_sector[MAP_MAX][MAX_X + 1][MAX_Y + 1]; /* Initalizes the resource array */ unsigned char kingdom_sector[MAP_MAX][MAX_X + 1][MAX_Y + 1]; /* Initalizes the kingdom array */ int winddir; int windstr; int snows; int cur_ship_uid; //Use this instead of the table to show colors, uses less color parsing char *show_room args((int sector, int x, int y, int map, int begin)); int get_distform args((int x, int y, int vx, int vy)); int check_ship_borders args((SHIP_DATA *ship)); ENTRANCE_DATA *first_entrance; ENTRANCE_DATA *last_entrance; FRONT_DATA *first_front; FRONT_DATA *last_front; void shutdown_mud args((char *reason)); char *const map_names[MAP_MAX] = { "Solan" }; char *const map_name[MAP_MAX] = { "solan" }; /* Sectortypes */ char *const sector_message[SECT_MAX] = { "Inside", "City", "Field", "Forest", "Hills", "Mountain", "Water Swim", "Water Noswim", "Underwater", "Air", "Desert", "Dunno", "Oceanfloor", "Underground", "Road", "Enter", "Mine Gold", "Mine Iron", "Corn Field", "Grain Field", "Chopped Trees", "Completely Chopped Trees", "Mined Gold mine", "Empty Gold mine", "Mined Iron mine", "Empty Iron mine", "Harvested Corn Field", "Empty Corn Field", "Harvested Grain Field", "Empty Grain Field", "River", "Jungle", "Shore", "Tundra", "Ice", "Ocean", "Lava", "Impass-Tree", "Impass-Stone", "Impass-Quicksand", "Wall", "Impass-Glacier", "Exit", "Swamp", "Path", "Plains", "Pavement", "Bridge", "Void", "Stable", "Fire", "Burnt", "Stone", "Some Stone", "No Stone", "Damaged Wall", "Broken Wall", "Door", "Closed Door", "Locked Door", "Hold", "Exit", "Ship" }; /* Note - this message array is used to broadcast both the in sector messages, * as well as the messages sent to PCs when they can't move into the sector */ char *const impass_message[SECT_MAX] = { "Inside", "City", "Field", "Forest", "Hills", "Mountain", "Water Swim", "Water Noswim", "Underwater", "Air", "Desert", "It is unknown, not quite safe to go into.", "Oceanfloor", "Underground", "Road", "Enter", "Mine Gold", "Mine Iron", "Corn Field", "Grain Field", "Chopped Trees", "Completely Chopped Trees", "Mined Gold mine", "Empty Gold mine", "Mined Iron mine", "Empty Iron mine", "Harvested Corn Field", "Empty Corn Field", "Harvested Grain Field", "Empty Grain Field", "River", "Jungle", "Shore", "Tundra", "Ice", "Ocean", "Lava", "The trees are too dense for you to pass through", "A huge massive boulder blocks your passage this direction", "Walking that direction into the quicksand is not a good idea.", "The wall is a little too big for you to pass over.", "A huge chunk of ice blocks you passage.", "Exit", "Swamp", "Path", "Plains", "Pavement", "Bridge", "That direction is blocked, you cannot enter.", "Stable", "Fire", "Burnt", "Stone", "Some Stone", "No Stone", "The damaged wall is a little too big for you to pass over.", "The nearly broken wall is a little too big for you to pass over." "Door", "You need to open the door first.", "You need to unlock and open the door first.", "Hold", "Exit", "Ship" }; /* Changing this to use numbers instead SECT_, it really isn't needed and will allow for a ton of sectors and easy addition online */ void do_showascii(CHAR_DATA * ch, char *argument) { int x; int sp; int mf; sp = 0; ch_printf(ch, "&R* &c&w Symbol for your location on the Map.\n\r"); ch_printf(ch, "&G&W* &c&wSymbol for the location of another player on the Map.\n\r"); ch_printf(ch, "^cC^x &c&wThe teal background indicated a mob (can be over any symbol.)\n\r"); ch_printf(ch, "F &c&wAn F indicated there is a Fight going at that point on the map.\n\r"); ch_printf(ch, "&BO &c&wA portal, help portal for more info.\n\r"); ch_printf(ch, "&C# &c&wA transporter, typically used for intro to Fsanc.\n\r"); ch_printf(ch, "&p+ &c&wAnything that uses the purple color has an item in the room.\n\r\n\r"); ch_printf(ch, "symbol mv Sector Type symbol mv Sector Type\n\r"); ch_printf(ch, " ratio ratio\n\r"); for (x = 0; x < SECT_MAX; x++) { if (sp % 2 == 0) ch_printf(ch, "\n\r"); mf = sect_show[x].move / 5; ch_printf(ch, " %s&c&w %2d %-23s ", show_room(x, -10, -10, -10, -1), mf, sect_show[x].desc); sp += 1; } ch_printf(ch, "\n\r"); } /* const struct portal_data portal_show[] = { { 259, 254, 0, "Rafermand City and Niemria" }, { 279, 247, 0, "Wolf Forest and Shattered Refuge" }, { 305, 224, 0, "Dwarven City and Anirandi Village" }, { 333, 228, 0, "Unholy Grounds" }, { 310, 268, 0, "Fire Newts" }, { 298, 299, 0, "Field of Combat" }, { 241, 307, 0, "Redferne" }, { 214, 299, 0, "Dulavan Village" }, { 274, 346, 0, "Midennir" }, { 472, 372, 0, "Tree Village and Bluehaven" }, { 280, 385, 0, "North Lake Alternity" }, { 277, 404, 0, "Middle Lake Alternity" }, { 315, 450, 0, "South Lake Alternity" }, { 378, 419, 0, "East Lake Alternity" }, { 243, 412, 0, "West Lake Alternity" }, { 454, 332, 0, "Crystal Skull Palace" }, { 429, 263, 0, "Seregon" }, { 402, 262, 0, "New Thalos" }, { 156, 375, 0, "Shadow Forest" }, { 227, 238, 0, "Pixie Forest" }, { 206, 220, 0, "Gallery" }, { 239, 200, 0, "Nature's Retreat" }, { 189, 194, 0, "Berum Manor" }, { 191, 171, 0, "Black Hand Kingdom and Berum Manor" }, { 294, 151, 0, "Aquarian Caves" }, { 430, 45, 0, "Dragon Valley" }, { 410, 127, 0, "Tree of Wisdom" }, { 360, 95, 0, "Trail of Blood" }, { 277, 222, 0, "Graveyard" }, { 46, 442, 0, "Cove of Fire" }, { 126, 167, 0, "Bood Caves" }, { 360, 328, 0, "Fortress Morgond" }, { 390, 420, 1, "Argoth Portal" }, { 400, 211, 1, "Shikara Portal" }, { 235, 330, 0, "Midnight Patch" }, { 320, 340, 0, "PureLand" } }; */ //Going to use functions instead of structures to give the information, will save on color usage. char *show_room(int sector, int x, int y, int map, int begin) { // -10 Use Color auto // -20 Don't use Color auto int type = 0; //no color int otype; if (x > -1 || y > -1 || map > -1) { if (map_sector[map][x - 1][y] != sector) type = 1; if (weather_sector[map][x - 1][y] >= 10) type = 1; if (begin == x) type = 1; } else { if (x == -10 || y == -10 || map == -10) type = 1; } otype = type; if (x > -1 && y > -1 && map > -1 && weather_sector[map][x][y] >= 10) { type = 2; if (NO_SNOW(map_sector[map][x][y])) { type = otype; } } if (type == 2 && snows == 0) { snows = 1; switch (sector) { case SECT_INSIDE: return "&w&W%"; case SECT_CITY: return "&w&W#"; case SECT_FIELD: return "&w&W\""; case SECT_FOREST: return "&w&W@"; case SECT_HILLS: return "&w&W^^"; case SECT_MOUNTAIN: return "&w&W^^"; case SECT_WATER_SWIM: return "&w&W~"; case SECT_WATER_NOSWIM: return "&w&W~"; case SECT_UNDERWATER: return "&w&W~"; case SECT_AIR: return "&w&W%"; case SECT_DESERT: return "&w&W="; case SECT_DUNNO: return "&w&W?"; case SECT_OCEANFLOOR: return "&w&W~"; case SECT_UNDERGROUND: return "&w&W#"; case SECT_ROAD: return "&w&W+"; case SECT_ENTER: return "&w&W#"; case SECT_MINEGOLD: return "&w&W^^"; case SECT_MINEIRON: return "&w&W^^"; case SECT_HCORN: return "&w&W\""; case SECT_HGRAIN: return "&w&W\""; case SECT_STREE: return "&w&W@"; case SECT_NTREE: return "&w&W@"; case SECT_SGOLD: return "&w&W^^"; case SECT_NGOLD: return "&w&W^^"; case SECT_SIRON: return "&w&W^^"; case SECT_NIRON: return "&w&W^^"; case SECT_SCORN: return "&w&W\""; case SECT_NCORN: return "&w&W\""; case SECT_SGRAIN: return "&w&W\""; case SECT_NGRAIN: return "&w&W\""; case SECT_RIVER: return "&w&W-"; case SECT_JUNGLE: return "&w&W*"; case SECT_SHORE: return "&w&W."; case SECT_TUNDRA: return "&w&W+"; case SECT_ICE: return "&w&WI"; case SECT_OCEAN: return "&w&W~"; case SECT_LAVA: return "&w&W:"; case SECT_TREE: return "&w&W*"; case SECT_NOSTONE: return "&w&W^^"; case SECT_QUICKSAND: return "&w&W%"; case SECT_WALL: return "&w&WI"; case SECT_DWALL: return "&w&OI"; case SECT_NBWALL: return "&w&RI"; case SECT_DOOR: return "&w&GD"; case SECT_CDOOR: return "&w&YD"; case SECT_LDOOR: return "&w&RD"; case SECT_GLACIER: return "&w&W="; case SECT_EXIT: return "&w&W#"; case SECT_SWAMP: return "&w&W%"; case SECT_PATH: return "&w&W+"; case SECT_PLAINS: return "&w&W~"; case SECT_PAVE: return "&w&W#"; case SECT_BRIDGE: return "&w&W="; case SECT_VOID: return "&w&W "; case SECT_STABLE: return "&w&W#"; case SECT_FIRE: return "&w&W#"; case SECT_BURNT: return "&w&W+"; case SECT_STONE: return "&w&W*"; case SECT_SSTONE: return "&w&W*"; case SECT_NSTONE: return "&w&W*"; case SECT_HOLD: return "&w&W0"; case SECT_QEXIT: return "&w&W#"; case SECT_SHIP: return "&w&RS"; default: return "&w&W?"; } } if (type == 2 && snows == 1) { switch (sector) { case SECT_INSIDE: return "%"; case SECT_CITY: return "#"; case SECT_FIELD: return "\""; case SECT_FOREST: return "@"; case SECT_HILLS: return "^^"; case SECT_MOUNTAIN: return "^^"; case SECT_WATER_SWIM: return "~"; case SECT_WATER_NOSWIM: return "~"; case SECT_UNDERWATER: return "~"; case SECT_AIR: return "%"; case SECT_DESERT: return "="; case SECT_DUNNO: return "?"; case SECT_OCEANFLOOR: return "~"; case SECT_UNDERGROUND: return "#"; case SECT_ROAD: return "+"; case SECT_ENTER: return "#"; case SECT_MINEGOLD: return "^^"; case SECT_MINEIRON: return "^^"; case SECT_HCORN: return "\""; case SECT_HGRAIN: return "\""; case SECT_STREE: return "@"; case SECT_NTREE: return "@"; case SECT_SGOLD: return "^^"; case SECT_NGOLD: return "^^"; case SECT_SIRON: return "^^"; case SECT_NIRON: return "^^"; case SECT_SCORN: return "\""; case SECT_NCORN: return "\""; case SECT_SGRAIN: return "\""; case SECT_NGRAIN: return "\""; case SECT_RIVER: return "-"; case SECT_JUNGLE: return "*"; case SECT_SHORE: return "."; case SECT_TUNDRA: return "+"; case SECT_ICE: return "I"; case SECT_OCEAN: return "~"; case SECT_LAVA: return ":"; case SECT_TREE: return "*"; case SECT_NOSTONE: return "^^"; case SECT_QUICKSAND: return "%"; case SECT_WALL: case SECT_DWALL: case SECT_NBWALL: return "I"; case SECT_DOOR: case SECT_CDOOR: case SECT_LDOOR: return "D"; case SECT_GLACIER: return "="; case SECT_EXIT: return "#"; case SECT_SWAMP: return "%"; case SECT_PATH: return "+"; case SECT_PLAINS: return "~"; case SECT_PAVE: return "#"; case SECT_BRIDGE: return "="; case SECT_VOID: return " "; case SECT_STABLE: return "#"; case SECT_FIRE: return "#"; case SECT_BURNT: return "+"; case SECT_STONE: return "*"; case SECT_SSTONE: return "*"; case SECT_NSTONE: return "*"; case SECT_HOLD: return "0"; case SECT_QEXIT: return "#"; case SECT_SHIP: return "S"; default: return "?"; } } snows = 0; if (type == 1) { switch (sector) { case SECT_INSIDE: return "&G&W%"; case SECT_CITY: return "&G&W#"; case SECT_FIELD: return "&G\""; case SECT_FOREST: return "&G@"; case SECT_HILLS: return "&G^^"; case SECT_MOUNTAIN: return "&O^^"; case SECT_WATER_SWIM: return "&C~"; case SECT_WATER_NOSWIM: return "&c~"; case SECT_UNDERWATER: return "&B~"; case SECT_AIR: return "&C%"; case SECT_DESERT: return "&Y="; case SECT_DUNNO: return "&x?"; case SECT_OCEANFLOOR: return "&b~"; case SECT_UNDERGROUND: return "&O#"; case SECT_ROAD: return "&c&w+"; case SECT_ENTER: return "&G&W#"; case SECT_MINEGOLD: return "&Y^^"; case SECT_MINEIRON: return "&R^^"; case SECT_HCORN: return "&Y\""; case SECT_HGRAIN: return "&z\""; case SECT_STREE: return "&g@"; case SECT_NTREE: return "&c&w@"; case SECT_SGOLD: return "&c&w^^"; case SECT_NGOLD: return "&b^^"; case SECT_SIRON: return "&B^^"; case SECT_NIRON: return "&z^^"; case SECT_SCORN: return "&O\""; case SECT_NCORN: return "&b\""; case SECT_SGRAIN: return "&z\""; case SECT_NGRAIN: return "&G\""; case SECT_RIVER: return "&B-"; case SECT_JUNGLE: return "&g*"; case SECT_SHORE: return "&Y."; case SECT_TUNDRA: return "&G&W+"; case SECT_ICE: return "&G&WI"; case SECT_OCEAN: return "&b~"; case SECT_LAVA: return "&R:"; case SECT_TREE: return "&G*"; case SECT_NOSTONE: return "&c&w^^"; case SECT_QUICKSAND: return "&O%"; case SECT_WALL: return "&c&wI"; case SECT_DWALL: return "&OI"; case SECT_NBWALL: return "&RI"; case SECT_DOOR: return "&w&GD"; case SECT_CDOOR: return "&w&YD"; case SECT_LDOOR: return "&w&RD"; case SECT_GLACIER: return "&G&W="; case SECT_EXIT: return "&G&W#"; case SECT_SWAMP: return "&g%"; case SECT_PATH: return "&g+"; case SECT_PLAINS: return "&O~"; case SECT_PAVE: return "&z#"; case SECT_BRIDGE: return "&C="; case SECT_VOID: return "&x "; case SECT_STABLE: return "&c&w#"; case SECT_FIRE: return "&R#"; case SECT_BURNT: return "&r+"; case SECT_STONE: return "&c&w*"; case SECT_SSTONE: return "&z*"; case SECT_NSTONE: return "&Y*"; case SECT_HOLD: return "&w&R0"; case SECT_QEXIT: return "&w&P#"; case SECT_SHIP: return "&w&RS"; default: return "&G?"; } } else { if (begin == x) { return show_room(sector, -10, -10, -10, -1); } switch (sector) { case SECT_INSIDE: return "%"; case SECT_CITY: return "#"; case SECT_FIELD: return "\""; case SECT_FOREST: return "@"; case SECT_HILLS: return "^^"; case SECT_MOUNTAIN: return "^^"; case SECT_WATER_SWIM: return "~"; case SECT_WATER_NOSWIM: return "~"; case SECT_UNDERWATER: return "~"; case SECT_AIR: return "%"; case SECT_DESERT: return "="; case SECT_DUNNO: return "?"; case SECT_OCEANFLOOR: return "~"; case SECT_UNDERGROUND: return "#"; case SECT_ROAD: return "+"; case SECT_ENTER: return "#"; case SECT_MINEGOLD: return "^^"; case SECT_MINEIRON: return "^^"; case SECT_HCORN: return "\""; case SECT_HGRAIN: return "\""; case SECT_STREE: return "@"; case SECT_NTREE: return "@"; case SECT_SGOLD: return "^^"; case SECT_NGOLD: return "^^"; case SECT_SIRON: return "^^"; case SECT_NIRON: return "^^"; case SECT_SCORN: return "\""; case SECT_NCORN: return "\""; case SECT_SGRAIN: return "\""; case SECT_NGRAIN: return "\""; case SECT_RIVER: return "-"; case SECT_JUNGLE: return "*"; case SECT_SHORE: return "."; case SECT_TUNDRA: return "+"; case SECT_ICE: return "I"; case SECT_OCEAN: return "~"; case SECT_LAVA: return ":"; case SECT_TREE: return "*"; case SECT_NOSTONE: return "^^"; case SECT_QUICKSAND: return "%"; case SECT_WALL: case SECT_DWALL: case SECT_NBWALL: return "I"; case SECT_DOOR: case SECT_CDOOR: case SECT_LDOOR: return "D"; case SECT_GLACIER: return "="; case SECT_EXIT: return "#"; case SECT_SWAMP: return "%"; case SECT_PATH: return "+"; case SECT_PLAINS: return "~"; case SECT_PAVE: return "#"; case SECT_BRIDGE: return "="; case SECT_VOID: return " "; case SECT_STABLE: return "#"; case SECT_FIRE: return "#"; case SECT_BURNT: return "+"; case SECT_STONE: return "*"; case SECT_SSTONE: return "*"; case SECT_NSTONE: return "*"; case SECT_HOLD: return "0"; case SECT_QEXIT: return "#"; case SECT_SHIP: return "S"; default: return "?"; } } return "&G?"; } /* Values are base 9, 9 being good, 1 being bad */ const struct sect_color_type sect_show[] = { {SECT_INSIDE, "&G&W", "%", "%", "", 0, 5, "inside", TRUE, "c.gif"}, {SECT_CITY, "&G&W", "#", "#", "", 0, 10, "city", TRUE, "c.gif"}, {SECT_FIELD, "&G", "\"", "\"", "", 2, 14, "field", TRUE, "f.gif"}, {SECT_FOREST, "&G", "@", "@", "", 4, 25, "forest", TRUE, "f2.gif"}, {SECT_HILLS, "&G", "^^", "^", "", 3, 32, "hills", TRUE, "h.gif"}, {SECT_MOUNTAIN, "&O", "^^", "^", "", 5, 45, "mountain", TRUE, "m.gif"}, {SECT_WATER_SWIM, "&C", "~", "~", "", 2, 35, "shallow water", TRUE, "w3.gif"}, {SECT_WATER_NOSWIM, "&c", "~", "~", "", 3, 40, "deep water", TRUE, "w2.gif"}, {SECT_UNDERWATER, "&B", "~", "~", "", 3, 42, "underwater", TRUE, "o.gif"}, {SECT_AIR, "&C", "%", "%", "", 2, 70, "air", TRUE, "f.gif"}, {SECT_DESERT, "&Y", "=", "=", "", 2, 45, "desert", TRUE, "d.gif"}, {SECT_DUNNO, "&x", "?", "?", "", 2, 39, "Unknown", FALSE, "f.gif"}, {SECT_OCEANFLOOR, "&b", "~", "~", "", 3, 50, "ocean floor", TRUE, "o.gif"}, {SECT_UNDERGROUND, "&O", "#", "#", "", 3, 34, "underground", TRUE, "f.gif"}, {SECT_ROAD, "&c&w", "+", "+", "", 1, 5, "road", TRUE, "r.gif"}, {SECT_ENTER, "&G&W", "#", "#", "", 0, 12, "enter", TRUE, "e.gif"}, {SECT_MINEGOLD, "&Y", "^^", "^", "", 5, 45, "gold mine", TRUE, "m.gif"}, {SECT_MINEIRON, "&R", "^^", "^", "", 5, 45, "iron mine", TRUE, "m.gif"}, {SECT_HCORN, "&Y", "\"", "\"", "", 2, 14, "corn field", TRUE, "f.gif"}, {SECT_HGRAIN, "&z", "\"", "\"", "", 2, 14, "grain field", TRUE, "f.gif"}, {SECT_STREE, "&g", "@", "@", "", 3, 25, "chopped trees", TRUE, "f2.gif"}, {SECT_NTREE, "&c&w", "@", "@", "", 3, 25, "tree stumps", TRUE, "f2.gif"}, {SECT_SGOLD, "&c&w", "^^", "^", "", 5, 45, "mined gold mine", TRUE, "m.gif"}, {SECT_NGOLD, "&b", "^^", "^", "", 5, 45, "empty gold mine", TRUE, "m.gif"}, {SECT_SIRON, "&B", "^^", "^", "", 5, 45, "mined iron mine", TRUE, "m.gif"}, {SECT_NIRON, "&z", "^^", "^", "", 5, 45, "empty iron mine", TRUE, "m.gif"}, {SECT_SCORN, "&O", "\"", "\"", "", 2, 14, "havested corn field", TRUE, "f.gif"}, {SECT_NCORN, "&b", "\"", "\"", "", 2, 14, "empty corn field", TRUE, "f.gif"}, {SECT_SGRAIN, "&z", "\"", "\"", "", 2, 14, "harvested grain field", TRUE, "f.gif"}, {SECT_NGRAIN, "&G", "\"", "\"", "", 2, 14, "empty grain field", TRUE, "f.gif"}, {SECT_RIVER, "&B", "-", "-", "", 2, 42, "river", TRUE, "r2.gif"}, {SECT_JUNGLE, "&g", "*", "*", "", 3, 35, "jungle", TRUE, "j.gif"}, {SECT_SHORE, "&Y", ".", ".", "", 2, 9, "shoreline", TRUE, "s.gif"}, {SECT_TUNDRA, "&G&W", "+", "+", "", 3, 21, "tundra", TRUE, "i.gif"}, {SECT_ICE, "&G&W", "I", "I", "", 4, 40, "ice", TRUE, "i.gif"}, {SECT_OCEAN, "&b", "~", "~", "", 4, 80, "ocean", FALSE, "o.gif"}, {SECT_LAVA, "&R", ":", ":", "", 5, 68, "lava", TRUE, "l.gif"}, {SECT_TREE, "&G", "*", "*", "", 0, 0, "impassable forest", FALSE, "f2.gif"}, {SECT_NOSTONE, "&c&w", "^^", "^", "", 0, 0, "impassable mountain", FALSE, "m.gif"}, {SECT_QUICKSAND, "&O", "%", "%", "", 0, 0, "quicksand(nopass swamp)", FALSE, "f.gif"}, {SECT_WALL, "&c&w", "I", "I", "", 0, 0, "wall", FALSE, "w.gif"}, {SECT_GLACIER, "&W", "=", "=", "", 0, 0, "glacier(nopass ice)", FALSE, "f.gif"}, {SECT_EXIT, "&G&W", "#", "#", "", 0, 0, "exit", TRUE, "e.gif"}, {SECT_SWAMP, "&g", "%", "%", "", 4, 38, "swamp", TRUE, "s4.gif"}, {SECT_PATH, "&g", "+", "+", "", 1, 5, "path", TRUE, "r.gif"}, {SECT_PLAINS, "&O", "~", "~", "", 2, 12, "plains", TRUE, "p.gif"}, {SECT_PAVE, "&z", "#", "#", "", 2, 7, "pavement", TRUE, "r.gif"}, {SECT_BRIDGE, "&C", "=", "=", "", 2, 7, "bridge", TRUE, "r.gif"}, {SECT_VOID, "&x", " ", " ", "", 0, 0, "void", FALSE, "v.gif"}, {SECT_STABLE, "&c&w", "#", "#", "", 0, 0, "stable", TRUE, "r.gif"}, {SECT_FIRE, "&R", "#", "#", "", 0, 20, "fire", TRUE, "f.gif"}, {SECT_BURNT, "&r", "+", "+", "", 2, 14, "burnt", TRUE, "f.gif"}, {SECT_STONE, "&c&w", "*", "*", "", 3, 27, "stone", TRUE, "s3.gif"}, {SECT_SSTONE, "&z", "*", "*", "", 3, 27, "some stone", TRUE, "s3.gif"}, {SECT_NSTONE, "&Y", "*", "*", "", 3, 27, "no stone", TRUE, "s3.gif"}, {SECT_DWALL, "&O", "I", "I", "", 0, 0, "damaged wall", FALSE, "w.gif"}, {SECT_NBWALL, "&R", "I", "I", "", 0, 0, "nearly broke wall", FALSE, "w.gif"}, {SECT_DOOR, "&G", "D", "D", "", 0, 5, "door", TRUE, "d2.gif"}, {SECT_CDOOR, "&Y", "D", "D", "", 0, 0, "closed door", FALSE, "d2.gif"}, {SECT_LDOOR, "&R", "D", "D", "", 0, 0, "locked door", FALSE, "d2.gif"}, {SECT_HOLD, "&R", "0", "0", "", 0, 5, "hold", TRUE, "s2.gif"}, {SECT_QEXIT, "&w&P", "#", "#", "", 0, 0, "exit", TRUE, "q.gif"}, {SECT_SHIP, "&w&R", "S", "S", "", 0, 0, "ship", FALSE, "q.gif"} }; //Checks to see if the movement is valid, and changes the pointers //to x and y with the new coords. Passes back failure messages if //ch is passed to it! bool is_valid_movement(int *px, int *py, char *arg, CHAR_DATA *ch) { int x, y; x = *px; y = *py; if (!str_cmp(arg, "n") || !str_cmp(arg, "north")) y = y-1; if (!str_cmp(arg, "s") || !str_cmp(arg, "south")) y = y+1; if (!str_cmp(arg, "e") || !str_cmp(arg, "east")) x = x+1; if (!str_cmp(arg, "w") || !str_cmp(arg, "west")) x = x-1; if (!str_cmp(arg, "nw") || !str_cmp(arg, "northwest")) { y = y-1; x = x-1; } if (!str_cmp(arg, "ne") || !str_cmp(arg, "northeast")) { y = y-1; x = x+1; } if (!str_cmp(arg, "sw") || !str_cmp(arg, "southwest")) { y = y+1; x = x-1; } if (!str_cmp(arg, "se") || !str_cmp(arg, "southeast")) { y = y+1; x = x+1; } if (x < 1 || x > MAX_X || y < 1 || y > MAX_Y) { if (ch) send_to_char("That is off the map, you cannot do that.\n\r", ch); return FALSE; } if (*px == x && *py == y) { if (ch) send_to_char("You have to choose a direction, ex: n nw n northwest\n\r", ch); return FALSE; } *px = x; *py = y; return TRUE; } void add_entrance(int tomap, int onmap, int hereX, int hereY, int thereX, int thereY, int vnum) { ENTRANCE_DATA *enter; CREATE(enter, ENTRANCE_DATA, 1); LINK(enter, first_entrance, last_entrance, next, prev); enter->tomap = tomap; enter->onmap = onmap; CREATE(enter->here, COORD_DATA, 1); CREATE(enter->there, COORD_DATA, 1); enter->here->x = hereX; enter->here->y = hereY; enter->there->x = thereX; enter->there->y = thereY; enter->vnum = vnum; return; } void delete_entrance(ENTRANCE_DATA * enter) { enter->tomap = 0; enter->onmap = 0; enter->here->x = 0; enter->here->y = 0; enter->there->x = 0; enter->there->y = 0; enter->vnum = 0; UNLINK(enter, first_entrance, last_entrance, next, prev); return; } #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } void fread_entrance(ENTRANCE_DATA * enter, FILE * fp) { char buf[MSL]; char *word; bool fMatch; for (;;) { word = feof(fp) ? "End" : fread_word(fp); fMatch = FALSE; switch (UPPER(word[0])) { case '*': fMatch = TRUE; fread_to_eol(fp); break; case 'E': if (!str_cmp(word, "End")) { return; } break; case 'H': if (!str_cmp(word, "Here")) { enter->here->x = fread_number(fp); enter->here->y = fread_number(fp); fMatch = TRUE; break; } break; case 'O': KEY("OnMap", enter->onmap, fread_number(fp)); break; case 'T': if (!str_cmp(word, "There")) { enter->there->x = fread_number(fp); enter->there->y = fread_number(fp); fMatch = TRUE; break; } KEY("ToMap", enter->tomap, fread_number(fp)); break; case 'V': KEY("Vnum", enter->vnum, fread_number(fp)); break; } if (!fMatch) { sprintf(buf, "Fread_entrance: no match: %s", word); bug(buf, 0); } } } void load_entrances() { char filename[256]; ENTRANCE_DATA *enter; FILE *fp; first_entrance = NULL; last_entrance = NULL; sprintf(filename, "%s%s", MAP_DIR, ENTRANCE_FILE); if ((fp = fopen(filename, "r")) != NULL) { for (;;) { char letter; char *word; letter = fread_letter(fp); if (letter == '*') { fread_to_eol(fp); continue; } if (letter != '#') { bug("Load_entrances: # not found.", 0); break; } word = fread_word(fp); if (!str_cmp(word, "ENTRANCE")) { CREATE(enter, ENTRANCE_DATA, 1); CREATE(enter->here, COORD_DATA, 1); CREATE(enter->there, COORD_DATA, 1); fread_entrance(enter, fp); LINK(enter, first_entrance, last_entrance, next, prev); continue; } else if (!str_cmp(word, "END")) break; else { char buf[MSL]; sprintf(buf, "Load_entrances: bad section: %s.", word); bug(buf, 0); continue; } } FCLOSE(fp); } return; } char *get_area_from_vnum(int vnum) { static char area[200]; AREA_DATA *tarea; for (tarea = first_asort; tarea; tarea = tarea->next) { if (vnum >= tarea->low_r_vnum && vnum <= tarea->hi_r_vnum) break; } if (!tarea) { for (tarea = first_bsort; tarea; tarea = tarea->next) { if (vnum >= tarea->low_r_vnum && vnum <= tarea->hi_r_vnum) break; } } if (!tarea) return "Unknown"; else { sprintf(area, "%s", tarea->name); return &area[0]; } } //sorts and cleans entrances. Removing those that are linked oddly void sort_entrances() { ENTRANCE_DATA *enter; ENTRANCE_DATA *senter; ENTRANCE_DATA *nenter; ENTRANCE_DATA *next_entrance; ENTRANCE_DATA *first_sort_entrance = NULL; ENTRANCE_DATA *last_sort_entrance = NULL; for (enter = first_entrance; enter; enter = next_entrance) { next_entrance = enter->next; if (!first_sort_entrance) LINK(enter, first_sort_entrance, last_sort_entrance, next, prev); else { if (enter->vnum <= first_sort_entrance->vnum) { nenter = first_sort_entrance; enter->prev = NULL; nenter->prev = enter; enter->next = nenter; first_sort_entrance = enter; continue; } for (senter = first_sort_entrance; senter; senter = senter->next) { if (senter->next == NULL) { LINK(enter, first_sort_entrance, last_sort_entrance, next, prev); break; } if (enter->vnum <= senter->next->vnum) { nenter = senter->next; nenter->prev->next = enter; enter->prev = nenter->prev; nenter->prev = enter; enter->next = nenter; break; } } } } first_entrance = first_sort_entrance; last_entrance = last_sort_entrance; for (enter = first_entrance; enter; enter = next_entrance) { next_entrance = enter->next; if (enter->next && enter->next->vnum == enter->vnum && enter->next->here->x == enter->here->x && enter->next->here->y == enter->here->y) { UNLINK(enter, first_entrance, last_entrance, next, prev); } } for (enter = first_entrance; enter; enter = next_entrance) { next_entrance = enter->next; if (!str_cmp(get_area_from_vnum(enter->vnum), "Unknown")) { UNLINK(enter, first_entrance, last_entrance, next, prev); } } } void do_showentrances(CHAR_DATA *ch, char *argument) { ENTRANCE_DATA *enter; int num = 1; sort_entrances(); send_to_char("Num ToMap Onmap Here There Vnum Area\n\r-----------------------------------------------------------\n\r", ch); for (enter = first_entrance; enter; enter = enter->next) { ch_printf(ch, "%-3d %-2d %-2d %-4d %-4d %-4d %-4d %-5d %s\n\r", num, enter->tomap, enter->onmap, enter->here->x, enter->here->y, enter->there->x, enter->there->y, enter->vnum, get_area_from_vnum(enter->vnum)); num++; } } void save_entrances() { ENTRANCE_DATA *enter; FILE *fp; char filename[256]; sprintf(filename, "%s%s", MAP_DIR, ENTRANCE_FILE); FCLOSE(fpReserve); if ((fp = fopen(filename, "w")) == NULL) { bug("save_entrances: fopen", 0); perror(filename); } else { for (enter = first_entrance; enter; enter = enter->next) { fprintf(fp, "#ENTRANCE\n"); fprintf(fp, "ToMap %d\n", enter->tomap); fprintf(fp, "OnMap %d\n", enter->onmap); fprintf(fp, "Here %d %d\n", enter->here->x, enter->here->y); fprintf(fp, "There %d %d\n", enter->there->x, enter->there->y); fprintf(fp, "Vnum %d\n", enter->vnum); fprintf(fp, "End\n\n"); } fprintf(fp, "#END\n"); FCLOSE(fp); } fpReserve = fopen(NULL_FILE, "r"); return; } ENTRANCE_DATA *check_entrance(CHAR_DATA * ch, int map, int x, int y) { ENTRANCE_DATA *enter; for (enter = first_entrance; enter; enter = enter->next) { if (enter->onmap == map) { if (enter->here->x == x && enter->here->y == y) return enter; } } return NULL; } char *get_map_name(int map) { if (map < 0 || map > MAP_MAX) return "unknown"; else return map_names[map]; } bool can_see_room(int x, int y, int map, int sector) { TOWN_DATA *town; DOOR_DATA *ddata; int z; //the map does a lot of processing, lets not do more than is needed... if (sector != SECT_INSIDE) return TRUE; if (kingdom_sector[map][x][y] < 2 || kingdom_sector[map][x][y] > sysdata.max_kingdom) return TRUE; town = find_town(x, y, map); if (town) { for (ddata = town->first_doorlist->first_door; ddata; ddata = ddata->next) { for (z = 0; z <= MAX_HPOINTS-1; z++) { if (ddata->roomcoordx[z] == x && ddata->roomcoordy[z] == y && ddata->roomcoordmap[z] == map) { if (ddata->cansee == 0) return FALSE; else return TRUE; } } } } return TRUE; } int update_inside_stat(int fnddoor[], CHAR_DATA *ch, TOWN_DATA *town, int x, int y, int map) { int udoornum; DOOR_DATA *ddata; int z; int fnx; int cnt; int fnd; int fx; int dx; fx = 0; cnt = -1; for (ddata = town->first_doorlist->first_door; ddata; ddata = ddata->next) { for (z = 0; z <= MAX_HPOINTS-1; z++) { if (ddata->roomcoordx[z] == x && ddata->roomcoordy[z] == y && ddata->roomcoordmap[z] == map) break; } if (z != MAX_HPOINTS) { for (dx = 0; dx <= 9; dx++) { if (ddata->doorvalue[dx] > 0) { for (fnx = 0; fnx <= 99; fnx++) { if (town->doorstate[4][fnx] == ddata->doorvalue[dx] && town->doorstate[0][fnx] == 0) { fnddoor[fx++] = town->doorstate[4][fnx]; ddata->cannotsee = 1; break; } } if (fnx <= 99) break; } } } } if (fx == 0) return 0; for (;;) { if (fx == ++cnt) //we managed to exhaust all the doors, lets exit break; udoornum = fnddoor[cnt]; for (ddata = town->first_doorlist->first_door; ddata; ddata = ddata->next) { fnd = 1; for (z = 0; z <= 9; z++) { if (ddata->doorvalue[z] == udoornum) break; } if (z != 10) { ddata->cannotsee = 1; //lets look for open doors.... for (z = 0; z <= 9; z++) { if (ddata->doorvalue[z] > 0) { for (fnx = 0; fnx <= 99; fnx++) { if (town->doorstate[4][fnx] == ddata->doorvalue[z]) break; } if (town->doorstate[0][fnx] == 0 && town->doorstate[3][fnx] == 1) //Open Master Door, I can see light!!! return 1; if (fnx <= 99 && town->doorstate[0][fnx] == 0) //open { for (fnx = 0; fnx <= 99; fnx++) { if (fnddoor[fnx] == 0) { fnd = 0; break; } if (fnddoor[fnx] == ddata->doorvalue[z]) { break; } } if (fnx == 100) //err this shouldn't happen.... { bug("update_inside_stat: The fnddoor array is full for town %s", town->name); return 1; } if (fnd == 0) { fnddoor[fx++] = ddata->doorvalue[z]; } } } } } }//end ddata for check for open }//end infinite loop for open return 0; } void do_mxp(CHAR_DATA *ch, char *argument) { char arg[MIL]; if (check_npc(ch)) return; if (argument[0] == '\0') { send_to_char("Syntax: mxp mapwindow [on/off]\n\r", ch); send_to_char("Syntax: mxp mapwindow [close/open]\n\r", ch); send_to_char("Syntax: mxp wildernesstiles [on/off]\n\r", ch); return; } argument = one_argument(argument, arg); if (!str_cmp(arg, "wildernesstiles")) { if (!str_cmp(argument, "on")) { xSET_BIT(ch->act, PLR_WILDERTILES); send_to_char("Wilderness Tiles set to load, make sure you have downloaded them or you will get nothing.\n\r", ch); return; } if (!str_cmp(argument, "off")) { xREMOVE_BIT(ch->act, PLR_WILDERTILES); send_to_char("Wilderness Tiles set to not load.\n\r", ch); return; } } if (!str_cmp(arg, "mapwindow")) { if (!str_cmp(argument, "on")) { xSET_BIT(ch->act, PLR_MAPWINDOW); ch->pcdata->xsize = 0; ch->pcdata->ysize = 0; ch_printf(ch, "%s", MXPTAG("FRAME Name=\"Map\" FLOATING Left=\"-21c\" Top=\"0\" Width=\"21c\" Height=\"21c\"")); send_to_char("The window was turned on and loaded, if you do not see it, you might not have mxp support.\n\r", ch); return; } if (!str_cmp(argument, "off")) { xREMOVE_BIT(ch->act, PLR_MAPWINDOW); ch->pcdata->xsize = 0; ch->pcdata->ysize = 0; ch_printf(ch, "%s", MXPTAG("FRAME Map CLOSE")); send_to_char("The window was turned off and the window was closed.\n\r", ch); return; } if (!str_cmp(argument, "close")) { ch_printf(ch, "%s", MXPTAG("FRAME Map CLOSE")); send_to_char("Window closed, but not turned off.\n\r", ch); return; } if (!str_cmp(argument, "open")) { ch_printf(ch, "%s", MXPTAG("FRAME Name=\"Map\" FLOATING Left=\"-21c\" Top=\"0\" Width=\"21c\" Height=\"21c\"")); send_to_char("Window opened but not turned on/off.\n\r", ch); return; } } do_mxp(ch, ""); return; } void do_portal(CHAR_DATA *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; char arg4[MIL]; int p; int count = 0; int x, y, map; PORTAL_DATA *portal; x=y=0; map=-1; if (argument[0] == '\0') { send_to_char("Syntax: portal list\n\r", ch); send_to_char("Syntax: portal add [x] [y] [map] <Description>\n\r", ch); send_to_char("Syntax: portal remove [x] [y] [map]\n\r", ch); return; } argument = one_argument(argument, arg1); if (!str_cmp(arg1, "list")) { for (p = 0; p < sysdata.last_portal; p++) { ch_printf(ch, "[%2d] %-4dX %-4dY %s\n\r", ++count, portal_show[p]->x, portal_show[p]->y, portal_show[p]->desc); } return; } if (!str_cmp(arg1, "remove")) { if (atoi(argument) > 0) { argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); x = atoi(arg2); y = atoi(arg3); map = atoi(arg4); } if (x == 0) { if (!IN_WILDERNESS(ch)) { send_to_char("You need to be in the wilderness to remove a portal.\n\r", ch); return; } x = ch->coord->x; y = ch->coord->y; map = ch->map; } if (x < 1 || x > MAX_X || y < 1 || y > MAX_Y || map < 0 || map >= MAP_MAX) { send_to_char("That is not a valid coordinates.\n\r", ch); return; } for (p = 0; p < sysdata.last_portal; p++) { if (portal_show[p]->x == x && portal_show[p]->y == y && portal_show[p]->map == map) break; } if (p == sysdata.last_portal) { send_to_char("There is no portal to remove!!!\n\r", ch); return; } STRFREE(portal_show[p]->desc); for (x = p+1; x < sysdata.last_portal; x++) { portal_show[x-1] = portal_show[x]; } portal_show[x-1] = NULL; sysdata.last_portal--; send_to_char("Done.\n\r", ch); save_portal_file(); return; } if (!str_cmp(arg1, "add")) { if (sysdata.last_portal == LAST_PORTAL) { send_to_char("There are 100 portals, that is the max, increase LAST_PORTAL variable to add more.\n\r", ch); return; } if (atoi(argument) > 0) { argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); x = atoi(arg2); y = atoi(arg3); map = atoi(arg4); } if (x == 0) { if (!IN_WILDERNESS(ch)) { send_to_char("You need to be in the wilderness to add a portal.\n\r", ch); return; } x = ch->coord->x; y = ch->coord->y; map = ch->map; } if (x < 1 || x > MAX_X || y < 1 || y > MAX_Y || map < 0 || map >= MAP_MAX) { send_to_char("That is not a valid coordinates.\n\r", ch); return; } for (p = 0; p < sysdata.last_portal; p++) { if (portal_show[p]->x == x && portal_show[p]->y == y && portal_show[p]->map == map) break; } if (p < sysdata.last_portal) { send_to_char("There is already a portal here, remove it first if you want to add a new one.\n\r", ch); return; } CREATE(portal, PORTAL_DATA, 1); portal->x = x; portal->y = y; portal->map = map; portal->desc = STRALLOC(argument); portal_show[sysdata.last_portal++] = portal; send_to_char("Done.\n\r", ch); save_portal_file(); return; } do_portal(ch, ""); return; } void do_ships(CHAR_DATA *ch, char *argument) { SHIP_DATA *ship; int num = 1; char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; if (argument[0] == '\0') { send_to_char("Syntax: ships create\n\r", ch); send_to_char("Syntax: ships list\n\r", ch); send_to_char("Syntax: ships delete <number>\n\r", ch); send_to_char("Syntax: ships edit <number> <size/route/routetime/occupants> <value>\n\r", ch); return; } if (!str_cmp(argument, "list")) { send_to_char("Num X Y TX TY Dir Occupants Routetime Route Size\n\r-----------------------------------------------\n\r", ch); for (ship = first_ship; ship; ship = ship->next) { ch_printf(ch, "%-3d> %-4d %-4d %-4d %-4d %-5s %-3d %-3d %-3s %d\n\r", num++, ship->x, ship->y, ship->tx, ship->ty, dir_name[ship->direction], ship->occupants, ship->routetime, ship->travelroute ? ship->travelroute[0] != '\0' ? "Yes" : "No" : "No", ship->size); } return; } if (!str_cmp(argument, "create")) { CREATE(ship, SHIP_DATA, 1); ship->x = ch->coord->x; ship->y = ch->coord->y; ship->map = ch->map; ship->tx = ship->ty = ship->tmap = -1; ship->direction = 0; ship->size = 2; if (!check_ship_borders(ship)) { send_to_char("Something is blocking you from creating the ship, move a bit further into the ocean.\n\r", ch); DISPOSE(ship); return; } ship->travelroute = STRALLOC(""); ship->uid = ++cur_ship_uid; LINK(ship, first_ship, last_ship, next, prev); set_ship_sector(ship, 0, 1); send_to_char("Done.\n\r", ch); fwrite_ship_data(); return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); if (!str_cmp(arg1, "delete")) { for (ship = first_ship; ship; ship = ship->next) { if (atoi(arg2) == num++) break; } if (!ship) { send_to_char("The number you specified does not exist.\n\r", ch); return; } if (ship->occupants > 0) { send_to_char("There is someone on that ship, you cannot delete it.\n\r", ch); return; } set_ship_sector(ship, 1, 0); STRFREE(ship->travelroute); UNLINK(ship, first_ship, last_ship, next, prev); DISPOSE(ship); send_to_char("Deleted.\n\r", ch); return; } if (!str_cmp(arg1, "edit")) { for (ship = first_ship; ship; ship = ship->next) { if (atoi(arg2) == num++) break; } if (!ship) { send_to_char("The number you specified does not exist.\n\r", ch); return; } if (!str_cmp(arg3, "size")) { int oldsize = ship->size; if (atoi(argument) < 1 || atoi(argument) > 10) { send_to_char("Range is 1 to 10.\n\r", ch); return; } set_ship_sector(ship, 1, 0); ship->size = atoi(argument); if (check_ship_borders(ship)) { set_ship_sector(ship, 0, 1); fwrite_ship_data(); send_to_char("Done.\n\r", ch); return; } else { ship->size = oldsize; set_ship_sector(ship, 0, 1); send_to_char("Cannot change the size, something is blocking you from doing so.\n\r", ch); return; } } if (!str_cmp(arg3, "route")) { if (ship->travelroute) STRFREE(ship->travelroute); ship->travelroute = STRALLOC(argument); if (argument[0] == '\0') { ship->routeplace = 0; ship->routedir = 0; ship->routetick = 0; } send_to_char("Done.\n\r", ch); fwrite_ship_data(); return; } if (!str_cmp(arg3, "occupants")) { if (atoi(argument) < 0 || atoi(argument) > 600) { send_to_char("Range is 0 to 600.\n\r", ch); return; } ship->occupants = atoi(argument); send_to_char("Done.\n\r", ch); fwrite_ship_data(); return; } if (!str_cmp(arg3, "routetime")) { if (atoi(argument) < 0 || atoi(argument) > 600) { send_to_char("Range is 0 to 600.\n\r", ch); return; } ship->routetime = atoi(argument); send_to_char("Done.\n\r", ch); fwrite_ship_data(); return; } } do_ships(ch, ""); return; } /* Below are the ship designs for the 10 sizes. The design will shift for north/south and east/west facing x x xxx x x xxx xxx xxx x xxx xxxxx xxxxx xxxxx xxx xxx xxxxx xxxxx xxxxx xxxxx xxxxx xxx xxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxx xxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxxxx xxxxx xxxxx xxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxx xxxxx xxxxx xxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxx xxxxx xxxxx xxxxxxx xxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxx xxxxxxx xxxxx */ //Reset 0 - Do not reset sectors (make ship sectors) 1 - Reset (make ocean sectors) void set_ship_sector(SHIP_DATA *ship, int reset, int save) { int sector; int sy, sx; if (reset == 0) sector = SECT_SHIP; else sector = SECT_OCEAN; map_sector[ship->map][ship->x][ship->y] = sector; if (ship->direction == 0 || ship->direction == 2) //North - South { if (ship->size == 2) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-1; sx <= ship->x+1; sx++) { if ((sy == ship->y-3 || sy == ship->y+3) && sx != ship->x) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 3) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-1; sx <= ship->x+1; sx++) { if ((sy == ship->y-4 || sy == ship->y+4) && sx != ship->x) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 4) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-2; sx <= ship->x+2; sx++) { if ((sy == ship->y-4 || sy == ship->y+4) && (sx == ship->x-2 || sx == ship->x+2)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 5) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-2; sx <= ship->x+2; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-2 || sx == ship->x+2)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 6) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-3 || sx == ship->x+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 7) { for (sy = ship->y-6; sy <= ship->y+6; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sy == ship->y-6 || sy == ship->y+6) && (sx == ship->x-3 || sx == ship->x+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 8) { for (sy = ship->y-6; sy <= ship->y+6; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-4 || sx == ship->x+4)) continue; if ((sy == ship->y-6 || sy == ship->y+6) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 9) { for (sy = ship->y-7; sy <= ship->y+7; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sy == ship->y-6 || sy == ship->y+6) && (sx == ship->x-4 || sx == ship->x+4)) continue; if ((sy == ship->y-7 || sy == ship->y+7) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 10) { for (sy = ship->y-7; sy <= ship->y+7; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-5 || sx == ship->x+5)) continue; if ((sy == ship->y-6 || sy == ship->y+6) && (sx <= ship->x-4 || sx >= ship->x+4)) continue; if ((sy == ship->y-7 || sy == ship->y+7) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } } else { if (ship->size == 2) { for (sy = ship->y-1; sy <= ship->y+1; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sx == ship->x-3 || sx == ship->x+3) && sy != ship->y) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 3) { for (sy = ship->y-1; sy <= ship->y+1; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sx == ship->x-4 || sx == ship->x+4) && sy != ship->y) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 4) { for (sy = ship->y-2; sy <= ship->y+2; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sx == ship->x-4 || sx == ship->x+4) && (sy == ship->y-2 || sy == ship->y+2)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 5) { for (sy = ship->y-2; sy <= ship->y+2; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-2 || sy == ship->y+2)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 6) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-3 || sy == ship->y+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 7) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-6; sx <= ship->x+6; sx++) { if ((sx == ship->x-6 || sx == ship->x+6) && (sy == ship->y-3 || sy == ship->y+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 8) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-6; sx <= ship->x+6; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-4 || sy == ship->y+4)) continue; if ((sx == ship->x-6 || sx == ship->x+6) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 9) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-7; sx <= ship->x+7; sx++) { if ((sx == ship->x-6 || sx == ship->x+6) && (sy == ship->y-4 || sy == ship->y+4)) continue; if ((sx == ship->x-7 || sx == ship->x+7) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } if (ship->size == 10) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-7; sx <= ship->x+7; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-5 || sy == ship->y+5)) continue; if ((sx == ship->x-6 || sx == ship->x+6) && (sy <= ship->y-4 || sy >= ship->y+4)) continue; if ((sx == ship->x-7 || sx == ship->x+7) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; map_sector[ship->map][sx][sy] = sector; } } } } //if (save) // save_map("solan", 0); } int check_ship_borders(SHIP_DATA *ship) { int sx; int sy; if (ship->x < 1 || ship->x > MAX_X || ship->y < 1 || ship->y > MAX_Y) return 0; if (map_sector[ship->map][ship->x][ship->y] != SECT_OCEAN) return 0; if (ship->direction == 0 || ship->direction == 2) //North - South { if (ship->size == 2) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-1; sx <= ship->x+1; sx++) { if ((sy == ship->y-3 || sy == ship->y+3) && sx != ship->x) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 3) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-1; sx <= ship->x+1; sx++) { if ((sy == ship->y-4 || sy == ship->y+4) && sx != ship->x) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 4) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-2; sx <= ship->x+2; sx++) { if ((sy == ship->y-4 || sy == ship->y+4) && (sx == ship->x-2 || sx == ship->x+2)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 5) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-2; sx <= ship->x+2; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-2 || sx == ship->x+2)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 6) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-3 || sx == ship->x+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 7) { for (sy = ship->y-6; sy <= ship->y+6; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sy == ship->y-6 || sy == ship->y+6) && (sx == ship->x-3 || sx == ship->x+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 8) { for (sy = ship->y-6; sy <= ship->y+6; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-4 || sx == ship->x+4)) continue; if ((sy == ship->y-6 || sy == ship->y+6) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 9) { for (sy = ship->y-7; sy <= ship->y+7; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sy == ship->y-6 || sy == ship->y+6) && (sx == ship->x-4 || sx == ship->x+4)) continue; if ((sy == ship->y-7 || sy == ship->y+7) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 10) { for (sy = ship->y-7; sy <= ship->y+7; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-5 || sx == ship->x+5)) continue; if ((sy == ship->y-6 || sy == ship->y+6) && (sx <= ship->x-4 || sx >= ship->x+4)) continue; if ((sy == ship->y-7 || sy == ship->y+7) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } } else { if (ship->size == 2) { for (sy = ship->y-1; sy <= ship->y+1; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sx == ship->x-3 || sx == ship->x+3) && sy != ship->y) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 3) { for (sy = ship->y-1; sy <= ship->y+1; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sx == ship->x-4 || sx == ship->x+4) && sy != ship->y) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 4) { for (sy = ship->y-2; sy <= ship->y+2; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sx == ship->x-4 || sx == ship->x+4) && (sy == ship->y-2 || sy == ship->y+2)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 5) { for (sy = ship->y-2; sy <= ship->y+2; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-2 || sy == ship->y+2)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 6) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-3 || sy == ship->y+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 7) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-6; sx <= ship->x+6; sx++) { if ((sx == ship->x-6 || sx == ship->x+6) && (sy == ship->y-3 || sy == ship->y+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 8) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-6; sx <= ship->x+6; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-4 || sy == ship->y+4)) continue; if ((sx == ship->x-6 || sx == ship->x+6) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 9) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-7; sx <= ship->x+7; sx++) { if ((sx == ship->x-6 || sx == ship->x+6) && (sy == ship->y-4 || sy == ship->y+4)) continue; if ((sx == ship->x-7 || sx == ship->x+7) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } if (ship->size == 10) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-7; sx <= ship->x+7; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-5 || sy == ship->y+5)) continue; if ((sx == ship->x-6 || sx == ship->x+6) && (sy <= ship->y-4 || sy >= ship->y+4)) continue; if ((sx == ship->x-7 || sx == ship->x+7) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; if (sx < 1 || sx > MAX_X || sy < 1 || sy > MAX_Y) return 0; if (map_sector[ship->map][sx][sy] != SECT_OCEAN) return 0; } } } } return 1; } SHIP_DATA *is_ship_sector(int x, int y, int map) { SHIP_DATA *ship; int sx; int sy; for (ship = first_ship; ship; ship = ship->next) { if (ship->x == x && ship->y == y && ship->map == map) return ship; //Do a proximity check. No need to loop through all of this if we aren't even near a ship if ((ship->direction == 0 || ship->direction == 2) && (abs(x + y - ship->x - ship->y) < ship->size+3)) { if (ship->size == 2) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-1; sx <= ship->x+1; sx++) { if ((sy == ship->y-3 || sy == ship->y+3) && sx != ship->x) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 3) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-1; sx <= ship->x+1; sx++) { if ((sy == ship->y-4 || sy == ship->y+4) && sx != ship->x) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 4) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-2; sx <= ship->x+2; sx++) { if ((sy == ship->y-4 || sy == ship->y+4) && (sx == ship->x-2 || sx == ship->x+2)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 5) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-2; sx <= ship->x+2; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-2 || sx == ship->x+2)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 6) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-3 || sx == ship->x+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 7) { for (sy = ship->y-6; sy <= ship->y+6; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sy == ship->y-6 || sy == ship->y+6) && (sx == ship->x-3 || sx == ship->x+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 8) { for (sy = ship->y-6; sy <= ship->y+6; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-4 || sx == ship->x+4)) continue; if ((sy == ship->y-6 || sy == ship->y+6) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 9) { for (sy = ship->y-7; sy <= ship->y+7; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sy == ship->y-6 || sy == ship->y+6) && (sx == ship->x-4 || sx == ship->x+4)) continue; if ((sy == ship->y-7 || sy == ship->y+7) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 10) { for (sy = ship->y-7; sy <= ship->y+7; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sy == ship->y-5 || sy == ship->y+5) && (sx == ship->x-5 || sx == ship->x+5)) continue; if ((sy == ship->y-6 || sy == ship->y+6) && (sx <= ship->x-4 || sx >= ship->x+4)) continue; if ((sy == ship->y-7 || sy == ship->y+7) && (sx <= ship->x-3 || sx >= ship->x+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } } else if ((ship->direction == 1 || ship->direction == 3) && (abs(x + y - ship->x - ship->y) < ship->size+3)) { if (ship->size == 2) { for (sy = ship->y-1; sy <= ship->y+1; sy++) { for (sx = ship->x-3; sx <= ship->x+3; sx++) { if ((sx == ship->x-3 || sx == ship->x+3) && sy != ship->y) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 3) { for (sy = ship->y-1; sy <= ship->y+1; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sx == ship->x-4 || sx == ship->x+4) && sy != ship->y) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 4) { for (sy = ship->y-2; sy <= ship->y+2; sy++) { for (sx = ship->x-4; sx <= ship->x+4; sx++) { if ((sx == ship->x-4 || sx == ship->x+4) && (sy == ship->y-2 || sy == ship->y+2)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 5) { for (sy = ship->y-2; sy <= ship->y+2; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-2 || sy == ship->y+2)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 6) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-5; sx <= ship->x+5; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-3 || sy == ship->y+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 7) { for (sy = ship->y-3; sy <= ship->y+3; sy++) { for (sx = ship->x-6; sx <= ship->x+6; sx++) { if ((sx == ship->x-6 || sx == ship->x+6) && (sy == ship->y-3 || sy == ship->y+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 8) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-6; sx <= ship->x+6; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-4 || sy == ship->y+4)) continue; if ((sx == ship->x-6 || sx == ship->x+6) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 9) { for (sy = ship->y-4; sy <= ship->y+4; sy++) { for (sx = ship->x-7; sx <= ship->x+7; sx++) { if ((sx == ship->x-6 || sx == ship->x+6) && (sy == ship->y-4 || sy == ship->y+4)) continue; if ((sx == ship->x-7 || sx == ship->x+7) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } if (ship->size == 10) { for (sy = ship->y-5; sy <= ship->y+5; sy++) { for (sx = ship->x-7; sx <= ship->x+7; sx++) { if ((sx == ship->x-5 || sx == ship->x+5) && (sy == ship->y-5 || sy == ship->y+5)) continue; if ((sx == ship->x-6 || sx == ship->x+6) && (sy <= ship->y-4 || sy >= ship->y+4)) continue; if ((sx == ship->x-7 || sx == ship->x+7) && (sy <= ship->y-3 || sy >= ship->y+3)) continue; if (sx == x && sy == y && ship->map == map) return ship; } } } } } return NULL; } void update_ship_chars(SHIP_DATA *ship) { CHAR_DATA *ch; for (ch = ship->first_char; ch; ch = ch->next_ship) { ch->coord->x = ship->x; ch->coord->y = ship->y; update_objects(ch, ch->coord->x, ch->coord->y, ch->map); do_look(ch, "auto"); } } void update_object_contents(OBJ_DATA *obj, int x, int y) { OBJ_DATA *cobj; obj->coord->x = x; obj->coord->y = y; for (cobj = obj->first_content; cobj; cobj = cobj->next_content) { update_object_contents(cobj, x, y); } } void steer_ship(CHAR_DATA *ch, SHIP_DATA *ship, int dir) { int ox; int oy; int odir; int x; int y; ROOM_INDEX_DATA *room; char buf[MSL]; OBJ_DATA *obj; x = y = 0; if (dir == 0) y = -1; if (dir == 1) x = 1; if (dir == 2) y = 1; if (dir == 3) x = -1; ox = ship->x; oy = ship->y; odir = ship->direction; set_ship_sector(ship, 1, 0); ship->x += x; ship->y += y; ship->direction = dir; if (!ch) ch = ship->first_char; if (check_ship_borders(ship)) { if (ch) { sprintf(buf, "The ship sails to the %s", dir_name[dir]); act(AT_WHITE, buf, ch, NULL, NULL, TO_ROOM); act(AT_WHITE, buf, ch, NULL, NULL, TO_CHAR); } set_ship_sector(ship, 0, 1); update_ship_chars(ship); fwrite_ship_data(); if (ch) room = ch->in_room; else room = get_room_index(OVERLAND_SOLAN); for (obj = room->first_content; obj; obj = obj->next_content) { if (obj->coord->x == ox && obj->coord->y == oy) { update_object_contents(obj, ship->x, ship->y); } } return; } else { ship->x -= x; ship->y -= y; ship->direction = odir; set_ship_sector(ship, 0, 0); if (ch) send_to_char("Something is blocking you from going that direction.\n\r", ch); return; } } void do_steership(CHAR_DATA *ch, char *argument) { int dir = -1; if (get_trust(ch) < LEVEL_IMMORTAL || IS_NPC(ch)) { send_to_char("Huh?\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("Syntax: steership <direction>\n\r", ch); send_to_char("Ships can only move in 4 directions - north west south east.\n\r", ch); return; } if (!str_cmp(argument, "n") || !str_cmp(argument, "north")) dir = 0; if (!str_cmp(argument, "e") || !str_cmp(argument, "east")) dir = 1; if (!str_cmp(argument, "s") || !str_cmp(argument, "south")) dir = 2; if (!str_cmp(argument, "w") || !str_cmp(argument, "west")) dir = 3; if (dir == -1) { do_steership(ch, ""); return; } if (!ch->ship) { send_to_char("You have to be on a ship to steer it.\n\r", ch); return; } steer_ship(ch, ch->ship, dir); } void new_map_to_char(CHAR_DATA * ch, int startx, int starty, int endx, int endy, int showeoc) { int x, y, p; int sx, sy; int stx, sty, enx, eny; int seeobj; int bfight, bobj, bportal, bcolor; sh_int seemap, seeportal, eoc, eeoc, istown; CMAP_DATA *mch; OMAP_DATA *mobj; //int bsize = ((endx - startx) * (endy - starty)) * 20; char buf[MSL]; //char hbuf[bsize]; /* Sent in one huge buf, might save sending time */ char hbuf[MSL]; DESCRIPTOR_DATA *d; sh_int tbufx[10]; sh_int tbufy[10]; char fground[10]; char rground[10]; int cannotseeindoors = 0; sh_int tbx, ttorn, tcur, tlast; TORNADO_DATA *torn; TOWN_DATA *town; DOOR_DATA *ddata; int cnt, cx, cy; int curx, cury; int lastblank = 0; int isinside = 0; int dx; int fnddoor[100]; int canseeinside[101][101]; tcur = tlast = 0; for (tbx = 0; tbx < 10; tbx++) { tbufx[tbx] = 0; tbufy[tbx] = 0; } ttorn = 0; //Tornado present int sprintf(hbuf, "\n\r"); bfight = bobj = bportal = 0; stx = startx; sty = starty; enx = endx; eny = endy; snows = 0; if (stx < 1) stx = 1; if (sty < 1) sty = 1; if (enx > MAX_X) enx = MAX_X; if (eny > MAX_Y) eny = MAX_Y; for (torn = first_tornado; torn; torn = torn->next) { tbx = 0; if (torn->x >= stx && torn->x <= enx && torn->y >= sty && torn->y <= eny && ch->map == torn->map) { tbufx[tbx] = torn->x; tbufy[tbx] = torn->y; tbx++; ttorn = 1; } } //time for Inside check.... for (cx = 0; cx <= 99; cx++) fnddoor[cx] = 0; town = find_town(ch->coord->x, ch->coord->y, ch->map); if (town) { for (ddata = town->first_doorlist->first_door; ddata; ddata = ddata->next) ddata->cannotsee = 0; } curx = ch->coord->x; cury = ch->coord->y; if (town && (map_sector[ch->map][curx][cury] == SECT_INSIDE || map_sector[ch->map][curx][cury] == SECT_DOOR || map_sector[ch->map][curx][cury] == SECT_CDOOR || map_sector[ch->map][curx][cury] == SECT_LDOOR)) { if (map_sector[ch->map][curx][cury] != SECT_INSIDE) //door { for (dx = 0; dx <= 99; dx++) { if (town->doorstate[5][dx] == curx && town->doorstate[6][dx] == cury && town->doorstate[7][dx] == ch->map) { for (ddata = town->first_doorlist->first_door; ddata; ddata = ddata->next) { for (x = 0; x <= 9; x++) { if (ddata->doorvalue[x] == town->doorstate[4][dx]) { for (y = 0; y <= MAX_HPOINTS-1; y++) { if (ddata->roomcoordx[y] > 0) { curx = ddata->roomcoordx[y]; cury = ddata->roomcoordy[y]; break; } } if (curx != ch->coord->x && cury != ch->coord->y) break; } } if (curx != ch->coord->x && cury != ch->coord->y) break; } if (curx != ch->coord->x && cury != ch->coord->y) break; } } } if (map_sector[ch->map][curx][cury] == SECT_INSIDE) { for (ddata = town->first_doorlist->first_door; ddata; ddata = ddata->next) { for (dx = 0; dx <= MAX_HPOINTS-1; dx++) { if (ddata->roomcoordx[dx] == curx && ddata->roomcoordy[dx] == cury && ddata->roomcoordmap[dx] == ch->map) { if (update_inside_stat(fnddoor, ch, town, curx, cury, ch->map) == 0) //are indeed inside { isinside = 1; for (x = 0; x <= 100; x++) { for (y = 0; y <= 100; y++) { canseeinside[x][y] = 0; } } canseeinside[50][50] = 1; for (dx = 0; dx <= MAX_HPOINTS-1; dx++) { if (ddata->roomcoordx[dx] > 0) { for (cnt = 1; cnt <= 8; cnt++) { cx = ddata->roomcoordx[dx]; cy = ddata->roomcoordy[dx]; if (cnt == 1 || cnt == 5 || cnt == 7) //east cx = cx+1; if (cnt == 2 || cnt == 7 || cnt == 8) //south cy = cy+1; if (cnt == 3 || cnt == 6 || cnt == 8) //west cx = cx-1; if (cnt == 4 || cnt == 5 || cnt == 6) //north cy = cy-1; canseeinside[50+ch->coord->x-cx][50+ch->coord->y-cy] = 1; } } } for (ddata = town->first_doorlist->first_door; ddata; ddata = ddata->next) { if (ddata->cannotsee == 1) { for (dx = 0; dx <= MAX_HPOINTS-1; dx++) { if (ddata->roomcoordx[dx] > 0) { canseeinside[50+ch->coord->x-ddata->roomcoordx[dx]][50+ch->coord->y-ddata->roomcoordy[dx]] = 1; for (cnt = 1; cnt <= 8; cnt++) { cx = ddata->roomcoordx[dx]; cy = ddata->roomcoordy[dx]; if (cnt == 1 || cnt == 5 || cnt == 7) //east cx = cx+1; if (cnt == 2 || cnt == 7 || cnt == 8) //south cy = cy+1; if (cnt == 3 || cnt == 6 || cnt == 8) //west cx = cx-1; if (cnt == 4 || cnt == 5 || cnt == 6) //north cy = cy-1; canseeinside[50+ch->coord->x-cx][50+ch->coord->y-cy] = 1; } } } } } break; }//end update_inside_stat brace } } if (isinside == 1) break; } } } //ch_printf(ch, "%s", MXPTAG("FRAME Name=\"Map\" FLOATING Left=\"-55c\" Top=\"0\" Width=\"55c\" Height=\"21c\"")); //ch_printf(ch, "%s %s %s", MXPTAG("DEST Map EOF"), MXPTAG("/DEST"), MXPTAG("DEST Map")); //ch_printf(ch, "%s", MXPTAG("DEST Map")); if (xIS_SET(ch->act, PLR_MAPWINDOW) && !IS_NPC(ch)) { if (ch->pcdata->xsize != endx-startx+2 && ch->pcdata->ysize != endy-starty+1) { ch_printf(ch, "%s" "FRAME Name=\"Map\" FLOATING Left=\"-%dc\" Top=\"0\" Width=\"%dc\" Height=\"%dc\"" "%s", MXP_BEG, endx-startx+2, endx-startx+2, endy-starty+1, MXP_END); ch->pcdata->xsize = endx-startx+2; ch->pcdata->ysize = endy-starty+1; } ch_printf(ch, "%s %s %s", MXPTAG("DEST Map EOF"), MXPTAG("/DEST"), MXPTAG("DEST Map")); } for (y = sty; y < eny + 1; y += 1) { int fnd = 0; sy = y; for (x = stx; x < enx + 1; x += 1) { if (tcur == 1) tlast = 1; tcur = 0; seemap = 0; seeobj = 0; seeportal = 0; bcolor = 0; eoc = 0; eeoc = 0; istown = 0; bfight = UMAX(0, bfight - 1); bobj = UMAX(0, bobj - 1); bportal = UMAX(0, bportal - 1); if (ttorn == 1) { for (tbx = 0; tbx < 9; tbx++) //Tornado Present at this location { if (x == tbufx[tbx] && y == tbufy[tbx]) { strcat(hbuf, "&PT"); snows = 0; fnd = 0; tcur = 1; break; } } } if (tcur == 1) continue; if (bfight > 0 || bobj > 0 || bportal > 0 || (ch->coord->x + 1 == x && ch->coord->y == y)) bcolor = 1; sx = x; for (d = first_descriptor; d; d = d->next) { if (d->connected == CON_PLAYING && d->character != ch && d->character->in_room && d->newstate != 2 && can_see_map(ch, d->character) && (d->character->coord->x + 1 == x && d->character->coord->y == y && d->character->map == ch->map)) { bcolor = 1; } if (d->connected == CON_PLAYING && d->character != ch && d->character->in_room && d->newstate != 2 && can_see_map(ch, d->character) && (d->character->coord->x == x && d->character->coord->y == y && d->character->map == ch->map)) { fnd = 1; if (IS_AFFECTED(d->character, AFF_INVISIBLE) && !IS_AFFECTED(ch, AFF_DETECT_INVIS)) fnd = 0; if (IS_AFFECTED(d->character, AFF_HIDE) && !IS_AFFECTED(ch, AFF_DETECT_HIDDEN)) fnd = 0; if (IS_AFFECTED(d->character, AFF_STALK)) fnd = 0; if (xIS_SET(ch->act, PLR_HOLYLIGHT)) fnd = 1; if (xIS_SET(d->character->act, PLR_WIZINVIS) && get_trust(ch) < d->character->pcdata->wizinvis) fnd = 0; } } for (p = 0; p < sysdata.last_portal; p++) { if (portal_show[p]->map == ch->map && portal_show[p]->x == x && portal_show[p]->y == y) { if (abs(x - ch->coord->x) <= 3 && abs(y - ch->coord->y) <= 3 && xIS_SET(ch->act, PLR_PORTALHUNT)) { seeportal = 1; bportal = 2; } if (xIS_SET(ch->pcdata->portalfnd, p)) { seeportal = 1; bportal = 2; } } } for (mobj = first_wilderobj; mobj; mobj = mobj->next) { if ((mobj->mapobj->coord->x == x && mobj->mapobj->coord->y == y && mobj->mapobj->map == ch->map)) { seeobj = 1; bobj = 2; } else continue; if (IS_OBJ_STAT(mobj->mapobj, ITEM_INVIS)) { if (!IS_AFFECTED(ch, AFF_DETECT_INVIS) && !IS_AFFECTED(ch, AFF_TRUESIGHT)) { seeobj = 0; bobj = 0; } } if (mobj->mapobj->item_type == ITEM_PORTAL) { seeobj = 0; bobj = 0; } if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_HOLYLIGHT)) { seeobj = 1; bobj = 2; } } if (showeoc && kingdom_sector[ch->map][x][y] > 1 && kingdom_sector[ch->map][x][y] == ch->pcdata->hometown) eoc = 1; if (showeoc && kingdom_sector[ch->map][x][y] > 1 && kingdom_sector[ch->map][x][y] != ch->pcdata->hometown) { if (kingdom_table[ch->pcdata->hometown]->peace[kingdom_sector[ch->map][x][y]] == 0) //war eeoc = 1; if (kingdom_table[ch->pcdata->hometown]->peace[kingdom_sector[ch->map][x][y]] == 1) //neutral eeoc = 2; if (kingdom_table[ch->pcdata->hometown]->peace[kingdom_sector[ch->map][x][y]] == 2) //trading eeoc = 3; if (kingdom_table[ch->pcdata->hometown]->peace[kingdom_sector[ch->map][x][y]] == 3) //peace eeoc = 4; } if (eoc || eeoc) { for (town = kingdom_table[kingdom_sector[ch->map][x][y]]->first_town; town; town = town->next) { if (town->startx == x && town->starty == y && town->startmap == ch->map) istown = 1; } } if (!can_see_room(x, y, ch->map, map_sector[ch->map][x][y])) cannotseeindoors = 1; if (isinside == 1 && canseeinside[50+ch->coord->x-x][50+ch->coord->y-y] == 0) cannotseeindoors = 1; if (isinside == 1 && canseeinside[50+ch->coord->x-x][50+ch->coord->y-y] == 1) cannotseeindoors = 0; for (mch = first_wilderchar; mch; mch = mch->next) { if (mch->mapch->coord->x == x && mch->mapch->coord->y == y && mch->mapch->map == ch->map && cannotseeindoors == 0) { seemap = 1; /* seemap = 0 see only terrain 1 = see vis mobs 2 = see hide mobs 3 = see invis mobs 4 = see both */ if (!xIS_SET(ch->act, PLR_HOLYLIGHT) || !IS_AFFECTED(ch, AFF_TRUESIGHT)) { if (IS_AFFECTED(mch->mapch, AFF_INVISIBLE) && !IS_AFFECTED(ch, AFF_DETECT_INVIS)) seemap = 0; if (IS_AFFECTED(mch->mapch, AFF_HIDE) && !IS_AFFECTED(ch, AFF_DETECT_HIDDEN)) seemap = 0; if (IS_AFFECTED(mch->mapch, AFF_STALK)) seemap = 0; if (IS_AFFECTED(ch, AFF_BLIND)) seemap = 0; } if (IS_AFFECTED(ch, AFF_TRUESIGHT)) seemap = 1; if (xIS_SET(mch->mapch->act, ACT_MOBINVIS) && get_trust(ch) <= LEVEL_GUEST) seemap = 0; if (xIS_SET(mch->mapch->act, ACT_TRAINER)) if ((abs(ch->coord->x - mch->mapch->coord->x) > 3) || (abs(ch->coord->y - mch->mapch->coord->y) > 3)) seemap = 0; if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_HOLYLIGHT)) seemap = 1; if (seemap == 1 && (IS_NPC(ch) || !xIS_SET(ch->act, PLR_WILDERTILES))) { if (eoc == 1) sprintf(fground, "^b"); else if (eeoc == 1) sprintf(fground, "^r"); else if (eeoc == 2) sprintf(fground, "^g"); else if (eeoc == 3) sprintf(fground, "^w"); else if (eeoc == 4) sprintf(fground, "^O"); else sprintf(fground, "^c"); if (istown) { snows = 0; sprintf(buf, "%s&RT&w^x", fground); strcat(hbuf, buf); break; } else if ((global_x[0] == x && global_y[0] == y) && (abs(global_x[0] - ch->coord->x) <= 3 && abs(global_y[0] - ch->coord->y) <= 3)) { snows = 0; sprintf(buf, "%s&C#^x", fground); strcat(hbuf, buf); break; } else { if (x == ch->coord->x && y == ch->coord->y) { sprintf(buf, "%s&R*^x", fground); strcat(hbuf, buf); snows = 0; } else if (seeportal) { sprintf(buf, "%s&BO^x", fground); strcat(hbuf, buf); snows = 0; } else if (fnd == 1) { snows = 0; if (seeobj == 1) sprintf(buf, "%s&p*^x", fground); else sprintf(buf, "%s&G&W*^x", fground); strcat(hbuf, buf); } else { if (seeobj == 1) { sprintf(buf, "%s&p%s^x", fground, show_room(map_sector[ch->map][x][y], -20, -20, -20, -1)); snows = 0; } else { if (bcolor == 1 || tlast == 1) sprintf(buf, "%s%s^x", fground, show_room(map_sector[ch->map][x][y], x, y, ch->map, x)); else if (lastblank == 1) { sprintf(buf, "%s%s^x", fground, show_room(map_sector[ch->map][x][y], -10, -10, -10, -1)); lastblank = 0; } else sprintf(buf, "%s%s^x", fground, show_room(map_sector[ch->map][x][y], x, y, ch->map, stx)); } strcat(hbuf, buf); } break; } } else if (seemap == 1 && !IS_NPC(ch) && xIS_SET(ch->act, PLR_WILDERTILES)) { if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_WILDERTILES)) { sprintf(buf, "\x03Image a3.gif align=bottom\x04"); strcat(hbuf, buf); break; } } } }//end mobile check if (seemap == 0 && cannotseeindoors == 0) { if (eoc == 1) { sprintf(fground, "^b"); sprintf(rground, "^x"); } else if (eeoc == 1) { sprintf(fground, "^r"); sprintf(rground, "^x"); } else if (eeoc == 2) { sprintf(fground, "^g"); sprintf(rground, "^x"); } else if (eeoc == 3) { sprintf(fground, "^w"); sprintf(rground, "^x"); } else if (eeoc == 4) { sprintf(fground, "^O"); sprintf(rground, "^x"); } else { strcpy(fground, ""); strcpy(rground, ""); } if (istown) { snows = 0; sprintf(buf, "%s&RT&w%s", fground, rground); strcat(hbuf, buf); } else if ((global_x[0] == x && global_y[0] == y) && (abs(global_x[0] - ch->coord->x) <= 3 && abs(global_y[0] - ch->coord->y) <= 3)) { snows = 0; sprintf(buf, "%s&C#%s", fground, rground); strcat(hbuf, buf); } else { if (x == ch->coord->x && y == ch->coord->y) { if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_WILDERTILES)) { sprintf(buf, "\x03Image a.gif align=bottom\x04"); strcat(hbuf, buf); } else { sprintf(buf, "%s&R*%s", fground, rground); strcat(hbuf, buf); } snows = 0; } else if (seeportal) { if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_WILDERTILES)) { sprintf(buf, "\x03Image p2.gif align=bottom\x04"); strcat(hbuf, buf); } else { sprintf(buf, "%s&BO%s", fground, rground); strcat(hbuf, buf); } snows = 0; } else if (fnd == 1) { snows = 0; if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_WILDERTILES)) { sprintf(buf, "\x03Image a2.gif align=bottom\x04"); strcat(hbuf, buf); } else { if (seeobj == 1) sprintf(buf, "%s&p*%s", fground, rground); else sprintf(buf, "%s&G&W*%s", fground, rground); strcat(hbuf, buf); } } else { if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_WILDERTILES)) { sprintf(buf, "\x03Image %s align=bottom\x04", sect_show[map_sector[ch->map][x][y]].tilefile); strcat(hbuf, buf); } else if (seeobj == 1) { sprintf(buf, "%s&p%s%s", fground, show_room(map_sector[ch->map][x][y], -20, -20, -20, -1), rground); strcat(hbuf, buf); snows = 0; } else { if (bcolor == 1 || tlast == 1) sprintf(buf, "%s%s^x%s", fground, show_room(map_sector[ch->map][x][y], x, y, ch->map, x), rground); else if (lastblank == 1) { sprintf(buf, "%s%s^x%s", fground, show_room(map_sector[ch->map][x][y], -10, -10, -10, -1), rground); lastblank = 0; } else sprintf(buf, "%s%s^x%s", fground, show_room(map_sector[ch->map][x][y], x, y, ch->map, stx), rground); strcat(hbuf, buf); } } x = sx; y = sy; } x = sx; y = sy; } if (cannotseeindoors == 1) { if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_WILDERTILES)) { sprintf(buf, "\x03Image v.gif align=bottom\x04"); strcat(hbuf, buf); } else { strcat(hbuf, " "); lastblank = 1; //to refresh color... } } fnd = 0; cannotseeindoors = 0; } /* NorthWest North NorthEast \ | / West - - East / | \ Southwest South SouthEast */ if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_AUTOEXIT) && y >= endy-4 && ch->desc && ch->desc->mxp && !xIS_SET(ch->act, PLR_MAPWINDOW) && !xIS_SET(ch->act, PLR_WILDERTILES)) { strcat(hbuf, "&w&G"); if (y == endy-4) strcat(hbuf, " " MXPFTAG ("Ex", "NorthWest", "/Ex") " " MXPFTAG("Ex", "North", "/Ex") " " MXPFTAG("Ex", "NorthEast", "/Ex")); if (y == endy-3) strcat(hbuf, " \\ | /"); if (y == endy-2) strcat(hbuf, " " MXPFTAG ("Ex", "West", "/Ex") " - - " MXPFTAG ("Ex", "East", "/Ex")); if (y == endy-1) strcat(hbuf, " / | \\"); if (y == endy) strcat(hbuf, " " MXPFTAG ("Ex", "SouthWest", "/Ex") " " MXPFTAG("Ex", "South", "/Ex") " " MXPFTAG("Ex", "SouthEast", "/Ex")); } strcat(hbuf, "\n\r"); send_to_char(hbuf, ch); strcpy(hbuf, ""); } send_to_char(hbuf, ch); if (!IS_NPC(ch) && xIS_SET(ch->act, PLR_MAPWINDOW)) ch_printf(ch, "%s", MXPTAG("/DEST")); } void display_map(CHAR_DATA * ch, sh_int vx, sh_int vy, sh_int eoc) { sh_int startx, starty, endx, endy; sh_int sector; sh_int x, y, z; int mod; CHAR_DATA *sch; TOWN_DATA *town; sch = ch; if (ch->map == -1) { bug("display_map: Player %s on an invalid map! Moving them to Solan.", ch->name); send_to_char("&RYou were found on an invalid map and have been moved to Solan.\n\r", ch); enter_map(ch, 260, 250, MAP_SOLAN); return; } sector = map_sector[ch->map][ch->coord->x][ch->coord->y]; if (IS_IMMORTAL(ch) && vx != 6000 && vy != 6000) { if (vx == -1 && vy == -1) { startx = ch->coord->x - 8; endx = ch->coord->x + 8; starty = ch->coord->y - 8; endy = ch->coord->y + 8; } else { startx = ch->coord->x - vx; endx = ch->coord->x + vx; starty = ch->coord->y - vy; endy = ch->coord->y + vy; } } else { OBJ_DATA *light; if ((vx == 5000 && vy == 5000)) { mod = 8; if (!IS_AFFECTED(ch, AFF_WIZARDEYE) && !IS_AFFECTED(ch, AFF_E_WIZARDEYE) && !IS_AFFECTED(ch, AFF_M_WIZARDEYE)) { light = get_eq_char(ch, WEAR_LIGHT); if (gethour() == 6 || gethour() == 21) mod = 7; if (gethour() > 21 || gethour() < 6) mod = 3; if (light != NULL || IS_AFFECTED(ch, AFF_INFRARED)) { if (IS_AFFECTED(ch, AFF_INFRARED)) { if (gethour() > 21 || gethour() < 6) mod += 4; else mod += 0; } else if (light->item_type == ITEM_LIGHT && (gethour() > 21 || gethour() < 6)) mod += 4; } if (!IS_NPC(ch) && LEARNED(ch, gsn_thiefeye) > 0) { if (MASTERED(ch, gsn_thiefeye) == 6) mod += 5; if (MASTERED(ch, gsn_thiefeye) == 5) mod += 4; if (MASTERED(ch, gsn_thiefeye) == 4) mod += 3; if (MASTERED(ch, gsn_thiefeye) == 3) mod += 2; if (MASTERED(ch, gsn_thiefeye) == 2) mod += 1; if (MASTERED(ch, gsn_thiefeye) == 1) mod += 1; learn_from_success(ch, gsn_thiefeye, NULL); } } } else if (vx == 6000 && vy == 6000) //scan { mod = 8; light = get_eq_char(ch, WEAR_LIGHT); if (gethour() == 6 || gethour() == 21) mod = 7; if (gethour() > 21 || gethour() < 6) mod = 3; if (light != NULL || IS_AFFECTED(ch, AFF_INFRARED)) { if (IS_AFFECTED(ch, AFF_INFRARED)) { if (gethour() > 21 || gethour() < 6) mod += 4; else mod += 0; } else if (light->item_type == ITEM_LIGHT && (gethour() > 21 || gethour() < 6)) mod += 4; } if (MASTERED(ch, gsn_scan) == 5) mod += 7; else if (MASTERED(ch, gsn_scan) == 4) mod += 6; else if (MASTERED(ch, gsn_scan) == 3) mod += 4; else if (MASTERED(ch, gsn_scan) == 2) mod += 2; else if (MASTERED(ch, gsn_scan) == 1) mod += 1; else mod += 9; mod = UMAX(1, mod); } else { mod = 5; if (!IS_AFFECTED(ch, AFF_WIZARDEYE) && !IS_AFFECTED(ch, AFF_E_WIZARDEYE) && !IS_AFFECTED(ch, AFF_M_WIZARDEYE)) { light = get_eq_char(ch, WEAR_LIGHT); if (gethour() == 6 || gethour() == 21) mod = 4; if (gethour() > 21 || gethour() < 6) mod = 2; if (light != NULL || IS_AFFECTED(ch, AFF_INFRARED)) { if (IS_AFFECTED(ch, AFF_INFRARED)) { if (gethour() > 21 || gethour() < 6) mod += 2; else mod += 0; } else if (light->item_type == ITEM_LIGHT && (gethour() > 21 || gethour() < 6)) mod += 2; } if (!IS_NPC(ch) && LEARNED(ch, gsn_thiefeye) > 0) { if (MASTERED(ch, gsn_thiefeye) == 6) mod += 5; if (MASTERED(ch, gsn_thiefeye) == 5) mod += 4; if (MASTERED(ch, gsn_thiefeye) == 4) mod += 3; if (MASTERED(ch, gsn_thiefeye) == 3) mod += 2; if (MASTERED(ch, gsn_thiefeye) == 2) mod += 1; if (MASTERED(ch, gsn_thiefeye) == 1) mod += 1; learn_from_success(ch, gsn_thiefeye, NULL); } } } x = ch->coord->x; y = ch->coord->y; if (!IS_NPC(ch) && mod <= 12) { if (IS_AFFECTED(ch, AFF_WIZARDEYE)) mod = UMAX(mod, 6); if (IS_AFFECTED(ch, AFF_E_WIZARDEYE)) mod = UMAX(mod, 7); if (IS_AFFECTED(ch, AFF_M_WIZARDEYE)) mod = UMAX(mod, 8); } startx = ch->coord->x - mod; starty = ch->coord->y - mod; endx = ch->coord->x + mod; endy = ch->coord->y + mod; } if (IS_PLR_FLAG(ch, PLR_MAPEDIT) && sector != SECT_EXIT) { map_sector[ch->map][ch->coord->x][ch->coord->y] = ch->pcdata->secedit; resource_sector[ch->map][ch->coord->x][ch->coord->y] = 0; sector = ch->pcdata->secedit; } new_map_to_char(ch, startx, starty, endx, endy, eoc); /* Kept dumping the character here, just put it back in ??? Hell if I know */ ch = sch; if (kingdom_sector[ch->map][ch->coord->x][ch->coord->y] > 1) { for (town = kingdom_table[kingdom_sector[ch->map][ch->coord->x][ch->coord->y]]->first_town; town; town = town->next) { for (z = 1; z <= 150; z++) { if (town->roomcoords[z][0] == ch->coord->x && town->roomcoords[z][1] == ch->coord->y && town->roomcoords[z][2] == ch->map) { set_char_color(AT_RMNAME, ch); ch_printf(ch, "\n\r%s\n\r", town->roomtitles[z]); set_char_color(AT_RMNAME, ch); break; } } if (z < 151) break; } } if (IS_IMMORTAL(ch)) { ch_printf(ch, "\n\r&GSector type: %s. Coordinates: %dX, %dY Resources: %d Kingdom: %d\n\r", sect_show[sector].desc, ch->coord->x, ch->coord->y, resource_sector[ch->map][ch->coord->x][ch->coord->y], kingdom_sector[ch->map][ch->coord->x][ch->coord->y]); if (IS_PLR_FLAG(ch, PLR_MAPEDIT)) { ch_printf(ch, "&YYou are currently creating %s sectors.&z\n\r", sect_show[ch->pcdata->secedit].desc); } } return; } void update_player_container(CHAR_DATA * ch, OBJ_DATA *iobj) { OBJ_DATA *cobj; int x, y, map; x = ch->coord->x; y = ch->coord->y; map = ch->map; for (cobj = iobj->first_content; cobj; cobj = cobj->next_content) { if (x > -1 || y > -1 || map > -1) SET_OBJ_STAT(cobj, ITEM_ONMAP); else REMOVE_OBJ_STAT(cobj, ITEM_ONMAP); cobj->coord->x = ch->coord->x; cobj->coord->y = ch->coord->y; cobj->map = ch->map; if (cobj->first_content) update_player_container(ch, cobj); } } void update_objects(CHAR_DATA * ch, sh_int map, sh_int x, sh_int y) { OBJ_DATA *iobj; /* Hrm, too lazy to go back and change, but don't really need the x, y and map, just make sure to update objects after you update the players/followers -- Xerves */ x = ch->coord->x; y = ch->coord->y; map = ch->map; for (iobj = ch->last_carrying; iobj; iobj = iobj->prev_content) { if (x > -1 || y > -1 || map > -1) SET_OBJ_STAT(iobj, ITEM_ONMAP); else REMOVE_OBJ_STAT(iobj, ITEM_ONMAP); iobj->coord->x = ch->coord->x; iobj->coord->y = ch->coord->y; iobj->map = ch->map; if (iobj->first_content) update_player_container(ch, iobj); } } /* who - 1 only mount and player 2 - only player 3 - Check choords*/ void update_players_map(CHAR_DATA * ch, int x, int y, int map, int who, ROOM_INDEX_DATA * room) { CHAR_DATA *nextinroom; CHAR_DATA *fch; sh_int type, pstatus; sh_int ox, oy, omap; if (room->vnum == OVERLAND_SOLAN) { type = 1; ox = ch->coord->x; oy = ch->coord->y; omap = ch->map; ch->map = map; ch->coord->x = x; ch->coord->y = y; update_objects(ch, x, y, map); SET_ONMAP_FLAG(ch); } else { type = 0; ox = ch->coord->x; oy = ch->coord->y; omap = ch->map; ch->coord->x = x; ch->coord->y = y; ch->map = map; update_objects(ch, x, y, map); REMOVE_ONMAP_FLAG(ch); } if (who == 2) { char_from_room(ch); char_to_room(ch, room); return; } if (ch->mount && ch->mount->con_rleg != -1 && ch->mount->con_lleg != -1) { if (ch->in_room && ch->mount->in_room && ch->in_room == ch->mount->in_room) { if (who == 3) { if (ch->mount->coord->x == ox && ch->mount->coord->y == oy && ch->mount->map == omap) { char_from_room(ch->mount); char_to_room(ch->mount, room); ch->mount->coord->x = x; ch->mount->coord->y = y; ch->mount->map = map; if (type == 1) { SET_ONMAP_FLAG(ch->mount); } else { REMOVE_ONMAP_FLAG(ch->mount); } } } else { char_from_room(ch->mount); char_to_room(ch->mount, room); ch->mount->coord->x = x; ch->mount->coord->y = y; ch->mount->map = map; if (type == 1) { SET_ONMAP_FLAG(ch->mount); } else { REMOVE_ONMAP_FLAG(ch->mount); } } } } if (who == 1) { char_from_room(ch); char_to_room(ch, room); return; } for (fch = ch->in_room->first_person; fch; fch = nextinroom) { nextinroom = fch->next_in_room; if (fch->con_rleg == -1 && fch->con_lleg == -1 && fch->position != POS_SHOVE && fch->position != POS_DRAG) { send_to_char("It is hard to move without any legs.\n\r", fch); continue; } if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && (ch->in_room && fch->in_room) && (ch->in_room == fch->in_room) && (fch->position == POS_STANDING || fch->position == POS_MOUNTED) && fch != ch->mount) { if (who == 3) { if (fch->coord->x == ox && fch->coord->y == oy && fch->map == omap) { if (IS_NPC(fch)) { char_from_room(fch); char_to_room(fch, room); fch->coord->x = x; fch->coord->y = y; fch->map = map; if (type == 1) SET_ONMAP_FLAG(fch); else REMOVE_ONMAP_FLAG(fch); update_objects(fch, x, y, map); } else { if (type == 1) SET_ONMAP_FLAG(fch); else REMOVE_ONMAP_FLAG(fch); update_players_map(fch, x, y, map, who, room); fch->coord->x = x; fch->coord->y = y; fch->map = map; update_objects(fch, x, y, map); } } } else { if (IS_NPC(fch)) { char_from_room(fch); char_to_room(fch, room); fch->coord->x = x; fch->coord->y = y; fch->map = map; if (type == 1) SET_ONMAP_FLAG(fch); else REMOVE_ONMAP_FLAG(fch); update_objects(fch, x, y, map); } else { fch->coord->x = x; fch->coord->y = y; fch->map = map; if (type == 1) SET_ONMAP_FLAG(fch); else REMOVE_ONMAP_FLAG(fch); update_players_map(fch, x, y, map, who, room); update_objects(fch, x, y, map); } } } } if (ch->rider) { fch = ch->rider; char_from_room(fch); char_to_room(fch, room); fch->coord->x = x; fch->coord->y = y; fch->map = map; if (type == 1) SET_ONMAP_FLAG(fch); else REMOVE_ONMAP_FLAG(fch); update_players_map(fch, x, y, map, who, room); update_objects(fch, x, y, map); } pstatus = check_room_pk(ch); char_from_room(ch); char_to_room(ch, room); do_look(ch, "auto"); return; } int find_mob_diff(int x, int y, int map) { WBLOCK_DATA *wblock; for (wblock = first_wblock; wblock; wblock = wblock->next) { if (x >= wblock->stx && y >= wblock->sty && x <= wblock->endx && y <= wblock->endy && map == wblock->map) { return wblock->lvl; } } return 1; } //7> has a chance for a dual wield int get_wilder_weapon(int lvl, int dual) { int chance; if (lvl <= 2) chance = number_range(1, 12); else if (lvl <= 4) chance = number_range(7, 18); else if (lvl <= 6) chance = number_range(19, 32); else if (lvl <= 9) chance = number_range(29, 38); else if (lvl <= 12) chance = number_range(35, 45); else chance = number_range(39, 45); if (dual > 0 && lvl >= 7) { if (lvl <= 9) chance = number_range(13, 28); if (lvl > 9) chance = number_range(19, 28); } if (chance == 1) return OBJ_FORGE_HAND_AXE; if (chance == 2) return OBJ_FORGE_SHORT_SWORD; if (chance == 3) return OBJ_FORGE_KNIFE; if (chance == 4) return OBJ_FORGE_CLUB; if (chance == 5) return OBJ_FORGE_SCEPTRE; if (chance == 6) return OBJ_FORGE_PILUM; if (chance == 7) return OBJ_FORGE_AXE; if (chance == 8) return OBJ_FORGE_CUTLASS; if (chance == 9) return OBJ_FORGE_DAGGER; if (chance == 10) return OBJ_FORGE_HAMMER; if (chance == 11) return OBJ_FORGE_ROD; if (chance == 12) return OBJ_FORGE_LANCE; if (chance == 13) return OBJ_FORGE_WARAXE; if (chance == 14) return OBJ_FORGE_RAPIER; if (chance == 15) return OBJ_FORGE_DIRK; if (chance == 16) return OBJ_FORGE_KRIS; if (chance == 17) return OBJ_FORGE_MACE; if (chance == 18) return OBJ_FORGE_WEIGHTED_ROD; if (chance == 19) return OBJ_FORGE_DOUBLE_AXE; if (chance == 20) return OBJ_FORGE_KATANA; if (chance == 21) return OBJ_FORGE_BROAD_SWORD; if (chance == 22) return OBJ_FORGE_CLEAVER; if (chance == 23) return OBJ_FORGE_MAIN_GAUCHE; if (chance == 24) return OBJ_FORGE_WAR_HAMMER; if (chance == 25) return OBJ_FORGE_STAFF; if (chance == 26) return OBJ_FORGE_LONG_SWORD; if (chance == 27) return OBJ_FORGE_STILETTO; if (chance == 28) //Last 1h weapon return OBJ_FORGE_FLAIL; if (chance == 29) return OBJ_FORGE_MATTOCK; if (chance == 30) return OBJ_FORGE_BASTARD_SWORD; if (chance == 31) return OBJ_FORGE_SPEAR; if (chance == 32) return OBJ_FORGE_HALBERD; if (chance == 33) return OBJ_FORGE_GREAT_FLAIL; if (chance == 34) return OBJ_FORGE_QUARTER_STAFF; if (chance == 35) return OBJ_FORGE_GREAT_AXE; if (chance == 36) return OBJ_FORGE_CLAYMORE; if (chance == 37) return OBJ_FORGE_GLAIVE; if (chance == 38) return OBJ_FORGE_GUISARME; if (chance == 39) return OBJ_FORGE_MORNING_STAR; if (chance == 40) return OBJ_FORGE_BATTLE_STAFF; if (chance == 41) return OBJ_FORGE_BATTLE_AXE; if (chance == 42) return OBJ_FORGE_FLAMBERGE; if (chance == 43) return OBJ_FORGE_TRIDENT; if (chance == 44) return OBJ_FORGE_MAUL; if (chance == 45) return OBJ_FORGE_BLADED_STAFF; return OBJ_FORGE_HAND_AXE; } int get_slab_vnum(int lvl, int num) { int num1; int num2; int num3; int per1; int per2; int per3; int x; num1=num2=num3=per1=per2=per3=0; if (lvl >= 121) { x = number_range(1, 5); num1 = OBJ_FORGE_ANGANAR + ((x-1)*2); num2 = OBJ_FORGE_MAEGLUIN + ((x-1)*2); per1 = UMIN(100, (3 * (lvl - 121))+3); per2 = 100-per1; } if (lvl >= 101) { x = number_range(1, 5); x = OBJ_FORGE_MAEGLUIN + ((x-1)*2); num1 = x; num2 = OBJ_FORGE_D_MITHRIL; num3 = OBJ_FORGE_MITHRILSLAB; per1 = UMIN(100, (5 * (lvl - 101))+5); per2 = UMIN(100-per1, (10 * (lvl-95))+10); per3 = 100-per1-per2; } else if (lvl >= 95) { num1 = OBJ_FORGE_D_MITHRIL; num2 = OBJ_FORGE_MITHRILSLAB; num3 = OBJ_FORGE_TUNGSTEN; per1 = UMIN(100, (10 * (lvl - 95))+10); per2 = UMIN(100-per1, (10 * (lvl - 90))+10); per3 = 100-per1-per2; } else if (lvl >= 91) { num1 = OBJ_FORGE_MITHRILSLAB; num2 = OBJ_FORGE_TUNGSTEN; per1 = UMIN(100, (10 * (lvl - 91))+10); per2 = 100-per1; } else if (lvl >= 75) { num1 = OBJ_FORGE_TUNGSTEN; num2 = OBJ_FORGE_TITANIUM; per1 = UMIN(100, (10 * (lvl - 75))+10); per2 = 100-per1; } else if (lvl >= 65) { num1 = OBJ_FORGE_TITANIUM; num2 = OBJ_FORGE_COBALT; per1 = UMIN(100, (10 * (lvl - 65))+10); per2 = 100-per1; } else if (lvl >= 55) { num1 = OBJ_FORGE_COBALT; num2 = OBJ_FORGE_BRASS; per1 = UMIN(100, (10 * (lvl - 55))+10); per2 = 100-per1; } else if (lvl >= 45) { num1 = OBJ_FORGE_BRASS; num2 = OBJ_FORGE_D_STEELSLAB; per1 = UMIN(100, (10 * (lvl - 45))+10); per2 = 100-per1; } else if (lvl >= 31) { num1 = OBJ_FORGE_D_STEELSLAB; num2 = OBJ_FORGE_STEELSLAB; num3 = OBJ_FORGE_IRONSLAB; per1 = UMIN(100, (10 * (lvl - 31))+10); per2 = UMIN(100-per1, (10 * (lvl - 25))+10); per3 = 100-per1-per2; } else if (lvl >= 25) { num1 = OBJ_FORGE_STEELSLAB; num2 = OBJ_FORGE_IRONSLAB; per1 = UMIN(100, (10 * (lvl - 25))+10); per2 = 100-per1; } else if (lvl >= 15) { num1 = OBJ_FORGE_IRONSLAB; num2 = OBJ_FORGE_BRONZESLAB; per1 = UMIN(100, (10 * (lvl - 15))+10); per2 = 100-per1; } else if (lvl >= 5) { num1 = OBJ_FORGE_BRONZESLAB; num2 = OBJ_FORGE_COPPERSLAB; per1 = UMIN(100, (10 * (lvl - 5))+10); per2 = 100-per1; } else { num1 = OBJ_FORGE_COPPERSLAB; num2 = OBJ_FORGE_COPPERSLAB; per1 = 100; per2 = 100; } if (num == 1) return num1; if (num == 2) return num2; if (num == 3) return num3; if (num == 4) return per1; if (num == 5) return per2; if (num == 6) return per3; return num1; } void adjust_wildermob(CHAR_DATA *mob, int lvl, int wilderness) { OBJ_DATA *weapon; OBJ_DATA *rleg; OBJ_DATA *lleg; OBJ_DATA *rarm; OBJ_DATA *larm; OBJ_DATA *neck; OBJ_DATA *chest; OBJ_DATA *head; SLAB_DATA *firstslab; SLAB_DATA *secondslab; SLAB_DATA *thirdslab = NULL; int dam; int mult; int inc; int race; int num; int hp; int slab1; int slab2; int slab3; int per1; int per2; int per3; int x; weapon=rleg=lleg=rarm=larm=neck=chest=head=NULL; mult = 4750; inc = 750; for (x = 11; x <= lvl; x = x+10) { inc += 250; if (x <= 101) mult += inc; } mult += 250; inc += 250 * (lvl-x+10) /10; if (lvl <= 100) mult += inc; hp = lvl * mult / 2000; hp = number_range(hp * 90, hp * 110)/100; mob->hit = hp; mob->max_hit = mob->hit; mob->perm_agi = UMIN(100, 35+(lvl*4/10)); if (lvl > 100) mob->perm_agi += 5; if (lvl > 110) mob->perm_agi += 5; if (lvl > 120) mob->perm_agi += 5; if (lvl <= 8) { if (lvl <= 3) mob->armor = 1; else if (lvl <= 6) mob->armor = 2; else mob->armor = 3; } else { mob->armor = 3+(lvl*100/666); } mob->tohitbash = UMAX(1, number_range(mob->armor-1, mob->armor+1)); mob->tohitslash = UMAX(1, number_range(mob->armor-1, mob->armor+1)); mob->tohitstab = UMAX(1, number_range(mob->armor-1, mob->armor+1)); dam = 1+lvl/5; if (lvl >= 48) dam+=(lvl-38)/10; if (lvl >= 97) dam+=1; mob->pIndexData->damnodice = 1; mob->pIndexData->damsizedice = 1+number_range(dam/2, dam/5); mob->pIndexData->damplus = dam - ((1 + (mob->pIndexData->damnodice*mob->pIndexData->damsizedice))/2); if (lvl > 70) { dam = (lvl-70)/3; if (lvl > 100) dam += UMIN(20,(lvl-100)); if (lvl > 120) dam += (lvl-120)*2; mob->damaddlow = dam * 75 / 100; mob->damaddhi = dam * 125 / 100; } if (mob->race >= 0 && mob->race < MAX_RACE) mob->gold = (lvl * lvl /2.5) + (lvl*20); else mob->gold = 0; if (wilderness == 0) { mob->pIndexData->tohitbash = mob->tohitbash; mob->pIndexData->tohitslash = mob->tohitslash; mob->pIndexData->tohitstab = mob->tohitstab; mob->pIndexData->ac = mob->armor; mob->pIndexData->gold = mob->gold; mob->pIndexData->perm_agi = mob->perm_agi; mob->pIndexData->damaddlow = mob->damaddlow; mob->pIndexData->damaddhi = mob->damaddhi; if (lvl > 100) { mob->pIndexData->hitnodice = UMAX(1, mob->hit/200); mob->pIndexData->hitsizedice = UMAX(1, mob->hit/50); } else if (lvl > 70) { mob->pIndexData->hitnodice = UMAX(1, mob->hit/100); mob->pIndexData->hitsizedice = UMAX(1, mob->hit/25); } else if (lvl > 40) { mob->pIndexData->hitnodice = UMAX(1, mob->hit/50); mob->pIndexData->hitsizedice = UMAX(1, mob->hit/12); } else if (lvl > 20) { mob->pIndexData->hitnodice = UMAX(1, mob->hit/25); mob->pIndexData->hitsizedice = UMAX(1, mob->hit/10); } else { mob->pIndexData->hitnodice = UMAX(1, mob->hit/25); mob->pIndexData->hitsizedice = UMAX(5, mob->hit/8); } mob->pIndexData->hitplus = mob->hit - ((mob->pIndexData->hitnodice*mob->pIndexData->hitsizedice)/2); mob->pIndexData->perm_str = 13+(lvl/12)+number_range(-2, 2); mob->pIndexData->perm_dex = 13+(lvl/12)+number_range(-2, 2); mob->pIndexData->perm_wis = 13+(lvl/12)+number_range(-2, 2); mob->pIndexData->perm_int = 13+(lvl/12)+number_range(-2, 2); mob->pIndexData->perm_lck = 13+(lvl/12)+number_range(-2, 2); mob->pIndexData->perm_wis = 13+(lvl/12)+number_range(-2, 2); if (lvl <= 10) { mob->pIndexData->perm_int = 6; mob->pIndexData->perm_wis = 6; } } if (mob->race >= 0 && mob->race < MAX_RACE && wilderness == 1) { int load = 0; if (number_range(1, 5) == 1) weapon = create_object(get_obj_index(get_wilder_weapon(((lvl-1)/10+1),0)), 1); if (number_range(1, 5) == 1) { load = 1; num = number_range(1, 8); if (num <= 2) neck = create_object(get_obj_index(OBJ_FORGE_AVENTAIL), 1); else if (num <= 5) neck = create_object(get_obj_index(OBJ_FORGE_COIF), 1); else if (num <= 8) neck = create_object(get_obj_index(OBJ_FORGE_DOUBLE_COIF), 1); } if (number_range(1, 5) == 1) { load = 1; num = number_range(1, 10); if (num <= 4) head = create_object(get_obj_index(OBJ_FORGE_CABASSET), 1); else if (num <= 8) head = create_object(get_obj_index(OBJ_FORGE_CASQUE), 1); else if (num <= 10) head = create_object(get_obj_index(OBJ_FORGE_ARMET), 1); } if (number_range(1, 5) == 1) { load = 1; num = number_range(1, 8); if (num <= 3) { rarm = create_object(get_obj_index(OBJ_FORGE_CHAIN_GAUNTLET), 1); larm = create_object(get_obj_index(OBJ_FORGE_CHAIN_GAUNTLET), 1); } else if (num <= 6) { rarm = create_object(get_obj_index(OBJ_FORGE_RING_GAUNTLET), 1); larm = create_object(get_obj_index(OBJ_FORGE_RING_GAUNTLET), 1); } else if (num <= 8) { rarm = create_object(get_obj_index(OBJ_FORGE_GAUNTLET), 1); larm = create_object(get_obj_index(OBJ_FORGE_GAUNTLET), 1); } } if (number_range(1, 5) == 1) { load = 1; num = number_range(1, 8); if (num <= 3) { rleg = create_object(get_obj_index(OBJ_FORGE_CHAIN_GREAVE), 1); lleg = create_object(get_obj_index(OBJ_FORGE_CHAIN_GREAVE), 1); } else if (num <= 6) { rleg = create_object(get_obj_index(OBJ_FORGE_RING_GREAVE), 1); lleg = create_object(get_obj_index(OBJ_FORGE_RING_GREAVE), 1); } else if (num <= 8) { rleg = create_object(get_obj_index(OBJ_FORGE_GREAVE), 1); lleg = create_object(get_obj_index(OBJ_FORGE_GREAVE), 1); } } if (number_range(1, 5) == 1 || load == 0) { num = number_range(1, 10); if (num <= 4) chest = create_object(get_obj_index(OBJ_FORGE_CHAIN_MAIL), 1); else if (num <= 7) chest = create_object(get_obj_index(OBJ_FORGE_CHAIN_HAUBERK), 1); else if (num <= 9) chest = create_object(get_obj_index(OBJ_FORGE_RING_MAIL), 1); else if (num <= 10) chest = create_object(get_obj_index(OBJ_FORGE_DOUBLE_RING_MAIL), 1); } slab1 = get_slab_vnum(lvl, 1); slab2 = get_slab_vnum(lvl, 2); slab3 = get_slab_vnum(lvl, 3); per1 = get_slab_vnum(lvl, 4); per2 = get_slab_vnum(lvl, 5); per3 = get_slab_vnum(lvl, 6); for (firstslab = first_slab; firstslab; firstslab = firstslab->next) { if (firstslab->vnum == slab1) break; } for (secondslab = first_slab; secondslab; secondslab = secondslab->next) { if (secondslab->vnum == slab2) break; } if (slab3 > 0) { for (thirdslab = first_slab; thirdslab; thirdslab = thirdslab->next) { if (thirdslab->vnum == slab3) break; } } if (!firstslab) { bug("Adjust_Wildermob: %d is not a valid Slab", slab1); } else if (!secondslab) { bug("Adjust_Wildermob: %d is not a valid Slab", slab2); } else if (slab3 > 0 && !thirdslab) { bug("Adjust_Wildermob: %d is not a valid Slab", slab3); } else { race = mob->race; if (per3 > 0) { per3 = per1+per2; } if (mob->race < 0 || mob->race >= MAX_RACE) mob->race = 0; //Needs a valid race if (weapon) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, weapon, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, weapon, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, weapon, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, weapon, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, weapon, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } if (neck) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, neck, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, neck, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, neck, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, neck, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, neck, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } if (head) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, head, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, head, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, head, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, head, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, head, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } if (rarm) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, rarm, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, rarm, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, rarm, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, rarm, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, rarm, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } if (larm) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, larm, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, larm, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, larm, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, larm, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, larm, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } if (rleg) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, rleg, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, rleg, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, rleg, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, rleg, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, rleg, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } if (lleg) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, lleg, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, lleg, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, lleg, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, lleg, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, lleg, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } if (chest) { if (per3 <= 0) { if (number_range(1, 100) <= per1) alter_forge_obj(mob, chest, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else alter_forge_obj(mob, chest, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } else { num = number_range(1, 100); if (num <= per1) alter_forge_obj(mob, chest, create_object(get_obj_index(firstslab->vnum), 1), firstslab); else if (num > per3) alter_forge_obj(mob, chest, create_object(get_obj_index(thirdslab->vnum), 1), thirdslab); else alter_forge_obj(mob, chest, create_object(get_obj_index(secondslab->vnum), 1), secondslab); } } mob->race = race; } if (rleg) { obj_to_char(rleg, mob); equip_char(mob, rleg, WEAR_LEG_R); } if (lleg) { obj_to_char(lleg, mob); equip_char(mob, lleg, WEAR_LEG_L); } if (larm) { obj_to_char(larm, mob); equip_char(mob, larm, WEAR_ARM_L); } if (rarm) { obj_to_char(rarm, mob); equip_char(mob, rarm, WEAR_ARM_R); } if (chest) { obj_to_char(chest, mob); equip_char(mob, chest, WEAR_BODY); } if (head) { obj_to_char(head, mob); equip_char(mob, head, WEAR_HEAD); } if (neck) { obj_to_char(neck, mob); equip_char(mob, neck, WEAR_NECK); } if (weapon) { obj_to_char(weapon, mob); equip_char(mob, weapon, WEAR_WIELD); } } } bool can_see_target(CHAR_DATA * ch, MOB_INDEX_DATA *mob) { CHAR_DATA *fch; if (can_see_index(mob, ch)) { return TRUE; } else { for (fch = ch->in_room->first_person; fch; fch = fch->next_in_room) { if (fch != ch && !IS_NPC(fch) && fch->master == ch) { if (can_see_index(mob, fch)) return TRUE; } } } return FALSE; } bool load_mapmobiles(CHAR_DATA * ch, int ox, int oy) { int vnum; int vnumlist[MAX_MOB_HOLDER]; int x = 0; int xload = 0; //number actually found int y = 0; int vn; int numload; int goload; int lvl; int cnt = 0; int en = sect_show[(int)map_sector[ch->map][ox][oy]].encounter; char moblist[MSL]; char buf[MSL]; CHAR_DATA *victim; CHAR_DATA *fch; MOB_INDEX_DATA *mob; lvl = find_mob_diff(ch->coord->x, ch->coord->y, ch->map); for (vnum = OVERLAND_LOW_MOB; vnum < OVERLAND_HI_MOB; vnum++) { if ((mob = get_mob_index(vnum)) != NULL) { if (mob->m1 >= 1 && mob->m1 == lvl/10+1) { if (map_sector[ch->map][ch->coord->x][ch->coord->y] == SECT_UNDERWATER || map_sector[ch->map][ch->coord->x][ch->coord->y] == SECT_WATER_NOSWIM || map_sector[ch->map][ch->coord->x][ch->coord->y] == SECT_OCEAN) { if (!IS_ACT_FLAG(mob, ACT_PROTOTYPE) && !IS_ACT_FLAG(mob, ACT_SENTINEL) && !IS_ACT_FLAG(mob, ACT_TRAINER) && !IS_ACT_FLAG(mob, ACT_MOVEMAP) && IS_ACT_FLAG(mob, ACT_WATERMOB)) { if (can_see_target(ch, mob)) //can the target party be seen, no sense loading mobs if they cannot { vnumlist[x] = mob->vnum; x++; xload++; } else { xload++; } } } else { if (!IS_ACT_FLAG(mob, ACT_PROTOTYPE) && !IS_ACT_FLAG(mob, ACT_SENTINEL) && !IS_ACT_FLAG(mob, ACT_TRAINER) && !IS_ACT_FLAG(mob, ACT_MOVEMAP)) { if (map_sector[ch->map][ch->coord->x][ch->coord->y] == SECT_WATER_SWIM || map_sector[ch->map][ch->coord->x][ch->coord->y] == SECT_RIVER) { if (can_see_target(ch, mob)) //can the target party be seen, no sense loading mobs if they cannot { vnumlist[x] = mob->vnum; x++; xload++; } else { xload++; } } else { if (!IS_ACT_FLAG(mob, ACT_WATERMOB)) { if (can_see_target(ch, mob)) //can the target party be seen, no sense loading mobs if they cannot { vnumlist[x] = mob->vnum; x++; xload++; } else { xload++; } } } } } } } } if (xload == 0) { bug("load_mapmobiles: Not enough mobs for the level of %d", lvl); return FALSE; } if (x <= 0) //mobiles in this part cannot see our targets return FALSE; //Might as well add a bit more difficulty if there are larger groups. cnt = 1; for (fch = ch->in_room->first_person; fch; fch = fch->next_in_room) { if (fch != ch && !IS_NPC(fch) && fch->master == ch) { if (fch->coord->x < 1 || fch->coord->y < 1 || fch->map < 0) continue; if (!IS_WITHIN(fch->coord->x, 8) || !IS_WITHIN(fch->coord->y, 8) || ch->map != fch->map) continue; cnt++; if (cnt > 3) en++; if (cnt > 5) en++; } } numload = number_range(en - 1, en); numload = UMAX(1, numload); strcpy(moblist, ""); for (goload = 1; goload <= numload; goload++) { vn = number_range(0, x-1); mob = get_mob_index(vnumlist[vn]); if (!mob) { bug("load_mapmobiles: Null mob vnum %d", vn); continue; } victim = create_mobile(mob); adjust_wildermob(victim, lvl, 1); char_to_room(victim, ch->in_room); victim->coord->x = number_range(-4, 4)+ch->coord->x; victim->coord->y = number_range(-4, 4)+ch->coord->y; victim->map = ch->map; SET_ONMAP_FLAG(victim); sprintf(buf, "%s\n\r", victim->short_descr); cnt = 0; if (goload == 1) sprintf(moblist, buf); else strcat(moblist, buf); for (fch = ch->in_room->first_person; fch; fch = fch->next_in_room) { if (fch != ch && !IS_NPC(fch) && fch->master == ch) { if (fch->coord->x < 1 || fch->coord->y < 1 || fch->map < 0) continue; if (!IS_WITHIN(fch->coord->x, 8) || !IS_WITHIN(fch->coord->y, 8) || ch->map != fch->map) continue; cnt++; } } cnt++; //add character cnt = number_range(1, cnt); y = 1; if (cnt != 1) { for (fch = ch->in_room->first_person; fch; fch = fch->next_in_room) { if (fch != ch && !IS_NPC(fch) && fch->master == ch) { if (fch->coord->x < 1 || fch->coord->y < 1 || fch->map < 0) continue; if (!IS_WITHIN(fch->coord->x, 8) || !IS_WITHIN(fch->coord->y, 8) || ch->map != fch->map) continue; y++; if (y == cnt) break; } } } else { fch = ch; } if (can_see_map(victim, fch) || fch->level >= LEVEL_IMMORTAL) //make sure they target the visible player, hate for them to cheat this way :-) start_hunting(victim, fch); else find_next_hunt(victim, 1); } act(AT_CYAN, "\n\rYour enemies are.\n\r-------------------------------------", ch, NULL, NULL, TO_CHAR); send_to_char(moblist, ch); for (fch = ch->in_room->first_person; fch; fch = fch->next_in_room) { if (fch != ch && (fch->master == ch || fch->riding == ch) && (fch->position == POS_STANDING || fch->position == POS_MOUNTED || fch->position == POS_RIDING)) { if (fch->coord->x > -1 || fch->coord->y > -1 || fch->map > -1) continue; if (!IS_WITHIN(fch->coord->x, 8) || !IS_WITHIN(fch->coord->y, 8) || ch->map != fch->map) continue; send_to_char("Your party is being attacked, prepare for battle.\n\r", ch); act(AT_CYAN, "\n\rYour enemies are.\n\r-------------------------------------", fch, NULL, NULL, TO_CHAR); send_to_char(moblist, fch); } } return TRUE; } bool map_battle(CHAR_DATA * ch, int ox, int oy, int map) { sh_int en = sect_show[(int)map_sector[ch->map][ox][oy]].encounter; sh_int gofight = 0; if (get_trust(ch) >= LEVEL_IMMORTAL && !xIS_SET(ch->act, PLR_MMOBILES)) return FALSE; if (IS_NPC(ch)) return FALSE; if (wIS_SET(ch, ROOM_NO_MOB)) return FALSE; if (map_sector[ch->map][ox][oy] == SECT_ROAD) en = 0; ch->fcounter++; if (ch->fcounter >= 11 && ch->fcounter <= 15) { if (number_range(1, 100) <= 1) gofight = 1; } if (ch->fcounter > 15 && ch->fcounter <= 20) { if (number_range(1, 100) <= UMAX(1, en - 1)) gofight = 1; } if (ch->fcounter > 20 && ch->fcounter <= 30) { if (number_range(1, 100) <= en + 1) gofight = 1; } if (ch->fcounter > 30 && ch->fcounter <= 35) { if (number_range(1, 100) <= en + 2) gofight = 1; } if (ch->fcounter >= 36 && ch->fcounter <= 40) { if (number_range(1, 100) <= en + 4) gofight = 1; } if (ch->fcounter > 40) { if (number_range(1, 100) <= en + 6) gofight = 1; } if (gofight == 1) { ch->fcounter = 0; load_mapmobiles(ch, ox, oy); return TRUE; } return FALSE; } int get_wilderness_hunt_cost(CHAR_DATA *ch, int x, int y) { int move; move = sect_show[(int)map_sector[ch->map][x][y]].move; move = number_range(move*.08, move*.12); if (move < 1) move = 1; move += number_range(1, 2); return move; } int ship_is_full(SHIP_DATA *ship, int extra) { int capacity; if (ship->size == 1) capacity = 1; else if (ship->size == 2) capacity = 3; else if (ship->size == 3) capacity = 5; else if (ship->size == 4) capacity = 10; else if (ship->size == 5) capacity = 20; else if (ship->size == 6) capacity = 30; else if (ship->size == 7) capacity = 50; else if (ship->size == 8) capacity = 75; else if (ship->size == 9) capacity = 100; else capacity = 150; if (ship->occupants + extra >= capacity) return 1; else return 0; } void do_entership(CHAR_DATA *ch, char *argument) { int x; int y; int ox; int oy; CHAR_DATA *fch; SHIP_DATA *ship; CHAR_DATA *nextinroom; int cnt = 0; if (!IN_WILDERNESS(ch)) { send_to_char("You can only enter a ship out in the wilderness.\n\r", ch); return; } if (ch->ship) { send_to_char("You are already aboard a ship.\n\r", ch); return; } if (ch->rider || ch->mount) cnt = 1; for (x = ch->coord->x-1; x <= ch->coord->x+1; x++) { for (y = ch->coord->y-1; y <= ch->coord->y+1; y++) { if ((ship = is_ship_sector(x, y, ch->map)) != NULL) { if (ship_is_full(ship, cnt)) { send_to_char("The ship's is filled to its capacity, you cannot enter it.\n\r", ch); return; } act(AT_WHITE, "$n quickly boards the ship that is anchored in the water.", ch, NULL, NULL, TO_CANSEE); ch->ship = ship; ox = ch->coord->x; oy = ch->coord->y; ch->coord->x = ship->x; ch->coord->y = ship->y; LINK(ch, ship->first_char, ship->last_char, next_ship, prev_ship); ship->occupants++; act(AT_WHITE, "$n joins you on the ship.", ch, NULL, NULL, TO_CANSEE); act(AT_WHITE, "You quickly board the ship that is anchored in the water.", ch, NULL, NULL, TO_CHAR); update_objects(ch, ch->coord->x, ch->coord->y, ch->map); if (ch->rider) { act(AT_ACTION, "You board the ship along with $N", ch->rider, NULL, ch, TO_CHAR); act(AT_WHITE, "$n quickly boards the ship on the back of $N.", ch->rider, NULL, ch, TO_CANSEE); ch->rider->ship = ship; ch->rider->coord->x = ship->x; ch->rider->coord->y = ship->y; LINK(ch->rider, ship->first_char, ship->last_char, next_ship, prev_ship); ship->occupants++; act(AT_WHITE, "$n joins you on the ship.", ch->rider, NULL, NULL, TO_CANSEE); act(AT_WHITE, "$N carries you into the ship anchored in the water.", ch->rider, NULL, ch, TO_CHAR); update_objects(ch->rider, ch->rider->coord->x, ch->rider->coord->y, ch->rider->map); do_look(ch->rider, "auto"); } for (fch = ch->in_room->first_person; fch; fch = nextinroom) { nextinroom = fch->next_in_room; if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->coord->x == ox && fch->coord->y == oy && fch->map == ch->map) { act(AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR); do_entership(fch, ""); } } do_look(ch, "auto"); return; } } } send_to_char("There is no ship anchored in the water for you to board.\n\r", ch); return; } void do_leaveship(CHAR_DATA *ch, char *argument) { int x; int y; int tx; int ty; int ox; int oy; CHAR_DATA *fch; SHIP_DATA *ship; CHAR_DATA *nextinroom; if (!IN_WILDERNESS(ch)) { send_to_char("You can only enter a ship out in the wilderness.\n\r", ch); return; } if (!ch->ship) { send_to_char("You are not aboard a ship.\n\r", ch); return; } for (x = ch->coord->x-7; x <= ch->coord->x+7; x++) { for (y = ch->coord->y-7; y <= ch->coord->y+7; y++) { if ((ship = is_ship_sector(x, y, ch->map)) != NULL) { for (tx = x-1; tx <= x+1; tx++) { for (ty = y-1; ty <= y+1; ty++) { if (sect_show[(int)map_sector[ch->map][tx][ty]].canpass) { act(AT_WHITE, "$n leaves the ship for dry land.", ch, NULL, NULL, TO_CANSEE); ox = ch->coord->x; oy = ch->coord->y; ch->coord->x = tx; ch->coord->y = ty; UNLINK(ch, ch->ship->first_char, ch->ship->last_char, next_ship, prev_ship); ch->ship->occupants--; ch->ship = NULL; act(AT_WHITE, "$n arrives from the ship that is anchored in the water.", ch, NULL, NULL, TO_CANSEE); act(AT_WHITE, "You leave the ship for dry land.", ch, NULL, NULL, TO_CHAR); update_objects(ch, ch->coord->x, ch->coord->y, ch->map); if (ch->rider) { act(AT_ACTION, "You leave the ship along with $N", ch->rider, NULL, ch, TO_CHAR); act(AT_WHITE, "$n, on the back of $N, leaves the ship for dry land.", ch->rider, NULL, ch, TO_CANSEE); ch->coord->x = tx; ch->coord->y = ty; UNLINK(ch, ch->ship->first_char, ch->ship->last_char, next_ship, prev_ship); ch->ship->occupants--; ch->ship = NULL; act(AT_WHITE, "$n, on the back of $N, arrives from the ship that is anchored in the water.", ch->rider, NULL, ch, TO_CANSEE); act(AT_WHITE, "$N carries you off the ship.", ch->rider, NULL, ch, TO_CHAR); update_objects(ch->rider, ch->rider->coord->x, ch->rider->coord->y, ch->rider->map); do_look(ch->rider, "auto"); } for (fch = ch->in_room->first_person; fch; fch = nextinroom) { nextinroom = fch->next_in_room; if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->coord->x == ox && fch->coord->y == oy && fch->map == ch->map) { act(AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR); do_leaveship(fch, ""); } } do_look(ch, "auto"); return; } } } } } } send_to_char("There is no dry land near your ship.\n\r", ch); return; } void process_exit(CHAR_DATA * ch, sh_int map, sh_int x, sh_int y, sh_int dir, sh_int first) { char buf[MSL]; sh_int sector = map_sector[map][x][y]; int maxx, maxy, ht; int nosnow = -1; int move; char *txt; char *dtxt; bool drunk = FALSE; CHAR_DATA *fch; CHAR_DATA *gmob; CHAR_DATA *nextinroom; ROOM_INDEX_DATA *from_room; WBLOCK_DATA *wblock; OBJ_DATA *boat; OBJ_DATA *climb = NULL; int chars = 0, count = 0; int fx, fy, fmap; int level; from_room = ch->in_room; ht = -1; fx = ch->coord->x; fy = ch->coord->y; fmap = ch->map; if (!IS_NPC(ch)) { if (IS_DRUNK(ch, 2) && (ch->position != POS_SHOVE) && (ch->position != POS_DRAG)) drunk = TRUE; } if (ch->on != NULL) { act(AT_PLAIN, "Need to get off of $p before moving on.", ch, ch->on, NULL, TO_CHAR); return; } if (ch->con_rleg == -1 && ch->con_lleg == -1 && ch->position != POS_SHOVE && ch->position != POS_DRAG) { send_to_char("You cannot move without any legs.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_WEB) || IS_AFFECTED(ch, AFF_SNARE)) { send_to_char("You are currently bound to this spot and cannot move.\n\r", ch); return; } if (ch->position == POS_RIDING) { send_to_char("You cannot move when you are on someone's back.\n\r", ch); return; } if (ch->ship) { send_to_char("You cannot move around on a ship. To leave the ship type leaveship.\n\r", ch); return; } if (sector == SECT_QEXIT) { ROOM_INDEX_DATA *toroom = NULL; if (check_npc(ch)) return; if (!ch->pcdata->quest) { send_to_char("You have to be on a quest to use this exit.\n\r", ch); return; } if (ch->rider) { send_to_char("You need to lose your rider before entering a quest.\n\r", ch); return; } if (x != ch->pcdata->quest->x || y != ch->pcdata->quest->y || map != ch->pcdata->quest->map) { send_to_char("This is not the exit to your quest.\n\r", ch); return; } if ((toroom = get_room_index(ch->pcdata->quest->questarea->low_r_vnum)) == NULL) { bug("Target vnum %d for map quest exit does not exist!", ch->pcdata->quest->questarea->low_r_vnum); send_to_char("Ooops. Something bad happened. Contact the immortals ASAP.\n\r", ch); return; } leave_map(ch, toroom, dir, 1); if (ch->mount) leave_map(ch->mount, toroom, dir, 1); for (fch = from_room->first_person; fch; fch = fch->next_in_room) chars++; for (fch = from_room->first_person; fch && (count < chars); fch = nextinroom) { nextinroom = fch->next_in_room; count++; if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->coord->x == fx && fch->coord->y == fy && fch->map == fmap && !IS_NPC(fch) && fch->pcdata->quest && fch->pcdata->quest == ch->pcdata->quest) { act(AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR); leave_map(fch, toroom, dir, 1); } } ch->pcdata->quest->traveltime = -1; return; } if (sector == SECT_EXIT) { ENTRANCE_DATA *enter; ROOM_INDEX_DATA *toroom = NULL; enter = check_entrance(ch, map, x, y); //military does not need to be in areas...if you so choose to remove, unit checks are done in the //wilderness room only, so you will need to fix that if (IS_NPC(ch) && xIS_SET(ch->act, ACT_MILITARY)) return; //check the mount of a military mob, don't want it roaming off... if (xIS_SET(ch->act, ACT_MOUNTABLE)) { for (fch = first_char; fch; fch = fch->next) { if (fch->mount == ch) { if (IS_NPC(fch) && xIS_SET(fch->act, ACT_MILITARY)) return; } } } if (enter != NULL && !IS_PLR_FLAG(ch, PLR_MAPEDIT)) { if (enter->tomap != -1) /* Means exit goes to another map */ { enter_map(ch, enter->there->x, enter->there->y, enter->tomap); if (ch->mount) enter_map(ch->mount, enter->there->x, enter->there->y, enter->tomap); if (ch->rider) enter_map(ch->rider, enter->there->x, enter->there->y, enter->tomap); for (fch = from_room->first_person; fch; fch = fch->next_in_room) chars++; for (fch = from_room->first_person; fch && (count < chars); fch = nextinroom) { nextinroom = fch->next_in_room; count++; if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->coord->x == fx && fch->coord->y == fy && fch->map == fmap) { act(AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR); enter_map(fch, enter->there->x, enter->there->y, enter->tomap); } } return; } if ((toroom = get_room_index(enter->vnum)) == NULL) { bug("Target vnum %d for map exit does not exist!", enter->vnum); send_to_char("Ooops. Something bad happened. Contact the immortals ASAP.\n\r", ch); return; } leave_map(ch, toroom, dir, 0); if (ch->mount) leave_map(ch->mount, toroom, dir, 0); if (ch->rider) leave_map(ch->rider, toroom, dir, 0); for (fch = from_room->first_person; fch; fch = fch->next_in_room) chars++; for (fch = from_room->first_person; fch && (count < chars); fch = nextinroom) { nextinroom = fch->next_in_room; count++; if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->coord->x == fx && fch->coord->y == fy && fch->map == fmap) { act(AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR); leave_map(fch, toroom, dir, 0); } } return; } if (enter != NULL && IS_PLR_FLAG(ch, PLR_MAPEDIT)) { delete_entrance(enter); map_sector[ch->map][x][y] = ch->pcdata->secedit; send_to_char("&RMap exit deleted.\n\r", ch); } } if (x == global_x[0] && y == global_y[0]) { act(AT_ACTION, "You hit a transporter and are whisped away.", ch, NULL, ch->mount, TO_CHAR); ch->coord->x = 205; ch->coord->y = 460; if (ch->mount) { ch->mount->coord->x = 205; ch->mount->coord->y = 460; } if (ch->rider) { ch->rider->coord->x = 205; ch->rider->coord->y = 460; } do_look(ch, "auto"); if (ch->rider) do_look(ch->rider, "auto"); for (fch = from_room->first_person; fch; fch = nextinroom) { nextinroom = fch->next_in_room; if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && (fch->position == POS_STANDING || fch->position == POS_MOUNTED) && fch->coord->x == fx && fch->coord->y == fy && fch->map == map) { act(AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR); if (IS_NPC(fch)) { fch->coord->x = 205; fch->coord->y = 460; update_objects(fch, x, y, map); } else { process_exit(fch, map, x, y, dir, 1); } } } return; } if (!sect_show[sector].canpass && !IS_IMMORTAL(ch)) { ch_printf(ch, "%s\n\r", impass_message[sector]); return; } maxx = MAX_X; maxy = MAX_Y; switch (dir) { case DIR_NORTH: if (y == 0) { send_to_char("You cannot go any further north!\n\r", ch); return; } break; case DIR_EAST: if (x == maxx + 1) { send_to_char("You cannot go any further east!\n\r", ch); return; } break; case DIR_SOUTH: if (y == maxy + 1) { send_to_char("You cannot go any further south!\n\r", ch); return; } break; case DIR_WEST: if (x == 0) { send_to_char("You cannot go any further west!\n\r", ch); return; } break; case DIR_NORTHEAST: if (x == maxx + 1 || y == 0) { send_to_char("You cannot go any further northeast!\n\r", ch); return; } break; case DIR_NORTHWEST: if (x == 0 || y == 0) { send_to_char("You cannot go any further northwest!\n\r", ch); return; } break; case DIR_SOUTHEAST: if (x == maxx + 1 || y == maxy + 1) { send_to_char("You cannot go any further southeast!\n\r", ch); return; } break; case DIR_SOUTHWEST: if (x == 0 || y == maxy + 1) { send_to_char("You cannot go any further southwest!\n\r", ch); return; } break; } if (IS_MOUNTAIN(sect_show[sector].sector)) { if (ch->mount) { send_to_char("You cannot hope to climb a mountain while mounted!\n\r", ch); return; } } if (IS_MOUNTAIN(sect_show[sector].sector) && get_trust(ch) < LEVEL_IMMORTAL) { if (MASTERED(ch, gsn_mountain_climb) < 1) { if ((climb = get_objtype(ch, ITEM_MCLIMB)) == NULL) { send_to_char("A huge, unclimbable mountain blocks your path in that direction.\n\r", ch); return; } } } if (sect_show[sector].sector == SECT_AIR) { if (ch->mount && !IS_AFFECTED(ch->mount, AFF_FLYING)) { send_to_char("Your mount can't fly.\n\r", ch); return; } if (!ch->mount && !IS_AFFECTED(ch, AFF_FLYING)) { send_to_char("You'd need to fly to go there.\n\r", ch); return; } } if (IS_NOSWIM(sect_show[sector].sector)) { if ((ch->mount && !IS_FLOATING(ch->mount)) || !IS_FLOATING(ch)) { /* * Look for a boat. * We can use the boat obj for a more detailed description. */ if ((boat = get_objtype(ch, ITEM_BOAT)) != NULL) { if (drunk) txt = "paddles unevenly"; else txt = "paddles"; } else if (!IS_NPC(ch) && ch->pcdata->learned[gsn_swimming] >= 0) { if (ch->mount) { send_to_char("You need to leave your mount behind if you wish to swim.\n\r", ch); return; } else { level = POINT_LEVEL(GET_POINTS(ch, gsn_swimming, 0, 1), GET_MASTERY(ch, gsn_swimming, 0, 1)); if (number_range(1, 100) > 40+level) { send_to_char("You struggle to move forward.\n\r", ch); WAIT_STATE(ch, number_range(3, 6)); learn_from_failure(ch, gsn_swimming, NULL); return; } else { if (drunk) txt = "swims unevenly"; else txt = "swims"; learn_from_success(ch, gsn_swimming, NULL); } } } else { if (ch->mount) send_to_char("Your mount would drown!\n\r", ch); else send_to_char("You'd need a boat to go there.\n\r", ch); return; } } } if (IS_NPC(ch) && (xIS_SET(ch->act, ACT_MILITARY) || xIS_SET(ch->act, ACT_KINGDOMMOB) || xIS_SET(ch->act, ACT_MOUNTSAVE))) ht = ch->m4; if (!IS_NPC(ch)) ht = ch->pcdata->hometown; for (gmob = ch->in_room->first_person; gmob; gmob = gmob->next_in_room) { if (!IS_NPC(ch) && ((xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NOPASS) && in_same_room(ch, gmob) && gmob->m4 != ht) || (xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NOCLOAK) && get_wear_cloak(ch) && in_same_room(ch, gmob) && gmob->m4 != ht) || (xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NOHOOD) && get_wear_hidden_cloak(ch) && in_same_room(ch, gmob) && gmob->m4 != ht) || (xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NEEDINTRO) && !str_cmp(ch->name, PERS_KINGDOM(ch, gmob->m4)) && in_same_room(ch, gmob) && gmob->m4 != ht))) { if (!IS_NPC(ch) && dir != rev_dir[ch->pcdata->mapdir]) { send_to_char("\n\r", ch); sprintf(buf, "%s I gave you a chance, time to die now.", ch->name); do_tell(gmob, buf); one_hit(gmob, ch, TYPE_UNDEFINED, LM_BODY); return; } } } if (ch->mount) { switch (ch->mount->position) { case POS_DEAD: send_to_char("Your mount is dead!\n\r", ch); return; break; case POS_MORTAL: case POS_INCAP: send_to_char("Your mount is hurt far too badly to move.\n\r", ch); return; break; case POS_STUNNED: send_to_char("Your mount is too stunned to do that.\n\r", ch); return; break; case POS_SLEEPING: send_to_char("Your mount is sleeping.\n\r", ch); return; break; case POS_RESTING: send_to_char("Your mount is resting.\n\r", ch); return; break; case POS_SITTING: send_to_char("Your mount is sitting down.\n\r", ch); return; break; default: break; } if (!IS_FLOATING(ch->mount)) move = sect_show[(int)map_sector[ch->map][get_x(ch->coord->x, dir)][get_y(ch->coord->y, dir)]].move; else move = 5; move = calculate_movement_cost(move, ch->mount); //Takes the normal move and calculates cost based on the stats if (ch->mount->move < move) { send_to_char("Your mount is too exhausted.\n\r", ch); return; } } else { if (!IS_FLOATING(ch) || sect_show[sector].sector == SECT_MOUNTAIN) move = encumbrance(ch, sect_show[(int)map_sector[ch->map][get_x(ch->coord->x, dir)][get_y(ch->coord->y, dir)]].move); else move = 5; if (IS_MOUNTAIN(sect_show[sector].sector)) { if (climb) { if (climb->value[0] == 1) move *= 5; if (climb->value[0] == 2) move *= 4; if (climb->value[0] == 3) move *= 2; } else if (MASTERED(ch, gsn_mountain_climb) >= 1) { int mlevel; mlevel = POINT_LEVEL(LEARNED(ch, gsn_mountain_climb), MASTERED(ch, gsn_mountain_climb)); move *= (500-(UMIN(400, mlevel*5))) / 100; learn_from_success(ch, gsn_mountain_climb, NULL); } } move = calculate_movement_cost(move, ch); //Takes the normal move and calculates cost based on the stats if (ch->move < move) { send_to_char("You are too exhausted.\n\r", ch); return; } } nosnow = 0; if (NO_SNOW(map_sector[ch->map][get_x(ch->coord->x, dir)][get_y(ch->coord->y, dir)])) nosnow = 1; if (weather_sector[ch->map][ch->coord->x][ch->coord->y] >= 10 && !nosnow) { if (ch->mount) { if (!IS_FLOATING(ch->mount)) move *= 2.5; if (ch->mount->move < move) { send_to_char("Your mount is too exhausted.\n\r", ch); return; } } else { if (!IS_FLOATING(ch)) move *= 3; if (ch->move < move) { send_to_char("You are too exhausted.\n\r", ch); return; } } } if (ch->mount) WAIT_STATE(ch, movement_lag(ch->mount, move/5)); else WAIT_STATE(ch, movement_lag(ch, move/5)); if (ch->mount) { update_movement_points(ch->mount, move); ch->mount->move -= move; } else { update_movement_points(ch, move); ch->move -= move; } if (ch->mount) { if (IS_AFFECTED(ch->mount, AFF_FLOATING)) txt = "floats"; else if (IS_AFFECTED(ch->mount, AFF_FLYING)) txt = "flies"; else txt = "rides"; } else if (IS_AFFECTED(ch, AFF_FLOATING)) { if (drunk) txt = "floats unsteadily"; else txt = "floats"; } else if (IS_AFFECTED(ch, AFF_FLYING)) { if (drunk) txt = "flies shakily"; else txt = "flies"; } else if (ch->position == POS_SHOVE) txt = "is shoved"; else if (ch->position == POS_DRAG) txt = "is dragged"; else { if (drunk) txt = "stumbles drunkenly"; else { if (!ch->movement || (ch->movement && ch->movement[0] == '\0')) txt = "leaves"; else txt = ch->movement; } } if (!IS_AFFECTED(ch, AFF_SNEAK) && (IS_NPC(ch) || !xIS_SET(ch->act, PLR_WIZINVIS))) { if (ch->mount) { sprintf(buf, "$n %s %s upon $N.", txt, dir_name[dir]); act(AT_ACTION, buf, ch, NULL, ch->mount, TO_NOTVICT); } else { if (!IS_NPC(ch) && ch->rider) { sprintf(buf, "$n %s %s with $N on $s back.", txt, dir_name[dir]); act(AT_ACTION, buf, ch, NULL, ch->rider, TO_ROOM); } else { sprintf(buf, "$n %s $T.", txt); act(AT_ACTION, buf, ch, NULL, dir_name[dir], TO_ROOM); } } } if (!IS_NPC(ch)) ch->pcdata->mapdir = dir; ch->coord->x = x; ch->coord->y = y; update_objects(ch, x, y, map); /* Take away Hide */ if (IS_AFFECTED(ch, AFF_HIDE)) { if (number_range(1, 100) > check_hide_move(ch, map_sector[ch->map][x][y], ch->in_room)) { xREMOVE_BIT(ch->affected_by, AFF_HIDE); act(AT_RED, "$n quickly appears from the shadows.", ch, NULL, NULL, TO_ROOM); } } if (IS_AFFECTED(ch, AFF_STALK)) { if (!check_stalk_move(ch, ch->in_room)) { affect_strip(ch, gsn_stalk); act(AT_RED, "$n attemps to stalk silently into the room but fails!.", ch, NULL, NULL, TO_ROOM); } } // WAIT_STATE( ch, move ); if (ch->mount) { if (IS_AFFECTED(ch->mount, AFF_FLOATING)) txt = "floats in"; else if (IS_AFFECTED(ch->mount, AFF_FLYING)) txt = "flies in"; else txt = "rides in"; } else { if (IS_AFFECTED(ch, AFF_FLOATING)) { if (drunk) txt = "floats in unsteadily"; else txt = "floats in"; } else if (IS_AFFECTED(ch, AFF_FLYING)) { if (drunk) txt = "flies in shakily"; else txt = "flies in"; } else if (ch->position == POS_SHOVE) txt = "is shoved in"; else if (ch->position == POS_DRAG) txt = "is dragged in"; else { if (drunk) txt = "stumbles drunkenly in"; else { if (!ch->movement || (ch->movement && ch->movement[0] == '\0')) txt = "arrives"; else txt = ch->movement; } } } dtxt = rev_exit(dir); if (!IS_AFFECTED(ch, AFF_SNEAK) && (IS_NPC(ch) || !xIS_SET(ch->act, PLR_WIZINVIS))) { if ( ch->mount ) { sprintf( buf, "$n %s from %s upon $N.", txt, dtxt ); act( AT_ACTION, buf, ch, NULL, ch->mount, TO_ROOM ); } else { if (!IS_NPC(ch) && ch->rider) { if (!ch->movement || (ch->movement && ch->movement[0] == '\0')) sprintf( buf, "$n %s from %s with $N on $s back.", txt, dtxt ); else sprintf( buf, "$n %s in from %s with $N on $s back.", txt, dtxt ); act( AT_ACTION, buf, ch, NULL, ch->rider, TO_ROOM ); } else { if (!ch->movement || (ch->movement && ch->movement[0] == '\0')) sprintf( buf, "$n %s from %s.", txt, dtxt ); else sprintf( buf, "$n %s in from %s.", txt, dtxt ); act( AT_ACTION, buf, ch, NULL, NULL, TO_ROOM ); } } } if (IS_AFFECTED(ch, AFF_SNEAK)) learn_from_success(ch, gsn_sneak, NULL); //Update rider so they both see eachother... if (ch->rider) { ch->rider->coord->x = x; ch->rider->coord->y = y; update_objects(ch->rider, x, y, map); } do_look(ch, "auto"); if (ch->rider) do_look(ch->rider, "auto"); for (fch = from_room->first_person; fch; fch = nextinroom) { nextinroom = fch->next_in_room; if (fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && (fch->position == POS_STANDING || fch->position == POS_MOUNTED) && fch->coord->x == fx && fch->coord->y == fy && fch->map == map) { act(AT_ACTION, "You follow $N.", fch, NULL, ch, TO_CHAR); if (IS_NPC(fch)) { fch->coord->x = x; fch->coord->y = y; update_objects(fch, x, y, map); } else { process_exit(fch, map, x, y, dir, 1); } } } mprog_entry_trigger(ch); if (char_died(ch)) return; rprog_enter_trigger(ch); if (char_died(ch)) return; mprog_greet_trigger(ch); if (char_died(ch)) return; oprog_greet_trigger(ch); if (char_died(ch)) return; for (wblock = first_wblock; wblock; wblock = wblock->next) { if (ch->coord->x <= wblock->endx && ch->coord->x >= wblock->stx && ch->coord->y <= wblock->endy && ch->coord->y >= wblock->sty && ch->map == wblock->map && !IS_NPC(ch)) { WINFO_DATA *winfo; if (!wblock->first_player) { CREATE(winfo, WINFO_DATA, 1); winfo->pid = ch->pcdata->pid; winfo->time = time(0); LINK(winfo, wblock->first_player, wblock->last_player, next, prev); } else { for (winfo = wblock->first_player; winfo; winfo = winfo->next) { if (winfo->pid == ch->pcdata->pid) { if (time(0) - winfo->time > 7200) //2 hours real time winfo->time = time(0); break; } } if (!winfo) { CREATE(winfo, WINFO_DATA, 1); winfo->pid = ch->pcdata->pid; winfo->time = time(0); LINK(winfo, wblock->first_player, wblock->last_player, next, prev); } } } } if (first == 0) map_battle(ch, x, y, map); for (gmob = ch->in_room->first_person; gmob; gmob = gmob->next_in_room) { if (!IS_NPC(ch) && !IS_NPC(gmob)) { INTRO_DATA *intro; OBJ_DATA *light; int mod; if (gethour() > 21 || gethour() < 6) { mod = 2; light = get_eq_char(ch, WEAR_LIGHT); if (light && light->item_type == ITEM_LIGHT) mod = 4; } else { mod = 5; } for (intro = ch->pcdata->first_introduction; intro; intro = intro->next) { if (intro->pid == gmob->pcdata->pid) { if (time(0) - intro->lastseen > 300) //5 minutes { if (abs(ch->coord->x - gmob->coord->x) > mod || abs(ch->coord->y - gmob->coord->y) > mod) continue; if (intro->value > 0) intro->value += number_range(100, 225); else intro->value -= number_range(100, 225); intro->lastseen = 0; break; } } } if (intro) { if (gethour() > 21 || gethour() < 6) { mod = 2; light = get_eq_char(gmob, WEAR_LIGHT); if (light && light->item_type == ITEM_LIGHT) mod = 4; } else { mod = 5; } for (intro = gmob->pcdata->first_introduction; intro; intro = intro->next) { if (intro->pid == ch->pcdata->pid) { if (time(0) - intro->lastseen > 300) //5 minutes { if (abs(ch->coord->x - gmob->coord->x) > mod || abs(ch->coord->y - gmob->coord->y) > mod) continue; if (intro->value > 0) intro->value += number_range(100, 225); else intro->value -= number_range(100, 225); intro->lastseen = 0; break; } } } } } if (!IS_NPC(ch) && ((xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NOPASS) && in_same_room(ch, gmob) && gmob->m4 != ht) || (xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NOCLOAK) && get_wear_cloak(ch) && in_same_room(ch, gmob) && gmob->m4 != ht) || (xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NOHOOD) && get_wear_hidden_cloak(ch) && in_same_room(ch, gmob) && gmob->m4 != ht) || (xIS_SET(gmob->act, ACT_MILITARY) && xIS_SET(gmob->miflags, KM_NEEDINTRO) && !str_cmp(ch->name, PERS_KINGDOM(ch, gmob->m4)) && in_same_room(ch, gmob) && gmob->m4 != ht))) { if (!IS_NPC(ch)) { send_to_char("\n\r", ch); if (xIS_SET(gmob->miflags, KM_NOPASS)) { sprintf(buf, "%s you are not welcome beyond this point, please leave the way you came in.", ch->name); do_tell(gmob, buf); } if (xIS_SET(gmob->miflags, KM_NOCLOAK) && get_wear_cloak(ch)) { sprintf(buf, "%s you need to remove your cloak before entering. Try to enter and you will DIE!", ch->name); do_tell(gmob, buf); } if (xIS_SET(gmob->miflags, KM_NOHOOD) && get_wear_hidden_cloak(ch)) { sprintf(buf, "%s you need to remove your hood before entering. Try to enter and you will DIE!", ch->name); do_tell(gmob, buf); } if (xIS_SET(gmob->miflags, KM_NEEDINTRO) && !str_cmp(ch->name, PERS_KINGDOM(ch, gmob->m4))) { sprintf(buf, "%s Your face is unknown here. If you wish to enter you must first introduce yourself. If you attempt to move forward you will be struck down!", ch->name); do_tell(gmob, buf); } } else { send_to_char("\n\r", ch); sprintf(buf, "%s, I shall not allow you to ENTER!", ch->name); do_say(gmob, buf); one_hit(gmob, ch, TYPE_UNDEFINED, LM_BODY); return; } } } return; } void map_north(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x, ch->coord->y - 1, DIR_NORTH, 0); return; } void map_east(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x + 1, ch->coord->y, DIR_EAST, 0); return; } void map_south(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x, ch->coord->y + 1, DIR_SOUTH, 0); return; } void map_west(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x - 1, ch->coord->y, DIR_WEST, 0); return; } void map_up(CHAR_DATA * ch) { send_to_char("Huh?\n\r", ch); return; } void map_down(CHAR_DATA * ch) { send_to_char("Huh?\n\r", ch); return; } void map_ne(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x + 1, ch->coord->y - 1, DIR_NORTHEAST, 0); return; } void map_nw(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x - 1, ch->coord->y - 1, DIR_NORTHWEST, 0); return; } void map_se(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x + 1, ch->coord->y + 1, DIR_SOUTHEAST, 0); return; } void map_sw(CHAR_DATA * ch) { process_exit(ch, ch->map, ch->coord->x - 1, ch->coord->y + 1, DIR_SOUTHWEST, 0); return; } void process_movement_value(CHAR_DATA *ch, int dir) { if (dir == 0) map_north(ch); if (dir == 1) map_east(ch); if (dir == 2) map_south(ch); if (dir == 3) map_west(ch); if (dir == 6) map_ne(ch); if (dir == 7) map_nw(ch); if (dir == 8) map_se(ch); if (dir == 9) map_sw(ch); } ROOM_INDEX_DATA *find_continent(CHAR_DATA * ch, int maproom) { ROOM_INDEX_DATA *location = NULL; if (maproom == OVERLAND_SOLAN) location = get_room_index(OVERLAND_SOLAN); return location; } void enter_map(CHAR_DATA * ch, int x, int y, int continent) { ROOM_INDEX_DATA *maproom = NULL; if (continent > MAP_MAX) /* Sending the vnum of the room to goto, make sure the target room is not in limbo.are */ maproom = find_continent(ch, continent); else /* Means you are likely an immortal using the goto command */ { switch (continent) { case MAP_SOLAN: maproom = get_room_index(OVERLAND_SOLAN); ch->map = MAP_SOLAN; break; default: bug("Invalid target map specified: %d", continent); return; } } if (!maproom) { bug("enter_map: Overland map room is missing!", 0); send_to_char("Woops. Something is majorly wrong here - inform the immortals.\n\r", ch); return; } if (maproom->vnum == OVERLAND_SOLAN) ch->map = MAP_SOLAN; if (!IS_NPC(ch)) if (ch->pcdata->mapdir == -1) ch->pcdata->mapdir = 1; update_players_map(ch, x, y, ch->map, 0, maproom); update_objects(ch, x, y, ch->map); return; } void leave_map(CHAR_DATA * ch, ROOM_INDEX_DATA * target, int dir, int qexit) { if (!IS_NPC(ch)) REMOVE_PLR_FLAG(ch, PLR_MAPEDIT); /* Just in case they were editing */ if (!IS_NPC(ch)) ch->pcdata->mapdir = dir; if (!qexit) update_players_map(ch, -1, -1, -1, 3, target); else { char_from_room(ch); char_to_room(ch, target); ch->coord->x = -1; ch->coord->y = -1; ch->map = -1; REMOVE_ONMAP_FLAG(ch); do_look(ch, ""); } update_objects(ch, -1, -1, -1); return; } /* void do_joinfight(CHAR_DATA * ch, char *argument) { DESCRIPTOR_DATA *d; CMAP_DATA *mch; CHAR_DATA *fch; int found = 0; int used = -1; if (ch->fcoord->x > -1 || ch->fcoord->y > -1 || ch->fightm > -1) { send_to_char("You cannot join a fight while you are in one.\n\r", ch); return; } for (d = first_descriptor; d; d = d->next) { if (d->connected == CON_PLAYING && d->character != ch && d->character->in_room && d->newstate != 2 && can_see_map(ch, d->character) && (d->character->coord->x == ch->coord->x && d->character->coord->y == ch->coord->y && d->character->map == ch->map)) { if (d->character->fcoord->x > -1 && d->character->fcoord->y > -1 && d->character->fightm > -1) { found = 1; used = d->character->fightm; } } } for (mch = first_wilderchar; mch; mch = mch->next) { if (mch->mapch->coord->x == ch->coord->x && mch->mapch->coord->y == ch->coord->y && mch->mapch->map == ch->map) if (mch->mapch->fcoord->x > -1 && mch->mapch->fcoord->y > -1 && mch->mapch->fightm > -1) { found = 1; used = mch->mapch->fightm; } } if (found == 0 || used == -1) { if (found == 0 && used != -1) bug("do_joinfight: used has a value while found doesn't.", 0); if (found != 0 && used == -1) bug("do_joinfight: found has a value while used doesn't.", 0); send_to_char("There is no fight here to join.\n\r", ch); return; } else { ch->fightm = used; ch->fcoord->x = number_range(8, 14); ch->fcoord->y = number_range(8, 14); ch->fcounter = 0; update_followers(ch, ch->fcoord->x, ch->fcoord->y, ch->fightm, ch->coord->x, ch->coord->y, ch->map); do_look(ch, "auto"); act(AT_CYAN, "\n\r[$n] has joined the chaos.", ch, NULL, NULL, TO_FIGHT); for (fch = ch->in_room->first_person; fch; fch = fch->next_in_room) { if (fch != ch && fch->master == ch && (ch->in_room && fch->in_room) && !IS_NPC(fch) && fch->coord->x == ch->coord->x && fch->coord->y == ch->coord->y && fch->map == ch->map && (ch->in_room == fch->in_room) && (fch->position == POS_STANDING || fch->position == POS_MOUNTED)) { act(AT_CYAN, "[$n] has joined the chaos.", fch, NULL, NULL, TO_FIGHT); } } } return; } */ void do_lookaround(CHAR_DATA * ch, char *argument) { if (IS_IMMORTAL(ch)) { send_to_char("This command is for mortals only (he he you cannot use it).\n\r", ch); return; } if (ch->coord->x < 1 || ch->coord->y < 1 || ch->map < 0) { send_to_char("You can only use this command while out in the Wilderness.\n\r", ch); return; } if (ch->position <= POS_SLEEPING) { send_to_char("You cannot do that in your sleep.\n\r", ch); return; } display_map(ch, 5000, 5000, 0); return; } void do_coords(CHAR_DATA * ch, char *argument) { char arg[MIL]; char buf[MSL]; int x, y; if (IS_NPC(ch)) { send_to_char("NPCs cannot use this command.\n\r", ch); return; } if (!IS_ONMAP_FLAG(ch)) { send_to_char("This command can only be used from the overland maps.\n\r", ch); return; } argument = one_argument(argument, arg); if (arg[0] == '\0' || argument[0] == '\0') { send_to_char("Usage: coords <x> <y>\n\r", ch); send_to_char("Usage: coords view <x> <y>\n\r", ch); return; } if (!str_cmp(arg, "view")) { char arg2[MIL]; argument = one_argument(argument, arg2); x = atoi(arg2); y = atoi(argument); if ((x > 50 || y > 50) || (x < 1 || y < 1)) { send_to_char("Valid range is 1 to 50 for both x and y.\n\r", ch); return; } display_map(ch, x, y, 0); return; } x = atoi(arg); y = atoi(argument); if (x < 1 || x > MAX_X) { sprintf(buf, "Valid x coordinates are 1 to %d.\n\r", MAX_X); send_to_char(buf, ch); return; } if (y < 1 || y > MAX_Y) { sprintf(buf, "Valid y coordinates are 1 to %d.\n\r", MAX_Y); send_to_char(buf, ch); return; } ch->coord->x = x; ch->coord->y = y; update_objects(ch, x, y, ch->map); do_look(ch, "auto"); return; } void load_solan() { FILE *fp; char filename[256]; int stx, sty, endx, endy, sector; int x, y; sprintf(filename, "%ssolan.map", MAP_DIR); if ((fp = fopen(filename, "r")) == NULL) { bug("load_solan: File for map not found!", 0); shutdown_mud("Missing solan.map file"); exit(1); } for (;;) { char letter; char *word; if (feof(fp)) break; letter = fread_letter(fp); if (letter != '#') { bug("load_solan: # not found, possibly not a map file.", 0); shutdown_mud("Bad file data in solan.map"); exit(1); } word = fread_word(fp); if (!str_cmp(word, "MAP")) { for (;;) { if (feof(fp)) { bug("load_solan: Reached EOL."); break; } stx = fread_number(fp); sty = fread_number(fp); endx = fread_number(fp); endy = fread_number(fp); sector = fread_number(fp); for (x = stx; x <= endx; x++) { if (x == stx) y = sty; else y = 1; for (;; y++) { if ((x == endx && y > endy) || y == MAX_Y+1) break; map_sector[0][x][y] = sector; } } if (endx == MAX_X && endy == MAX_Y) break; } } else if (!str_cmp(word, "END")) break; else { char buf[MSL]; sprintf(buf, "load_solan: bad section: %s.", word); bug(buf, 0); continue; } } FCLOSE(fp); for (x = 1; x <= MAX_X; x++) { for (y = 1; y <= MAX_Y; y++) { if (map_sector[0][x][y] == SECT_SHIP) map_sector[0][x][y] = SECT_OCEAN; } } return; } //Average weather for the center of the map, adjust as needed const int avg_temp[12][4] = { {62, 60, 58, 57}, //Jan {56, 57, 59, 61}, //Feb {63, 65, 68, 70}, //Mar {74, 78, 80, 84}, //Apr {88, 92, 97, 102}, //May {105, 107, 110, 113}, //Jun {116, 118, 120, 124}, //Jul {126, 130, 123, 118}, //Aug {115, 110, 102, 97}, //Sep {95, 93, 90, 86}, //Oct {81, 77, 74, 71}, //Nov {69, 67, 65, 63} //Dec }; int get_avg_temp() { int day; int month; int week; day = getday(); month = day / 30; day = getdayofmonth(day); week = (day / 7.5) + 1; if (day == 30) week = 4; return avg_temp[month][week]; } int get_curr_dir(int x, int fx, int y, int fy) { if (y < fy) //Front is South of Player { if (x > fx) //Front is West of Player { if (y == fy) return 4; if ((((abs(x - fx) * 100) / abs(y - fy)) > 150) || (((abs(x - fx) * 100) / abs(y - fy)) < 60)) { if (((abs(x - fx) * 100) / abs(y - fy)) >= 500) return 4; if (((abs(x - fx) * 100) / abs(y - fy)) <= 20) return 0; if (((abs(x - fx) * 100) / abs(y - fy)) > 150) return 3; if (((abs(x - fx) * 100) / abs(y - fy)) < 60) return 1; } else return 2; } if (x < fx) //Front is East of Player { if (y == fy) return 12; if ((((abs(x - fx) * 100) / abs(y - fy)) > 150) || (((abs(x - fx) * 100) / abs(y - fy)) < 60)) { if (((abs(x - fx) * 100) / abs(y - fy)) >= 500) return 12; if (((abs(x - fx) * 100) / abs(y - fy)) <= 20) return 0; if (((abs(x - fx) * 100) / abs(y - fy)) > 150) return 13; if (((abs(x - fx) * 100) / abs(y - fy)) < 60) return 15; } else return 14; } } else //Front is north of Player { if (x > fx) //Front is West of Player { if (y == fy) return 4; if ((((abs(x - fx) * 100) / abs(y - fy)) > 150) || (((abs(x - fx) * 100) / abs(y - fy)) < 60)) { if (((abs(x - fx) * 100) / abs(y - fy)) >= 500) return 4; if (((abs(x - fx) * 100) / abs(y - fy)) <= 20) return 8; if (((abs(x - fx) * 100) / abs(y - fy)) > 150) return 5; if (((abs(x - fx) * 100) / abs(y - fy)) < 60) return 7; } else return 6; } if (x < fx) //Front is East of Player { if (y == fy) return 12; if ((((abs(x - fx) * 100) / abs(y - fy)) > 150) || (((abs(x - fx) * 100) / abs(y - fy)) < 60)) { if (((abs(x - fx) * 100) / abs(y - fy)) >= 500) return 12; if (((abs(x - fx) * 100) / abs(y - fy)) <= 20) return 8; if (((abs(x - fx) * 100) / abs(y - fy)) > 150) return 11; if (((abs(x - fx) * 100) / abs(y - fy)) < 60) return 9; } else return 10; } } return 8; } float getsl(float lx, float ly, float hx, float hy) { float diff1; float diff2; if (ly > hy) diff1 = ly - hy; else diff1 = hy - ly; if (lx > hx) diff2 = lx - hx; else diff2 = hx - lx; if (diff1 <= 0 || diff2 <= 0) return 0; return (float) diff1 / diff2; } float find_fsqrt(float dist) { float x = 1.0; for (;;) { if ((x * x) >= dist) return x; x++; } return 1.0; } void check_torn_damage(int x, int y, int map) { int stx; int sty; int sector; for (stx = x - 5; stx <= x + 5; stx++) { for (sty = y - 5; sty <= y + 5; sty++) { if (stx < 1 || stx > MAX_X || sty < 1 || sty > MAX_Y) continue; if ((((x - stx) * (x - stx)) + ((y - sty) * (y - sty))) <= 25) { sector = map_sector[map][stx][sty]; if (sector == SECT_FOREST || sector == SECT_ROAD || sector == SECT_HCORN || sector == SECT_HGRAIN || sector == SECT_STREE || sector == SECT_NTREE || sector == SECT_SCORN || sector == SECT_NCORN || sector == SECT_SGRAIN || sector == SECT_NGRAIN || sector == SECT_JUNGLE || sector == SECT_PATH || sector == SECT_PAVE || sector == SECT_BRIDGE) { if (sector != SECT_BRIDGE) sector = SECT_FIELD; else sector = SECT_WATER_NOSWIM; } resource_sector[map][stx][sty] -= 150; if (resource_sector[map][stx][sty] <= 0) { map_sector[map][stx][sty] = sector; resource_sector[map][stx][sty] = 0; } } } } } const int front_offsetx[8][30] = { {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7}, {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, {1, 0, 2, 1, 2, 2, 3, 2, 4, 3, 4, 4, 5, 4, 6, 5, 6, 6, 7, 6, 8, 7, 8, 8, 9, 8, 10, 9, 10, 10}, {1, 0, 2, 1, 2, 2, 2, 2, 3, 2, 4, 3, 4, 4, 4, 4, 5, 4, 6, 5, 6, 6, 6, 6, 7, 6, 8, 7, 8, 8}, {0, 1, 0, 2, 1, 2, 2, 2, 2, 3, 2, 4, 3, 4, 4, 4, 4, 5, 4, 6, 5, 6, 6, 6, 6, 7, 6, 8, 7, 8}, {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5} }; const int front_offsety[8][30] = { {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8}, {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7}, {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7}, {0, 1, 0, 2, 1, 2, 2, 2, 2, 3, 2, 4, 3, 4, 4, 4, 4, 5, 4, 6, 5, 6, 6, 6, 6, 7, 6, 8, 7, 8}, {1, 0, 2, 1, 2, 2, 2, 2, 3, 2, 4, 3, 4, 4, 4, 4, 5, 4, 6, 5, 6, 6, 6, 6, 7, 6, 8, 7, 8, 8}, {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5}, {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15} }; //Math at its finest (well my finest, rofl) void update_local_weather(FRONT_DATA * fnt, int type) { float x; //Start x float y; //Start y float cx; //Right move float cy; //Right move float ox; //Left move float oy; //Left move float map; //Map float lx; //Lowest X float ly; //Lowest y float hx; //Highest x float hy; //Highest y float stx; float sty; float bx; float by; float endx; float endy; float add; float snow; float temp; float sl; float r; float dist; float dist2; x = (float) fnt->x; y = (float) fnt->y; cx = x; cy = y; ox = cx; oy = cy; lx = hx = ox; ly = hy = oy; map = (float) fnt->map; if (fnt->size % 2 == 0) //Even { ox -= (float) front_offsetx[fnt->typec][fnt->size - 1]; oy += (float) front_offsety[fnt->typec][fnt->size - 1]; cx += (float) front_offsetx[fnt->typec][fnt->size - 2]; cy -= (float) front_offsety[fnt->typec][fnt->size - 2]; } else { ox -= (float) front_offsetx[fnt->typec][fnt->size - 2]; oy += (float) front_offsety[fnt->typec][fnt->size - 2]; cx += (float) front_offsetx[fnt->typec][fnt->size - 1]; cy -= (float) front_offsety[fnt->typec][fnt->size - 1]; } if (cx > hx) hx = cx; if (ox > hx) hx = ox; if (cx < lx) lx = cx; if (ox < lx) lx = ox; if (cy > hy) hy = cy; if (oy > hy) hy = oy; if (cy < ly) ly = cy; if (oy < ly) ly = oy; if (lx < 1) lx = 1; if (ly < 1) ly = 1; if (hx > MAX_X) hx = MAX_X; if (hy > MAX_Y) hy = MAX_Y; bx = lx - 10; by = ly - 10; endx = hx + 10; endy = hy + 10; if (bx < 1) bx = 1; if (by < 1) by = 1; if (endx > MAX_X) endx = MAX_X; if (endy > MAX_Y) endy = MAX_Y; r = ((x - endx) * (x - endx)) + ((y - endy) * (y - endy)); r = find_fsqrt(r); sl = getsl(lx, ly, hx, hy); //Due to how the circle works, it will form a cone instead of a circle, so //don't look for half a circle to show up, but a cone for (sty = by; sty <= endy; sty++) { temp = generate_temperature(NULL, fnt->x, (int) sty, fnt->map); for (stx = bx; stx <= endx; stx++) { //Never thought you would see geometry used, neither did I till now if (fnt->type == 0) //Cold { // Slope Cng X Y axis if (sty <= (sl * (hx - stx) + ly)) //NW of line { // x^2 y^2 r^2 if ((((x - stx) * (x - stx)) + ((y - sty) * (y - sty))) <= (r * r)) //within the circle { //Find the shortest distance from the line dist = get_distform(stx, (sl * (hx - stx) + ly), stx, sty); dist2 = get_distform((hx - (sty / sl) + (ly / sl)), sty, stx, sty); if (dist2 < dist) dist = dist2; snow = weather_sector[(int) map][(int) stx][(int) sty] / 10; if (snow < 0) snow = 0; add = (int) (UMAX(1, 6 - (dist / 4))); if (weather_sector[(int) map][(int) stx][(int) sty] + add >= (snow + 1) * 10) weather_sector[(int) map][(int) stx][(int) sty] = (int) snow *10 + 9; else weather_sector[(int) map][(int) stx][(int) sty] += (int) add; if (temp >= 20 && temp <= 35) { if (snow == 0 && add > 0) weather_sector[(int) map][(int) stx][(int) sty] += 20; if (add >= 1 && add <= 2) if (number_range(1, 3) == 1) weather_sector[(int) map][(int) stx][(int) sty] += 10; if (add >= 3 && add <= 4) if (number_range(1, 2) == 1) weather_sector[(int) map][(int) stx][(int) sty] += 10; if (add > 4) weather_sector[(int) map][(int) stx][(int) sty] += 10; } if (weather_sector[(int) map][(int) stx][(int) sty] < 0) weather_sector[(int) map][(int) stx][(int) sty] = (int) add; } } } if (fnt->type == 1) //Warm { // Slope Cng X Y axis if (sty >= (hy - (sl * (hx - stx)))) //NW of line { // x^2 y^2 r^2 if ((((x - stx) * (x - stx)) + ((y - sty) * (y - sty))) <= (r * r)) //within the circle { //Find the shortest distance from the line dist = get_distform(stx, (hy - (sl * (hx - stx))), stx, sty); dist2 = get_distform((sty / sl + hx - (hy / sl)), sty, stx, sty); if (dist2 < dist) dist = dist2; snow = weather_sector[(int) map][(int) stx][(int) sty] / 10; if (snow < 0) snow = 0; add = (int) (UMAX(1, 6 - (dist / 4))); if (weather_sector[(int) map][(int) stx][(int) sty] + add >= (snow + 1) * 10) weather_sector[(int) map][(int) stx][(int) sty] = (int) snow *10 + 9; else weather_sector[(int) map][(int) stx][(int) sty] += (int) add; if (temp >= 20 && temp <= 35) { if (snow == 0 && add > 0) weather_sector[(int) map][(int) stx][(int) sty] += 20; if (add >= 1 && add <= 2) if (number_range(1, 3) == 1) weather_sector[(int) map][(int) stx][(int) sty] += 10; if (add >= 3 && add <= 4) if (number_range(1, 2) == 1) weather_sector[(int) map][(int) stx][(int) sty] += 10; if (add > 4) weather_sector[(int) map][(int) stx][(int) sty] += 10; } if (weather_sector[(int) map][(int) stx][(int) sty] < 0) weather_sector[(int) map][(int) stx][(int) sty] = (int) add; } } } } } } //Lovely thing for generating wind direction, a similar formula is used for generating bad //weather void generate_wind(CHAR_DATA * ch, int x, int y, int map) { FRONT_DATA *front; int curdir = -1; int curstr = -1; int diff; if (ch != NULL && x == -1 && y == -1 && map == -1) { x = ch->coord->x; y = ch->coord->y; map = ch->map; } winddir = windstr = -1; for (front = first_front; front; front = front->next) { if (map == front->map && abs(x - front->x) <= 50 && abs(y - front->y) <= 50) { curdir = get_curr_dir(x, front->x, y, front->y); curstr = (100 - (abs(x - front->x) + abs((y - front->y)))) / 2; if (windstr != -1 && winddir != curdir) { if ((abs(winddir - curdir > 8))) diff = 8 - (abs(winddir - curdir) - 8); else diff = abs(winddir - curdir); if (diff <= 2) { if (diff == 1) { if (curstr > windstr) winddir = curdir; } if (diff == 2) { if (curstr > windstr) winddir = curdir; if (windstr != 0 && ((curstr * 10) / windstr >= 7)) { if ((winddir == 15 && curdir == 1) || (curdir == 15 && winddir == 1)) winddir = 0; else if ((winddir == 14 && curdir == 0) || (curdir == 14 && winddir == 0)) winddir = 15; else winddir = (curdir + winddir) / 2; } } windstr += (((curstr * 10) * (5 + (diff * 2))) / 100); } else windstr -= (((curstr * 10) * (6 + ((diff - 1) / 2))) / 100); if (windstr < 0) { windstr = abs(windstr); winddir = curdir; } } else if (windstr == -1) { winddir = curdir; windstr = curstr; } else windstr += curstr; } } } char *const owindd[16] = { "south", "south/southwest", "southwest", "west/southwest", "west", "west/northwest", "northwest", "north/northwest", "north", "north/northeast", "northeast", "east/northeast", "east", "east/southeast", "southeast", "south/southeast" }; char *const windd[16] = { "north", "north/northeast", "northeast", "east/northeast", "east", "east/southeast", "southeast", "south/southeast", "south", "south/southwest", "southwest", "west/southwest", "west", "west/northwest", "northwest", "north/northwest" }; const int front_cr[8][30] = { {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, {0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1}, {1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0}, {2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2}, {0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0}, {0, 2, 0, 2, 2, 0, 2, 0, 0, 2, 0, 2, 2, 0, 2, 0, 0, 2, 0, 2, 2, 0, 2, 0, 0, 2, 0, 2, 2, 0}, {0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0}, {1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1} }; void create_front(int type) { FRONT_DATA *fnt; int pc; int cnt; int ttype; int x; for (x = 0; x < MAP_MAX; x++) { CREATE(fnt, FRONT_DATA, 1); fnt->type = type; if (type == 0) //Cold { fnt->x = number_range(1, 450); fnt->y = number_range(1, 450); } else { fnt->x = MAX_X - number_range(1, 450); fnt->y = number_range(1, 450); } fnt->map = x; pc = number_range(20, 30); //Size of front fnt->size = pc; ttype = number_range(0, 7); //Creates 8 different kinds, produces slightly different angles. fnt->speed = number_range(1, 3); for (cnt = 0; cnt < 30; cnt++) fnt->f[cnt] = -1; for (cnt = 0; cnt < pc; cnt++) { fnt->f[cnt] = front_cr[ttype][cnt]; } fnt->typec = ttype; LINK(fnt, first_front, last_front, next, prev); } } //Generate temperatures based on front locations int get_front_temp(CHAR_DATA * ch, int x, int y, int map) { FRONT_DATA *fnt; int dist = 0; int neg = 1; int diff = 0; for (fnt = first_front; fnt; fnt = fnt->next) { if (abs(fnt->x - x) <= 50 && abs(fnt->y - y) <= 50) { if (fnt->type == 1) //Warm Front { if (x < fnt->x && y < fnt->y) //Player is W to N of front dist += 71 - get_distform(x, y, fnt->x, fnt->y); } if (fnt->type == 0) //Cold front { if (x < fnt->x && y > fnt->y) //Player is W to S of front dist -= get_distform(x, y, fnt->x, fnt->y) - 71; } } } if (dist == 0) return 0; if (dist * -1 > 0) neg = -1; if (abs(dist) >= 10 && abs(dist) <= 20) diff = abs(dist) / 5.9; if (abs(dist) > 20 && abs(dist) <= 30) diff = abs(dist) / 5.5; if (abs(dist) > 30 && abs(dist) <= 40) diff = abs(dist) / 5.1; if (abs(dist) > 40 && abs(dist) <= 50) diff = abs(dist) / 4.7; if (abs(dist) > 50 && abs(dist) <= 60) diff = abs(dist) / 4.3; if (abs(dist) > 60) diff = 18; return diff * neg; } int generate_temperature(CHAR_DATA * ch, int x, int y, int map) { int temp; int windmod = 0; int fntmod = 0; int hour; if (ch != NULL && x == -1 && y == -1 && map == -1) { x = ch->coord->x; y = ch->coord->y; map = ch->map; } temp = get_avg_temp(); temp -= ((abs(750 - y) / 75) * 10); //Position change, farther from center the colder it is. hour = gethour(); if (hour >= 0 && hour <= 4) temp -= 8; if (hour >= 5 && hour <= 7) temp -= 5; if (hour >= 8 && hour <= 10) temp -= 3; if (hour >= 12 && hour <= 14) temp += 5; if (hour >= 18 && hour <= 19) temp -= 3; if (hour >= 20 && hour <= 22) temp -= 5; if (hour == 23) temp -= 8; generate_wind(ch, x, y, map); if (windstr >= 0 && windstr <= 10) windmod = 1; if (windstr >= 11 && windstr <= 20) windmod = (windstr / 9.5); if (windstr >= 21 && windstr <= 40) windmod = (windstr / 9.3); if (windstr >= 41 && windstr <= 60) windmod = (windstr / 9.2); if (windstr >= 61 && windstr <= 90) windmod = (windstr / 9); if (windstr > 90) windmod = 12; if (temp > 85) //Warm weather is harder to cool down windmod /= 4; if (temp < 32) //Make it chill the bone more :-) windmod *= 1.2; temp -= windmod; fntmod = get_front_temp(ch, x, y, map); if (fntmod < 0 && temp < 32) fntmod /= 2; if (fntmod > 0 && temp > 80) fntmod /= 2; temp += fntmod; return temp; } bool no_snow(int sector) { if (sector == SECT_WATER_SWIM || sector == SECT_WATER_NOSWIM || sector == SECT_UNDERWATER || sector == SECT_DESERT || sector == SECT_OCEANFLOOR || sector == SECT_UNDERGROUND || sector == SECT_MINEGOLD || sector == SECT_MINEIRON || sector == SECT_SGOLD || sector == SECT_NGOLD || sector == SECT_SIRON || sector == SECT_NIRON || sector == SECT_RIVER || sector == SECT_SHORE || sector == SECT_ICE || sector == SECT_OCEAN || sector == SECT_LAVA || sector == SECT_TREE || sector == SECT_NOSTONE || sector == SECT_QUICKSAND || sector == SECT_VOID || sector == SECT_FIRE || sector == SECT_STONE || sector == SECT_SSTONE || sector == SECT_NSTONE || sector == SECT_AIR) return TRUE; else return FALSE; } void generate_forecast(CHAR_DATA * ch, int x, int y, int map) { char tbuf[8]; char dbuf[25]; FRONT_DATA *fnt; int cnt; int cx, cy, ox, oy; int dir = 0; int dist = 0; if (!ch) return; if (ch != NULL && x == -1 && y == -1 && map == -1) { x = ch->coord->x; y = ch->coord->y; map = ch->map; } for (fnt = first_front; fnt; fnt = fnt->next) { if (abs(fnt->x - x) <= 70 && abs(fnt->y - y) <= 70 && fnt->map == ch->map) { cx = fnt->x; cy = fnt->y; ox = cx; oy = cy; dist = 150; dir = 0; for (cnt = 2; cnt < 31; cnt++) { if (fnt->f[cnt - 2] == 0) { if (cnt % 2) cx++; else ox--; } if (fnt->f[cnt - 2] == 1) { if (cnt % 2) { if (fnt->type == 1) //Warm cy++; else cy--; } else { if (fnt->type == 1) //Warm oy--; else oy++; } } if (fnt->f[cnt - 2] == 2) { if (cnt % 2) { cx++; if (fnt->type == 1) cy++; else cy--; } else { ox--; if (fnt->type == 1) //Warm oy--; else oy++; } } if (cnt % 2) { if (get_distform(x, y, cx, cy) < dist) { dist = get_distform(x, y, cx, cy); dir = get_curr_dir(x, cx, y, cy); } } else { if (get_distform(x, y, ox, oy) < dist) { dist = get_distform(x, y, ox, oy); dir = get_curr_dir(x, ox, y, oy); } } if (fnt->f[cnt - 2] == -1) break; } sprintf(dbuf, "%s", owindd[dir]); if (fnt->type == 0) sprintf(tbuf, "Cold"); else sprintf(tbuf, "Warm"); if (dist >= 0 && dist <= 5) ch_printf(ch, "A %s front to the %s is just a few steps away from you.\n\r", tbuf, dbuf); if (dist >= 6 && dist <= 15) ch_printf(ch, "A %s front to the %s is a short distance away.\n\r", tbuf, dbuf); if (dist >= 16 && dist <= 25) ch_printf(ch, "A %s front to the %s is a moderate distance away.\n\r", tbuf, dbuf); if (dist >= 26 && dist <= 40) ch_printf(ch, "A %s front to the %s is a large distance away.\n\r", tbuf, dbuf); if (dist >= 41 && dist <= 55) ch_printf(ch, "A %s front is very far away in the general direction of %s.\n\r", tbuf, dbuf); if (dist >= 55 && dist <= 75) ch_printf(ch, "A %s front is a very SIZEABLE distance in the general direction of %s.\n\r", tbuf, dbuf); if (dist > 75) ch_printf(ch, "A %s front is a good FEW DAYS travel in the general direction of %s.\n\r", tbuf, dbuf); } } } void show_temp(CHAR_DATA * ch, int x, int y, int map) { int temp; if (!ch) return; if (ch != NULL && x == -1 && y == -1 && map == -1) { x = ch->coord->x; y = ch->coord->y; map = ch->map; } //This is based in F, not C temp = generate_temperature(ch, x, y, map); if (temp < -30) send_to_char("As the frigid air flows by you, you can hear the voice of death in your ear.\n\r", ch); if (temp >= -29 && temp <= -20) send_to_char("If you do not find heat soon, your chances of surviving for long is low.\n\r", ch); if (temp >= -19 && temp <= -10) send_to_char("Any open bodypart will quickly freeze at this temperature.\n\r", ch); if (temp >= -9 && temp <= 5) send_to_char("It is very cold, but with enough clothing it is bareable.\n\r", ch); if (temp >= 6 && temp <= 20) send_to_char("A thick layer of clothing is a good idea because it is a bit below freezing.\n\r", ch); if (temp >= 21 && temp <= 35) send_to_char("It is right at the freezing mark, it is a good idea to be completely clothed.\n\r", ch); if (temp >= 36 && temp <= 45) send_to_char("It is a little chilly, but above freezing.\n\r", ch); if (temp >= 46 && temp <= 55) send_to_char("The air still has a bit of cold to it, but a pleasant cold.\n\r", ch); if (temp >= 56 && temp <= 65) send_to_char("The weather is pleasant, not too cold, not too hot.\n\r", ch); if (temp >= 66 && temp <= 80) send_to_char("The weather is pleasant, a bit warm, but not hot.\n\r", ch); if (temp >= 81 && temp <= 90) send_to_char("The air is a little humid, a little bit of cool air would be nice.\n\r", ch); if (temp >= 91 && temp <= 100) send_to_char("It is just below blistering hot, good swimming weather.\n\r", ch); if (temp >= 100 && temp <= 115) send_to_char("You can feel the sun burning your skin, it is rather uncomfertable.\n\r", ch); if (temp >= 116 && temp <= 130) send_to_char("It is hot enough to kill someone if they do not drink and stay out too long.\n\r", ch); if (temp > 130) send_to_char("Remember those bones you see in the desert, yeah this heat causes that.\n\r", ch); } //Gives out the messages for the wind direction void generate_wind_dir(CHAR_DATA * ch, int x, int y, int map) { char buf[MIL]; if (!ch) return; if (ch != NULL && x == -1 && y == -1 && map == -1) { x = ch->coord->x; y = ch->coord->y; map = ch->map; } generate_wind(ch, x, y, map); //ALWAYS do this first so it sets the global variables. if (windstr != -1 && winddir != -1) sprintf(buf, "%s", windd[winddir]); if (windstr == -1) ch_printf(ch, "This wind has died down to nothing.\n\r"); if (windstr >= 0 && windstr <= 10) ch_printf(ch, "A gentle %s wind blows through the air.\n\r", buf); if (windstr >= 11 && windstr <= 20) ch_printf(ch, "A light %s wind flows pleasantly through the air.\n\r", buf); if (windstr >= 21 && windstr <= 40) ch_printf(ch, "The %s wind blows through the air ruffling everything in its path.\n\r", buf); if (windstr >= 41 && windstr <= 60) ch_printf(ch, "A strong %s wind buzzes through the air distrupting everything in sight.\n\r", buf); if (windstr >= 61 && windstr <= 90) ch_printf(ch, "A very strong %s wind is making everything in sight move or bend.\n\r", buf); if (windstr > 90) ch_printf(ch, "The %s wind is literally moving you, it is time to find a shelter.\n\r", buf); // ch_printf(ch, "\n\r%d %d\n\r", dir, str); return; } //Load a new/fresh weather system if one is not present. void init_area_weather() { int temp; int cnt; temp = get_avg_temp(); //Temp first_front = last_front = NULL; //Create a few fronts, cold start nw, warm ne and move in opposite directions along the path for (cnt = 1; cnt <= 6; cnt++) { create_front(0); create_front(1); } } void save_snow() { FILE *fp; char filename[256]; int x, y, map; sprintf(filename, "%s", SNOW_FILE); FCLOSE(fpReserve); if ((fp = fopen(filename, "w")) == NULL) { bug("save_snow: fopen", 0); perror(filename); } else { fprintf(fp, "#SNOW\n"); for (x = 1; x < MAX_X + 1; x++) { for (y = 1; y < MAX_Y + 1; y++) { for (map = 0; map < MAP_MAX; map++) { if (weather_sector[map][x][y] >= 10) { fprintf(fp, "%d %d %d %d\n", weather_sector[map][x][y], x, y, map); } } } } fprintf(fp, "-1 -1 -1 -1\n"); FCLOSE(fp); } fpReserve = fopen(NULL_FILE, "r"); return; } void load_snow() { FILE *fp; char filename[256]; char *ln; int x1, x2, x3, x4; sprintf(filename, "%s", SNOW_FILE); if ((fp = fopen(filename, "r")) == NULL) { bug("load_snow: File for resources not found!", 0); return; } for (;;) { char letter; char *word; letter = fread_letter(fp); if (letter != '#') { bug("load_caste_resources: # not found, possibly not a file.", 0); return; } word = fread_word(fp); if (!str_cmp(word, "SNOW")) { for (;;) { ln = fread_line(fp); x1 = x2 = x3 = x4 = 0; sscanf(ln, "%d %d %d %d", &x1, &x2, &x3, &x4); if (x1 == -1 && x2 == -1 && x3 == -1 && x4 == -1) { FCLOSE(fp); return; } weather_sector[x4][x2][x3] = x1; } } } } void load_resources() { FILE *fp; char filename[256]; int stx, sty, endx, endy, sector; int x, y; sprintf(filename, "%ssolan.res", MAP_DIR); if ((fp = fopen(filename, "r")) == NULL) { bug("load_resources: File for resources not found!", 0); shutdown_mud("Missing solan.res file"); exit(1); } for (;;) { char letter; char *word; if (feof(fp)) break; letter = fread_letter(fp); if (letter != '#') { bug("load_resources: # not found, possibly not a resource file.", 0); shutdown_mud("Bad file data in solan.res"); exit(1); } word = fread_word(fp); if (!str_cmp(word, "RESOURCES")) { for (;;) { if (feof(fp)) { bug("load_resources: Reached EOL."); break; } stx = fread_number(fp); sty = fread_number(fp); endx = fread_number(fp); endy = fread_number(fp); sector = fread_number(fp); for (x = stx; x <= endx; x++) { if (x == stx) y = sty; else y = 1; for (;; y++) { if ((x == endx && y > endy) || y == MAX_Y+1) break; resource_sector[0][x][y] = sector; } } if (endx == MAX_X && endy == MAX_Y) break; } } else if (!str_cmp(word, "END")) break; else { char buf[MSL]; sprintf(buf, "load_resources: bad section: %s.", word); bug(buf, 0); continue; } } FCLOSE(fp); return; } void load_maps(void) { log_string("Loading continent of Solan...."); load_solan(); log_string("Loading resources for Solan...."); load_resources(); log_string("Loading overland map exits...."); load_entrances(); return; } void save_mapoutline(char *name, int map) { FILE *fp; char filename[256]; int x, y; name = strlower(name); /* Forces filename into lowercase */ sprintf(filename, "%s%s.mapout", MAP_DIR, name); FCLOSE(fpReserve); if ((fp = fopen(filename, "w")) == NULL) { bug("save_map: fopen", 0); perror(filename); } else { for (y = 1; y < MAX_Y + 1; y++) { for (x = 1; x < MAX_X + 1; x++) { fprintf(fp, "%s", sect_show[(int)map_sector[map][x][y]].print); } fprintf(fp, "\n\r"); } FCLOSE(fp); } fpReserve = fopen(NULL_FILE, "r"); return; } void save_resources(char *name, int map) { FILE *fp; char filename[256]; int x, y; int stx, sty; int cursect = -1; stx=sty=1; name = strlower(name); sprintf(filename, "%s%s.res", MAP_DIR, name); FCLOSE(fpReserve); if ((fp = fopen(filename, "w")) == NULL) { bug("save_resources: fopen", 0); perror(filename); } else { fprintf(fp, "#RESOURCES\n"); for (x = 1; x < MAX_X + 1; x++) { for (y = 1; y < MAX_Y + 1; y++) { if (cursect == -1) { cursect = resource_sector[map][x][y]; continue; } if (x == MAX_X && y == MAX_Y) { if (resource_sector[map][x][y] == cursect) { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x, y, cursect); } else { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x, y-1, cursect); fprintf(fp, "%d %d %d %d %d\n", x, y, x, y, resource_sector[map][x][y]); } continue; } if (resource_sector[map][x][y] == cursect) continue; else { if (y > 1) { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x, y-1, cursect); stx = x; sty = y; cursect = resource_sector[map][x][y]; continue; } else { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x-1, MAX_Y, cursect); stx = x; sty = y; cursect = resource_sector[map][x][y]; continue; } } } } fprintf(fp, "#END\n"); FCLOSE(fp); } fpReserve = fopen(NULL_FILE, "r"); return; } void save_map(char *name, int map) { FILE *fp; char filename[256]; int x, y; int stx, sty; int cursect = -1; stx=sty=1; name = strlower(name); sprintf(filename, "%s%s.map", MAP_DIR, name); FCLOSE(fpReserve); if ((fp = fopen(filename, "w")) == NULL) { bug("save_map: fopen", 0); perror(filename); } else { fprintf(fp, "#MAP\n"); for (x = 1; x < MAX_X + 1; x++) { for (y = 1; y < MAX_Y + 1; y++) { if (cursect == -1) { cursect = map_sector[map][x][y]; continue; } if (x == MAX_X && y == MAX_Y) { if (map_sector[map][x][y] == cursect) { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x, y, cursect); } else { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x, y-1, cursect); fprintf(fp, "%d %d %d %d %d\n", x, y, x, y, map_sector[map][x][y]); } continue; } if (map_sector[map][x][y] == cursect) continue; else { if (y > 1) { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x, y-1, cursect); stx = x; sty = y; cursect = map_sector[map][x][y]; continue; } else { fprintf(fp, "%d %d %d %d %d\n", stx, sty, x-1, MAX_Y, cursect); stx = x; sty = y; cursect = map_sector[map][x][y]; continue; } } } } fprintf(fp, "#END\n"); FCLOSE(fp); } fpReserve = fopen(NULL_FILE, "r"); save_entrances(); return; } void do_mapedit(CHAR_DATA * ch, char *argument) { char arg1[MIL]; char buf[MSL]; int value; int fnd = 0; if (IS_NPC(ch)) { send_to_char("Sorry, NPCs can't edit the overland maps.\n\r", ch); return; } argument = one_argument(argument, arg1); if (arg1[0] == '\0') { if (!IS_ONMAP_FLAG(ch)) { send_to_char("This command can only be used from an overland map.\n\r", ch); return; } if (IS_PLR_FLAG(ch, PLR_MAPEDIT)) { REMOVE_PLR_FLAG(ch, PLR_MAPEDIT); send_to_char("&GMap editing mode is now OFF.\n\r", ch); return; } SET_PLR_FLAG(ch, PLR_MAPEDIT); send_to_char("&RMap editing mode is now ON.\n\r", ch); ch_printf(ch, "&YYou are currently creating %s sectors.&z\n\r", sect_show[ch->pcdata->secedit].desc); return; } if (!str_cmp(arg1, "help")) { send_to_char("Usage: mapedit sector <sector number>\n\r", ch); send_to_char("Usage: mapedit save <mapname>\n\r", ch); send_to_char("Usage: mapedit exit <vnum>\n\r", ch); send_to_char("Usage: mapedit exit map <mapname> <X> <Y>\n\r", ch); return; } if (!str_cmp(arg1, "cleanresources")) { int x, y, changed; changed = 0; for (x = 1; x <= MAX_X; x++) { for (y = 1; y <= MAX_Y; y++) { if (map_sector[MAP_SOLAN][x][y] != SECT_SCORN && map_sector[MAP_SOLAN][x][y] != SECT_SGRAIN && map_sector[MAP_SOLAN][x][y] != SECT_STREE && map_sector[MAP_SOLAN][x][y] != SECT_SSTONE && map_sector[MAP_SOLAN][x][y] != SECT_NCORN && map_sector[MAP_SOLAN][x][y] != SECT_NGRAIN && map_sector[MAP_SOLAN][x][y] != SECT_NTREE && map_sector[MAP_SOLAN][x][y] != SECT_NSTONE && map_sector[MAP_SOLAN][x][y] != SECT_SGOLD && map_sector[MAP_SOLAN][x][y] != SECT_NGOLD && map_sector[MAP_SOLAN][x][y] != SECT_SIRON && map_sector[MAP_SOLAN][x][y] != SECT_NIRON && map_sector[MAP_SOLAN][x][y] != SECT_MINEGOLD && map_sector[MAP_SOLAN][x][y] != SECT_MINEIRON && map_sector[MAP_SOLAN][x][y] != SECT_FOREST && map_sector[MAP_SOLAN][x][y] != SECT_STONE && map_sector[MAP_SOLAN][x][y] != SECT_HCORN && map_sector[MAP_SOLAN][x][y] != SECT_HGRAIN) { resource_sector[MAP_SOLAN][x][y] = 0; changed++; } } } ch_printf(ch, "%d resource sectors have been changed.\n\r", changed); return; } if (!str_cmp(arg1, "putstones")) { int x, y, sx, sy; for (x = 1; x <= MAX_X; x++) { for (y = 1; y <= MAX_Y; y++) { fnd = 0; if (map_sector[MAP_SOLAN][x][y] == SECT_FIELD || map_sector[MAP_SOLAN][x][y] == SECT_HILLS || map_sector[MAP_SOLAN][x][y] == SECT_JUNGLE || map_sector[MAP_SOLAN][x][y] == SECT_SWAMP || map_sector[MAP_SOLAN][x][y] == SECT_PLAINS) { for (sx = x - 3; sx <= x + 3; sx++) { for (sy = y - 3; sy <= y + 3; sy++) { if (map_sector[MAP_SOLAN][sx][sy] == SECT_RIVER) { if (number_range(1, 6) == 3) { map_sector[MAP_SOLAN][x][y] = SECT_STONE; resource_sector[MAP_SOLAN][x][y] = 6000; fnd = 1; } else fnd = 1; } if (fnd == 1) break; } if (fnd == 1) break; } } } } } if (!str_cmp(arg1, "exit")) { ROOM_INDEX_DATA *location; char arg2[MIL]; int vnum; if (!IS_ONMAP_FLAG(ch)) { send_to_char("This command can only be used from an overland map.\n\r", ch); return; } if (ch->map == -1) { bug("do_mapedit: %s is not on a valid map!", ch->name); send_to_char("Can't do that - your on an invalid map.\n\r", ch); return; } argument = one_argument(argument, arg2); if (arg2[0] == '\0') { send_to_char("Usage: mapedit exit <vnum>\n\r", ch); send_to_char("Usage: mapedit exit map <mapname> <X> <Y>\n\r", ch); return; } if (!str_cmp(arg2, "map")) { char arg3[MIL]; char arg4[MIL]; int x, y; int map = -1; argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); if (!IS_ONMAP_FLAG(ch)) { send_to_char("This command can only be used from an overland map.\n\r", ch); return; } if (arg3[0] == '\0') { send_to_char("Make an exit to what map??\n\r", ch); return; } if (!str_cmp(arg3, "solan")) map = MAP_SOLAN; if (map == -1) { ch_printf(ch, "There isn't a map for '%s'.\n\r", arg3); return; } x = atoi(arg4); y = atoi(argument); if (x < 1 || x > MAX_X) { sprintf(buf, "Valid x coordinates are 1 to %d.\n\r", MAX_X); send_to_char(buf, ch); return; } if (y < 1 || y > MAX_Y) { sprintf(buf, "Valid y coordinates are 1 to %d.\n\r", MAX_Y); send_to_char(buf, ch); return; } add_entrance(map, ch->map, ch->coord->x, ch->coord->y, x, y, -1); ch_printf(ch, "Exit created to map of %s, at %dX, %dY.\n\r", arg3, x, y); map_sector[ch->map][ch->coord->x][ch->coord->y] = SECT_EXIT; return; } vnum = atoi(arg2); if ((location = get_room_index(vnum)) == NULL) { send_to_char("No such room exists.\n\r", ch); return; } add_entrance(-1, ch->map, ch->coord->x, ch->coord->y, -1, -1, vnum); ch_printf(ch, "Exit created to room %d.\n\r", vnum); map_sector[ch->map][ch->coord->x][ch->coord->y] = SECT_EXIT; return; } if (!str_cmp(arg1, "save")) { char buf[MSL]; int map = -1; if (!IS_ONMAP_FLAG(ch)) { send_to_char("This command can only be used from an overland map.\n\r", ch); return; } if (argument[0] == '\0') { char *mapname; if (ch->map == -1) { bug("do_mapedit: %s is not on a valid map!", ch->name); send_to_char("Can't do that - your on an invalid map.\n\r", ch); return; } mapname = map_name[ch->map]; sprintf(buf, "Saving map of %s....\n\r", mapname); send_to_pager(buf, ch); save_map(mapname, ch->map); return; } if (!str_cmp(argument, "solan")) map = MAP_SOLAN; if (map == -1) { ch_printf(ch, "There isn't a map for '%s'.\n\r", arg1); return; } sprintf(buf, "Saving map of %s....", argument); send_to_pager(buf, ch); save_map(argument, map); return; } if (!str_cmp(arg1, "saveoutline")) { char buf[MSL]; int map = -1; if (!IS_ONMAP_FLAG(ch)) { send_to_char("This command can only be used from an overland map.\n\r", ch); return; } if (argument[0] == '\0') { char *mapname; if (ch->map == -1) { bug("do_mapedit: %s is not on a valid map!", ch->name); send_to_char("Can't do that - your on an invalid map.\n\r", ch); return; } mapname = map_name[ch->map]; sprintf(buf, "Saving mapoutline of %s....\n\r", mapname); send_to_pager(buf, ch); save_mapoutline(mapname, ch->map); return; } if (!str_cmp(argument, "solan")) map = MAP_SOLAN; if (map == -1) { ch_printf(ch, "There isn't a map for '%s'.\n\r", arg1); return; } sprintf(buf, "Saving mapoutline of %s....", argument); send_to_pager(buf, ch); save_mapoutline(argument, map); return; } if (!str_cmp(arg1, "sector")) { char arg2[MIL]; argument = one_argument(argument, arg2); if (!IS_ONMAP_FLAG(ch)) { send_to_char("This command can only be used from an overland map.\n\r", ch); return; } if (isalpha(arg2[0])) { send_to_char("Only takes numeric values, help sectortypes", ch); return; } value = atoi(arg2); if (value < 0 || value >= SECT_MAX) { send_to_char("Invalid sector type.\n\r", ch); return; } if (!str_cmp(arg2, "exit")) { send_to_char("You cannot place exits this way.\n\r", ch); send_to_char("Usage: mapedit exit <vnum>\n\r", ch); send_to_char("Usage: mapedit exit map <mapname> <X> <Y>\n\r", ch); return; } ch->pcdata->secedit = value; ch_printf(ch, "&YYou are now creating %s sectors.\n\r", sect_show[value].desc); return; } send_to_char("Usage: mapedit sector <sector number>\n\r", ch); send_to_char("Usage: mapedit save <mapname>\n\r", ch); send_to_char("Usage: mapedit exit <vnum>\n\r", ch); send_to_char("Usage: mapedit exit map <mapname> <X> <Y>\n\r", ch); return; } //Moves a block of wilderness to a different block, BE CAREFUL when using, it isn't meant to be used more than once or twice void do_blockmove(CHAR_DATA *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; char arg4[MIL]; char arg5[MIL]; ENTRANCE_DATA *enter; ROOM_INDEX_DATA *room; EXIT_DATA *pexit; int xstart, ystart, xend, yend, xshift, yshift, x, y; WBLOCK_DATA *wblock; WBLOCK_DATA *sblock; if (IS_NPC(ch)) { send_to_char("NPCs cannot do this.\n\r", ch); return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); argument = one_argument(argument, arg5); if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' || arg4[0] == '\0' || arg5[0] == '\0' || argument[0] == '\0') { send_to_char("Syntax: blockmove <startx> <starty> <endx> <endy> <xshift> <yshift>\n\r", ch); send_to_char("WARNING: This command moves a block of sectors and remaps it to the new shift location.\n\r It then deletes the block you shifted, so make a backup.\n\r", ch); return; } xstart = atoi(arg1); ystart = atoi(arg2); xend = atoi(arg3); yend = atoi(arg4); xshift = atoi(arg5); yshift = atoi(argument); if (xstart < 1 || xstart > MAX_X || ystart < 1 || ystart > MAX_Y || xend < 1 || xend > MAX_X || yend < 1 || yend > MAX_Y) { ch_printf(ch, "Valid coordinates are from 1 to %d.\n\r", MAX_X); return; } if (xend < xstart) { send_to_char("Invalid X range specified.\n\r", ch); return; } if (yend < ystart) { send_to_char("Invalid Y range specified.\n\r", ch); return; } if (xshift < 0) { if (xshift < -MAX_X) { ch_printf(ch, "xshift cannot be less than %d.\n\r", MAX_X*-1); return; } if (xstart + xshift < 1) { send_to_char("When applying the xshift, the startx value will be less than 1.\n\r", ch); return; } } else { if (xshift > MAX_X) { ch_printf(ch, "xshift cannot be greater than %d.\n\r", MAX_X); return; } if (xend + xshift > MAX_X) { ch_printf(ch, "When applying the xshift, the endx value will be greater than %d.\n\r", MAX_X); return; } } if (yshift < 0) { if (yshift < -MAX_Y) { ch_printf(ch, "yxshift cannot be less than %d.\n\r", MAX_Y*-1); return; } if (ystart + yshift < 1) { send_to_char("When applying the yshift, the starty value will be less than 1.\n\r", ch); return; } } else { if (yshift > MAX_Y) { ch_printf(ch, "yshift cannot be greater than %d.\n\r", MAX_Y); return; } if (yend + yshift > MAX_Y) { ch_printf(ch, "When applying the yshift, the endx value will be greater than %d.\n\r", MAX_X); return; } } for (y = ystart; y < yend + 1; y++) { for (x = xstart; x < xend + 1; x++) { map_sector[ch->map][x+xshift][y+yshift] = map_sector[ch->map][x][y]; } } for (y = ystart; y < yend + 1; y++) { for (x = xstart; x < xend + 1; x++) { map_sector[ch->map][x][y] = SECT_FIELD; } } for (y = ystart; y < yend + 1; y++) { for (x = xstart; x < xend + 1; x++) { resource_sector[ch->map][x+xshift][y+yshift] = resource_sector[ch->map][x][y]; } } for (y = ystart; y < yend + 1; y++) { for (x = xstart; x < xend + 1; x++) { resource_sector[ch->map][x][y] = 0; } } ch_printf(ch, "All map sectors between %dX %dY and %dX %dY shifted %dX and %dY.\n\r", xstart, ystart, xend, yend, xshift, yshift); //do exits now for (enter = first_entrance; enter; enter = enter->next) { if (enter->here->x >= xstart && enter->here->x <= xend && enter->here->y >= ystart && enter->here->y <= yend) { room = get_room_index(enter->vnum); for (pexit = room->first_exit; pexit; pexit = pexit->next) { if (pexit->coord && pexit->coord->x >= xstart && pexit->coord->y <= xend && pexit->coord->y >= ystart && pexit->coord->y <= yend) { pexit->coord->x += xshift; pexit->coord->y += yshift; fold_area(room->area, room->area->filename, FALSE, 1); } } } } ch_printf(ch, "All areas with exits out into the block have been corrected.\n\r", ch); for (enter = first_entrance; enter; enter = enter->next) { if (enter->here->x >= xstart && enter->here->x <= xend && enter->here->y >= ystart && enter->here->y <= yend) { enter->here->x += xshift; enter->here->y += yshift; } } send_to_char("All Entrances in the block area have been shifted to their correct spots.\n\r", ch); xstart = (xstart /50); xstart = xstart * 50; xend = (xend /50)+1; xend = xend * 50 - 1; ystart = (ystart /50); ystart = ystart * 50; yend = (yend /50)+1; yend = yend * 50 - 1; for (wblock = first_wblock; wblock; wblock = wblock->next) { if (wblock->stx >= xstart && wblock->sty >= ystart && wblock->endx <= xend && wblock->endy <= yend) { for (sblock = first_wblock; sblock; sblock = sblock->next) { if (wblock->stx+xshift == sblock->stx && wblock->sty+yshift == sblock->sty) { sblock->lvl = wblock->lvl; wblock->lvl = 10; sblock->kills = wblock->kills; wblock->kills = 0; } } } } return; } //Replaces all sectors in a certain direction till it meets a certain sectortype, good for fill out //an outline void do_mapline(CHAR_DATA *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; char arg4[MIL]; char arg5[MIL]; int max; int skip; int cnt; int x; int y; if (IS_NPC(ch)) { send_to_char("NPCs cannot edit the overland maps.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("Syntax: mapline <dir> <start> <end> <new sector> <till sector> [skips]\n\r", ch); send_to_char(" dir: 0 - North, 1 - East, 2 - South, 3 - West\n\r", ch); return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); argument = one_argument(argument, arg5); if (atoi(arg1) < 0 || atoi(arg1) > 3) { send_to_char("Direction is 0 to 3.\n\r", ch); return; } if (atoi(arg1) == 0 || atoi(arg1) == 2) max = MAX_X; else max = MAX_Y; if (atoi(arg2) < 1 || atoi(arg2) > max) { send_to_char("That is not a valid starting coordinate.\n\r", ch); return; } if (atoi(arg3) < 1 || atoi(arg3) > max) { send_to_char("That is not a valid ending coordinate.\n\r", ch); return; } if (atoi(arg3) < atoi(arg2)) { send_to_char("That is not a valid range.\n\r", ch); return; } if (atoi(arg4) < 0 || atoi(arg4) > SECT_MAX) { send_to_char("That is not a valid sectortype.\n\r", ch); return; } if (atoi(arg5) < 0 || atoi(arg5) > SECT_MAX) { send_to_char("That is not a valid sectortype.\n\r", ch); return; } if (atoi(argument) > 0) skip = atoi(argument); else skip = 0; if (atoi(arg1) == 0 || atoi(arg1) == 2) { for (x = atoi(arg2); x <= atoi(arg3); x++) { cnt = 0; if (atoi(arg1) == 0) { for (y = ch->coord->y; y >= 1; y--) { if (map_sector[ch->map][x][y] == atoi(arg5)) { if (skip == 0) break; else { if (cnt == skip) break; else cnt++; } } map_sector[ch->map][x][y] = atoi(arg4); } } else { for (y = ch->coord->y; y <= MAX_Y; y++) { if (map_sector[ch->map][x][y] == atoi(arg5)) { if (skip == 0) break; else { if (cnt == skip) break; else cnt++; } } map_sector[ch->map][x][y] = atoi(arg4); } } } send_to_char("Done.\n\r", ch); return; } else { for (y = atoi(arg2); y <= atoi(arg3); y++) { cnt = 0; if (atoi(arg1) == 3) { for (x = ch->coord->x; x >= 1; x--) { if (map_sector[ch->map][x][y] == atoi(arg5)) { if (skip == 0) break; else { if (cnt == skip) break; else cnt++; } } map_sector[ch->map][x][y] = atoi(arg4); } } else { for (x = ch->coord->x; x <= MAX_X; x++) { if (map_sector[ch->map][x][y] == atoi(arg5)) { if (skip == 0) break; else { if (cnt == skip) break; else cnt++; } } map_sector[ch->map][x][y] = atoi(arg4); } } } send_to_char("Done.\n\r", ch); return; } do_mapline(ch, ""); return; } void do_mapat(CHAR_DATA * ch, char *argument) { char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; char arg4[MIL]; char arg5[MIL]; char arg6[MIL]; char buf[MSL]; int count, cx; int fnd = 0; int keep[10]; //Max 10 int xstart, ystart, xend, yend, sector, x, y; count = -1; if (IS_NPC(ch)) { send_to_char("NPCs cannot edit the overland maps.\n\r", ch); return; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); argument = one_argument(argument, arg4); argument = one_argument(argument, arg5); if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' || arg4[0] == '\0' || arg5[0] == '\0') { send_to_char ("Usage: mapat <startx> <starty> <endx> <endy> <sectortype> <keep sectors>\n\rKeep Sectors has a limit of 10 sectors, values only.\n\r", ch); return; } xstart = atoi(arg1); ystart = atoi(arg2); xend = atoi(arg3); yend = atoi(arg4); if (xstart < 1 || xstart > MAX_X || ystart < 1 || ystart > MAX_Y || xend < 1 || xend > MAX_X || yend < 1 || yend > MAX_Y) { sprintf(buf, "Valid coordinates are from 1 to %d.\n\r", MAX_X); send_to_char(buf, ch); return; } if (xend < xstart) { send_to_char("Invalid X range specified.\n\r", ch); return; } if (yend < ystart) { send_to_char("Invalid Y range specified.\n\r", ch); return; } sector = atoi(arg5); if (sector < 0 || sector > SECT_MAX) { send_to_char("Invalid sector type.\n\r", ch); return; } if (sector == SECT_EXIT) { send_to_char("Exits cannot be range edited!\n\r", ch); return; } for (;;) { if (argument[0] == '\0') { break; } else { if (count == 9) { send_to_char("You can only have 10 do not change values.\n\r", ch); return; } else { count++; argument = one_argument(argument, arg6); keep[count] = atoi(arg6); } } } for (y = ystart; y < yend + 1; y++) { for (x = xstart; x < xend + 1; x++) { fnd = 0; if (count != -1) { for (cx = 0; cx <= count; cx++) { if (map_sector[ch->map][x][y] == keep[cx]) fnd = 1; } } if (fnd == 1) continue; if (map_sector[ch->map][x][y] != SECT_EXIT) map_sector[ch->map][x][y] = sector; } } ch_printf(ch, "All map sectors between %dX %dY and %dX %dY changed to %d.\n\r", xstart, ystart, xend, yend, sector); }