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