asgard/
asgard/.settings/
asgard/area/
asgard/data/clans/
asgard/data/clans/history/
asgard/data/rosters/
asgard/src/notice/
/***************************************************************************   
 *  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 = get_temp_file()) == NULL)
	{
		perror(BANK_FILE);
		return;
	}

	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);
	}

	close_write_file(BANK_FILE);

	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) > 2000000000)
	{
		sprintf(
				buf,
				"%s tells you '{_Sorry, but I can only hold 2,000,000,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 *= .02;
	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;
}