sunder2.1/clan/
sunder2.1/class/
sunder2.1/class/bak/
sunder2.1/doc/ideas/
sunder2.1/gods/
sunder2.1/log/
sunder2.1/msgbase/
sunder2.1/src/o/
sunder2.1/time/
/**********************************************************
 *************** S U N D E R M U D *** 2 . 0 **************
 **********************************************************
 * The unique portions of the SunderMud code as well as   *
 * the integration efforts for code from other sources is *
 * based primarily on the efforts of:                     *
 *                                                        *
 * Lotherius <aelfwyne@operamail.com> (Alvin W. Brinson)  *
 *    and many others, see "help sundermud" in the mud.   *
 **********************************************************/

/* routines related to leasing. Entire file 100% unique coding by Lotherius (aelfwyne@operamail.com) */
/* Before you do much here, peruse merc.h for IS_LEASE and IS_RENTED and see how they work           */

#include "everything.h"

/* local functions and vars */

void                save_leases (  );
struct lease_data   *lease_list;

void do_lease ( CHAR_DATA * ch, char *argument )
{
     LEASE              *lease;

	 /* is room rentable at all? */

     if ( IS_LEASE(ch->in_room->lease) )
     {
          lease = ch->in_room->lease;
          if ( argument[0] == '\0' )
          {
               if ( IS_RENTED(lease) )
               {
                    if ( lease->rented_by != ch->name )	/* if room is rented by ch */
                    {
                         send_to_char ( "This room is not currently for rent.\n\r", ch );
                         return;
                    }
                    else
                    {
                         form_to_char ( ch, "{CYour rent is paid until the month of %s of Year %d.{x\n\r",
                                   month_name[lease->paid_month], lease->paid_year );
                         return;
                    }
               }

               form_to_char ( ch, "{CThe monthly rent on this room is ${Y%d{x.\n\r", lease->room_rent );
               return;
          }
          else
          {
               int                 timeleft;	/* time left on lease */
               int                 months;

               if ( !is_number ( argument ) )
               {
                    send_to_char ( "{RInvalid argument. Syntax: lease <number>.{x\n\r", ch );
                    return;
               }

               months = atoi ( argument );

               if ( months < 1 )	/* trying to unrent? */
               {
                    send_to_char ( "{MYou must rent for at least 1 full month.{x\n\r", ch );
                    return;
               }
			   /* end of unrent */
               if ( months > 17 )	/* can't rent for longer than 1 mud year */
               {
                    send_to_char ( "{MYou can only rent for a maximum of 1 year.{x\n\r", ch );
                    return;
               }
			   /* end of too long rent */
               timeleft = 0;

               if ( lease->paid_year < time_info.year )
               {
                    timeleft = 0;
               }
               else if ( lease->paid_year == time_info.year )
               {
                    timeleft = lease->paid_month - time_info.month;
               }
               else if ( lease->paid_year > time_info.year )
               {
                    timeleft = lease->paid_month - time_info.month;
                    timeleft += 17;
               }

               if ( timeleft >= 17 )
               {
                    send_to_char ( "{YYou are currently paid for a full year.{x\n\r", ch );
                    return;
               }

               if ( ( timeleft + months ) > 17 )
               {
                    send_to_char ( "{MYou can't rent past 1 year. Try fewer months.{x\n\r", ch );
                    return;
               }
			   /* now all that's out of the way, we have an almost valid number of months to rent. */

               if ( ( months * lease->room_rent ) > ch->gold )
               {
                    send_to_char ( "{RYou don't have enough gold.{x\n\r", ch );
                    /* 		if ( (ch->gold / (months * ch->in_room->room_rent) ) >= 1 )
                     *              SNP(buf,"You have enough gold for {Y%d{x months.\n\r",
                     *                           (ch->gold / (months * ch->in_room->room_rent)) ); 
                     */
                    return;
               }

               ch->gold -= months * lease->room_rent;
               lease->paid_month = time_info.month;
               lease->paid_year = time_info.year;

               if ( ( timeleft + months ) > 17 )
               {
                    ++lease->paid_year;
               }
               else
               {
                    if ( ( time_info.month + ( months + timeleft ) ) > 17 )
                    {
                         ++lease->paid_year;
                         lease->paid_month += ( ( months + timeleft ) - 17 );
                    }
                    else
                    {
                         lease->paid_month += ( months + timeleft );
                    }
               }
               form_to_char ( ch, "{CYou have now rented this room for ${Y%d{C gold coins for a total of %d months.\n\r{x",
                         months * lease->room_rent, months );
               form_to_char ( ch, "{CThe rent is NOW paid until the month of %s of Year %d.{x\n\r",
                         month_name[lease->paid_month], lease->paid_year );
               act ( "$n has signed a lease on this room.", ch, NULL, NULL, TO_ROOM );
               free_string ( lease->rented_by );
               lease->rented_by = str_dup ( ch->name );
               save_leases (  );
               return;
          }
     }
     send_to_char ( "{xThis room cannot be rented.\n\r", ch );
     return;
}
/* end of do_lease */

void do_checklease ( CHAR_DATA * ch, char *argument )	/* immortal command to show lease info */
{
     char                buf2[MIL];
     LEASE              *lease;

     if ( IS_LEASE(ch->in_room->lease) )	/* if rentable */
     {
          lease = ch->in_room->lease;
          if ( IS_RENTED(lease) )
          {
               if ( lease->clan )
                    SNP ( buf2, "The Clan: %s", lease->clan->clan_name );
               else
                    SNP ( buf2, lease->rented_by );
               form_to_char ( ch, "{GRented By:     {W%s\n\r",  buf2 );
               form_to_char ( ch, "{GMonthly Rent:  {W%d\n\r",  lease->room_rent );
               form_to_char ( ch, "{GLease Expires: {WMonth of %s of Year %d.{x\n\r",
                         month_name[lease->paid_month],
                         lease->paid_year );               
               return;
          }
          else			/* not currently being rented */
          {
               send_to_char ( "{GNot currently being rented.\n\r", ch );
               form_to_char ( ch, "Monthly Rent:  {W%d{x\n\r",	lease->room_rent );
               return;
          }
     }
     send_to_char ( "{GThis is a non-rentable room.{x\n\r", ch );
     return;
}

void do_myleases ( CHAR_DATA *ch, char *argument )
{
     BUFFER *buffer;
     bool    match = FALSE;
     bool    showall = FALSE;
     LEASE  *lease;

     buffer = buffer_new (512);

     bprintf ( buffer, "You have the following leases in the lands:\n\r" );

     if ( !str_cmp ( argument, "all" ) )
          showall = TRUE;

     for ( lease = lease_list; lease != NULL ; lease = lease->next )
     {
          if ( !IS_RENTED(lease) )
          {
               if (showall)
               {
                    bprintf ( buffer, "{G%d{w:: unrented.\n\r", lease->room->vnum );
                    match = TRUE;
               }
               continue;
          }
          if ( !str_cmp (ch->name, lease->rented_by) || (showall == TRUE) )
          {
               if (showall)
                    bprintf ( buffer, "{G%d{w::{W%s\n\r", lease->room->vnum, lease->rented_by );
               bprintf ( buffer, "{C%s ",
                         !IS_NULLSTR ( lease->lease_name ) ? lease->lease_name : lease->room->name );
               bprintf ( buffer, "at ${Y%ld {Cmonthly, paid to the Month of {W%s{C, %d.{x\n\r",
                         lease->room_rent, month_name[lease->paid_month],
                         lease->paid_year );
               match = TRUE;
          }
     }
     if ( !match )
          bprintf ( buffer, "None, you've been sleeping on the ground, poor thing.\n\r" );
     page_to_char ( buffer->data, ch );
     buffer_free ( buffer );
}

void save_leases (  )
{
     char                buf[MAX_STRING_LENGTH];
     FILE               *fp = NULL;
     LEASE              *lease = NULL;
     bool                clanflag = FALSE;

     SNP ( buf, "%sLease.DAT", DATA_DIR );

     fp = fopen ( buf, "w" );

     if ( !fp )
     {
          bugf ( "Could not open Lease.DAT for writing!" );
          return;
     }

     for ( lease = lease_list; lease != NULL ; lease = lease->next )
     {
          clanflag = FALSE;
          if ( IS_LEASE(lease) )
          {
               if ( lease->clan )
                    clanflag = TRUE;
               fprintf ( fp, "L %d %d %d %d %d %d %d %d %d %s~\n",
                         lease->room->vnum,
                         lease->room_rent,
                         lease->paid_month,
                         lease->paid_day,
                         lease->paid_year,
                         lease->owner_only,
                         lease->shop_type,
                         lease->shop_gold,
                         clanflag,
                         IS_RENTED ( lease ) ? lease->rented_by : "" );
               fprintf ( fp, "%s~\n",
                         !IS_NULLSTR( lease->lease_name) ? lease->lease_name : "" );
               fprintf ( fp, "%s~\n",
                         !IS_NULLSTR( lease->lease_name) ? lease->lease_descr : "" );

          }
          /* end of is rentable */
          else
               log_string ("Bad Lease.");
     }
     /* end of for loop */
     fprintf ( fp, "END\n" );
     fclose ( fp );

     return;
}

void load_leases (  )
{
     FILE               *fp = NULL;
     char                buf[MAX_STRING_LENGTH];
     char               *word;
     bool                fMatch;
     bool                clanflag;
     bool                done = FALSE;
     int                 iHash;
     ROOM_INDEX_DATA    *pRoomIndex;
     LEASE              *lease = NULL;

     SNP ( buf, "%sLease.DAT", DATA_DIR );

     fp = fopen ( buf, "r" );

     if ( !fp )
     {
          bugf ( "Could not open Lease.DAT for Reading!" );
          return;
     }

     fMatch = FALSE;

     while ( !done )
     {
          word = fread_word ( fp );
          if ( !str_cmp ( word, "L" ) )
          {
               pRoomIndex = get_room_index ( fread_number ( fp ) );

               lease = new_lease ( );
               lease->room_rent = fread_number ( fp );
               lease->paid_month = fread_number ( fp );
               lease->paid_day = fread_number ( fp );
               lease->paid_year = fread_number ( fp );
               lease->owner_only = fread_number ( fp );
               lease->shop_type = fread_number ( fp );
               lease->shop_gold = fread_number ( fp );
               clanflag = fread_number ( fp );
               lease->rented_by = fread_string ( fp );
               lease->lease_name = fread_string ( fp );
               lease->lease_descr = fread_string ( fp );
               pRoomIndex->lease = lease;
               lease->room = pRoomIndex;
               if (clanflag == TRUE)
               {
                    lease->clan = clan_by_short ( lease->rented_by );
                    if ( !lease->clan )
                    {
                         bugf ("Invalid clan found in leasefile. Clearing lease.\n\r" );
                         free_string ( lease->rented_by );
                         free_string ( lease->lease_name );
                         free_string ( lease->lease_descr );
                         lease->rented_by = NULL;
                         lease->lease_name = str_dup ( "" );
                         lease->lease_descr = str_dup ( "" );
                    }
               }
               VALIDATE (lease);
          }
          else if ( !str_cmp ( word, "END" ) )
          {
               done = TRUE;
               break;
          }
          else
          {
               bugf ( "Invalid data found in leasefile." );
               break;
          }
     }
     /* end of while !done */

     fclose ( fp );

	 /* Now we need to find those rooms that have ROOM_RENT but didn't get a lease loaded */

     for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
     {
          for ( pRoomIndex = room_index_hash[iHash]; pRoomIndex; pRoomIndex = pRoomIndex->next )
          {
               if ( IS_SET ( pRoomIndex->room_flags, ROOM_RENT ) )
               {
                    if ( IS_LEASE(pRoomIndex->lease) )
                         continue;
                    else
                    {
                         bugf ( "We got some ROOM_RENT rooms that didn't have entries in the Lease File!" );
                         lease = new_lease ( );
                         pRoomIndex->lease = lease;
                         lease->room = pRoomIndex;
                         VALIDATE ( lease );
                    }
               }
          }
     }

     return;
}

void do_setrent ( CHAR_DATA * ch, char *argument )
{
     LEASE              *lease;

     if ( IS_LEASE(ch->in_room->lease) )
     {
          lease = ch->in_room->lease;
          if ( ( argument[0] != '\0' ) && ( ( atoi ( argument ) >= 15000 )
                                            || ( ch->in_room->sector_type == SECT_FORT ) ) )
          {
               form_to_char ( ch, "\n\rRent set to %d.\n\r", atoi ( argument ) );
               lease->room_rent = atoi ( argument );
               save_leases (  );
          }
          else
               send_to_char ( "You must specify a rent amount, and it must be AT LEAST 15000 coins.\n\r", ch );
     }
     else
          send_to_char ( "This room is not rentable.\n\r", ch );
     return;
}

void do_roomdesc ( CHAR_DATA * ch, char *argument )
{
     LEASE  *lease;

     if ( IS_NPC ( ch ) )
          return;

     if ( !IS_LEASE(ch->in_room->lease) )
     {
          send_to_char ( "This room cannot be rented.\n\r", ch );
          return;
     }

     lease = ch->in_room->lease;

     if ( !IS_RENTED(lease) )
     {
          send_to_char ( "Try leasing the room first.\n\r", ch);
          return;
     }

     if ( str_cmp ( ch->name, lease->rented_by ) )
     {
          send_to_char ( "Nice Try. This ain't your room.\n\r", ch );
          return;
     }
     
     ch->pcdata->mode = MODE_LEASEDESC;
     string_append ( ch, &lease->lease_descr );
     // We would run a save here... but it's pretty pointless. I guess we'll just hope
     // that leases get saved before something bad happens.
}

void do_roomname ( CHAR_DATA * ch, char *argument )
{
     LEASE   *lease;
     if ( IS_NPC ( ch ) )
          return;
     
     if ( !IS_LEASE(ch->in_room->lease) )
     {
          send_to_char ( "This room cannot be rented.\n\r", ch );
          return;
     }

     lease = ch->in_room->lease;

     if ( !IS_RENTED(lease) )
     {
          send_to_char ( "Try leasing the room first.\n\r", ch);
          return;
     }

     if ( str_cmp ( lease->rented_by, ch->name ) )
     {
          send_to_char ( "Nice Try. This ain't your room.\n\r", ch );
          return;
     }

     if ( argument[0] == '\0' )
     {
          send_to_char ( "Set the room's name to what?\n\r", ch );
          return;
     }

     if ( cstrlen ( argument ) > 45 )
     {
          send_to_char ("Room name must not exceed 45 characters.\n\r", ch );
          return;
     }

     /* Also smash < > codes... cheap hack to prevent MXP codes in user-entered roomnames. */
     for ( ; *argument != '\0'; argument++ )
     {
          if ( *argument == '<' )
               *argument = '(';
          if ( *argument == '>' )
               *argument = ')';
     }     
      
     free_string ( lease->lease_name );
     
     lease->lease_name = str_dup ( argument );
     send_to_char ( "Room Name Set.\n\r", ch );
     save_leases (  );
}

void do_private ( CHAR_DATA * ch, char *argument )
{
     LEASE    *lease;

     if ( IS_NPC ( ch ) )
          return;

     if ( !IS_LEASE(ch->in_room->lease) )
     {
          send_to_char ( "You can't do that here!\n\r", ch );
          return;
     }

     lease = ch->in_room->lease;

     if ( !IS_RENTED(lease) )
     {
          send_to_char ( "Try leasing the room first.\n\r", ch);
          return;
     }

     if  ( lease->rented_by == ch->name )
     {
          if ( lease->owner_only == TRUE )
          {
               lease->owner_only = FALSE;
               send_to_char ( "Others may now enter your domain.\n\r", ch );
          }
          else
          {
               lease->owner_only = TRUE;
               send_to_char ( "You lock the door on your domain.\n\r", ch );
          }
          save_leases (  );	/* be sure to save the leases */
     }
     else
          send_to_char ( "This room does not belong to you!\n\r", ch );
     return;
}