feat: Added a Clear button to the Arcane Workbench. Clicking it removes all spell bindings of the item in the center slot

This commit is contained in:
WinDanesz
2023-06-28 20:51:54 +02:00
parent 85e724d88a
commit 931ca1b2c0
7 changed files with 112 additions and 1 deletions
@@ -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);
}
}
}
@@ -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;
@@ -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, <i>it is guaranteed that</i> {@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 <i>active</i> (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.
@@ -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){
@@ -51,6 +51,17 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
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<Message, IMessage> {
}
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 {
@@ -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!
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 33 KiB