Jump to content

Question

Greetings,

 

Upon going through the modifications I have to make for my scripts and ideas to work with Herc, I encountered different kinds of shops and other features.

However, stubborn as I am, I wonder if it is possible to modify clif.c to add/modify the current currencies for an item from our item database?

Taking the source for the Cash/Point shop, I see that currency is being declared, but due to my lack of programming skills I can't think of a way to point it to a new value, namely one from the item database.

Is anyone able to push me in the right direction? I've already located the most likely point of origin to modify for this to be possible, the spoiler below contains the cash shop code from clif.c.

 

 

/// CASH/POINT SHOP////// List of items offered in a cash shop (ZC_PC_CASH_POINT_ITEMLIST)./// 0287 <packet len>.W <cash point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }*/// 0287 <packet len>.W <cash point>.L <kafra point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* (PACKETVER >= 20070711)void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) {	struct npc_item_list *shop = NULL;	unsigned short shop_size = 0;	int fd,i, c = 0;	int currency[2] = { 0,0 };#if PACKETVER < 20070711	const int offset = 8;#else	const int offset = 12;#endif	nullpo_retv(sd);	nullpo_retv(nd);	if( nd->subtype == SCRIPT ) {		shop = nd->u.scr.shop->item;		shop_size = nd->u.scr.shop->items;		npc->trader_count_funds(nd, sd);		currency[0] = npc->trader_funds[0];		currency[1] = npc->trader_funds[1];	} else {		shop = nd->u.shop.shop_item;		shop_size = nd->u.shop.count;		currency[0] = sd->cashPoints;		currency[1] = sd->kafraPoints;	}	fd = sd->fd;	sd->npc_shopid = nd->bl.id;	WFIFOHEAD(fd,offset+shop_size*11);	WFIFOW(fd,0) = 0x287;	/* 0x2 = length, set after parsing */	WFIFOL(fd,4) = currency[0]; // Cash Points#if PACKETVER >= 20070711	WFIFOL(fd,8) = currency[1]; // Kafra Points#endif	for( i = 0; i < shop_size; i++ ) {		if( shop[i].nameid ) {			struct item_data* id = itemdb->search(shop[i].nameid);			WFIFOL(fd,offset+0+i*11) = shop[i].value;			WFIFOL(fd,offset+4+i*11) = shop[i].value; // Discount Price			WFIFOB(fd,offset+8+i*11) = itemtype(id->type);			WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;			c++;		}	}	WFIFOW(fd,2) = offset+c*11;	WFIFOSET(fd,WFIFOW(fd,2));}/// Cashshop Buy Ack (ZC_PC_CASH_POINT_UPDATE)./// 0289 <cash point>.L <error>.W/// 0289 <cash point>.L <kafra point>.L <error>.W (PACKETVER >= 20070711)/// For error return codes see enum [email protected] clif_cashshop_ack(struct map_session_data* sd, int error) {	struct npc_data *nd;	int fd;	int currency[2] = { 0,0 };	nullpo_retv(sd);	fd = sd->fd;	if( (nd = map->id2nd(sd->npc_shopid)) && nd->subtype == SCRIPT ) {		npc->trader_count_funds(nd,sd);		currency[0] = npc->trader_funds[0];		currency[1] = npc->trader_funds[1];	} else {		currency[0] = sd->cashPoints;		currency[1] = sd->kafraPoints;	}	WFIFOHEAD(fd, packet_len(0x289));	WFIFOW(fd,0) = 0x289;	WFIFOL(fd,2) = currency[0];#if PACKETVER < 20070711	WFIFOW(fd,6) = TOW(error);#else	WFIFOL(fd,6) = currency[1];	WFIFOW(fd,10) = TOW(error);#endif	WFIFOSET(fd, packet_len(0x289));}void clif_parse_cashshop_buy(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));/// Request to buy item(s) from cash shop (CZ_PC_BUY_CASH_POINT_ITEM)./// 0288 <name id>.W <amount>.W/// 0288 <name id>.W <amount>.W <kafra points>.L (PACKETVER >= 20070711)/// 0288 <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W }.4B*count (PACKETVER >= 20100803)void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){	int fail = 0;	if( sd->state.trading || !sd->npc_shopid || pc_has_permission(sd,PC_PERM_DISABLE_STORE) )		fail = 1;	else {#if PACKETVER < 20101116		short nameid = RFIFOW(fd,2);		short amount = RFIFOW(fd,4);		int points = RFIFOL(fd,6);		fail = npc->cashshop_buy(sd, nameid, amount, points);#else		int len = RFIFOW(fd,2);		int points = RFIFOL(fd,4);		int count = RFIFOW(fd,8);		unsigned short* item_list = (unsigned short*)RFIFOP(fd,10);		if( len < 10 || len != 10 + count * 4) {			ShowWarning("Player %u sent incorrect cash shop buy packet (len %u:%u)!n", sd->status.char_id, len, 10 + count * 4);			return;		}		fail = npc->cashshop_buylist(sd,points,count,item_list);#endif	}	clif->cashshop_ack(sd,fail);}

 

 

 

Thanks in advance.

 

Note: I have done my search and did find this as an option, however I like to expand my horizon and get things done how I have them in mind. Potentially providing a change for others to use.
I'm not too lazy to search, just too stubborn to accept workaround to be a valid solution.

 

Edited by Tranquility

Share this post


Link to post
Share on other sites

9 answers to this question

Recommended Posts

  • 0

Something like this ? : https://raw.githubusercontent.com/HerculesWS/Hercules/master/doc/sample/npc_trader_sample.txt

 

/* custom npc trader */prontera,153,152,1	trader	TestCustom2	4_F_EDEN_OFFICER,{	OnInit:	tradertype(NST_CUSTOM);	sellitem Red_Potion,2;	end;/* allows currency to be item 501 and 502 */OnCountFunds:	setcurrency(countitem(Red_Potion),countitem(Orange_Potion));	end;/* receives @price (total cost) and @points (the secondary input field for cash windows) */OnPayFunds:	dispbottom "Hi: price="+@price+" and points="+@points;	if( countitem(Orange_Potion) < @points || countitem(Red_Potion) < @price-@points )		end;	delitem Orange_Potion,@points;	delitem Red_Potion,@price-@points;	purchaseok();	end;}

Share this post


Link to post
Share on other sites
  • 0

Something like this ? : https://raw.githubusercontent.com/HerculesWS/Hercules/master/doc/sample/npc_trader_sample.txt

 

 

/* custom npc trader */prontera,153,152,1	trader	TestCustom2	4_F_EDEN_OFFICER,{	OnInit:	tradertype(NST_CUSTOM);	sellitem Red_Potion,2;	end;/* allows currency to be item 501 and 502 */OnCountFunds:	setcurrency(countitem(Red_Potion),countitem(Orange_Potion));	end;/* receives @price (total cost) and @points (the secondary input field for cash windows) */OnPayFunds:	dispbottom "Hi: price="+@price+" and points="+@points;	if( countitem(Orange_Potion) < @points || countitem(Red_Potion) < @price-@points )		end;	delitem Orange_Potion,@points;	delitem Red_Potion,@price-@points;	purchaseok();	end;}

 

 

I'll get back to this soon, need to verify ;p

Else I might have to try make a plugin for this, to have the rA cashshop feature with custom currency here too.

Share this post


Link to post
Share on other sites
  • 0

Finally tested it and it's a yes/no thing.

Yes I would like the functionality to modify the currency like that script shows there, however I would like to use the original cashshop user interface, located in the rop right to do this.

The currencies are hard-coded inside source, but when reading the original commit for the cashshop, I was hoping a variable could be added that allows to read a currency set in cashshop_db.conf (in this scenario an itemID).

Yet defaulting to the cashpoint variable if nothing is specified.

 

Hopefully this isn't too far fetched of an idea.

Share this post


Link to post
Share on other sites
  • 0

by finding pc->paycash command

I found that buying this stuff are actually clif_parse_CashShopBuy located in clif.c

 

I think you just have to change pc->paycash into your delitem ... something

Share this post


Link to post
Share on other sites
  • 0

by finding pc->paycash command

I found that buying this stuff are actually clif_parse_CashShopBuy located in clif.c

 

I think you just have to change pc->paycash into your delitem ... something

Hmm, trying to think along here with what you posted. Browing further through clif.c the following is what I've come up with..

 

First we'd need to verify that if the player has enough currency 'x' to buy item 'y'. Replacing:

if( sd->kafraPoints < kafra_pay ) {  result = CSBR_SHORTTAGE_CASH;} else if( (sd->cashPoints+kafra_pay) < (clif->cs.data[tab][j]->price * qty) ) {  result = CSBR_SHORTTAGE_CASH;}

Next, replacing the paycash reference for a delitem referrence, however, delitem has more parameters to take into account(?)

pc->paycash(sd, clif->cs.data[tab][j]->price * qty, kafra_pay);// [Ryuuzaki]To something like:pc->delitem(sd,n,clif->cs.data[tab][j]->price * qty,0,DELITEM_NORMAL,LOG_TYPE_NPC);

Honestly I lack the skill or insight to know what I'm doing, but this is what I can deduce from the code elsewhere.

Would reading a variable from the item_cash_db.conf be nicer to know whether or not a custom currency is to be used? Then if the variable isn't set, default will be cashpoints/kafrapoints.

Edited by Tranquility

Share this post


Link to post
Share on other sites
  • 0

although its possible to do this on the source, but I'm client noob

I know how to delete item directly when make a purchase

but the client side still shows "x points will be deducted from your kafra credit points"

Would reading a variable from the item_cash_db.conf be nicer to know whether or not a custom currency is to be used? Then if the variable isn't set, default will be cashpoints/kafrapoints.

that will require some intense source modification I guess

why not just write a plugin and add a configuration for require item ID ?

Share this post


Link to post
Share on other sites
  • 0

 

although its possible to do this on the source, but I'm client noob

I know how to delete item directly when make a purchase

but the client side still shows "x points will be deducted from your kafra credit points"

Would reading a variable from the item_cash_db.conf be nicer to know whether or not a custom currency is to be used? Then if the variable isn't set, default will be cashpoints/kafrapoints.

that will require some intense source modification I guess

why not just write a plugin and add a configuration for require item ID ?

Thanks for the input, I'll give it a try. When I get stuck, I'll get back you guys :)

Share this post


Link to post
Share on other sites
  • 0

any news about this?

Not from my side, I can't get my things to work. Nor know where to make the right adjustment to not make it hard-coded.

Still in process of learning how, what, where and why.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.