<NME> StdBanker.java
<BEF> package com.planet_ink.coffee_mud.MOBS;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.DatabaseEngine.PlayerData;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

/*
   Copyright 2003-2022 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class StdBanker extends StdShopKeeper implements Banker
{
	@Override
	public String ID()
	{
		return "StdBanker";
	}

	protected double					coinInterest	= -0.000;
	protected double					itemInterest	= -0.0001;
	protected double					loanInterest	= 0.01;
	protected static Map<String, Long>	bankTimes		= new Hashtable<String, Long>();

	public StdBanker()
	{
		super();
		_name="a banker";
		setDescription("He\\`s pleased to be of assistance.");
		setDisplayText("A banker is waiting to serve you.");
		CMLib.factions().setAlignment(this,Faction.Align.GOOD);
		setMoney(0);
		whatIsSoldMask=ShopKeeper.DEAL_BANKER;
		basePhyStats.setWeight(150);
		setWimpHitPoint(0);

		baseCharStats().setStat(CharStats.STAT_INTELLIGENCE,16);
		baseCharStats().setStat(CharStats.STAT_CHARISMA,25);

		basePhyStats().setArmor(0);

		baseState.setHitPoints(1000);

		recoverMaxState();
		resetToMaxState();
		recoverPhyStats();
		recoverCharStats();
	}

	@Override
	public void addSoldType(final int mask)
	{
		setWhatIsSoldMask(CMath.abs(mask));
	}

	@Override
	public void setWhatIsSoldMask(final long newSellCode)
	{
		super.setWhatIsSoldMask(newSellCode);
		if(!isSold(ShopKeeper.DEAL_CLANBANKER))
			whatIsSoldMask=ShopKeeper.DEAL_BANKER;
		else
			whatIsSoldMask=ShopKeeper.DEAL_CLANBANKER;
	}

	@Override
	public String bankChain()
	{
		return text();
	}

	@Override
	public void setBankChain(final String name)
	{
		setMiscText(name);
	}

	@Override
	public void addDepositInventory(final String depositorName, final Item item, final Item container)
	{
		final String classID;
		if((item instanceof Coins)&&(container == null))
		{
			((Coins)item).setCurrency(CMLib.beanCounter().getCurrency(this));
			classID="COINS";
		}
		else
			classID=item.ID();
		CMLib.catalog().updateCatalogIntegrity(item);
		final String key=""+item+item.hashCode();
		if(container != null)
		{
			final String containerKey=""+container+container.hashCode();
			CMLib.database().DBCreatePlayerData(depositorName,bankChain(),key,classID+";CONTAINER="+containerKey+";"+CMLib.coffeeMaker().getEnvironmentalMiscTextXML(item,true));
		}
		else
			CMLib.database().DBCreatePlayerData(depositorName,bankChain(),key,classID+";"+CMLib.coffeeMaker().getEnvironmentalMiscTextXML(item,true));
	}

	protected Pair<Item,String> makeItemContainer(final String data)
	{
		int x=data.indexOf(';');
		if(x<0)
			return null;
		Item I=null;
		if(data.substring(0,x).equals("COINS"))
			I=CMClass.getItem("StdCoins");
		else
			I=CMClass.getItem(data.substring(0,x));
		if(I!=null)
		{
			String container="";
			String xml = data.substring(x+1);
			if(xml.startsWith("CONTAINER="))
			{
				x=xml.indexOf(';');
				if(x>0)
				{
					container=xml.substring(10,x);
					xml=xml.substring(x+1);
				}
			}
			CMLib.coffeeMaker().unpackEnvironmentalMiscTextXML(I,xml,true);
			if((I instanceof Coins)
			&&(((Coins)I).getDenomination()==0.0)
			&&(((Coins)I).getNumberOfCoins()>0))
				((Coins)I).setDenomination(1.0);
			I.recoverPhyStats();
			I.text();
			return new Pair<Item,String>(I,container);
		}
		return null;
	}

	protected List<Item> findDeleteRecursiveDepositInventoryByContainerKey(final Container C, final List<PlayerData> rawInventoryV, final String key)
	{
		final List<Item> inventory=new LinkedList<Item>();
		for(int v=rawInventoryV.size()-1;v>=0;v--)
		{
			final DatabaseEngine.PlayerData PD=rawInventoryV.get(v);
			final int IDx=PD.xml().indexOf(';');
			if(IDx>0)
			{
				if(PD.xml().substring(IDx+1).startsWith("CONTAINER="+key+";"))
				{
					final Item I=makeItemContainer(PD.xml()).first;
					I.setContainer(C);
					inventory.add(I);
					rawInventoryV.remove(v);
					if(I instanceof Container)
						inventory.addAll(findDeleteRecursiveDepositInventoryByContainerKey((Container)I,rawInventoryV,PD.key()));
					CMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());
				}
			}
		}
		return inventory;
	}

	@Override
	public List<Item> delDepositInventory(final String depositorName, final Item likeItem)
	{
		final List<PlayerData> rawInventoryV=getRawPDDepositInventory(depositorName);
		final List<Item> items = new ArrayList<Item>();
		if(likeItem.container()==null)
		{
			if(likeItem instanceof Coins)
			{
				for(int v=rawInventoryV.size()-1;v>=0;v--)
				{
					final DatabaseEngine.PlayerData PD=rawInventoryV.get(v);
					if(PD.xml().startsWith("COINS;"))
					{
						CMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());
						items.add(makeItemContainer(PD.xml()).first);
					}
				}
			}
			else
			{
				for(int v=rawInventoryV.size()-1;v>=0;v--)
				{
					final DatabaseEngine.PlayerData PD=rawInventoryV.get(v);
					if(PD.xml().startsWith(likeItem.ID()+";") && (!PD.xml().startsWith(likeItem.ID()+";CONTAINER=")))
					{
						final Pair<Item,String> pI=makeItemContainer(PD.xml());
						if((pI!=null) && likeItem.sameAs(pI.first))
						{
							pI.first.setContainer(null);
							if(pI.first instanceof Container)
							{
								items.add(pI.first);
								final Hashtable<String,List<DatabaseEngine.PlayerData>> pairings=new Hashtable<String,List<DatabaseEngine.PlayerData>>();
								for(final PlayerData PDp : rawInventoryV)
								{
									final int IDx=PDp.xml().indexOf(';');
									if(IDx>0)
									{
										final String subXML=PDp.xml().substring(IDx+1);
										if(subXML.startsWith("CONTAINER="))
										{
											final int x=subXML.indexOf(';');
											if(x>0)
											{
												final String contKey=subXML.substring(10,x);
												if(!pairings.containsKey(contKey))
													pairings.put(contKey, new LinkedList<DatabaseEngine.PlayerData>());
												pairings.get(contKey).add(PDp);
											}
										}
									}
								}
								CMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());
								final Map<String,Container> containerMap=new Hashtable<String,Container>();
								containerMap.put(PD.key(), (Container)pI.first);
								while(containerMap.size()>0)
								{
									final String contKey=containerMap.keySet().iterator().next();
									final Container container=containerMap.remove(contKey);
									final List<DatabaseEngine.PlayerData> contents=pairings.get(contKey);
									if(contents != null)
									{
										for(final DatabaseEngine.PlayerData PDi : contents)
										{
											final Pair<Item,String> pairI=makeItemContainer(PDi.xml());
											CMLib.database().DBDeletePlayerData(PDi.who(),PDi.section(),PDi.key());
											pairI.first.setContainer(container);
											items.add(pairI.first);
											if(pairI.first instanceof Container)
												containerMap.put(PDi.key(), (Container)pairI.first);
										}
									}
								}
							}
							else
							{
								items.add(pI.first);
								CMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());
							}
							break;
						}
					}
				}
			}
		}
		return items;
	}

	@Override
	public void delAllDeposits(final String depositorName)
	{
		CMLib.database().DBDeletePlayerData(depositorName,bankChain());
	}

	@Override
	public int numberDeposited(final String depositorName)
	{
		return getRawPDDepositInventory(depositorName).size();
	}

	@Override
	public List<Item> getDepositedItems(final String depositorName)
	{
		if((depositorName==null)||(depositorName.length()==0))
			return new ArrayList<Item>();
		final List<Item> items=new Vector<Item>();
		final Hashtable<String,Pair<Item,String>> pairings=new Hashtable<String,Pair<Item,String>>();
		for(final PlayerData PD : getRawPDDepositInventory(depositorName))
		{
			final Pair<Item,String> pair=makeItemContainer(PD.xml());
			if(pair!=null)
				pairings.put(PD.key(), pair);
		}
		for(final Pair<Item,String> pair : pairings.values())
		{
			if(pair.second.length()>0)
			{
				final Pair<Item,String> otherPair = pairings.get(pair.second);
				if((otherPair != null)&&(otherPair.first instanceof Container))
					pair.first.setContainer((Container)otherPair.first);
			}
			items.add(pair.first);
		}
		return items;
	}

	protected List<PlayerData> getRawPDDepositInventory(final String depositorName)
	{
		return CMLib.database().DBReadPlayerData(depositorName,bankChain());
	}

	@Override
	public List<String> getAccountNames()
	{
		final List<String> V=CMLib.database().DBReadPlayerDataPlayersBySection(bankChain());
		final HashSet<String> h=new HashSet<String>();
		final Vector<String> mine=new Vector<String>();
		for(int v=0;v<V.size();v++)
		{
			final String name=V.get(v);
			if(!h.contains(name))
			{
				h.add(name);
				mine.addElement(name);
			}
		}
		return mine;
	}

	@Override
	public boolean isAccountName(final String name)
	{
		return CMLib.database().DBExistsPlayerData(bankChain(),name);
	}

	protected void bankLedger(final String depositorName, final String msg)
	{
		final String date=CMLib.utensils().getFormattedDate(this);
		CMLib.beanCounter().addToBankLedger(bankChain(),depositorName,date+": "+msg);
	}

	@Override
	public Item findDepositInventory(final String depositorName, final String itemName)
	{
		final List<PlayerData> V=getRawPDDepositInventory(depositorName);
		if(CMath.s_int(itemName)>0)
		{
			for(int v=0;v<V.size();v++)
			{
				final DatabaseEngine.PlayerData PD=V.get(v);
				if(PD.xml().startsWith("COINS;"))
					return makeItemContainer(PD.xml()).first;
			}
		}
		else
		for(int v=0;v<V.size();v++)
		{
			final DatabaseEngine.PlayerData PD=V.get(v);
			if(PD.xml().lastIndexOf(";CONTAINER=",81)<0)
			{
				final Pair<Item,String> pair=makeItemContainer(PD.xml());
				if(pair!=null)
				{
					if(CMLib.english().containsString(pair.first.Name(),itemName))
						return pair.first;
					pair.first.destroy();
				}
			}
		}
		return null;
	}

	public long timeInterval()
	{
		return (location().getArea().getTimeObj().getHoursInDay())
				*CMProps.getMillisPerMudHour()
				*location().getArea().getTimeObj().getDaysInMonth();
	}

	@Override
	public void setCoinInterest(final double interest)
	{
		coinInterest = interest;
	}

	@Override
	public void setItemInterest(final double interest)
	{
		itemInterest = interest;
	}

	@Override
	public double getCoinInterest()
	{
		return coinInterest;
	}

	@Override
	public double getItemInterest()
	{
		return itemInterest;
	}

	@Override
	public void setLoanInterest(final double interest)
	{
		loanInterest = interest;
	}

	@Override
	public double getLoanInterest()
	{
		return loanInterest;
	}

	@Override
	public MoneyLibrary.DebtItem getDebtInfo(final String depositorName)
	{
		final List<MoneyLibrary.DebtItem> debt=CMLib.beanCounter().getDebtOwed(bankChain());
		if(depositorName.length()==0)
			return null;
		for(int d=0;d<debt.size();d++)
		{
			if(debt.get(d).debtor().equalsIgnoreCase(depositorName))
				return debt.get(d);
		}
		return null;
	}

	protected void processAccounts()
	{
		boolean proceed=false;
		Long L=bankTimes.get(bankChain());
		long timeInterval=1;
		if(((L==null)||(L.longValue()<System.currentTimeMillis()))
		&&(location!=null)
		&&(location.getArea()!=null)
		&&(location.getArea().getTimeObj()!=null)
		&&(CMLib.flags().isInTheGame(this,true)))
		{
			timeInterval=timeInterval();
			L=Long.valueOf(System.currentTimeMillis()+timeInterval);
			proceed=true;
			bankTimes.remove(bankChain());
			bankTimes.put(bankChain(),L);
		}
		if(proceed)
		{
			final List<String> bankDataV=CMLib.database().DBReadPlayerDataPlayersBySection(bankChain());
			final Set<String> userNames=new HashSet<String>();
			for(int v=0;v<bankDataV.size();v++)
			{
				final String name=bankDataV.get(v);
				if(!userNames.contains(name))
				{
					if(!CMLib.players().playerExistsAllHosts(name))
					{
						if((CMLib.clans().getClanAnyHost(name))==null)
							delAllDeposits(name);
						else
							userNames.add(name);
					}
					else
						userNames.add(name);
				}
			}
			final List<MoneyLibrary.DebtItem> debts=CMLib.beanCounter().getDebtOwed(bankChain());
			for(final Iterator<String> i=userNames.iterator();i.hasNext();)
			{
				final String name=i.next();
				Coins coinItem=null;
				int totalValue=0;
				final List<Item> items=getDepositedItems(name);
				for(int v=0;v<items.size();v++)
				{
					final Item I=items.get(v);
					if(I instanceof Coins)
						coinItem=(Coins)I;
					else
					if(itemInterest!=0.0)
						totalValue+=I.value();
				}
				double newBalance=0.0;
				if(coinItem!=null)
					newBalance=coinItem.getTotalValue();
				newBalance+=CMath.mul(newBalance,coinInterest);
				if(totalValue>0)
					newBalance+=CMath.mul(totalValue,itemInterest);
				for(int d=debts.size()-1;d>=0;d--)
				{
					final MoneyLibrary.DebtItem debtItem=debts.get(d);
					final String debtor=debtItem.debtor();
					if(debtor.equalsIgnoreCase(name))
					{
						final long debtDueAt = debtItem.due();
						final double intRate = debtItem.interest();
						final double dueAmount = debtItem.amt();
						final String reason = debtItem.reason();
						final double intDue = CMath.mul(intRate, dueAmount);
						final long timeRemaining = debtDueAt - System.currentTimeMillis();
						if((timeRemaining<0)&&(newBalance<((dueAmount)+intDue)))
							newBalance=-1.0;
						else
						{
							final double amtDueNow=(timeRemaining<0)?(dueAmount+intDue):CMath.div((dueAmount+intDue),(timeRemaining/timeInterval));
							if(newBalance>=amtDueNow)
							{
								CMLib.beanCounter().addToBankLedger(bankChain(),name,CMLib.utensils().getFormattedDate(this)+": Withdrawal of "+CMLib.beanCounter().nameCurrencyShort(this,amtDueNow)+": Loan payment made.");
								CMLib.beanCounter().adjustDebt(debtor,bankChain(),intDue-amtDueNow,reason,intRate,debtDueAt);
								newBalance-=amtDueNow;
							}
							else
								CMLib.beanCounter().adjustDebt(debtor,bankChain(),intDue,reason,intRate,debtDueAt);
						}
						debts.remove(d);
					}
				}
				if(newBalance<0)
				{
					for(int v=0;v<items.size();v++)
					{
						final Item I=items.get(v);
						if((I instanceof LandTitle)&&(((LandTitle)I).getOwnerName().length()>0))
						{
							((LandTitle)I).setOwnerName("");
							((LandTitle)I).updateTitle();
							((LandTitle)I).updateLot(null);
						}
						if(!(I instanceof Coins))
							getShop().addStoreInventory(I);
					}
					delAllDeposits(name);
					CMLib.beanCounter().delAllDebt(name,bankChain());
				}
				else
				if((coinItem==null)||(newBalance!=coinItem.getTotalValue()))
				{
					if(coinItem!=null)
					{
						if(newBalance>coinItem.getTotalValue())
							CMLib.beanCounter().addToBankLedger(bankChain(),name,CMLib.utensils().getFormattedDate(this)+": Deposit of "+CMLib.beanCounter().nameCurrencyShort(this,newBalance-coinItem.getTotalValue())+": Interest paid.");
						else
							CMLib.beanCounter().addToBankLedger(bankChain(),name,CMLib.utensils().getFormattedDate(this)+": Withdrawl of "+CMLib.beanCounter().nameCurrencyShort(this,coinItem.getTotalValue()-newBalance)+": Interest charged.");
						delDepositInventory(name,coinItem);
					}
					final String currency=CMLib.beanCounter().getCurrency(this);
					coinItem=CMLib.beanCounter().makeBestCurrency(currency,newBalance);
					if(coinItem!=null)
						addDepositInventory(name,coinItem,null);
				}
				for(int v=0;v<items.size();v++)
				{
					final Item I=items.get(v);
					if(I!=null)
						I.destroy();
				}
			}
			for(int d=debts.size()-1;d>=0;d--)
				CMLib.beanCounter().delAllDebt(debts.get(d).debtor(),bankChain());
		}
	}

	@Override
	public boolean tick(final Tickable ticking, final int tickID)
	{
		if(!super.tick(ticking,tickID))
			return false;
		if(!CMProps.getBoolVar(CMProps.Bool.MUDSTARTED))
			return true;
		try
		{
			if(tickID==Tickable.TICKID_MOB)
			{
				// handle interest by watching the days go by...
				// put stuff up for sale if the account runs out
				AtomicBoolean flag;
				synchronized(StdBanker.class)
				{
					@SuppressWarnings({ "unchecked", "rawtypes" })
					Map<String,AtomicBoolean> processingMap = (Map)Resources.getResource("SYSTEM_SEMAPHORES_BANKING");
					if(processingMap == null)
					{
						processingMap = new TreeMap<String,AtomicBoolean>();
						Resources.submitResource("SYSTEM_SEMAPHORES_BANKING", processingMap);
					}
					flag = processingMap.get(bankChain());
					if(flag == null)
					{
						flag = new AtomicBoolean(false);
						processingMap.put(bankChain(), flag);
					}
				}
				boolean isProcessing=true;
				synchronized(flag)
				{
					isProcessing = flag.get();
					if(!isProcessing)
						flag.set(true);
				}
				if(!isProcessing)
				{
					try
					{
						processAccounts();
					}
					finally
					{
						flag.set(false);
					}
				}
			}
		}
		catch (final Exception e)
		{
			Log.errOut("StdBanker", e);
		}
		return true;
	}

	@Override
	public double getBalance(final String depositorName)
	{
		final Item old=findDepositInventory(depositorName,""+Integer.MAX_VALUE);
		if((old!=null)&&(old instanceof Coins))
			return ((Coins)old).getTotalValue();
		return 0;
	}

	@Override
	public double totalItemsWorth(final String depositorName)
	{
		return min;
	}

	@Override
	public String getBankClientName(final MOB mob, final Clan.Function func, final boolean checked)
	{
				min+=CMLib.coffeeShops().pawningPrice(this, buyer, I, this, shop).absoluteGoldPrice;
			I.destroy();
		}
		return min;
	}

	@Override
	public String getBankClientName(final MOB mob, final Clan.Function func, final boolean checked)
	{
		if(isSold(ShopKeeper.DEAL_CLANBANKER))
		{
			final Pair<Clan,Integer> clanPair=CMLib.clans().findPrivilegedClan(mob, func);
			if(clanPair!=null)
				return clanPair.first.clanID();
			else
			if(checked)
			{
				if(mob.clans().iterator().hasNext())
				{
					CMLib.commands().postSay(this,mob,L("I'm sorry, you aren't authorized by your clan to do that."),true,false);
					return null;
				}
				else
				{
					CMLib.commands().postSay(this,mob,L("I'm sorry, I only deal with clans."),true,false);
					return null;
				}
			}
		}
		return mob.Name();
	}

	@Override
	public void executeMsg(final Environmental myHost, final CMMsg msg)
	{
		final MOB mob=msg.source();
		if(msg.amITarget(this))
		{
			switch(msg.targetMinor())
			{
			case CMMsg.TYP_GIVE:
			case CMMsg.TYP_DEPOSIT:
				if(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))
				{
					String depositorName=getBankClientName(msg.source(),Clan.Function.DEPOSIT,false);
					//if(msg.tool() instanceof Container)
					//	((Container)msg.tool()).emptyPlease(true);
					CMMsg msg2=CMClass.getMsg(msg.source(),msg.tool(),null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null);
					location().send(this,msg2);
					msg2=CMClass.getMsg((MOB)msg.target(),msg.tool(),null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null);
					location().send(this,msg2);
					if(msg.tool() instanceof Coins)
					{
						final Coins older=(Coins)msg.tool();
						double newValue=older.getTotalValue();
						Item oldCoins=findDepositInventory(depositorName,""+Integer.MAX_VALUE);
						if((oldCoins==null)
						&&(!isSold(ShopKeeper.DEAL_CLANBANKER))
						&&(msg.source().isMarriedToLiege()))
						{
							oldCoins=findDepositInventory(msg.source().getLiegeID(),""+Integer.MAX_VALUE);
							if(oldCoins!=null)
							{
								final MOB owner=CMLib.players().getPlayerAllHosts(msg.source().getLiegeID());
								if(owner != null)
									depositorName=owner.Name();
							}
						}
						if((oldCoins!=null)&&(oldCoins instanceof Coins))
							newValue+=((Coins)oldCoins).getTotalValue();
						final Coins coins=CMLib.beanCounter().makeBestCurrency(CMLib.beanCounter().getCurrency(this),newValue);
						bankLedger(depositorName,"Deposit of "+CMLib.beanCounter().nameCurrencyShort(this,newValue)+": "+msg.source().Name());
						if(oldCoins!=null)
							delDepositInventory(depositorName,oldCoins);
						if(coins!=null)
							addDepositInventory(depositorName,coins,null);
						if(isSold(ShopKeeper.DEAL_CLANBANKER))
							CMLib.commands().postSay(this,mob,L("Ok, @x1 now has a balance of @x2.",CMStrings.capitalizeFirstLetter(depositorName),CMLib.beanCounter().nameCurrencyLong(this,getBalance(depositorName))),true,false);
						else
							CMLib.commands().postSay(this,mob,L("Ok, your new balance is @x1.",CMLib.beanCounter().nameCurrencyLong(this,getBalance(depositorName))),true,false);
						recoverPhyStats();
						if((!msg.source().isMonster())
						&&(isSold(ShopKeeper.DEAL_CLANBANKER)))
						{
							final Clan C=CMLib.clans().getClan(depositorName);
							if(C!=null)
								C.adjDeposit(msg.source(), older.getTotalValue());
						}

						if(msg.sourceMessage()!=null)
							msg.setSourceMessage(CMStrings.replaceAll(msg.sourceMessage(),"<O-NAME>",msg.tool().name()));
						if(msg.targetMessage()!=null)
							msg.setTargetMessage(CMStrings.replaceAll(msg.targetMessage(),"<O-NAME>",msg.tool().name()));
						if(msg.othersMessage()!=null)
							msg.setOthersMessage(CMStrings.replaceAll(msg.othersMessage(),"<O-NAME>",msg.tool().name()));
						((Coins)msg.tool()).setNumberOfCoins(0); // prevents banker from accumulating wealth
						final double riches=CMLib.beanCounter().getTotalAbsoluteNativeValue(this);
						if(riches>0.0)
							CMLib.beanCounter().subtractMoney(this,riches);
					}
					else
					{
						List<Item> items;
						if(msg.tool() instanceof Container)
							items=CMLib.utensils().deepCopyOf((Item)msg.tool());
						else
							items=new XVector<Item>((Item)msg.tool().copyOf());
						for(final Item I : items)
						{
							if(!I.amDestroyed())
							{
								addDepositInventory(depositorName,I,I.container());
							}
							else
							{
								CMLib.commands().postSay(this,mob,L("Whoops! Where'd it go?"),true,false);
								super.executeMsg(myHost, msg);
								return;
							}
						}
						CMLib.commands().postSay(this,mob,L("Thank you, @x1 is safe with us.",items.get(0).name()),true,false);
						((Item)msg.tool()).destroy();
					}
				}
				if ((CMSecurity.isAllowed(msg.source(), location(), CMSecurity.SecFlag.ORDER)
				|| (CMLib.law().doesHavePriviledgesHere(msg.source(), getStartRoom()))
				|| (CMSecurity.isAllowed(msg.source(), location(), CMSecurity.SecFlag.CMDMOBS) && (isMonster()))
				|| (CMSecurity.isAllowed(msg.source(), location(), CMSecurity.SecFlag.CMDROOMS) && (isMonster()))))
					return;
				super.executeMsg(myHost, msg);
				return;
			case CMMsg.TYP_BORROW:
				if(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))
				{
					final Item old=(Item)msg.tool();
					if(old instanceof Coins)
					{
						final String borrowerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,false);
						bankLedger(borrowerName,"Loan of "+old.Name()+": "+msg.source().Name());
						addItem(old);
						final double amt=((Coins)old).getTotalValue();
						final CMMsg newMsg=CMClass.getMsg(this,msg.source(),old,CMMsg.MSG_GIVE,L("<S-NAME> give(s) <O-NAME> to <T-NAMESELF>."));
						if(location().okMessage(this,newMsg))
						{
							location().send(this,newMsg);
							((Coins)old).putCoinsBack();
						}
						else
							CMLib.commands().postDrop(this,old,true,false,false);
						final double interestRate=getLoanInterest();
						int months=2;
						while((months<(location().getArea().getTimeObj().getMonthsInYear()*10))
							&&(CMath.div(amt,months)>250.0)) months++;
						final long dueAt=System.currentTimeMillis()+(timeInterval()*months);
						CMLib.beanCounter().adjustDebt(borrowerName,bankChain(),amt,"Bank Loan",interestRate,dueAt);
					}
				}
				break;
			case CMMsg.TYP_WITHDRAW:
				if(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))
				{
					String withdrawerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,false);
					final Item old=(Item)msg.tool();
					if((old instanceof Coins)&&(old.container()==null))
					{
						Item depositInventoryItem=findDepositInventory(withdrawerName,""+Integer.MAX_VALUE);
						if((!isSold(ShopKeeper.DEAL_CLANBANKER))
						&&(msg.source().isMarriedToLiege())
						&&((depositInventoryItem==null)
							||((depositInventoryItem instanceof Coins)
								&&(((Coins)depositInventoryItem).getTotalValue()<((Coins)old).getTotalValue()))))
						{
							final Item item2=findDepositInventory(msg.source().getLiegeID(),""+Integer.MAX_VALUE);
							if((item2!=null)&&(item2 instanceof Coins)&&(((Coins)item2).getTotalValue()>=((Coins)old).getTotalValue()))
							{
								depositInventoryItem=item2;
								final MOB owner=CMLib.players().getPlayerAllHosts(msg.source().getLiegeID());
								if(owner!=null)
									withdrawerName=owner.Name();
							}
						}
						if((depositInventoryItem instanceof Coins)
						&&(old instanceof Coins)
						&&(((Coins)depositInventoryItem).getTotalValue()>=((Coins)old).getTotalValue()))
						{
							final Coins coins=CMLib.beanCounter().makeBestCurrency(this,((Coins)depositInventoryItem).getTotalValue()-((Coins)old).getTotalValue());
							bankLedger(withdrawerName,"Withdrawl of "+CMLib.beanCounter().nameCurrencyShort(this,((Coins)old).getTotalValue())+": "+msg.source().Name());
							delDepositInventory(withdrawerName,depositInventoryItem);

							addItem(old);
							final CMMsg newMsg=CMClass.getMsg(this,msg.source(),old,CMMsg.MSG_GIVE,L("<S-NAME> give(s) <O-NAME> to <T-NAMESELF>."));
							if(location().okMessage(this,newMsg))
							{
								location().send(this,newMsg);
								((Coins)old).putCoinsBack();
							}
							else
								CMLib.commands().postDrop(this,old,true,false,false);
							if((!msg.source().isMonster())
							&&(isSold(ShopKeeper.DEAL_CLANBANKER)))
							{
								final Clan C=CMLib.clans().getClan(withdrawerName);
								if(C!=null)
									C.adjDeposit(msg.source(), -((Coins)msg.tool()).getTotalValue());
							}
							if((coins==null)||(coins.getNumberOfCoins()<=0))
							{
								if(isSold(ShopKeeper.DEAL_CLANBANKER))
									CMLib.commands().postSay(this,mob,L("I have closed the account for @x1. Thanks for your business.",CMStrings.capitalizeFirstLetter(withdrawerName)),true,false);
								else
									CMLib.commands().postSay(this,mob,L("I have closed that account. Thanks for your business."),true,false);
								super.executeMsg(myHost, msg);
								return;
							}
							addDepositInventory(withdrawerName,coins,null);
							if(isSold(ShopKeeper.DEAL_CLANBANKER))
								CMLib.commands().postSay(this,mob,L("Ok, @x1 now has a balance of @x2.",CMStrings.capitalizeFirstLetter(withdrawerName),CMLib.beanCounter().nameCurrencyLong(this,coins.getTotalValue())),true,false);
							else
								CMLib.commands().postSay(this,mob,L("Ok, your new balance is @x1.",CMLib.beanCounter().nameCurrencyLong(this,coins.getTotalValue())),true,false);
						}
						else
						if(depositInventoryItem!=null)
							CMLib.commands().postSay(this,mob,L("But, your balance is @x1.",CMLib.beanCounter().nameCurrencyLong(this,((Coins)depositInventoryItem).getTotalValue())),true,false);
					}
					else
					{
						List<Item> deletedItems=delDepositInventory(withdrawerName,old);
						if((deletedItems.size()==0)
						&&(!isSold(ShopKeeper.DEAL_CLANBANKER))
						&&(msg.source().isMarriedToLiege()))
							deletedItems = delDepositInventory(msg.source().getLiegeID(),old);
						CMLib.commands().postSay(this,mob,L("Thank you for your trust."),true,false);
						for(final Item I : deletedItems)
						{
							if((I instanceof Coins)&&(I.container()!=null))
							{
								mob.addItem(I);
							}
							else
							{
								final Container C=I.container();
								I.setContainer(null); // has to be plainly in the room so that, if the get fails, it will be visible.
								if(location()!=null)
									location().addItem(I,ItemPossessor.Expire.Player_Drop);
								final CMMsg msg2=CMClass.getMsg(mob,I,this,CMMsg.MSG_GET,null);
								if(location().okMessage(mob,msg2))
								{
									location().send(mob,msg2);
									I.setContainer(C);
								}
							}
						}
					}

				}
				super.executeMsg(myHost, msg);
				return;
			case CMMsg.TYP_VALUE:
			case CMMsg.TYP_SELL:
			case CMMsg.TYP_VIEW:
				super.executeMsg(myHost,msg);
				return;
			case CMMsg.TYP_BUY:
				super.executeMsg(myHost,msg);
				return;
			case CMMsg.TYP_LIST:
			{
				super.executeMsg(myHost,msg);
				if(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))
				{
					final String listerName=getBankClientName(msg.source(),Clan.Function.DEPOSIT_LIST,false);
					List<Item> V=null;
					if(isSold(ShopKeeper.DEAL_CLANBANKER))
						V=getDepositedItems(listerName);
					else
					{
						V=getDepositedItems(listerName);
						if(mob.isMarriedToLiege())
						{
							final List<Item> V2=getDepositedItems(mob.getLiegeID());
							if((V2!=null)&&(V2.size()>0))
								V.addAll(V2);
						}
					}
					for(int v=V.size()-1;v>=0;v--)
					{
						if(V.get(v) instanceof LandTitle)
						{
							final LandTitle L=(LandTitle)V.get(v);
							if(!L.isProperlyOwned())
							{
								final Item I=(Item)L;
								delDepositInventory(listerName,I);
								V.remove(I);
							}
						}
					}

					final int COL_LEN=CMLib.lister().fixColWidth(34.0,mob);
					StringBuffer str=new StringBuffer("");
					str.append(L("\n\rAccount balance at '@x1'.\n\r",bankChain()));
					final String c="^x[Item                              ] ";
					str.append(c+c+"^.^N\n\r");
					int colNum=0;
					boolean otherThanCoins=false;
					for(int i=0;i<V.size();i++)
					{
						final Item I=V.get(i);
						if((!(I instanceof Coins))&&(I.container()==null))
						{
							otherThanCoins=true;
							String col=null;
							col="["+CMStrings.padRight(I.name(mob),COL_LEN)+"] ";
							if((++colNum)>2)
							{
								str.append("\n\r");
								colNum=1;
							}
							str.append(col);
						}
					}
					if(!otherThanCoins)
						str=new StringBuffer("\n\r^N");
					else
						str.append("\n\r\n\r");
					final double balance=getBalance(listerName);
					if(balance>0)
					{
						if(isSold(ShopKeeper.DEAL_CLANBANKER))
							str.append(CMStrings.capitalizeFirstLetter(listerName)+" has a balance of ^H"+CMLib.beanCounter().nameCurrencyLong(this,balance)+"^?.");
						else
							str.append("Your balance is ^H"+CMLib.beanCounter().nameCurrencyLong(this,balance)+"^?.");
					}
					final List<MoneyLibrary.DebtItem> debts=CMLib.beanCounter().getDebt(listerName,bankChain());
					if(debts!=null)
					{
						for(int d=0;d<debts.size();d++)
						{
							final MoneyLibrary.DebtItem debt=debts.get(d);
							final long debtDueAt=debt.due();
							final double intRate=debt.interest();
							final double dueAmount=debt.amt();
							final long timeRemaining=debtDueAt-System.currentTimeMillis();
							if(timeRemaining>0)
								str.append(L("\n\r@x1 owe ^H@x2^? in debt.\n\rMonthly interest is @x3%.  The loan must be paid in full in @x4 months.",((isSold(ShopKeeper.DEAL_CLANBANKER))?CMStrings.capitalizeFirstLetter(listerName):L("You")),CMLib.beanCounter().nameCurrencyLong(this,dueAmount),""+(intRate*100.0),""+(timeRemaining/timeInterval())));
						}
					}
					if(coinInterest!=0.0)
					{
						final double cci=CMath.mul(Math.abs(coinInterest),100.0);
						final String ci=((coinInterest>0.0)?"pay ":"charge ")+cci+"% interest ";
						str.append(L("\n\rThey @x1monthly on money deposited here.",ci));
					}
					if(itemInterest!=0.0)
					{
						final double cci=CMath.mul(Math.abs(itemInterest),100.0);
						final String ci=((itemInterest>0.0)?"pay ":"charge ")+cci+"% interest ";
						str.append(L("\n\rThey @x1monthly on items deposited here.",ci));
					}
					mob.tell(str.toString()+"^T");
					for(int i=0;i<V.size();i++)
					{
						final Item I=V.get(i);
						if(I!=null)
							I.destroy();
					}
				}
				return;
			}
			default:
				break;
			}
		}
		else
		if(msg.sourceMinor()==CMMsg.TYP_RETIRE)
			delAllDeposits(msg.source().Name());
		super.executeMsg(myHost,msg);
	}

	@Override
	public boolean okMessage(final Environmental myHost, final CMMsg msg)
	{
		final MOB mob=msg.source();
		if(msg.amITarget(this))
		{
			switch(msg.targetMinor())
			{
			case CMMsg.TYP_GIVE:
			case CMMsg.TYP_DEPOSIT:
				{
					if(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))
						return false;
					if(msg.tool()==null)
						return false;
					final String listerName=getBankClientName(msg.source(),Clan.Function.DEPOSIT,true);
					if(listerName==null)
						return false;
					final double balance=getBalance(listerName);
					if(msg.tool() instanceof Coins)
					{
						if((Double.MAX_VALUE-balance)<=((Coins)msg.tool()).getTotalValue())
						{
							CMLib.commands().postSay(this,mob,L("I'm sorry, the law prevents us from holding that much money in one account."),true,false);
							return false;
						}
						if(!CMLib.beanCounter().isCurrencyMatch(((Coins)msg.tool()).getCurrency(),CMLib.beanCounter().getCurrency(this)))
						{
							CMLib.commands().postSay(this,mob,L("I'm sorry, this bank only deals in @x1.",CMLib.beanCounter().getDenominationName(CMLib.beanCounter().getCurrency(this))),true,false);
							return false;
						}
						return super.okMessage(myHost, msg);
					}
					else
					{
						if(getItemInterest()>0.5)
						{
							CMLib.commands().postSay(this,mob,L("I'm sorry, I don't have any deposit boxes to hold items like that."),true,false);
							return false;
						}
					}
					if(!(msg.tool() instanceof Item))
					{
						mob.tell(L("@x1 doesn't look interested.",mob.charStats().HeShe()));
						return false;
					}
					if(CMLib.flags().isEnspelled((Item)msg.tool())
					|| CMLib.flags().isOnFire((Item)msg.tool())
					||(msg.tool() instanceof CagedAnimal))
					{
						mob.tell(this,msg.tool(),null,L("<S-HE-SHE> refuses to accept <T-NAME> for deposit."));
						return false;
					MOB owner=msg.source();
					double balance=getBalance(withdrawerName);
					final double collateral=totalItemsWorth(withdrawerName);
					if(msg.tool() instanceof Coins)
					{
						if(!((Coins)msg.tool()).getCurrency().equals(CMLib.beanCounter().getCurrency(this)))
						else
							CMLib.commands().postSay(this,mob,L("You'll need a total balance of @x1 for me to hold that.",CMLib.beanCounter().nameCurrencyShort(this,minbalance)),true,false);
						return false;
					}
				}
				return super.okMessage(myHost, msg);
			case CMMsg.TYP_WITHDRAW:
				{
					if(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))
						return false;
					String withdrawerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,true);
					if(withdrawerName==null)
						return false;
					if((msg.tool()==null)||(!(msg.tool() instanceof Item)))
					{
						CMLib.commands().postSay(this,mob,L("What do you want? I'm busy!"),true,false);
						return false;
					}
					if((msg.tool()!=null)&&(!msg.tool().okMessage(myHost,msg)))
						return false;
					MOB owner=msg.source();
					double balance=getBalance(withdrawerName);
					final double totalItemsWorth=totalItemsWorth(withdrawerName);
					if(msg.tool() instanceof Coins)
					{
						if(!CMLib.beanCounter().isCurrencyMatch(((Coins)msg.tool()).getCurrency(),CMLib.beanCounter().getCurrency(this)))
						{
							CMLib.commands().postSay(this,mob,L("I'm sorry, I can only give you @x1.",CMLib.beanCounter().getDenominationName(CMLib.beanCounter().getCurrency(this))),true,false);
							return false;
						}

						if((!isSold(ShopKeeper.DEAL_CLANBANKER))
						&&(owner.isMarriedToLiege())
						&&(balance<((Coins)msg.tool()).getTotalValue()))
						{
					if(msg.tool() instanceof Item)
					{
						final double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());
						if((debt>0.0)
						&&((collateral-((Item)msg.tool()).value())<debt))
						{
								balance=b;
							return false;
						}
					}
					final double minbalance=(collateral/MIN_ITEM_BALANCE_DIVISOR);
					if(msg.tool() instanceof Coins)
					{
						if(((Coins)msg.tool()).getTotalValue()>balance)
						if((!isSold(ShopKeeper.DEAL_CLANBANKER))
						&&(msg.source().isMarriedToLiege())
						&&(findDepositInventory(msg.source().getLiegeID(),msg.tool().Name())!=null))
							owner=CMLib.players().getPlayerAllHosts(msg.source().getLiegeID());
						else
						{
							CMLib.commands().postSay(this,mob,L("You want WHAT?"),true,false);
							return false;
						}
					}
					else
					if(msg.tool() instanceof Item)
					{
						final double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());
						final double collateral=totalItemsPawningWorth(mob,withdrawerName);
						if((debt>0.0)
						&&((collateral-((Item)msg.tool()).value())<debt))
						{
							CMLib.commands().postSay(this,mob,L("I'm sorry, but that item is being held as collateral against your debt at this time."),true,false);
							return false;
						}
					}
					final double minbalance=(totalItemsWorth/MIN_ITEM_BALANCE_DIVISOR);
					if(msg.tool() instanceof Coins)
					{
						if(((Coins)msg.tool()).getTotalValue()>balance)
						{
							if(isSold(ShopKeeper.DEAL_CLANBANKER))
								CMLib.commands().postSay(this,mob,L("I'm sorry,  @x1 has only @x2 in its account.",CMStrings.capitalizeFirstLetter(withdrawerName),CMLib.beanCounter().nameCurrencyShort(this,balance)),true,false);
							else
								CMLib.commands().postSay(this,mob,L("I'm sorry, you have only @x1 in that account.",CMLib.beanCounter().nameCurrencyShort(this,balance)),true,false);
							return false;
						}
						if(minbalance==0)
							return super.okMessage(myHost, msg);
						if(((Coins)msg.tool()).getTotalValue()>(balance-minbalance))
						{
							if((balance-minbalance)>0)
								CMLib.commands().postSay(this,mob,L("I'm sorry, you may only withdraw @x1  at this time.",CMLib.beanCounter().nameCurrencyShort(this,balance-minbalance)),true,false);
							else
								CMLib.commands().postSay(this,mob,L("I am holding other items in trust, so you may not withdraw funds at this time."),true,false);
							return false;
						}
					}
				}
				return super.okMessage(myHost, msg);
			case CMMsg.TYP_VALUE:
			case CMMsg.TYP_SELL:
			case CMMsg.TYP_VIEW:
				return super.okMessage(myHost,msg);
			case CMMsg.TYP_BUY:
				return super.okMessage(myHost,msg);
			case CMMsg.TYP_BORROW:
			{
				if(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))
					return false;
				if(!(msg.tool() instanceof Coins))
				{
					CMLib.commands().postSay(this,mob,L("I'm sorry, only MONEY can be borrowed."),true,false);
					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
					return false;
				}
				final double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsWorth(withdrawerName);
				if(collateralRemaining>0)
				{
					final StringBuffer str=new StringBuffer("");
				final String withdrawerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,true);
						str.append(CMStrings.capitalizeFirstLetter(withdrawerName)+" ");
					else
						str.append("You ");
					str.append(L("will need to deposit enough items with us as collateral.  You'll need items worth @x1 more to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));
					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
					return false;
				}
					final StringBuffer str=new StringBuffer("");
					if(isSold(ShopKeeper.DEAL_CLANBANKER))
						str.append(L("@x1 does not have an account with us, I'm afraid.",CMStrings.capitalizeFirstLetter(withdrawerName)));
					else
						str.append(L("You don't have an account with us, I'm afraid."));
					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
					return false;
				}
				final double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());
				if(debt>0.0)
				{
					final StringBuffer str=new StringBuffer("");
					if(isSold(ShopKeeper.DEAL_CLANBANKER))
						str.append(L("@x1 already has a @x2 loan out with us.",CMStrings.capitalizeFirstLetter(withdrawerName),CMLib.beanCounter().nameCurrencyShort(this,debt)));
					else
						str.append(L("You already have a @x1 loan out with us.",CMLib.beanCounter().nameCurrencyShort(this,debt)));
					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
					return false;
				}
				final double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsPawningWorth(mob,withdrawerName);
				if(collateralRemaining>0)
				{
					final StringBuffer str=new StringBuffer("");
					if(isSold(ShopKeeper.DEAL_CLANBANKER))
						str.append(CMStrings.capitalizeFirstLetter(withdrawerName)+" ");
					else
						str.append("You ");
					str.append(L("will need to deposit enough items with us as collateral.  You'll need items worth @x1 more to me to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));
					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
					return false;
				}
				return super.okMessage(myHost, msg);
			}
			case CMMsg.TYP_LIST:
			{
				if(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))
					return false;
				final String listerName=getBankClientName(msg.source(),Clan.Function.DEPOSIT_LIST,true);
				if(listerName==null)
					return false;
				if((numberDeposited(listerName)==0)
				&&((isSold(ShopKeeper.DEAL_CLANBANKER))
					||(!msg.source().isMarriedToLiege())
					||(numberDeposited(msg.source().getLiegeID())==0)))
				{
					final StringBuffer str=new StringBuffer("");
					if(isSold(ShopKeeper.DEAL_CLANBANKER))
						str.append(L("@x1 does not have an account with us, I'm afraid.",CMStrings.capitalizeFirstLetter(listerName)));
					else
						str.append(L("You don't have an account with us, I'm afraid."));
					if(coinInterest!=0.0)
					{
						final double cci=CMath.mul(Math.abs(coinInterest),100.0);
						final String ci=((coinInterest>0.0)?"pay ":"charge ")+cci+"% interest ";
						str.append(L("\n\rWe @x1monthly on money deposited here.",ci));
					}
					if(itemInterest!=0.0)
					{
						final double cci=CMath.mul(Math.abs(itemInterest),100.0);
						final String ci=((itemInterest>0.0)?"pay ":"charge ")+cci+"% interest ";
						str.append(L("\n\rWe @x1monthly on items kept with us.",ci));
					}
					if(bankChain().length()>0)
						str.append(L("\n\rI am a banker for @x1.",bankChain()));
					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
					return false;
				}
				return true;
			}
			default:
				break;
			}
		}
		return super.okMessage(myHost,msg);
	}
}

<MSG> Loans are now based on the pawning price of the items instead of their full value.

git-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@17628 0d6f1817-ed0e-0410-87c9-987e46238f29

<DFF> @@ -636,6 +636,20 @@ public class StdBanker extends StdShopKeeper implements Banker
 		return min;
 	}
 
+	protected double totalItemsPawningWorth(final MOB buyer, final String depositorName)
+	{
+		final List<Item> V=getDepositedItems(depositorName);
+		double min=0;
+		for(int v=0;v<V.size();v++)
+		{
+			final Item I=V.get(v);
+			if(!(I instanceof Coins))
+				min+=CMLib.coffeeShops().pawningPrice(this, buyer, I, this, shop).absoluteGoldPrice;
+			I.destroy();
+		}
+		return min;
+	}
+
 	@Override
 	public String getBankClientName(final MOB mob, final Clan.Function func, final boolean checked)
 	{
@@ -1072,7 +1086,7 @@ public class StdBanker extends StdShopKeeper implements Banker
 						return false;
 					MOB owner=msg.source();
 					double balance=getBalance(withdrawerName);
-					final double collateral=totalItemsWorth(withdrawerName);
+					final double totalItemsWorth=totalItemsWorth(withdrawerName);
 					if(msg.tool() instanceof Coins)
 					{
 						if(!((Coins)msg.tool()).getCurrency().equals(CMLib.beanCounter().getCurrency(this)))
@@ -1114,6 +1128,7 @@ public class StdBanker extends StdShopKeeper implements Banker
 					if(msg.tool() instanceof Item)
 					{
 						final double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());
+						final double collateral=totalItemsPawningWorth(mob,withdrawerName);
 						if((debt>0.0)
 						&&((collateral-((Item)msg.tool()).value())<debt))
 						{
@@ -1121,7 +1136,7 @@ public class StdBanker extends StdShopKeeper implements Banker
 							return false;
 						}
 					}
-					final double minbalance=(collateral/MIN_ITEM_BALANCE_DIVISOR);
+					final double minbalance=(totalItemsWorth/MIN_ITEM_BALANCE_DIVISOR);
 					if(msg.tool() instanceof Coins)
 					{
 						if(((Coins)msg.tool()).getTotalValue()>balance)
@@ -1187,7 +1202,7 @@ public class StdBanker extends StdShopKeeper implements Banker
 					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
 					return false;
 				}
-				final double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsWorth(withdrawerName);
+				final double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsPawningWorth(mob,withdrawerName);
 				if(collateralRemaining>0)
 				{
 					final StringBuffer str=new StringBuffer("");
@@ -1195,7 +1210,7 @@ public class StdBanker extends StdShopKeeper implements Banker
 						str.append(CMStrings.capitalizeFirstLetter(withdrawerName)+" ");
 					else
 						str.append("You ");
-					str.append(L("will need to deposit enough items with us as collateral.  You'll need items worth @x1 more to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));
+					str.append(L("will need to deposit enough items with us as collateral.  You'll need items worth @x1 more to me to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));
 					CMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);
 					return false;
 				}

{'commit': 'diff --git a/com/planet_ink/coffee_mud/MOBS/StdBanker.java b/com/planet_ink/coffee_mud/MOBS/StdBanker.java\nindex 61dffd590b..77047c07f5 100644\n--- a/com/planet_ink/coffee_mud/MOBS/StdBanker.java\n+++ b/com/planet_ink/coffee_mud/MOBS/StdBanker.java\n@@ -636,6 +636,20 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\treturn min;\r\n \t}\r\n \r\n+\tprotected double totalItemsPawningWorth(final MOB buyer, final String depositorName)\r\n+\t{\r\n+\t\tfinal List<Item> V=getDepositedItems(depositorName);\r\n+\t\tdouble min=0;\r\n+\t\tfor(int v=0;v<V.size();v++)\r\n+\t\t{\r\n+\t\t\tfinal Item I=V.get(v);\r\n+\t\t\tif(!(I instanceof Coins))\r\n+\t\t\t\tmin+=CMLib.coffeeShops().pawningPrice(this, buyer, I, this, shop).absoluteGoldPrice;\r\n+\t\t\tI.destroy();\r\n+\t\t}\r\n+\t\treturn min;\r\n+\t}\r\n+\r\n \t@Override\r\n \tpublic String getBankClientName(final MOB mob, final Clan.Function func, final boolean checked)\r\n \t{\r\n@@ -1072,7 +1086,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\t\treturn false;\r\n \t\t\t\t\tMOB owner=msg.source();\r\n \t\t\t\t\tdouble balance=getBalance(withdrawerName);\r\n-\t\t\t\t\tfinal double collateral=totalItemsWorth(withdrawerName);\r\n+\t\t\t\t\tfinal double totalItemsWorth=totalItemsWorth(withdrawerName);\r\n \t\t\t\t\tif(msg.tool() instanceof Coins)\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\tif(!((Coins)msg.tool()).getCurrency().equals(CMLib.beanCounter().getCurrency(this)))\r\n@@ -1114,6 +1128,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\tif(msg.tool() instanceof Item)\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\tfinal double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());\r\n+\t\t\t\t\t\tfinal double collateral=totalItemsPawningWorth(mob,withdrawerName);\r\n \t\t\t\t\t\tif((debt>0.0)\r\n \t\t\t\t\t\t&&((collateral-((Item)msg.tool()).value())<debt))\r\n \t\t\t\t\t\t{\r\n@@ -1121,7 +1136,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\t\t\treturn false;\r\n \t\t\t\t\t\t}\r\n \t\t\t\t\t}\r\n-\t\t\t\t\tfinal double minbalance=(collateral/MIN_ITEM_BALANCE_DIVISOR);\r\n+\t\t\t\t\tfinal double minbalance=(totalItemsWorth/MIN_ITEM_BALANCE_DIVISOR);\r\n \t\t\t\t\tif(msg.tool() instanceof Coins)\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\tif(((Coins)msg.tool()).getTotalValue()>balance)\r\n@@ -1187,7 +1202,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\r\n \t\t\t\t\treturn false;\r\n \t\t\t\t}\r\n-\t\t\t\tfinal double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsWorth(withdrawerName);\r\n+\t\t\t\tfinal double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsPawningWorth(mob,withdrawerName);\r\n \t\t\t\tif(collateralRemaining>0)\r\n \t\t\t\t{\r\n \t\t\t\t\tfinal StringBuffer str=new StringBuffer("");\r\n@@ -1195,7 +1210,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\t\tstr.append(CMStrings.capitalizeFirstLetter(withdrawerName)+" ");\r\n \t\t\t\t\telse\r\n \t\t\t\t\t\tstr.append("You ");\r\n-\t\t\t\t\tstr.append(L("will need to deposit enough items with us as collateral.  You\'ll need items worth @x1 more to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));\r\n+\t\t\t\t\tstr.append(L("will need to deposit enough items with us as collateral.  You\'ll need items worth @x1 more to me to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));\r\n \t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\r\n \t\t\t\t\treturn false;\r\n \t\t\t\t}\r\n', 'commit_subject': 'Loans are now based on the pawning price of the items instead of their full value.', 'repo_name': 'bozimmerman/CoffeeMud', 'committer': {'name': 'bozimmerman', 'email': 'dc45fe023482b3b890b5e574e53c1d051f45b1ef@zimmers.net', 'time_sec': '1548093586', 'tz_offset': '0', 'date': {'seconds': '1548093586'}}, 'commit_tree': 'c52e263e48b6debbd726e003e4d195ffe7d44fb8', 'commit_message': 'Loans are now based on the pawning price of the items instead of their full value.\n\ngit-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@17628 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'language_name': 'JavaScript', 'license': 'apache-2.0', 'hunks': '@@ -636,6 +636,20 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\treturn min;\r\n \t}\r\n \r\n+\tprotected double totalItemsPawningWorth(final MOB buyer, final String depositorName)\r\n+\t{\r\n+\t\tfinal List<Item> V=getDepositedItems(depositorName);\r\n+\t\tdouble min=0;\r\n+\t\tfor(int v=0;v<V.size();v++)\r\n+\t\t{\r\n+\t\t\tfinal Item I=V.get(v);\r\n+\t\t\tif(!(I instanceof Coins))\r\n+\t\t\t\tmin+=CMLib.coffeeShops().pawningPrice(this, buyer, I, this, shop).absoluteGoldPrice;\r\n+\t\t\tI.destroy();\r\n+\t\t}\r\n+\t\treturn min;\r\n+\t}\r\n+\r\n \t@Override\r\n \tpublic String getBankClientName(final MOB mob, final Clan.Function func, final boolean checked)\r\n \t{\r\n@@ -1072,7 +1086,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\t\treturn false;\r\n \t\t\t\t\tMOB owner=msg.source();\r\n \t\t\t\t\tdouble balance=getBalance(withdrawerName);\r\n-\t\t\t\t\tfinal double collateral=totalItemsWorth(withdrawerName);\r\n+\t\t\t\t\tfinal double totalItemsWorth=totalItemsWorth(withdrawerName);\r\n \t\t\t\t\tif(msg.tool() instanceof Coins)\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\tif(!((Coins)msg.tool()).getCurrency().equals(CMLib.beanCounter().getCurrency(this)))\r\n@@ -1114,6 +1128,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\tif(msg.tool() instanceof Item)\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\tfinal double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());\r\n+\t\t\t\t\t\tfinal double collateral=totalItemsPawningWorth(mob,withdrawerName);\r\n \t\t\t\t\t\tif((debt>0.0)\r\n \t\t\t\t\t\t&&((collateral-((Item)msg.tool()).value())<debt))\r\n \t\t\t\t\t\t{\r\n@@ -1121,7 +1136,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\t\t\treturn false;\r\n \t\t\t\t\t\t}\r\n \t\t\t\t\t}\r\n-\t\t\t\t\tfinal double minbalance=(collateral/MIN_ITEM_BALANCE_DIVISOR);\r\n+\t\t\t\t\tfinal double minbalance=(totalItemsWorth/MIN_ITEM_BALANCE_DIVISOR);\r\n \t\t\t\t\tif(msg.tool() instanceof Coins)\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\tif(((Coins)msg.tool()).getTotalValue()>balance)\r\n@@ -1187,7 +1202,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\r\n \t\t\t\t\treturn false;\r\n \t\t\t\t}\r\n-\t\t\t\tfinal double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsWorth(withdrawerName);\r\n+\t\t\t\tfinal double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsPawningWorth(mob,withdrawerName);\r\n \t\t\t\tif(collateralRemaining>0)\r\n \t\t\t\t{\r\n \t\t\t\t\tfinal StringBuffer str=new StringBuffer("");\r\n@@ -1195,7 +1210,7 @@ public class StdBanker extends StdShopKeeper implements Banker\n \t\t\t\t\t\tstr.append(CMStrings.capitalizeFirstLetter(withdrawerName)+" ");\r\n \t\t\t\t\telse\r\n \t\t\t\t\t\tstr.append("You ");\r\n-\t\t\t\t\tstr.append(L("will need to deposit enough items with us as collateral.  You\'ll need items worth @x1 more to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));\r\n+\t\t\t\t\tstr.append(L("will need to deposit enough items with us as collateral.  You\'ll need items worth @x1 more to me to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));\r\n \t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\r\n \t\t\t\t\treturn false;\r\n \t\t\t\t}\r\n', 'addition_count': 19, 'deletion_count': 4, 'src_file': 'a/com/planet_ink/coffee_mud/MOBS/StdBanker.java', 'tgt_file': 'b/com/planet_ink/coffee_mud/MOBS/StdBanker.java', 'file_extension': '.java', 'before_file': 'package com.planet_ink.coffee_mud.MOBS;\nimport com.planet_ink.coffee_mud.core.interfaces.*;\nimport com.planet_ink.coffee_mud.core.*;\nimport com.planet_ink.coffee_mud.core.collections.*;\nimport com.planet_ink.coffee_mud.Abilities.interfaces.*;\nimport com.planet_ink.coffee_mud.Areas.interfaces.*;\nimport com.planet_ink.coffee_mud.Behaviors.interfaces.*;\nimport com.planet_ink.coffee_mud.CharClasses.interfaces.*;\nimport com.planet_ink.coffee_mud.Commands.interfaces.*;\nimport com.planet_ink.coffee_mud.Common.interfaces.*;\nimport com.planet_ink.coffee_mud.Exits.interfaces.*;\nimport com.planet_ink.coffee_mud.Items.interfaces.*;\nimport com.planet_ink.coffee_mud.Locales.interfaces.*;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.*;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.DatabaseEngine.PlayerData;\nimport com.planet_ink.coffee_mud.MOBS.interfaces.*;\nimport com.planet_ink.coffee_mud.Races.interfaces.*;\n\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\n/*\n   Copyright 2003-2022 Bo Zimmerman\n\n   Licensed under the Apache License, Version 2.0 (the "License");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n\t   http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an "AS IS" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\npublic class StdBanker extends StdShopKeeper implements Banker\n{\n\t@Override\n\tpublic String ID()\n\t{\n\t\treturn "StdBanker";\n\t}\n\n\tprotected double\t\t\t\t\tcoinInterest\t= -0.000;\n\tprotected double\t\t\t\t\titemInterest\t= -0.0001;\n\tprotected double\t\t\t\t\tloanInterest\t= 0.01;\n\tprotected static Map<String, Long>\tbankTimes\t\t= new Hashtable<String, Long>();\n\n\tpublic StdBanker()\n\t{\n\t\tsuper();\n\t\t_name="a banker";\n\t\tsetDescription("He\\\\`s pleased to be of assistance.");\n\t\tsetDisplayText("A banker is waiting to serve you.");\n\t\tCMLib.factions().setAlignment(this,Faction.Align.GOOD);\n\t\tsetMoney(0);\n\t\twhatIsSoldMask=ShopKeeper.DEAL_BANKER;\n\t\tbasePhyStats.setWeight(150);\n\t\tsetWimpHitPoint(0);\n\n\t\tbaseCharStats().setStat(CharStats.STAT_INTELLIGENCE,16);\n\t\tbaseCharStats().setStat(CharStats.STAT_CHARISMA,25);\n\n\t\tbasePhyStats().setArmor(0);\n\n\t\tbaseState.setHitPoints(1000);\n\n\t\trecoverMaxState();\n\t\tresetToMaxState();\n\t\trecoverPhyStats();\n\t\trecoverCharStats();\n\t}\n\n\t@Override\n\tpublic void addSoldType(final int mask)\n\t{\n\t\tsetWhatIsSoldMask(CMath.abs(mask));\n\t}\n\n\t@Override\n\tpublic void setWhatIsSoldMask(final long newSellCode)\n\t{\n\t\tsuper.setWhatIsSoldMask(newSellCode);\n\t\tif(!isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\twhatIsSoldMask=ShopKeeper.DEAL_BANKER;\n\t\telse\n\t\t\twhatIsSoldMask=ShopKeeper.DEAL_CLANBANKER;\n\t}\n\n\t@Override\n\tpublic String bankChain()\n\t{\n\t\treturn text();\n\t}\n\n\t@Override\n\tpublic void setBankChain(final String name)\n\t{\n\t\tsetMiscText(name);\n\t}\n\n\t@Override\n\tpublic void addDepositInventory(final String depositorName, final Item item, final Item container)\n\t{\n\t\tfinal String classID;\n\t\tif((item instanceof Coins)&&(container == null))\n\t\t{\n\t\t\t((Coins)item).setCurrency(CMLib.beanCounter().getCurrency(this));\n\t\t\tclassID="COINS";\n\t\t}\n\t\telse\n\t\t\tclassID=item.ID();\n\t\tCMLib.catalog().updateCatalogIntegrity(item);\n\t\tfinal String key=""+item+item.hashCode();\n\t\tif(container != null)\n\t\t{\n\t\t\tfinal String containerKey=""+container+container.hashCode();\n\t\t\tCMLib.database().DBCreatePlayerData(depositorName,bankChain(),key,classID+";CONTAINER="+containerKey+";"+CMLib.coffeeMaker().getEnvironmentalMiscTextXML(item,true));\n\t\t}\n\t\telse\n\t\t\tCMLib.database().DBCreatePlayerData(depositorName,bankChain(),key,classID+";"+CMLib.coffeeMaker().getEnvironmentalMiscTextXML(item,true));\n\t}\n\n\tprotected Pair<Item,String> makeItemContainer(final String data)\n\t{\n\t\tint x=data.indexOf(\';\');\n\t\tif(x<0)\n\t\t\treturn null;\n\t\tItem I=null;\n\t\tif(data.substring(0,x).equals("COINS"))\n\t\t\tI=CMClass.getItem("StdCoins");\n\t\telse\n\t\t\tI=CMClass.getItem(data.substring(0,x));\n\t\tif(I!=null)\n\t\t{\n\t\t\tString container="";\n\t\t\tString xml = data.substring(x+1);\n\t\t\tif(xml.startsWith("CONTAINER="))\n\t\t\t{\n\t\t\t\tx=xml.indexOf(\';\');\n\t\t\t\tif(x>0)\n\t\t\t\t{\n\t\t\t\t\tcontainer=xml.substring(10,x);\n\t\t\t\t\txml=xml.substring(x+1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tCMLib.coffeeMaker().unpackEnvironmentalMiscTextXML(I,xml,true);\n\t\t\tif((I instanceof Coins)\n\t\t\t&&(((Coins)I).getDenomination()==0.0)\n\t\t\t&&(((Coins)I).getNumberOfCoins()>0))\n\t\t\t\t((Coins)I).setDenomination(1.0);\n\t\t\tI.recoverPhyStats();\n\t\t\tI.text();\n\t\t\treturn new Pair<Item,String>(I,container);\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected List<Item> findDeleteRecursiveDepositInventoryByContainerKey(final Container C, final List<PlayerData> rawInventoryV, final String key)\n\t{\n\t\tfinal List<Item> inventory=new LinkedList<Item>();\n\t\tfor(int v=rawInventoryV.size()-1;v>=0;v--)\n\t\t{\n\t\t\tfinal DatabaseEngine.PlayerData PD=rawInventoryV.get(v);\n\t\t\tfinal int IDx=PD.xml().indexOf(\';\');\n\t\t\tif(IDx>0)\n\t\t\t{\n\t\t\t\tif(PD.xml().substring(IDx+1).startsWith("CONTAINER="+key+";"))\n\t\t\t\t{\n\t\t\t\t\tfinal Item I=makeItemContainer(PD.xml()).first;\n\t\t\t\t\tI.setContainer(C);\n\t\t\t\t\tinventory.add(I);\n\t\t\t\t\trawInventoryV.remove(v);\n\t\t\t\t\tif(I instanceof Container)\n\t\t\t\t\t\tinventory.addAll(findDeleteRecursiveDepositInventoryByContainerKey((Container)I,rawInventoryV,PD.key()));\n\t\t\t\t\tCMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn inventory;\n\t}\n\n\t@Override\n\tpublic List<Item> delDepositInventory(final String depositorName, final Item likeItem)\n\t{\n\t\tfinal List<PlayerData> rawInventoryV=getRawPDDepositInventory(depositorName);\n\t\tfinal List<Item> items = new ArrayList<Item>();\n\t\tif(likeItem.container()==null)\n\t\t{\n\t\t\tif(likeItem instanceof Coins)\n\t\t\t{\n\t\t\t\tfor(int v=rawInventoryV.size()-1;v>=0;v--)\n\t\t\t\t{\n\t\t\t\t\tfinal DatabaseEngine.PlayerData PD=rawInventoryV.get(v);\n\t\t\t\t\tif(PD.xml().startsWith("COINS;"))\n\t\t\t\t\t{\n\t\t\t\t\t\tCMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());\n\t\t\t\t\t\titems.add(makeItemContainer(PD.xml()).first);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor(int v=rawInventoryV.size()-1;v>=0;v--)\n\t\t\t\t{\n\t\t\t\t\tfinal DatabaseEngine.PlayerData PD=rawInventoryV.get(v);\n\t\t\t\t\tif(PD.xml().startsWith(likeItem.ID()+";") && (!PD.xml().startsWith(likeItem.ID()+";CONTAINER=")))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Pair<Item,String> pI=makeItemContainer(PD.xml());\n\t\t\t\t\t\tif((pI!=null) && likeItem.sameAs(pI.first))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpI.first.setContainer(null);\n\t\t\t\t\t\t\tif(pI.first instanceof Container)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\titems.add(pI.first);\n\t\t\t\t\t\t\t\tfinal Hashtable<String,List<DatabaseEngine.PlayerData>> pairings=new Hashtable<String,List<DatabaseEngine.PlayerData>>();\n\t\t\t\t\t\t\t\tfor(final PlayerData PDp : rawInventoryV)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal int IDx=PDp.xml().indexOf(\';\');\n\t\t\t\t\t\t\t\t\tif(IDx>0)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal String subXML=PDp.xml().substring(IDx+1);\n\t\t\t\t\t\t\t\t\t\tif(subXML.startsWith("CONTAINER="))\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfinal int x=subXML.indexOf(\';\');\n\t\t\t\t\t\t\t\t\t\t\tif(x>0)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tfinal String contKey=subXML.substring(10,x);\n\t\t\t\t\t\t\t\t\t\t\t\tif(!pairings.containsKey(contKey))\n\t\t\t\t\t\t\t\t\t\t\t\t\tpairings.put(contKey, new LinkedList<DatabaseEngine.PlayerData>());\n\t\t\t\t\t\t\t\t\t\t\t\tpairings.get(contKey).add(PDp);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tCMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());\n\t\t\t\t\t\t\t\tfinal Map<String,Container> containerMap=new Hashtable<String,Container>();\n\t\t\t\t\t\t\t\tcontainerMap.put(PD.key(), (Container)pI.first);\n\t\t\t\t\t\t\t\twhile(containerMap.size()>0)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal String contKey=containerMap.keySet().iterator().next();\n\t\t\t\t\t\t\t\t\tfinal Container container=containerMap.remove(contKey);\n\t\t\t\t\t\t\t\t\tfinal List<DatabaseEngine.PlayerData> contents=pairings.get(contKey);\n\t\t\t\t\t\t\t\t\tif(contents != null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfor(final DatabaseEngine.PlayerData PDi : contents)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfinal Pair<Item,String> pairI=makeItemContainer(PDi.xml());\n\t\t\t\t\t\t\t\t\t\t\tCMLib.database().DBDeletePlayerData(PDi.who(),PDi.section(),PDi.key());\n\t\t\t\t\t\t\t\t\t\t\tpairI.first.setContainer(container);\n\t\t\t\t\t\t\t\t\t\t\titems.add(pairI.first);\n\t\t\t\t\t\t\t\t\t\t\tif(pairI.first instanceof Container)\n\t\t\t\t\t\t\t\t\t\t\t\tcontainerMap.put(PDi.key(), (Container)pairI.first);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\titems.add(pI.first);\n\t\t\t\t\t\t\t\tCMLib.database().DBDeletePlayerData(PD.who(),PD.section(),PD.key());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn items;\n\t}\n\n\t@Override\n\tpublic void delAllDeposits(final String depositorName)\n\t{\n\t\tCMLib.database().DBDeletePlayerData(depositorName,bankChain());\n\t}\n\n\t@Override\n\tpublic int numberDeposited(final String depositorName)\n\t{\n\t\treturn getRawPDDepositInventory(depositorName).size();\n\t}\n\n\t@Override\n\tpublic List<Item> getDepositedItems(final String depositorName)\n\t{\n\t\tif((depositorName==null)||(depositorName.length()==0))\n\t\t\treturn new ArrayList<Item>();\n\t\tfinal List<Item> items=new Vector<Item>();\n\t\tfinal Hashtable<String,Pair<Item,String>> pairings=new Hashtable<String,Pair<Item,String>>();\n\t\tfor(final PlayerData PD : getRawPDDepositInventory(depositorName))\n\t\t{\n\t\t\tfinal Pair<Item,String> pair=makeItemContainer(PD.xml());\n\t\t\tif(pair!=null)\n\t\t\t\tpairings.put(PD.key(), pair);\n\t\t}\n\t\tfor(final Pair<Item,String> pair : pairings.values())\n\t\t{\n\t\t\tif(pair.second.length()>0)\n\t\t\t{\n\t\t\t\tfinal Pair<Item,String> otherPair = pairings.get(pair.second);\n\t\t\t\tif((otherPair != null)&&(otherPair.first instanceof Container))\n\t\t\t\t\tpair.first.setContainer((Container)otherPair.first);\n\t\t\t}\n\t\t\titems.add(pair.first);\n\t\t}\n\t\treturn items;\n\t}\n\n\tprotected List<PlayerData> getRawPDDepositInventory(final String depositorName)\n\t{\n\t\treturn CMLib.database().DBReadPlayerData(depositorName,bankChain());\n\t}\n\n\t@Override\n\tpublic List<String> getAccountNames()\n\t{\n\t\tfinal List<String> V=CMLib.database().DBReadPlayerDataPlayersBySection(bankChain());\n\t\tfinal HashSet<String> h=new HashSet<String>();\n\t\tfinal Vector<String> mine=new Vector<String>();\n\t\tfor(int v=0;v<V.size();v++)\n\t\t{\n\t\t\tfinal String name=V.get(v);\n\t\t\tif(!h.contains(name))\n\t\t\t{\n\t\t\t\th.add(name);\n\t\t\t\tmine.addElement(name);\n\t\t\t}\n\t\t}\n\t\treturn mine;\n\t}\n\n\t@Override\n\tpublic boolean isAccountName(final String name)\n\t{\n\t\treturn CMLib.database().DBExistsPlayerData(bankChain(),name);\n\t}\n\n\tprotected void bankLedger(final String depositorName, final String msg)\n\t{\n\t\tfinal String date=CMLib.utensils().getFormattedDate(this);\n\t\tCMLib.beanCounter().addToBankLedger(bankChain(),depositorName,date+": "+msg);\n\t}\n\n\t@Override\n\tpublic Item findDepositInventory(final String depositorName, final String itemName)\n\t{\n\t\tfinal List<PlayerData> V=getRawPDDepositInventory(depositorName);\n\t\tif(CMath.s_int(itemName)>0)\n\t\t{\n\t\t\tfor(int v=0;v<V.size();v++)\n\t\t\t{\n\t\t\t\tfinal DatabaseEngine.PlayerData PD=V.get(v);\n\t\t\t\tif(PD.xml().startsWith("COINS;"))\n\t\t\t\t\treturn makeItemContainer(PD.xml()).first;\n\t\t\t}\n\t\t}\n\t\telse\n\t\tfor(int v=0;v<V.size();v++)\n\t\t{\n\t\t\tfinal DatabaseEngine.PlayerData PD=V.get(v);\n\t\t\tif(PD.xml().lastIndexOf(";CONTAINER=",81)<0)\n\t\t\t{\n\t\t\t\tfinal Pair<Item,String> pair=makeItemContainer(PD.xml());\n\t\t\t\tif(pair!=null)\n\t\t\t\t{\n\t\t\t\t\tif(CMLib.english().containsString(pair.first.Name(),itemName))\n\t\t\t\t\t\treturn pair.first;\n\t\t\t\t\tpair.first.destroy();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic long timeInterval()\n\t{\n\t\treturn (location().getArea().getTimeObj().getHoursInDay())\n\t\t\t\t*CMProps.getMillisPerMudHour()\n\t\t\t\t*location().getArea().getTimeObj().getDaysInMonth();\n\t}\n\n\t@Override\n\tpublic void setCoinInterest(final double interest)\n\t{\n\t\tcoinInterest = interest;\n\t}\n\n\t@Override\n\tpublic void setItemInterest(final double interest)\n\t{\n\t\titemInterest = interest;\n\t}\n\n\t@Override\n\tpublic double getCoinInterest()\n\t{\n\t\treturn coinInterest;\n\t}\n\n\t@Override\n\tpublic double getItemInterest()\n\t{\n\t\treturn itemInterest;\n\t}\n\n\t@Override\n\tpublic void setLoanInterest(final double interest)\n\t{\n\t\tloanInterest = interest;\n\t}\n\n\t@Override\n\tpublic double getLoanInterest()\n\t{\n\t\treturn loanInterest;\n\t}\n\n\t@Override\n\tpublic MoneyLibrary.DebtItem getDebtInfo(final String depositorName)\n\t{\n\t\tfinal List<MoneyLibrary.DebtItem> debt=CMLib.beanCounter().getDebtOwed(bankChain());\n\t\tif(depositorName.length()==0)\n\t\t\treturn null;\n\t\tfor(int d=0;d<debt.size();d++)\n\t\t{\n\t\t\tif(debt.get(d).debtor().equalsIgnoreCase(depositorName))\n\t\t\t\treturn debt.get(d);\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected void processAccounts()\n\t{\n\t\tboolean proceed=false;\n\t\tLong L=bankTimes.get(bankChain());\n\t\tlong timeInterval=1;\n\t\tif(((L==null)||(L.longValue()<System.currentTimeMillis()))\n\t\t&&(location!=null)\n\t\t&&(location.getArea()!=null)\n\t\t&&(location.getArea().getTimeObj()!=null)\n\t\t&&(CMLib.flags().isInTheGame(this,true)))\n\t\t{\n\t\t\ttimeInterval=timeInterval();\n\t\t\tL=Long.valueOf(System.currentTimeMillis()+timeInterval);\n\t\t\tproceed=true;\n\t\t\tbankTimes.remove(bankChain());\n\t\t\tbankTimes.put(bankChain(),L);\n\t\t}\n\t\tif(proceed)\n\t\t{\n\t\t\tfinal List<String> bankDataV=CMLib.database().DBReadPlayerDataPlayersBySection(bankChain());\n\t\t\tfinal Set<String> userNames=new HashSet<String>();\n\t\t\tfor(int v=0;v<bankDataV.size();v++)\n\t\t\t{\n\t\t\t\tfinal String name=bankDataV.get(v);\n\t\t\t\tif(!userNames.contains(name))\n\t\t\t\t{\n\t\t\t\t\tif(!CMLib.players().playerExistsAllHosts(name))\n\t\t\t\t\t{\n\t\t\t\t\t\tif((CMLib.clans().getClanAnyHost(name))==null)\n\t\t\t\t\t\t\tdelAllDeposits(name);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tuserNames.add(name);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tuserNames.add(name);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinal List<MoneyLibrary.DebtItem> debts=CMLib.beanCounter().getDebtOwed(bankChain());\n\t\t\tfor(final Iterator<String> i=userNames.iterator();i.hasNext();)\n\t\t\t{\n\t\t\t\tfinal String name=i.next();\n\t\t\t\tCoins coinItem=null;\n\t\t\t\tint totalValue=0;\n\t\t\t\tfinal List<Item> items=getDepositedItems(name);\n\t\t\t\tfor(int v=0;v<items.size();v++)\n\t\t\t\t{\n\t\t\t\t\tfinal Item I=items.get(v);\n\t\t\t\t\tif(I instanceof Coins)\n\t\t\t\t\t\tcoinItem=(Coins)I;\n\t\t\t\t\telse\n\t\t\t\t\tif(itemInterest!=0.0)\n\t\t\t\t\t\ttotalValue+=I.value();\n\t\t\t\t}\n\t\t\t\tdouble newBalance=0.0;\n\t\t\t\tif(coinItem!=null)\n\t\t\t\t\tnewBalance=coinItem.getTotalValue();\n\t\t\t\tnewBalance+=CMath.mul(newBalance,coinInterest);\n\t\t\t\tif(totalValue>0)\n\t\t\t\t\tnewBalance+=CMath.mul(totalValue,itemInterest);\n\t\t\t\tfor(int d=debts.size()-1;d>=0;d--)\n\t\t\t\t{\n\t\t\t\t\tfinal MoneyLibrary.DebtItem debtItem=debts.get(d);\n\t\t\t\t\tfinal String debtor=debtItem.debtor();\n\t\t\t\t\tif(debtor.equalsIgnoreCase(name))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal long debtDueAt = debtItem.due();\n\t\t\t\t\t\tfinal double intRate = debtItem.interest();\n\t\t\t\t\t\tfinal double dueAmount = debtItem.amt();\n\t\t\t\t\t\tfinal String reason = debtItem.reason();\n\t\t\t\t\t\tfinal double intDue = CMath.mul(intRate, dueAmount);\n\t\t\t\t\t\tfinal long timeRemaining = debtDueAt - System.currentTimeMillis();\n\t\t\t\t\t\tif((timeRemaining<0)&&(newBalance<((dueAmount)+intDue)))\n\t\t\t\t\t\t\tnewBalance=-1.0;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal double amtDueNow=(timeRemaining<0)?(dueAmount+intDue):CMath.div((dueAmount+intDue),(timeRemaining/timeInterval));\n\t\t\t\t\t\t\tif(newBalance>=amtDueNow)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCMLib.beanCounter().addToBankLedger(bankChain(),name,CMLib.utensils().getFormattedDate(this)+": Withdrawal of "+CMLib.beanCounter().nameCurrencyShort(this,amtDueNow)+": Loan payment made.");\n\t\t\t\t\t\t\t\tCMLib.beanCounter().adjustDebt(debtor,bankChain(),intDue-amtDueNow,reason,intRate,debtDueAt);\n\t\t\t\t\t\t\t\tnewBalance-=amtDueNow;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tCMLib.beanCounter().adjustDebt(debtor,bankChain(),intDue,reason,intRate,debtDueAt);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdebts.remove(d);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(newBalance<0)\n\t\t\t\t{\n\t\t\t\t\tfor(int v=0;v<items.size();v++)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Item I=items.get(v);\n\t\t\t\t\t\tif((I instanceof LandTitle)&&(((LandTitle)I).getOwnerName().length()>0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t((LandTitle)I).setOwnerName("");\n\t\t\t\t\t\t\t((LandTitle)I).updateTitle();\n\t\t\t\t\t\t\t((LandTitle)I).updateLot(null);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!(I instanceof Coins))\n\t\t\t\t\t\t\tgetShop().addStoreInventory(I);\n\t\t\t\t\t}\n\t\t\t\t\tdelAllDeposits(name);\n\t\t\t\t\tCMLib.beanCounter().delAllDebt(name,bankChain());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif((coinItem==null)||(newBalance!=coinItem.getTotalValue()))\n\t\t\t\t{\n\t\t\t\t\tif(coinItem!=null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(newBalance>coinItem.getTotalValue())\n\t\t\t\t\t\t\tCMLib.beanCounter().addToBankLedger(bankChain(),name,CMLib.utensils().getFormattedDate(this)+": Deposit of "+CMLib.beanCounter().nameCurrencyShort(this,newBalance-coinItem.getTotalValue())+": Interest paid.");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tCMLib.beanCounter().addToBankLedger(bankChain(),name,CMLib.utensils().getFormattedDate(this)+": Withdrawl of "+CMLib.beanCounter().nameCurrencyShort(this,coinItem.getTotalValue()-newBalance)+": Interest charged.");\n\t\t\t\t\t\tdelDepositInventory(name,coinItem);\n\t\t\t\t\t}\n\t\t\t\t\tfinal String currency=CMLib.beanCounter().getCurrency(this);\n\t\t\t\t\tcoinItem=CMLib.beanCounter().makeBestCurrency(currency,newBalance);\n\t\t\t\t\tif(coinItem!=null)\n\t\t\t\t\t\taddDepositInventory(name,coinItem,null);\n\t\t\t\t}\n\t\t\t\tfor(int v=0;v<items.size();v++)\n\t\t\t\t{\n\t\t\t\t\tfinal Item I=items.get(v);\n\t\t\t\t\tif(I!=null)\n\t\t\t\t\t\tI.destroy();\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(int d=debts.size()-1;d>=0;d--)\n\t\t\t\tCMLib.beanCounter().delAllDebt(debts.get(d).debtor(),bankChain());\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean tick(final Tickable ticking, final int tickID)\n\t{\n\t\tif(!super.tick(ticking,tickID))\n\t\t\treturn false;\n\t\tif(!CMProps.getBoolVar(CMProps.Bool.MUDSTARTED))\n\t\t\treturn true;\n\t\ttry\n\t\t{\n\t\t\tif(tickID==Tickable.TICKID_MOB)\n\t\t\t{\n\t\t\t\t// handle interest by watching the days go by...\n\t\t\t\t// put stuff up for sale if the account runs out\n\t\t\t\tAtomicBoolean flag;\n\t\t\t\tsynchronized(StdBanker.class)\n\t\t\t\t{\n\t\t\t\t\t@SuppressWarnings({ "unchecked", "rawtypes" })\n\t\t\t\t\tMap<String,AtomicBoolean> processingMap = (Map)Resources.getResource("SYSTEM_SEMAPHORES_BANKING");\n\t\t\t\t\tif(processingMap == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tprocessingMap = new TreeMap<String,AtomicBoolean>();\n\t\t\t\t\t\tResources.submitResource("SYSTEM_SEMAPHORES_BANKING", processingMap);\n\t\t\t\t\t}\n\t\t\t\t\tflag = processingMap.get(bankChain());\n\t\t\t\t\tif(flag == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tflag = new AtomicBoolean(false);\n\t\t\t\t\t\tprocessingMap.put(bankChain(), flag);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tboolean isProcessing=true;\n\t\t\t\tsynchronized(flag)\n\t\t\t\t{\n\t\t\t\t\tisProcessing = flag.get();\n\t\t\t\t\tif(!isProcessing)\n\t\t\t\t\t\tflag.set(true);\n\t\t\t\t}\n\t\t\t\tif(!isProcessing)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tprocessAccounts();\n\t\t\t\t\t}\n\t\t\t\t\tfinally\n\t\t\t\t\t{\n\t\t\t\t\t\tflag.set(false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (final Exception e)\n\t\t{\n\t\t\tLog.errOut("StdBanker", e);\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic double getBalance(final String depositorName)\n\t{\n\t\tfinal Item old=findDepositInventory(depositorName,""+Integer.MAX_VALUE);\n\t\tif((old!=null)&&(old instanceof Coins))\n\t\t\treturn ((Coins)old).getTotalValue();\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic double totalItemsWorth(final String depositorName)\n\t{\n\t\treturn min;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic String getBankClientName(final MOB mob, final Clan.Function func, final boolean checked)\r\n\t{\r\n\t\t\t\tmin+=CMLib.coffeeShops().pawningPrice(this, buyer, I, this, shop).absoluteGoldPrice;\n\t\t\tI.destroy();\n\t\t}\n\t\treturn min;\n\t}\n\n\t@Override\n\tpublic String getBankClientName(final MOB mob, final Clan.Function func, final boolean checked)\n\t{\n\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t{\n\t\t\tfinal Pair<Clan,Integer> clanPair=CMLib.clans().findPrivilegedClan(mob, func);\n\t\t\tif(clanPair!=null)\n\t\t\t\treturn clanPair.first.clanID();\n\t\t\telse\n\t\t\tif(checked)\n\t\t\t{\n\t\t\t\tif(mob.clans().iterator().hasNext())\n\t\t\t\t{\n\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, you aren\'t authorized by your clan to do that."),true,false);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, I only deal with clans."),true,false);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn mob.Name();\n\t}\n\n\t@Override\n\tpublic void executeMsg(final Environmental myHost, final CMMsg msg)\n\t{\n\t\tfinal MOB mob=msg.source();\n\t\tif(msg.amITarget(this))\n\t\t{\n\t\t\tswitch(msg.targetMinor())\n\t\t\t{\n\t\t\tcase CMMsg.TYP_GIVE:\n\t\t\tcase CMMsg.TYP_DEPOSIT:\n\t\t\t\tif(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))\n\t\t\t\t{\n\t\t\t\t\tString depositorName=getBankClientName(msg.source(),Clan.Function.DEPOSIT,false);\n\t\t\t\t\t//if(msg.tool() instanceof Container)\n\t\t\t\t\t//\t((Container)msg.tool()).emptyPlease(true);\n\t\t\t\t\tCMMsg msg2=CMClass.getMsg(msg.source(),msg.tool(),null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null);\n\t\t\t\t\tlocation().send(this,msg2);\n\t\t\t\t\tmsg2=CMClass.getMsg((MOB)msg.target(),msg.tool(),null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null);\n\t\t\t\t\tlocation().send(this,msg2);\n\t\t\t\t\tif(msg.tool() instanceof Coins)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Coins older=(Coins)msg.tool();\n\t\t\t\t\t\tdouble newValue=older.getTotalValue();\n\t\t\t\t\t\tItem oldCoins=findDepositInventory(depositorName,""+Integer.MAX_VALUE);\n\t\t\t\t\t\tif((oldCoins==null)\n\t\t\t\t\t\t&&(!isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t&&(msg.source().isMarriedToLiege()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toldCoins=findDepositInventory(msg.source().getLiegeID(),""+Integer.MAX_VALUE);\n\t\t\t\t\t\t\tif(oldCoins!=null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal MOB owner=CMLib.players().getPlayerAllHosts(msg.source().getLiegeID());\n\t\t\t\t\t\t\t\tif(owner != null)\n\t\t\t\t\t\t\t\t\tdepositorName=owner.Name();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((oldCoins!=null)&&(oldCoins instanceof Coins))\n\t\t\t\t\t\t\tnewValue+=((Coins)oldCoins).getTotalValue();\n\t\t\t\t\t\tfinal Coins coins=CMLib.beanCounter().makeBestCurrency(CMLib.beanCounter().getCurrency(this),newValue);\n\t\t\t\t\t\tbankLedger(depositorName,"Deposit of "+CMLib.beanCounter().nameCurrencyShort(this,newValue)+": "+msg.source().Name());\n\t\t\t\t\t\tif(oldCoins!=null)\n\t\t\t\t\t\t\tdelDepositInventory(depositorName,oldCoins);\n\t\t\t\t\t\tif(coins!=null)\n\t\t\t\t\t\t\taddDepositInventory(depositorName,coins,null);\n\t\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("Ok, @x1 now has a balance of @x2.",CMStrings.capitalizeFirstLetter(depositorName),CMLib.beanCounter().nameCurrencyLong(this,getBalance(depositorName))),true,false);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("Ok, your new balance is @x1.",CMLib.beanCounter().nameCurrencyLong(this,getBalance(depositorName))),true,false);\n\t\t\t\t\t\trecoverPhyStats();\n\t\t\t\t\t\tif((!msg.source().isMonster())\n\t\t\t\t\t\t&&(isSold(ShopKeeper.DEAL_CLANBANKER)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Clan C=CMLib.clans().getClan(depositorName);\n\t\t\t\t\t\t\tif(C!=null)\n\t\t\t\t\t\t\t\tC.adjDeposit(msg.source(), older.getTotalValue());\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(msg.sourceMessage()!=null)\n\t\t\t\t\t\t\tmsg.setSourceMessage(CMStrings.replaceAll(msg.sourceMessage(),"<O-NAME>",msg.tool().name()));\n\t\t\t\t\t\tif(msg.targetMessage()!=null)\n\t\t\t\t\t\t\tmsg.setTargetMessage(CMStrings.replaceAll(msg.targetMessage(),"<O-NAME>",msg.tool().name()));\n\t\t\t\t\t\tif(msg.othersMessage()!=null)\n\t\t\t\t\t\t\tmsg.setOthersMessage(CMStrings.replaceAll(msg.othersMessage(),"<O-NAME>",msg.tool().name()));\n\t\t\t\t\t\t((Coins)msg.tool()).setNumberOfCoins(0); // prevents banker from accumulating wealth\n\t\t\t\t\t\tfinal double riches=CMLib.beanCounter().getTotalAbsoluteNativeValue(this);\n\t\t\t\t\t\tif(riches>0.0)\n\t\t\t\t\t\t\tCMLib.beanCounter().subtractMoney(this,riches);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tList<Item> items;\n\t\t\t\t\t\tif(msg.tool() instanceof Container)\n\t\t\t\t\t\t\titems=CMLib.utensils().deepCopyOf((Item)msg.tool());\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\titems=new XVector<Item>((Item)msg.tool().copyOf());\n\t\t\t\t\t\tfor(final Item I : items)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!I.amDestroyed())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\taddDepositInventory(depositorName,I,I.container());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("Whoops! Where\'d it go?"),true,false);\n\t\t\t\t\t\t\t\tsuper.executeMsg(myHost, msg);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("Thank you, @x1 is safe with us.",items.get(0).name()),true,false);\n\t\t\t\t\t\t((Item)msg.tool()).destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ((CMSecurity.isAllowed(msg.source(), location(), CMSecurity.SecFlag.ORDER)\n\t\t\t\t|| (CMLib.law().doesHavePriviledgesHere(msg.source(), getStartRoom()))\n\t\t\t\t|| (CMSecurity.isAllowed(msg.source(), location(), CMSecurity.SecFlag.CMDMOBS) && (isMonster()))\n\t\t\t\t|| (CMSecurity.isAllowed(msg.source(), location(), CMSecurity.SecFlag.CMDROOMS) && (isMonster()))))\n\t\t\t\t\treturn;\n\t\t\t\tsuper.executeMsg(myHost, msg);\n\t\t\t\treturn;\n\t\t\tcase CMMsg.TYP_BORROW:\n\t\t\t\tif(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))\n\t\t\t\t{\n\t\t\t\t\tfinal Item old=(Item)msg.tool();\n\t\t\t\t\tif(old instanceof Coins)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal String borrowerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,false);\n\t\t\t\t\t\tbankLedger(borrowerName,"Loan of "+old.Name()+": "+msg.source().Name());\n\t\t\t\t\t\taddItem(old);\n\t\t\t\t\t\tfinal double amt=((Coins)old).getTotalValue();\n\t\t\t\t\t\tfinal CMMsg newMsg=CMClass.getMsg(this,msg.source(),old,CMMsg.MSG_GIVE,L("<S-NAME> give(s) <O-NAME> to <T-NAMESELF>."));\n\t\t\t\t\t\tif(location().okMessage(this,newMsg))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlocation().send(this,newMsg);\n\t\t\t\t\t\t\t((Coins)old).putCoinsBack();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tCMLib.commands().postDrop(this,old,true,false,false);\n\t\t\t\t\t\tfinal double interestRate=getLoanInterest();\n\t\t\t\t\t\tint months=2;\n\t\t\t\t\t\twhile((months<(location().getArea().getTimeObj().getMonthsInYear()*10))\n\t\t\t\t\t\t\t&&(CMath.div(amt,months)>250.0)) months++;\n\t\t\t\t\t\tfinal long dueAt=System.currentTimeMillis()+(timeInterval()*months);\n\t\t\t\t\t\tCMLib.beanCounter().adjustDebt(borrowerName,bankChain(),amt,"Bank Loan",interestRate,dueAt);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_WITHDRAW:\n\t\t\t\tif(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))\n\t\t\t\t{\n\t\t\t\t\tString withdrawerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,false);\n\t\t\t\t\tfinal Item old=(Item)msg.tool();\n\t\t\t\t\tif((old instanceof Coins)&&(old.container()==null))\n\t\t\t\t\t{\n\t\t\t\t\t\tItem depositInventoryItem=findDepositInventory(withdrawerName,""+Integer.MAX_VALUE);\n\t\t\t\t\t\tif((!isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t&&(msg.source().isMarriedToLiege())\n\t\t\t\t\t\t&&((depositInventoryItem==null)\n\t\t\t\t\t\t\t||((depositInventoryItem instanceof Coins)\n\t\t\t\t\t\t\t\t&&(((Coins)depositInventoryItem).getTotalValue()<((Coins)old).getTotalValue()))))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Item item2=findDepositInventory(msg.source().getLiegeID(),""+Integer.MAX_VALUE);\n\t\t\t\t\t\t\tif((item2!=null)&&(item2 instanceof Coins)&&(((Coins)item2).getTotalValue()>=((Coins)old).getTotalValue()))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdepositInventoryItem=item2;\n\t\t\t\t\t\t\t\tfinal MOB owner=CMLib.players().getPlayerAllHosts(msg.source().getLiegeID());\n\t\t\t\t\t\t\t\tif(owner!=null)\n\t\t\t\t\t\t\t\t\twithdrawerName=owner.Name();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((depositInventoryItem instanceof Coins)\n\t\t\t\t\t\t&&(old instanceof Coins)\n\t\t\t\t\t\t&&(((Coins)depositInventoryItem).getTotalValue()>=((Coins)old).getTotalValue()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Coins coins=CMLib.beanCounter().makeBestCurrency(this,((Coins)depositInventoryItem).getTotalValue()-((Coins)old).getTotalValue());\n\t\t\t\t\t\t\tbankLedger(withdrawerName,"Withdrawl of "+CMLib.beanCounter().nameCurrencyShort(this,((Coins)old).getTotalValue())+": "+msg.source().Name());\n\t\t\t\t\t\t\tdelDepositInventory(withdrawerName,depositInventoryItem);\n\n\t\t\t\t\t\t\taddItem(old);\n\t\t\t\t\t\t\tfinal CMMsg newMsg=CMClass.getMsg(this,msg.source(),old,CMMsg.MSG_GIVE,L("<S-NAME> give(s) <O-NAME> to <T-NAMESELF>."));\n\t\t\t\t\t\t\tif(location().okMessage(this,newMsg))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlocation().send(this,newMsg);\n\t\t\t\t\t\t\t\t((Coins)old).putCoinsBack();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tCMLib.commands().postDrop(this,old,true,false,false);\n\t\t\t\t\t\t\tif((!msg.source().isMonster())\n\t\t\t\t\t\t\t&&(isSold(ShopKeeper.DEAL_CLANBANKER)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Clan C=CMLib.clans().getClan(withdrawerName);\n\t\t\t\t\t\t\t\tif(C!=null)\n\t\t\t\t\t\t\t\t\tC.adjDeposit(msg.source(), -((Coins)msg.tool()).getTotalValue());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif((coins==null)||(coins.getNumberOfCoins()<=0))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I have closed the account for @x1. Thanks for your business.",CMStrings.capitalizeFirstLetter(withdrawerName)),true,false);\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I have closed that account. Thanks for your business."),true,false);\n\t\t\t\t\t\t\t\tsuper.executeMsg(myHost, msg);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\taddDepositInventory(withdrawerName,coins,null);\n\t\t\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("Ok, @x1 now has a balance of @x2.",CMStrings.capitalizeFirstLetter(withdrawerName),CMLib.beanCounter().nameCurrencyLong(this,coins.getTotalValue())),true,false);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("Ok, your new balance is @x1.",CMLib.beanCounter().nameCurrencyLong(this,coins.getTotalValue())),true,false);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(depositInventoryItem!=null)\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("But, your balance is @x1.",CMLib.beanCounter().nameCurrencyLong(this,((Coins)depositInventoryItem).getTotalValue())),true,false);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tList<Item> deletedItems=delDepositInventory(withdrawerName,old);\n\t\t\t\t\t\tif((deletedItems.size()==0)\n\t\t\t\t\t\t&&(!isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t&&(msg.source().isMarriedToLiege()))\n\t\t\t\t\t\t\tdeletedItems = delDepositInventory(msg.source().getLiegeID(),old);\n\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("Thank you for your trust."),true,false);\n\t\t\t\t\t\tfor(final Item I : deletedItems)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif((I instanceof Coins)&&(I.container()!=null))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmob.addItem(I);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Container C=I.container();\n\t\t\t\t\t\t\t\tI.setContainer(null); // has to be plainly in the room so that, if the get fails, it will be visible.\n\t\t\t\t\t\t\t\tif(location()!=null)\n\t\t\t\t\t\t\t\t\tlocation().addItem(I,ItemPossessor.Expire.Player_Drop);\n\t\t\t\t\t\t\t\tfinal CMMsg msg2=CMClass.getMsg(mob,I,this,CMMsg.MSG_GET,null);\n\t\t\t\t\t\t\t\tif(location().okMessage(mob,msg2))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlocation().send(mob,msg2);\n\t\t\t\t\t\t\t\t\tI.setContainer(C);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\tsuper.executeMsg(myHost, msg);\n\t\t\t\treturn;\n\t\t\tcase CMMsg.TYP_VALUE:\n\t\t\tcase CMMsg.TYP_SELL:\n\t\t\tcase CMMsg.TYP_VIEW:\n\t\t\t\tsuper.executeMsg(myHost,msg);\n\t\t\t\treturn;\n\t\t\tcase CMMsg.TYP_BUY:\n\t\t\t\tsuper.executeMsg(myHost,msg);\n\t\t\t\treturn;\n\t\t\tcase CMMsg.TYP_LIST:\n\t\t\t{\n\t\t\t\tsuper.executeMsg(myHost,msg);\n\t\t\t\tif(CMLib.flags().isAliveAwakeMobileUnbound(mob,true))\n\t\t\t\t{\n\t\t\t\t\tfinal String listerName=getBankClientName(msg.source(),Clan.Function.DEPOSIT_LIST,false);\n\t\t\t\t\tList<Item> V=null;\n\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\tV=getDepositedItems(listerName);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tV=getDepositedItems(listerName);\n\t\t\t\t\t\tif(mob.isMarriedToLiege())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal List<Item> V2=getDepositedItems(mob.getLiegeID());\n\t\t\t\t\t\t\tif((V2!=null)&&(V2.size()>0))\n\t\t\t\t\t\t\t\tV.addAll(V2);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor(int v=V.size()-1;v>=0;v--)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(V.get(v) instanceof LandTitle)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal LandTitle L=(LandTitle)V.get(v);\n\t\t\t\t\t\t\tif(!L.isProperlyOwned())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Item I=(Item)L;\n\t\t\t\t\t\t\t\tdelDepositInventory(listerName,I);\n\t\t\t\t\t\t\t\tV.remove(I);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfinal int COL_LEN=CMLib.lister().fixColWidth(34.0,mob);\n\t\t\t\t\tStringBuffer str=new StringBuffer("");\n\t\t\t\t\tstr.append(L("\\n\\rAccount balance at \'@x1\'.\\n\\r",bankChain()));\n\t\t\t\t\tfinal String c="^x[Item                              ] ";\n\t\t\t\t\tstr.append(c+c+"^.^N\\n\\r");\n\t\t\t\t\tint colNum=0;\n\t\t\t\t\tboolean otherThanCoins=false;\n\t\t\t\t\tfor(int i=0;i<V.size();i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Item I=V.get(i);\n\t\t\t\t\t\tif((!(I instanceof Coins))&&(I.container()==null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\totherThanCoins=true;\n\t\t\t\t\t\t\tString col=null;\n\t\t\t\t\t\t\tcol="["+CMStrings.padRight(I.name(mob),COL_LEN)+"] ";\n\t\t\t\t\t\t\tif((++colNum)>2)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstr.append("\\n\\r");\n\t\t\t\t\t\t\t\tcolNum=1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstr.append(col);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(!otherThanCoins)\n\t\t\t\t\t\tstr=new StringBuffer("\\n\\r^N");\n\t\t\t\t\telse\n\t\t\t\t\t\tstr.append("\\n\\r\\n\\r");\n\t\t\t\t\tfinal double balance=getBalance(listerName);\n\t\t\t\t\tif(balance>0)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t\tstr.append(CMStrings.capitalizeFirstLetter(listerName)+" has a balance of ^H"+CMLib.beanCounter().nameCurrencyLong(this,balance)+"^?.");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstr.append("Your balance is ^H"+CMLib.beanCounter().nameCurrencyLong(this,balance)+"^?.");\n\t\t\t\t\t}\n\t\t\t\t\tfinal List<MoneyLibrary.DebtItem> debts=CMLib.beanCounter().getDebt(listerName,bankChain());\n\t\t\t\t\tif(debts!=null)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor(int d=0;d<debts.size();d++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MoneyLibrary.DebtItem debt=debts.get(d);\n\t\t\t\t\t\t\tfinal long debtDueAt=debt.due();\n\t\t\t\t\t\t\tfinal double intRate=debt.interest();\n\t\t\t\t\t\t\tfinal double dueAmount=debt.amt();\n\t\t\t\t\t\t\tfinal long timeRemaining=debtDueAt-System.currentTimeMillis();\n\t\t\t\t\t\t\tif(timeRemaining>0)\n\t\t\t\t\t\t\t\tstr.append(L("\\n\\r@x1 owe ^H@x2^? in debt.\\n\\rMonthly interest is @x3%.  The loan must be paid in full in @x4 months.",((isSold(ShopKeeper.DEAL_CLANBANKER))?CMStrings.capitalizeFirstLetter(listerName):L("You")),CMLib.beanCounter().nameCurrencyLong(this,dueAmount),""+(intRate*100.0),""+(timeRemaining/timeInterval())));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(coinInterest!=0.0)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal double cci=CMath.mul(Math.abs(coinInterest),100.0);\n\t\t\t\t\t\tfinal String ci=((coinInterest>0.0)?"pay ":"charge ")+cci+"% interest ";\n\t\t\t\t\t\tstr.append(L("\\n\\rThey @x1monthly on money deposited here.",ci));\n\t\t\t\t\t}\n\t\t\t\t\tif(itemInterest!=0.0)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal double cci=CMath.mul(Math.abs(itemInterest),100.0);\n\t\t\t\t\t\tfinal String ci=((itemInterest>0.0)?"pay ":"charge ")+cci+"% interest ";\n\t\t\t\t\t\tstr.append(L("\\n\\rThey @x1monthly on items deposited here.",ci));\n\t\t\t\t\t}\n\t\t\t\t\tmob.tell(str.toString()+"^T");\n\t\t\t\t\tfor(int i=0;i<V.size();i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Item I=V.get(i);\n\t\t\t\t\t\tif(I!=null)\n\t\t\t\t\t\t\tI.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(msg.sourceMinor()==CMMsg.TYP_RETIRE)\n\t\t\tdelAllDeposits(msg.source().Name());\n\t\tsuper.executeMsg(myHost,msg);\n\t}\n\n\t@Override\n\tpublic boolean okMessage(final Environmental myHost, final CMMsg msg)\n\t{\n\t\tfinal MOB mob=msg.source();\n\t\tif(msg.amITarget(this))\n\t\t{\n\t\t\tswitch(msg.targetMinor())\n\t\t\t{\n\t\t\tcase CMMsg.TYP_GIVE:\n\t\t\tcase CMMsg.TYP_DEPOSIT:\n\t\t\t\t{\n\t\t\t\t\tif(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif(msg.tool()==null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfinal String listerName=getBankClientName(msg.source(),Clan.Function.DEPOSIT,true);\n\t\t\t\t\tif(listerName==null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfinal double balance=getBalance(listerName);\n\t\t\t\t\tif(msg.tool() instanceof Coins)\n\t\t\t\t\t{\n\t\t\t\t\t\tif((Double.MAX_VALUE-balance)<=((Coins)msg.tool()).getTotalValue())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, the law prevents us from holding that much money in one account."),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!CMLib.beanCounter().isCurrencyMatch(((Coins)msg.tool()).getCurrency(),CMLib.beanCounter().getCurrency(this)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, this bank only deals in @x1.",CMLib.beanCounter().getDenominationName(CMLib.beanCounter().getCurrency(this))),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn super.okMessage(myHost, msg);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(getItemInterest()>0.5)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, I don\'t have any deposit boxes to hold items like that."),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(!(msg.tool() instanceof Item))\n\t\t\t\t\t{\n\t\t\t\t\t\tmob.tell(L("@x1 doesn\'t look interested.",mob.charStats().HeShe()));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif(CMLib.flags().isEnspelled((Item)msg.tool())\n\t\t\t\t\t|| CMLib.flags().isOnFire((Item)msg.tool())\n\t\t\t\t\t||(msg.tool() instanceof CagedAnimal))\n\t\t\t\t\t{\n\t\t\t\t\t\tmob.tell(this,msg.tool(),null,L("<S-HE-SHE> refuses to accept <T-NAME> for deposit."));\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\tMOB owner=msg.source();\r\n\t\t\t\t\tdouble balance=getBalance(withdrawerName);\r\n\t\t\t\t\tfinal double collateral=totalItemsWorth(withdrawerName);\r\n\t\t\t\t\tif(msg.tool() instanceof Coins)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tif(!((Coins)msg.tool()).getCurrency().equals(CMLib.beanCounter().getCurrency(this)))\r\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("You\'ll need a total balance of @x1 for me to hold that.",CMLib.beanCounter().nameCurrencyShort(this,minbalance)),true,false);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn super.okMessage(myHost, msg);\n\t\t\tcase CMMsg.TYP_WITHDRAW:\n\t\t\t\t{\n\t\t\t\t\tif(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tString withdrawerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,true);\n\t\t\t\t\tif(withdrawerName==null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif((msg.tool()==null)||(!(msg.tool() instanceof Item)))\n\t\t\t\t\t{\n\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("What do you want? I\'m busy!"),true,false);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif((msg.tool()!=null)&&(!msg.tool().okMessage(myHost,msg)))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tMOB owner=msg.source();\n\t\t\t\t\tdouble balance=getBalance(withdrawerName);\n\t\t\t\t\tfinal double totalItemsWorth=totalItemsWorth(withdrawerName);\n\t\t\t\t\tif(msg.tool() instanceof Coins)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(!CMLib.beanCounter().isCurrencyMatch(((Coins)msg.tool()).getCurrency(),CMLib.beanCounter().getCurrency(this)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, I can only give you @x1.",CMLib.beanCounter().getDenominationName(CMLib.beanCounter().getCurrency(this))),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif((!isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t&&(owner.isMarriedToLiege())\n\t\t\t\t\t\t&&(balance<((Coins)msg.tool()).getTotalValue()))\n\t\t\t\t\t\t{\n\t\t\t\t\tif(msg.tool() instanceof Item)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tfinal double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());\r\n\t\t\t\t\t\tif((debt>0.0)\r\n\t\t\t\t\t\t&&((collateral-((Item)msg.tool()).value())<debt))\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\tbalance=b;\n\t\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tfinal double minbalance=(collateral/MIN_ITEM_BALANCE_DIVISOR);\r\n\t\t\t\t\tif(msg.tool() instanceof Coins)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tif(((Coins)msg.tool()).getTotalValue()>balance)\r\n\t\t\t\t\t\tif((!isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t&&(msg.source().isMarriedToLiege())\n\t\t\t\t\t\t&&(findDepositInventory(msg.source().getLiegeID(),msg.tool().Name())!=null))\n\t\t\t\t\t\t\towner=CMLib.players().getPlayerAllHosts(msg.source().getLiegeID());\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("You want WHAT?"),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(msg.tool() instanceof Item)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());\n\t\t\t\t\t\tfinal double collateral=totalItemsPawningWorth(mob,withdrawerName);\n\t\t\t\t\t\tif((debt>0.0)\n\t\t\t\t\t\t&&((collateral-((Item)msg.tool()).value())<debt))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, but that item is being held as collateral against your debt at this time."),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfinal double minbalance=(totalItemsWorth/MIN_ITEM_BALANCE_DIVISOR);\n\t\t\t\t\tif(msg.tool() instanceof Coins)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(((Coins)msg.tool()).getTotalValue()>balance)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry,  @x1 has only @x2 in its account.",CMStrings.capitalizeFirstLetter(withdrawerName),CMLib.beanCounter().nameCurrencyShort(this,balance)),true,false);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, you have only @x1 in that account.",CMLib.beanCounter().nameCurrencyShort(this,balance)),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(minbalance==0)\n\t\t\t\t\t\t\treturn super.okMessage(myHost, msg);\n\t\t\t\t\t\tif(((Coins)msg.tool()).getTotalValue()>(balance-minbalance))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif((balance-minbalance)>0)\n\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, you may only withdraw @x1  at this time.",CMLib.beanCounter().nameCurrencyShort(this,balance-minbalance)),true,false);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I am holding other items in trust, so you may not withdraw funds at this time."),true,false);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn super.okMessage(myHost, msg);\n\t\t\tcase CMMsg.TYP_VALUE:\n\t\t\tcase CMMsg.TYP_SELL:\n\t\t\tcase CMMsg.TYP_VIEW:\n\t\t\t\treturn super.okMessage(myHost,msg);\n\t\t\tcase CMMsg.TYP_BUY:\n\t\t\t\treturn super.okMessage(myHost,msg);\n\t\t\tcase CMMsg.TYP_BORROW:\n\t\t\t{\n\t\t\t\tif(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))\n\t\t\t\t\treturn false;\n\t\t\t\tif(!(msg.tool() instanceof Coins))\n\t\t\t\t{\n\t\t\t\t\tCMLib.commands().postSay(this,mob,L("I\'m sorry, only MONEY can be borrowed."),true,false);\n\t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t\tfinal double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsWorth(withdrawerName);\r\n\t\t\t\tif(collateralRemaining>0)\r\n\t\t\t\t{\r\n\t\t\t\t\tfinal StringBuffer str=new StringBuffer("");\r\n\t\t\t\tfinal String withdrawerName=getBankClientName(msg.source(),Clan.Function.WITHDRAW,true);\n\t\t\t\t\t\tstr.append(CMStrings.capitalizeFirstLetter(withdrawerName)+" ");\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tstr.append("You ");\r\n\t\t\t\t\tstr.append(L("will need to deposit enough items with us as collateral.  You\'ll need items worth @x1 more to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));\r\n\t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t\t\tfinal StringBuffer str=new StringBuffer("");\n\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\tstr.append(L("@x1 does not have an account with us, I\'m afraid.",CMStrings.capitalizeFirstLetter(withdrawerName)));\n\t\t\t\t\telse\n\t\t\t\t\t\tstr.append(L("You don\'t have an account with us, I\'m afraid."));\n\t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tfinal double debt=CMLib.beanCounter().getDebtOwed(withdrawerName,bankChain());\n\t\t\t\tif(debt>0.0)\n\t\t\t\t{\n\t\t\t\t\tfinal StringBuffer str=new StringBuffer("");\n\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\tstr.append(L("@x1 already has a @x2 loan out with us.",CMStrings.capitalizeFirstLetter(withdrawerName),CMLib.beanCounter().nameCurrencyShort(this,debt)));\n\t\t\t\t\telse\n\t\t\t\t\t\tstr.append(L("You already have a @x1 loan out with us.",CMLib.beanCounter().nameCurrencyShort(this,debt)));\n\t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tfinal double collateralRemaining=((Coins)msg.tool()).getTotalValue()-totalItemsPawningWorth(mob,withdrawerName);\n\t\t\t\tif(collateralRemaining>0)\n\t\t\t\t{\n\t\t\t\t\tfinal StringBuffer str=new StringBuffer("");\n\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\tstr.append(CMStrings.capitalizeFirstLetter(withdrawerName)+" ");\n\t\t\t\t\telse\n\t\t\t\t\t\tstr.append("You ");\n\t\t\t\t\tstr.append(L("will need to deposit enough items with us as collateral.  You\'ll need items worth @x1 more to me to qualify.",CMLib.beanCounter().nameCurrencyShort(this,collateralRemaining)));\n\t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn super.okMessage(myHost, msg);\n\t\t\t}\n\t\t\tcase CMMsg.TYP_LIST:\n\t\t\t{\n\t\t\t\tif(!CMLib.coffeeShops().ignoreIfNecessary(msg.source(),getFinalIgnoreMask(),this))\n\t\t\t\t\treturn false;\n\t\t\t\tfinal String listerName=getBankClientName(msg.source(),Clan.Function.DEPOSIT_LIST,true);\n\t\t\t\tif(listerName==null)\n\t\t\t\t\treturn false;\n\t\t\t\tif((numberDeposited(listerName)==0)\n\t\t\t\t&&((isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t||(!msg.source().isMarriedToLiege())\n\t\t\t\t\t||(numberDeposited(msg.source().getLiegeID())==0)))\n\t\t\t\t{\n\t\t\t\t\tfinal StringBuffer str=new StringBuffer("");\n\t\t\t\t\tif(isSold(ShopKeeper.DEAL_CLANBANKER))\n\t\t\t\t\t\tstr.append(L("@x1 does not have an account with us, I\'m afraid.",CMStrings.capitalizeFirstLetter(listerName)));\n\t\t\t\t\telse\n\t\t\t\t\t\tstr.append(L("You don\'t have an account with us, I\'m afraid."));\n\t\t\t\t\tif(coinInterest!=0.0)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal double cci=CMath.mul(Math.abs(coinInterest),100.0);\n\t\t\t\t\t\tfinal String ci=((coinInterest>0.0)?"pay ":"charge ")+cci+"% interest ";\n\t\t\t\t\t\tstr.append(L("\\n\\rWe @x1monthly on money deposited here.",ci));\n\t\t\t\t\t}\n\t\t\t\t\tif(itemInterest!=0.0)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal double cci=CMath.mul(Math.abs(itemInterest),100.0);\n\t\t\t\t\t\tfinal String ci=((itemInterest>0.0)?"pay ":"charge ")+cci+"% interest ";\n\t\t\t\t\t\tstr.append(L("\\n\\rWe @x1monthly on items kept with us.",ci));\n\t\t\t\t\t}\n\t\t\t\t\tif(bankChain().length()>0)\n\t\t\t\t\t\tstr.append(L("\\n\\rI am a banker for @x1.",bankChain()));\n\t\t\t\t\tCMLib.commands().postSay(this,mob,str.toString()+"^T",true,false);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn super.okMessage(myHost,msg);\n\t}\n}\n', 'message': 'Loans are now based on the pawning price of the items instead of their full value.\n\ngit-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@17628 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'author_name': 'bozimmerman', 'lang': 'java'}