Thread: Shopkeeper Code
View Single Post
  #1  
Old 01-28-2002, 11:59 AM
darvik
Fire Beetle
 
Join Date: Jan 2002
Posts: 21
Default Shopkeeper Code

Been doing some adds to the code - based off 0.2.0 , added lots of stuff for merchant interaction, but it's far from complete. I coulnd't figure out how to do the database stuff right, so basicly the item list is hardcoded for all merchants, they all sell the same 2 items, and no matter what you buy, you get grapes. You can sell stuff and get money though.. and the client no longer locks up when you try to interact with a merchant.
Had to figure out a lot of this stuff out on my own because nobody else has done it before.. the opCodes were not even in showEQ.

Anyway - someone else will have to do the database portion of this -- I also included some sample sql of how this can be done without having to modify the npc_types table.

Have to split code into seperate posts ;/

code for eq_opcodes.h
Code:
// Darvik: for shopkeepers
#define OP_ShopRequest     0x0b20 // right-click on merchant
#define OP_ShopItem        0x0c20
#define OP_ShopWelcome     0x1420
#define OP_ShopPlayerBuy   0x3520
#define OP_ShopGiveItem    0x3120
#define OP_ShopTakeMoney   0x3520
#define OP_ShopPlayerSell  0x2720
#define OP_ShopEnd         0x3720
#define OP_ShopEndConfirm  0x4521
code for client_process.cpp - I added this just above case OP_Jump:
Code:
case OP_ShopRequest:
{
	Merchant_Click_Struct* mc=(Merchant_Click_Struct*)app->pBuffer;
	if (app->size == sizeof(Merchant_Click_Struct))
	{
		cout << name << " is at merchant. ID:" << mc->merchantid << endl;
		DumpPacketHex(app);
		int32 mi = mc->merchantid;

		// Send back opcode OP_ShopRequest - tells client to open merchant window.
		APPLAYER* outapp = new APPLAYER;
		outapp->opcode = OP_ShopRequest;
		outapp->size = sizeof(Merchant_Click_Struct);
		outapp->pBuffer = new uchar[sizeof(Merchant_Click_Struct)];
		Merchant_Click_Struct* mco=(Merchant_Click_Struct*)outapp->pBuffer;
		mco->mcs_unknown001 = mc->mcs_unknown001;
		mco->merchantid = mc->merchantid;
		mco->itemslot = 0x01;			// unused here, but we set to a harmless value.
		mco->mcs_unknown002[0] = mc->mcs_unknown002[0];
		mco->mcs_unknown002[1] = mc->mcs_unknown002[0];
		mco->mcs_unknown002[2] = mc->mcs_unknown002[0];
		mco->quantity = 0x1b;			// qty when used in purchase, unused here.
		mco->mcs_unknown003[0] = 0x0d;	// unknown data - has something to do with
		mco->mcs_unknown003[1] = 0xa0;	// buying and selling cost or markup.
		mco->mcs_unknown003[2] = 0x3F;	// <- changing this value even slightly severly screws up price.
		cout << "sending back merchant_click_struct to client." << endl;
		DumpPacketHex(outapp);

		QueuePacket(outapp);
		delete outapp;
							
		// TODO: Lookup	merchants wares..
		// TODO: Start Loop through wares..
			// Debug - hardcoded short beer .. trying to get stackable items to work.
			uint16 item_nr = 16592;
			Item_Struct* item = database.GetItem(item_nr);
			cout << "merchant is selling: " << item->name << endl;
			// Send this item to the client.
			outapp = new APPLAYER;
			outapp->opcode = OP_ShopItem;
			outapp->size = sizeof(Item_Shop_Struct);
			outapp->pBuffer = new uchar[outapp->size];
			Item_Shop_Struct* iss = (Item_Shop_Struct*)outapp->pBuffer;
			iss->merchantid = mi;
			iss->itemtype = 0x00;			// TODO: needs to be parsed from item.
			item->equipSlot = 0x00;			// this needs to be incremented in loop.
			memcpy(&iss->item, item, sizeof(Item_Struct));
			iss->iss_unknown001 = 0;
			QueuePacket(outapp);
			delete outapp;


			// Debug - hardcoded cloth cap..
			item_nr = 1001;
			item = database.GetItem(item_nr);
			cout << "merchant is selling: " << item->name << endl;
			// Send this item to the client.
			outapp = new APPLAYER;
			outapp->opcode = OP_ShopItem;
			outapp->size = sizeof(Item_Shop_Struct);
			outapp->pBuffer = new uchar[outapp->size];
			iss = (Item_Shop_Struct*)outapp->pBuffer;
			iss->merchantid = mi;
			iss->itemtype = 0x01;			// TODO: needs to be parsed from item.
			item->equipSlot = 0x01;			// this needs to be incremented in loop.
			item->common.number = 1;		// not sure if this tells how many the merchant has.
			memcpy(&iss->item, item, sizeof(Item_Struct));
			iss->iss_unknown001 = 0;
			QueuePacket(outapp);
			delete outapp;

		// TODO: End Loop through wares..

		// say welcome to player - dont know c well enough to do this right.
		// it's just a single null terminated string, heh.
		outapp = new APPLAYER;
		outapp->opcode = OP_ShopWelcome;
		outapp->pBuffer = new uchar[12];
		outapp->size = 12;
		outapp->pBuffer[0] = 0x48;
		outapp->pBuffer[1] = 0x65;
		outapp->pBuffer[2] = 0x6c;
		outapp->pBuffer[3] = 0x6c;
		outapp->pBuffer[4] = 0x6f;
		outapp->pBuffer[5] = 0x20;
		outapp->pBuffer[6] = 0x74;
		outapp->pBuffer[7] = 0x68;
		outapp->pBuffer[8] = 0x65;
		outapp->pBuffer[9] = 0x72;
		outapp->pBuffer[10] = 0x65;
		outapp->pBuffer[11] = 0x00;	
		QueuePacket(outapp);
		delete outapp;

	}
	else
	{
		cout << "Wrong size" << app->size  << ", should be " << sizeof(Merchant_Click_Struct) << endl;
	}
	break;
}
Will follow this post with the rest of the opCodes..
Reply With Quote