From c6221588182ae62957d1aeb78c04f97231fbf0b7 Mon Sep 17 00:00:00 2001 From: Electroblob77 <35599699+Electroblob77@users.noreply.github.com> Date: Sun, 12 Apr 2020 18:35:30 +0100 Subject: [PATCH] Fix syncing of everything --- .../electroblob/wizardry/CommonProxy.java | 15 +++++ .../wizardry/block/BlockBookshelf.java | 62 +++++++++++++++++++ .../wizardry/client/ClientProxy.java | 16 +++++ .../wizardry/client/gui/GuiLectern.java | 12 ++-- .../client/model/BakedModelBookshelf.java | 4 +- .../inventory/ContainerArcaneWorkbench.java | 10 +-- .../tileentity/TileEntityArcaneWorkbench.java | 19 +++--- .../tileentity/TileEntityBookshelf.java | 20 +++--- .../tileentity/TileEntityLectern.java | 2 +- 9 files changed, 124 insertions(+), 36 deletions(-) diff --git a/src/main/java/electroblob/wizardry/CommonProxy.java b/src/main/java/electroblob/wizardry/CommonProxy.java index 947a6e93..5d79bd80 100644 --- a/src/main/java/electroblob/wizardry/CommonProxy.java +++ b/src/main/java/electroblob/wizardry/CommonProxy.java @@ -1,5 +1,7 @@ package electroblob.wizardry; +import electroblob.wizardry.block.BlockBookshelf; +import electroblob.wizardry.inventory.ContainerArcaneWorkbench; import electroblob.wizardry.item.ItemSpectralBow; import electroblob.wizardry.packet.*; import electroblob.wizardry.registry.WizardryItems; @@ -261,4 +263,17 @@ public class CommonProxy { public Set getSpellHUDSkins(){ return null; } + + /** Notifies nearby players of a bookshelf change, causing any lectern or arcane workbench GUI (client-side) or + * container (both sides) to refresh its linked bookshelves (does not send packets). */ + public void notifyBookshelfChange(World world, BlockPos pos){ + for(EntityPlayer player : world.playerEntities){ + if(player.getDistanceSq(pos) < BlockBookshelf.PLAYER_NOTIFY_RANGE * BlockBookshelf.PLAYER_NOTIFY_RANGE){ + if(player.openContainer instanceof ContainerArcaneWorkbench){ + ((ContainerArcaneWorkbench)player.openContainer).refreshBookshelfSlots(); + } + } + } + } + } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/block/BlockBookshelf.java b/src/main/java/electroblob/wizardry/block/BlockBookshelf.java index 42d6317e..2c50e8b5 100644 --- a/src/main/java/electroblob/wizardry/block/BlockBookshelf.java +++ b/src/main/java/electroblob/wizardry/block/BlockBookshelf.java @@ -12,6 +12,7 @@ import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.BlockFaceShape; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; @@ -19,19 +20,30 @@ import net.minecraft.inventory.InventoryHelper; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; +import net.minecraft.world.IWorldEventListener; import net.minecraft.world.World; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.Properties; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.apache.commons.lang3.ArrayUtils; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; +@Mod.EventBusSubscriber public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvider { + /** When a bookshelf block (of any kind specified in the config) is added or removed, players within this range will + * be notified of the change. */ + public static final double PLAYER_NOTIFY_RANGE = 32; public static final int SLOT_COUNT = 12; public static final UnlistedPropertyBool[] BOOKS = new UnlistedPropertyBool[SLOT_COUNT]; @@ -65,6 +77,11 @@ public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvid return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); } + @Override + public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state){ + super.onBlockAdded(worldIn, pos, state); + } + @Override public void breakBlock(World world, BlockPos pos, IBlockState block){ @@ -172,4 +189,49 @@ public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvid } + @SubscribeEvent + public static void onWorldLoadEvent(WorldEvent.Load event){ + event.getWorld().addEventListener(Listener.instance); + } + + @SubscribeEvent + public static void onWorldUnloadEvent(WorldEvent.Unload event){ + event.getWorld().removeEventListener(Listener.instance); + } + + public static class Listener implements IWorldEventListener { + + public static final Listener instance = new Listener(); + + private Listener(){} + + @Override + public void notifyBlockUpdate(World world, BlockPos pos, IBlockState oldState, IBlockState newState, int flags){ + + if(oldState == newState) return; // Probably won't happen but just in case + + if(Settings.containsMetaBlock(Wizardry.settings.bookshelfBlocks, oldState) // Bookshelf removed + || Settings.containsMetaBlock(Wizardry.settings.bookshelfBlocks, newState)){ // Bookshelf placed + // It is also possible (with commands) for a bookshelf to be replaced with another bookshelf, in which + // case this should still just be called once + Wizardry.proxy.notifyBookshelfChange(world, pos); + } + + } + + // Dummy implementations + @Override public void notifyLightSet(BlockPos pos){} + @Override public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2){} + @Override public void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch){} + @Override public void playRecord(SoundEvent soundIn, BlockPos pos){} + @Override public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int... parameters){} + @Override public void spawnParticle(int id, boolean ignoreRange, boolean minimiseParticleLevel, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, int... parameters){} + @Override public void onEntityAdded(Entity entityIn){} + @Override public void onEntityRemoved(Entity entityIn){} + @Override public void broadcastSound(int soundID, BlockPos pos, int data){} + @Override public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data){} + @Override public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress){} + + } + } diff --git a/src/main/java/electroblob/wizardry/client/ClientProxy.java b/src/main/java/electroblob/wizardry/client/ClientProxy.java index 64e746d7..df4b4a80 100644 --- a/src/main/java/electroblob/wizardry/client/ClientProxy.java +++ b/src/main/java/electroblob/wizardry/client/ClientProxy.java @@ -2,9 +2,11 @@ package electroblob.wizardry.client; import electroblob.wizardry.CommonProxy; import electroblob.wizardry.Wizardry; +import electroblob.wizardry.block.BlockBookshelf; import electroblob.wizardry.client.audio.MovingSoundEntity; import electroblob.wizardry.client.audio.SoundLoop; import electroblob.wizardry.client.audio.SoundLoopSpell; +import electroblob.wizardry.client.gui.GuiLectern; import electroblob.wizardry.client.gui.GuiSpellDisplay; import electroblob.wizardry.client.gui.config.NamedBooleanEntry; import electroblob.wizardry.client.gui.config.SpellHUDSkinChooserEntry; @@ -202,6 +204,20 @@ public class ClientProxy extends CommonProxy { return GuiSpellDisplay.getSkinKeys(); } + @Override + public void notifyBookshelfChange(World world, BlockPos pos){ + + super.notifyBookshelfChange(world, pos); + + EntityPlayer player = Minecraft.getMinecraft().player; + + if(player.getDistanceSq(pos) < BlockBookshelf.PLAYER_NOTIFY_RANGE * BlockBookshelf.PLAYER_NOTIFY_RANGE){ + if(Minecraft.getMinecraft().currentScreen instanceof GuiLectern){ + ((GuiLectern)Minecraft.getMinecraft().currentScreen).refreshAvailableSpells(); + } + } + } + // SECTION Items // =============================================================================================================== diff --git a/src/main/java/electroblob/wizardry/client/gui/GuiLectern.java b/src/main/java/electroblob/wizardry/client/gui/GuiLectern.java index c795d842..4a6571f4 100644 --- a/src/main/java/electroblob/wizardry/client/gui/GuiLectern.java +++ b/src/main/java/electroblob/wizardry/client/gui/GuiLectern.java @@ -127,8 +127,6 @@ public class GuiLectern extends GuiSpellInfo implements ISpellSortable { super.initGui(); - updateAvailableSpells(); - final int left = this.width / 2 - this.xSize / 2; final int top = this.height / 2 - this.ySize / 2; @@ -181,8 +179,7 @@ public class GuiLectern extends GuiSpellInfo implements ISpellSortable { this.searchField.setCanLoseFocus(false); this.searchField.setFocused(true); - updateMatchingSpells(); - updateButtonVisiblity(); + refreshAvailableSpells(); // Must be done last } @@ -383,9 +380,9 @@ public class GuiLectern extends GuiSpellInfo implements ISpellSortable { .collect(Collectors.toList()); } - // TODO: Call this when a bookshelf is added or removed // TODO: Config option to always display all spells when in creative - private void updateAvailableSpells(){ + /** Called on initialisation and whenever a bookshelf is added or removed, to update the list of spells. */ + public void refreshAvailableSpells(){ availableSpells.clear(); @@ -405,6 +402,9 @@ public class GuiLectern extends GuiSpellInfo implements ISpellSortable { if(!availableSpells.contains(currentSpell)) currentSpell = Spells.none; // TODO: Do we want this? + updateMatchingSpells(); + updateButtonVisiblity(); + } private class GuiButtonLocateBook extends GuiButton { diff --git a/src/main/java/electroblob/wizardry/client/model/BakedModelBookshelf.java b/src/main/java/electroblob/wizardry/client/model/BakedModelBookshelf.java index 4e682688..c100b369 100644 --- a/src/main/java/electroblob/wizardry/client/model/BakedModelBookshelf.java +++ b/src/main/java/electroblob/wizardry/client/model/BakedModelBookshelf.java @@ -36,7 +36,9 @@ public class BakedModelBookshelf implements IBakedModel { IExtendedBlockState extendedState = (IExtendedBlockState)state; for(int i = 0; i getInventoryStackLimit()){ stack.setCount(getInventoryStackLimit()); @@ -199,12 +202,10 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory, NBTTagList itemList = new NBTTagList(); for(int i = 0; i < getSizeInventory(); i++){ ItemStack stack = getStackInSlot(i); - if(!stack.isEmpty()){ - NBTTagCompound tag = new NBTTagCompound(); - tag.setByte("Slot", (byte)i); - stack.writeToNBT(tag); - itemList.appendTag(tag); - } + NBTTagCompound tag = new NBTTagCompound(); + tag.setByte("Slot", (byte)i); + stack.writeToNBT(tag); + itemList.appendTag(tag); } NBTExtras.storeTagSafely(tagCompound, "Inventory", itemList); diff --git a/src/main/java/electroblob/wizardry/tileentity/TileEntityBookshelf.java b/src/main/java/electroblob/wizardry/tileentity/TileEntityBookshelf.java index ce513635..c469e62d 100644 --- a/src/main/java/electroblob/wizardry/tileentity/TileEntityBookshelf.java +++ b/src/main/java/electroblob/wizardry/tileentity/TileEntityBookshelf.java @@ -30,7 +30,7 @@ public class TileEntityBookshelf extends TileEntity implements IInventory, ITick /** Called to manually sync the tile entity with clients. */ public void sync(){ - this.world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); + this.world.markAndNotifyBlock(pos, null, world.getBlockState(pos), world.getBlockState(pos), 3); } @Override @@ -82,16 +82,15 @@ public class TileEntityBookshelf extends TileEntity implements IInventory, ITick @Override public void setInventorySlotContents(int slot, ItemStack stack){ - - inventory.set(slot, stack); - //ItemStack previous = inventory.set(slot, stack); + ItemStack previous = inventory.set(slot, stack); - //if(previous.isEmpty() != stack.isEmpty()) this.sync(); + if(previous.isEmpty() != stack.isEmpty()) this.sync(); if(!stack.isEmpty() && stack.getCount() > getInventoryStackLimit()){ stack.setCount(getInventoryStackLimit()); } + } @Override @@ -157,12 +156,10 @@ public class TileEntityBookshelf extends TileEntity implements IInventory, ITick NBTTagList itemList = new NBTTagList(); for(int i = 0; i < getSizeInventory(); i++){ ItemStack stack = getStackInSlot(i); - if(!stack.isEmpty()){ - NBTTagCompound tag = new NBTTagCompound(); - tag.setByte("Slot", (byte)i); - stack.writeToNBT(tag); - itemList.appendTag(tag); - } + NBTTagCompound tag = new NBTTagCompound(); + tag.setByte("Slot", (byte)i); + stack.writeToNBT(tag); + itemList.appendTag(tag); } NBTExtras.storeTagSafely(tagCompound, "Inventory", itemList); @@ -182,6 +179,7 @@ public class TileEntityBookshelf extends TileEntity implements IInventory, ITick @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt){ readFromNBT(pkt.getNbtCompound()); + Wizardry.proxy.notifyBookshelfChange(world, pos); } // What are all these for? diff --git a/src/main/java/electroblob/wizardry/tileentity/TileEntityLectern.java b/src/main/java/electroblob/wizardry/tileentity/TileEntityLectern.java index 2cbdd8e6..bcaded49 100644 --- a/src/main/java/electroblob/wizardry/tileentity/TileEntityLectern.java +++ b/src/main/java/electroblob/wizardry/tileentity/TileEntityLectern.java @@ -64,7 +64,7 @@ public class TileEntityLectern extends TileEntity implements ITickable { /** Called to manually sync the tile entity with clients. */ public void sync(){ - this.world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3); + this.world.markAndNotifyBlock(pos, null, world.getBlockState(pos), world.getBlockState(pos), 3); } @Override