/************************************************************************** * 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, 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; pObj->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObj; 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; pRoom->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoom; // 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; pRoom->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoom; // 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->contents; 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->people; 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 doens'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); } }