/* /lib/vendor.c
* From the Nightmare IV 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;
}