/* ....[@@@..[@@@..............[@.................. MUD++ is a written from ....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and ....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++. ....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing ....[@......[@..[@@@@@..[@@@@@.................. development project. All ................................................ contributions are welcome. ....Copyright(C).1995.Melvin.Smith.............. Enjoy. ------------------------------------------------------------------------------ Melvin Smith (aka Fusion) msmith@hom.net MUD++ development mailing list mudpp@van.ml.org ------------------------------------------------------------------------------ shop.cc */ #include "config.h" #include "string.h" #include "llist.h" #include "object.h" #include "shop.h" #include "global.h" LList<ShopKeeper> shops; int ShopKeeper::readFrom_shopblock( StaticInput & in ) { char buf[BUF]; String str; ShopTrade * st; Object * obj; in.getword( buf ); if( strcmp( buf, "SHOP" ) ) { Cout << "shopkeeper " << getShort() << " has no shop data.\n"; return 0; } // Rewrite to allow ommision of certain parameters // I'm getting lazy! -Fusion in.getword( buf ); // '{' in.getword( buf ); shop = in.getword( buf ); // room index of shop in.getword( buf ); warehouse = in.getword( buf ); // room index of warehouse in.getword( buf ); shop_open = in.getnum(); in.getword( buf ); shop_close = in.getnum(); while( *in.getword( buf ) != '}' ) { if ( !strcmp( buf, "Trade" ) ) { in.getword(buf); // { st = new ShopTrade( lookupObjType(in.getword(buf)), in.getnum(),in.getnum(), in.getnum(),in.getnum() ); tradeList.reset(); tradeList.add(st); in.getword(buf); // } } else if ( !strcmp( buf, "Owners" ) ) { owners = in.getstring(buf); } else if ( !strcmp( buf, "O" ) ) { obj = Object::createObject(lookupObjType(in.getword(buf) )); obj->readFrom(in); addObjInv(obj); } else in.error("Unsupported data in SHOP block"); } return 1; } int ShopKeeper::readFrom( StaticInput &in ) { char buf[ BUF ]; if( *in.getword( buf ) != '{' ) in.error("NPC::readFrom() - expected '{'" ); readFrom_mainblock(in); readFrom_shopblock(in); if ( !readFrom_optionalblock(in) ) in.error("NPC::readFrom() - expected '}'" ); return 0; } void ShopKeeper::writeTo_shopblock( Output & outf ) const { outf << "SHOP\n{" << endl; outf << "room " << shop << endl; outf << "warehouse " << warehouse << endl; outf << "open " << shop_open << endl; outf << "close " << shop_close << endl; // outf << "buy " << buy_profit << endl; // outf << "sell " << sell_profit << endl; ShopTrade * st; Object * obj; // Write trade types if ( (bool)owners ) { outf << "Owners " << owners << "~" <<endl; } for_each(tradeList, st) { outf << "Trade{ " << lookupObjTypeName(st->getType()) << " " << st->getBuyProfit() << " " << st->getSellProfit() << " " << st->getMaxIdentical() << " " << st->getMaxType() << " }\n"; } for_each(inv, obj ) { outf << "O "; outf << obj->typeName() << endl; obj->writeTo(outf); outf << endl; } outf << '}' << endl; } int ShopKeeper::writeTo( Output & outf ) const { outf << '{' << endl; writeTo_mainblock(outf); writeTo_shopblock(outf); writeTo_optionalblock(outf); outf << '}' << endl; return 1; } bool ShopKeeper::isTrading(int type ) { ShopTrade * st; for_each(tradeList, st) if ( st->getType() == type ) return true; return false; } // How much he give for object int ShopKeeper::buyValue(Object * obj) { ShopTrade * st; int cost; Object * objMatch; int matchCount; int typeMatchCount; for_each(tradeList, st ) { if ( obj->isType(st->getType()) ) { cost = (obj->getCost() * st->getBuyProfit()) / 100; // Little fuzzy here, just comparing short desc // Since MUD++ doesn't use index/prototype pointers we don't match // objects exactly so there can be similar or identical objects // with different values or stats. The Implementor must handle // this and that's the way I like it. Would be nice to implement // a little supply/demand code but I'll save that for later. --Fusion matchCount = 0; typeMatchCount = 0; for_each( inv, objMatch ) { if( objMatch->getShort() == obj->getShort() ) matchCount++; // if ( objMatch->getType() == obj->getType() ) // typeMatchCount++; } if( matchCount && (matchCount > st->getMaxIdentical() ) ) { return SHOPKEEPER_HAS_IDENTICAL; } if( typeMatchCount && (typeMatchCount > st->getMaxType() ) ) { return SHOPKEEPER_HAS_TYPE; } // If keeper has 1 or more lower the offered value if( matchCount ) cost /= ( matchCount + 1 ); return cost; } } return SHOPKEEPER_NOT_TRADING; } // how much he demands for object int ShopKeeper::sellValue(Object * obj) { ShopTrade * st; for_each(tradeList, st ) { if ( obj->isType(st->getType()) ) { return ( (obj->getCost() * st->getSellProfit()) /100 ); } } return SHOPKEEPER_NOT_TRADING; } bool ShopKeeper::isOwnedBy( Char * person) { if ( strstr(owners.chars(), person->getName().chars() ) ) return true; return false; } void ShopKeeper::addOwner( String & nomine ) { if ( strstr(owners.chars(), nomine.chars() ) ) return; owners << " " << nomine; } void ShopKeeper::removeOwner( String & nomine ) { String arg; String new_owners; owners.startArgs(); while ( (bool)(arg = owners.getArg() ) ) { if ( arg != nomine ) new_owners << arg << " "; } }