diff --git a/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java b/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java
index 76445c10..78d1e66b 100644
--- a/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java
+++ b/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java
@@ -93,6 +93,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
private ContainerArcaneWorkbench arcaneWorkbenchContainer;
private GuiButton applyBtn;
+ private GuiButton clearBtn;
private GuiButton[] sortButtons = new GuiButton[3];
private GuiTextField searchField;
@@ -126,6 +127,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
this.buttonList.clear();
this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width / 2 + 64, this.height / 2 + 3));
+ this.buttonList.add(this.clearBtn = new GuiButtonClear(0, this.width / 2 + 64, this.height / 2 - 16));
this.buttonList.add(sortButtons[0] = new GuiButtonSpellSort(1, this.guiLeft - 44, this.guiTop + 8, ISpellSortable.SortType.TIER, arcaneWorkbenchContainer, this));
this.buttonList.add(sortButtons[1] = new GuiButtonSpellSort(2, this.guiLeft - 31, this.guiTop + 8, ISpellSortable.SortType.ELEMENT, arcaneWorkbenchContainer, this));
this.buttonList.add(sortButtons[2] = new GuiButtonSpellSort(3, this.guiLeft - 18, this.guiTop + 8, ISpellSortable.SortType.ALPHABETICAL, arcaneWorkbenchContainer, this));
@@ -205,6 +207,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
// Show/hide the relevant gui elements
this.applyBtn.enabled = centreSlot.getHasStack();
+ this.clearBtn.enabled = centreSlot.getHasStack() && centreSlot.getStack().getItem() instanceof IWorkbenchItem && ((IWorkbenchItem) centreSlot.getStack().getItem()).isClearable();
for(GuiButton button : this.sortButtons) button.visible = arcaneWorkbenchContainer.hasBookshelves();
this.searchField.setVisible(arcaneWorkbenchContainer.hasBookshelves());
@@ -444,6 +447,17 @@ public class GuiArcaneWorkbench extends GuiContainer {
animationTimer = 20;
}
+ if(button == clearBtn){
+ // Packet building
+ IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.CLEAR_BUTTON);
+ WizardryPacketHandler.net.sendToServer(msg);
+ // Sound
+ Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(
+ WizardrySounds.BLOCK_ARCANE_WORKBENCH_SPELLBIND, 0.8f));
+ // Animation
+ animationTimer = 20;
+ }
+
if(button instanceof GuiButtonSpellSort) this.arcaneWorkbenchContainer.setSortType(((GuiButtonSpellSort)button).sortType);
}
}
@@ -1006,4 +1020,36 @@ public class GuiArcaneWorkbench extends GuiContainer {
}
}
+ private static class GuiButtonClear extends GuiButton {
+
+ public GuiButtonClear(int id, int x, int y){
+ super(id, x, y, 16, 16, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.clear"));
+ }
+
+ @Override
+ public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
+
+ // Whether the button is highlighted
+ this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
+
+ int k = 72;
+ int l = 236;
+ //int colour = 14737632;
+
+ if(this.enabled){
+ if(this.hovered){
+ k += this.width * 2;
+ //colour = 16777120;
+ }
+ }else{
+ k += this.width;
+ //colour = 10526880;
+ }
+
+ DrawingUtils.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT);
+ //this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.x + this.width / 2,
+ // this.y + (this.height - 8) / 2, colour);
+ }
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/electroblob/wizardry/inventory/ContainerArcaneWorkbench.java b/src/main/java/electroblob/wizardry/inventory/ContainerArcaneWorkbench.java
index aa7af8f9..e9653f62 100644
--- a/src/main/java/electroblob/wizardry/inventory/ContainerArcaneWorkbench.java
+++ b/src/main/java/electroblob/wizardry/inventory/ContainerArcaneWorkbench.java
@@ -452,6 +452,24 @@ public class ContainerArcaneWorkbench extends Container implements ISpellSortabl
}
}
+ /**
+ * Called (via {@link electroblob.wizardry.packet.PacketControlInput PacketControlInput}) when the clear button in
+ * the arcane workbench GUI is pressed.
+ */
+ // As of 2.1, for the sake of events and neatness of code, this was moved here from TileEntityArcaneWorkbench.
+ // As of 4.2, the spell binding/charging/upgrading code was delegated (via IWorkbenchItem) to the items themselves.
+ public void onClearButtonPressed(EntityPlayer player){
+
+ Slot centre = this.getSlot(CENTRE_SLOT);
+
+ if(centre.getStack().getItem() instanceof IWorkbenchItem){ // Should always be true, but no harm in checking.
+
+ Slot[] spellBooks = this.inventorySlots.subList(0, 8).toArray(new Slot[8]);
+
+ ((IWorkbenchItem) centre.getStack().getItem()).onClearButtonPressed(player, centre, this.getSlot(CRYSTAL_SLOT), this.getSlot(UPGRADE_SLOT), spellBooks);
+ }
+ }
+
/** Scrolls to the given row number. */
public void scrollTo(int row){
this.scroll = row;
diff --git a/src/main/java/electroblob/wizardry/item/IWorkbenchItem.java b/src/main/java/electroblob/wizardry/item/IWorkbenchItem.java
index 146246e3..6a0a0591 100644
--- a/src/main/java/electroblob/wizardry/item/IWorkbenchItem.java
+++ b/src/main/java/electroblob/wizardry/item/IWorkbenchItem.java
@@ -55,6 +55,26 @@ public interface IWorkbenchItem {
*/
boolean onApplyButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks);
+ /**
+ * Called when this item is in the central slot of an arcane workbench and the apply clear is pressed. Items must
+ * implement this method to define what happens when the apply button is pressed.
+ * @param player The player that pressed the apply button.
+ * @param centre The central slot in the arcane workbench. This slot will always contain a stack of the implementing
+ * item, or in other words, it is guaranteed that {@code this == centre.getStack().getItem()}.
+ * @param crystals The magic crystal slot of the arcane workbench.
+ * @param upgrade The upgrade slot of the arcane workbench.
+ * @param spellBooks An array of the active (visible) spell book slots in the arcane workbench. The length of
+ * the array will be equal to the value returned by {@link IWorkbenchItem#getSpellSlotCount(ItemStack)}.
+ * */
+ default void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){};
+
+ /**
+ * Must be overridden in the item class to make the clear button in the Arcane Workbench clickable.
+ * */
+ default boolean isClearable() {
+ return false;
+ }
+
/**
* Returns whether the tooltip (dark grey box) should be drawn when this item is in an arcane workbench. Only
* called client-side.
diff --git a/src/main/java/electroblob/wizardry/item/ItemWand.java b/src/main/java/electroblob/wizardry/item/ItemWand.java
index bf380e8f..d55dd9de 100644
--- a/src/main/java/electroblob/wizardry/item/ItemWand.java
+++ b/src/main/java/electroblob/wizardry/item/ItemWand.java
@@ -28,6 +28,7 @@ import net.minecraft.inventory.Slot;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
@@ -881,6 +882,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
return changed;
}
+ @Override
+ public void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){
+ ItemStack stack = centre.getStack();
+ if (stack.hasTagCompound() && stack.getTagCompound().hasKey(WandHelper.SPELL_ARRAY_KEY)) {
+ NBTTagCompound nbt = stack.getTagCompound();
+ nbt.removeTag(WandHelper.SPELL_ARRAY_KEY);
+ stack.setTagCompound(nbt);
+ }
+ }
+
+ @Override
+ public boolean isClearable() { return true; }
+
// hitEntity is only called server-side, so we'll have to use events
@SubscribeEvent
public static void onAttackEntityEvent(AttackEntityEvent event){
diff --git a/src/main/java/electroblob/wizardry/packet/PacketControlInput.java b/src/main/java/electroblob/wizardry/packet/PacketControlInput.java
index 0a72784f..5d3d28d3 100644
--- a/src/main/java/electroblob/wizardry/packet/PacketControlInput.java
+++ b/src/main/java/electroblob/wizardry/packet/PacketControlInput.java
@@ -51,6 +51,17 @@ public class PacketControlInput implements IMessageHandler {
break;
+ case CLEAR_BUTTON:
+
+ if(!(player.openContainer instanceof ContainerArcaneWorkbench)){
+ Wizardry.logger.warn("Received a PacketControlInput, but the player that sent it was not " +
+ "currently using an arcane workbench. This should not happen!");
+ }else{
+ ((ContainerArcaneWorkbench)player.openContainer).onClearButtonPressed(player);
+ }
+
+ break;
+
case NEXT_SPELL_KEY:
if(wand.getItem() instanceof ISpellCastingItem){
@@ -133,7 +144,7 @@ public class PacketControlInput implements IMessageHandler {
}
public enum ControlType {
- APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE
+ APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE, CLEAR_BUTTON
}
public static class Message implements IMessage {
diff --git a/src/main/resources/assets/ebwizardry/lang/en_us.lang b/src/main/resources/assets/ebwizardry/lang/en_us.lang
index 64c41b5a..845761d9 100644
--- a/src/main/resources/assets/ebwizardry/lang/en_us.lang
+++ b/src/main/resources/assets/ebwizardry/lang/en_us.lang
@@ -882,6 +882,7 @@ container.ebwizardry\:arcane_workbench.sort_tier=Sort by Tier
container.ebwizardry\:arcane_workbench.sort_element=Sort by Element
container.ebwizardry\:arcane_workbench.sort_alphabetical=Sort Alphabetically
container.ebwizardry\:arcane_workbench.search_tooltip=%1$sSearch Tips\n\ntier=%2$s, %1$st=%2$s: match tiers\n%1$selement=%2$s, %1$se=%2$s: match elements\n%1$stype=%2$s, %1$sp=%2$s: match spell types\n%1$sdiscovered=true/false%2$s, %1$sd=t/f%2$s: include only (un)discovered\n%1$smodid=%2$s, %1$sm=%2$s: match mod IDs\n\nSeparate multiple values with %1$s,%2$s\nSeparate multiple criteria with %1$s;
+container.ebwizardry\:arcane_workbench.clear=Clear Spell Slots
container.ebwizardry\:bookshelf=Bookshelf
@@ -1370,6 +1371,7 @@ forfeit.ebwizardry\:bury_self=The ground collapses beneath you!
forfeit.ebwizardry\:spill_inventory=Your items spill themselves everywhere!
forfeit.ebwizardry\:teleport_self=You are instantly teleported somewhere!
+forfeit.ebwizardry\:teleport_self_large_distance=You are instantly teleported somewhere far away!
forfeit.ebwizardry\:levitate_self=You begin to float upwards helplessly!
forfeit.ebwizardry\:vex_horde=A horde of vexes materializes around you!
forfeit.ebwizardry\:black_hole=A swirling vortex appears in front of you!
diff --git a/src/main/resources/assets/ebwizardry/textures/gui/container/arcane_workbench.png b/src/main/resources/assets/ebwizardry/textures/gui/container/arcane_workbench.png
index 2261cfa3..bb6b7fb7 100644
Binary files a/src/main/resources/assets/ebwizardry/textures/gui/container/arcane_workbench.png and b/src/main/resources/assets/ebwizardry/textures/gui/container/arcane_workbench.png differ