Player Merchants

Get Help on scripting in POL with configurations, config setups, script trouble shooting, etc.
Post Reply
gundamwing84
Grandmaster Poster
Posts: 178
Joined: Tue Sep 08, 2009 1:57 am

Player Merchants

Post by gundamwing84 »

heya guys!

im having more trouble hahaha.

i seem to have this player merchants script that was in the scriptbase, but when i go to create the player merchant, it has an error saying

Code: Select all

"error text" 's Merchant
ill put the script up for you to take a look if your interested, i will also make this script public if fixed.

Code: Select all

use os;
use uo;
use npc;
use util;
use cfgfile;

include "include/client";
include "include/objtype";
include "include/eventid";
include "include/utility";
include "include/yesno";
include "include/myutil";
include "../pkg/npcs/npc_util";
include "../pkg/npcs/npcinfo";
include "../pkg/items/housing/house";
include "../pkg/world/townstones/townstone";
include "../pkg/world/gumps/customgumps";

var storage, inv_fs, inv_pb;
var me := Self();
var mymasterserial := CINT (GetObjProperty (me, "master"));
var mymasteracctname := GetObjProperty (me, "mymasteracctname");
var mymastername := getobjproperty (me, "mn");
var cont := getobjproperty (me, "cont");
var mymaster := cint(getobjproperty (me, "master"));

program merchant ()
	if (!me.backpack)
		DoMerchantOnCreationSetup ();
	endif

	
	RevokePrivilege (me, "invul");
	me.graphic := 400 + me.gender;
	me.hidden := 0;
	if (getobjproperty (me, "frozen"))
		me.frozen := 1;
	endif

	if (mymaster)
		var acctname := GetObjProperty (me, "acctname");
		storage := FindStorageArea( "Vendor Storage" );
		if (!storage)
			storage := CreateStorageArea( "Vendor Storage" );
			if (!storage)
				say("No storage area!");
				exit;
			endif
		endif
		inv_pb := find_or_create_item (storage, acctname + " PB", 0xE7C);
		inv_fs := find_or_create_item (storage, acctname + " 1C", 0xE7C);
		if (!inv_fs or !inv_pb)
			exit;
		endif
		LogMyStuff();
	endif

	setobjproperty (me, "serial", me.serial);
	EnableEvents (EVID_ITEM_GIVEN + EVID_MERCHANT_SOLD + EVID_DAMAGED + EVID_ENGAGED);
	EnableEvents (EVID_SPEECH, 1);
	LogMyStuff ();

	var ev;
	while (me)
		ev := os::wait_for_event (600);
		if (ev)
			case (ev.type)
				EVID_DAMAGED:
				EVID_ENGAGED:
					me.hidden := 1;
					var hidetime := ReadGameClock ();
					repeat
						ev := os::wait_for_event (120);
						if (!me.hidden)
							me.hidden := 1;
						endif
					until (hidetime + 120 < ReadGameClock());
					me.hidden := 0;
				EVID_SPEECH:
					ProcessSpeech (ev);
				EVID_MERCHANT_SOLD:
					if (ev.source)
						if (ev.amount)
							TurnToward (ev.source);
							PlaySoundEffect (me, 0x38);
							PrintTextAbovePrivate (me, "The total of your purchase is " + ev.amount + ".", ev.source);
							TakeSale (ev, ev.amount, ev.source.serial);
						else
							TurnToward (ev.source);
							PrintTextAbovePrivate (me, "I'm sorry we couldn't do business.  Maybe next time.", ev.source);
						endif
					endif
				EVID_ITEM_GIVEN:
					if (ev.source.serial == mymaster)
						StockItem (ev.item, ev.source);
					else
						buyitem(ev.source, ev.item);
					endif
			endcase  
		endif
	endwhile
endprogram




///////////////////
//  called when the merchant is first created
///////////////////

function DoMerchantOnCreationSetup ()
	sleep (1);
	me.graphic := 400 + me.gender;
	if ( me.name ["<random>"] )
		me.name := RandomName (me) + ", " + mymastername + "'s Merchant";
	endif

	if (!me.backpack)
		var newbackpack := CreateItemAtLocation (4550, 3687  , 0, UOBJ_BACKPACK, 1);
		EquipItem (me, newbackpack);
	endif

	var parms := {};
	parms[1]:= me;
	parms[2]:= "rich";
	say ("Ooh, I better get dressed!");
	run_script_to_completion ("::/misc/dressme", parms);
	foreach item in ListEquippedItems (me)
		SetObjProperty (item, "mine", 1);
	endforeach
endfunction



///////////////////
//  when someone says something in range of the merchant, this function takes care of it
///////////////////

function ProcessSpeech (byref ev);
	if (ev.text["buy"]) 
		TurnToward( ev.source );
		if (!mymaster)
			Say("I am currently unemployed.  Want to hire me?");
		elseif ( TownCheck( ev.source ) )
			eraseobjproperty (ev.source, "#vendoracctname");
			eraseobjproperty (ev.source, "#vendormerchantname");
			var stuffforsale := EnumerateItemsInContainer (inv_fs);
			if (stuffforsale.size())
				SendBuyWindow (ev.source, inv_fs, self(), inv_pb);
			else
				Say ("I'm sorry, but I have nothing for sale.");
			endif
		endif

	elseif (ev.text["trade"])
		TurnToward( ev.source );
		if (!mymaster)
			Say("I am currently unemployed.  Want to hire me?");
		elseif ( TownCheck( ev.source ) )
			GlobalTrade( ev.source );
		endif
	elseif (ev.text["purchase"])
			if (ev.source.serial == mymaster)
				TurnToward( ev.source );				
				addthingstobuy(ev.source);
			endif
	elseif (ev.text["release"])
		TurnToward( ev.source );
					if (ev.source.serial == mymaster)
						ReleaseMe (ev.source);
						PrintTextAbovePrivate (me, "Ok I'm gone!......I guess.....hmm.....we have a bug sir!", ev.source);
					else
						Say("I don't even work for you.");
					endif

	elseif (ev.text["sell"])
		TurnToward (ev.source);
		SpoutBuyList (ev.source);

	elseif (ev.text["contact"])
		TurnToward (ev.source);
		if (ev.source.serial == mymaster)
			SetNewContactInformation (ev.source);
		elseif (cont)
			say ("You may contact my employer: " + cont);
		else
			Say ("I wish I could help you, but my mymaster hasn't told me how to reach him.");
		endif

	elseif (ev.text["collect"] and (ev.source.serial == mymaster))
		TurnToward (ev.source);
		CashOut (ev.source);

	elseif (ev.text["status"] and (ev.source.serial == mymaster))
		AddToAccountMerchants (mymaster);
		TurnToward (ev.source);
		StatusCheck (ev.source);

	elseif (ev.text["wear"] and (ev.source.serial == mymaster))
		TurnToward (ev.source);
		say ("What shall I wear?");
		var this := target (ev.source);
		wear_item (this, ev.source);

	elseif (ev.text["strip"] and (ev.source.serial == mymaster))
		TurnToward( ev.source );
		say ("Ooh, I think I feel a draft!");
		strip_items (ev.source);

	elseif (ev.text["undress"] and (ev.source.serial == mymaster))
		TurnToward (ev.source);
		say ("This is so humiliating.");
		undress_items(ev.source);

	elseif (ev.text["follow"] and (ev.source.serial == mymaster))
		var myfullname := Lower (me.name);
		var myname := myfullname [1, find (myfullname, ",", 2)];
		myname [","] := "";
		var evtext := Lower (ev.text);

		if (myname and evtext [myname])
			say ("Lead the way!");
			Follow (ev.source);
		else
			Say ("If you're talking to me, say " + myname + " follow me.");
		endif
	elseif (ev.text["log"] and (ev.source.serial == mymaster))
		TurnToward (ev.source);
		ViewMessageLog (ev.source);
	elseif ((ev.text["stock"]) and (ev.source.serial == mymaster))
		TurnToward (ev.source);
		say ("Stock what?");
		StockLotsOfItems (ev.source);
	elseif (ev.text["help"])
		TurnToward (ev.source);
		say ("I will obey the following orders:");
		sleep(1);
		say ("release, buy, sell, contact, collect,");
		sleep(2);
		say ("wear, undress, strip, follow, stop, status, log and purchase");
	elseif (ev.text["sort"])
		if (ev.source.acctname == mymasteracctname)
			var myfullname := Lower (me.name);
			var myname := myfullname [1, find (myfullname, ",", 2)];
			myname [","] := "";
			var evtext := Lower (ev.text);
			if (myname and evtext[myname])
				var parms := Array {};
				parms [1] := me;
				parms[2] := ev.source;
				start_script (":merchants:playermerchant_sort", parms);
			else
				Say ("If you're talking to me, say " + myname + " sort");
			endif
		endif
endif

endfunction


function StockLotsOfItems( you )

	var stockwhat := Target( you );
	if (!stockwhat or !InInventory(you.backpack, stockwhat))
		return;
	endif
	if (Isfancyore( stockwhat))
		
			Say ("You cannot use the stock option  for Fancy Ores");
			return ;
	endif
		

	if (IsStackableWithOtherItems (stockwhat) )
		Say ("I'll just sell those at the same price as the others.");
		foreach item in ListLikeItems (you, stockwhat);
			if (CreateItemInInventory (inv_fs, item.objtype, item.amount))
				DestroyItem (item);
			endif
		endforeach
		return;
	endif

	var cost := Cint(SendTextEntryGump( you, "How much shall I charge for this item? ",
				TE_CANCEL_ENABLE, TE_STYLE_NORMAL));
	if ( cost > 0 )
		stockwhat.sellprice := cint(cost);
	else
		say("Well, just keep it, then");
		return;
	endif

	foreach item in (ListLikeItems (you, stockwhat))
		if (!item.movable)
			item.movable := 1;
		endif
		moveitemtocontainer (item, inv_fs);
		item.sellprice := stockwhat.sellprice;
	endforeach

	say( "I will sell " + stockwhat.desc + " for " + stockwhat.sellprice);

endfunction

function ListLikeItems (who, stockwhat)
	var items := { };
	foreach item in EnumerateItemsInContainer (who.backpack)
		if (item.objtype == stockwhat.objtype and item.color == stockwhat.color)
			if (( item.name == stockwhat.name ) or (!stockwhat.name and !item.name) )
				if (IsContainer (item))
					var stuff := ListRootItemsInContainer (item);
					if (!stuff.size())
						items.append (item);
					endif
				elseif (item.container.objtype != UOBJ_SPELLBOOK)
					items.append( item );
				endif
			endif
		endif
	endforeach

	return items;
endfunction


///////////////////
//  npc runs along following his mymaster until told to stop
///////////////////

function follow (byref mmymaster)
	var d := distance (mmymaster, me);
	me.run_speed := 250;

	var ev;
	while (mmymaster)
		d:= distance (mmymaster, me);
		if (d > 20)
			PlayStationaryEffect (me.x, me.y, me.z, FX_SMOKE, speed:=0xA, loop:=0xA);
			MoveObjectToLocation (me, mmymaster.x, mmymaster.y, mmymaster.z);
			PlayStationaryEffect (me.x, me.y, me.z, FX_SMOKE, speed:=0xA, loop:=0xA);
			PlaySoundEffect (mmymaster, SFX_SPELL_TELEPORT);
		elseif (d > 1)
			RunToward (mmymaster);
		else
			sleep (1);
		endif

		ev := wait_for_event(0);
		if (ev)
			if (ev.type == EVID_SPEECH)
				if ((ev.source == mmymaster) and (ev.text["stop"]))
					TurnToward (ev.source);
					say ("Ok, I'll just stand right here.");
					return;
				else
					say("I am following you!");
				endif
					
				else
					say ("I am following you!");
				
			endif
		endif
	endwhile

endfunction




///////////////////
//  called when the vendor's owner gives them another item to sell
///////////////////

function stockitem (byref item, byref seller)
	if (item.objtype == UOBJ_GOLD_COIN)
		TakeGold (item);
		return;
	endif
//// 8/27 change to help fancy ore issue - Ack
	if (Isfancyore( item))
		if (!MoveItemToContainer (item, inv_fs))
			Say ("*My pack is full!*");
			return 0;
			endif
///// End of change
	elseif (IsStackableWithOtherItems (item) )
		Say ("I'll just sell this at the same price as the others.");
		CreateItemInInventory (inv_fs, item.objtype, item.amount);
		DestroyItem (item);
		return;
	endif
	
	if (GetObjProperty (item, "ownerserial") )
		Say ("That item has an owners mark!  Should I sell it anyway?");
		if (!YesNo (seller, "Sell anyway?"))
			Say ("Ok, never mind then.");
		MoveItemToContainer (item, seller.backpack);
			return;
		endif
	endif

	if (item.isa (POLCLASS_CONTAINER))
		if (item.objtype != UOBJ_SPELLBOOK and item.objtype != UOBJ_TRASHBARREL and item.objtype != UOBJ_POTION_KEG)
			var tname := SendTextEntryGump (seller, "How shall I advertise this item?" ,
					TE_CANCEL_ENABLE, TE_STYLE_NORMAL, 60, "(Blank to keep current name)");
			if (tname)
				item.name := tname;
			endif
		endif
	endif
                   
	var cost := CINT (SendTextEntryGump (seller, "How much shall I charge for this item?", 
				TE_CANCEL_ENABLE, TE_STYLE_NORMAL));
	if (cost and cost > 0)
		item.sellprice := cost;
	else
		say ("Well, just keep it, then");
		MoveItemToContainer (item, seller.backpack);
		return;
	endif
	
	if (!item.movable)
		item.movable := 1;
	endif

	MoveItemToContainer (item, inv_fs);
	say ("I will sell " + item.desc + " for " + item.sellprice);
	SetObjProperty (me, "#merchant_sort_inv_change", 1);
endfunction

///////////
///// Added to help the custom ore issue
//////////

function Isfancyore( item )
	if (item.objtype >= 0x8000 and item.objtype <=  0x8031)
		return 1;
	else
		return 0;
	endif
endfunction


///////////////////
//  determines if the item passed is one that can be stacked with existing items
///////////////////

function IsStackableWithOtherItems (byref item)
	var old_item := FindObjtypeInContainer (inv_fs, item.objtype);
	if (!old_item)
		return 0;
	endif

	if (item.amount > 1 or old_item.amount > 1)
		return old_item;
	endif

	if (IsStackableItem (item))
		return old_item;
	endif

	return 0;
endfunction




///////////////////
//  Gives all the gold we're holding, plus any items we've bought to our mymaster
///////////////////

function CashOut (mmymaster)
	var mygold := CINT (getobjproperty (me, "g"));
	if (mygold and mygold > 0)
		var payamt := mygold;
		while (payamt > 60000)
			if (!CreateItemInContainer (mmymaster.backpack, UOBJ_GOLD_COIN, 60000))
				PrintTextAbovePrivate (me, "Your backpack is full!", mmymaster);
				SetObjProperty (me, "g", payamt);
				return 0;
			endif
			payamt := payamt - 60000;
		endwhile;
		if (!CreateItemInContainer (mmymaster.backpack, UOBJ_GOLD_COIN, payamt))
			PrintTextAbovePrivate (me, "Your backpack is full!", mmymaster);
			SetObjProperty (me, "g", payamt);
			return 0;
		endif
		PlaySoundEffect (me, 0x38);
		PrintTextAbovePrivate (me, "Here is your " + mygold + " gold", mmymaster);
		SetObjProperty (me, "g", 0);
	else
		PrintTextAbovePrivate (me, "I'm not holding any gold for you.", mmymaster);
	endif

	foreach thingie in ListRootItemsInContainer (me.backpack)
		if (!MoveItemToContainer (thingie, mmymaster.backpack))
			Say ("Your backpack is full!");
			return 0;
		endif
	endforeach
	return 1;
endfunction




///////////////////
//  Tell the mymaster how much gold we have and any items we've bought
///////////////////

function StatusCheck (mmymaster)
	foreach thingie in ListRootItemsInContainer (me.backpack)
        	PrintTextAbovePrivate (me, "I have " + thingie.desc, mmymaster);
		sleepms (500);
	endforeach
	var mygold := CINT (getobjproperty(me, "g"));
	if (!mygold)
		PrintTextAbovePrivate (me, "I don't have any gold.", mmymaster);
	else
		PrintTextAbovePrivate (me, "I currently hold " + mygold + " gold for you.", mmymaster);
	endif
endfunction




///////////////////
//  Allows the merchant's owner to set new contact information
///////////////////

function SetNewContactInformation (byref who)
	var oldcont := cont;
	if (!oldcont)
		oldcont := "Not set";
	endif
	var newcont := SendTextEntryGump (who, "How shall I tell people to contact you? ",
			TE_CANCEL_DISABLE, TE_STYLE_NORMAL, 50, "(Currently: "+oldcont);
	if (!newcont)
		Say ("Ok, never mind then.");
		return;
	endif

	SetObjProperty (me, "cont", newcont);
	cont := newcont;
endfunction




///////////////////
//  Try to equip an item
///////////////////

function wear_item (byref item, byref you)
	foreach thing in ListEquippedItems (you)
		if (thing == item)
			Say ("But you're wearing that!");
			return;
		endif
	endforeach

	foreach thing in ListEquippedItems (me)
		MoveItemToContainer (thing, inv_pb);
	endforeach

	EquipItem (me, item);

	foreach thingie in ListRootItemsInContainer (inv_pb)
        	if (!EquipItem (me, thingie))
			if (GetObjProperty (thingie, "mine"))
				DestroyItem (thingie);
			else
		        	MoveObjectToLocation (thingie, me.x, me.y, me.z, realm := _DEFAULT_REALM, flags := MOVEOBJECT_FORCELOCATION );
			endif
		endif
	endforeach
endfunction




///////////////////
//  Undress and clean out items for sale
///////////////////

function strip_items (mmymaster)
	if (!me.backpack)
		var newbackpack := CreateItemAtLocation (4550, 3687  , 0, UOBJ_BACKPACK, 1);
		if (!EquipItem (me, newbackpack))
			DestroyItem (newbackpack);
		endif
	endif

	foreach thing in listequippeditems (me)
		if ( (thing.objtype < STARTHAIR or thing.objtype > ENDHAIR) and thing != me.backpack )
			if (!GetObjProperty (thing, "mine"))
				if (!MoveItemToContainer (thing, inv_pb))
					return 0;
				endif
			endif
		endif
	endforeach

	foreach item in ListRootItemsInContainer (inv_fs)
		if (!MoveItemToContainer (item, mmymaster.backpack))
			PrintTextAbovePrivate (me, "Your backpack is full!", mmymaster);
			return 0;
		endif
	endforeach

	foreach item in ListRootItemsInContainer (inv_pb)
		if (!MoveItemToContainer (item, mmymaster.backpack))
			PrintTextAbovePrivate (me, "Your backpack is full!", mmymaster);
			return 0;
		endif
	endforeach

	foreach item in ListRootItemsInContainer (me.backpack)
		if (!MoveItemToContainer (item, mmymaster.backpack))
			PrintTextAbovePrivate (me, "Your backpack is full!", mmymaster);
			return 0;
		endif
	endforeach
	return 1;
endfunction




///////////////////
//  Looks like we're out of work...
///////////////////

function ReleaseMe (mmymaster)
	if (!cashout (mmymaster))
		return;
	endif

	if (!YesNo (mmymaster, "Fire him?"))
		return;
	endif

	if (!strip_items (mmymaster))
		return;
	endif
	CreateItemInContainer (mmymaster.backpack, 0x7008, 1);
	PerformAction (me, ANIM_CAST_DIR);
	say ("Kal Ort Por");
	sleep (2);
	PlaySoundEffect (me, SFX_SPELL_RECALL);
	RevokePrivilege (me, "invul");
	KillMe ();
endfunction




///////////////////
//  add to or remove from the list of items that the merchant buys from other players
///////////////////

function addthingstobuy (mymaster)

	var buylist := {};
	var buyprice := { };
	var buyobj := { };

	if (GetObjProperty (me,"buylist"))
		buylist := GetObjProperty (me, "buylist");
		buyprice := GetObjProperty (me, "buyprice");
		buyobj := GetObjProperty (me, "buyobj");
	endif

	Say ("What do you want me to buy?");
	var what := Target (mymaster);
    	if (!what or !what.isa(POLCLASS_ITEM) )
		Say ("Nevermind");
		return;
    	endif

	//if we're already buying it, stop buying it
	if (what.objtype in buyobj)
		say ("I will no longer purchase " + what.desc);
		var NewBuyList := { };
		var NewBuyPrice := { };
		var NewBuyObj := { };
		for i := 1 to len (buylist)
			if (buyobj[i] != what.objtype)
				newbuylist.append (buylist[i]);
				newbuyprice.append (buyprice[i]);
				newbuyobj.append (buyobj[i]);
			endif
		endfor
		
		if (!len(newbuylist))
			EraseObjProperty (me, "buylist");
			EraseObjProperty (me, "buyprice");
			EraseObjProperty (me, "buyobj");
			return;
		endif

		SetObjProperty (me, "buylist", NewBuyList);
		SetObjProperty (me, "buyprice", NewBuyPrice);
		SetObjProperty (me, "buyobj", NewBuyObj);
		return;
	endif

	if (what.amount > 1)
		Say ("Er, how about we try it one at a time?");
		return;
	endif

	var price := SendTextEntryGump (mymaster, "How much shall I pay for this item?",
			TE_CANCEL_ENABLE, TE_STYLE_NORMAL);
	price := CINT (price);
	if (!price)
		say ("OK, never mind then.");
		return;
	endif
	
	BuyList.append (what.desc);
	BuyPrice.append (price);
	BuyObj.append (what.objtype);
	SetObjProperty (me, "buylist", BuyList);
	SetObjProperty (me, "buyprice", BuyPrice);
	SetObjProperty (me, "buyobj", BuyObj);


	if (len(BuyList)==1)
		say("I will purchase "+BuyList[1]);
	elseif (len(BuyList)==2)
		say("I will purchase "+BuyList[1] +" and "+ BuyList[2]);
	else
		var buying := "I will purchase "+buylist[1];
		for i := 2 to (len(buylist)-1)
			buying := buying + ", " +buylist[i];
		endfor
		buying := buying + " and " + buylist[len(buylist)];
		say(buying);
	endif

endfunction

function SpoutBuyList (byref you)

	var buylist := {};
	var buyprice := {};
	var i;

	if (!GetObjProperty(me,"buylist"))
		say("I don't buy anything.");
		return;
	else
		buylist := GetObjProperty(me,"buylist");
		buyprice := GetObjProperty(me,"buyprice");
	endif

	for (i := 1; i<=len(buylist); i:=i+1)
		PrintTextAbovePrivate (me, "I'll pay "+ buyprice[i] + " for " + buylist[i], you);
		sleep(2);
	endfor

	Say( "Just hand me what you want me to buy." );

endfunction




///////////////////
//  lets the merchants mymaster know what the merchant has sold or other messages
///////////////////

function Notifymymaster (themessage)
	var messagelog := GetObjProperty (me, "messagelog");
	if (!messagelog)
		messagelog := {};
	endif

	if (len (messagelog) >= 19)
		var newmessagelog := {};
		var messlen := len (messagelog);
		for i := (messlen-19) to messlen
			newmessagelog.append (messagelog[i]);
		endfor
		messagelog := newmessagelog;
	endif

	messagelog.append (themessage);
	SetObjProperty (me, "messagelog", messagelog);

	foreach onlinechr in EnumerateOnlineCharacters()
		if (onlinechr.acctname == mymasteracctname)
			PlaySoundEffect (me, 0x38);
			SendSysMessage (onlinechr, me.name + " : " + themessage);
			return;
		endif
	endforeach
endfunction




function ViewMessageLog (byref you)
	var messagelog := GetObjProperty (me, "messagelog");
	if (!messagelog)
		PrintTextAbovePrivate (me, "Its been pretty dull around here.", you);
		return;
	endif

	foreach message in messagelog
		PrintTextAbovePrivate (me, message, you);
		sleep (1);
	endforeach
	EraseObjProperty (me, "messagelog");
endfunction




///////////////////
//  Called when someone buys something from us, calculate our commission
///////////////////

function TakeSale (ev, goldamount, byref who)

	if ( getobjproperty( ev.source,"#vendoracctname") )
		var vendoracctname := getobjproperty( ev.source,"#vendoracctname");
		var vendormrcname := getobjproperty( ev.source, "#vendormerchantname");
		TakeGlobalSale(ev.amount, vendoracctname, vendormrcname);
	//	Notifymymaster (vendoracctname, ev.source.name + " bought " + goldamount + " gold worth of items.");
		eraseobjproperty( ev.source,"#vendoracctname");
		eraseobjproperty( ev.source, "#vendormerchantname");
		return;
	endif
	Notifymymaster (who.name + " bought " + goldamount + " gold worth of items.");

	var mygold := cint(getobjproperty (me, "g"));
	var commission := cint( 0.1 * goldamount);
	

	if (who.serial == mymaster)
		Say ("Since I work for you, I won't take a commission on that.");
		commission := 0;
	endif

	mygold := mygold + goldamount - commission;
	Setobjproperty (me, "g", mygold);
endfunction




///////////////////
//  called when the vendor's mymaster hands gold to the NPC
///////////////////

function TakeGold (byref item)
	var goldamount := item.amount;
	var mygold := cint(getobjproperty (me, "g"));

	if (goldamount)
		mygold := mygold + goldamount;
		say("I am holding " + mygold + " gold for you.");
	endif

	PlaySoundEffect (me, 0x38);
	setobjproperty (me, "g", mygold);
	destroyitem (item);
endfunction




///////////////////
//  when a player hands an item to the NPC, this function is called to see if the merchant buys that item
///////////////////

function BuyItem (byref you, byref it)
	var itsownerserial := CINT (GetObjProperty (it, "ownerserial"));
	if (itsownerserial)
		if (itsownerserial == CINT (mymasterserial))
			Say ("I'll see that this is returned to my employer.");
			MoveItemToContainer (it, me.backpack);
			Notifymymaster (you.name + " gave me an item of yours.");
			return;
		else
			Say ("I'm sorry, but that belongs to someone else.");
			return;
		endif
	endif

	if (!GetObjProperty (me, "buylist"))
		say ("I don't buy anything");
		MoveItemToContainer (it, you.backpack);
		return;
	endif

	var buylist := GetObjProperty (me, "buylist");
	var buyprice := GetObjProperty (me, "buyprice");
	var buyobj := GetObjProperty (me, "buyobj");

	if (!(it.objtype in buyobj))
		say ("Ugh, I don't want that.");
		MoveItemToContainer (it, you.backpack);
		return;
	endif

	var index := 0;
	for i := 1 to len(buylist)
		if (it.objtype == buyobj[i])
			index := i;
			break;
		endif
	endfor

	if (!index)
		say ("Ugh, I don't want that.");
		MoveItemToContainer (it, you.backpack);
		return;
	endif

	var mygold := CINT (GetObjProperty (me, "g"));
	if ( (mygold-250) < (buyprice[index]*it.amount))
		say ("Sorry, I can't afford that right now.");
		MoveItemToContainer (it,you.backpack);
		return;
	endif

	var itamount := it.amount;
	var itdesc := it.desc;
	if ( grabitem (it, me.backpack) )
		var goldamount := buyprice[index]*itamount;
		say("Thank you!  Here's your " + goldamount + " gold.");
		PlaySoundEffect (me, 0x38);
		while (goldamount > 60000)
			CreateItemInBackpack (you, UOBJ_GOLD_COIN, 60000);
			goldamount := goldamount - 60000;
		endwhile
		CreateItemInBackpack (you, UOBJ_GOLD_COIN, goldamount);
		Notifymymaster(you.name + " just sold me " + itdesc);
	else
		Notifymymaster ("My backpack is full!");
		MoveItemToContainer (it, you.backpack);
		return;
	endif

	var theprice := buyprice[index]*itamount;
	mygold := mygold - theprice;
	Setobjproperty (me, "g", mygold);
endfunction




///////////////////
//  when someone hands the merchant an item that this merchant purchases, this function makes sure that
//  the merchant is able to carry the item, stacking it, if possible
///////////////////

function GrabItem (byref item, byref mypack)
	if (item.amount > 1 )
		if (CreateItemInContainer (mypack, item.objtype, item.amount ))
			DestroyItem (item);
			return 1;
		else
			say ("My backpack is full!");
			return 0;
		endif
	else
		var old_item := FindObjtypeInContainer (mypack, item.objtype);
		if (old_item and old_item.amount > 1)
			if (CreateItemInContainer (mypack, item.objtype, item.amount))
				DestroyItem (item);
				return 1;
			else
				say ("My backpack is full!");
				return 0;
			endif
		else
			if (MoveItemToContainer (item, mypack))
				return 1;
			else
				say ("My backpack is full!");
				return 0;
			endif
		endif
	endif
endfunction




///////////////////
//  called when the merchant is told to undress
///////////////////

function undress_items (byref you)
	if (!me.backpack)
		var newbackpack := CreateItemAtLocation (5288, 1176, 0, UOBJ_BACKPACK, 1);
		if (!EquipItem(me, newbackpack))
			DestroyItem (newbackpack);
		endif
	endif

	foreach thing in listequippeditems (me)
		if ((thing.objtype < STARTHAIR or thing.objtype > ENDHAIR) and thing != me.backpack)
			if (GetObjProperty (thing, "mine"))
				DestroyItem (thing);
			else
		        	MoveItemToContainer (thing, you.backpack);
			endif
		endif
	endforeach
endfunction

function MobsAroundMe()

	foreach mobile in ListMobilesNearLocation( me.x, me.y, me.z, 10 )
		if ( IsHostile( mobile ) )
			say("Eek! " + mobile.name);
			me.hidden := 1;
			var sleeptime := ReadGameClock() + 180;
			repeat
				wait_for_event (180);
				if (!me.hidden)
					me.hidden := 1;
				endif
			until (ReadGameClock() > sleeptime);
			restartscript(me);
			return 1;
		endif
	endforeach

	return 0;

endfunction


///////////////////
//  determines if the merchant is in a valid location to sell stuff
///////////////////

function CanSellAtThisLocation ()
	var sign := FindHouseSignAtLocation (me.x, me.y);
	if (!sign)
		var sign := ListItemsNearLocationOfType (me.x, me.y, me.z, 10, 0x7009);
		if (len (sign))
			return 2;
		endif
		return 0;
	endif

	var mymymaster := SystemFindObjectBySerial (mymasterserial);
	if (!mymymaster)
		mymymaster := SystemFindObjectBySerial (mymasterserial, SYSFIND_SEARCH_OFFLINE_MOBILES );
	endif

	if (!mymymaster)
		return 0;
	endif
	
	if (IsAFriend (sign, mymymaster))
		return 1;
	endif
	sign := ListItemsNearLocationOfType (me.x, me.y, me.z, 10, 0x7009);
	if (len (sign))
		return 2;
	endif

	return 0;
endfunction

function TownCheck( who )
//	AlertGM("Line 1056");
	var yourtownnum := GetObjProperty( who, "townnum" );
//	AlertGM("Line 1058");
	var mystone := FindMyStone( me );
//	AlertGM("Line 1060");
	if (!mystone) say("Sorry, but I'm homeless."); return 0; endif
	var mytownnum := cint(GetObjProperty( mystone, "townnum"));
	if (!mytownnum)
		say("I don't know where I am!");
		return;
	endif
//AlertGM("Line 1067");
	var mymymaster := SystemFindObjectBySerial( mymaster );
	if (!mymymaster)
		mymymaster := SystemFindObjectBySerial( mymaster, SYSFIND_SEARCH_OFFLINE_MOBILES );
	endif
//AlertGM("Line 1071");
	if (!mymymaster)
		say("I don't know who my employer is!");
			PerformAction(me,ANIM_CAST_DIR);
			say("Kal Ort Por");
			PlaySoundEffect( me, SFX_SPELL_RECALL );
			sleep(2);
			MoveObjectToLocation(me,4550, 3687  , 0, realm := _DEFAULT_REALM, flags := MOVEOBJECT_FORCELOCATION );
			RevokePrivilege( me, "invul" );
			setobjproperty(me, "guardkill", 1);
			ApplyRawDamage (me, GetVital (me, "Life") + 3 );
			return 0;
	endif
//AlertGM("Line 1085");
	if ( mytownnum != GetObjProperty( mymymaster, "townnum" ) )
		say("I don't work in this town.");
		return 0;
	endif
//AlertGM("Line 1090");
	if (MobsAroundMe())
	 	return 0; 
	endif
//AlertGM("Line 1094");
	if (BannedFromTown( who, mytownnum ))
		say("What are you, some kind of outcast?");
		return 0;
	endif
//AlertGM("Line 1099");
	if (!yourtownnum)
		say("If you become a citizen of the town, I'll be happy to serve you.");
		say("Visit the townstone to join our community.");
		return 0;
	endif
//AlertGM("Line 1105");
	return 1;

endfunction


///////////////////
//  called at merchant AI startup, this function writes all the items the vendor is carrying to 
//  a config file, which can then be used to make a webpage
///////////////////

function LogMyStuff ()
	set_critical (1);
	var playermerchantlist := GetGlobalProperty ("#playermerchantlist");
	if (!playermerchantlist)
		playermerchantlist := {};
	endif

	if (! (me.serial in playermerchantlist) )
		playermerchantlist.append (me.serial);
		SetGlobalProperty ("#playermerchantlist", playermerchantlist);
	endif
	set_critical (0);
endfunction




///////////////////
//  counts how many henchmen a particular account has
///////////////////

function AddToAccountMerchants (mymasterserial)
	set_critical (1);
	var mymymaster := SystemFindObjectBySerial (mymasterserial);
	if (!mymymaster)
		mymymaster := SystemFindObjectBySerial (mymasterserial, SYSFIND_SEARCH_OFFLINE_MOBILES );
	endif

	if (!mymymaster)
		set_critical (0);
		KillMe ();
		return;
	endif

	mymasteracctname := mymymaster.acctname;
	if (!mymasteracctname)
		set_critical (0);
		return 0;
	endif

	SetObjProperty (me, "mymasteracctname", mymasteracctname);
	var merchants := GetGlobalProperty ("#merchants_of_" + mymasteracctname);
	if (!merchants)
		merchants := {};
	endif

	if (me.serial in merchants)
		set_critical (0);
		return 1;
	endif
	merchants.append (me.serial);
	SetGlobalProperty ("#merchants_of_" + mymasteracctname, merchants);
	set_critical (0);
	return 1;
endfunction
function ChooseMerchant( who )

	var accountnames := { };
	var merchantnames := { };
	var nearstone := FindMyStone( who );
	nearstone := GetObjProperty( nearstone, "townnum" );

	foreach acctname in ListAccounts()
		var mercname := HasStorageArea( acctname, nearstone );
		if ( mercname )
			merchantnames.append( mercname );
			accountnames.append( acctname );
		endif
	endforeach

	if (!merchantnames.size())
		sendsysmessage( who, "No merchants!");
		return;
	endif

	var entrynum := 1;
	var selection := { };
	repeat
		var vendormenu := CreateCustomMenu("Merchants of Ackadia", 1, 1);
		var i;
		for ( i := entrynum; i <= entrynum+10; i := i + 1 )
			if ( i <= merchantnames.size() )
				AddOptionToCustomMenu (vendormenu, merchantnames[ i ] );
			endif
		endfor
		if ( merchantnames.size() > (entrynum+10) )
			AddOptionToCustomMenu (vendormenu, "NEXT PAGE");
		endif
		selection := SelectCustomMenuOption(who, vendormenu);
		var ev;
		repeat
			ev := wait_for_event(0);
		until (!ev);
		if ( selection[3] == 12 )
			entrynum := entrynum + 10;
		else
			if ( selection[3] )
				var indexnum := (selection[3] + (entrynum-1) );
				var vendor := { };
				vendor .+ merchantname := merchantnames[ indexnum ];
				vendor .+ acctname := accountnames[ indexnum ];
				return vendor;
			endif
		endif
	until (selection[3] != 12);

	return 0;

endfunction

function HasStorageArea( acctname, nearstone )

	var area := FindRootItemInStorageArea( storage, acctname + " 1C" );
	if ( area )
		var stuff := ListRootItemsInContainer( area );
		if (stuff.size())
			var mrcname := GetMercName( acctname, nearstone );
			if ( mrcname )
				return mrcname;
			else
				return 0;
			endif
		endif
	endif
	return 0;

endfunction

function globaltrade( who )
//AlertGM("line 1245");
	var vendor := ChooseMerchant( who );
	if (!vendor )
		SendSysMessage( who, "Canceled" );
		return;
	endif
//AlertGM("line 1251");
	if (!CanTrade( who, vendor.acctname ))
//		AlertGM("line 1253");
		return;
	endif
//	AlertGM("line 1256");
	var newinv_pb := find_or_create_item( storage, vendor.acctname + " PB", 0xE7C );
	var newinv_fs := find_or_create_item( storage, vendor.acctname + " 1C", 0xE7C );
	if (!newinv_fs or !newinv_pb)
//		AlertGM("line 254");
		SendSysMessage( who, "Canceled" );
		return;
	endif
//	AlertGM("line 258");
	setobjproperty( who, "#vendoracctname", vendor.acctname);
	setobjproperty( who, "#vendormerchantname", vendor.merchantname);
	SendBuyWindow( who, newinv_fs, self(), newinv_pb );
//	var res := SendBuyWindow( who, newinv_fs, self(), newinv_pb );

endfunction

function CanTrade( who, acctname )

	var acct := FindAccount( acctname );
	var thechar;
	for i := 1 to 5
		var char := acct.GetCharacter( i );
		if (char)
			if ( GetObjProperty( char, "validchar" ) )
				thechar := char;
				break;
			endif
		endif
	endfor
	if (!thechar)
		say("Do what to the who now?");
		return 0;
	endif
	var histown := GetObjProperty( thechar, "townnum" );
	if (!histown)
		say("That guy is an outcast");
		return 0;
	endif
	if ( BannedFromTown( who, histown ) )
		say("That guy won't trade with you.  Banned from his town?");
		return 0;
	endif

	return 1;

endfunction

function GetMercName( acctname, nearstone )

	var acct := FindAccount( acctname );
	for i := 1 to 5
		var char := acct.GetCharacter( i );
		if (char)
			if ( GetObjProperty( char, "validchar" ) )
				var townnum := GetObjProperty( char, "townnum" );
				if ( townnum == nearstone )					
					return char.name;
				else
					return 0;
				endif
			endif
		endif
	endfor

	return 0;

endfunction

function TakeGlobalSale(goldamount, acctname, mrcname)

	var mypay := cint(getObjProperty(me, "mypay"));
	var commission := cint( 0.05 * goldamount);

	mypay := mypay + commission;
	goldamount := goldamount - commission;

	say("I'll be sure that " + mrcname + " gets the money");
	say("Less my commission, of course...");

	var bankbox := FindBankBox (acctname);
	if ( goldamount > 60000 )
		repeat
			CreateItemInContainer( bankbox, UOBJ_GOLD_COIN, 60000 );
			goldamount := goldamount - 60000;
		until (goldamount <=60000 );
	endif
	CreateItemInContainer( bankbox, UOBJ_GOLD_COIN, goldamount );
endfunction
the error is early in the script, but i jsut cant figure out why its doing it.

thanks,
mat
User avatar
atreiu
Grandmaster Poster
Posts: 151
Joined: Mon May 24, 2010 1:08 pm

Re: Player Merchants

Post by atreiu »

are you sure what this npc is using this script in npcdesc.cfg?
Script :brainAI:<your_script_name>
gundamwing84
Grandmaster Poster
Posts: 178
Joined: Tue Sep 08, 2009 1:57 am

Re: Player Merchants

Post by gundamwing84 »

I use the WOD 97 script set with a 98 core. so the player merchants are a separate script to the rest of merchants in my shard.

if anyone has a working WOD player merchant script, would it be possible to upload it to here?

please and thankyou,
mat
Post Reply