Tio Akima Posted January 18, 2019 Group: Members Topic Count: 94 Topics Per Day: 0.02 Content Count: 191 Reputation: 138 Joined: 09/24/12 Last Seen: March 21 Share Posted January 18, 2019 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? Quote Link to comment Share on other sites More sharing options...
0 utofaery Posted January 21, 2019 Group: Members Topic Count: 23 Topics Per Day: 0.01 Content Count: 228 Reputation: 19 Joined: 10/27/12 Last Seen: March 17, 2019 Share Posted January 21, 2019 Answer to your questions: https://rathena.org/board/topic/114960-card-item-limitation/?do=findComment&comment=343029 why did you created post or topic in between forums?? https://rathena.org/board/topic/118003-not-equip-equal-cards/?do=findComment&comment=356502 http://herc.ws/board/topic/16525-not-equip-equal-cards/ Quote Link to comment Share on other sites More sharing options...
0 AnnieRuru Posted January 21, 2019 Group: Members Topic Count: 18 Topics Per Day: 0.00 Content Count: 2044 Reputation: 682 Joined: 10/09/12 Last Seen: December 20, 2020 Share Posted January 21, 2019 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 1 Quote Link to comment Share on other sites More sharing options...
0 Tio Akima Posted January 21, 2019 Group: Members Topic Count: 94 Topics Per Day: 0.02 Content Count: 191 Reputation: 138 Joined: 09/24/12 Last Seen: March 21 Author Share Posted January 21, 2019 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 Quote Link to comment Share on other sites More sharing options...
0 n0tttt Posted January 21, 2019 Group: Members Topic Count: 4 Topics Per Day: 0.00 Content Count: 303 Reputation: 118 Joined: 12/10/16 Last Seen: March 5 Share Posted January 21, 2019 (edited) 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 January 24, 2019 by n0tttt 1 Quote Link to comment Share on other sites More sharing options...
0 AnnieRuru Posted January 24, 2019 Group: Members Topic Count: 18 Topics Per Day: 0.00 Content Count: 2044 Reputation: 682 Joined: 10/09/12 Last Seen: December 20, 2020 Share Posted January 24, 2019 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 ... Quote Link to comment Share on other sites More sharing options...
0 n0tttt Posted January 24, 2019 Group: Members Topic Count: 4 Topics Per Day: 0.00 Content Count: 303 Reputation: 118 Joined: 12/10/16 Last Seen: March 5 Share Posted January 24, 2019 Edited the post. Thanks. Quote Link to comment Share on other sites More sharing options...
0 Starfoxcat Posted December 31, 2020 Group: Members Topic Count: 0 Topics Per Day: 0 Content Count: 23 Reputation: 2 Joined: 08/15/19 Last Seen: April 15, 2021 Share Posted December 31, 2020 (edited) 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 December 31, 2020 by Starfoxcat Little more details. Quote Link to comment Share on other sites More sharing options...
Question
Tio Akima
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
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.