/**************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvements 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 *
* benefiting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************
* ROM 2.4 is copyright 1993-1998 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@hypercube.org) *
* Gabrielle Taylor (gtaylor@hypercube.org) *
* 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 *
***************************************************************************
* _/_/_/ _/ _/ _/ Devil's Lament MUD *
* _/ _/ _/ _/ _/ _/ (c) 1999-2002 by Ryan Jennings *
* _/ _/ _/ _/ _/ Telnet : <dlmud.com:3778> *
* _/_/_/ _/_/_/ _/ _/ E-Mail : <dlmud@dlmud.com> *
* Website: <http://www.dlmud.com/> *
***************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#if !defined(WIN32)
#include <unistd.h>
#endif
#include "merc.h"
#include "interp.h"
#include "recycle.h"
#include "olc.h"
DECLARE_DO_FUN(home_buy);
DECLARE_DO_FUN(home_add);
DECLARE_DO_FUN(home_furnish);
DECLARE_DO_FUN(home_unfurnish);
DECLARE_DO_FUN(home_sell);
DECLARE_DO_FUN(home_describe);
DECLARE_DO_FUN(home_name);
DECLARE_DO_FUN(home_evict);
DECLARE_DO_FUN(home_invite);
DECLARE_DO_FUN(home_accept);
DECLARE_DO_FUN(home_deny);
DECLARE_DO_FUN(do_get_key);
DECLARE_DO_FUN(home_help);
DECLARE_DO_FUN(home_link);
DECLARE_DO_FUN(home_unlink);
DECLARE_DO_FUN(do_gohome);
void unlink_reset(ROOM_INDEX_DATA * pRoom, RESET_DATA * pReset);
#define HOUSE_PRICE 5000000
#define ROOM_PRICE 3000000
#define H_NONE 0
#define H_OBJ 1
#define H_MOB 2
struct home_type
{
vnum_t vnum;
long cost;
int quest;
int tp;
char *name;
char *list;
int type;
};
const struct home_type home_table[] = {
{0, 125000, 10, 0, "healrate", "Up a rooms Heal Rate by 50", H_NONE},
{0, 125000, 10, 0, "manarate", "Up a rooms Mana Rate by 50", H_NONE},
/* examples
{HOME_VNUM_QUESTMASTER, 5000000, 10, 0, "questmaster", "A personal Questmaster.", H_MOB},
{HOME_VNUM_BED, 100000, 2, 0, "bed", "A double bed.", H_OBJ},
*/
{0, 0, 0, 0, NULL, NULL, 0}
};
int count_home(CHAR_DATA * ch)
{
int i, count = 0;
if (!ch || IS_NPC(ch))
return 0;
for (i = 0; i < MAX_HOUSE_ROOMS; i++)
if (ch->pcdata->home[i] > 0
&& get_room_index(ch->pcdata->home[i]) != NULL)
count++;
return count;
}
void reset_homes(CHAR_DATA * ch)
{
int i;
if (!ch || IS_NPC(ch))
return;
for (i = 0; i < MAX_HOUSE_ROOMS; i++)
ch->pcdata->home[i] = -1;
ch->pcdata->home_key = -1;
return;
}
bool is_home_owner(CHAR_DATA * ch, ROOM_INDEX_DATA * pHome)
{
int i;
if (pHome == NULL)
return FALSE;
if (!ch || IS_NPC(ch))
return FALSE;
for (i = 0; i < MAX_HOUSE_ROOMS; i++)
if (ch->pcdata->home[i] > 0
&& get_room_index(ch->pcdata->home[i]) == pHome)
return TRUE;
return FALSE;
}
int tally_resets(ROOM_INDEX_DATA * pRoom, long cost, int trivia, int quest)
{
RESET_DATA *pReset;
int rcount = 0, i;
if (pRoom == NULL)
return 0;
for (pReset = pRoom->reset_first; pReset != NULL; pReset = pReset->next)
{
if (pReset->command == 'O' || pReset->command == 'M')
{
for (i = 0; home_table[i].name != NULL; i++)
{
if (pReset->arg1 == home_table[i].vnum)
{
cost += home_table[i].cost / 3;
trivia += home_table[i].tp / 3;
quest += home_table[i].quest / 3;
rcount++;
}
}
}
}
return rcount;
}
int get_direction(const char *arg)
{
if (!str_cmp(arg, "n") || !str_cmp(arg, "north"))
return 0;
if (!str_cmp(arg, "e") || !str_cmp(arg, "east"))
return 1;
if (!str_cmp(arg, "s") || !str_cmp(arg, "south"))
return 2;
if (!str_cmp(arg, "w") || !str_cmp(arg, "west"))
return 3;
if (!str_cmp(arg, "u") || !str_cmp(arg, "up"))
return 4;
if (!str_cmp(arg, "d") || !str_cmp(arg, "down"))
return 5;
return -1;
}
bool get_key(CHAR_DATA * ch)
{
OBJ_INDEX_DATA *keyindex = NULL;
OBJ_DATA *key = NULL;
if (!ch || IS_NPC(ch) || ch->pcdata->home_key <= 0)
return FALSE;
if ((keyindex = get_obj_index(ch->pcdata->home_key)) == NULL)
{
chprintln(ch,
"Could not find your key, please have an immortal fix this.");
return FALSE;
}
if (get_obj_here(ch, NULL, keyindex->name) != NULL)
{
chprintln(ch, "You already have a key to your home.");
return TRUE;
}
if ((key = create_object(keyindex, 1)) == NULL)
return FALSE;
obj_to_char(key, ch);
chprintln(ch, "A house key appears in your inventory.");
return TRUE;
}
CH_CMD(do_get_key)
{
get_key(ch);
}
CH_CMD(home_help)
{
chprintln(ch, "Syntax(s):");
if (ch->pcdata->home_invite != 0)
{
chprintln(ch, "Accept - accept an invitation to someone's home");
chprintln(ch, "Deny - turn down an invitation to someone's home");
}
if (count_home(ch) == 0)
chprintln(ch,
"Buy - purchase a home in <direction> (must be in the right area)");
else
{
chprintln(ch,
"Sell - sells your home completly for 1/3 the price");
chprintln(ch,
"Add - adds another room in <direction>, must be in your home");
chprintln(ch, "Describe - describes a room using the string editor");
chprintln(ch, "Name - name or rename's a room");
chprintln(ch,
"Furnish - add objects or mobiles to a room in your home");
chprintln(ch,
"Unfurnish - sells objects or mobiles placed in your home");
chprintln(ch, "Key - gets a replacement key for your home");
chprintln(ch,
"Recall - recalls you to your home (gohome for short)");
chprintln(ch, "Evict - kick's someone out of your home");
chprintln(ch, "Invite - invite someone to your home");
chprintln(ch, "Link - Link a room to a specified area");
chprintln(ch, "Unlink - Unlink an exit");
}
}
CH_CMD(do_home)
{
if (!ch)
return;
if (IS_NPC(ch))
{
chprintln(ch, "Mobiles don't have homes =).");
return;
}
vinterpret(ch, argument, "buy", home_buy, "add", home_add, "sell",
home_sell, "describe", home_describe, "name", home_name,
"furnish", home_furnish, "unfurnish", home_unfurnish, "key",
do_get_key, "recall", do_gohome, "evict", home_evict, "link",
home_link, "unlink", home_unlink, "list", home_help, "invite",
home_invite, "accept", home_accept, "deny", home_deny, NULL,
home_help);
}
CH_CMD(home_buy)
{
ROOM_INDEX_DATA *pRoom = NULL;
OBJ_INDEX_DATA *pObj;
AREA_DATA *pArea;
EXIT_DATA *pExit;
char buf[MSL];
int door, rev, iHash;
vnum_t i;
if (!ch || IS_NPC(ch))
return;
pArea = ch->in_room->area;
if (!pArea || !IS_SET(pArea->area_flags, AREA_PLAYER_HOMES))
{
chprintln(ch, "Player Homes are not allowed in this area.");
return;
}
if (ch->gold < HOUSE_PRICE)
{
chprintlnf(ch, "{wIt costs %d gold to buy a home.", HOUSE_PRICE);
return;
}
if (ch->pcdata->trivia < 40)
{
chprintln(ch, "It costs 40 trivia points to buy a house.");
return;
}
if (count_home(ch) > 0)
{
chprintln(ch,
"{wYou already own a home, use HOME ADD or HOME FURNISH.");
return;
}
if (!IS_SET(ch->in_room->room_flags, HOME_ENTRANCE))
{
chprintln(ch, "You must be at an entrance to a future home.");
return;
}
if ((door = get_direction(argument)) == -1 || door > 3)
{
chprintln(ch,
"Which direction from here do you want to start your home?");
return;
}
if (ch->in_room->exit[door])
{
chprintln(ch, "A room already exits in that location.");
return;
}
for (i = pArea->min_vnum; i < pArea->max_vnum; i++)
{
if ((get_obj_index(i)) == NULL)
{
pObj = new_obj_index();
pObj->vnum = i;
pObj->area = pArea;
sprintf(buf, "key %s home", ch->name);
replace_string(pObj->name, buf);
sprintf(buf, "%s's key", capitalize(ch->name));
replace_string(pObj->short_descr, buf);
sprintf(buf, "The key to %s's home is here.", capitalize(ch->name));
replace_string(pObj->description, buf);
pObj->item_type = ITEM_KEY;
SET_BIT(pObj->wear_flags, ITEM_TAKE);
SET_BIT(pObj->wear_flags, ITEM_HOLD);
pObj->condition = -1;
iHash = i % MAX_KEY_HASH;
LINK_SINGLE(pObj, next, obj_index_hash[iHash]);
ch->pcdata->home_key = pObj->vnum;
break;
}
}
for (i = pArea->min_vnum; i < pArea->max_vnum; i++)
{
if ((get_room_index(i)) == NULL)
{
// do the room
pRoom = new_room_index();
pRoom->area = pArea;
pRoom->vnum = i;
pRoom->sector_type = SECT_INSIDE;
sprintf(buf, "%s\'s Home", capitalize(ch->name));
replace_string(pRoom->name, buf);
replace_string(pRoom->description,
"This is your desc. You can edit this with HOME DESCRIBE.\n\r");
replace_string(pRoom->owner, ch->name);
SET_BIT(pRoom->room_flags, ROOM_INDOORS);
iHash = i % MAX_KEY_HASH;
LINK_SINGLE(pRoom, next, room_index_hash[iHash]);
// do the exit
// first room
ch->in_room->exit[door] = new_exit();
ch->in_room->exit[door]->u1.to_room = pRoom;
ch->in_room->exit[door]->orig_door = door;
SET_BIT(ch->in_room->exit[door]->rs_flags,
EX_ISDOOR | EX_CLOSED | EX_NOPASS | EX_PICKPROOF);
ch->in_room->exit[door]->exit_info =
ch->in_room->exit[door]->rs_flags;
replace_string(ch->in_room->exit[door]->keyword, "door");
sprintf(buf, "You see the door to %s's home.",
capitalize(ch->name));
replace_string(ch->in_room->exit[door]->description, buf);
// end first room
rev = rev_dir[door];
// new room
pExit = new_exit();
pExit->u1.to_room = ch->in_room;
pExit->orig_door = rev;
pRoom->exit[rev] = pExit;
pRoom->exit[rev]->rs_flags = ch->in_room->exit[door]->rs_flags;
pRoom->exit[rev]->exit_info = ch->in_room->exit[door]->exit_info;
replace_string(pRoom->exit[rev]->keyword, "door");
sprintf(buf, "You see the door to %s's home.",
capitalize(ch->name));
replace_string(pRoom->exit[rev]->description, buf);
// end new room
// lock if key exits
if (get_key(ch) == TRUE)
{
SET_BIT(ch->in_room->exit[door]->rs_flags, EX_LOCKED);
ch->in_room->exit[door]->key = ch->pcdata->home_key;
pRoom->exit[rev]->key = ch->pcdata->home_key;
}
save_area(pArea);
break;
}
}
if (!pRoom)
{
chprintln(ch,
"A new home could not be created for you. please contact an immortal.");
return;
}
ch->pcdata->home[count_home(ch)] = pRoom->vnum;
ch->gold -= HOUSE_PRICE;
ch->pcdata->trivia -= 40;
chprintln(ch, "Congratulations, you are now a proud home owner.");
save_char_obj(ch);
return;
}
CH_CMD(home_add)
{
ROOM_INDEX_DATA *pRoom = NULL;
AREA_DATA *pArea;
EXIT_DATA *pExit;
char buf[MSL];
int door, rev, iHash;
vnum_t i;
if (!ch || IS_NPC(ch))
return;
pArea = ch->in_room->area;
if (!pArea || !IS_SET(pArea->area_flags, AREA_PLAYER_HOMES))
{
chprintln(ch, "Player Homes are not allowed in this area.");
return;
}
if (count_home(ch) == 0)
{
chprintln(ch, "Use HOME BUY to purchase a home first.");
return;
}
if (ch->gold < ROOM_PRICE)
{
chprintln(ch, "{wYou don't have enough to buy a another room.");
return;
}
if (ch->pcdata->questpoints < 200)
{
chprintln(ch, "{wYou need 200 questpoints to buy another room.");
return;
}
if (count_home(ch) == MAX_HOUSE_ROOMS)
{
chprintln(ch, "{wYou have the max allowable rooms in your house.");
return;
}
if (!is_home_owner(ch, ch->in_room))
{
chprintln(ch, "You must add only to your home!");
return;
}
if ((door = get_direction(argument)) == -1 || door > 3)
{
chprintln(ch, "Which direction from here do you want the new room?");
return;
}
if (ch->in_room->exit[door])
{
chprintln(ch, "A room already exits in that location.");
return;
}
for (i = pArea->min_vnum; i < pArea->max_vnum; i++)
{
if ((get_room_index(i)) == NULL)
{
// do the room
pRoom = new_room_index();
pRoom->area = pArea;
pRoom->vnum = i;
pRoom->sector_type = SECT_INSIDE;
sprintf(buf, "%s\'s %d Room", capitalize(ch->name),
count_home(ch) + 1);
replace_string(pRoom->name, buf);
replace_string(pRoom->description,
"This is your desc. You can edit this with HOME DESCRIBE.\n\r");
replace_string(pRoom->owner, ch->name);
SET_BIT(pRoom->room_flags, ROOM_INDOORS);
iHash = i % MAX_KEY_HASH;
LINK_SINGLE(pRoom, next, room_index_hash[iHash]);
// do the exit
ch->in_room->exit[door] = new_exit();
ch->in_room->exit[door]->u1.to_room = pRoom;
ch->in_room->exit[door]->orig_door = door;
rev = rev_dir[door];
pExit = new_exit();
pExit->u1.to_room = ch->in_room;
pExit->orig_door = rev;
pRoom->exit[rev] = pExit;
break;
}
}
if (!pRoom)
{
chprintln(ch,
"A new room could not be created for you. please contact an immortal.");
return;
}
ch->pcdata->home[count_home(ch)] = pRoom->vnum;
ch->gold -= ROOM_PRICE;
ch->pcdata->questpoints -= 200;
chprintln
(ch,
"The mayors hired contractors come and do additions to your home.");
chprintlnf(ch, "Your home now contains %d rooms.", count_home(ch));
save_char_obj(ch);
save_area(pArea);
return;
}
CH_CMD(home_sell)
{
ROOM_INDEX_DATA *pRoom = NULL;
int home, i = 0, rooms = 0;
long cost = 0;
int quest = 0;
int tp = 0;
char buf[MSL];
if (!ch || IS_NPC(ch))
return;
if ((rooms = count_home(ch)) == 0)
{
chprintln(ch, "You don't have a home yet.");
return;
}
if (IS_NULLSTR(argument))
{
chprintln(ch, "This command allows you to sell your home. The Mayors");
chprintln(ch,
"contractors will completly demolish your home when it is sold,");
chprintln(ch, "and you will be compensated half the cost of the home,");
chprintln(ch, "including any items you have purchased.");
chprintln(ch,
"{ROnce your home is sold, it cannot be brought back!!!{x");
chprintln(ch, "\n\rSyntax: Home (sell) (confirm)");
return;
}
else if (!str_cmp(argument, "confirm"))
{
sprintf(buf, "%ld", ch->pcdata->home_key);
oedit_delete(NULL, buf);
for (home = 0; home < MAX_HOUSE_ROOMS; home++)
{
if ((pRoom = get_room_index(ch->pcdata->home[home])) != NULL)
{
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
i += tally_resets(pRoom, cost, tp, quest);
sprintf(buf, "%ld", ch->pcdata->home[home]);
if (redit_delete(NULL, buf))
cost += ROOM_PRICE / 3;
}
}
ch->gold += cost;
ch->pcdata->trivia += tp;
ch->pcdata->questpoints += quest;
chprintlnf
(ch,
"Your home {R(%d rooms) {G(%d furnishings){x has been sold and you are now {Y%ld{x gold coins richer!",
rooms, i, cost);
reset_homes(ch);
save_char_obj(ch);
return;
}
else
{
home_sell(ch, str_empty);
return;
}
}
CH_CMD(home_describe)
{
ROOM_INDEX_DATA *loc;
char buf[MSL];
int len;
bool found = FALSE;
loc = ch->in_room;
if (!ch || IS_NPC(ch))
return;
if (count_home(ch) == 0)
{
chprintln(ch, "You have to BUY a home before you can describe it.");
return;
}
if (!is_home_owner(ch, loc))
{
chprintln(ch, "But you do not own this room!");
return;
}
if (IS_NULLSTR(argument))
{
chprintln(ch, "This command allows you to describe your home.");
chprintln(ch, "You should not describe items that are in the room,");
chprintln(ch, "rather allowing the furnishing of the home to do that.");
chprintln(ch,
"If you currently own this room, you will be placed into.");
chprintln(ch,
"the room editor. Be warned that while in the room editor,");
chprintln(ch,
"you are only allowed to type the description. If you are");
chprintln(ch,
"unsure or hesitant about this, please note the Immortals,");
chprintln(ch, "or better, discuss the how-to's with a Builder.");
chprintln(ch,
"If Using the string editor bothers you type /q on a new line\n\r"
"and use the syntax: Home describe +/- <string>{x");
string_append(ch, &loc->description);
SET_BIT(loc->area->area_flags, AREA_CHANGED);
return;
}
else
{
buf[0] = '\0';
if (argument[0] == '-')
{
if (IS_NULLSTR(loc->description))
{
chprintln(ch, "No lines left to remove.");
return;
}
strcpy(buf, loc->description);
for (len = strlen(buf); len > 0; len--)
{
if (buf[len] == '\r')
{
if (!found)
{
if (len > 0)
len--;
found = TRUE;
}
else
{
buf[len + 1] = '\0';
replace_string(loc->description, buf);
chprintln(ch, "OK.");
return;
}
}
}
buf[0] = '\0';
replace_string(loc->description, buf);
chprintln(ch, "Description cleared.");
return;
}
if (argument[0] == '+')
{
if (loc->description != NULL)
strcat(buf, loc->description);
argument++;
while (isspace(*argument))
argument++;
}
if (strlen(buf) + strlen(argument) >= MSL - 2)
{
chprintln(ch, "Description too long.");
return;
}
strcat(buf, argument);
strcat(buf, "\n\r");
replace_string(loc->description, buf);
save_area(loc->area);
}
return;
}
CH_CMD(home_name)
{
ROOM_INDEX_DATA *loc;
loc = ch->in_room;
if (!ch || IS_NPC(ch))
return;
if (count_home(ch) == 0)
{
chprintln(ch, "You have to BUY a home before you can rename it.");
return;
}
if (!is_home_owner(ch, loc))
{
chprintln(ch, "But you do not own this room!");
return;
}
if (IS_NULLSTR(argument))
{
chprintln(ch, "Change the this room title to what?");
return;
}
if (strlen_color(argument) > 25)
{
chprintln(ch, "This is the name, not the description.");
return;
}
replace_string(loc->name, argument);
save_area(loc->area);
return;
}
CH_CMD(home_furnish)
{
RESET_DATA *loc_reset, *pReset;
OBJ_DATA *furn = NULL;
OBJ_INDEX_DATA *pObj = NULL;
CHAR_DATA *moby = NULL;
MOB_INDEX_DATA *pMob = NULL;
int i;
if (!ch || IS_NPC(ch))
return;
if (count_home(ch) == 0)
{
chprintln(ch, "You have to BUY a home before you can furnish it.");
return;
}
if (!is_home_owner(ch, ch->in_room))
{
chprintln(ch, "But you do not own this room!");
return;
}
if (IS_NULLSTR(argument) || !str_cmp(argument, "list"))
{
chprintln(ch, "This command allows you to furnish your home.");
chprintln(ch,
"You must be standing in your home. You cannot have more");
chprintln(ch, "than five items and five mobiles in your home.");
chprintln(ch, "Other things like heal/mana rate have a limit instead.");
chprintln(ch, "Syntax: Home (furnish) (option)\n\r");
for (i = 0; home_table[i].name != NULL; i++)
{
chprintlnf(ch, "\t%-15s - %ld gold, %dqp, %dtp",
home_table[i].list, home_table[i].cost,
home_table[i].quest, home_table[i].tp);
}
return;
}
else
{
for (i = 0; home_table[i].name != NULL; i++)
{
if (is_name(argument, home_table[i].name))
{
if (ch->gold < home_table[i].cost)
{
chprintlnf
(ch, "You don't have enough gold for to buy a %s.",
home_table[i].name);
return;
}
if (ch->pcdata->questpoints < home_table[i].quest)
{
chprintlnf(ch, "You need %d questpoints to buy a %s.",
home_table[i].quest, home_table[i].name);
return;
}
if (ch->pcdata->trivia < home_table[i].tp)
{
chprintlnf(ch, "You need %d trivia points to buy a %s.",
home_table[i].quest, home_table[i].name);
return;
}
if (home_table[i].type == H_NONE)
{
if (!str_cmp(home_table[i].name, "healrate"))
{
if (ch->in_room->heal_rate >= 200)
{
chprintln
(ch,
"This rooms heal rate can't go any higher.");
return;
}
ch->in_room->heal_rate =
UMIN(ch->in_room->heal_rate + 50, 200);
}
if (!str_cmp(home_table[i].name, "manarate"))
{
if (ch->in_room->mana_rate >= 200)
{
chprintln
(ch,
"This rooms mana rate can't go any higher.");
return;
}
ch->in_room->mana_rate =
UMIN(ch->in_room->mana_rate + 50, 200);
}
}
else if (home_table[i].type == H_OBJ)
{
for (pReset = ch->in_room->reset_first; pReset != NULL;
pReset = pReset->next)
{
if (pReset->command == 'O'
&& pReset->arg1 == home_table[i].vnum)
{
chprintln
(ch,
"You already have one of those in this room.");
return;
}
}
if ((pObj = get_obj_index(home_table[i].vnum)) != NULL)
{
furn = create_object(pObj, pObj->level);
loc_reset = new_reset_data();
loc_reset->command = 'O';
loc_reset->arg1 = pObj->vnum;
loc_reset->arg2 = 0;
loc_reset->arg3 = ch->in_room->vnum;
loc_reset->arg4 = 0;
add_reset(ch->in_room, loc_reset, 0);
obj_to_room(furn, ch->in_room);
}
else
chprintln
(ch,
"Cannot find that object, please contact an immortal.");
}
else if (home_table[i].type == H_MOB)
{
for (pReset = ch->in_room->reset_first; pReset != NULL;
pReset = pReset->next)
{
if (pReset->command == 'M'
&& pReset->arg1 == home_table[i].vnum)
{
chprintln
(ch,
"You already have one of those in this room.");
return;
}
}
if ((pMob = get_mob_index(home_table[i].vnum)) != NULL)
{
moby = create_mobile(pMob);
loc_reset = new_reset_data();
loc_reset->command = 'M';
loc_reset->arg1 = pMob->vnum;
loc_reset->arg2 =
ch->in_room->area->max_vnum -
ch->in_room->area->min_vnum;
loc_reset->arg3 = ch->in_room->vnum;
loc_reset->arg4 = 1;
add_reset(ch->in_room, loc_reset, 0);
char_to_room(moby, ch->in_room);
}
else
chprintln
(ch,
"Cannot find that mobile, please contact an immortal.");
}
else
{
chprintln
(ch,
"Unable to complete your request. Please inform an Immortal.");
return;
}
ch->gold -= home_table[i].cost;
ch->pcdata->questpoints -= home_table[i].quest;
ch->pcdata->trivia -= home_table[i].tp;
chprintlnf
(ch,
"You have been deducted %ld gold, %dqp and %dtp for your purchase.",
home_table[i].cost, home_table[i].quest, home_table[i].tp);
save_area(ch->in_room->area);
return;
}
}
}
}
CH_CMD(home_unfurnish)
{
RESET_DATA *pReset = NULL;
OBJ_DATA *obj, *obj_next;
CHAR_DATA *mob, *mob_next;
int i = 0;
bool found = FALSE;
if (!ch || IS_NPC(ch))
return;
if (count_home(ch) == 0)
{
chprintln(ch, "You have to BUY a home before you can furnish it.");
return;
}
if (!ch->in_room || !is_home_owner(ch, ch->in_room))
{
chprintln(ch, "But you do not own this room!");
return;
}
if (IS_NULLSTR(argument))
{
chprintln(ch, "Unfurnish which object?.");
return;
}
else
{
for (i = 0; home_table[i].name != NULL; i++)
{
if (home_table[i].type == H_NONE || home_table[i].vnum <= 0)
continue;
if (is_name(argument, home_table[i].name))
{
for (pReset = ch->in_room->reset_first; pReset;
pReset = pReset->next)
{
if (pReset->command ==
(home_table[i].type == H_OBJ ? 'O' : 'M')
&& pReset->arg1 == home_table[i].vnum)
{
unlink_reset(ch->in_room, pReset);
free_reset_data(pReset);
ch->gold += home_table[i].cost / 3;
ch->pcdata->questpoints += home_table[i].quest / 3;
ch->pcdata->trivia += home_table[i].tp / 3;
save_area(ch->in_room->area);
found = TRUE;
if (home_table[i].type == H_OBJ)
{
for (obj = ch->in_room->first_content; obj != NULL;
obj = obj_next)
{
obj_next = obj->next_content;
if (obj->pIndexData->vnum == home_table[i].vnum)
extract_obj(obj);
}
}
else if (home_table[i].type == H_MOB)
{
for (mob = ch->in_room->first_person; mob != NULL;
mob = mob_next)
{
mob_next = mob->next_in_room;
if (IS_NPC(mob)
&& mob->pIndexData->vnum ==
home_table[i].vnum)
extract_char(mob, TRUE);
}
}
chprintlnf
(ch,
"You sell %s back to the mayor for %ld gold, %dqp and %dtp.",
home_table[i].list, home_table[i].cost / 3,
home_table[i].quest / 3, home_table[i].tp / 3);
}
}
}
}
if (!found)
chprintln(ch, "Unable to find your request.");
return;
}
}
CH_CMD(do_gohome)
{
CHAR_DATA *victim;
ROOM_INDEX_DATA *location = NULL;
int i;
if (!ch)
return;
if (IS_NPC(ch))
{
chprintln(ch, "Only players can go home.");
return;
}
if (IS_SET(ch->in_room->room_flags, ROOM_ARENA))
{
chprintln(ch, "You can't recall while in the arena!");
return;
}
act("$n prays for $s mother to take $m home!", ch, 0, 0, TO_ROOM);
for (i = 0; i < MAX_HOUSE_ROOMS; i++)
if (ch->pcdata->home[i] > 0
&& (location = get_room_index(ch->pcdata->home[i])) != NULL)
break;
if (location == NULL)
{
chprintln(ch, "You don't have a home *pout*.");
return;
}
if (ch->in_room == location)
return;
if ((victim = ch->fighting) != NULL)
{
chprintln(ch, "You run home from combat!");
stop_fighting(ch, TRUE);
}
ch->move -= ch->move / 5;
act("$n disappears.", ch, NULL, NULL, TO_ROOM);
char_from_room(ch);
char_to_room(ch, location);
act("$n appears in $s home.", ch, NULL, NULL, TO_ROOM);
do_function(ch, &do_look, "auto");
if (ch->pet != NULL)
{
act("$n disappears.", ch, NULL, NULL, TO_ROOM);
char_from_room(ch->pet);
char_to_room(ch->pet, location);
act("$n appears in the room.", ch, NULL, NULL, TO_ROOM);
}
return;
}
CH_CMD(home_evict)
{
CHAR_DATA *victim;
if (count_home(ch) == 0)
{
chprintln(ch, "You don't have a home to kick them out of.");
return;
}
if (IS_NULLSTR(argument))
{
chprintln(ch, "Syntax: home evict <char>");
return;
}
if ((victim = get_char_world(ch, argument)) == NULL)
{
chprintln(ch, "They aren't here.");
return;
}
if (IS_NPC(victim))
{
chprintln(ch, "No such player.");
return;
}
if (victim == ch)
{
chprintln(ch, "What would be the point of that?");
return;
}
if (ch->fighting != NULL)
{
chprintln(ch, "Your a little busy right now.");
return;
}
if (!is_home_owner(ch, victim->in_room))
{
chprintln(ch, "They aren't in your home.");
return;
}
if (victim->fighting != NULL)
stop_fighting(victim, TRUE);
char_from_room(victim);
char_to_room(victim, get_room_index(ROOM_VNUM_TEMPLE));
act("$n has someone escort you out of $s home.", ch, NULL, victim, TO_VICT);
do_function(victim, &do_look, "auto");
act("You are no longer welcome in $n's home.", ch, NULL, victim, TO_VICT);
act("$N is no longer welcome in your home.", ch, NULL, victim, TO_CHAR);
return;
}
CH_CMD(home_link)
{
int door;
AREA_DATA *pArea;
ROOM_INDEX_DATA *pRoom, *toRoom = NULL;
char arg[MIL];
vnum_t vnum;
if (count_home(ch) == 0)
{
chprintln(ch, "Use HOME BUY to purchase a home first.");
return;
}
if (ch->gold < ROOM_PRICE)
{
chprintln(ch, "{wYou don't have enough to buy a another room.");
return;
}
if (ch->pcdata->questpoints < 125)
{
chprintln(ch, "It costs 125 quest points to add a link to this room.");
return;
}
if (!is_home_owner(ch, ch->in_room))
{
chprintln(ch, "You must add only to your home!");
return;
}
argument = one_argument(argument, arg);
if ((door = get_direction(arg)) == -1 || door > 5)
{
chprintln(ch, "Which direction from here do you want the new exit?");
return;
}
pRoom = ch->in_room;
if (pRoom->exit[door])
{
chprintln(ch, "An exit already exits in that location.");
return;
}
if (IS_NULLSTR(argument))
{
chprintln(ch, "Invalid area to link to.");
return;
}
for (pArea = area_first; pArea != NULL; pArea = pArea->next)
{
if (!str_prefix(argument, pArea->name))
break;
}
if (pArea == NULL)
{
chprintln(ch, "Invalid area to link to.");
return;
}
for (vnum = pArea->min_vnum; vnum < pArea->max_vnum; vnum++)
{
if ((toRoom = get_room_index(vnum)) != NULL)
break;
}
if (toRoom == NULL)
{
chprintln(ch, "Unable to link to that area.");
return;
}
pRoom->exit[door] = new_exit();
pRoom->exit[door]->u1.to_room = toRoom;
pRoom->exit[door]->orig_door = door;
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
ch->gold -= ROOM_PRICE;
ch->pcdata->questpoints -= 125;
chprintlnf(ch, "Exit to %s added.", pArea->name);
}
CH_CMD(home_unlink)
{
char arg[MIL];
ROOM_INDEX_DATA *pRoom, *pToRoom;
int rev, door;
if (count_home(ch) == 0)
{
chprintln(ch, "You don't own a home.");
return;
}
if (!is_home_owner(ch, ch->in_room))
{
chprintln(ch, "You don't own this room!");
return;
}
argument = one_argument(argument, arg);
if ((door = get_direction(arg)) == -1 || door > 5)
{
chprintln(ch,
"Which direction from here do you want to delete the exit?");
return;
}
pRoom = ch->in_room;
if (!pRoom->exit[door])
{
chprintln(ch, "There is no exit in that direction.");
return;
}
rev = rev_dir[door];
pToRoom = pRoom->exit[door]->u1.to_room;
if (pToRoom->area == pRoom->area)
{
chprintln(ch, "You can't unlink that exit.");
return;
}
free_exit(pRoom->exit[door]);
pRoom->exit[door] = NULL;
ch->gold += ROOM_PRICE / 3;
ch->pcdata->questpoints += 125 / 3;
SET_BIT(pRoom->area->area_flags, AREA_CHANGED);
chprintln(ch, "Exit unlinked.");
return;
}
CH_CMD(home_invite)
{
CHAR_DATA *vch;
if (IS_NULLSTR(argument))
{
chprintln(ch, "Syntax: home invite <person>");
return;
}
if ((vch = get_char_world(ch, argument)) == NULL)
{
chprintln(ch, "They aren't online.");
return;
}
if (IS_NPC(vch))
{
chprintln(ch, "You can't invite them.");
return;
}
if (vch == ch)
{
chprintln(ch, "You can't invite yourself.");
return;
}
if (vch->pcdata->home_invite != 0)
{
chprintln(ch, "They have already been invited somewhere.");
return;
}
if (vch->fighting != NULL)
{
chprintln(ch, "They're a little busy right now.");
return;
}
vch->pcdata->home_invite = ch->id;
act
("$n has invited you to $s home. Type HOME ACCEPT to accept the invitation\n\r"
"and be transfered to $s home, or type HOME DENY to cancel the invitation.",
ch, NULL, vch, TO_VICT);
act("Invitation sent to $N.", ch, NULL, vch, TO_CHAR);
}
CH_CMD(home_accept)
{
CHAR_DATA *owner;
ROOM_INDEX_DATA *pRoom;
int i;
if (ch->pcdata->home_invite == 0)
{
chprintln(ch, "You haven't been invited anywhere.");
return;
}
if (ch->fighting != NULL || IS_IN_WAR(ch))
{
chprintln(ch, "You're a little busy right now.");
return;
}
if ((owner = get_char_id(ch->pcdata->home_invite)) == NULL)
{
chprintln(ch,
"Hmm, seems the person who invited you isn't around anymore.");
return;
}
pRoom = NULL;
for (i = 0; i < MAX_HOUSE_ROOMS; i++)
if ((pRoom = get_room_index(owner->pcdata->home[i])) != NULL)
break;
if (!pRoom)
{
chprintln(ch, "BUG: inviter doesn't own a home!");
return;
}
char_from_room(ch);
char_to_room(ch, pRoom);
act("$n arrives.", ch, NULL, NULL, TO_ROOM);
do_function(ch, &do_look, "auto");
ch->pcdata->home_invite = 0;
return;
}
CH_CMD(home_deny)
{
CHAR_DATA *owner;
if (ch->pcdata->home_invite == 0)
{
chprintln(ch, "You haven't been invited anywhere.");
return;
}
owner = get_char_id(ch->pcdata->home_invite);
if (owner)
{
act("You turn down $N's invitation.", ch, NULL, owner, TO_CHAR);
act("$n turns down your invitation.", ch, NULL, owner, TO_VICT);
}
else
chprintln(ch, "You turn down the invitation.");
ch->pcdata->home_invite = 0;
}
void delete_home(CHAR_DATA * ch)
{
int i;
char buf[MSL];
if (count_home(ch) > 0)
{
ROOM_INDEX_DATA *pRoom;
AREA_DATA *pArea = NULL;
for (i = 0; i < MAX_HOUSE_ROOMS; i++)
{
if ((pRoom = get_room_index(ch->pcdata->home[i])) != NULL)
{
pArea = pRoom->area;
sprintf(buf, "%ld", ch->pcdata->home[i]);
redit_delete(NULL, buf);
}
}
sprintf(buf, "%ld", ch->pcdata->home_key);
oedit_delete(NULL, buf);
if (pArea)
save_area(pArea);
}
}