Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Need help adding a check for "One of a kind" Items

Junior Spellweaver
Joined
Jan 4, 2010
Messages
123
Reaction score
9
Hello I am in the process of making a Boss Gachapon System, credits to 'Cure' for the idea.

I have the script complete and it is working great.
One of the players in my community alerted me that they had one item and pulled the item again, but did not receive a duplicate of the same item. I noticed that since some of the items are boss/end game equips that they are "one of a kind", thus you are only allowed to have one in your inventory or equipped.

Can someone please help me add a check to make sure they don't already have the item equipped or in their inventory.

By this I mean not checking for a specific item, but checking if an item is "one of a kind" or not in general .
Also I am using HeavenMS Source


I believe the check will need to be made on status 1 selection 0
PHP:
	} else if (status == 1) {
		name = cm.getPlayer().getName();
		if (selection == 0 && (cm.haveItem(currency, 1))) {
			if(!cm.getPlayer().getInventory(Packages.client.inventory.MapleInventoryType.EQUIP).isFull(weaponAmount)) {
				var weaponStr = "";
				for(var i = 0; i < weaponAmount; i++) {
					var weapon = prizes[Math.floor(Math.random() * prizes.length)];
					cm.gainItem(weapon, 1, true, true);
					cm.gainItem(currency, -1);
					cm.gainExp(10000000);
					cm.sendOk("You have successfully did a Gachapon Pull\r\n\r\n#fUI/UIWindow.img/QuestIcon/4/0#\r\n#rYou've pulled a \r\n\r\n#v"+weapon+"#\r\n\r\n#kI hope you enjoy your prize!!");
					cm.dispose();
					cm.worldMessage(6, "[Boss Gach] WOW "+name+" Just got a prize from the Boss Gachapon!! ");
				}
			} else {
				cm.sendOk("Please make sure you have enough space to hold the items!");
				cm.dispose();
			}


Thank you for any tips!~
 
Last edited:
Junior Spellweaver
Joined
Jan 4, 2010
Messages
123
Reaction score
9
Just to add I have already tried
PHP:
if (cm.canHold(equipitemid)) {

and it doesn't seem like this checks for it either
PHP:
            if(!cm.getPlayer().getInventory(Packages.client.inventory.MapleInventoryType.EQUIP).isFull(weaponAmount)) {
 
Upvote 0
Mythic Archon
Joined
Jul 2, 2013
Messages
723
Reaction score
70
I noticed that since some of the items are boss/end game equips that they are "one of a kind", thus you are only allowed to have one in your inventory or equipped.

If you look up the equip or item in them wz files, it most likely have a property that tells you if it is a unique item or not. Make sure that property is being loaded when your item is created and use that property as an additional check inside function you mentioned.

Code:
[COLOR=#007700]if ([/COLOR][COLOR=#0000BB]cm[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000BB]canHold[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000BB]equipitemid[/COLOR][COLOR=#007700])) { [/COLOR]

Best of luck!
 
Last edited:
Upvote 0
Newbie Spellweaver
Joined
Sep 21, 2019
Messages
25
Reaction score
2
Hey!

The first "one of a kind" item comes in my mind is HT necklace. This is the necklace configuration you should have in your server-side (if you didn't edit anything):

Look this specific property:

Code:
<int name="only" value="1"/>

By comparing to other items wz files, you can see they don't have the same property (at least not "one of a kind" items). So, this is probably the property you're looking for. :)

After that, you gotta check if any function or class use this specific property to do any validation. Check this class in specific:

Pretty sure they already have implemented a function that does what you're looking for. After finding your function, you can create a new function at NPCConversationManager or just directly call the class/function in your npc, if you prefer.

Hope it helped.
 
Upvote 0
Junior Spellweaver
Joined
Jan 4, 2010
Messages
123
Reaction score
9
Re: Need help adding a check for &amp;amp;quot;One of a kind&amp;amp;quot; Items

Thanks for the help !
I found this in the ItemInformationProvider

PHP:
         boolean bRestricted = false;
        if(itemId != 0) {
            MapleData data = getItemData(itemId);
            if (data != null) {
                bRestricted = MapleDataTool.getIntConvert("info/only", data, 0) == 1;
            }
        }

        pickupRestrictionCache.put(itemId, bRestricted);
        return bRestricted;
    }

I believe this is what I‘m looking for. Is there a way I can just not restrict them? Remove the block of code or adjust one of the values to make “one of a kind” items I guess, not a thing? Or is that client sided?



This is the solution to your problem. If you look up the equip or item in them wz files, it most likely have a property that tells you if it is a unique item or not. Make sure that property is being loaded when your item is created and use that property as an additional check inside function you mentioned.

Code:
[COLOR=#007700]if ([/COLOR][COLOR=#0000BB]cm[/COLOR][COLOR=#007700].[/COLOR][COLOR=#0000BB]canHold[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000BB]equipitemid[/COLOR][COLOR=#007700])) { [/COLOR]

Best of luck!

Hmmm are you suggesting that I just edit the canHold and add a check for items that are one of a kind? That way if I use (cm.canHold) It would check if they have space and/or if they’re receiving an item they already have?
 
Upvote 0
Mythic Archon
Joined
Jul 2, 2013
Messages
723
Reaction score
70
Re: Need help adding a check for &amp;amp;quot;One of a kind&amp;amp;quot; Items

Thanks for the help !
I found this in the ItemInformationProvider

PHP:
         boolean bRestricted = false;
        if(itemId != 0) {
            MapleData data = getItemData(itemId);
            if (data != null) {
                bRestricted = MapleDataTool.getIntConvert("info/only", data, 0) == 1;
            }
        }

        pickupRestrictionCache.put(itemId, bRestricted);
        return bRestricted;
    }

I believe this is what I‘m looking for. Is there a way I can just not restrict them? Remove the block of code or adjust one of the values to make “one of a kind” items I guess, not a thing? Or is that client sided?





Hmmm are you suggesting that I just edit the canHold and add a check for items that are one of a kind? That way if I use (cm.canHold) It would check if they have space and/or if they’re receiving an item they already have?

I took a quick look into ida to confirm if this is handled by the client and it is.

Code:
v3 = TSecType_long_::GetData(( * (20 * a2 + v2[113] + 16) + 12));
    if (CItemInfo::IsOnlyItem(v3)) {
        if (CWvsContext::IsExist( & off_C6FD18, v3)) {
            ... 
            v5 = StringPool::GetInstance();        
            StringPool::GetString(v5, & v9, SP_3518_YOU_MAY_ONLY_POSSESS_ONE_OF_THIS_ITEM);
            CUtilDlg::Notice(v9, v10, v11, v12, v13);
            return 0;
        }
    }
}

If you do not want to do the client edit, you would have use that check mentioned before, the "only" property. However, looking at your block of code you posted, it looks like the boolean is being stored in a cache called pickupRestrictionCache, which does not seem to fit what you are trying to achieve (either that or the cache is incorrectly named / used). I recommend double checking if this "only" property is the one you are after. If it is, then you should rename / re-program how it functions. If it is not, you can load the property the same time the item is loaded from the xmls and store it somewhere like the item object.

For this post, let us say the property name that makes it so you can not hold more than one item is called unique, a boolean in the item object, and an exposed field isUnique() for accessing this boolean.

The next step for you to do is filter out items the user can not hold so you can begin pulling prizes.

Code:
var pool = prizes.filter(item => !item.isUnique() || (item.isUnique && !cm.hasItem(item.getId()));
if(pool.length == 0){
    //gg no items can be held gotta tell the player the bad news :(
} else {
    var weapon = pool[Math.floor(Math.random() * prizes.length)];
    // your code for gaining the item, taking the currency, sending message, disposing; etc
}

I did not check if my js was right or if cm.hasItem is the right function name, but I hope this still helps! Best of luck!
 
Upvote 0
Back
Top