dsI/bin/
dsI/extra/creremote/
dsI/extra/mingw/
dsI/extra/wolfpaw/
dsI/fluffos-2.7-ds2.018/
dsI/fluffos-2.7-ds2.018/ChangeLog.old/
dsI/fluffos-2.7-ds2.018/Win32/
dsI/fluffos-2.7-ds2.018/compat/
dsI/fluffos-2.7-ds2.018/compat/simuls/
dsI/fluffos-2.7-ds2.018/testsuite/
dsI/fluffos-2.7-ds2.018/testsuite/clone/
dsI/fluffos-2.7-ds2.018/testsuite/command/
dsI/fluffos-2.7-ds2.018/testsuite/data/
dsI/fluffos-2.7-ds2.018/testsuite/etc/
dsI/fluffos-2.7-ds2.018/testsuite/include/
dsI/fluffos-2.7-ds2.018/testsuite/inherit/
dsI/fluffos-2.7-ds2.018/testsuite/inherit/master/
dsI/fluffos-2.7-ds2.018/testsuite/log/
dsI/fluffos-2.7-ds2.018/testsuite/single/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
dsI/fluffos-2.7-ds2.018/testsuite/u/
dsI/fluffos-2.7-ds2.018/tmp/
dsI/lib/cfg/
dsI/lib/cmds/common/
dsI/lib/cmds/creators/include/
dsI/lib/cmds/creators/include/SCCS/
dsI/lib/daemon/services/
dsI/lib/doc/
dsI/lib/domains/Ylsrim/
dsI/lib/domains/Ylsrim/adm/
dsI/lib/domains/Ylsrim/armour/
dsI/lib/domains/Ylsrim/broken/
dsI/lib/domains/Ylsrim/fish/
dsI/lib/domains/Ylsrim/meal/
dsI/lib/domains/Ylsrim/npc/
dsI/lib/domains/Ylsrim/virtual/
dsI/lib/domains/Ylsrim/weapon/
dsI/lib/domains/default/creator/
dsI/lib/domains/default/etc/
dsI/lib/domains/default/room/
dsI/lib/lib/comp/
dsI/lib/lib/lvs/
dsI/lib/lib/user/
dsI/lib/lib/virtual/
dsI/lib/obj/
dsI/lib/obj/include/
dsI/lib/realms/
dsI/lib/save/kills/a/
dsI/lib/save/kills/b/
dsI/lib/save/kills/f/
dsI/lib/save/kills/m/
dsI/lib/save/kills/q/
dsI/lib/save/kills/r/
dsI/lib/secure/cfg/
dsI/lib/secure/cfg/classes/
dsI/lib/secure/cfg/races/SCCS/
dsI/lib/secure/cmds/creators/include/
dsI/lib/secure/cmds/players/
dsI/lib/secure/cmds/players/include/
dsI/lib/secure/daemon/include/
dsI/lib/secure/lib/
dsI/lib/secure/lib/include/
dsI/lib/secure/lib/net/
dsI/lib/secure/lib/net/include/
dsI/lib/secure/lib/std/
dsI/lib/secure/obj/
dsI/lib/secure/obj/include/
dsI/lib/secure/save/
dsI/lib/spells/
dsI/lib/verbs/admins/include/
dsI/lib/verbs/common/
dsI/lib/verbs/common/include/
dsI/lib/verbs/creators/
dsI/lib/verbs/creators/include/
dsI/lib/verbs/players/include/SCCS/
dsI/lib/verbs/rooms/
dsI/lib/verbs/rooms/include/
dsI/lib/www/
dsI/v22.2b14/
dsI/win32/
/*    /lib/vendor.c
 *    From the Dead Souls LPC Library
 *    The standard vendor npc
 *    created by Descartes of Borg 950522
 *    Version: @(#) vendor.c 1.10@(#)
 *    Last Modified: 97/01/01
 */

#include <lib.h>
#include <armour_types.h>
#include <vendor_types.h>

inherit LIB_SENTIENT;

private static mapping Costs         = ([]);
private static string  LocalCurrency = "gold";
private static int     MaxItems      = 40;
private static int     MaxSingleItem = 4;
private static string  StorageRoom   = 0;
private static mapping Values        = ([]);
private static int     VendorType    = VT_TREASURE;

string GetLocalCurrency();
int eventBrowse(object who, string args);
mixed eventBuy(object who, object array obs);
int eventPrice(object who, string args);
mixed eventSell(object who, string what);
int eventShowItem(object who, string args);

/* ******************** vendor.c attributes ********************** */
int GetCost(object ob, object who) {
    int cost, mod, train;

    // this person has already checked on this object
    if( Costs[who] && Costs[who][ob] ) {
	return Costs[who][ob];
    }
    cost = ob->GetValue();
    mod = who->GetSkillLevel("bargaining") - GetSkillLevel("bargaining");
    if( mod < -90 ) {
	mod = -90;
    }
    if( mod > 90 ) {
	mod = 90;
    }
    cost += to_int((cost * (100 - mod))/100);
    train = cost/100;
    if( train > 100 ) {
	train = 100;
    }
    who->eventTrainSkill("bargaining", train, GetSkillLevel("bargaining"), 1);
    cost = to_int(cost * currency_rate(GetLocalCurrency()));
    if( !Costs[who] ) {
	Costs[who] = ([ ob : cost ]);
    }
    else {
	Costs[who][ob] = cost;
    }
    return cost;
}

string GetLocalCurrency() {
    return LocalCurrency;
}

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

int GetMaxItems() {
    return MaxItems;
}

int SetMaxItems(int x) {
    return (MaxItems = x);
}

int GetMaxSingleItem() {
    return MaxSingleItem;
}

int SetMaxSingleItem(int x) {
    return (MaxSingleItem = x);
}

string GetStorageRoom() {
    return StorageRoom;
}

string SetStorageRoom(string room) {
    return (StorageRoom = room);
}

int GetValue(object ob, object who) {
    int value, mod, train;

    if( Values[who] && Values[who][ob] ) {
	return Values[who][ob];
    }
    value = ob->GetValue();
    mod = who->GetSkillLevel("bargaining") - GetSkillLevel("bargaining");
    if( mod < -90 ) {
	mod = -90;
    }
    if( mod > 90 ) {
	mod = 90;
    }
    value = to_int((value * (100 - -mod))/100);
    train = value/100;
    if( train > 100 ) {
	train = 100;
    }
    who->eventTrainSkill("bargaining", train, GetSkillLevel("bargaining"), 1);
    value = to_int(value * currency_rate(GetLocalCurrency()));
    if( !Values[who] ) {
	Values[who] = ([ ob : value ]);
    }
    else {
	Values[who][ob] = value;
    }
    return value;
}

int GetVendorType() {
    return VendorType;
}

int SetVendorType(int x) {
    return (VendorType = x);
}

/* ********************* vendor.c modals ******************** */
int CanCarry(int amount) {
    return 1;
}

mixed CanBuy(object who, object *obs) {
    if( !load_object(StorageRoom) ) {
	return "There is a bug with the vendor's storage, please report it.";
    }
    return 1;
}

mixed CanSell(object who, string what) {
    if( !load_object(StorageRoom) ) {
	return "There is a bug with the vendor's storage, please report it.";
    }
    return 1;
}

/* ************************ vendor.c events ********************** */
int eventAppraise(object who, string args) {
    object ob;
    int x;

    if( !args || args == "" ) {
        eventForce("speak appraise what?");
        return 1;
    }
    if( !(ob = present(args = lower_case(args), who)) ) {
        eventForce("speak You have no such thing!");
        return 1;
    }
    if( !((int)ob->GetVendorType() & GetVendorType()) ) {
        eventForce("speak I have no use for " + ob->GetShort());
        return 1;
    }
    x = GetValue(ob, this_player());
    eventForce("speak " + who->GetName() + ", I will offer "
               "you " + x + " " + GetLocalCurrency() + " for " +
               ob->GetDefiniteShort());
    return 1;
}

mixed eventAsk(object who, string str) {
    string cmd, args;
    object array obs;
    object ob;
    mixed tmp;
    
    if( !str || str == "" ) {
	eventForce("speak what do you want from me?");
	return 1;
    }
    if( sscanf(str, "%s %s", cmd, args) != 2 ) {
	cmd = str;
	args = 0;
    }
    switch(cmd) {
	case "appraise":
	if( !args ) {
	    eventForce("speak Appraise what?");
	    return 1;
	}
	return eventAppraise(who, args);

	case "browse":
	return eventBrowse(who, args);

	case "buy":
	if( !args ) {
	    eventForce("speak What do you want me to buy?");
	    return 1;
	}
	else if( args == "all" ) {
	    obs = filter(all_inventory(who), (: (int)$1->CanSell() :));
	}
	else {
	    if( !(ob = present(args, who)) ) {
		eventForce("speak Get out of here you cheat!");
		eventForce("bump " + (string)this_player()->GetKeyName());
		return 1;
	    }
	    obs = ({ ob });
	}
	return eventBuy(who, obs);

	case "price":
        if( !args ) {
	    eventForce("speak the price for what?");
	    return 1;
	}
	return eventPrice(who, args);

	case "sell":
        if( !args ) {
	    eventForce("speak What would you like me to sell?");
	    return 1;
	}
	tmp = CanSell(who, args);
	if( tmp == 1 ) {
	    return eventSell(who, args);
	}
	else if( stringp(tmp) ) {
	    eventForce("speak " + tmp);
	    return 1;
	}
	else {
	    return 0;
	}

	case "show":
        if( !args ) {
	    eventForce("speak what would you like me to show you?");
	    return 1;
	}
	return eventShowItem(who, args);
	
	default:
	eventForce("speak I am not quite sure what you want from me");
	return 1;
    }
}
	
int eventBrowse(object who, string args) {
    object array obs;
    string array list;
    object sroom;
    int i, maxi;

    if( !args ) {
	args = "all";
    }
    if( !(sroom = load_object(StorageRoom)) ) {
        eventForce("speak I am having terrific difficulties today");
        return 1;
    }
    if( !(maxi = sizeof(obs = all_inventory(sroom))) ) {
        eventForce("speak I have nothing to sell right now.");
        return 1;
    }
    list = ({ " #  Description", "" });
    i = this_player()->GetScreen()[0];
    while( i-- ) {
	list[1] += "_";
    }
    for(i=0; i<maxi; i++) {
        int ok;
        int gat;

        ok = 0;
        gat = (int)obs[i]->GetArmourType();
        switch(args) {
            case "all": ok = 1; break;
            case "weapon": case "weapons":
              ok = (gat & A_WEAPON) && ((int)obs[i]->GetClass() > 1);
              break;
            case "armour": case "armours":
              ok = (int)obs[i]->GetProperty("armour");
              break;
            case "bag": case "bags":
              ok = (int)obs[i]->GetProperty("bag");
              break;
            case "ring": case "rings":
              ok = gat & A_RING;
              break;
            case "glove": case "gloves":
              ok = gat & (A_GLOVE | A_LONG_GLOVE);
              break;
            case "boot": case "boots":
              ok = gat & (A_BOOT | A_LONG_BOOT);
              break;
            case "sock": case "socks":
              ok = gat & (A_SOCK | A_LONG_SOCK);
              break;
            case "helm": case "helmet":
              ok = gat & A_HELMET;
              break;
            case "visor": case "visors":
              ok = gat & A_VISOR;
              break;
            case "pants":
              ok = gat & A_PANTS;
              break;
            case "shirt": case "shirts":
              ok = gat & A_SHIRT;
              break;
            case "cloak": case "cloaks":
              ok = gat & A_CLOAK;
              break;
            case "belt": case "belts":
              ok = gat & A_BELT;
              break;
            case "vest": case "vests":
              ok = gat & A_VEST;
              break;
            case "shield": case "shields":
              ok = gat & A_SHIELD;
              break;
            case "body armour": case "body armours":
              ok = gat & A_BODY_ARMOUR;
              break;
            case "blunt": case "knife": case "blade": case "projectile":
            case "blunts": case "knives": case "blades": case "projectiles":
              ok = ((string)obs[i]->GetWeaponType() == args) ||
                (pluralize((string)obs[i]->GetWeaponType()) == args);
              break;
            default:
              ok = (int)obs[i]->id(args);
              break;
        }
        if( !ok ) {
	    continue;
	}
        list += ({ sprintf("%:-3d %s", (i+1), (string)obs[i]->GetShort()) });
    }
    if( !sizeof(list) ) {
        eventForce("frown");
        eventForce("speak I have nothing like that to sell.");
        return 1;
    }
    this_player()->eventPage(list);
    return 1;
}

mixed eventBuy(object who, object array obs) {
    object array tmp;
    object sroom;
    int train;

    sroom = load_object(StorageRoom);
    if( sizeof(all_inventory(sroom)) > GetMaxItems() ) {
        eventForce("speak I am having trouble getting rid of the things I "
		   "have to sell right now.");
        return 1;
    }
    if( !sizeof(obs) ) {
        eventForce("speak you have nothing to sell!");
        return 1;
    }
    tmp = ({});
    foreach(object ob in obs) {
        int value;

	if( !ob->GetShort() ) {
	    continue;
	}
	if( !(ob->GetVendorType() & GetVendorType()) ) {
            eventForce("speak I do not buy things like " +
		       ob->GetShort() + ".");
            continue;
        }
	value = GetValue(ob, who);
	if( value < 1 ) {
            eventForce("speak " + ob->GetDefiniteShort() + " is worthless!");
            continue;
        }
	if( !ob->CanSell(who) ) {
	    eventForce("speak You cannot sell " + ob->GetDefiniteShort() +".");
	    continue;
	}
        if( sizeof(filter(all_inventory(sroom),
                          (: $1->GetShort() == $(ob)->GetShort() :)))
	    >= MaxSingleItem ) {
            eventForce("speak " + ob->GetDefiniteShort() + " is too " +
                       "common.");
            continue;
        }
        eventForce("speak " + ob->GetShort() + "! Excellent!");
        if( !ob->eventMove(sroom) ) {
            eventForce("speak I cannot seem to carry that");
            return 1;
        }
        if( who->AddCurrency(GetLocalCurrency(), value) == -1 ){
            eventForce("speak you cannot carry that much money!");
            ob->eventMove(environment());
            continue;
        }
	train = value/100;
	if( train > 100 ) {
	    train = 100;
	}
	who->eventTrainSkill("bargaining", train, GetSkillLevel("bargaining"),
			     1);
	tmp += ({ ob });
	send_messages("sell", "$agent_name $agent_verb " + ob->GetShort() +
		      " to $target_name.", who, this_object(),
		      environment(who));
    }
    if( !sizeof(tmp) ) {
	eventForce("speak I am sorry, " + who->GetName() + ", "
		   "that we could not come to a better agreement.");
    }
    else {
	map(tmp, function(object ob) {
                     if( ob->GetDestroyOnSell() ) {
			 ob->eventDestruct();
		     }
		  });
    }
    return 1;
}

int eventPrice(object who, string args) {
    object array obs;
    object ob, sroom;
    int x;

    if( !args || args == "" ) {
        eventForce("speak price what?");
        return 1;
    }
    if( !(sroom = load_object(StorageRoom)) ) {
        eventForce("speak today is not really a good day for me");
        return 0;
    }
    obs = all_inventory(sroom);
    if( x = to_int(args) ) {
        if( x < 1 || x > sizeof(obs) ) {
	    ob = 0;
	}
        else {
	    ob = obs[x-1];
	}
    }
    else {
	ob = present(args = lower_case(args), sroom);
    }
    if( !ob ) {
        eventForce("speak I have no such thing!");
        return 1;
    }
    if( !(x = GetCost(ob, this_player())) ) {
        eventForce("speak that thing has no value!");
        return 1;
    }
    eventForce("speak " + who->GetName() + ", I will take " +
               x + " " + GetLocalCurrency() + " for " +
               ob->GetDefiniteShort());
    return 1;
}

mixed eventSell(object who, string what) {
    object ob, sroom;
    int cost, train;
    
    sroom = load_object(StorageRoom);
    if( !(ob = present(what, sroom)) ) {
        eventForce("speak I have nothing like that to sell");
        return 1;
    }
    cost = GetCost(ob, who);
    if( (int)who->GetCurrency(GetLocalCurrency()) < cost ) {
        eventForce("speak go out on the streets and beg you pathetic wretch!");
        return 1;
    }
    if( !((int)ob->eventMove(this_object())) ) {
	message("error", "An error occurred moving the object, use bug -r.",
		who);
	return 1;
    }
    eventForce("speak here is " + (string)ob->GetShort() + " for " + cost +
               " " + GetLocalCurrency() + "!");
    eventForce("give " + what + " to " + (string)who->GetKeyName());
    if( environment(ob) == this_object() ) {
        eventForce("speak you cannot carry that!");
	eventForce("drop " + what);
    }
    train = cost/100;
    if( train > 100 ) {
	train = 100;
    }
    who->eventTrainSkill("bargaining", train, GetSkillLevel("bargaining"), 1);
    who->AddCurrency(GetLocalCurrency(), -cost);
    return 1;
}

int eventShowItem(object who, string args) {
    object ob, sroom;
    int x;

    if( !args || args == "" ) {
        eventForce("speak show you what?");
        return 1;
    }
    if( !(sroom = load_object(StorageRoom)) ) {
        eventForce("speak I am having troubles right now");
        return 1;
    }
    if( x = to_int(args) ) {
        object array obs;

        x--;
        obs = all_inventory(sroom);
        if( x > sizeof(obs) || x < 0 ) {
	    ob = 0;
	}
        else {
	    ob = obs[x];
	}
    }
    else {
	ob = present(args = lower_case(args), sroom);
    }
    if( !ob ) {
        eventForce("speak I have no such thing to show you");
        return 1;
    }
    who->eventPrint(GetName() + " shows you " + ob->GetDefiniteShort() + ".");
    who->eventPrint(ob->GetLong());
    return 1;
}

/* ********************* vendor.c driver applies ****************** */
mixed direct_buy_str_from_liv(string str) { 
    return CanSell(this_player(), remove_article(lower_case(str))); 
}

mixed direct_sell_liv_obj() {
    return 1;
}

mixed indirect_sell_obj_to_liv() {
    return 1;
}