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