/************************************************************************** * 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); } }