/***************************************************************************
 *  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-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							*
*****************************************************************************/

/****************************************************************************
*	I've seen other innkeeper/room rental snippets out there, but they all	*
*	seemed rather generic and lacking on options.  Prior to writing this	*
*	code, all "inns" on my game consisted of an innkeeper mob programmed	*
*	to let people into a room for a certain amount of money, and the room	*
*	had a ridiculously high regen rate with a high regen bed.  This			*
*	solution wasn't very elegant, so I coded this.	What it allows is for	*
*	a player to go into a room and type rent and they will have the option	*
*	to rent the room out as a single (temporarily flags the room to			*
*	solitary) for a base amount of money, a double room (flags to private)	*
*	for a higher cost, or an "all" room which has no person limit and		*
*	charges an even higher cost.  In addition, a smaller amount of money is	*
*	charged every tick they are in the room and have it rented.  All of the	*
*	prices are also adjusted according to the player's level in order to	*
*	keep the prices scaled to level and a worthy money sink.  In order to	*
*	use this code, you must	abide by the Diku, Merc, and Rom licenses, and	*
*	may not be used in any MUD that may be considered commercial,			*
*	pay-to-play, or pay-for-perks.  No credit is required, but is certainly	*
*	appreciated if my name was added as credit in a snippet or rent			*
*	helpfile.  Code comments must remain in the do_rent and do_checkout		*
*	functions.  This code was originally released on Mudbytes at			*
*	http://www.mudbytes.net/												*
****************************************************************************/


/* Go into merc.h and look for the ROOM_ flags and add these two where ? represents
	any free letters you have: */

#define ROOM_RENT			(?)
#define ROOM_RENTED			(?)


/* In interp.c in the command table you need to add: */

	{"rent", do_rent, POS_STANDING, 0, LOG_NORMAL, 1},
	{"checkout", do_checkout, POS_STANDING, 0, LOG_NORMAL, 1},


/* In interp.h you'll need to add: */

DECLARE_DO_FUN(	do_checkout		);
DECLARE_DO_FUN(	do_rent			);



//The next few things are to make sure that the character renting the room will no longer
//be renting for any reason that might cause them to leave the room.  I think I caught them
//all, but it might be worth remembering this incase I missed something

/* In act_wiz.c go to do_transfer and add this just above or below the call to stop_fighting: */

if (IS_SET(victim->in_room->room_flags, ROOM_RENTED)
		&&  is_room_owner(victim,victim->in_room) )
	do_function(victim, &do_checkout, "");


/* In handler.c find extract_char and before the check and call for char_from_room add: */

/* clear out any rented room stuff when the character leaves the game */
if (IS_SET(ch->in_room->room_flags, ROOM_RENTED)
		&&  is_room_owner(ch,ch->in_room) )
{
	if (IS_SET(ch->in_room->room_flags, ROOM_SOLITARY))
		REMOVE_BIT(ch->in_room->room_flags, ROOM_SOLITARY);
	if (IS_SET(ch->in_room->room_flags, ROOM_PRIVATE))
		REMOVE_BIT(ch->in_room->room_flags, ROOM_PRIVATE);
	REMOVE_BIT(ch->in_room->room_flags, ROOM_RENTED);
	ch->in_room->heal_rate = 100;
	ch->in_room->mana_rate = 100;
	free_string( ch->in_room->owner );
	ch->in_room->owner = str_dup( "" );
}

/* If you have a word_of_recall spell (probably in magic.c) find it and add this near the top: */
//You might need to add a similar check in spells like gate, summon, etc.

if (IS_SET(ch->in_room->room_flags, ROOM_RENTED)
		&&  is_room_owner(ch,ch->in_room) )
{
	send_to_char("You can't leave until you checkout!\r\n",ch);
	return;
}


/* In tables.c find
const struct flag_type room_flags[]
and add: */

    { "rent",		ROOM_RENT,			TRUE	},

/* Note that we don't add 'rented' as to keep that from being able to be set by a builder in OLC.
	Its also worth noting that you probably never want to set a room to rent that is also set to
	private or solitary since the code will remove those flags upon checkout as a way of clearing
	and modifications to the room as a result of renting */


/* In update.c find the char_update function.  Just after the part where the code deals with a
	a light flickering or burning out, add: */

/* handle all of the rent stuff */
if (IS_SET(ch->in_room->room_flags, ROOM_RENTED)
		&&  is_room_owner(ch,ch->in_room) )
{
	cost = ch->level * 6;
	if (cost < 100)
		cost = 100;

	cost /= 10;

	if ( ch->silver > cost )
		ch->silver -= cost;
	else
	{
		if (IS_SET(ch->in_room->room_flags, ROOM_SOLITARY))
			REMOVE_BIT(ch->in_room->room_flags, ROOM_SOLITARY);
		if (IS_SET(ch->in_room->room_flags, ROOM_PRIVATE))
			REMOVE_BIT(ch->in_room->room_flags, ROOM_PRIVATE);
		REMOVE_BIT(ch->in_room->room_flags, ROOM_RENTED);
		ch->in_room->heal_rate = 100;
		ch->in_room->mana_rate = 100;
		free_string( ch->in_room->owner );
		ch->in_room->owner = str_dup( "" );
		send_to_char("You are kicked out of the room for insufficient funds!\r\n",ch);
	}
}


/* Finally, we go into act_move.c (with some final additions to prevent people from leaving
	the room without checking out, and this is also where I chose to put my functions for
	renting and checking out)

/* In the move_char and do_recall functions, add near the top: */

    if (IS_SET(ch->in_room->room_flags, ROOM_RENTED)
            &&  is_room_owner(ch,ch->in_room) )
    {
        send_to_char("You can't leave until you checkout!\r\n",ch);
        return;
    }

/* Anywhere in the file, at the bottom if you prefer, these are the main functions that
	handle the code: */

void do_rent( CHAR_DATA *ch, char *argument )
{
	/* Rent/Checkout commands written by Joseph, aka Diablos, of End of Time	eotmud.com:4000	*/
    char arg[MIL];
    char buf[MIL];
    CHAR_DATA *rch;
    int count = 0, cost = 0;

    argument = one_argument (argument, arg);

	//Count how many people are in the room
    for ( rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room )
        if (!IS_NPC(rch))
		count++;

    if (IS_NPC(ch))
    {
        send_to_char("NPCs may not rent rooms!\r\n",ch);
        return;
    }

	//Room must be set to rent in order to be rentable
    if (!IS_SET(ch->in_room->room_flags, ROOM_RENT) )
    {
        send_to_char("This room is not for rent.\r\n",ch);
        return;
    }

    if (IS_SET(ch->in_room->room_flags, ROOM_RENTED) )
    {
        send_to_char("This room is already rented out.\r\n",ch);
        return;
    }

	//This is your base cost, adjusted by level.  If you modify this, you need to also be sure
	//to modfiy the same line in update.c as well
    cost = ch->level * 6;
    if (cost < 100)
        cost = 100;

	//Where is says "gold" you may need to change to silver, or otherwise recalculate exactly how
	//it is handled as my game handles money in a different way
    if ( arg[0] == '\0' )
    {
        sprintf(buf, "Syntax: rent <single/double/all>\r\nRental Rates: Single - %d  Gold\r\n"
                "            : Double - %d Gold\r\n            : All    - %d Gold\r\n"
                "An additional %d Gold will be charged per hour.\r\n",
                cost - (cost / 4),
                cost,
                cost + (cost / 4),
                cost / 10);
        send_to_char(buf,ch);
        return;
    }
    else if (!str_prefix (arg, "single"))
    {
        if ( ch->silver < cost * 0.75 )
        {
            send_to_char( "You can't afford it.\r\n", ch );
            return;
        }

        if (count > 1)
        {
            send_to_char( "You can't rent a single room with more than one person in the room.\r\n", ch );
            return;
        }

        ch->silver -= cost * 0.75;
        SET_BIT(ch->in_room->room_flags, ROOM_SOLITARY);
        SET_BIT(ch->in_room->room_flags, ROOM_RENTED);
        ch->in_room->heal_rate = 2000;
        ch->in_room->mana_rate = 2000;
        send_to_char( "You have rented this room.\r\n", ch );
        act("$n has rented this room as a single.",ch, NULL, NULL, TO_ROOM);
        free_string( ch->in_room->owner );
        ch->in_room->owner = str_dup( ch->name );
    }
    else if (!str_prefix (arg, "double"))
    {
        if ( ch->silver < cost )
        {
            send_to_char( "You can't afford it.\r\n", ch );
            return;
        }

        if (count > 2)
        {
            send_to_char( "You can't rent a double room with more than two people in the room.\r\n", ch );
            return;
        }

        ch->silver -= cost;
        SET_BIT(ch->in_room->room_flags, ROOM_PRIVATE);
        SET_BIT(ch->in_room->room_flags, ROOM_RENTED);
        ch->in_room->heal_rate = 2000;
        ch->in_room->mana_rate = 2000;
        send_to_char( "You have rented this room.\r\n", ch );
        act("$n has rented this room as a double.",ch, NULL, NULL, TO_ROOM);
        free_string( ch->in_room->owner );
        ch->in_room->owner = str_dup( ch->name );
    }
    else if (!str_prefix (arg, "all"))
    {
        if ( ch->silver < cost * 1.25 )
        {
            send_to_char( "You can't afford it.\r\n", ch );
            return;
        }

        ch->silver -= cost * 1.25;
        SET_BIT(ch->in_room->room_flags, ROOM_RENTED);
        ch->in_room->heal_rate = 2000;
        ch->in_room->mana_rate = 2000;
        send_to_char( "You have rented this room.\r\n", ch );
        act("$n has rented this room.",ch, NULL, NULL, TO_ROOM);
        free_string( ch->in_room->owner );
        ch->in_room->owner = str_dup( ch->name );
    }
    return;
};

void do_checkout( CHAR_DATA *ch, char *argument )
{
	/* Rent/Checkout commands written by Joseph, aka Diablos, of End of Time	eotmud.com:4000	*/
    if (IS_NPC(ch))
    {
        send_to_char("NPCs may not rent rooms!\r\n",ch);
        return;
    }

    if (!IS_SET(ch->in_room->room_flags, ROOM_RENT) )
    {
        send_to_char("This room is not for rent.\r\n",ch);
        return;
    }

    if (!IS_SET(ch->in_room->room_flags, ROOM_RENTED) )
    {
        send_to_char("This room is not rented out.\r\n",ch);
        return;
    }

    if (!is_room_owner(ch,ch->in_room))
    {
        send_to_char("You didn't rent this room out.\r\n",ch);
        return;
    }

    if (IS_SET(ch->in_room->room_flags, ROOM_SOLITARY))
        REMOVE_BIT(ch->in_room->room_flags, ROOM_SOLITARY);
    if (IS_SET(ch->in_room->room_flags, ROOM_PRIVATE))
        REMOVE_BIT(ch->in_room->room_flags, ROOM_PRIVATE);
    REMOVE_BIT(ch->in_room->room_flags, ROOM_RENTED);
    ch->in_room->heal_rate = 100;
    ch->in_room->mana_rate = 100;
    free_string( ch->in_room->owner );
    ch->in_room->owner = str_dup( "" );
    send_to_char( "You have checked out from this room.\r\n", ch );
    act("$n has checked out of this room.",ch, NULL, NULL, TO_ROOM);
    return;
};