/******************************************************************************
 Snippet: Wilderness system (v1.0).
 Author:  Richard Woolcock (aka KaVir).
 Date:    2nd September 1998.
 ******************************************************************************
 File:    wild_cmd.c
 Purpose: Deals with wilderness commands.
 ******************************************************************************
 This code is copyright (C) 1998 by Richard Woolcock.  It may be used and
 distributed freely, as long as you do not remove this copyright notice.
 ******************************************************************************/

/******************************************************************************
 Required libraries
 ******************************************************************************/

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "wild.h"

/******************************************************************************
 Local operation prototypes
 ******************************************************************************/

void	smooth_water	args( ( int x, int y ) );

/******************************************************************************
 Global operations
 ******************************************************************************/

/* Command to save all/part of the wilderness. */
void do_wsave( CHAR_DATA *ch, char *argument )
{
    char arg [MAX_INPUT_LENGTH];
    int x, y;

    one_argument( argument, arg );

    if (arg[0] == '\0')
    {
	send_to_char("Wsave should be one of: zone, world, auto.\n\r",ch);
	return;
    }

    if (!str_cmp(arg,"world"))
    {
	for ( x = 0; x < 10; x++ )
	{
	    for ( y = 0; y < 10; y++ )
	    {
		wild_write(x,y);
	    }
	}
	send_to_char("World saved.\n\r",ch);
	return;
    }

    if (!str_cmp(arg,"zone"))
    {
	if (ch->x < 0 || ch->x >= WILDERNESS_SIZE || 
	    ch->y < 0 || ch->y >= WILDERNESS_SIZE)
	{
	    send_to_char("You are not in a wilderness zone.\n\r",ch);
	    return;
	}
	x = ch->x / 100;
	y = ch->y / 100;
	wild_write(x,y);
	send_to_char("Zone saved.\n\r",ch);
	return;
    }

    if (!str_cmp(arg,"auto"))
    {
	if (check_world_saving())
	{
	    send_to_char("The world is no longer autosaving.\n\r",ch);
	    set_world_saving( FALSE );
	}
	else
	{
	    send_to_char("The world is now autosaving.\n\r",ch);
	    set_world_saving( TRUE );
	}
	return;
    }

    do_wsave(ch,"");

    return;
}

/* Immortal command for initially evolving the wilderness */
void do_evolve( CHAR_DATA *ch, char *argument )
{
    char arg [MAX_INPUT_LENGTH];
    int xx, yy, xxx, yyy, rand_num, chance = 0;

    one_argument( argument, arg );

    if (arg[0] == '\0')
    {
	send_to_char("Evolve what? Forest, Water or Mountains?\n\r",ch);
	return;
    }
    if ( !str_cmp(arg,"forest") )
    {
    	for ( xx = 0; xx < 1000; xx++ )
    	{
	    for ( yy = 0; yy < 1000; yy++ )
	    {
	    	if (map_data(xx,yy) != WILD_FOREST_1 &&
		    map_data(xx,yy) != WILD_FOREST_2 &&
		    map_data(xx,yy) != WILD_FOREST_3 &&
		    map_data(xx,yy) != WILD_FOREST_4) continue;
	    	rand_num = number_range(1,10);
	    	switch (map_data(xx,yy))
	    	{
		    default: break;
		    case WILD_FOREST_1:
		    	if (rand_num <= 6)
			    set_map_data(xx, yy, WILD_FOREST_2);
		    	chance = 0;
		    	break;
		    case WILD_FOREST_2:
		    	if (rand_num <= 4)
			    set_map_data(xx, yy, WILD_FOREST_3);
		    	chance = 2;
		    	break;
		    case WILD_FOREST_3:
		    	if (rand_num <= 2)
			    set_map_data(xx, yy, WILD_FOREST_4);
		    	chance = 4;
		    	break;
		    case WILD_FOREST_4:
		    	chance = 6;
		    	break;
	        }
	    	if (number_range(1,10) < chance) continue;
	    	xxx = xx; yyy = yy;
	    	switch (number_range(1,4))
	    	{
		    default: break;
		    case 1: xxx++; if (xxx >= 1000) xxx = 0;    break;
		    case 2: xxx--; if (xxx <     0) xxx = 999; break;
		    case 3: yyy++; if (yyy >= 1000) yyy = 0;    break;
		    case 4: yyy--; if (yyy <     0) yyy = 999; break;
	    	}
	        if (map_data(xxx,yyy) != WILD_PLAINS) continue;
		set_map_data(xxx, yyy, WILD_FOREST_1);
	    }
	}
	send_to_char("Ok.\n\r",ch);
	return;
    }
    else if ( !str_cmp(arg,"water") )
    {
    	for ( xx = 0; xx < 1000; xx++ )
    	{
	    for ( yy = 0; yy < 1000; yy++ )
	    {
	    	if (map_data(xx,yy) == WILD_WATER_1)
		    set_map_data(xx, yy, WILD_WATER_DEEP_1);
	    	else if (map_data(xx,yy) == WILD_WATER_2)
		    set_map_data(xx, yy, WILD_WATER_DEEP_2);
	    }
	}
    	for ( xx = 0; xx < 1000; xx++ )
    	{
	    for ( yy = 0; yy < 1000; yy++ )
	    {
	    	if (map_data(xx,yy) != WILD_WATER_DEEP_1 &&
		    map_data(xx,yy) != WILD_WATER_DEEP_2) continue;
	    	xxx = xx; yyy = yy;
	    	switch (number_range(1,4))
	    	{
		    default: break;
		    case 1: xxx++; if (xxx >= 1000) xxx = 0;    break;
		    case 2: xxx--; if (xxx <     0) xxx = 999; break;
		    case 3: yyy++; if (yyy >= 1000) yyy = 0;    break;
		    case 4: yyy--; if (yyy <     0) yyy = 999; break;
	    	}
	        if (map_data(xxx,yyy) == WILD_AREA_LINK ||
		    map_data(xxx,yyy) == WILD_MOUNTAINS_NONE ||
		    map_data(xxx,yyy) == WILD_MOUNTAINS_STONE ||
		    map_data(xxx,yyy) == WILD_MOUNTAINS_IRON ||
		    map_data(xxx,yyy) == WILD_MOUNTAINS_GOLD ||
		    map_data(xxx,yyy) == WILD_MOUNTAINS_OIL) continue;
		if (number_range(1,3) == 1)
		    set_map_data(xxx, yyy, WILD_WATER_DEEP_2);
		else
		    set_map_data(xxx, yyy, WILD_WATER_DEEP_1);
	    }
	}
    	for ( xx = 0; xx < 1000; xx++ )
    	{
	    for ( yy = 0; yy < 1000; yy++ )
	    {
	    	if (map_data(xx,yy) != WILD_WATER_DEEP_1 &&
		    map_data(xx,yy) != WILD_WATER_DEEP_2) continue;
		smooth_water(xx,yy);
	    }
	}
	send_to_char("Ok.\n\r",ch);
	return;
    }
    if ( !str_cmp(arg,"mountains") )
    {
    	for ( xx = 0; xx < 1000; xx++ )
    	{
	    for ( yy = 0; yy < 1000; yy++ )
	    {
	    	if (map_data(xx,yy) != WILD_MOUNTAINS_NONE &&
		    map_data(xx,yy) != WILD_MOUNTAINS_STONE &&
		    map_data(xx,yy) != WILD_MOUNTAINS_IRON &&
		    map_data(xx,yy) != WILD_MOUNTAINS_GOLD &&
		    map_data(xx,yy) != WILD_MOUNTAINS_OIL ) continue;
	    	rand_num = number_range(1,20);
	    	if (map_data(xx,yy) == WILD_MOUNTAINS_NONE)
		{
		    switch (rand_num)
		    {
			default: break;
			case 1: set_map_data(xx, yy, WILD_MOUNTAINS_STONE);
				break;
			case 2: set_map_data(xx, yy, WILD_MOUNTAINS_IRON);
				break;
			case 3: set_map_data(xx, yy, WILD_MOUNTAINS_GOLD);
				break;
			case 4: set_map_data(xx, yy, WILD_MOUNTAINS_OIL);
				break;
		    }
		    chance = 0;
		    break;
	        }
	    	xxx = xx; yyy = yy;
	    	switch (number_range(1,4))
	    	{
		    default: break;
		    case 1: xxx++; if (xxx >= 1000) xxx = 0;    break;
		    case 2: xxx--; if (xxx <     0) xxx = 999; break;
		    case 3: yyy++; if (yyy >= 1000) yyy = 0;    break;
		    case 4: yyy--; if (yyy <     0) yyy = 999; break;
	    	}
	        if (map_data(xxx,yyy) != WILD_PLAINS) continue;
		set_map_data(xxx, yyy, WILD_MOUNTAINS_NONE);
	    }
	}
	send_to_char("Ok.\n\r",ch);
	return;
    }
    do_evolve(ch,"");
    return;
}

/* Immortal command to modify the landscape one room at a time. */
void do_landscape( CHAR_DATA *ch, char *argument )
{
    char arg [MAX_INPUT_LENGTH];
    int x = ch->x;
    int y = ch->y;

    one_argument( argument, arg );

    if (x < 0 || x >= 1000 || y < 0 || y >= 1000)
    {
	send_to_char("You cannot change the landscape here.\n\r",ch);
	return;
    }

    if (arg[0] == '\0')
    {
	send_to_char("Landscape type can be one of: Road Water Forest Hut Cabin Cottage House\n\rPlain Mountain.\n\r",ch);
	return;
    }
    if ( !str_cmp(arg,"road") )
	set_map_data(x, y, WILD_ROAD);
    else if ( !str_cmp(arg,"water") )
    {
	if (number_range(1,3) == 1)
	    set_map_data(x, y, WILD_WATER_2);
	else
	    set_map_data(x, y, WILD_WATER_1);
    }
    else if ( !str_cmp(arg,"forest") )
    {
	switch (number_range(1,4))
	{
	    default: set_map_data(x, y, WILD_FOREST_1); break;
	    case 2:  set_map_data(x, y, WILD_FOREST_2); break;
	    case 3:  set_map_data(x, y, WILD_FOREST_3); break;
	    case 4:  set_map_data(x, y, WILD_FOREST_4); break;
	}
    }
    else if ( !str_cmp(arg,"arealink") )
	set_map_data(x, y, WILD_AREA_LINK);
    else if ( !str_cmp(arg,"hut") )
	set_map_data(x, y, WILD_HUT);
    else if ( !str_cmp(arg,"cabin") )
	set_map_data(x, y, WILD_CABIN);
    else if ( !str_cmp(arg,"cottage") )
	set_map_data(x, y, WILD_COTTAGE);
    else if ( !str_cmp(arg,"house") )
	set_map_data(x, y, WILD_HOUSE);
    else if ( !str_cmp(arg,"plain") || !str_cmp(arg,"plains") )
	set_map_data(x, y, WILD_PLAINS);
    else if ( !str_cmp(arg,"mountain") || !str_cmp(arg,"mountains") )
    {
	switch (number_range(1,20))
	{
	    default:  set_map_data(x, y, WILD_MOUNTAINS_NONE); break;
	    case 1:
	    case 2:
	    case 4:
	    case 5:   set_map_data(x, y, WILD_MOUNTAINS_STONE); break;
	    case 6:
	    case 7:
	    case 8:   set_map_data(x, y, WILD_MOUNTAINS_IRON); break;
	    case 9:   set_map_data(x, y, WILD_MOUNTAINS_GOLD); break;
	    case 10:  set_map_data(x, y, WILD_MOUNTAINS_OIL); break;
	}
    }
    else do_landscape(ch,"");
    send_to_char("Ok.\n\r",ch);
    return;
}

/* Command to begin chopping down trees. */
void do_chop( CHAR_DATA *ch, char *argument )
{
    bool in_forest = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_FOREST_1:
	case WILD_FOREST_2:
	case WILD_FOREST_3:
	case WILD_FOREST_4:
	    in_forest = TRUE;
	    break;
    }

    if (!in_forest)
    {
	send_to_char("You can only chop down trees in the forest!\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop chopping trees.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_CHOPPING_SWING;
    ch->state = 0;
    ch->quality = number_range(25,50);
    return;
}

/* Command to begin mining for ore or oil. */
void do_mine( CHAR_DATA *ch, char *argument )
{
    bool in_mine = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_MINE_EMPTY:
	case WILD_MINE_STONE_1:
	case WILD_MINE_STONE_2:
	case WILD_MINE_IRON_1:
	case WILD_MINE_IRON_2:
	case WILD_MINE_GOLD_1:
	case WILD_MINE_GOLD_2:
	case WILD_MINE_OIL_1:
	case WILD_MINE_OIL_2:
	    in_mine = TRUE;
	    break;
    }

    if (!in_mine)
    {
	send_to_char("But you are not in a mine!\n\r",ch);
	return;
    }

    if (ch->room < 3 || ch->room > 6)
    {
	send_to_char("You cannot mine in this part.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop mining.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_MINING_CHOP;
    ch->state = 0;
    ch->quality = number_range(20,60);
    return;
}

/* Command to begin digging a mine. */
void do_dig( CHAR_DATA *ch, char *argument )
{
    bool in_mine = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_MINE_STRUCTURE_EMPTY:
	case WILD_MINE_STRUCTURE_STONE:
	case WILD_MINE_STRUCTURE_IRON:
	case WILD_MINE_STRUCTURE_GOLD:
	case WILD_MINE_STRUCTURE_OIL:
	    if (ch->room == 1) in_mine = TRUE;
	    break;
    }

    if (!in_mine)
    {
	send_to_char("You cannot dig here.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop digging.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_DIGGING_CHOP;
    ch->state = 0;
    return;
}

/* Command to begin hoeing a field. */
void do_hoe( CHAR_DATA *ch, char *argument )
{
    bool in_field = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_PLAINS:
	    in_field = TRUE;
	    break;
    }

    if (!in_field)
    {
	send_to_char("You can only hoe a plain.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop hoeing.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_HOE;
    ch->state = 0;
    return;
}

/* Command to begin seeding a hoed field. */
void do_seed( CHAR_DATA *ch, char *argument )
{
    bool in_field = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_FIELD_HOED:
	    in_field = TRUE;
	    break;
    }

    if (!in_field)
    {
	send_to_char("You can only seed a hoed field.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop seeding.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_SEED;
    ch->state = 0;
    return;
}

/* Command to begin scything a field of wheat. */
void do_scythe( CHAR_DATA *ch, char *argument )
{
    bool in_field = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_FIELD_WHEAT:
	    in_field = TRUE;
	    break;
    }

    if (!in_field)
    {
	send_to_char("You can only scythe a wheat field.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop gathering the wheat.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_SCYTHE;
    ch->state = 0;
    return;
}

/* Command to begin building a structure. */
void do_build( CHAR_DATA *ch, char *argument )
{
    bool is_mine = FALSE;
    bool can_build = FALSE;
    int  resources = 100;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_PLAINS:
	case WILD_BUILDING_CONSTRUCTION:
	    can_build = TRUE;
	    resources = 100;
	    break;
	case WILD_HUT:
	case WILD_HUT_OWNED:
	case WILD_HUT_LOCKED:
	    can_build = TRUE;
	    resources = 200;
	    break;
	case WILD_CABIN:
	case WILD_CABIN_OWNED:
	case WILD_CABIN_LOCKED:
	    can_build = TRUE;
	    resources = 300;
	    break;
	case WILD_COTTAGE:
	case WILD_COTTAGE_OWNED:
	case WILD_COTTAGE_LOCKED:
	    can_build = TRUE;
	    resources = 600;
	    break;
	case WILD_MOUNTAINS_NONE:
	case WILD_MOUNTAINS_STONE:
	case WILD_MOUNTAINS_IRON:
	case WILD_MOUNTAINS_GOLD:
	case WILD_MOUNTAINS_OIL:
	    can_build = TRUE;
	    is_mine = TRUE;
	    resources = 50;
	    break;
    }

    if (!can_build)
    {
	send_to_char("You cannot build here.\n\r",ch);
	return;
    }

    if (ch->room != 0)
    {
	send_to_char("You must stand in the entrance to the building.\n\r",ch);
	return;
    }

    if (ch->in_room->ground <= 0)
    {
	send_to_char("There are no resources in the room.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop building.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    if (ch->in_room->build <= 0) ch->in_room->build = 1;
    ch->action = WA_BUILDING_FOUNDATION;
    ch->state = 0;
    return;
}

/* Command to begin trimming a tree. */
void do_trim( CHAR_DATA *ch, char *argument )
{
    OBJ_DATA *obj;

    if ( ( obj = get_obj_here( ch, "tree" ) ) == NULL )
    {
	send_to_char("You don't see any trees to trim.\n\r",ch);
	return;
    }

    if ( obj->item_type != ITEM_RESOURCE || obj->value[1] != RESOURCE_TREE )
    {
	send_to_char("You can only trim trees.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop trimming the tree.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_TRIM;
    ch->state = 0;
    ch->quality = obj->weight;
    return;
}

/* Command to begin sawing up a log. */
void do_saw( CHAR_DATA *ch, char *argument )
{
    OBJ_DATA *obj;

    if ( ( obj = get_obj_here( ch, "log" ) ) == NULL )
    {
	send_to_char("You don't see any logs to saw up.\n\r",ch);
	return;
    }

    if ( obj->item_type != ITEM_RESOURCE || obj->value[1] != RESOURCE_LOG )
    {
	send_to_char("You can only saw up logs.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop sawing the log.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_SAW;
    ch->state = 0;
    ch->quality = obj->weight;
    return;
}

/* Command to begin laying a road. */
void do_lay( CHAR_DATA *ch, char *argument )
{
    OBJ_DATA *obj;
    bool in_plains = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_PLAINS:
	    in_plains = TRUE;
	    break;
    }

    if (!in_plains)
    {
	send_to_char("You cannot lay a road here.\n\r",ch);
	return;
    }

    if ( ( obj = get_obj_here( ch, "stone" ) ) == NULL )
    {
	send_to_char("You don't see any stones to lay.\n\r",ch);
	return;
    }

    if ( obj->item_type != ITEM_RESOURCE || obj->value[1] != RESOURCE_ROCK )
    {
	send_to_char("You can only lay stones to form a road.\n\r",ch);
	return;
    }

    if (get_eq_char(ch, WEAR_WIELD) != NULL ||
	get_eq_char(ch, WEAR_HOLD)  != NULL )
    {
	send_to_char("You need two free hands to lay a road.\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop laying the road.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_ROAD;
    ch->state = 0;
    return;
}

/* Command to begin fishing. */
void do_fish( CHAR_DATA *ch, char *argument )
{
    bool in_water = FALSE;

    if (ch->x >= 0 || ch->y >= 0) switch (map_data(ch->x,ch->y))
    {
	default: break;
	case WILD_WATER_1:
	case WILD_WATER_2:
	case WILD_WATER_DEEP_1:
	case WILD_WATER_DEEP_2:
	    in_water = TRUE;
	    break;
    }

    if (!in_water)
    {
	send_to_char("You can only go fishing in water!\n\r",ch);
	return;
    }

    if (ch->action != 0)
    {
	send_to_char("You stop fishing.\n\r",ch);
	ch->action = 0;
	ch->state = 0;
	ch->quality = 0;
	return;
    }

    send_to_char("Ok.\n\r",ch);
    ch->action = WA_FISHING_MENDING;
    ch->state = 0;
    return;
}

/* Command to prospect for resources on a mountain range. */
void do_prospect( CHAR_DATA *ch, char *argument )
{
    int x = ch->x;
    int y = ch->y;

    if (x < 0 || x >= 1000 || y < 0 || y >= 1000)
    {
	send_to_char("You cannot prospect here.\n\r",ch);
	return;
    }

    switch (map_data(x,y))
    {
	default:
	case WILD_MOUNTAINS_NONE:
	    send_to_char("Seems like a pretty rubbish place to build a mine.\n\r",ch);
	    break;
	case WILD_MOUNTAINS_STONE:
	    send_to_char("Looks like it could have potential for stone.\n\r",ch);
	    break;
	case WILD_MOUNTAINS_IRON:
	    send_to_char("Looks like it could have potential for iron.\n\r",ch);
	    break;
	case WILD_MOUNTAINS_GOLD:
	    send_to_char("Looks like it could have potential for gold.\n\r",ch);
	    break;
	case WILD_MOUNTAINS_OIL:
	    send_to_char("Looks like it could have potential for oil.\n\r",ch);
	    break;
    }

    return;
}

void do_home( CHAR_DATA *ch, char *argument )
{
    char arg [MAX_INPUT_LENGTH];
    bool found_home = FALSE;
    int x = ch->home_x;
    int y = ch->home_y;

    argument = one_argument( argument, arg );

    if ( IS_NPC(ch) ) return;

    if (ch->in_room == NULL || ch->in_room->vnum < 20000 || 
	ch->in_room->vnum >= 21000 || ch->x < 0 || ch->y < 0)
    {
	send_to_char("You can only make your home in the wilderness.\n\r",ch);
	return;
    }

    if ( arg[0] == '\0' )
    {
	send_to_char( "Syntax: home <here/new/lock>.\n\r", ch );
	return;
    }

    if (!str_cmp(arg,"lock"))
    {
	if ( ch->home_x != ch->x || ch->home_y != ch->y )
	{
	    send_to_char("But you do not even live here!\n\r",ch);
	    return;
	}

	if ( ch->room != 0 )
	{
	    send_to_char("You must stand at the front door of the building you wish to lock.\n\r",ch);
	    return;
	}

	switch (map_data(ch->x,ch->y))
	{
	    default:
		send_to_char( "But you don't even live here!\n\r", ch );
		break;
	    case WILD_HUT_OWNED:
		send_to_char("You lock the front door of your hut.\n\r",ch);
		act("$n locks the hut door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_HUT_LOCKED);
		do_wsave(ch,"zone");
		break;
	    case WILD_CABIN_OWNED:
		send_to_char("You lock the front door of your cabin.\n\r",ch);
		act("$n locks the cabin door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_CABIN_LOCKED);
		do_wsave(ch,"zone");
		break;
	    case WILD_COTTAGE_OWNED:
		send_to_char("You lock the front door of your cottage.\n\r",ch);
		act("$n locks the cottage door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_COTTAGE_LOCKED);
		do_wsave(ch,"zone");
		break;
	    case WILD_HOUSE_OWNED:
		send_to_char("You lock the front door of your house.\n\r",ch);
		act("$n locks the house door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_HOUSE_LOCKED);
		do_wsave(ch,"zone");
		break;
	    case WILD_HUT_LOCKED:
		send_to_char("You unlock the front door of your hut.\n\r",ch);
		act("$n unlocks the hut door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_HUT_OWNED);
		do_wsave(ch,"zone");
		break;
	    case WILD_CABIN_LOCKED:
		send_to_char("You unlock the front door of your cabin.\n\r",ch);
		act("$n unlocks the cabin door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_CABIN_OWNED);
		do_wsave(ch,"zone");
		break;
	    case WILD_COTTAGE_LOCKED:
		send_to_char("You unlock the front door of your cottage.\n\r",ch);
		act("$n unlocks the cottage door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_COTTAGE_OWNED);
		do_wsave(ch,"zone");
		break;
	    case WILD_HOUSE_LOCKED:
		send_to_char("You unlock the front door of your house.\n\r",ch);
		act("$n unlocks the house door.",ch,NULL,NULL,TO_ROOM);
		set_map_data(ch->x, ch->y, WILD_HOUSE_OWNED);
		do_wsave(ch,"zone");
		break;
	}
	return;
    }

    if ( (str_cmp(arg,"here") && str_cmp(arg,"new")) )
    {
	send_to_char( "If you wish this to be your home, you must type 'home here'.\n\r", ch );
	return;
    }

    if ( ch->x == ch->home_x && ch->y == ch->home_y )
    {
	send_to_char( "But this is already your home!\n\r", ch );
	return;
    }

    if ( ch->home_x >= 0 && ch->x != ch->home_x && ch->y != ch->home_y )
    {
	if ( str_cmp(arg,"new") )
	{
	    send_to_char( "To abandon your old home for here, you must type 'home new'.\n\r", ch );
	    return;
	}
    }

    switch (map_data(ch->x,ch->y))
    {
	default:
	    send_to_char( "But you are not in a building!\n\r", ch );
	    break;
	case WILD_HUT_OWNED:
	case WILD_CABIN_OWNED:
	case WILD_COTTAGE_OWNED:
	case WILD_HOUSE_OWNED:
	case WILD_HUT_LOCKED:
	case WILD_CABIN_LOCKED:
	case WILD_COTTAGE_LOCKED:
	case WILD_HOUSE_LOCKED:
	    send_to_char( "Someone else already lives here.\n\r", ch );
	    break;
	case WILD_HUT:
	    set_map_data(ch->x, ch->y, WILD_HUT_LOCKED);
	    send_to_char( "This hut is now your home.\n\r", ch );
	    ch->home_x = ch->x;
	    ch->home_y = ch->y;
	    found_home = TRUE;
	    break;
	case WILD_CABIN:
	    set_map_data(ch->x, ch->y, WILD_CABIN_LOCKED);
	    send_to_char( "This cabin is now your home.\n\r", ch );
	    ch->home_x = ch->x;
	    ch->home_y = ch->y;
	    found_home = TRUE;
	    break;
	case WILD_COTTAGE:
	    set_map_data(ch->x, ch->y, WILD_COTTAGE_LOCKED);
	    send_to_char( "This cottage is now your home.\n\r", ch );
	    ch->home_x = ch->x;
	    ch->home_y = ch->y;
	    found_home = TRUE;
	    break;
	case WILD_HOUSE:
	    set_map_data(ch->x, ch->y, WILD_HOUSE_LOCKED);
	    send_to_char( "This house is now your home.\n\r", ch );
	    ch->home_x = ch->x;
	    ch->home_y = ch->y;
	    found_home = TRUE;
	    break;
    }

    if (found_home && x >= 0 && y >= 0)
    {
	switch (map_data(x,y))
	{
	    default:
		break;
	    case WILD_HUT_OWNED:
	    case WILD_HUT_LOCKED:
		set_map_data(x, y, WILD_HUT);
		break;
	    case WILD_CABIN_OWNED:
	    case WILD_CABIN_LOCKED:
		set_map_data(x, y, WILD_CABIN);
		break;
	    case WILD_COTTAGE_OWNED:
	    case WILD_COTTAGE_LOCKED:
		set_map_data(x, y, WILD_COTTAGE);
		break;
	    case WILD_HOUSE_OWNED:
	    case WILD_HOUSE_LOCKED:
		set_map_data(x, y, WILD_HOUSE);
		break;
	}
    }
    return;
}

/******************************************************************************
 Local operations
 ******************************************************************************/

/* Operation to ensure that water edges are shallow. */
void smooth_water( int x, int y )
{
    int xx, yy, xxx, yyy;

    for ( xxx = -1; xxx < 2; xxx++ )
    {
	for ( yyy = -1; yyy < 2; yyy++ )
	{
	    xx = xxx + x;
	    yy = yyy + y;
	    if ( xx == x && yy == y ) continue;
	    while (xx <     0) xx += 1000;
	    while (xx >= 1000) xx -= 1000;
	    while (yy <     0) yy += 1000;
	    while (yy >= 1000) yy -= 1000;
	    if (map_data(xx,yy) != WILD_WATER_DEEP_1 &&
		map_data(xx,yy) != WILD_WATER_DEEP_2 &&
		map_data(xx,yy) != WILD_WATER_1 &&
		map_data(xx,yy) != WILD_WATER_2 &&
		map_data(xx,yy) != WILD_AREA_LINK)
	    {

		if (number_range(1,3) == 1) 
		    set_map_data(xx, yy, WILD_WATER_2);
		else
		    set_map_data(xx, yy, WILD_WATER_1);
	    }
	}
    }
    return;
}
