asgard/
asgard/.settings/
asgard/area/
asgard/data/clans/
asgard/data/clans/history/
asgard/data/rosters/
asgard/src/notice/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 **************************************************************************/

/***************************************************************************
 *       ROM 2.4 is copyright 1993-1996 Russ Taylor                         *
 *       ROM has been brought to you by the ROM consortium                  *
 *           Russ Taylor (rtaylor@efn.org)                                  *
 *           Gabrielle Taylor                                               *
 *           Brian Moore (zump@rom.org)                                     *
 *       By using this code, you have agreed to follow the terms of the     *
 *       ROM license, in the file Rom24/doc/rom.license                     *
 ***************************************************************************/

#if defined( macintosh )
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "tables.h"
#include "recycle.h"
#include "olc.h"
#include "interp.h"

bool change_exitargs( ( CHAR_DATA *ch, char *argument, int door ) );

void save_area(AREA_DATA *pArea);
void save_houseargs( ( ) );
void home_sell(CHAR_DATA *ch, int cost);
CHAR_DATA * find_architectargs( ( CHAR_DATA * ch ) );
HOUSE_DATA *house_list;

#define MAX_HORESET	5
#define MAX_HMRESETS	5

#define VNUM_START 5800
#define VNUM_STOP  5999

CHAR_DATA * find_architect(CHAR_DATA *ch)
{
	CHAR_DATA * architect;

	for (architect = ch->in_room->people; architect != NULL; architect
			= architect->next_in_room)
	{
		if (!IS_NPC(architect))
			continue;

		if (architect->spec_fun == spec_lookup("spec_architect"))
			return architect;
	}

	if (architect == NULL || architect->spec_fun != spec_lookup(
			"spec_architect"))
	{
		send_to_char("You can't do that here, find an Architect.\n\r", ch);
		return NULL;
	}

	if (architect->fighting != NULL)
	{
		send_to_char("Wait until the fighting stops.\n\r", ch);
		return NULL;
	}

	return NULL;
}

void do_objbuy(CHAR_DATA *ch, char *argument)
{
	char arg[MSL];
	char arg1[MSL];
	char buf[MSL];
	OBJ_DATA *obj;
	HOUSE_DATA *hOuse;
	int i;

	argument = one_argument(argument, arg);
	argument = one_argument(argument, arg1);

	if (!HAS_HOME(ch))
	{
		send_to_char("If you only had a home...\n\r", ch);
		return;
	}

	if (!IS_HOME(ch))
	{
		send_to_char("You gotta be in your house.\n\r", ch);
		return;
	}

	if (arg[0] == '\0')
	{
		send_to_char("Syntax: objbuy <list>\n\rSyntax: objbuy buy <name>", ch);
		return;
	}

	if (!str_cmp(arg, "list"))
	{
		send_to_char("The following objects are available for purchase:\n\r",
				ch);
		send_to_char("{cName:             Cost:{x\n\r", ch);
		send_to_char("{Y========================{x\n\r", ch);
		for (i = 0; house_table[i].name != NULL; i++)
		{
			if (house_table[i].type != OBJ_VNUM)
				continue;
			printf_to_char(ch, "%-10s        %-5d\n\r", house_table[i].name,
					house_table[i].cost);
		}

		return;
	}

	if (!str_cmp(arg, "buy"))
	{
		if (arg1[0] == '\0')
		{
			send_to_char("To buy an item type objbuy buy <item>.\n\r", ch);
			return;
		}

		for (i = 0; house_table[i].name != NULL; i++)
		{
			if (is_name(arg1, house_table[i].name) && house_table[i].type
					== OBJ_VNUM)
			{
				if (ch->gold >= house_table[i].cost)
				{
					if ((obj = create_object(
							get_obj_index(house_table[i].vnum), ch->level))
							== NULL)
					{
						send_to_char(
								"That object could not be found contact an imm.\n\r",
								ch);
						return;
					}

					if (ch->pcdata->horesets > MAX_HORESET)
					{
						send_to_char(
								"Sorry you can only have 5 resetting objects.\n\r",
								ch);
						return;
					}

					ch->pcdata->horesets++;
					ch->gold -= house_table[i].cost;
					sprintf(buf, "%d", house_table[i].vnum);
					redit_oreset(ch, buf);
					sprintf(buf, " ");
					save_area(ch->in_room->area);

					obj = create_object(get_obj_index(house_table[i].vnum),
							ch->level);

					for (hOuse = house_list; hOuse != NULL; hOuse = hOuse->next)
					{
						if (!str_cmp(obj->name, hOuse->objname))
							break;

						hOuse = new_house();
						free_string(hOuse->oname);
						hOuse->oname = str_dup(ch->name);
						free_string(hOuse->objname);
						hOuse->objname = str_dup(obj->name);
						hOuse->ovalue = house_table[i].cost;
						hOuse->next = house_list;
						house_list = hOuse;
						save_house();
					}

					return;
				}

				else
				{
					printf_to_char(ch,
							"Sorry %s but you need %d gold for that.\n\r",
							ch->name, house_table[i].cost);
					return;
				}
			}
		}
	}

	send_to_char("To buy an item type objbuy buy <item>.\n\r", ch);
	return;
}

void do_mobbuy(CHAR_DATA *ch, char *argument)
{
	char arg[MSL];
	char arg1[MSL];
	CHAR_DATA *mob;
	char buf[MSL];
	HOUSE_DATA *hOuse;
	int i;

	argument = one_argument(argument, arg);
	argument = one_argument(argument, arg1);

	if (!HAS_HOME(ch))
	{
		send_to_char("If you only had a home...\n\r", ch);
		return;
	}

	if (!IS_HOME(ch))
	{
		send_to_char("You gotta be in your house.\n\r", ch);
		return;
	}

	if (arg[0] == '\0')
	{
		send_to_char("Syntax: mobbuy <list>\n\rSyntax: mobbuy buy <name>", ch);
		return;
	}

	if (!str_cmp(arg, "list"))
	{
		send_to_char("The following mobiles are available for purchase:\n\r",
				ch);
		send_to_char("{cName:             Cost:{x\n\r", ch);
		send_to_char("{Y========================{x\n\r", ch);
		for (i = 0; house_table[i].name != NULL; i++)
		{
			if (house_table[i].type != MOB_VNUM)
				continue;
			printf_to_char(ch, "%-10s        %-5d\n\r", house_table[i].name,
					house_table[i].cost);
		}

		return;

	}

	if (!str_cmp(arg, "buy"))
	{
		if (arg1[0] == '\0')
		{
			send_to_char("To buy an item type mobbuy buy <item>.\n\r", ch);
			return;
		}

		for (i = 0; house_table[i].name != NULL; i++)
		{
			if (is_name(arg1, house_table[i].name) && house_table[i].type
					== MOB_VNUM)
			{
				if (ch->gold >= house_table[i].cost)
				{
					mob = create_mobile(get_mob_index(house_table[i].vnum));

					if (mob == NULL)
					{
						send_to_char(
								"That mob could not be found contact an imm.\n\r",
								ch);
						return;
					}

					if (ch->pcdata->hmresets > MAX_HMRESETS)
					{
						send_to_char(
								"Sorry you can only have 5 resetting mobiles.\n\r",
								ch);
						return;
					}

					ch->pcdata->hmresets++;
					ch->gold -= house_table[i].cost;
					sprintf(buf, "%d", house_table[i].vnum);
					redit_mreset(ch, buf);
					sprintf(buf, " ");
					save_area(ch->in_room->area);

					mob = create_mobile(get_mob_index(house_table[i].vnum));

					for (hOuse = house_list; hOuse != NULL; hOuse = hOuse->next)
					{
						if (!str_cmp(mob->name, hOuse->mobname))
							break;

						hOuse = new_house();
						free_string(hOuse->oname);
						hOuse->oname = str_dup(ch->name);
						free_string(hOuse->mobname);
						hOuse->mobname = str_dup(mob->name);
						hOuse->mvalue = house_table[i].cost;
						hOuse->next = house_list;
						house_list = hOuse;
						save_house();
					}

					return;
				}

				else
				{

					printf_to_char(ch,
							"Sorry %s but you need %d gold for a %s.\n\r",
							ch->name, house_table[i].cost, house_table[i].name);
					return;
				}
			}
		}
	}

	send_to_char("Syntax: mobbuy <list>\n\rSyntax: mobbuy buy <name>", ch);
	return;
}

void do_house(CHAR_DATA *ch, char *argument)
{
	CHAR_DATA *architect;
	char arg[MIL];
	int osec;
	char buf[MSL];
	int i, i2;
	int cost = 100000;
	HOUSE_DATA *hOuse;

	architect = find_architect(ch);

	if (!architect)
		return;

	argument = one_argument(argument, arg);

	if (IS_NPC(ch))
	{
		send_to_char("Sorry, you'll have to just wander, mobile.\n\r", ch);
		return;
	}

	if (arg[0] == '\0' && HAS_HOME(ch))
	{
		send_to_char(
				"You already bought a house. To sell it type house <sell>.\n\r",
				ch);
		send_to_char("You can also value your house. Type house <value>\n\r",
				ch);
		return;
	}

	if (!str_cmp(arg, "sell") && HAS_HOME(ch))
	{
		home_sell(ch, cost);
		return;
	}

	if (!str_cmp(arg, "value") && HAS_HOME(ch))
	{
		int value, t;

		for (hOuse = house_list; hOuse != NULL; hOuse = hOuse->next)
		{
			if (!str_cmp(ch->name, hOuse->oname))
				break;

			value += (hOuse->ovalue + hOuse->mvalue);
			t++;
			save_house();

		}

		printf_to_char(ch,
				"You have a total of %d mobs and objects in your house.\n\r", t);
		printf_to_char(ch, "Your house is valued at a total of %d gold.\n\r",
				(cost / 2) + value);
		return;
	}

	if (HAS_HOME(ch))
	{
		send_to_char(
				"You already own a house. To sell it type house <sell>.\n\r",
				ch);
		return;
	}

	if (ch->gold < cost)
	{
		printf_to_char(ch, "I'm sorry but it cost %d gold to buy a house.\n\r",
				cost);
		return;
	}

	i = VNUM_START;

	while (get_room_index(i) != NULL)
	{
		i++;

		if (i > VNUM_STOP - 5)
		{
			send_to_char(
					"Sorry all of the house vnums are used up! Tell an immortal.\n\r",
					ch);
			return;
		}
	}

	send_to_char("Okay... Attempting creation of your home.\n\r\n\r", ch);
	ch->gold -= cost;
	osec = ch->pcdata->security;
	ch->pcdata->security = 5;

	for (i2 = 4; i2 >= 0; i2--)
	{
		sprintf(buf, "%d", i + i2);

		if (!redit_create(ch, buf))
		{
			send_to_char(
					"Unable to create your house. Contact an Immortal.\n\r", ch);
			return;
		}

		ch->desc->editor = ED_ROOM;
		char_from_room(ch);
		char_to_room(ch, ch->desc->pEdit);
		SET_BIT( ((ROOM_INDEX_DATA *)ch->desc->pEdit)->area->area_flags, AREA_CHANGED );
		sprintf(buf, "%s's Home", ch->name);
		redit_name(ch, buf);
	}

	/*
	 *  Link the rooms together
	 *      3
	 *      |
	 *   2--1--4
	 *      |
	 *	5
	 */

	sprintf(buf, "link %d", i + 1);
	change_exit(ch, buf, DIR_WEST);
	sprintf(buf, "link %d", i + 2);
	change_exit(ch, buf, DIR_NORTH);
	sprintf(buf, "link %d", i + 3);
	change_exit(ch, buf, DIR_EAST);
	sprintf(buf, "link %d", i + 4);
	change_exit(ch, buf, DIR_SOUTH);
	if (osec > 1)
		ch->pcdata->security = osec;
	send_to_char("\n\rHURRAY! Your house was made successfully.\n\r", ch);
	ch->pcdata->h_vnum = i;
	save_area(ch->in_room->area);
	edit_done(ch);
	return;
}

void do_hname(CHAR_DATA *ch, char *argument)
{
	int cost = 500;

	if (!HAS_HOME(ch))
	{
		send_to_char("If you only had a home...\n\r", ch);
		return;
	}

	if (!IS_HOME(ch))
	{
		send_to_char("You've got to be in your house to do that.\n\r", ch);
		return;

	}

	if (ch->gold < cost)
	{
		printf_to_char(ch,
				"It cost %d to change the name of a room in your house.\n\r",
				cost);
		return;
	}

	if (argument[0] == '\0')
	{
		send_to_char("Change the name to what?\n\r", ch);
		return;
	}

	ch->gold -= cost;
	send_to_char("Ok.\n\r", ch);
	redit_name(ch, argument);
	save_area(ch->in_room->area);
	edit_done(ch);
	return;
}

void do_hdesc(CHAR_DATA *ch, char *argument)
{
	int cost = 500;

	if (!HAS_HOME(ch))
	{
		send_to_char("If you only had a home...\n\r", ch);
		return;
	}

	if (!IS_HOME(ch))
	{
		send_to_char("You gotta be in your house.\n\r", ch);
		return;
	}

	if (ch->gold < cost)
	{
		printf_to_char(ch, "It cost % gold to change your description.\n\r",
				cost);
		return;
	}

	ch->gold -= cost;
	send_to_char("Ok.\n\r", ch);
	ch->desc->pEdit = ch->in_room;
	ch->desc->editor = 2;
	ch->pcdata->hchange = TRUE;
	redit_desc(ch, "");
	edit_done(ch);
	save_area(ch->in_room->area);
	return;
}

void do_home(CHAR_DATA *ch, char *argument)
{
	char buf[MSL];
	CHAR_DATA *victim;
	ROOM_INDEX_DATA *location;

	if (IS_NPC(ch) && IS_SET(ch->act,ACT_PET))
	{
		send_to_char("Only players can go home.\n\r", ch);
		return;
	}

	if (!HAS_HOME(ch))
	{
		send_to_char("If you only had a home...\n\r", ch);
		return;
	}

	if (IS_NPC(ch))
		location = get_room_index(ch->master->pcdata->h_vnum);
	else
		location = get_room_index(ch->pcdata->h_vnum);

	if (location == NULL)
	{
		send_to_char(
				"Yikes write a note to immortal and let them know your house is Null.\n\r",
				ch);
		return;
	}

	act("$n prays for transportation!", ch, 0, 0, TO_ROOM );

	if (ch->in_room == location)
		return;

	if (IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)
			|| IS_AFFECTED(ch, AFF_CURSE))
	{
		send_to_char("Immortals have forsaken you.\n\r", ch);
		return;
	}

	if ((victim = ch->fighting) != NULL)
	{
		int lose, skill;

		skill = get_skill(ch, skill_lookup("recall"));

		if (number_percent() < 80 * skill / 100)
		{
			check_improve(ch, skill_lookup("recall"), FALSE, 6);
			WAIT_STATE( ch, 4 )
;			sprintf( buf, "You failed!.\n\r");
			send_to_char( buf, ch );
			return;
		}

		lose = (ch->desc != NULL) ? 25 : 50;
		gain_exp( ch, 0 - lose );
		check_improve(ch,skill_lookup("recall"),TRUE,4);
		sprintf( buf, "You recall from combat!  You lose %d exps.\n\r", lose );
		send_to_char( buf, ch );
		stop_fighting( ch, TRUE );
	}

	act( "$n disappears.", ch, NULL, NULL, TO_ROOM );

	char_from_room( ch );
	char_to_room( ch, location );
	act( "$n appears in the room.", ch, NULL, NULL, TO_ROOM );
	do_look( ch, "auto" );

	if (ch->pet != NULL)
	do_home(ch->pet,"");

	if (ch->mount != NULL)
	{
		char_from_room( ch->mount );
		char_to_room( ch->mount, ch->in_room );
	}

	return;
}

void do_invite(CHAR_DATA *ch, char *argument)
{
	CHAR_DATA *victim;
	char buf[MSL];

	if (argument[0] == '\0')
	{
		send_to_char("Invite whom to your home?\n\r", ch);
		return;
	}

	if ((victim = get_char_world(ch, argument)) == NULL)
	{
		send_to_char("Who is that?\n\r", ch);
		return;
	}

	if (!IS_HOME(ch))
	{
		send_to_char(
				"Can't invite someone to your house when you aren't in it.\n\r",
				ch);
		return;
	}

	if (ch == victim)
	{
		send_to_char("Lonely person, huh?\n\r", ch);
		return;
	}

	sprintf(buf, "%s has invited you to come to their house!\n\r", ch->name);
	send_to_char(buf, victim);

	send_to_char("You have invited them to come in.\n\r", ch);
	victim->pcdata->hinvite = ch->pcdata->h_vnum;
}

void do_join(CHAR_DATA *ch, char *argument)
{
	int ohvnum = 0;

	if (ch->pcdata->hinvite == 0)
	{
		send_to_char("You haven't been invited anywhere.\n\r", ch);
		return;
	}

	ohvnum = ch->pcdata->h_vnum;
	ch->pcdata->h_vnum = ch->pcdata->hinvite;
	do_home(ch, "");
	ch->pcdata->h_vnum = ohvnum;
	ch->pcdata->hinvite = 0;
}

void home_sell(CHAR_DATA *ch, int cost)
{
	char buf[MSL];
	int i, t;
	HOUSE_DATA *hOuse;
	int value;

	send_to_char("Ok. Attempting to sell your home.\n\r\n\r", ch);

	for (i = ch->pcdata->h_vnum; i < ch->pcdata->h_vnum + 5; i++)
	{
		sprintf(buf, "%d", i);
		redit_delete(ch, buf);
	}

	if (ch->pcdata->security <= 5)
		ch->pcdata->security = 0;
	ch->gold += (cost / 2);
	ch->pcdata->h_vnum = 0;
	send_to_char("\n\rYou have successfully sold your house.\n\r", ch);

	for (hOuse = house_list; hOuse != NULL; hOuse = hOuse->next)
	{
		if (!str_cmp(ch->name, hOuse->oname))
			break;

		value += (hOuse->ovalue + hOuse->mvalue);
		t++;
		save_house();
	}

	printf_to_char(ch, "You recieve %d gold for selling it.\n\r", (cost / 2)
			+ value);
	printf_to_char(ch,
			"You had a total of %d mobs and objects in your house.\n\r", t);
	return;
}

void do_boot(CHAR_DATA *ch, char *argument)
{
	CHAR_DATA *victim;

	if (argument[0] == '\0')
	{
		send_to_char("Who would you like to boot out of your house?\n\r", ch);
		return;
	}

	if ((victim = get_char_world(ch, argument)) == NULL)
	{
		send_to_char("Who is that?\n\r", ch);
		return;
	}

	if (!IS_HOME(ch))
	{
		send_to_char("You can't boot someone if your not in your house!\n\r",
				ch);
		return;
	}

	if ((victim->in_room->vnum < ch->pcdata->h_vnum) || (victim->in_room->vnum
			> ch->pcdata->h_vnum + 4))
	{
		send_to_char("You can't boot someone if their not in your house!\n\r",
				ch);
		return;
	}

	printf_to_char(
			ch,
			"You get in %s's face and yell at %s to get out of your house!\n\r",
			victim->name, victim->sex == 0 ? "It" : victim->sex == 1 ? "Him"
					: "Her");
	printf_to_char(
			victim,
			"%s begins yelling at you, and tells you to get out of %s house!\n\r",
			ch->name, ch->sex == 0 ? "It's" : ch->sex == 1 ? "His" : "Her");
	printf_to_char(victim, "You have been kicked out of %s's house!\n\r",
			ch->name);
	do_recall(victim, "");
	return;
}

void save_house()
{
	FILE *fp;
	HOUSE_DATA *hOuse;

	if ((fp = file_open(HOUSE_FILE, "w")) == NULL)
	{
		logf2("The house file is gone!\n\r");
		return;
	}

	for (hOuse = house_list; hOuse != NULL; hOuse = hOuse->next)
	{
		fprintf(fp, "Oname %s~\n", hOuse->oname);
		fprintf(fp, "Objname %s~\n", hOuse->objname);
		fprintf(fp, "Mobname %s~\n", hOuse->mobname);
		fprintf(fp, "Ovalue %d\n", hOuse->ovalue);
		fprintf(fp, "Mvalue %d\n\n", hOuse->mvalue);
	}

	fprintf(fp, "$\n");
	logf2("House saved.");
	file_close(fp);
	return;
}

void load_house()
{
	FILE *fp;
	char *word;
	HOUSE_DATA *hlist;
	HOUSE_DATA *hOuse;

	if (file_exists(HOUSE_FILE))
	{
		fp = file_open(HOUSE_FILE, "r");

		hlist = NULL;

		for (;;)
		{
			word = feof(fp) ? "End" : fread_word(fp);

			if (word[0] == '$')
				return;

			if (!str_cmp(word, "Oname"))
			{
				hOuse = new_house();
				if (house_list == NULL)
					house_list = hOuse;
				else
					hlist->next = hOuse;
				hlist = hOuse;
				hOuse->oname = str_dup(fread_string(fp));
			}

			if (!str_cmp(word, "Objname"))
				hOuse->objname = str_dup(fread_string(fp));

			if (!str_cmp(word, "Mobname"))
				hOuse->mobname = str_dup(fread_string(fp));

			if (!str_cmp(word, "Ovalue"))
				hOuse->ovalue = fread_number(fp);

			if (!str_cmp(word, "Mvalue"))
				hOuse->mvalue = fread_number(fp);
		}
	}

	return;

}