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