ds2.9a12/bin/
ds2.9a12/extra/
ds2.9a12/extra/crat/
ds2.9a12/extra/creremote/
ds2.9a12/extra/mingw/
ds2.9a12/extra/wolfpaw/
ds2.9a12/fluffos-2.14-ds13/
ds2.9a12/fluffos-2.14-ds13/Win32/
ds2.9a12/fluffos-2.14-ds13/compat/
ds2.9a12/fluffos-2.14-ds13/compat/simuls/
ds2.9a12/fluffos-2.14-ds13/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/
ds2.9a12/fluffos-2.14-ds13/testsuite/clone/
ds2.9a12/fluffos-2.14-ds13/testsuite/command/
ds2.9a12/fluffos-2.14-ds13/testsuite/data/
ds2.9a12/fluffos-2.14-ds13/testsuite/etc/
ds2.9a12/fluffos-2.14-ds13/testsuite/include/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/
ds2.9a12/fluffos-2.14-ds13/testsuite/inherit/master/
ds2.9a12/fluffos-2.14-ds13/testsuite/log/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/compiler/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/efuns/
ds2.9a12/fluffos-2.14-ds13/testsuite/single/tests/operators/
ds2.9a12/fluffos-2.14-ds13/testsuite/u/
ds2.9a12/lib/cmds/admins/
ds2.9a12/lib/cmds/common/
ds2.9a12/lib/cmds/creators/include/
ds2.9a12/lib/daemon/services/
ds2.9a12/lib/daemon/tmp/
ds2.9a12/lib/doc/
ds2.9a12/lib/doc/bguide/
ds2.9a12/lib/doc/efun/all/
ds2.9a12/lib/doc/efun/arrays/
ds2.9a12/lib/doc/efun/buffers/
ds2.9a12/lib/doc/efun/compile/
ds2.9a12/lib/doc/efun/floats/
ds2.9a12/lib/doc/efun/functions/
ds2.9a12/lib/doc/efun/general/
ds2.9a12/lib/doc/efun/mixed/
ds2.9a12/lib/doc/efun/numbers/
ds2.9a12/lib/doc/efun/parsing/
ds2.9a12/lib/doc/hbook/
ds2.9a12/lib/doc/help/classes/
ds2.9a12/lib/doc/help/races/
ds2.9a12/lib/doc/lfun/
ds2.9a12/lib/doc/lfun/all/
ds2.9a12/lib/doc/lfun/lib/abilities/
ds2.9a12/lib/doc/lfun/lib/armor/
ds2.9a12/lib/doc/lfun/lib/bank/
ds2.9a12/lib/doc/lfun/lib/bot/
ds2.9a12/lib/doc/lfun/lib/clay/
ds2.9a12/lib/doc/lfun/lib/clean/
ds2.9a12/lib/doc/lfun/lib/clerk/
ds2.9a12/lib/doc/lfun/lib/client/
ds2.9a12/lib/doc/lfun/lib/combat/
ds2.9a12/lib/doc/lfun/lib/connect/
ds2.9a12/lib/doc/lfun/lib/container/
ds2.9a12/lib/doc/lfun/lib/corpse/
ds2.9a12/lib/doc/lfun/lib/creator/
ds2.9a12/lib/doc/lfun/lib/daemon/
ds2.9a12/lib/doc/lfun/lib/damage/
ds2.9a12/lib/doc/lfun/lib/deterioration/
ds2.9a12/lib/doc/lfun/lib/donate/
ds2.9a12/lib/doc/lfun/lib/door/
ds2.9a12/lib/doc/lfun/lib/equip/
ds2.9a12/lib/doc/lfun/lib/file/
ds2.9a12/lib/doc/lfun/lib/fish/
ds2.9a12/lib/doc/lfun/lib/fishing/
ds2.9a12/lib/doc/lfun/lib/flashlight/
ds2.9a12/lib/doc/lfun/lib/follow/
ds2.9a12/lib/doc/lfun/lib/ftp_client/
ds2.9a12/lib/doc/lfun/lib/ftp_data_connection/
ds2.9a12/lib/doc/lfun/lib/fuel/
ds2.9a12/lib/doc/lfun/lib/furnace/
ds2.9a12/lib/doc/lfun/lib/genetics/
ds2.9a12/lib/doc/lfun/lib/holder/
ds2.9a12/lib/doc/lfun/lib/id/
ds2.9a12/lib/doc/lfun/lib/interactive/
ds2.9a12/lib/doc/lfun/lib/lamp/
ds2.9a12/lib/doc/lfun/lib/leader/
ds2.9a12/lib/doc/lfun/lib/light/
ds2.9a12/lib/doc/lfun/lib/limb/
ds2.9a12/lib/doc/lfun/lib/living/
ds2.9a12/lib/doc/lfun/lib/load/
ds2.9a12/lib/doc/lfun/lib/look/
ds2.9a12/lib/doc/lfun/lib/manipulate/
ds2.9a12/lib/doc/lfun/lib/meal/
ds2.9a12/lib/doc/lfun/lib/messages/
ds2.9a12/lib/doc/lfun/lib/player/
ds2.9a12/lib/doc/lfun/lib/poison/
ds2.9a12/lib/doc/lfun/lib/position/
ds2.9a12/lib/doc/lfun/lib/post_office/
ds2.9a12/lib/doc/lfun/lib/potion/
ds2.9a12/lib/doc/lfun/lib/room/
ds2.9a12/lib/doc/lfun/lib/server/
ds2.9a12/lib/doc/lfun/lib/spell/
ds2.9a12/lib/doc/lfun/lib/torch/
ds2.9a12/lib/doc/lfun/lib/vendor/
ds2.9a12/lib/doc/lfun/lib/virt_sky/
ds2.9a12/lib/doc/lfun/lib/weapon/
ds2.9a12/lib/doc/lfun/lib/worn_storage/
ds2.9a12/lib/doc/lpc/basic/
ds2.9a12/lib/doc/lpc/concepts/
ds2.9a12/lib/doc/lpc/constructs/
ds2.9a12/lib/doc/lpc/etc/
ds2.9a12/lib/doc/lpc/intermediate/
ds2.9a12/lib/doc/lpc/types/
ds2.9a12/lib/doc/misc/
ds2.9a12/lib/doc/old/
ds2.9a12/lib/domains/
ds2.9a12/lib/domains/Praxis/adm/
ds2.9a12/lib/domains/Praxis/attic/
ds2.9a12/lib/domains/Praxis/cemetery/mon/
ds2.9a12/lib/domains/Praxis/data/
ds2.9a12/lib/domains/Praxis/death/
ds2.9a12/lib/domains/Praxis/mountains/
ds2.9a12/lib/domains/Praxis/obj/armour/
ds2.9a12/lib/domains/Praxis/obj/magic/
ds2.9a12/lib/domains/Praxis/obj/weapon/
ds2.9a12/lib/domains/Praxis/orc_valley/
ds2.9a12/lib/domains/Ylsrim/
ds2.9a12/lib/domains/Ylsrim/adm/
ds2.9a12/lib/domains/Ylsrim/armor/
ds2.9a12/lib/domains/Ylsrim/broken/
ds2.9a12/lib/domains/Ylsrim/fish/
ds2.9a12/lib/domains/Ylsrim/meal/
ds2.9a12/lib/domains/Ylsrim/npc/
ds2.9a12/lib/domains/Ylsrim/obj/
ds2.9a12/lib/domains/Ylsrim/virtual/
ds2.9a12/lib/domains/Ylsrim/weapon/
ds2.9a12/lib/domains/campus/adm/
ds2.9a12/lib/domains/campus/etc/
ds2.9a12/lib/domains/campus/meals/
ds2.9a12/lib/domains/campus/save/
ds2.9a12/lib/domains/campus/txt/ai/charles/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/
ds2.9a12/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.9a12/lib/domains/campus/txt/ai/charly/
ds2.9a12/lib/domains/campus/txt/ai/charly/bak/
ds2.9a12/lib/domains/campus/txt/jenny/
ds2.9a12/lib/domains/cave/doors/
ds2.9a12/lib/domains/cave/etc/
ds2.9a12/lib/domains/cave/meals/
ds2.9a12/lib/domains/cave/weap/
ds2.9a12/lib/domains/default/creator/
ds2.9a12/lib/domains/default/doors/
ds2.9a12/lib/domains/default/etc/
ds2.9a12/lib/domains/default/vehicles/
ds2.9a12/lib/domains/default/virtual/
ds2.9a12/lib/domains/default/weap/
ds2.9a12/lib/domains/town/txt/shame/
ds2.9a12/lib/domains/town/virtual/
ds2.9a12/lib/domains/town/virtual/bottom/
ds2.9a12/lib/domains/town/virtual/space/
ds2.9a12/lib/estates/
ds2.9a12/lib/ftp/
ds2.9a12/lib/lib/comp/
ds2.9a12/lib/lib/daemons/
ds2.9a12/lib/lib/daemons/include/
ds2.9a12/lib/lib/lvs/
ds2.9a12/lib/lib/user/
ds2.9a12/lib/lib/virtual/
ds2.9a12/lib/log/
ds2.9a12/lib/log/adm/
ds2.9a12/lib/log/archive/
ds2.9a12/lib/log/chan/
ds2.9a12/lib/log/errors/
ds2.9a12/lib/log/law/adm/
ds2.9a12/lib/log/law/email/
ds2.9a12/lib/log/law/names/
ds2.9a12/lib/log/law/sites-misc/
ds2.9a12/lib/log/law/sites-register/
ds2.9a12/lib/log/law/sites-tempban/
ds2.9a12/lib/log/law/sites-watch/
ds2.9a12/lib/log/open/
ds2.9a12/lib/log/reports/
ds2.9a12/lib/log/router/
ds2.9a12/lib/log/secure/
ds2.9a12/lib/log/watch/
ds2.9a12/lib/obj/book_source/
ds2.9a12/lib/obj/include/
ds2.9a12/lib/powers/prayers/
ds2.9a12/lib/powers/spells/
ds2.9a12/lib/realms/template/adm/
ds2.9a12/lib/realms/template/area/armor/
ds2.9a12/lib/realms/template/area/npc/
ds2.9a12/lib/realms/template/area/obj/
ds2.9a12/lib/realms/template/area/room/
ds2.9a12/lib/realms/template/area/weap/
ds2.9a12/lib/realms/template/bak/
ds2.9a12/lib/realms/template/cmds/
ds2.9a12/lib/save/kills/o/
ds2.9a12/lib/secure/cfg/classes/
ds2.9a12/lib/secure/cmds/builders/
ds2.9a12/lib/secure/cmds/creators/include/
ds2.9a12/lib/secure/cmds/players/
ds2.9a12/lib/secure/cmds/players/include/
ds2.9a12/lib/secure/daemon/imc2server/
ds2.9a12/lib/secure/daemon/include/
ds2.9a12/lib/secure/lib/
ds2.9a12/lib/secure/lib/include/
ds2.9a12/lib/secure/lib/net/include/
ds2.9a12/lib/secure/lib/std/
ds2.9a12/lib/secure/log/adm/
ds2.9a12/lib/secure/log/bak/
ds2.9a12/lib/secure/log/intermud/
ds2.9a12/lib/secure/log/network/
ds2.9a12/lib/secure/modules/
ds2.9a12/lib/secure/npc/
ds2.9a12/lib/secure/obj/include/
ds2.9a12/lib/secure/room/
ds2.9a12/lib/secure/save/
ds2.9a12/lib/secure/save/backup/
ds2.9a12/lib/secure/save/boards/
ds2.9a12/lib/secure/tmp/
ds2.9a12/lib/secure/upgrades/files/
ds2.9a12/lib/secure/verbs/creators/
ds2.9a12/lib/std/board/
ds2.9a12/lib/std/lib/
ds2.9a12/lib/tmp/
ds2.9a12/lib/verbs/admins/include/
ds2.9a12/lib/verbs/builders/
ds2.9a12/lib/verbs/common/
ds2.9a12/lib/verbs/common/include/
ds2.9a12/lib/verbs/creators/
ds2.9a12/lib/verbs/creators/include/
ds2.9a12/lib/verbs/rooms/
ds2.9a12/lib/verbs/rooms/include/
ds2.9a12/lib/www/client/
ds2.9a12/lib/www/errors/
ds2.9a12/lib/www/images/
ds2.9a12/lib/www/lpmuds/downloads_files/
ds2.9a12/lib/www/lpmuds/intermud_files/
ds2.9a12/lib/www/lpmuds/links_files/
ds2.9a12/win32/
/*   /lib/teller.c
 *   from the Dead Souls Object Library
 *   npc interface which handles banking transactions
 *   created by Blitz@Dead Souls 960105
 *   Version: @(#) teller.c 1.3@(#)
 *   Last Modified: 96/10/22
 */

#include <lib.h>
#include <daemons.h>
#include "include/teller.h"

inherit LIB_SENTIENT;
inherit LIB_MANYCOINS;

string BankName, LocalCurrency;
string *Currencies;
int LocalFee, NonLocalFee, OpenFee;
float ExchangeFee;

static void create(){
    sentient::create();
    BankName = "Town Trust";
    LocalCurrency = "silver";
    LocalFee = 1;
    NonLocalFee = 5;
    OpenFee = 5;
    Currencies = ({ "copper", "silver", "electrum", "gold", "platinum" });
    SetCommandResponses( ([
        "default" : (: cmdParse :),
      ]) );
    SetRequestResponses( ([
        "default" : (: cmdParse :),
      ]) );
}

string SetBankName(string str){ return (BankName = str); }

string SetLocalCurrency(string str){ return (LocalCurrency = str); }

int SetLocalFee(int x){ return (LocalFee = x); }

int SetNonLocalFee(int x){ return (NonLocalFee = x); }

int SetOpenFee(int x){ return (OpenFee = x); }

float SetExchangeFee(float x){ return (ExchangeFee = x); }

mixed SetCurrencies(mixed var){
    if( arrayp(var) ){
        if( member_array(LocalCurrency, var) == -1 )
            var += ({ LocalCurrency });
        return (Currencies = var);
    }
    else error("Bad argument 1 to SetCurrencies()");
}

int GetLocalFee(){ return LocalFee; }

int GetNonLocalFee(){ return NonLocalFee; }

int GetExchangeFee(){ return ExchangeFee; }

int GetOpenFee(){ return OpenFee; }

mixed GetCurrencies(){ return copy(Currencies); }

string GetBankName(){ return BankName; }

string GetLocalCurrency(){ return LocalCurrency; }

mixed CanBank(object who){
    if( !(int)who->GetAccountInfo( GetBankName() ) )
        return "You must create an account with "+GetBankName()+" first.";
    return 1;
}

int AddSurcharge(object who, string currency, int amount){
    int charge;
    string type;

    if( (string)who->GetTown() == GetTown() ){
        type = "standard";
        charge = GetLocalFee();
    } else {
        type = "non-residential";
        charge = GetNonLocalFee();
    }
    if( !charge ) return amount;
    if( amount > charge ){
        amount -= charge;
        who->eventPrint(sprintf("The bank retains a %s "
            "surcharge of %d %s.", type, charge, currency));
        return amount;
    }
    else {
        who->eventPrint(sprintf("You are unable to afford the "
            "%s surcharge of %d %s.", type, charge, currency));
        return 0;
    }
    return amount;
}

int eventBalance(object who){
    string str, ret, *tmp;
    mapping mp;
    float val;
    int total;

    mp = (mapping)who->GetAccountInfo( GetBankName() );
    if( !mp ) return 0;
    environment()->eventPrint( (string)who->GetName() + " requests "
      "current balance.", ({ who }) );
    ret = "Your account with "+GetBankName()+" was "
    "opened "+ctime(mp["open"])+".\n";
    ret += "This location's default currency is "+GetLocalCurrency()+".\n\n";
    tmp = filter(keys(mp), (: member_array($1, Currencies) > -1 :));
    total = 0;
    if( !sizeof(tmp) )
        ret += "You have made no deposits.\n";
    else foreach(str in tmp){
            if( mp[str] < 1 ) continue;
            ret += sprintf("%-20s : %d\n", str+"", mp[str]);
            if( str == GetLocalCurrency() ) total += mp[str];
            else if( mp[str] ){
                if( currency_rate(str) )
                    val = query_value(mp[str],str,GetLocalCurrency()); 
                else val = 0;
                if(val) total += val;
            }
        }
    ret += sprintf("%-20s ----------\n%-22s %d",
      "", "Total in "+GetLocalCurrency(), total);
    if( mp["last time"] )
        ret += sprintf("\n\nYour last transaction: %s at %s.",
          mp["last trans"], ctime(mp["last time"]) );
    who->eventPage(explode(ret, "\n"), "info");
    return 1;
}

int eventDeposit(object who, string currency, int amount){
    int i;
    if( amount < 1 ){
        eventForce("speak " + (string)who->GetName() + ", "
          "That transaction is unacceptable.");
        return 1;
    }
    if( !currency ) currency = GetLocalCurrency();
    if( !(i = (int)who->GetCurrency(currency)) ){
        eventForce("speak You are not carrying any "+currency+".");
        return 1;
    }
    if( amount > i ){
        eventForce("speak You are not carrying that much "+ currency +".");
        return 1;
    }
    who->eventPrint(sprintf("You deposit %d %s into your "
        "account.", amount, currency));
    environment()->eventPrint((string)who->GetName() + " makes "
      "a deposit.", ({ who }) );
    who->AddCurrency(currency, -amount);
    who->AddBank(GetBankName(), currency, amount);
    return 1;
}

int eventWithdraw(object who, string currency, int amount){
    int i, x, charge;

    x = amount;
    if( amount < 1 ){
        eventForce("speak Withdrawing a negative amount is not a prudent "
          "idea, "+ (string)who->GetName() +".");
        return 1;
    }
    if( !currency ) currency = GetLocalCurrency();
    if( !(i = (int)who->GetBank(GetBankName(), currency)) ){
        eventForce("speak You have no "+currency+" in your account.");
        return 1;
    }
    if( amount > i ){
        eventForce("speak You do not have that much "+currency+" in your "
          "account.");
        return 1;
    }
    if( !(amount = AddSurcharge(who, currency, amount)) ) return 1;
    charge = x - amount;
    if( (int)who->AddCurrency(currency, x) < 0 ){
        eventForce("speak You are unable to carry that "
          "much "+currency+"!");
        who->eventPrint("The bank credits your account with the fee.");
        return 1;
    }
    who->AddCurrency(currency, -charge);
    who->AddBank(GetBankName(), currency, -x);
    who->eventPrint(sprintf("You withdraw %d %s from your account.",
        amount, currency));
    environment()->eventPrint(sprintf("%s withdraws some %s.",
        (string)who->GetName(), currency), ({ who }));
    return 1;
}

int eventExchange(object who, int amount, string str1, string str2){
    int i, x, charge;
    float val;

    if( amount < 1 ){
        eventForce("speak " + (string)who->GetName() + ", that "
          "transaction cannot be completed.");
        return 1;
    }
    if( amount > (int)who->GetCurrency(str1) ){
        eventForce("speak You do not have enough of that currency to exchange.");
        return 1;
    }
    if( str1 == str2 ){
        eventForce("speak That would be pointless.");
        return 1;
    }
    if( member_array(str1, GetCurrencies()) == -1 ){
        eventForce("speak You cannot exchange that currency here.");
        return 1;
    }
    if( member_array(str2, GetCurrencies()) == -1 ){
        eventForce("speak You cannot exchange that currency here.");
        return 1;
    }
    val = query_base_value(str1,amount);
    x = to_int( (amount * 0.01) + amount );
    i = val / currency_rate(str2);
    if( GetExchangeFee() )
        charge = to_int(i / (100 / GetExchangeFee()));
    else charge = 0;
    if( charge ) i -= charge;
    if( i < 1 ){
        eventForce("speak That isn't even worth one " + str2 + "!");
        return 1;
    }
    if( (int)who->AddCurrency(str2, i) < 0 ){
        eventForce("speak You cannot carry that much "+str2+", " +
          (string)who->GetName()+".");
        return 1;
    }
    who->AddCurrency(str1, -amount);
    who->eventPrint(sprintf("You exchange %d %s for %d %s.",
        amount, str1, i, str2));
    if( charge )
        who->eventPrint(sprintf("You were charged a fee of %d %s.",      
            charge, str2) );
    environment()->eventPrint((string)who->GetName()+" exchanges some "+
      str1+" for "+str2+".", who);
    return 1;
}

int eventOpenAccount(object who){
    if( who->GetAccountInfo( GetBankName() ) ){
        eventForce("speak You already have an account with "+GetBankName()+", " +
          (string)who->GetName()+"!");
        return 1;
    }
    if( (int)who->GetCurrency( GetLocalCurrency() ) < OpenFee ){
        eventForce(" speak "+ sprintf("You must have at least %d %s to open "
            "an account at this branch of %s, %s.", GetOpenFee(),
            GetLocalCurrency(), GetBankName(), (string)who->GetName()));
        return 1;
    }
    if( OpenFee < 1 ) return 0;
    who->AddCurrency(GetLocalCurrency(), -OpenFee);
    who->AddBank(GetBankName(), GetLocalCurrency(), OpenFee);
    who->eventPrint(sprintf("You deposit %d %s and open an account "
        "with %s.", OpenFee, GetLocalCurrency(), GetBankName()) );
    eventBalance(who);
    environment()->eventPrint((string)who->GetName() + " opens an "
      "account.", who);
    eventForce("smile "+(string)who->GetKeyName());
    return 1;
}

int cmdParse(object who, string cmd, string str){
    int x;
    string s1, s2, honorific;
    mixed err;

    if( cmd != "account" && stringp(err = CanBank(who)) ){
        who->eventPrint(err);
        return 1;
    }
    switch(cmd){
    case "balance" :
        return eventBalance(who);
        break;
    case "deposit" : 
        if( !str ){
            eventForce("speak How much of what?");
            return 1;
        }
        if(str == "all"){
            if(!sizeof(this_player()->GetCurrencies())){
                who->eventPrint("You have no money to deposit.");
                return 1;
            }
            foreach(string dinero in this_player()->GetCurrencies()){
                if(this_player()->GetCurrency(dinero) > 0)
                    eventDeposit(who, dinero, this_player()->GetCurrency(dinero));
            }
            return 1;
        }
        sscanf(str, "%d %s", x, s1);
        if( member_array(s1, Currencies) < 0 ){
            who->eventPrint("That's not a valid currency.");
            return 1;
        }
        return eventDeposit(who, s1, x);
        break;
    case "withdraw" :
        if( !str ){
            eventForce("speak How much of what?");
            return 1;
        }
        if(str == "all"){
            if(this_player()->GetGender() == "female") honorific = "ma'am";
            else honorific = "sir";
            eventForce("speak I'm sorry, "+honorific+", but withdrawals must be specified explicitly in terms of currency type and amount.");
            return 1;
        }
        sscanf(str, "%d %s", x, s1);
        if( member_array(s1, Currencies) < 0 ){
            if(!s1) who->eventPrint("Please specify a currency.");
            else who->eventPrint(s1 + " is not supported here!");
            return 1;
        }
        return eventWithdraw(who, s1, x);
        break;
    case "exchange" :
        if( !str ){
            eventForce("speak Exchange what for what?");
            return 1;
        }
        sscanf(str, "%d %s for %s", x, s1, s2);
        return eventExchange(who, x, s1, s2);
        break;
    case "account" :
        return eventOpenAccount(who);
        break;
    default:
        eventForce("speak " + (string)who->GetName() + ", I do not "
          "understand what you want.");
        eventForce("whisper to " + (string)who->GetKeyName() + " Try "
          "\"help banking\" if you are confused.");

    }
    return 1;
}