Skip to content

Commit

Permalink
vanilla recipe blocker for item scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Mar 1, 2021
1 parent c83f40c commit ce0495c
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
Expand Up @@ -78,6 +78,11 @@ public class ItemScriptContainer extends ScriptContainer {
// - enchantment_name:level
// - ...
//
// # Set this to 'true' to allow the item script item to be used in material-based recipe (eg most vanilla recipes).
// # Defaults to false if unspecified.
// # | Most item scripts should exclude this key!
// allow in material recipes: false
//
// # You can specify flags to be added to the item.
// flags:
// # Each line within the flags section should be a flag name as a key, and the flag value as the value.
Expand Down Expand Up @@ -164,10 +169,12 @@ public class ItemScriptContainer extends ScriptContainer {

String hash = "";

public boolean allowInMaterialRecipes;

public ItemScriptContainer(YamlConfiguration configurationSection, String scriptContainerName) {
super(configurationSection, scriptContainerName);
canRunScripts = false;

allowInMaterialRecipes = getString("allow in material recipes", "false").equalsIgnoreCase("true");
ItemScriptHelper.item_scripts.put(CoreUtilities.toLowerCase(getName()), this);
ItemScriptHelper.item_scripts_by_hash_id.put(ItemScriptHelper.createItemScriptID(this), this);
}
Expand Down
Expand Up @@ -20,7 +20,11 @@
import com.denizenscript.denizencore.utilities.text.StringHolder;
import org.bukkit.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockCookEvent;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.inventory.*;

import java.math.BigInteger;
Expand Down Expand Up @@ -338,4 +342,97 @@ public static String createItemScriptID(String name) {
}
return colors.toString();
}

public static boolean isAllowedChoice(ItemScriptContainer script, RecipeChoice choice) {
if (choice instanceof RecipeChoice.ExactChoice) {
for (ItemStack choiceOpt : ((RecipeChoice.ExactChoice) choice).getChoices()) {
ItemScriptContainer choiceOptContainer = getItemScriptContainer(choiceOpt);
if (script == choiceOptContainer) {
return true;
}
}
}
return false;
}

public static boolean shouldDenyCraft(ItemStack[] items, Recipe recipe) {
for (int i = 0; i < items.length; i++) {
ItemStack item = items[i];
if (item == null || item.getType() == Material.AIR) {
continue;
}
ItemScriptContainer container = getItemScriptContainer(item);
if (container == null || container.allowInMaterialRecipes) {
continue;
}
boolean allowed = false;
if (recipe instanceof ShapelessRecipe) {
for (RecipeChoice choice : ((ShapelessRecipe) recipe).getChoiceList()) {
if (isAllowedChoice(container, choice)) {
allowed = true;
break;
}
}
}
else if (recipe instanceof ShapedRecipe) {
int width = items.length == 9 ? 3 : 2;
int x = i % width;
int y = i / width;
String[] shape = ((ShapedRecipe) recipe).getShape();
if (y < shape.length && x < shape[y].length()) {
char c = shape[y].charAt(x);
RecipeChoice choice = ((ShapedRecipe) recipe).getChoiceMap().get(c);
if (isAllowedChoice(container, choice)) {
allowed = true;
}
}
}
else if (recipe instanceof CookingRecipe) {
allowed = isAllowedChoice(container, ((CookingRecipe) recipe).getInputChoice());
}
else {
allowed = true; // Shouldn't be possible?
}
if (!allowed) {
return true;
}
}
return false;
}

@EventHandler(priority = EventPriority.LOW)
public void onCraftPrepared(PrepareItemCraftEvent event) {
Recipe recipe = event.getRecipe();
if (recipe == null) {
return;
}
ItemStack[] items = event.getInventory().getMatrix();
if (shouldDenyCraft(items, recipe)) {
event.getInventory().setResult(null);
}
}

@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onItemCrafted(CraftItemEvent event) {
Recipe recipe = event.getRecipe();
ItemStack[] items = event.getInventory().getMatrix();
if (shouldDenyCraft(items, recipe)) {
event.setCancelled(true);
}
}

@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onItemCooked(BlockCookEvent event) {
ItemScriptContainer container = getItemScriptContainer(event.getSource());
if (container == null || container.allowInMaterialRecipes) {
return;
}
ItemStack[] stacks = new ItemStack[] { event.getSource() };
for (Recipe recipe : Bukkit.getRecipesFor(event.getResult())) {
if (recipe instanceof CookingRecipe && !shouldDenyCraft(stacks, recipe)) {
return;
}
}
event.setCancelled(true);
}
}

0 comments on commit ce0495c

Please sign in to comment.