/***************************************************************************
* 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-1995 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@pacinfo.com) *
* Gabrielle Taylor (gtaylor@pacinfo.com) *
* Brian Moore (rom@rom.efn.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
***************************************************************************/
/***************************************************************************
* ROT 1.5 is copyright 1996-1997 by Russ Walsh *
* By using this code, you have agreed to follow the terms of the *
* ROT license, in the file doc/rot.license *
***************************************************************************/
#if defined(macintosh)
#include <types.h>
#include <time.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "recycle.h"
/* command procedures needed */
DECLARE_DO_FUN( do_say );
DECLARE_DO_FUN( do_yell );
DECLARE_DO_FUN( do_give );
BANK_DATA *bank_list;
void save_banklist(void)
{
BANK_DATA *pbank;
FILE *fp;
bool found = FALSE;
if ( ( fp = fopen( BANK_FILE, "w" ) ) == NULL )
{
perror( BANK_FILE );
}
for (pbank = bank_list; pbank != NULL; pbank = pbank->next)
{
found = TRUE;
fprintf(fp,"%d %s\n%d %d %d\n%ld\n",
pbank->passwd,pbank->name,pbank->bank,pbank->type,pbank->amount,
pbank->date);
}
fclose(fp);
if (!found)
unlink(BANK_FILE);
}
void load_banklist(void)
{
FILE *fp;
BANK_DATA *bank_last;
if ( ( fp = fopen( BANK_FILE, "r" ) ) == NULL )
return;
bank_last = NULL;
for ( ; ; )
{
BANK_DATA *pbank;
if ( feof(fp) )
{
fclose( fp );
return;
}
pbank = new_bank();
pbank->passwd = fread_number(fp);
pbank->name = str_dup(fread_word(fp));
pbank->bank = fread_number(fp);
pbank->type = fread_number(fp);
pbank->amount = fread_number(fp);
pbank->date = fread_number(fp);
fread_to_eol(fp);
if (bank_list == NULL)
bank_list = pbank;
else
bank_last->next = pbank;
bank_last = pbank;
}
}
void do_deposit( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *mob;
char buf[MAX_STRING_LENGTH];
int amount;
int bank;
bool found = FALSE;
if ( !is_number( argument ) )
{
send_to_char( "Deposit how much platinum?\n\r", ch );
return;
}
for (bank = 0; bank < 4; bank++)
{
if (ch->in_room->vnum == bank_table[bank].vnum)
{
found = TRUE;
break;
}
}
if (!found)
{
send_to_char( "Does this look like a bank to you?\n\r", ch);
return;
}
for ( mob = ch->in_room->people; mob; mob = mob->next_in_room )
{
if ( IS_NPC(mob) && IS_SET(mob->act, ACT_IS_BANKER) )
break;
}
if ( mob == NULL )
{
send_to_char( "The banker appears to be on a break.\n\r", ch );
return;
}
if ( ( time_info.hour < bank_table[bank].open )
|| ( time_info.hour > bank_table[bank].close ) )
{
sprintf(buf, "{_Sorry, our hours are %d:00%s to %d:00%s.{x",
bank_table[bank].open == 0 ? 12 :
bank_table[bank].open < 13 ? bank_table[bank].open :
bank_table[bank].open - 12,
bank_table[bank].open < 13 ? "am" : "pm",
bank_table[bank].close == 0 ? 12 :
bank_table[bank].close < 13 ? bank_table[bank].close :
bank_table[bank].close - 12,
bank_table[bank].close < 13 ? "am" : "pm");
do_say(mob, buf);
return;
}
if (is_compromised(ch, bank))
change_banklist(ch, FALSE, bank, 0, 0, ch->name);
amount = atoi(argument);
if ( amount < 1 )
{
return;
}
if ( ( amount % 50 ) != 0 )
{
send_to_char( "Deposits must be made in multiples of 50 platinum.\n\r", ch);
return;
}
if ( amount > ch->platinum )
{
send_to_char( "You don't have that much platinum.\n\r", ch);
return;
}
if ( ( ch->balance[bank] + amount ) > 40000 )
{
sprintf(buf,
"%s tells you '{_Sorry, but I can only hold 40,000 coins per player.{x'\n\r",
mob->short_descr);
send_to_char( buf, ch);
return;
}
ch->balance[bank] += amount;
ch->platinum -= amount;
sprintf(buf, "You give %d platinum coins to %s.\n\r",
amount, mob->short_descr);
send_to_char(buf, ch);
sprintf(buf,
"%s tells you '{_Thank you, your new balance is {W%ld{a platinum.{x'\n\r",
mob->short_descr, ch->balance[bank]);
send_to_char(buf, ch);
return;
}
void do_withdraw( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *mob;
char buf[MAX_STRING_LENGTH];
int amount;
int bank;
bool found = FALSE;
if ( !is_number( argument ) )
{
send_to_char( "Withdraw how much platinum?\n\r", ch );
return;
}
for (bank = 0; bank < 4; bank++)
{
if (ch->in_room->vnum == bank_table[bank].vnum)
{
found = TRUE;
break;
}
}
if (!found)
{
send_to_char( "Does this look like a bank to you?\n\r", ch);
return;
}
for ( mob = ch->in_room->people; mob; mob = mob->next_in_room )
{
if ( IS_NPC(mob) && IS_SET(mob->act, ACT_IS_BANKER) )
break;
}
if ( mob == NULL )
{
send_to_char( "The banker appears to be on a break.\n\r", ch );
return;
}
if ( ( time_info.hour < bank_table[bank].open )
|| ( time_info.hour > bank_table[bank].close ) )
{
sprintf(buf, "{_Sorry, our hours are %d:00%s to %d:00%s.{x",
bank_table[bank].open == 0 ? 12 :
bank_table[bank].open < 13 ? bank_table[bank].open :
bank_table[bank].open - 12,
bank_table[bank].open < 13 ? "am" : "pm",
bank_table[bank].close == 0 ? 12 :
bank_table[bank].close < 13 ? bank_table[bank].close :
bank_table[bank].close - 12,
bank_table[bank].close < 13 ? "am" : "pm");
do_say(mob, buf);
return;
}
if (is_compromised(ch, bank))
change_banklist(ch, FALSE, bank, 0, 0, ch->name);
amount = atoi(argument);
if ( amount < 1 )
{
return;
}
if ( ( ( amount % 50 ) != 0 ) && ( ch->balance[bank] >= 50 ) )
{
send_to_char( "Withdrawals must be made in multiples of 50 platinum.\n\r", ch);
return;
}
if ( amount > ch->balance[bank] )
{
send_to_char( "You don't have that much platinum in this bank.\n\r", ch);
return;
}
if ( amount > 50 && amount == ch->balance[bank] )
amount -= 50;
if ( ( ch->platinum + amount ) > 50000 )
{
send_to_char( "You can't carry that much platinum.\n\r", ch);
return;
}
ch->platinum += amount;
ch->balance[bank] -= amount;
sprintf(buf, "%s gives you %d platinum coins.\n\r",
mob->short_descr, amount);
send_to_char(buf, ch);
amount *= .04;
ch->balance[bank] -= amount;
ch->balance[bank] = UMAX(ch->balance[bank], 0);
return;
}
void do_rob( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *mob;
OBJ_DATA *passbook;
int amount;
int bank;
bool found = FALSE;
if (IS_NPC(ch))
return;
for (bank = 0; bank < 4; bank++)
{
if (ch->in_room->vnum == bank_table[bank].vnum)
{
found = TRUE;
break;
}
}
if (!found)
{
send_to_char( "Does this look like a bank to you?\n\r", ch);
return;
}
for ( mob = ch->in_room->people; mob; mob = mob->next_in_room )
{
if ( IS_NPC(mob) && IS_SET(mob->act, ACT_IS_BANKER) )
break;
}
if ( mob == NULL )
{
send_to_char( "The banker appears to be on a break.\n\r", ch );
return;
}
if ( ( time_info.hour < bank_table[bank].open )
|| ( time_info.hour > bank_table[bank].close ) )
{
sprintf(buf, "{_Sorry, our hours are %d:00%s to %d:00%s.{x",
bank_table[bank].open == 0 ? 12 :
bank_table[bank].open < 13 ? bank_table[bank].open :
bank_table[bank].open - 12,
bank_table[bank].open < 13 ? "am" : "pm",
bank_table[bank].close == 0 ? 12 :
bank_table[bank].close < 13 ? bank_table[bank].close :
bank_table[bank].close - 12,
bank_table[bank].close < 13 ? "am" : "pm");
do_say(mob, buf);
return;
}
passbook = get_eq_char(ch,WEAR_HOLD);
if (passbook == NULL || passbook->item_type != ITEM_PASSBOOK)
{
send_to_char("You need to hold someones passbook to rob thier account.\n\r", ch);
return;
}
if ( !is_number( argument ) )
{
send_to_char( "Rob how much platinum?\n\r", ch );
return;
}
found = TRUE;
amount = atoi(argument);
if (amount < 1)
found = FALSE;
if (!is_othcomp(passbook->value[0],passbook->value[1],passbook->name))
found = FALSE;
if (amount > passbook->value[2])
found = FALSE;
if (bank != passbook->value[0])
found = FALSE;
act("$n gives $p to $N.", ch, passbook, mob, TO_ROOM);
act("You give $p to $N.", ch, passbook, mob, TO_CHAR);
if (found)
{
if (mob->platinum < amount)
{
mob->platinum += amount;
}
sprintf(buf,"%d platinum %s", amount, ch->name);
do_give(mob,buf);
change_banklist(ch, FALSE, bank, amount, passbook->value[1], passbook->name);
} else
{
change_banklist(ch, FALSE, passbook->value[0], 0, passbook->value[1], passbook->name);
sprintf( buf, "{_%s is a {RTHIEF{a!{x", ch->name);
REMOVE_BIT(mob->comm,COMM_NOSHOUT);
do_yell( mob, buf );
}
extract_obj(passbook);
return;
}
void change_banklist(CHAR_DATA *ch, bool add, int bank, int amount, int pwd, char *argument)
{
char arg[MAX_INPUT_LENGTH];
BANK_DATA *prev;
BANK_DATA *curr;
DESCRIPTOR_DATA *d;
OBJ_DATA *object;
bool found = FALSE;
one_argument( argument, arg );
if ( !add && !str_cmp( capitalize( ch->name ), capitalize( arg ) ) )
{
prev = NULL;
for ( curr = bank_list; curr != NULL; prev = curr, curr = curr->next )
{
if ( !str_cmp( capitalize( arg ), curr->name )
&& (curr->type == 0)
&& (curr->bank == bank))
{
if ( prev == NULL )
bank_list = bank_list->next;
else
prev->next = curr->next;
free_bank(curr);
for (d = descriptor_list; d != NULL; d = d->next)
{
CHAR_DATA *victim;
if (d->connected != CON_PLAYING)
continue;
victim = ( d->original != NULL ) ? d->original : d->character;
for ( object = victim->carrying; object != NULL; object = object->next_content )
{
if (object->pIndexData->vnum == OBJ_VNUM_PASSBOOK)
{
char oname[MAX_INPUT_LENGTH];
one_argument(object->name, oname);
if (!str_cmp(oname, arg))
{
found = TRUE;
object->timer = 1;
}
}
}
}
save_banklist();
}
}
} else if ( !add )
{
CHAR_DATA *victim;
char buf[MAX_STRING_LENGTH];
prev = NULL;
for ( curr = bank_list; curr != NULL; prev = curr, curr = curr->next )
{
if ( !str_cmp( capitalize( arg ), curr->name )
&& (curr->type == 0)
&& (curr->bank == bank))
{
if ( prev == NULL )
bank_list = bank_list->next;
else
prev->next = curr->next;
free_bank(curr);
if ((victim = get_char_mortal(ch, arg)) != NULL)
{
if (amount > 0)
{
sprintf(buf, "{RSomeone just stole %d platinum from one of your accounts!{x\n\r", amount);
send_to_char(buf, victim);
victim->balance[bank] -= amount;
victim->balance[bank] = UMAX(victim->balance[bank],0);
}
} else {
if (amount > 0)
{
curr = new_bank();
curr->name = str_dup( capitalize( arg ) );
curr->amount = amount;
curr->bank = bank;
curr->type = 1;
curr->passwd = pwd;
curr->next = bank_list;
curr->date = 0;
bank_list = curr;
}
}
save_banklist();
}
}
} else
{
curr = new_bank();
curr->name = str_dup( capitalize( arg ) );
curr->bank = bank;
curr->amount = amount;
curr->type = 0;
curr->passwd = pwd;
curr->next = bank_list;
curr->date = current_time;
bank_list = curr;
save_banklist();
}
return;
}
bool is_compromised(CHAR_DATA *ch, int bank)
{
BANK_DATA *curr;
bool found = FALSE;
for ( curr = bank_list; curr != NULL; curr = curr->next )
{
if ( !str_cmp( capitalize( ch->name ), curr->name ) )
{
if ( ( bank == curr->bank ) && ( curr->type == 0) )
found = TRUE;
}
}
return found;
}
void check_robbed( CHAR_DATA *ch )
{
BANK_DATA *curr;
BANK_DATA *prev;
char buf[MAX_STRING_LENGTH];
prev = NULL;
for ( curr = bank_list; curr != NULL; prev = curr, curr = curr->next )
{
if ( !str_cmp( capitalize( ch->name ), curr->name ) )
{
if (curr->type == 1)
{
sprintf(buf, "{RSomeone stole %d platinum from one of your accounts!{x\n\r", curr->amount);
send_to_char(buf, ch);
ch->balance[curr->bank] -= curr->amount;
ch->balance[curr->bank] = UMAX(ch->balance[curr->bank],0);
if ( prev == NULL )
bank_list = bank_list->next;
else
prev->next = curr->next;
free_bank(curr);
save_banklist();
}
}
}
}
bool is_banklist( CHAR_DATA *ch )
{
BANK_DATA *curr;
bool found = FALSE;
for ( curr = bank_list; curr != NULL; curr = curr->next )
{
if ( !str_cmp( capitalize( ch->name ), curr->name ) )
{
if (curr->type == 0)
found = TRUE;
}
}
return found;
}
bool is_othcomp(int bank, int pass, char *argument)
{
char arg[MAX_INPUT_LENGTH];
BANK_DATA *curr;
bool found = FALSE;
one_argument( argument, arg );
for ( curr = bank_list; curr != NULL; curr = curr->next )
{
if ( !str_cmp( capitalize( arg ), curr->name ) )
{
if ( ( bank == curr->bank ) && ( curr->type == 0) )
{
if (pass == curr->passwd)
found = TRUE;
}
}
}
return found;
}
void expire_banks ( void )
{
BANK_DATA *curr;
BANK_DATA *prev;
long diff;
prev = NULL;
for ( curr = bank_list; curr != NULL; prev = curr, curr = curr->next )
{
if (curr->date != 0)
{
diff = (long)current_time - (long)curr->date;
if (diff > 172800)
{
if ( prev == NULL )
bank_list = bank_list->next;
else
prev->next = curr->next;
free_bank(curr);
expire_banks();
return;
}
}
}
save_banklist();
return;
}