diff --git a/src/main/java/kamkeel/npcs/controllers/SyncController.java b/src/main/java/kamkeel/npcs/controllers/SyncController.java index 982d7d494..8a18ebca4 100644 --- a/src/main/java/kamkeel/npcs/controllers/SyncController.java +++ b/src/main/java/kamkeel/npcs/controllers/SyncController.java @@ -108,7 +108,7 @@ public class SyncController { NBTTagList list = new NBTTagList(); NBTTagCompound compound = new NBTTagCompound(); for (RecipeCarpentry recipe : controller.globalRecipes.values()) { - list.appendTag(recipe.writeNBT()); + list.appendTag(recipe.writeNBT(false)); } compound.setTag("recipes", list); return compound; @@ -119,7 +119,7 @@ public class SyncController { NBTTagList list = new NBTTagList(); NBTTagCompound compound = new NBTTagCompound(); for (RecipeCarpentry recipe : controller.carpentryRecipes.values()) { - list.appendTag(recipe.writeNBT()); + list.appendTag(recipe.writeNBT(false)); } compound.setTag("recipes", list); return compound; @@ -130,7 +130,7 @@ public class SyncController { NBTTagList list = new NBTTagList(); NBTTagCompound compound = new NBTTagCompound(); for (RecipeAnvil recipe : controller.anvilRecipes.values()) { - list.appendTag(recipe.writeNBT()); + list.appendTag(recipe.writeNBT(false)); } compound.setTag("recipes", list); return compound; @@ -430,7 +430,9 @@ public class SyncController { return; for (int i = 0; i < list.tagCount(); i++) { - RecipeCarpentry recipe = RecipeCarpentry.read(list.getCompoundTagAt(i)); + NBTTagCompound recipeCompound = list.getCompoundTagAt(i); + RecipeCarpentry recipe = RecipeCarpentry.create(recipeCompound); + recipe.readNBT(recipeCompound); RecipeController.syncRecipes.put(recipe.id, recipe); } @@ -444,7 +446,9 @@ public class SyncController { return; for (int i = 0; i < list.tagCount(); i++) { - RecipeCarpentry recipe = RecipeCarpentry.read(list.getCompoundTagAt(i)); + NBTTagCompound recipeCompound = list.getCompoundTagAt(i); + RecipeCarpentry recipe = RecipeCarpentry.create(recipeCompound); + recipe.readNBT(recipeCompound); RecipeController.syncRecipes.put(recipe.id, recipe); } @@ -458,7 +462,8 @@ public class SyncController { return; for (int i = 0; i < list.tagCount(); i++) { - RecipeAnvil recipe = RecipeAnvil.read(list.getCompoundTagAt(i)); + RecipeAnvil recipe = new RecipeAnvil(); + recipe.readNBT(list.getCompoundTagAt(i)); RecipeController.syncAnvilRecipes.put(recipe.id, recipe); } diff --git a/src/main/java/kamkeel/npcs/network/PacketHandler.java b/src/main/java/kamkeel/npcs/network/PacketHandler.java index d1a5df29b..bcb94e80f 100644 --- a/src/main/java/kamkeel/npcs/network/PacketHandler.java +++ b/src/main/java/kamkeel/npcs/network/PacketHandler.java @@ -173,6 +173,7 @@ public class PacketHandler { REQUEST_PACKET.registerPacket(new RecipeGetPacket()); REQUEST_PACKET.registerPacket(new RecipeRemovePacket()); REQUEST_PACKET.registerPacket(new RecipeSavePacket()); + REQUEST_PACKET.registerPacket(new RecipeScriptPacket()); // Natural Spawn Packets REQUEST_PACKET.registerPacket(new NaturalSpawnGetAllPacket()); diff --git a/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java b/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java index 5503a8d24..0159fe719 100644 --- a/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java +++ b/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java @@ -192,5 +192,8 @@ public enum EnumRequestPacket { MagicGet, MagicSave, NpcMagicGet, - NpcMagicSave, Hammer, + NpcMagicSave, + Hammer, + + RecipeScript, } diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/RecipeScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/RecipeScriptPacket.java new file mode 100644 index 000000000..32b90e93e --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/RecipeScriptPacket.java @@ -0,0 +1,120 @@ +package kamkeel.npcs.network.packets.request.script; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.network.*; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.util.ByteBufUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.CustomNpcsPermissions; +import noppes.npcs.config.ConfigDebug; +import noppes.npcs.config.ConfigScript; +import noppes.npcs.controllers.RecipeController; +import noppes.npcs.controllers.data.IScriptHandler; +import noppes.npcs.controllers.data.RecipeAnvil; +import noppes.npcs.controllers.data.RecipeCarpentry; +import noppes.npcs.controllers.data.RecipeScript; + +import java.io.IOException; + +public final class RecipeScriptPacket extends AbstractPacket { + public static String packetName = "Request|RecipeScript"; + + private Action type; + private boolean anvil; + private int id; + private int tab; + private int maxSize; + private NBTTagCompound compound; + + public RecipeScriptPacket() {} + + public RecipeScriptPacket(Action type, boolean anvil, int id, int tab, int maxSize, NBTTagCompound compound) { + this.type = type; + this.anvil = anvil; + this.id = id; + this.tab = tab; + this.maxSize = maxSize; + this.compound = compound; + } + + @Override + public Enum getType() { + return EnumRequestPacket.RecipeScript; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @Override + public CustomNpcsPermissions.Permission getPermission() { + return CustomNpcsPermissions.GLOBAL_RECIPE; + } + + @SideOnly(Side.CLIENT) + @Override + public void sendData(ByteBuf out) throws IOException { + out.writeInt(type.ordinal()); + out.writeBoolean(anvil); + out.writeInt(id); + if (type == Action.SAVE) { + out.writeInt(tab); + out.writeInt(maxSize); + ByteBufUtils.writeNBT(out, compound); + } + } + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + if (!ConfigScript.canScript(player, CustomNpcsPermissions.SCRIPT)) + return; + + Action action = Action.values()[in.readInt()]; + boolean isAnvil = in.readBoolean(); + int recipeId = in.readInt(); + + if (isAnvil) { + RecipeAnvil recipe = RecipeController.Instance.getAnvilRecipe(recipeId); + if (recipe == null) + return; + handle(action, recipe.getOrCreateScriptHandler(), in, (EntityPlayerMP) player); + } else { + RecipeCarpentry recipe = RecipeController.Instance.getRecipe(recipeId); + if (recipe == null) + return; + handle(action, recipe.getOrCreateScriptHandler(), in, (EntityPlayerMP) player); + } + } + + private void handle(Action action, RecipeScript script, ByteBuf in, EntityPlayerMP player) throws IOException { + if (action == Action.GET) { + PacketUtil.getScripts(script, player); + } else { + script.saveScript(in); + if (ConfigDebug.PlayerLogging && FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { + // TODO: Log Recipe Script Saving + } + } + } + + public static void Save(boolean anvil, int id, int tab, int maxSize, NBTTagCompound compound) { + PacketClient.sendClient(new RecipeScriptPacket(Action.SAVE, anvil, id, tab, maxSize, compound)); + } + + public static void Get(boolean anvil, int id) { + PacketClient.sendClient(new RecipeScriptPacket(Action.GET, anvil, id, -1, -1, new NBTTagCompound())); + } + + private enum Action { + GET, + SAVE + } +} diff --git a/src/main/java/noppes/npcs/EventHooks.java b/src/main/java/noppes/npcs/EventHooks.java index 17f9e2dd6..622781ce9 100644 --- a/src/main/java/noppes/npcs/EventHooks.java +++ b/src/main/java/noppes/npcs/EventHooks.java @@ -19,10 +19,7 @@ import noppes.npcs.api.entity.*; import noppes.npcs.api.event.IAnimationEvent; import noppes.npcs.api.gui.ICustomGui; import noppes.npcs.api.gui.IItemSlot; -import noppes.npcs.api.handler.data.IAnimation; -import noppes.npcs.api.handler.data.IFrame; -import noppes.npcs.api.handler.data.IPlayerEffect; -import noppes.npcs.api.handler.data.IProfile; +import noppes.npcs.api.handler.data.*; import noppes.npcs.api.item.IItemCustomizable; import noppes.npcs.api.item.IItemLinked; import noppes.npcs.api.item.IItemStack; @@ -37,6 +34,7 @@ import noppes.npcs.scripted.NpcAPI; import noppes.npcs.scripted.event.*; import noppes.npcs.scripted.event.player.*; import noppes.npcs.scripted.event.player.PlayerEvent.*; +import noppes.npcs.scripted.item.ScriptItemStack; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; @@ -168,6 +166,33 @@ public class EventHooks { NpcAPI.EVENT_BUS.post(event); } + + public static boolean onRecipeScriptPre(EntityPlayer player, RecipeScript script, Object recipe, ItemStack[] items) { + IItemStack[] iitems = new IItemStack[items.length]; + for (int i = 0; i < items.length; i++) { + iitems[i] = items[i] == null ? null : NpcAPI.Instance().getIItemStack(items[i]); + } + RecipeScriptEvent.Pre event = new RecipeScriptEvent.Pre(NoppesUtilServer.getIPlayer(player), recipe, recipe instanceof IAnvilRecipe, iitems); + if (script != null) { + script.callScript(RecipeScript.ScriptType.PRE.function, event); + } + return NpcAPI.EVENT_BUS.post(event); + } + + public static ItemStack onRecipeScriptPost(EntityPlayer player, RecipeScript script, Object recipe, ItemStack[] items, ItemStack result) { + IItemStack[] iitems = new IItemStack[items.length]; + for (int i = 0; i < items.length; i++) { + iitems[i] = items[i] == null ? null : NpcAPI.Instance().getIItemStack(items[i]); + } + RecipeScriptEvent.Post event = new RecipeScriptEvent.Post(NoppesUtilServer.getIPlayer(player), recipe, recipe instanceof IAnvilRecipe, iitems, NpcAPI.Instance().getIItemStack(result)); + if (script != null) { + script.callScript(RecipeScript.ScriptType.POST.function, event); + } + NpcAPI.EVENT_BUS.post(event); + return event.getResult() == null ? null : ((ScriptItemStack) event.getCraft()).getMCItemStack(); + } + + public static void onLinkedItemVersionChange(IItemLinked item, int version, int prevVersion) { INpcScriptHandler handler = (INpcScriptHandler) item.getScriptHandler(); LinkedItemEvent.VersionChangeEvent event = new LinkedItemEvent.VersionChangeEvent(item, version, prevVersion); diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java index 4fa1dd407..57b3255c5 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java @@ -12,6 +12,7 @@ import net.minecraft.util.StatCollector; import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.SubGuiNpcAvailability; +import noppes.npcs.client.gui.script.GuiScriptRecipe; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.constants.EnumScrollData; @@ -83,10 +84,12 @@ public class GuiNpcManageRecipes extends GuiContainerNPCInterface2 implements IS buttonPos += 22; this.addButton(new GuiNpcButton(15, guiLeft + 172, buttonPos - 5, 103, 20, "availability.options")); + this.addButton(new GuiNpcButton(16, guiLeft + 172, buttonPos + 17, 103, 20, "script.scripts")); this.getButton(5).setEnabled(false); this.getButton(6).setEnabled(false); this.getButton(15).setEnabled(false); + this.getButton(16).setEnabled(false); this.addTextField(new GuiNpcTextField(0, this, fontRendererObj, guiLeft + 8, guiTop + 8, 160, 20, container.recipe.name)); this.getTextField(0).enabled = false; @@ -116,11 +119,13 @@ public class GuiNpcManageRecipes extends GuiContainerNPCInterface2 implements IS buttonPos += 22; this.addButton(new GuiNpcButton(15, guiLeft + 172, buttonPos - 5, 103, 20, "availability.options")); + this.addButton(new GuiNpcButton(16, guiLeft + 172, buttonPos + 17, 103, 20, "script.scripts")); this.getButton(7).setEnabled(false); this.getButton(8).setEnabled(false); this.getButton(9).setEnabled(false); this.getButton(15).setEnabled(false); + this.getButton(16).setEnabled(false); this.addTextField(new GuiNpcTextField(0, this, fontRendererObj, guiLeft + 8, guiTop + 8, 160, 20, container.recipeAnvil.name)); this.getTextField(0).enabled = false; @@ -200,6 +205,21 @@ public class GuiNpcManageRecipes extends GuiContainerNPCInterface2 implements IS setSubGui(new SubGuiNpcAvailability(container.recipe.availability)); } } + + if (button.id == 16) { + save(); + if (container.width == 1) { + GuiScriptRecipe gui = new GuiScriptRecipe(this, container.recipeAnvil); + gui.setWorldAndResolution(mc, width, height); + gui.initGui(); + mc.currentScreen = gui; + } else if (!container.recipe.isGlobal) { + GuiScriptRecipe gui = new GuiScriptRecipe(this, container.recipe); + gui.setWorldAndResolution(mc, width, height); + gui.initGui(); + mc.currentScreen = gui; + } + } } @Override @@ -231,13 +251,15 @@ public class GuiNpcManageRecipes extends GuiContainerNPCInterface2 implements IS @Override public void setGuiData(NBTTagCompound compound) { if (compound.hasKey("IsAnvil")) { - RecipeAnvil recipe = RecipeAnvil.read(compound); + RecipeAnvil recipe = new RecipeAnvil(); + recipe.readNBT(compound); container.setRecipe(recipe); container.width = 1; tab = 2; fixButtons(); } else { - RecipeCarpentry recipe = RecipeCarpentry.read(compound); + RecipeCarpentry recipe = RecipeCarpentry.create(compound); + recipe.readNBT(compound); container.setRecipe(recipe); fixButtons(); } @@ -273,6 +295,10 @@ public class GuiNpcManageRecipes extends GuiContainerNPCInterface2 implements IS GuiNpcButton avail = this.getButton(15); if (avail != null) avail.setEnabled(true); + + GuiNpcButton script = this.getButton(16); + if (script != null) + script.setEnabled(true); } else { getTextField(0).setText(container.recipe.name); @@ -287,6 +313,10 @@ public class GuiNpcManageRecipes extends GuiContainerNPCInterface2 implements IS GuiNpcButton avail = this.getButton(15); if (avail != null) avail.setEnabled(true); + + GuiNpcButton script = this.getButton(16); + if (script != null) + script.setEnabled(true); } } } diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptRecipe.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptRecipe.java new file mode 100644 index 000000000..60ca1fa54 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptRecipe.java @@ -0,0 +1,89 @@ +package noppes.npcs.client.gui.script; + +import kamkeel.npcs.network.packets.request.script.RecipeScriptPacket; +import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.NBTTags; +import noppes.npcs.client.gui.global.GuiNpcManageRecipes; +import noppes.npcs.controllers.ScriptContainer; +import noppes.npcs.controllers.data.RecipeAnvil; +import noppes.npcs.controllers.data.RecipeCarpentry; +import noppes.npcs.controllers.data.RecipeScript; + +import java.util.List; + +public class GuiScriptRecipe extends GuiScriptInterface { + private final GuiNpcManageRecipes parent; + private final RecipeScript scriptHandler; + private final boolean anvil; + private final int recipeId; + + public GuiScriptRecipe(GuiNpcManageRecipes parent, RecipeCarpentry recipe) { + this.parent = parent; + this.scriptHandler = recipe.getOrCreateScriptHandler(); + this.anvil = false; + this.recipeId = recipe.id; + hookList.add(RecipeScript.ScriptType.PRE.function); + hookList.add(RecipeScript.ScriptType.POST.function); + RecipeScriptPacket.Get(false, recipeId); + this.handler = scriptHandler; + } + + public GuiScriptRecipe(GuiNpcManageRecipes parent, RecipeAnvil recipe) { + this.parent = parent; + this.scriptHandler = recipe.getOrCreateScriptHandler(); + this.anvil = true; + this.recipeId = recipe.id; + hookList.add(RecipeScript.ScriptType.PRE.function); + hookList.add(RecipeScript.ScriptType.POST.function); + RecipeScriptPacket.Get(true, recipeId); + this.handler = scriptHandler; + } + + @Override + public void setGuiData(NBTTagCompound compound) { + if (!compound.hasKey("Tab")) { + scriptHandler.setLanguage(compound.getString("ScriptLanguage")); + scriptHandler.setEnabled(compound.getBoolean("ScriptEnabled")); + copiedSetGuiData(compound); + } else { + int tab = compound.getInteger("Tab"); + ScriptContainer container = new ScriptContainer(scriptHandler); + container.readFromNBT(compound.getCompoundTag("Script")); + scriptHandler.setScripts(java.util.Collections.singletonList(container)); + } + loaded = true; + initGui(); + } + + private void copiedSetGuiData(NBTTagCompound compound) { + net.minecraft.nbt.NBTTagList data = compound.getTagList("Languages", 10); + java.util.HashMap languages = new java.util.HashMap(); + for (int i = 0; i < data.tagCount(); ++i) { + NBTTagCompound comp = data.getCompoundTagAt(i); + java.util.ArrayList scripts = new java.util.ArrayList(); + net.minecraft.nbt.NBTTagList list = comp.getTagList("Scripts", 8); + for (int j = 0; j < list.tagCount(); ++j) { + scripts.add(list.getStringTagAt(j)); + } + languages.put(comp.getString("Language"), scripts); + } + this.languages = languages; + } + + @Override + public void save() { + if (loaded) { + super.save(); + List containers = scriptHandler.getScripts(); + for (int i = 0; i < containers.size(); i++) { + ScriptContainer sc = containers.get(i); + RecipeScriptPacket.Save(anvil, recipeId, i, containers.size(), sc.writeToNBT(new NBTTagCompound())); + } + NBTTagCompound data = new NBTTagCompound(); + data.setString("ScriptLanguage", scriptHandler.getLanguage()); + data.setBoolean("ScriptEnabled", scriptHandler.getEnabled()); + data.setTag("ScriptConsole", NBTTags.NBTLongStringMap(scriptHandler.getConsoleText())); + RecipeScriptPacket.Save(anvil, recipeId, -1, containers.size(), data); + } + } +} diff --git a/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java b/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java index ff873ce58..24fedbd1f 100644 --- a/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java +++ b/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java @@ -6,6 +6,7 @@ import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.*; import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import noppes.npcs.EventHooks; import noppes.npcs.api.handler.data.IAnvilRecipe; import noppes.npcs.controllers.RecipeController; import noppes.npcs.controllers.data.RecipeAnvil; @@ -25,6 +26,8 @@ public class ContainerAnvilRepair extends Container { public int repairCost = 0; public int repairMaterialConsumed = 0; + private RecipeAnvil currentRecipe; + public ContainerAnvilRepair(InventoryPlayer playerInv, World world, int x, int y, int z) { this.worldObj = world; this.posX = x; @@ -109,6 +112,8 @@ public class ContainerAnvilRepair extends Container { } } + currentRecipe = matchingRecipe; + ItemStack output = null; if (matchingRecipe != null) { if (!matchingRecipe.availability.isAvailable(player)) { @@ -272,6 +277,19 @@ public class ContainerAnvilRepair extends Container { @Override public void onPickupFromSlot(EntityPlayer player, ItemStack stack) { + RecipeAnvil recipe = container.currentRecipe; + ItemStack[] items = new ItemStack[]{ + container.anvilMatrix.getStackInRowAndColumn(0, 0), + container.anvilMatrix.getStackInRowAndColumn(1, 0) + }; + if (recipe != null) { + if (EventHooks.onRecipeScriptPre(player, recipe.getScriptHandler(), recipe, items)) { + return; + } + container.updateRepairResult(); + stack = EventHooks.onRecipeScriptPost(player, recipe.getScriptHandler(), recipe, items, stack); + } + if (player.experienceTotal < container.repairCost) { container.updateRepairResult(); return; diff --git a/src/main/java/noppes/npcs/containers/ContainerCarpentryBench.java b/src/main/java/noppes/npcs/containers/ContainerCarpentryBench.java index ef5d3a9b3..4522bab1c 100644 --- a/src/main/java/noppes/npcs/containers/ContainerCarpentryBench.java +++ b/src/main/java/noppes/npcs/containers/ContainerCarpentryBench.java @@ -8,6 +8,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.play.server.S2FPacketSetSlot; import net.minecraft.world.World; import noppes.npcs.CustomItems; +import noppes.npcs.EventHooks; import noppes.npcs.controllers.RecipeController; import noppes.npcs.controllers.data.RecipeCarpentry; @@ -20,13 +21,15 @@ public class ContainerCarpentryBench extends Container { private int posY; private int posZ; + private RecipeCarpentry currentRecipe; + public ContainerCarpentryBench(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5) { this.worldObj = par2World; this.posX = par3; this.posY = par4; this.posZ = par5; this.player = par1InventoryPlayer.player; - this.addSlotToContainer(new SlotCrafting(par1InventoryPlayer.player, this.craftMatrix, this.craftResult, 0, 133, 41)); + this.addSlotToContainer(new SlotCarpentryResult(this, par1InventoryPlayer.player, this.craftMatrix, this.craftResult, 0, 133, 41)); int var6; int var7; @@ -60,6 +63,7 @@ public class ContainerCarpentryBench extends Container { public void onCraftMatrixChanged(IInventory par1IInventory) { if (!this.worldObj.isRemote) { RecipeCarpentry recipe = RecipeController.Instance.findMatchingRecipe(this.craftMatrix); + this.currentRecipe = recipe; ItemStack item = null; if (recipe != null && recipe.availability.isAvailable(player)) { @@ -150,4 +154,33 @@ public class ContainerCarpentryBench extends Container { public boolean func_94530_a(ItemStack stack, Slot slotIn) { return slotIn.inventory != this.craftResult && super.func_94530_a(stack, slotIn); } + + // Custom result slot to handle recipe scripts + private class SlotCarpentryResult extends SlotCrafting { + private final ContainerCarpentryBench container; + private final InventoryCrafting matrix; + + public SlotCarpentryResult(ContainerCarpentryBench container, EntityPlayer player, InventoryCrafting matrix, IInventory result, int index, int x, int y) { + super(player, matrix, result, index, x, y); + this.container = container; + this.matrix = matrix; + } + + @Override + public void onPickupFromSlot(EntityPlayer player, ItemStack stack) { + RecipeCarpentry recipe = container.currentRecipe; + ItemStack[] items = new ItemStack[matrix.getSizeInventory()]; + for (int i = 0; i < items.length; i++) { + items[i] = matrix.getStackInSlot(i); + } + if (recipe != null) { + if (EventHooks.onRecipeScriptPre(player, recipe.getScriptHandler(), recipe, items)) { + container.onCraftMatrixChanged(matrix); + return; + } + stack = EventHooks.onRecipeScriptPost(player, recipe.getScriptHandler(), recipe, items, stack); + } + super.onPickupFromSlot(player, stack); + } + } } diff --git a/src/main/java/noppes/npcs/controllers/RecipeController.java b/src/main/java/noppes/npcs/controllers/RecipeController.java index 77d877b40..33a3a31d8 100644 --- a/src/main/java/noppes/npcs/controllers/RecipeController.java +++ b/src/main/java/noppes/npcs/controllers/RecipeController.java @@ -11,9 +11,7 @@ import noppes.npcs.CustomNpcs; import noppes.npcs.api.handler.IRecipeHandler; import noppes.npcs.api.handler.data.IAnvilRecipe; import noppes.npcs.api.handler.data.IRecipe; -import noppes.npcs.controllers.data.RecipeAnvil; -import noppes.npcs.controllers.data.RecipeCarpentry; -import noppes.npcs.controllers.data.RecipesDefault; +import noppes.npcs.controllers.data.*; import java.io.File; import java.io.FileInputStream; @@ -28,6 +26,9 @@ public class RecipeController implements IRecipeHandler { public HashMap carpentryRecipes = new HashMap(); public HashMap anvilRecipes = new HashMap(); + public HashMap carpentryScripts = new HashMap<>(); + public HashMap anvilScripts = new HashMap<>(); + public static RecipeController Instance; public static final int version = 1; @@ -104,12 +105,14 @@ public class RecipeController implements IRecipeHandler { for (int i = 0; i < list.tagCount(); i++) { NBTTagCompound compound = list.getCompoundTagAt(i); if (compound.hasKey("IsAnvil")) { - RecipeAnvil anvil = RecipeAnvil.read(compound); + RecipeAnvil anvil = new RecipeAnvil(); + anvil.readNBT(compound); anvilRecipes.put(anvil.id, anvil); if (anvil.id > nextAnvilId) nextAnvilId = anvil.id; } else { - RecipeCarpentry recipe = RecipeCarpentry.read(compound); + RecipeCarpentry recipe = RecipeCarpentry.create(compound); + recipe.readNBT(compound); if (recipe.isGlobal) globalRecipes.put(recipe.id, recipe); else @@ -130,13 +133,13 @@ public class RecipeController implements IRecipeHandler { File saveDir = CustomNpcs.getWorldSaveDirectory(); NBTTagList list = new NBTTagList(); for (RecipeCarpentry recipe : globalRecipes.values()) { - list.appendTag(recipe.writeNBT()); + list.appendTag(recipe.writeNBT(true)); } for (RecipeCarpentry recipe : carpentryRecipes.values()) { - list.appendTag(recipe.writeNBT()); + list.appendTag(recipe.writeNBT(true)); } for (RecipeAnvil recipe : anvilRecipes.values()) { - list.appendTag(recipe.writeNBT()); + list.appendTag(recipe.writeNBT(true)); } NBTTagCompound nbttagcompound = new NBTTagCompound(); nbttagcompound.setTag("Data", list); @@ -186,7 +189,8 @@ public class RecipeController implements IRecipeHandler { } public RecipeCarpentry saveRecipe(NBTTagCompound compound) throws IOException { - RecipeCarpentry recipe = RecipeCarpentry.read(compound); + RecipeCarpentry recipe = RecipeCarpentry.create(compound); + recipe.readNBT(compound); RecipeCarpentry current = getRecipe(recipe.id); if (current != null && !current.name.equals(recipe.name)) { @@ -212,7 +216,8 @@ public class RecipeController implements IRecipeHandler { } public RecipeAnvil saveAnvilRecipe(NBTTagCompound compound) throws IOException { - RecipeAnvil recipe = RecipeAnvil.read(compound); + RecipeAnvil recipe = new RecipeAnvil(); + recipe.readNBT(compound); RecipeAnvil current = getAnvilRecipe(recipe.id); if (current != null && !current.name.equals(recipe.name)) { @@ -270,8 +275,10 @@ public class RecipeController implements IRecipeHandler { SyncController.syncAllWorkbenchRecipes(); RecipeCarpentry carpentry = carpentryRecipes.remove(recipe.id); - if (carpentry != null) + if (carpentry != null){ + carpentryScripts.remove(recipe.id); SyncController.syncAllCarpentryRecipes(); + } saveCategories(); reloadGlobalRecipes(globalRecipes); @@ -329,7 +336,7 @@ public class RecipeController implements IRecipeHandler { recipe = RecipeCarpentry.saveRecipe(recipe, result, objects); try { - this.saveRecipe(recipe.writeNBT()); + this.saveRecipe(recipe.writeNBT(true)); } catch (Exception var7) { var7.printStackTrace(); } @@ -352,7 +359,7 @@ public class RecipeController implements IRecipeHandler { recipe.name = name; try { - this.saveRecipe(recipe.writeNBT()); + this.saveRecipe(recipe.writeNBT(true)); } catch (IOException var12) { var12.printStackTrace(); } @@ -362,7 +369,7 @@ public class RecipeController implements IRecipeHandler { public void addAnvilRecipe(String name, boolean global, ItemStack itemToRepair, ItemStack repairMaterial, int xpCost, float repairPercentage) { RecipeAnvil recipe = new RecipeAnvil(name, itemToRepair, repairMaterial, xpCost, repairPercentage); try { - this.saveAnvilRecipe(recipe.writeNBT()); + this.saveAnvilRecipe(recipe.writeNBT(true)); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/noppes/npcs/controllers/data/CustomEffect.java b/src/main/java/noppes/npcs/controllers/data/CustomEffect.java index dbe49560d..3834bef08 100644 --- a/src/main/java/noppes/npcs/controllers/data/CustomEffect.java +++ b/src/main/java/noppes/npcs/controllers/data/CustomEffect.java @@ -254,7 +254,6 @@ public class CustomEffect implements ICustomEffect { compound.setString("icon", icon); compound.setBoolean("lossOnDeath", lossOnDeath); -// if (saveScripts && scriptContainer != null) { if (saveScripts) { NBTTagCompound scriptData = new NBTTagCompound(); EffectScript handler = getScriptHandler(); diff --git a/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java b/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java index fe6fd0905..7809f63a7 100644 --- a/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java +++ b/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java @@ -2,9 +2,11 @@ package noppes.npcs.controllers.data; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.Constants; import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.handler.data.IAnvilRecipe; +import noppes.npcs.controllers.RecipeController; public class RecipeAnvil implements IAnvilRecipe { public int id = -1; @@ -21,8 +23,6 @@ public class RecipeAnvil implements IAnvilRecipe { public int xpCost; public float repairPercentage; - private boolean isAnvil = true; - public RecipeAnvil() { } @@ -34,23 +34,31 @@ public class RecipeAnvil implements IAnvilRecipe { this.repairPercentage = repairPercentage; } - public static RecipeAnvil read(NBTTagCompound compound) { - RecipeAnvil recipe = new RecipeAnvil(); - recipe.id = compound.getInteger("ID"); - recipe.name = compound.getString("Name"); - recipe.availability.readFromNBT(compound.getCompoundTag("Availability")); - recipe.xpCost = compound.getInteger("XPCost"); - recipe.repairPercentage = compound.getFloat("RepairPercentage"); - recipe.itemToRepair = NoppesUtilServer.readItem(compound.getCompoundTag("ItemToRepair")); - recipe.repairMaterial = NoppesUtilServer.readItem(compound.getCompoundTag("RepairMaterial")); - recipe.ignoreRepairMaterialNBT = compound.getBoolean("IgnoreRepairMatNBT"); - recipe.ignoreRepairItemNBT = compound.getBoolean("IgnoreRepairItemNBT"); - recipe.ignoreRepairMaterialDamage = compound.getBoolean("IgnoreRepairMatDamage"); - recipe.isAnvil = true; - return recipe; + public void readNBT(NBTTagCompound compound) { + this.id = compound.getInteger("ID"); + this.name = compound.getString("Name"); + this.availability.readFromNBT(compound.getCompoundTag("Availability")); + this.xpCost = compound.getInteger("XPCost"); + this.repairPercentage = compound.getFloat("RepairPercentage"); + this.itemToRepair = NoppesUtilServer.readItem(compound.getCompoundTag("ItemToRepair")); + this.repairMaterial = NoppesUtilServer.readItem(compound.getCompoundTag("RepairMaterial")); + this.ignoreRepairMaterialNBT = compound.getBoolean("IgnoreRepairMatNBT"); + this.ignoreRepairItemNBT = compound.getBoolean("IgnoreRepairItemNBT"); + this.ignoreRepairMaterialDamage = compound.getBoolean("IgnoreRepairMatDamage"); + + if (compound.hasKey("ScriptData", Constants.NBT.TAG_COMPOUND)) { + RecipeScript handler = new RecipeScript(); + handler.readFromNBT(compound.getCompoundTag("ScriptData")); + setScriptHandler(handler); + } } public NBTTagCompound writeNBT() { + return writeNBT(true); + } + + + public NBTTagCompound writeNBT(boolean saveScripts) { NBTTagCompound compound = new NBTTagCompound(); compound.setInteger("ID", id); compound.setString("Name", name); @@ -67,6 +75,14 @@ public class RecipeAnvil implements IAnvilRecipe { compound.setBoolean("IgnoreRepairItemNBT", ignoreRepairItemNBT); compound.setBoolean("IgnoreRepairMatDamage", ignoreRepairMaterialDamage); compound.setBoolean("IsAnvil", true); + + if (saveScripts) { + NBTTagCompound scriptData = new NBTTagCompound(); + RecipeScript handler = getScriptHandler(); + if (handler != null) + handler.writeToNBT(scriptData); + compound.setTag("ScriptData", scriptData); + } return compound; } @@ -146,7 +162,20 @@ public class RecipeAnvil implements IAnvilRecipe { this.ignoreRepairItemNBT = recipe.ignoreRepairItemNBT; this.ignoreRepairMaterialNBT = recipe.ignoreRepairMaterialNBT; this.repairPercentage = recipe.repairPercentage; - ; this.xpCost = recipe.xpCost; } + public RecipeScript getScriptHandler() { + return RecipeController.Instance.anvilScripts.get(this.id); + } + + public void setScriptHandler(RecipeScript handler) { + RecipeController.Instance.anvilScripts.put(this.id, handler); + } + + public RecipeScript getOrCreateScriptHandler() { + RecipeScript data = getScriptHandler(); + if (data == null) + setScriptHandler(data = new RecipeScript()); + return data; + } } diff --git a/src/main/java/noppes/npcs/controllers/data/RecipeCarpentry.java b/src/main/java/noppes/npcs/controllers/data/RecipeCarpentry.java index da03b548c..ff574f133 100644 --- a/src/main/java/noppes/npcs/controllers/data/RecipeCarpentry.java +++ b/src/main/java/noppes/npcs/controllers/data/RecipeCarpentry.java @@ -7,6 +7,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; import noppes.npcs.NBTTags; import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.NoppesUtilServer; @@ -24,7 +25,6 @@ public class RecipeCarpentry extends ShapedRecipes implements IRecipe { public boolean ignoreDamage = false; public boolean ignoreNBT = false; - public RecipeCarpentry(int width, int height, ItemStack[] recipe, ItemStack result) { super(width, height, recipe, result); } @@ -34,20 +34,33 @@ public class RecipeCarpentry extends ShapedRecipes implements IRecipe { this.name = name; } - public static RecipeCarpentry read(NBTTagCompound compound) { - RecipeCarpentry recipe = new RecipeCarpentry(compound.getInteger("Width"), compound.getInteger("Height"), + public static RecipeCarpentry create(NBTTagCompound compound) { + return new RecipeCarpentry(compound.getInteger("Width"), compound.getInteger("Height"), NBTTags.getItemStackArray(compound.getTagList("Materials", 10)), NoppesUtilServer.readItem(compound.getCompoundTag("Item"))); - recipe.name = compound.getString("Name"); - recipe.id = compound.getInteger("ID"); - recipe.availability.readFromNBT(compound.getCompoundTag("Availability")); - recipe.ignoreDamage = compound.getBoolean("IgnoreDamage"); - recipe.ignoreNBT = compound.getBoolean("IgnoreNBT"); - recipe.isGlobal = compound.getBoolean("Global"); + } - return recipe; + public void readNBT(NBTTagCompound compound) { + this.name = compound.getString("Name"); + this.id = compound.getInteger("ID"); + this.availability.readFromNBT(compound.getCompoundTag("Availability")); + this.ignoreDamage = compound.getBoolean("IgnoreDamage"); + this.ignoreNBT = compound.getBoolean("IgnoreNBT"); + this.isGlobal = compound.getBoolean("Global"); + + if(!isGlobal){ + if (compound.hasKey("ScriptData", Constants.NBT.TAG_COMPOUND)) { + RecipeScript handler = new RecipeScript(); + handler.readFromNBT(compound.getCompoundTag("ScriptData")); + setScriptHandler(handler); + } + } } public NBTTagCompound writeNBT() { + return writeNBT(true); + } + + public NBTTagCompound writeNBT(boolean saveScripts) { NBTTagCompound compound = new NBTTagCompound(); compound.setInteger("ID", id); compound.setInteger("Width", recipeWidth); @@ -60,6 +73,13 @@ public class RecipeCarpentry extends ShapedRecipes implements IRecipe { compound.setBoolean("Global", isGlobal); compound.setBoolean("IgnoreDamage", ignoreDamage); compound.setBoolean("IgnoreNBT", ignoreNBT); + if (saveScripts) { + NBTTagCompound scriptData = new NBTTagCompound(); + RecipeScript handler = getScriptHandler(); + if (handler != null) + handler.writeToNBT(scriptData); + compound.setTag("ScriptData", scriptData); + } return compound; } @@ -253,7 +273,7 @@ public class RecipeCarpentry extends ShapedRecipes implements IRecipe { public void save() { try { - RecipeController.Instance.saveRecipe(this.writeNBT()); + RecipeController.Instance.saveRecipe(this.writeNBT(true)); } catch (IOException var2) { } @@ -270,4 +290,19 @@ public class RecipeCarpentry extends ShapedRecipes implements IRecipe { public int getId() { return this.id; } + + public RecipeScript getScriptHandler() { + return RecipeController.Instance.carpentryScripts.get(this.id); + } + + public void setScriptHandler(RecipeScript handler) { + RecipeController.Instance.carpentryScripts.put(this.id, handler); + } + + public RecipeScript getOrCreateScriptHandler() { + RecipeScript data = getScriptHandler(); + if (data == null) + setScriptHandler(data = new RecipeScript()); + return data; + } } diff --git a/src/main/java/noppes/npcs/controllers/data/RecipeScript.java b/src/main/java/noppes/npcs/controllers/data/RecipeScript.java new file mode 100644 index 000000000..7095b02a5 --- /dev/null +++ b/src/main/java/noppes/npcs/controllers/data/RecipeScript.java @@ -0,0 +1,154 @@ +package noppes.npcs.controllers.data; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.Event; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.util.ByteBufUtils; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.util.Constants; +import noppes.npcs.config.ConfigScript; +import noppes.npcs.constants.EnumScriptType; +import noppes.npcs.controllers.ScriptContainer; +import noppes.npcs.controllers.ScriptController; + +import java.io.IOException; +import java.util.*; + +public class RecipeScript implements INpcScriptHandler { + public ScriptContainer container; + public String scriptLanguage = "ECMAScript"; + public boolean enabled = false; + + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + compound.setString("ScriptLanguage", scriptLanguage); + compound.setBoolean("ScriptEnabled", enabled); + if (container != null) + compound.setTag("ScriptContent", container.writeToNBT(new NBTTagCompound())); + return compound; + } + + public RecipeScript readFromNBT(NBTTagCompound compound) { + scriptLanguage = compound.getString("ScriptLanguage"); + enabled = compound.getBoolean("ScriptEnabled"); + if (compound.hasKey("ScriptContent", Constants.NBT.TAG_COMPOUND)) { + container = new ScriptContainer(this); + container.readFromNBT(compound.getCompoundTag("ScriptContent")); + } + return this; + } + + public boolean isEnabled() { + return this.enabled && ScriptController.HasStart && container != null && ConfigScript.ScriptingEnabled; + } + + @Override + public void callScript(EnumScriptType type, Event event) { + this.callScript(type.function, event); + } + + @Override + public void callScript(String s, Event event) { + if (!this.isEnabled()) + return; + container.run(s, event); + } + + @Override + public boolean isClient() { + return FMLCommonHandler.instance().getEffectiveSide().isClient(); + } + + @Override + public boolean getEnabled() { + return this.enabled; + } + + @Override + public void setEnabled(boolean b) { + this.enabled = b; + } + + @Override + public String getLanguage() { + return this.scriptLanguage; + } + + @Override + public void setLanguage(String s) { + this.scriptLanguage = s; + } + + @Override + public void setScripts(List list) { + if (list == null || list.isEmpty()) { + container = null; + return; + } + container = list.get(0); + } + + @Override + public List getScripts() { + if (container == null) + return new ArrayList<>(); + return Collections.singletonList(container); + } + + @Override + public String noticeString() { + return "RecipeScript"; + } + + @Override + public Map getConsoleText() { + TreeMap map = new TreeMap<>(); + int tab = 0; + for (ScriptContainer script : this.getScripts()) { + ++tab; + for (Map.Entry entry : script.console.entrySet()) { + map.put(entry.getKey(), " tab " + tab + ":\n" + entry.getValue()); + } + } + return map; + } + + @Override + public void clearConsole() { + for (ScriptContainer script : this.getScripts()) { + script.console.clear(); + } + } + + public void saveScript(ByteBuf buffer) throws IOException { + int tab = buffer.readInt(); + int totalScripts = buffer.readInt(); + if (totalScripts == 0) + this.container = null; + if (tab == 0) { + NBTTagCompound tabCompound = ByteBufUtils.readNBT(buffer); + ScriptContainer script = new ScriptContainer(this); + script.readFromNBT(tabCompound); + this.container = script; + } else { + NBTTagCompound compound = ByteBufUtils.readNBT(buffer); + this.setLanguage(compound.getString("ScriptLanguage")); + if (!ScriptController.Instance.languages.containsKey(this.getLanguage())) { + if (!ScriptController.Instance.languages.isEmpty()) { + this.setLanguage((String) ScriptController.Instance.languages.keySet().toArray()[0]); + } else { + this.setLanguage("ECMAScript"); + } + } + this.setEnabled(compound.getBoolean("ScriptEnabled")); + } + } + + public enum ScriptType { + PRE("pre"), + POST("post"); + public final String function; + ScriptType(String functionName) { + this.function = functionName; + } + } +} diff --git a/src/main/java/noppes/npcs/scripted/event/RecipeScriptEvent.java b/src/main/java/noppes/npcs/scripted/event/RecipeScriptEvent.java new file mode 100644 index 000000000..745da129f --- /dev/null +++ b/src/main/java/noppes/npcs/scripted/event/RecipeScriptEvent.java @@ -0,0 +1,66 @@ +package noppes.npcs.scripted.event; + +import cpw.mods.fml.common.eventhandler.Cancelable; +import noppes.npcs.api.handler.data.IRecipe; +import noppes.npcs.api.entity.IPlayer; +import noppes.npcs.api.item.IItemStack; +import noppes.npcs.constants.EnumScriptType; +import noppes.npcs.controllers.data.RecipeScript; +import noppes.npcs.scripted.NpcAPI; +import noppes.npcs.scripted.event.player.PlayerEvent; + +public class RecipeScriptEvent extends PlayerEvent { + public final Object recipe; + public final IItemStack[] items; + public final boolean isAnvil; + + public RecipeScriptEvent(IPlayer player, Object recipe, boolean anvil, IItemStack[] items) { + super(player); + this.recipe = recipe; + this.items = items; + this.isAnvil = anvil; + } + + public Object getRecipe() { + return recipe; + } + + public IItemStack[] getItems() { + return items; + } + + public boolean isAnvil() { + return isAnvil; + } + + @Cancelable + public static class Pre extends RecipeScriptEvent { + public Pre(IPlayer player, Object recipe, boolean isAnvil, IItemStack[] items) { + super(player, recipe, isAnvil, items); + } + public String getHookName() { + return RecipeScript.ScriptType.PRE.function; + } + } + + public static class Post extends RecipeScriptEvent { + private IItemStack result; + + public Post(IPlayer player, Object recipe, boolean isAnvil, IItemStack[] items, IItemStack result) { + super(player, recipe, isAnvil, items); + this.result = result; + } + + public IItemStack getCraft() { + return result; + } + + public void setResult(IItemStack stack) { + this.result = stack; + } + + public String getHookName() { + return RecipeScript.ScriptType.POST.function; + } + } +}