/* Make a new file called house.c and cut and paste all the contents below */
/***************************************************************************
* 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_exit args( ( CHAR_DATA *ch, char *argument, int door ) );
void save_area (AREA_DATA *pArea );
void save_house args( ( ) );
void home_sell ( CHAR_DATA *ch, int cost );
CHAR_DATA * find_architect args( ( CHAR_DATA * ch ) );
HOUSE_DATA *house_list;
#define MAX_HORESET 5
#define MAX_HMRESETS 5
#define VNUM_START 28000
#define VNUM_STOP 29800
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" )) || !IS_IMMORTAL(ch))
{
send_to_char("1: 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 && !IS_IMMORTAL(ch))
{
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--)
// i2 needs to be 24
{
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
*/
/*
8 == temp 6
X6 X7 X8 X9 X10
X11 S12 A3 H13 X14
X15 +2 F1 +4 X16
X17 H18 |5 B19 X20
X21 X22 X23 X24 X25
*/
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( "ShadowStorm has 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,"");
/*
We'll put this back in later. --Landren
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 save_house()
{
FILE *fp;
HOUSE_DATA *hOuse;
if ( ( fp = fopen( HOUSE_FILE, "w" ) ) == NULL )
{
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");
fclose(fp);
return;
}
void load_house()
{
FILE *fp;
char *word;
HOUSE_DATA *hlist;
HOUSE_DATA *hOuse;
if ( ( fp = fopen( HOUSE_FILE, "r" ) ) != NULL )
{
//fp = fopen( 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;
}