Jump to content
  • 0

not equip equal cards


Tio Akima

Question


  • Group:  Members
  • Topic Count:  94
  • Topics Per Day:  0.02
  • Content Count:  191
  • Reputation:   138
  • Joined:  09/24/12
  • Last Seen:  

hi guys
How can I prevent the player from using two (or more) equal cards in the same item?

I've tried isequippedcnt, but it does not work.

Maybe it is better (easier) to put this condition in source.
Has anyone tried something like this, and can you point the way?

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 0

  • Group:  Members
  • Topic Count:  23
  • Topics Per Day:  0.01
  • Content Count:  228
  • Reputation:   19
  • Joined:  10/27/12
  • Last Seen:  

  • 0

  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

topic starter is right,

@item2 1501 1 1 0 0 4001 4001 4001 4001
@item2 1502 1 1 0 0 4001 4001 4001 4001
@item2 1503 1 1 0 0 4001 4001 4001 4001

make 3 clubs, each having different slots

Item ID 1501 shows I have 3 poring card insert
Item ID 1502 shows I have 4 poring card insert
Item ID 1503 shows I don't have poring card inserted

in other words this *isequippedcnt is totally depends on the amount of slots the equipment having

if the check is just based on the player insert the card by double clicking the card, above post might give correct answer
BUT if your server has a script that can slot cards into non-slot-able area (eg: rune, charms), then have to do source modifications ... maybe

  • Love 1
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  94
  • Topics Per Day:  0.02
  • Content Count:  191
  • Reputation:   138
  • Joined:  09/24/12
  • Last Seen:  

2 hours ago, AnnieRuru said:

topic starter is right,


@item2 1501 1 1 0 0 4001 4001 4001 4001
@item2 1502 1 1 0 0 4001 4001 4001 4001
@item2 1503 1 1 0 0 4001 4001 4001 4001

make 3 clubs, each having different slots

Item ID 1501 shows I have 3 poring card insert
Item ID 1502 shows I have 4 poring card insert
Item ID 1503 shows I don't have poring card inserted

in other words this *isequippedcnt is totally depends on the amount of slots the equipment having

if the check is just based on the player insert the card by double clicking the card, above post might give correct answer
BUT if your server has a script that can slot cards into non-slot-able area (eg: rune, charms), then have to do source modifications ... maybe

thanks Annie ❤️ 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  4
  • Topics Per Day:  0.00
  • Content Count:  303
  • Reputation:   117
  • Joined:  12/10/16
  • Last Seen:  

Try this.

pc.cpp

 

Change:

/*==========================================
 * Append a card to an item ?
 *------------------------------------------*/
int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
{
	int i;
	unsigned short nameid;

	nullpo_ret(sd);

	if( idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL )
		return 0; //Invalid item index.
	if( idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL )
		return 0; //Invalid card index.
	if( sd->inventory.u.items_inventory[idx_equip].nameid <= 0 || sd->inventory.u.items_inventory[idx_equip].amount < 1 )
		return 0; // target item missing
	if( sd->inventory.u.items_inventory[idx_card].nameid <= 0 || sd->inventory.u.items_inventory[idx_card].amount < 1 )
		return 0; // target card missing
	if( sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR )
		return 0; // only weapons and armor are allowed
	if( sd->inventory_data[idx_card]->type != IT_CARD )
		return 0; // must be a card
	if( sd->inventory.u.items_inventory[idx_equip].identify == 0 )
		return 0; // target must be identified
	if( itemdb_isspecial(sd->inventory.u.items_inventory[idx_equip].card[0]) )
		return 0; // card slots reserved for other purposes
	if( (sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0 )
		return 0; // card cannot be compounded on this item type
	if( sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD )
		return 0; // attempted to place shield card on left-hand weapon.
	if( sd->inventory.u.items_inventory[idx_equip].equip != 0 )
		return 0; // item must be unequipped

	ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->inventory.u.items_inventory[idx_equip].card[i] == 0 );
	if( i == sd->inventory_data[idx_equip]->slot )
		return 0; // no free slots

	// remember the card id to insert
	nameid = sd->inventory.u.items_inventory[idx_card].nameid;

	if( pc_delitem(sd,idx_card,1,1,0,LOG_TYPE_OTHER) == 1 )
	{// failed
		clif_insert_card(sd,idx_equip,idx_card,1);
	}
	else
	{// success
		log_pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->inventory.u.items_inventory[idx_equip]);
		sd->inventory.u.items_inventory[idx_equip].card[i] = nameid;
		log_pick_pc(sd, LOG_TYPE_OTHER,  1, &sd->inventory.u.items_inventory[idx_equip]);
		clif_insert_card(sd,idx_equip,idx_card,0);
	}

	return 0;
}

to:

/*==========================================
 * Append a card to an item ?
 *------------------------------------------*/
int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
{
	int i;
	unsigned short nameid;

	nullpo_ret(sd);

	if( idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL )
		return 0; //Invalid item index.
	if( idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL )
		return 0; //Invalid card index.
	if( sd->inventory.u.items_inventory[idx_equip].nameid <= 0 || sd->inventory.u.items_inventory[idx_equip].amount < 1 )
		return 0; // target item missing
	if( sd->inventory.u.items_inventory[idx_card].nameid <= 0 || sd->inventory.u.items_inventory[idx_card].amount < 1 )
		return 0; // target card missing
	if( sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR )
		return 0; // only weapons and armor are allowed
	if( sd->inventory_data[idx_card]->type != IT_CARD )
		return 0; // must be a card
	if( sd->inventory.u.items_inventory[idx_equip].identify == 0 )
		return 0; // target must be identified
	if( itemdb_isspecial(sd->inventory.u.items_inventory[idx_equip].card[0]) )
		return 0; // card slots reserved for other purposes
	if( (sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0 )
		return 0; // card cannot be compounded on this item type
	if( sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD )
		return 0; // attempted to place shield card on left-hand weapon.
	if( sd->inventory.u.items_inventory[idx_equip].equip != 0 )
		return 0; // item must be unequipped

	ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->inventory.u.items_inventory[idx_equip].card[i] == 0 );
	if( i == sd->inventory_data[idx_equip]->slot )
		return 0; // no free slots
      
	struct item_data* data;
	data = itemdb_search(item->nameid);

	if(data->stack.inventory) {
		int count;
		for(i = 0; i < sd->inventory_data[idx_equip]->slot; i++) {
			if(sd->inventory.u.items_inventory[idx_equip].card[i] == nameid)
				count++;
		}
		if(count >= data->stack.amount) {
			char output[255];
			sprintf(output, "This card cannot be stacked %d times or more.", data->stack.amount);
			clif_messagecolor(&sd->bl, color_table[COLOR_RED], output, false, SELF);
			return 0;
		}
	}

	// remember the card id to insert
	nameid = sd->inventory.u.items_inventory[idx_card].nameid;

	if( pc_delitem(sd,idx_card,1,1,0,LOG_TYPE_OTHER) == 1 )
	{// failed
		clif_insert_card(sd,idx_equip,idx_card,1);
	}
	else
	{// success
		log_pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->inventory.u.items_inventory[idx_equip]);
		sd->inventory.u.items_inventory[idx_equip].card[i] = nameid;
		log_pick_pc(sd, LOG_TYPE_OTHER,  1, &sd->inventory.u.items_inventory[idx_equip]);
		clif_insert_card(sd,idx_equip,idx_card,0);
	}

	return 0;
}

And change:

/*==========================================
 * Checking if we have enough place on inventory for new item
 * Make sure to take 30k as limit (for client I guess)
 * @param sd
 * @param nameid
 * @param amount
 * @return e_chkitem_result
 *------------------------------------------*/
char pc_checkadditem(struct map_session_data *sd, unsigned short nameid, int amount)
{
	int i;
	struct item_data* data;

	nullpo_ret(sd);

	if(amount > MAX_AMOUNT)
		return CHKADDITEM_OVERAMOUNT;

	data = itemdb_search(nameid);

	if(!itemdb_isstackable2(data))
		return CHKADDITEM_NEW;

	if( data->stack.inventory && amount > data->stack.amount )
		return CHKADDITEM_OVERAMOUNT;

	for(i=0;i<MAX_INVENTORY;i++){
		// FIXME: This does not consider the checked item's cards, thus could check a wrong slot for stackability.
		if(sd->inventory.u.items_inventory[i].nameid == nameid){
			if( amount > MAX_AMOUNT - sd->inventory.u.items_inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->inventory.u.items_inventory[i].amount ) )
				return CHKADDITEM_OVERAMOUNT;
			return CHKADDITEM_EXIST;
		}
	}

	return CHKADDITEM_NEW;
}

to:

/*==========================================
 * Checking if we have enough place on inventory for new item
 * Make sure to take 30k as limit (for client I guess)
 * @param sd
 * @param nameid
 * @param amount
 * @return e_chkitem_result
 *------------------------------------------*/
char pc_checkadditem(struct map_session_data *sd, unsigned short nameid, int amount)
{
	int i;
	struct item_data* data;

	nullpo_ret(sd);

	if(amount > MAX_AMOUNT)
		return CHKADDITEM_OVERAMOUNT;

	data = itemdb_search(nameid);

	if(!itemdb_isstackable2(data))
		return CHKADDITEM_NEW;

	if(itemdb_type(nameid) == IT_CARD)
		return CHKADDITEM_NEW;

	if( data->stack.inventory && amount > data->stack.amount )
		return CHKADDITEM_OVERAMOUNT;

	for(i=0;i<MAX_INVENTORY;i++){
		// FIXME: This does not consider the checked item's cards, thus could check a wrong slot for stackability.
		if(sd->inventory.u.items_inventory[i].nameid == nameid){
			if( amount > MAX_AMOUNT - sd->inventory.u.items_inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->inventory.u.items_inventory[i].amount ) )
				return CHKADDITEM_OVERAMOUNT;
			return CHKADDITEM_EXIST;
		}
	}

	return CHKADDITEM_NEW;
}

Then you add the cards in item_stack.txt

4001,1,1  // Poring Card

 

This way you can't insert the card more than X times. It's better than having a division or nullifying the effects since the player doesn't waste cards.

Edited by n0tttt
  • Like 1
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

On 1/22/2019 at 7:19 AM, n0tttt said:

Then you add the cards in item_stack.txt


4001,1,1  // Poring Card

 

This way you can't insert the card more than X times. It's better than having a division or nullifying the effects since the player doesn't waste cards.

wait, if you do like that, I can't carry more than 1 Poring Card

maybe introduce a new bit-mask &16 or something ...

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  4
  • Topics Per Day:  0.00
  • Content Count:  303
  • Reputation:   117
  • Joined:  12/10/16
  • Last Seen:  

Edited the post. Thanks.

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  23
  • Reputation:   2
  • Joined:  08/15/19
  • Last Seen:  

Hello,,

Firstly, I'm sorry for bringing this up back, but I haven't seen the real solution to this.

To fix what @Tio Akimaasked and @AnnieRuru explained, it can be done in a very simple way.

Head to script.cpp and in the "BUILDIN_FUNC(isequippedcnt)" section:

change:

Quote

for (short k = 0; k < sd->inventory_data[index]->slots; k++) { 

To:

for (short k = 0; k < 4; k++) {

It will make the isequippedcnt function to cease to ONLY check available card slots in an equipped item and FORCE it to always check all four slots whether they are closed or open.

That number 4 above and the "smaller than" operator is meant to check the card0, card1, card2, and card3 in an item. (Card0 = 1st card slot, Card1 = 2nd card slot, and so on).

By using that method, you will be able to use isequippedcnt function in an item that has cards in the closed card slots. This may be handy for those who use card/orb inserter NPC and still want to limit its abilities (eg. stacking Bigfoot card 4x = immune to insect because 30% x 4 = 120%).

Don't forget to recompile the source files, using "Build Solution" option is fine. Or use "Rebuild Solution" if you don't really trust this method.

 

PS:

  • Once again, sorry for bringing back an almost one-year-old post.
  • Lazy version to "find and replace" is in the attachment, download and overwrite your file with that one. Still, you will need to recompile the source files.
  • If you think this is helpful, please upvote so other members can really find this solution faster.

 

Cheers, happy new year 2021.

script.cpp

Edited by Starfoxcat
Little more details.
Link to comment
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.   Paste as plain text instead

  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.

×
×
  • Create New...