Allow any book to be placed in a bookshelf
- Modifies the bookshelf model and blockstate to choose a texture dynamically based on the book item - Changes bookshelf slots to accept all books from wizardry and vanilla minecraft by default - Adds a couple of hooks to allow addons to register their own book items and model textures - Adds a config option to allow modpack makers to add more book items
This commit is contained in:
@@ -296,6 +296,8 @@ public final class Settings {
|
||||
Wizardry.MODID + ":acacia_bookshelf",
|
||||
Wizardry.MODID + ":dark_oak_bookshelf"
|
||||
);
|
||||
/** <b>[Synchronised]</b> List of registry names of items that can be placed in a bookshelf. */
|
||||
public Pair<ResourceLocation, Short>[] bookItems = parseItemMetaStrings();
|
||||
|
||||
// Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys
|
||||
// its own values for these, and changing them on a dedicated server will have no effect.
|
||||
@@ -735,6 +737,11 @@ public final class Settings {
|
||||
bookshelfBlocks = parseItemMetaStrings(property.getStringList());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "bookItems", new String[0], "List of registry names of items which can be placed in a bookshelf, in addition to the defaults. Item names are not case sensitive. For mod items, prefix with the mod ID (e.g. thaumcraft:thaumonomicon).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".book_items");
|
||||
bookItems = parseItemMetaStrings(property.getStringList());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "bookshelfSearchRadius", 4,
|
||||
"The maximum number of blocks a bookshelf can be from an arcane workbench or lectern to be able to link to it.",
|
||||
1, 10);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.command.CommandCastSpell;
|
||||
import electroblob.wizardry.command.CommandDiscoverSpell;
|
||||
import electroblob.wizardry.command.CommandSetAlly;
|
||||
@@ -8,6 +9,7 @@ import electroblob.wizardry.data.DispenserCastingData;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration;
|
||||
import electroblob.wizardry.integration.baubles.WizardryBaublesIntegration;
|
||||
import electroblob.wizardry.inventory.ContainerBookshelf;
|
||||
import electroblob.wizardry.misc.Forfeit;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.*;
|
||||
@@ -123,6 +125,7 @@ public class Wizardry {
|
||||
WizardryLoot.register();
|
||||
WizardryAdvancementTriggers.register();
|
||||
Forfeit.register();
|
||||
BlockBookshelf.registerStandardBookModelTextures();
|
||||
|
||||
// Client-side stuff (via proxies)
|
||||
proxy.registerRenderers();
|
||||
@@ -159,6 +162,8 @@ public class Wizardry {
|
||||
WizardryPacketHandler.initPackets();
|
||||
|
||||
// Post-registry extras
|
||||
BlockBookshelf.compileBookModelTextures();
|
||||
ContainerBookshelf.initDefaultBookItems();
|
||||
WizardryItems.populateWandMap();
|
||||
WizardryItems.populateArmourMap();
|
||||
WizardryItems.registerDispenseBehaviours();
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
package electroblob.wizardry.block;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.WizardryGuiHandler;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import electroblob.wizardry.tileentity.TileEntityBookshelf;
|
||||
import net.minecraft.block.BlockHorizontal;
|
||||
import net.minecraft.block.ITileEntityProvider;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyInteger;
|
||||
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.init.Items;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.item.Item;
|
||||
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.*;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.IWorldEventListener;
|
||||
@@ -31,12 +32,17 @@ import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvider {
|
||||
@@ -46,13 +52,11 @@ public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvid
|
||||
public static final double PLAYER_NOTIFY_RANGE = 32;
|
||||
public static final int SLOT_COUNT = 12;
|
||||
|
||||
public static final UnlistedPropertyBool[] BOOKS = new UnlistedPropertyBool[SLOT_COUNT];
|
||||
public static final UnlistedPropertyInt[] BOOKS = new UnlistedPropertyInt[SLOT_COUNT];
|
||||
|
||||
static {
|
||||
for(int i=0; i<SLOT_COUNT; i++){
|
||||
BOOKS[i] = new UnlistedPropertyBool("book" + i);
|
||||
}
|
||||
}
|
||||
private static final Map<Supplier<Item>, ResourceLocation> BOOK_TEXTURE_MAP = new HashMap<>();
|
||||
private static ImmutableList<Item> bookItems;
|
||||
private static ImmutableList<ResourceLocation> bookTextures;
|
||||
|
||||
public BlockBookshelf(){
|
||||
super(Material.WOOD);
|
||||
@@ -115,9 +119,19 @@ public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvid
|
||||
IExtendedBlockState s = (IExtendedBlockState)super.getExtendedState(state, world, pos);
|
||||
|
||||
if(world.getTileEntity(pos) instanceof TileEntityBookshelf){
|
||||
|
||||
TileEntityBookshelf tileentity = ((TileEntityBookshelf)world.getTileEntity(pos));
|
||||
|
||||
for(int i = 0; i < tileentity.getSizeInventory(); i++){
|
||||
s = s.withProperty(BOOKS[i], !tileentity.getStackInSlot(i).isEmpty());
|
||||
|
||||
if(tileentity.getStackInSlot(i).isEmpty()){
|
||||
s = s.withProperty(BOOKS[i], bookItems.size());
|
||||
|
||||
}else{
|
||||
Item item = tileentity.getStackInSlot(i).getItem();
|
||||
// Default to the standard spell book texture, which will always be the first item in the list
|
||||
s = s.withProperty(BOOKS[i], bookItems.contains(item) ? bookItems.indexOf(item) : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,14 +190,71 @@ public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvid
|
||||
return tileentity != null && tileentity.receiveClientEvent(id, param);
|
||||
}
|
||||
|
||||
// Copied from BlockFluidBase, only reason it exists is because of java's weird restrictions on generics
|
||||
private static final class UnlistedPropertyBool extends Properties.PropertyAdapter<Boolean> {
|
||||
/** Returns the list of book textures, in ID order. */
|
||||
public static ImmutableList<ResourceLocation> getBookTextures(){
|
||||
// ModelBookshelf calls this before init() so we need to return the map values as a fallback
|
||||
return bookTextures == null ? ImmutableList.copyOf(BOOK_TEXTURE_MAP.values()) : bookTextures;
|
||||
}
|
||||
|
||||
public UnlistedPropertyBool(String name){
|
||||
super(PropertyBool.create(name));
|
||||
/** Called during block registration to initialise the block properties for each book. */
|
||||
public static void initBookProperties(){
|
||||
for(int i=0; i<SLOT_COUNT; i++){
|
||||
BOOKS[i] = new UnlistedPropertyInt("book" + i);
|
||||
}
|
||||
}
|
||||
|
||||
// Based on BlockFluid's UnlistedPropertyBool; this is only needed because of Java's weird restrictions on generics
|
||||
private static final class UnlistedPropertyInt extends Properties.PropertyAdapter<Integer> {
|
||||
|
||||
public UnlistedPropertyInt(String name){
|
||||
// Max is inclusive here, but we're using the largest value for no book so there's an extra one (can't use -1)
|
||||
super(PropertyInteger.create(name, 0, BOOK_TEXTURE_MAP.size()));
|
||||
}
|
||||
}
|
||||
|
||||
/** Called from {@link Wizardry#init(FMLInitializationEvent)} to retrieve the actual book items and compile them
|
||||
* and their textures into immutable lists. */
|
||||
public static void compileBookModelTextures(){
|
||||
|
||||
ImmutableList.Builder<Item> itemListBuider = ImmutableList.builder();
|
||||
ImmutableList.Builder<ResourceLocation> textureListBuilder = ImmutableList.builder();
|
||||
|
||||
for(Map.Entry<Supplier<Item>, ResourceLocation> entry : BOOK_TEXTURE_MAP.entrySet()){
|
||||
itemListBuider.add(entry.getKey().get());
|
||||
textureListBuilder.add(entry.getValue());
|
||||
}
|
||||
|
||||
bookItems = itemListBuider.build();
|
||||
bookTextures = textureListBuilder.build();
|
||||
}
|
||||
|
||||
/** Called from {@link Wizardry#preInit(FMLPreInitializationEvent)} to register the default set of book textures. */
|
||||
public static void registerStandardBookModelTextures(){
|
||||
// Vanilla Minecraft books
|
||||
// Regular brown books are the default so they're registered first
|
||||
registerBookModelTexture(() -> Items.BOOK, new ResourceLocation(Wizardry.MODID, "blocks/books_brown"));
|
||||
registerBookModelTexture(() -> Items.WRITABLE_BOOK, new ResourceLocation(Wizardry.MODID, "blocks/books_brown"));
|
||||
registerBookModelTexture(() -> Items.WRITTEN_BOOK, new ResourceLocation(Wizardry.MODID, "blocks/books_brown"));
|
||||
registerBookModelTexture(() -> Items.ENCHANTED_BOOK, new ResourceLocation(Wizardry.MODID, "blocks/books_enchanted"));
|
||||
// Wizardry books
|
||||
registerBookModelTexture(() -> WizardryItems.spell_book, new ResourceLocation(Wizardry.MODID, "blocks/books_red"));
|
||||
registerBookModelTexture(() -> WizardryItems.wizard_handbook, new ResourceLocation(Wizardry.MODID, "blocks/books_blue"));
|
||||
registerBookModelTexture(() -> WizardryItems.arcane_tome, new ResourceLocation(Wizardry.MODID, "blocks/books_purple"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a book texture to be used for the book model when the given item is placed in a bookshelf. This method
|
||||
* <b>must</b> be called from {@code preInit} as the registered item count is required during block registration.
|
||||
* This also necessitates the use of a supplier to fetch the item, since the items will not yet be registered.
|
||||
* @param itemFactory A {@link Supplier} that returns the book item to link the texture to. This item need not
|
||||
* be an instance of {@link electroblob.wizardry.item.ItemSpellBook ItemSpellBook}. Duplicate
|
||||
* items will result in an {@link IllegalArgumentException} being thrown later.
|
||||
* @param texture The texture to apply to the book model.
|
||||
*/
|
||||
public static void registerBookModelTexture(Supplier<Item> itemFactory, ResourceLocation texture){
|
||||
BOOK_TEXTURE_MAP.put(itemFactory, texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of nearby bookshelves' inventories, where 'bookshelves' are any tile entities with inventories
|
||||
* whose blocks are specified in the config file under the {@code bookshelfBlocks} option.
|
||||
|
||||
@@ -17,9 +17,9 @@ import java.util.List;
|
||||
public class BakedModelBookshelf implements IBakedModel {
|
||||
|
||||
private final IBakedModel bookshelf;
|
||||
private final IBakedModel[] books;
|
||||
private final IBakedModel[][] books;
|
||||
|
||||
public BakedModelBookshelf(IBakedModel bookshelf, IBakedModel... books){
|
||||
public BakedModelBookshelf(IBakedModel bookshelf, IBakedModel[][] books){
|
||||
this.bookshelf = bookshelf;
|
||||
this.books = books;
|
||||
}
|
||||
@@ -36,9 +36,9 @@ public class BakedModelBookshelf implements IBakedModel {
|
||||
IExtendedBlockState extendedState = (IExtendedBlockState)state;
|
||||
|
||||
for(int i = 0; i<BlockBookshelf.SLOT_COUNT; i++){
|
||||
Boolean value = extendedState.getValue(BlockBookshelf.BOOKS[i]);
|
||||
if(value == null) return fallback.getQuads(null, side, rand);
|
||||
if(value) quads.addAll(books[i].getQuads(state, side, rand));
|
||||
Integer value = extendedState.getValue(BlockBookshelf.BOOKS[i]);
|
||||
if(value == null || value < 0) return fallback.getQuads(null, side, rand);
|
||||
if(value < books.length) quads.addAll(books[value][i].getQuads(state, side, rand)); // Empty slots use books.length
|
||||
}
|
||||
|
||||
return quads;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
@@ -19,7 +20,7 @@ import java.util.function.Function;
|
||||
|
||||
public class ModelBookshelf implements IModel {
|
||||
|
||||
private static final ResourceLocation BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
private static final ResourceLocation DEFAULT_BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
|
||||
private static final List<ResourceLocation> bookModelLocations = new ArrayList<>();
|
||||
|
||||
@@ -48,11 +49,18 @@ public class ModelBookshelf implements IModel {
|
||||
// I don't know why default state works here (surely it ought to be the state param?), but it works so who cares
|
||||
IBakedModel bookshelf = bookshelfModel.bake(bookshelfModel.getDefaultState(), format, bakedTextureGetter);
|
||||
|
||||
IBakedModel[] books = new IBakedModel[BlockBookshelf.SLOT_COUNT];
|
||||
ImmutableList<ResourceLocation> textures = BlockBookshelf.getBookTextures();
|
||||
|
||||
for(int i = 0; i < BlockBookshelf.SLOT_COUNT; i++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(i), variant));
|
||||
books[i] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
IBakedModel[][] books = new IBakedModel[textures.size()][BlockBookshelf.SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < textures.size(); i++){
|
||||
|
||||
ImmutableMap<String, String> retexturer = ImmutableMap.of("books", textures.get(i).toString());
|
||||
|
||||
for(int j = 0; j < BlockBookshelf.SLOT_COUNT; j++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(j), variant)).retexture(retexturer);
|
||||
books[i][j] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
}
|
||||
|
||||
// To clarify: the whole point of doing this was to avoid having to bake 4 * 2^12 models per bookshelf type
|
||||
@@ -85,7 +93,7 @@ public class ModelBookshelf implements IModel {
|
||||
// 3. Is it correct to use getModel() to get the dependency models upon construction of this class so I can
|
||||
// access their textures properly? Or is that too early?
|
||||
// 4. If so, what's the point of getDependencies, and why should I override it?
|
||||
return ImmutableList.of(BOOK_TEXTURE);
|
||||
return BlockBookshelf.getBookTextures();// ImmutableList.of(DEFAULT_BOOK_TEXTURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
package electroblob.wizardry.inventory;
|
||||
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.tileentity.TileEntityBookshelf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ContainerBookshelf extends Container {
|
||||
|
||||
private static final Set<Item> validItems = new HashSet<>();
|
||||
|
||||
/** The bookshelf tile entity associated with this container. */
|
||||
public TileEntityBookshelf tileentity;
|
||||
|
||||
@@ -21,7 +33,7 @@ public class ContainerBookshelf extends Container {
|
||||
|
||||
for(int y = 0; y < 2; y++){
|
||||
for(int x = 0; x < BlockBookshelf.SLOT_COUNT / 2; x++){
|
||||
this.addSlotToContainer(new SlotBookshelf(tileentity, x + BlockBookshelf.SLOT_COUNT / 2 * y, 35 + x * 18, 17 + y * 18, 64, ItemSpellBook.class));
|
||||
this.addSlotToContainer(new SlotBookshelf(tileentity, x + BlockBookshelf.SLOT_COUNT / 2 * y, 35 + x * 18, 17 + y * 18));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,11 +106,31 @@ public class ContainerBookshelf extends Container {
|
||||
return remainder;
|
||||
}
|
||||
|
||||
public class SlotBookshelf extends SlotItemClassList {
|
||||
/**
|
||||
* Adds the given item to the set of items that can be put in a bookshelf. This method should be called from the
|
||||
* {@code init()} phase.
|
||||
* @param item The item to register
|
||||
* @see BlockBookshelf#registerBookModelTexture(Supplier, ResourceLocation)
|
||||
*/
|
||||
public static void registerBookItem(Item item){
|
||||
validItems.add(item);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public SlotBookshelf(IInventory inventory, int index, int x, int y, int stackLimit, Class<? extends Item>... allowedItemClasses){
|
||||
super(inventory, index, x, y, stackLimit, allowedItemClasses);
|
||||
/** Called from {@link Wizardry#init(FMLInitializationEvent)} to register the default book items. */
|
||||
public static void initDefaultBookItems(){
|
||||
registerBookItem(WizardryItems.spell_book);
|
||||
registerBookItem(WizardryItems.arcane_tome);
|
||||
registerBookItem(WizardryItems.wizard_handbook);
|
||||
registerBookItem(Items.BOOK);
|
||||
registerBookItem(Items.WRITTEN_BOOK);
|
||||
registerBookItem(Items.WRITABLE_BOOK);
|
||||
registerBookItem(Items.ENCHANTED_BOOK);
|
||||
}
|
||||
|
||||
public class SlotBookshelf extends Slot {
|
||||
|
||||
public SlotBookshelf(IInventory inventory, int index, int x, int y){
|
||||
super(inventory, index, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,6 +147,10 @@ public class ContainerBookshelf extends Container {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(ItemStack stack){
|
||||
return validItems.contains(stack.getItem()) || Settings.containsMetaItem(Wizardry.settings.bookItems, stack);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
|
||||
Wizardry.settings.forfeitChance = message.settings.forfeitChance;
|
||||
Wizardry.settings.bookshelfSearchRadius = message.settings.bookshelfSearchRadius;
|
||||
Wizardry.settings.bookshelfBlocks = message.settings.bookshelfBlocks;
|
||||
Wizardry.settings.bookItems = message.settings.bookItems;
|
||||
}
|
||||
|
||||
public static class Message implements IMessage {
|
||||
@@ -57,7 +58,6 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void fromBytes(ByteBuf buf){
|
||||
// I'm guessing the settings field will be null here, so it needs initialising.
|
||||
// This is also a great reason to have the settings as an actual object.
|
||||
@@ -69,12 +69,8 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
|
||||
settings.replaceVanillaFireballs = buf.readBoolean();
|
||||
settings.forfeitChance = buf.readFloat();
|
||||
settings.bookshelfSearchRadius = buf.readInt();
|
||||
int length = buf.readInt();
|
||||
List<Pair<ResourceLocation, Short>> entries = new ArrayList<>();
|
||||
for(int i=0; i<length; i++){
|
||||
entries.add(Pair.of(new ResourceLocation(ByteBufUtils.readUTF8String(buf)), buf.readShort()));
|
||||
}
|
||||
settings.bookshelfBlocks = entries.toArray(new Pair[0]);
|
||||
settings.bookshelfBlocks = readMetaItems(buf);
|
||||
settings.bookItems = readMetaItems(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,11 +81,27 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
|
||||
buf.writeBoolean(settings.replaceVanillaFireballs);
|
||||
buf.writeFloat((float)settings.forfeitChance); // Configs don't have floats but this can only be 0-1 anyway
|
||||
buf.writeInt(settings.bookshelfSearchRadius);
|
||||
buf.writeInt(settings.bookshelfBlocks.length);
|
||||
for(Pair<ResourceLocation, Short> entry : settings.bookshelfBlocks){
|
||||
writeMetaItems(buf, settings.bookshelfBlocks);
|
||||
writeMetaItems(buf, settings.bookItems);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Pair<ResourceLocation, Short>[] readMetaItems(ByteBuf buf){
|
||||
int length = buf.readInt();
|
||||
List<Pair<ResourceLocation, Short>> entries = new ArrayList<>();
|
||||
for(int i=0; i<length; i++){
|
||||
entries.add(Pair.of(new ResourceLocation(ByteBufUtils.readUTF8String(buf)), buf.readShort()));
|
||||
}
|
||||
return entries.toArray(new Pair[0]);
|
||||
}
|
||||
|
||||
private static void writeMetaItems(ByteBuf buf, Pair<ResourceLocation, Short>[] items){
|
||||
buf.writeInt(items.length);
|
||||
for(Pair<ResourceLocation, Short> entry : items){
|
||||
ByteBufUtils.writeUTF8String(buf, entry.getLeft().toString());
|
||||
buf.writeShort(entry.getRight());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,8 @@ public final class WizardryBlocks {
|
||||
@SubscribeEvent
|
||||
public static void register(RegistryEvent.Register<Block> event){
|
||||
|
||||
BlockBookshelf.initBookProperties();
|
||||
|
||||
IForgeRegistry<Block> registry = event.getRegistry();
|
||||
|
||||
registerBlock(registry, "arcane_workbench", new BlockArcaneWorkbench().setHardness(1.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
|
||||
Reference in New Issue
Block a user