From b14771e85ac8bbb8a35144815d0f80222f2f26b8 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 14 Sep 2022 21:15:29 +0200 Subject: [PATCH] Ensure tree types are available to the client when on a multiplayer server --- .../unicopia/ability/data/tree/TreeType.java | 4 +- .../ability/data/tree/TreeTypeLoader.java | 148 +++++++----------- .../unicopia/network/MsgServerResources.java | 5 + .../handler/ClientNetworkHandlerImpl.java | 2 + 4 files changed, 65 insertions(+), 94 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeType.java b/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeType.java index d883bdec..3443b490 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeType.java @@ -164,11 +164,11 @@ public interface TreeType { boolean isWide(); static TreeType at(BlockPos pos, World world) { - return TreeTypeLoader.INSTANCE.get(world.getBlockState(pos), pos, world); + return TreeTypes.get(world.getBlockState(pos), pos, world); } static TreeType of(BlockState state) { - return TreeTypeLoader.INSTANCE.get(state); + return TreeTypes.get(state); } static TreeType of(TreeType logs, TreeType leaves) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeTypeLoader.java b/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeTypeLoader.java index 42a1ebce..98887231 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeTypeLoader.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/data/tree/TreeTypeLoader.java @@ -1,147 +1,111 @@ package com.minelittlepony.unicopia.ability.data.tree; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.function.Supplier; +import java.util.stream.Collectors; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.minelittlepony.unicopia.Unicopia; -import com.minelittlepony.unicopia.util.PosHelper; import com.minelittlepony.unicopia.util.Resources; import com.minelittlepony.unicopia.util.Weighted; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.LeavesBlock; import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; import net.minecraft.resource.JsonDataLoader; import net.minecraft.resource.ResourceManager; -import net.minecraft.tag.BlockTags; import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.profiler.Profiler; import net.minecraft.util.registry.Registry; -import net.minecraft.world.World; public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResourceReloadListener { private static final Identifier ID = Unicopia.id("data/tree_type"); public static final TreeTypeLoader INSTANCE = new TreeTypeLoader(); - private final Set entries = new HashSet<>(); - - private final TreeType any1x = createDynamic(false); - private final TreeType any2x = createDynamic(true); + private Map entries = new HashMap<>(); TreeTypeLoader() { super(Resources.GSON, "tree_types"); } + public Map getEntries() { + return entries; + } + @Override public Identifier getFabricId() { return ID; } - public TreeType get(BlockState state, BlockPos pos, World world) { - return entries.stream() - .filter(type -> type.matches(state)) - .findFirst() - .map(type -> TreeType.of(type, type.findLeavesType(world, pos))) - .orElseGet(() -> { - if (any1x.matches(state)) { - if (PosHelper.any(pos, p -> world.getBlockState(p).isOf(state.getBlock()), PosHelper.HORIZONTAL)) { - return any2x; - } - - return any1x; - } - - return TreeType.NONE; - }); - } - - public TreeType get(BlockState state) { - return entries.stream() - .filter(type -> type.matches(state)) - .findFirst() - .orElse(TreeType.NONE); - } - - private TreeType createDynamic(boolean wide) { - return new TreeType() { - @Override - public boolean isLeaves(BlockState state) { - return (state.isIn(BlockTags.LEAVES) || state.getBlock() instanceof LeavesBlock || entries.stream().anyMatch(t -> t.isLeaves(state))) && TreeTypeImpl.isNonPersistent(state); - } - - @Override - public boolean isLog(BlockState state) { - return state.isIn(BlockTags.LOGS_THAT_BURN) || entries.stream().anyMatch(t -> t.isLog(state)); - } - - @Override - public ItemStack pickRandomStack(BlockState state) { - TreeType type = get(state); - if (type == TreeType.NONE) { - type = get(Blocks.OAK_LOG.getDefaultState()); - } - return type.pickRandomStack(state); - } - - @Override - public boolean isWide() { - return wide; - } - }; - } - @Override protected void apply(Map resources, ResourceManager manager, Profiler profiler) { - entries.clear(); - - for (Map.Entry entry : resources.entrySet()) { + entries = resources.entrySet().stream().filter(Objects::nonNull) + .collect(Collectors.toMap(Map.Entry::getKey, entry -> { try { - TreeTypeDef typeDef = Resources.GSON.fromJson(entry.getValue(), TreeTypeDef.class); - - if (typeDef != null) { - entries.add(new TreeTypeImpl( - entry.getKey(), - typeDef.wideTrunk, - typeDef.getWeighted(new Weighted>()), - Objects.requireNonNull(typeDef.logs, "TreeType must have logs"), - Objects.requireNonNull(typeDef.leaves, "TreeType must have leaves") - )); - } + return Resources.GSON.fromJson(entry.getValue(), TreeTypeDef.class); } catch (IllegalArgumentException | JsonParseException e) { - + return null; } - } + })); + TreeTypes.load(entries); } - static class TreeTypeDef { - Set logs; - Set leaves; - Set drops; - boolean wideTrunk; + public static final class TreeTypeDef { + final Set logs; + final Set leaves; + final Set drops; + final boolean wideTrunk; - Weighted> getWeighted(Weighted> weighted) { + public TreeTypeDef(PacketByteBuf buffer) { + logs = new HashSet<>(buffer.readList(PacketByteBuf::readIdentifier)); + leaves = new HashSet<>(buffer.readList(PacketByteBuf::readIdentifier)); + drops = new HashSet<>(buffer.readList(Drop::new)); + wideTrunk = buffer.readBoolean(); + } + + private Weighted> getWeighted(Weighted> weighted) { drops.forEach(drop -> drop.appendDrop(weighted)); return weighted; } + public TreeType toTreeType(Identifier id) { + return new TreeTypeImpl( + id, + wideTrunk, + getWeighted(new Weighted>()), + Objects.requireNonNull(logs, "TreeType must have logs"), + Objects.requireNonNull(leaves, "TreeType must have leaves") + ); + } + + public void write(PacketByteBuf buffer) { + buffer.writeCollection(logs, PacketByteBuf::writeIdentifier); + buffer.writeCollection(leaves, PacketByteBuf::writeIdentifier); + buffer.writeCollection(drops, (a, b) -> b.write(a)); + buffer.writeBoolean(wideTrunk); + } + static class Drop { - int weight; - Identifier item; + final int weight; + final Identifier item; + + public Drop(PacketByteBuf buffer) { + weight = buffer.readInt(); + item = buffer.readIdentifier(); + } void appendDrop(Weighted> weighted) { Registry.ITEM.getOrEmpty(item).ifPresent(item -> { weighted.put(weight, item::getDefaultStack); }); } + + public void write(PacketByteBuf buffer) { + buffer.writeInt(weight); + buffer.writeIdentifier(item); + } } } } diff --git a/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java b/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java index 9c1ca59d..7934abae 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java +++ b/src/main/java/com/minelittlepony/unicopia/network/MsgServerResources.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.network; import java.util.*; import com.minelittlepony.unicopia.InteractionManager; +import com.minelittlepony.unicopia.ability.data.tree.TreeTypeLoader; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.client.gui.spellbook.ClientChapters; import com.minelittlepony.unicopia.container.SpellbookChapterLoader; @@ -17,22 +18,26 @@ import net.minecraft.util.Identifier; public class MsgServerResources implements Packet { public final Map traits; public final Map chapters; + public final Map treeTypes; public MsgServerResources() { traits = SpellTraits.all(); chapters = SpellbookChapterLoader.INSTANCE.getChapters(); + treeTypes = TreeTypeLoader.INSTANCE.getEntries(); } @Environment(EnvType.CLIENT) public MsgServerResources(PacketByteBuf buffer) { traits = buffer.readMap(PacketByteBuf::readIdentifier, SpellTraits::fromPacket); chapters = buffer.readMap(PacketByteBuf::readIdentifier, ClientChapters::loadChapter); + treeTypes = buffer.readMap(PacketByteBuf::readIdentifier, TreeTypeLoader.TreeTypeDef::new); } @Override public void toBuffer(PacketByteBuf buffer) { buffer.writeMap(traits, PacketByteBuf::writeIdentifier, (r, v) -> v.write(r)); buffer.writeMap(chapters, PacketByteBuf::writeIdentifier, (r, v) -> ((SpellbookChapterLoader.Chapter)v).write(r)); + buffer.writeMap(treeTypes, PacketByteBuf::writeIdentifier, (r, v) -> v.write(r)); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java b/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java index 631c8bba..939a11b3 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java +++ b/src/main/java/com/minelittlepony/unicopia/network/handler/ClientNetworkHandlerImpl.java @@ -5,6 +5,7 @@ import java.util.Map; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.ability.data.tree.TreeTypes; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.client.ClientBlockDestructionManager; @@ -82,5 +83,6 @@ public class ClientNetworkHandlerImpl implements ClientNetworkHandler { public void handleServerResources(MsgServerResources packet) { SpellTraits.load(packet.traits); ClientChapters.load((Map)packet.chapters); + TreeTypes.load(packet.treeTypes); } }