Items duplicating with CanCraft hook
I used the following pattern to prevent crafting two specific items (returning false for those items) while allowing the rest (returning true for all other cases).  This resulted in a duplication bug on my server which has wrecked the economy and most of the builds and will require a wipe.

What is the recommended, safe way to prevent crafting of specific items while allowing the rest?

bool CanCraft(ItemCrafter itemCrafter, ItemBlueprint bp, int amount)
        {
            if (!this.allowCraft_CodeLockCheck(bp.targetItem))
            {
                itemCrafter.containers[0].GetOwnerPlayer().ChatMessage("explanation");
                return false;
            }

            else if(!this.allowCraft_DoorKeyCheck(bp.targetItem))
            {
                itemCrafter.containers[0].GetOwnerPlayer().ChatMessage("explanation");
                return false;
            }

            return true;
        }​


If a umod admin cares to get the details of HOW to duplicate with this code in place, contact me directly ([email protected]).
This plugin is kind of....messy.

I've made a quick mock up for you. Add item shortnames to the list at the top, seperated by commas. If an item is blocked, it will send the message in the chat and block it, otherwise it will be allowed.

private string[] _itemBlacklist = { "lock.code" };
        private bool CanCraft(ItemCrafter itemCrafter, ItemBlueprint bp, int amount)
        {
            if (_itemBlacklist.Contains(bp.targetItem.shortname))
            {
                itemCrafter.containers[0].GetOwnerPlayer().ChatMessage("Your message here.");
                return false;
            }
            return true;
        }​
5fec421510481.png Ryz0r
This plugin is kind of....messy.

I've made a quick mock up for you. Add item shortnames to the list at the top, seperated by commas. If an item is blocked, it will send the message in the chat and block it, otherwise it will be allowed.

private string[] _itemBlacklist = { "lock.code" };
        private bool CanCraft(ItemCrafter itemCrafter, ItemBlueprint bp, int amount)
        {
            if (_itemBlacklist.Contains(bp.targetItem.shortname))
            {
                itemCrafter.containers[0].GetOwnerPlayer().ChatMessage("Your message here.");
                return false;
            }
            return true;
        }​
Yours has the same outcome - can't just return true for cases I don't care about.  That's where the dup bug comes from.
change from bool to object and return null.

private string[] _itemBlacklist = { "lock.code" };
        private object CanCraft(ItemCrafter itemCrafter, ItemBlueprint bp, int amount)
        {
            if (_itemBlacklist.Contains(bp.targetItem.shortname))
            {
                itemCrafter.containers[0].GetOwnerPlayer().ChatMessage("Your message here.");
                return false;
            }
            return null;
        }​
I gave that return  null a try and it didn't work out for me either.  Ultimately I hooked OnCraft instead and scheduled a server task for the next frame...  that server task cancels that crafting task and returns the items.  It's the outcome I wanted, albeit more messy and roundabout than I'd like.  :)