diff --git a/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java b/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java index 1de1d4ae..9aea01eb 100644 --- a/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java +++ b/polymer-common/src/main/java/eu/pb4/polymer/common/impl/CommonImpl.java @@ -124,19 +124,22 @@ public static Path configDir() { public static T loadConfig(String name, Class clazz) { try { var folder = configDir(); - if (!folder.toFile().isDirectory()) { - if (folder.toFile().exists()) { + if (!Files.isDirectory(folder)) { + if (Files.exists(folder)) { Files.deleteIfExists(folder); } - folder.toFile().mkdirs(); + Files.createDirectories(folder); } var path = folder.resolve(name + ".json"); if (path.toFile().isFile()) { String json = IOUtils.toString(new InputStreamReader(new FileInputStream(path.toFile()), StandardCharsets.UTF_8)); var obj = GSON.fromJson(json, clazz); - saveConfig(name, obj); - return obj; + + if (obj != null) { + saveConfig(name, obj); + return obj; + } } } catch (Exception e) { LOGGER.warn("Couldn't load config! " + clazz.toString()); @@ -149,24 +152,24 @@ public static T loadConfig(String name, Class clazz) { return obj; } catch (Exception e) { LOGGER.error("Invalid config class! " + clazz.toString()); - return null; + throw new RuntimeException(e); } } public static void saveConfig(String name, Object obj) { try { var folder = configDir(); - if (!folder.toFile().isDirectory()) { - if (folder.toFile().exists()) { + if (!Files.isDirectory(folder)) { + if (Files.exists(folder)) { Files.deleteIfExists(folder); } - folder.toFile().mkdirs(); + Files.createDirectories(folder); } var path = folder.resolve(name + ".json"); Files.writeString(path, GSON_PRETTY.toJson(obj), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } catch (Exception e) { - LOGGER.warn("Couldn't save config! " + obj.getClass().toString()); + LOGGER.warn("Couldn't save config! " + obj.getClass()); } } diff --git a/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerConfigurationNetworkHandlerMixin.java b/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerConfigurationNetworkHandlerMixin.java index 8b7f1725..9fb3831f 100644 --- a/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerConfigurationNetworkHandlerMixin.java +++ b/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerConfigurationNetworkHandlerMixin.java @@ -29,8 +29,8 @@ public ServerConfigurationNetworkHandlerMixin(MinecraftServer server, ClientConn @WrapOperation(method = "onReady", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;onPlayerConnect(Lnet/minecraft/network/ClientConnection;Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/server/network/ConnectedClientData;)V")) private void polymerNet$prePlayHandshakeHackfest(PlayerManager manager, ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, Operation original) { EarlyPlayConnectionMagic.handle(player, clientData.syncedOptions(), (ServerConfigurationNetworkHandler) (Object) this, player.server, connection, (context) -> { - ((ExtClientConnection) connection).polymerNet$wrongPacketConsumer(context.storedPackets()::add); connection.disableAutoRead(); + ((ExtClientConnection) connection).polymerNet$wrongPacketConsumer(context.storedPackets()::add); var attr = ((ExtClientConnection) connection).polymerNet$getChannel().attr(ClientConnection.SERVERBOUND_PROTOCOL_KEY); attr.set(NetworkState.CONFIGURATION.getHandler(NetworkSide.SERVERBOUND)); connection.setPacketListener(this); diff --git a/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java b/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java index 07aab707..b1df37a9 100644 --- a/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java +++ b/polymer-networking/src/main/java/eu/pb4/polymer/networking/mixin/ServerLoginNetworkHandlerMixin.java @@ -61,8 +61,8 @@ public abstract class ServerLoginNetworkHandlerMixin implements NetworkHandlerEx ci.cancel(); var defaultOptions = SyncedClientOptions.createDefault(); EarlyConfigurationConnectionMagic.handle(this.profile, defaultOptions, (ServerLoginNetworkHandler) (Object) this, this.server, connection, (context) -> { - ((ExtClientConnection) connection).polymerNet$wrongPacketConsumer(context.storedPackets()::add); connection.disableAutoRead(); + ((ExtClientConnection) connection).polymerNet$wrongPacketConsumer(context.storedPackets()::add); var attr = ((ExtClientConnection) connection).polymerNet$getChannel().attr(ClientConnection.SERVERBOUND_PROTOCOL_KEY); attr.set(NetworkState.LOGIN.getHandler(NetworkSide.SERVERBOUND)); connection.setPacketListener((ServerLoginNetworkHandler) (Object) this); @@ -75,6 +75,7 @@ public abstract class ServerLoginNetworkHandlerMixin implements NetworkHandlerEx this.polymerNet$overrideOptions = context.options().getValue(); } this.onEnterConfiguration(packet); + this.connection.enableAutoRead(); if (this.connection.getPacketListener() instanceof ServerConfigurationPacketListener listener) { for (var packetx : context.storedPackets()) { try { @@ -84,7 +85,6 @@ public abstract class ServerLoginNetworkHandlerMixin implements NetworkHandlerEx } } } - this.connection.enableAutoRead(); } }); } diff --git a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/PolymerResourcePackUtils.java b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/PolymerResourcePackUtils.java index 361699c3..d92e2695 100644 --- a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/PolymerResourcePackUtils.java +++ b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/PolymerResourcePackUtils.java @@ -12,9 +12,11 @@ import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.Locale; import java.util.function.Consumer; /** @@ -169,6 +171,43 @@ public static boolean build(Path output, Consumer status) { builder.copyFromPath(path); } + try { + for (var field : PolymerResourcePackImpl.INCLUDE_MOD_IDS) { + builder.copyAssets(field); + } + var gamePath = FabricLoader.getInstance().getGameDir(); + + for (var field : PolymerResourcePackImpl.INCLUDE_ZIPS) { + var zipPath = gamePath.resolve(field); + + if (Files.exists(zipPath)) { + try (var fs = FileSystems.newFileSystem(zipPath)) { + builder.copyFromPath(fs.getPath("assets"), "assets/"); + + for (var root : fs.getRootDirectories()) { + try (var str = Files.list(root)) { + str.forEach(file -> { + try { + var name = file.getFileName().toString(); + if (name.toLowerCase(Locale.ROOT).contains("license") + || name.toLowerCase(Locale.ROOT).contains("licence")) { + builder.addData("licenses/" + + field.replace("/", "_").replace("\\", "_") + "/" + name, Files.readAllBytes(file)); + } + } catch (Throwable ignored) {} + }); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + } catch (Throwable e) { + e.printStackTrace(); + } + if (CompatStatus.POLYMC) { try { Files.createDirectories(path); diff --git a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/ResourcePackBuilder.java b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/ResourcePackBuilder.java index 40ff19d7..dcd4ff02 100644 --- a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/ResourcePackBuilder.java +++ b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/api/ResourcePackBuilder.java @@ -9,10 +9,18 @@ public interface ResourcePackBuilder { boolean addData(String path, byte[] data); boolean copyAssets(String modId); + + boolean copyFromPath(Path path, String targetPrefix, boolean override); + default boolean copyFromPath(Path path, String targetPrefix) { + return this.copyFromPath(path, targetPrefix, true); + } default boolean copyFromPath(Path path) { - return this.copyFromPath(path, true); + return this.copyFromPath(path, "", true); } - boolean copyFromPath(Path path, boolean override); + default boolean copyFromPath(Path path, boolean override) { + return this.copyFromPath(path, "", override); + } + boolean addCustomModelData(PolymerModelData itemModel); boolean addArmorModel(PolymerArmorModel model); @Nullable diff --git a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/PolymerResourcePackImpl.java b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/PolymerResourcePackImpl.java index 5e3c8802..ff1bb4df 100644 --- a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/PolymerResourcePackImpl.java +++ b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/PolymerResourcePackImpl.java @@ -4,11 +4,16 @@ import eu.pb4.polymer.common.impl.CommonImpl; import eu.pb4.polymer.common.impl.CompatStatus; +import java.util.ArrayList; +import java.util.List; + public class PolymerResourcePackImpl { public static final boolean FORCE_REQUIRE; public static final boolean USE_OFFSET; public static final int OFFSET_VALUES; public static final boolean USE_ALT_ARMOR_HANDLER; + public static final List INCLUDE_MOD_IDS; + public static final List INCLUDE_ZIPS; static { @@ -21,6 +26,10 @@ public class PolymerResourcePackImpl { OFFSET_VALUES = config.offsetValue; USE_ALT_ARMOR_HANDLER = config.useAlternativeArmorHandler || CompatStatus.REQUIRE_ALT_ARMOR_HANDLER; + + INCLUDE_MOD_IDS = config.includeModAssets; + + INCLUDE_ZIPS = config.includeZips; } @@ -36,5 +45,12 @@ public static class Config { public String _c4 = "Enables usage of alternative armor rendering for increased mod compatibility"; @SerializedName("use_alternative_armor_rendering") public boolean useAlternativeArmorHandler; + + public String _c5 = "Included resource packs from mods!"; + @SerializedName("include_mod_assets") + public List includeModAssets = new ArrayList<>(); + public String _c6 = "Included resource packs from zips!"; + @SerializedName("include_zips") + public List includeZips = List.of("world/resources.zip"); } } diff --git a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/generation/DefaultRPBuilder.java b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/generation/DefaultRPBuilder.java index e2076621..40f514ef 100644 --- a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/generation/DefaultRPBuilder.java +++ b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/impl/generation/DefaultRPBuilder.java @@ -24,7 +24,6 @@ import java.awt.image.BufferedImage; import java.io.*; import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -49,9 +48,8 @@ public class DefaultRPBuilder implements InternalRPBuilder { private final Path outputPath; private final List modsList = new ArrayList<>(); private final Map> customModelData = new HashMap<>(); - private Path clientPath = null; - private final Map atlasDefinitions = new HashMap<>(); + private Path clientPath = null; public DefaultRPBuilder(Path outputPath) { outputPath.getParent().toFile().mkdirs(); @@ -108,7 +106,7 @@ private boolean addAtlasFile(String path, byte[] data) { } @Override - public boolean copyFromPath(Path basePath, boolean override) { + public boolean copyFromPath(Path basePath, String targetPrefix, boolean override) { try { if (Files.isSymbolicLink(basePath)) { basePath = Files.readSymbolicLink(basePath); @@ -116,30 +114,31 @@ public boolean copyFromPath(Path basePath, boolean override) { if (Files.isDirectory(basePath)) { Path finalBasePath = basePath; - Files.walk(basePath).forEach((file) -> { - var relative = finalBasePath.relativize(file); - var path = relative.toString().replace("\\", "/"); - if ((override || !fileMap.containsKey(path)) && Files.isRegularFile(file)) { - try { - this.addData(path, Files.readAllBytes(file)); - } catch (IOException e) { - e.printStackTrace(); - } + try (var str = Files.walk(basePath)) { + str.forEach((file) -> { + var relative = finalBasePath.relativize(file); + var path = targetPrefix + relative.toString().replace("\\", "/"); + if ((override || !fileMap.containsKey(path)) && Files.isRegularFile(file)) { + try { + this.addData(path, Files.readAllBytes(file)); + } catch (IOException e) { + e.printStackTrace(); + } - } - }); + } + }); + } return true; } else if (Files.isRegularFile(basePath)) { try (var fs = FileSystems.newFileSystem(basePath, Collections.emptyMap())) { - fs.getRootDirectories().forEach(this::copyFromPath); + fs.getRootDirectories().forEach((path) -> copyFromPath(path, targetPrefix, override)); } return true; } return false; } catch (Exception e) { - CommonImpl.LOGGER.error("Something went wrong while copying data from: " + basePath); - e.printStackTrace(); + CommonImpl.LOGGER.error("Something went wrong while copying data from: " + basePath, e); return false; } } @@ -152,22 +151,39 @@ public boolean copyAssets(String modId) { this.modsList.add(container); try { for (var rootPaths : container.getRootPaths()) { - Path assets = rootPaths.resolve("assets"); - if (Files.exists(assets)) { - Files.walk(assets).forEach((file) -> { - var relative = assets.relativize(file); - var path = relative.toString().replace("\\", "/"); - if (Files.isRegularFile(file)) { - try { - this.addData("assets/" + path, Files.readAllBytes(file)); - } catch (IOException e) { - e.printStackTrace(); + try (var str = Files.list(rootPaths)) { + str.forEach(file -> { + try { + var name = file.getFileName().toString(); + if (name.toLowerCase(Locale.ROOT).contains("license") + || name.toLowerCase(Locale.ROOT).contains("licence")) { + this.addData("licenses/" + + modId + "/" + name, Files.readAllBytes(file)); } + } catch (Throwable ignored) { } }); + } catch (Throwable e) { + CommonImpl.LOGGER.warn("Failed while copying the license!", e); } - } + Path assets = rootPaths.resolve("assets"); + if (Files.exists(assets)) { + try(var str = Files.walk(assets)) { + str.forEach((file) -> { + var relative = assets.relativize(file); + var path = relative.toString().replace("\\", "/"); + if (Files.isRegularFile(file)) { + try { + this.addData("assets/" + path, Files.readAllBytes(file)); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + } + } + } return true; } catch (Exception e) { CommonImpl.LOGGER.error("Something went wrong while copying assets of mod: " + modId); @@ -179,14 +195,6 @@ public boolean copyAssets(String modId) { return false; } - public enum OverridePlace { - BEFORE_EXISTING, - EXISTING, - BEFORE_CUSTOM_MODEL_DATA, - CUSTOM_MODEL_DATA, - END - } - @Override public boolean addCustomModelData(PolymerModelData cmdInfo) { try { @@ -316,12 +324,29 @@ public CompletableFuture buildResourcePack() { credits.add(""); credits.add("Vanilla assets by Mojang Studios"); credits.add(""); - credits.add("Used mod assets: "); + credits.add("Contains assets from mods: "); for (var entry : this.modsList) { - credits.add(" - " + entry.getMetadata().getName() + " (" + entry.getMetadata().getId() + ")"); + var b = new StringBuilder(" - ").append( entry.getMetadata().getName()).append(" (").append(entry.getMetadata().getId()).append(")"); + if (!entry.getMetadata().getLicense().isEmpty()) { + b.append(" / License: "); + var iter = entry.getMetadata().getLicense().iterator(); + while(iter.hasNext()) { + b.append(iter.next()); + if (iter.hasNext()) { + b.append(", "); + } + } + } + + entry.getMetadata().getContact().get("homepage").ifPresent(s -> b.append(" / Website: ").append(s)); + entry.getMetadata().getContact().get("source").ifPresent(s -> b.append(" / Source: ").append(s)); + + credits.add(b.toString()); } credits.add(""); + credits.add("See licenses folder for more information!"); + credits.add(""); this.buildEvent.invoke((c) -> c.accept(credits)); @@ -329,7 +354,7 @@ public CompletableFuture buildResourcePack() { { var jsonObject = new JsonObject(); var sorted = new ArrayList<>(this.customModelData.entrySet()); - sorted.sort(Comparator.comparing(e -> e.getKey())); + sorted.sort(Map.Entry.comparingByKey()); for (var entry : sorted) { var jsonObject2 = new JsonObject(); for (var model : entry.getValue()) { @@ -385,7 +410,7 @@ public CompletableFuture buildResourcePack() { this.fileMap.put(entry.getKey(), obj.toString().getBytes(StandardCharsets.UTF_8)); } - if (this.armors.size() > 0) { + if (!this.armors.isEmpty()) { credits.add("Armor texture support is based on https://github.com/Ancientkingg/fancyPants"); credits.add(""); @@ -633,6 +658,13 @@ private Identifier vId(String path) { return new Identifier(path); } + public enum OverridePlace { + BEFORE_EXISTING, + EXISTING, + BEFORE_CUSTOM_MODEL_DATA, + CUSTOM_MODEL_DATA, + END + } private record ArmorData(Identifier identifier, int color, BufferedImage[] images, ArmorTextureMetadata[] metadata) { diff --git a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/mixin/MinecraftClientMixin.java b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/mixin/client/MinecraftClientMixin.java similarity index 96% rename from polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/mixin/MinecraftClientMixin.java rename to polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/mixin/client/MinecraftClientMixin.java index 9f664dd9..935ad26c 100644 --- a/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/mixin/MinecraftClientMixin.java +++ b/polymer-resource-pack/src/main/java/eu/pb4/polymer/resourcepack/mixin/client/MinecraftClientMixin.java @@ -1,4 +1,4 @@ -package eu.pb4.polymer.resourcepack.mixin; +package eu.pb4.polymer.resourcepack.mixin.client; import eu.pb4.polymer.resourcepack.impl.client.rendering.PolymerResourceReloader; import net.fabricmc.api.EnvType; diff --git a/polymer-resource-pack/src/main/resources/polymer-resource-pack.mixins.json b/polymer-resource-pack/src/main/resources/polymer-resource-pack.mixins.json index 4859a15d..730d60b2 100644 --- a/polymer-resource-pack/src/main/resources/polymer-resource-pack.mixins.json +++ b/polymer-resource-pack/src/main/resources/polymer-resource-pack.mixins.json @@ -9,7 +9,7 @@ "compat.polymc.polymc_FancyPantsItemPolyMixin" ], "client": [ - "MinecraftClientMixin", + "client.MinecraftClientMixin", "client.ArmorFeatureRendererAccessor", "client.ResourcePackManagerMixin", "client.compat.armor_ArmorFeatureRendererMixin" diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/AbstractElement.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/AbstractElement.java index 3e1391ec..d40a23d7 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/AbstractElement.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/AbstractElement.java @@ -5,12 +5,13 @@ import net.minecraft.util.math.Vec3d; import org.jetbrains.annotations.Nullable; +import java.util.Objects; + public abstract class AbstractElement implements VirtualElement { private ElementHolder holder; private Vec3d offset = Vec3d.ZERO; private InteractionHandler handler = InteractionHandler.EMPTY; - @Override public Vec3d getOffset() { return this.offset; diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/GenericEntityElement.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/GenericEntityElement.java index 5edab683..2d401b9d 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/GenericEntityElement.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/GenericEntityElement.java @@ -26,7 +26,7 @@ @SuppressWarnings("ConstantConditions") public abstract class GenericEntityElement extends AbstractElement { - protected final DataTrackerLike dataTracker = createDataTracker(); + protected final DataTrackerLike dataTracker = this.createDataTracker(); private final int id = VirtualEntityUtils.requestEntityId(); private final UUID uuid = UUID.randomUUID(); private float pitch; @@ -275,19 +275,4 @@ public boolean hasNoGravity() { public void setNoGravity(boolean noGravity) { this.dataTracker.set(EntityTrackedData.NO_GRAVITY, noGravity); } - - @Override - public InteractionHandler getInteractionHandler(ServerPlayerEntity player) { - return InteractionHandler.EMPTY; - } - - @Override - public boolean equals(Object o) { - return this == o; - } - - @Override - public int hashCode() { - return Objects.hash(id, uuid); - } } diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/InteractionElement.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/InteractionElement.java index a80221b0..fd2b78cb 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/InteractionElement.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/InteractionElement.java @@ -20,22 +20,7 @@ public InteractionElement(InteractionHandler handler) { } public static InteractionElement redirect(Entity redirectedEntity) { - return new InteractionElement(new InteractionHandler() { - @Override - public void interact(ServerPlayerEntity player, Hand hand) { - player.networkHandler.onPlayerInteractEntity(PlayerInteractEntityC2SPacket.interact(redirectedEntity, player.isSneaking(), hand)); - } - - @Override - public void interactAt(ServerPlayerEntity player, Hand hand, Vec3d pos) { - player.networkHandler.onPlayerInteractEntity(PlayerInteractEntityC2SPacket.interactAt(redirectedEntity, player.isSneaking(), hand, pos)); - } - - @Override - public void attack(ServerPlayerEntity player) { - player.networkHandler.onPlayerInteractEntity(PlayerInteractEntityC2SPacket.attack(redirectedEntity, player.isSneaking())); - } - }); + return new InteractionElement(InteractionHandler.redirect(redirectedEntity)); } public void setHandler(InteractionHandler handler) { diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/SimpleEntityElement.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/SimpleEntityElement.java index f0ca9935..86d3d25a 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/SimpleEntityElement.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/SimpleEntityElement.java @@ -1,15 +1,38 @@ package eu.pb4.polymer.virtualentity.api.elements; +import eu.pb4.polymer.virtualentity.api.tracker.DataTrackerLike; +import eu.pb4.polymer.virtualentity.api.tracker.SimpleDataTracker; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -public class SimpleEntityElement extends GenericEntityElement{ +public class SimpleEntityElement extends GenericEntityElement { + private static final ThreadLocal> LOCAL_TYPE = new ThreadLocal<>(); private final EntityType type; public SimpleEntityElement(EntityType type) { + this(type, hackyHack(type)); + LOCAL_TYPE.remove(); + } + + private static Object hackyHack(EntityType type) { + LOCAL_TYPE.set(type); + return type; + } + + private SimpleEntityElement(EntityType type, Object hack) { + super(); this.type = type; } + @Override + protected DataTrackerLike createDataTracker() { + if (this.type != null) { + return super.createDataTracker(); + } else { + return new SimpleDataTracker(LOCAL_TYPE.get()); + } + } + @Override protected EntityType getEntityType() { return this.type; diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/VirtualElement.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/VirtualElement.java index fc7438ce..04848045 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/VirtualElement.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/elements/VirtualElement.java @@ -2,6 +2,7 @@ import eu.pb4.polymer.virtualentity.api.ElementHolder; import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.entity.Entity; import net.minecraft.network.listener.ClientPlayPacketListener; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; @@ -37,6 +38,26 @@ default void setInitialPosition(Vec3d newPos) { interface InteractionHandler { InteractionHandler EMPTY = new InteractionHandler() {}; + + static InteractionHandler redirect(Entity redirectedEntity) { + return new InteractionHandler() { + @Override + public void interact(ServerPlayerEntity player, Hand hand) { + player.networkHandler.onPlayerInteractEntity(PlayerInteractEntityC2SPacket.interact(redirectedEntity, player.isSneaking(), hand)); + } + + @Override + public void interactAt(ServerPlayerEntity player, Hand hand, Vec3d pos) { + player.networkHandler.onPlayerInteractEntity(PlayerInteractEntityC2SPacket.interactAt(redirectedEntity, player.isSneaking(), hand, pos)); + } + + @Override + public void attack(ServerPlayerEntity player) { + player.networkHandler.onPlayerInteractEntity(PlayerInteractEntityC2SPacket.attack(redirectedEntity, player.isSneaking())); + } + }; + } + default void interact(ServerPlayerEntity player, Hand hand) {}; default void interactAt(ServerPlayerEntity player, Hand hand, Vec3d pos) {}; default void attack(ServerPlayerEntity player) {};