diff --git a/src/main/java/io/github/eggohito/eggolib/component/EggolibComponents.java b/src/main/java/io/github/eggohito/eggolib/component/EggolibComponents.java deleted file mode 100644 index 18f48ee..0000000 --- a/src/main/java/io/github/eggohito/eggolib/component/EggolibComponents.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.eggohito.eggolib.component; - -import dev.onyxstudios.cca.api.v3.component.ComponentKey; -import dev.onyxstudios.cca.api.v3.component.ComponentRegistry; -import io.github.eggohito.eggolib.Eggolib; -import io.github.eggohito.eggolib.component.entity.IMiscComponent; - -public interface EggolibComponents { - - ComponentKey MISC = ComponentRegistry.getOrCreate(Eggolib.identifier("misc"), IMiscComponent.class); - -} diff --git a/src/main/java/io/github/eggohito/eggolib/component/entity/IMiscComponent.java b/src/main/java/io/github/eggohito/eggolib/component/entity/IMiscComponent.java deleted file mode 100644 index 5745d2e..0000000 --- a/src/main/java/io/github/eggohito/eggolib/component/entity/IMiscComponent.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.eggohito.eggolib.component.entity; - -import dev.onyxstudios.cca.api.v3.component.sync.AutoSyncedComponent; - -import java.util.Set; - -@SuppressWarnings("UnusedReturnValue") -public interface IMiscComponent extends AutoSyncedComponent { - - Set getCommandTags(); - - void setCommandTags(Set commandTags); - - boolean removeCommandTag(String commandTag); - - boolean addCommandTag(String commandTag); - - void sync(boolean force); - - void sync(); - -} diff --git a/src/main/java/io/github/eggohito/eggolib/component/entity/MiscComponent.java b/src/main/java/io/github/eggohito/eggolib/component/entity/MiscComponent.java deleted file mode 100644 index b3398ba..0000000 --- a/src/main/java/io/github/eggohito/eggolib/component/entity/MiscComponent.java +++ /dev/null @@ -1,93 +0,0 @@ -package io.github.eggohito.eggolib.component.entity; - -import io.github.eggohito.eggolib.component.EggolibComponents; -import net.minecraft.entity.Entity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtList; -import net.minecraft.nbt.NbtString; - -import java.util.HashSet; -import java.util.Set; - -public class MiscComponent implements IMiscComponent { - - private final Set syncedCommandTags = new HashSet<>(); - private final Entity entity; - - private boolean dirty; - - public MiscComponent(Entity entity) { - this.entity = entity; - } - - @Override - public Set getCommandTags() { - return syncedCommandTags; - } - - @Override - public void setCommandTags(Set commandTags) { - - if (this.syncedCommandTags.equals(commandTags)) { - return; - } - - this.syncedCommandTags.clear(); - this.syncedCommandTags.addAll(commandTags); - - this.dirty = true; - - } - - @Override - public boolean removeCommandTag(String commandTag) { - return this.syncedCommandTags.remove(commandTag) - && (this.dirty = true); - } - - @Override - public boolean addCommandTag(String commandTag) { - return this.syncedCommandTags.add(commandTag) - && (this.dirty = true); - } - - @Override - public void sync(boolean force) { - if (force || dirty) { - this.dirty = false; - this.sync(); - } - } - - @Override - public void sync() { - EggolibComponents.MISC.sync(entity); - } - - @Override - public void readFromNbt(NbtCompound tag) { - - NbtList commandTagsNbt = tag.getList("Tags", NbtElement.STRING_TYPE); - this.syncedCommandTags.clear(); - - for (int i = 0; i < commandTagsNbt.size(); i++) { - this.syncedCommandTags.add(commandTagsNbt.getString(i)); - } - - } - - @Override - public void writeToNbt(NbtCompound tag) { - - NbtList commandTagsNbt = new NbtList(); - this.entity.commandTags - .stream() - .map(NbtString::of) - .forEach(commandTagsNbt::add); - - tag.put("Tags", commandTagsNbt); - - } - -} diff --git a/src/main/java/io/github/eggohito/eggolib/condition/bientity/HasMatchingTagCondition.java b/src/main/java/io/github/eggohito/eggolib/condition/bientity/HasMatchingTagCondition.java index 3255bf4..5c92ef6 100644 --- a/src/main/java/io/github/eggohito/eggolib/condition/bientity/HasMatchingTagCondition.java +++ b/src/main/java/io/github/eggohito/eggolib/condition/bientity/HasMatchingTagCondition.java @@ -3,7 +3,6 @@ import io.github.apace100.apoli.power.factory.condition.ConditionFactory; import io.github.apace100.calio.data.SerializableData; import io.github.eggohito.eggolib.Eggolib; -import io.github.eggohito.eggolib.component.EggolibComponents; import net.minecraft.entity.Entity; import net.minecraft.util.Pair; @@ -14,8 +13,8 @@ public class HasMatchingTagCondition { public static boolean condition(SerializableData.Instance data, Pair actorAndTarget) { - Set actorCommandTags = EggolibComponents.MISC.get(actorAndTarget.getLeft()).getCommandTags(); - Set targetCommandTags = EggolibComponents.MISC.get(actorAndTarget.getRight()).getCommandTags(); + Set actorCommandTags = actorAndTarget.getLeft().getCommandTags(); + Set targetCommandTags = actorAndTarget.getRight().getCommandTags(); return !Collections.disjoint(actorCommandTags, targetCommandTags); diff --git a/src/main/java/io/github/eggohito/eggolib/condition/entity/HasTagCondition.java b/src/main/java/io/github/eggohito/eggolib/condition/entity/HasTagCondition.java index a3eda28..66df109 100644 --- a/src/main/java/io/github/eggohito/eggolib/condition/entity/HasTagCondition.java +++ b/src/main/java/io/github/eggohito/eggolib/condition/entity/HasTagCondition.java @@ -4,7 +4,6 @@ import io.github.apace100.calio.data.SerializableData; import io.github.apace100.calio.data.SerializableDataTypes; import io.github.eggohito.eggolib.Eggolib; -import io.github.eggohito.eggolib.component.EggolibComponents; import net.minecraft.entity.Entity; import java.util.Collections; @@ -16,7 +15,7 @@ public class HasTagCondition { public static boolean condition(SerializableData.Instance data, Entity entity) { Set specifiedCommandTags = new HashSet<>(); - Set commandTags = EggolibComponents.MISC.get(entity).getCommandTags(); + Set commandTags = entity.getCommandTags(); data.ifPresent("tag", specifiedCommandTags::add); data.ifPresent("tags", specifiedCommandTags::addAll); diff --git a/src/main/java/io/github/eggohito/eggolib/data/EggolibDataHandlers.java b/src/main/java/io/github/eggohito/eggolib/data/EggolibDataHandlers.java new file mode 100644 index 0000000..098f1fb --- /dev/null +++ b/src/main/java/io/github/eggohito/eggolib/data/EggolibDataHandlers.java @@ -0,0 +1,21 @@ +package io.github.eggohito.eggolib.data; + +import net.minecraft.entity.data.TrackedDataHandler; +import net.minecraft.entity.data.TrackedDataHandlerRegistry; +import net.minecraft.network.PacketByteBuf; + +import java.util.HashSet; +import java.util.Set; + +public class EggolibDataHandlers { + + public static final TrackedDataHandler> STRING_SET = TrackedDataHandler.of( + (buf, strings) -> buf.writeCollection(strings, PacketByteBuf::writeString), + buf -> buf.readCollection(value -> new HashSet<>(), PacketByteBuf::readString) + ); + + public static void register() { + TrackedDataHandlerRegistry.register(STRING_SET); + } + +} diff --git a/src/main/java/io/github/eggohito/eggolib/loot/condition/HasTagLootCondition.java b/src/main/java/io/github/eggohito/eggolib/loot/condition/HasTagLootCondition.java index ed17289..35a6b8e 100644 --- a/src/main/java/io/github/eggohito/eggolib/loot/condition/HasTagLootCondition.java +++ b/src/main/java/io/github/eggohito/eggolib/loot/condition/HasTagLootCondition.java @@ -3,7 +3,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.github.eggohito.eggolib.Eggolib; -import io.github.eggohito.eggolib.component.EggolibComponents; import net.minecraft.entity.Entity; import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.condition.LootConditionType; @@ -35,7 +34,7 @@ public boolean test(LootContext lootContext) { return false; } - Set commandTags = EggolibComponents.MISC.get(entity).getCommandTags(); + Set commandTags = entity.getCommandTags(); Set specifiedCommandTags = new HashSet<>(); this.commandTag.ifPresent(specifiedCommandTags::add); diff --git a/src/main/java/io/github/eggohito/eggolib/mixin/EntityMixin.java b/src/main/java/io/github/eggohito/eggolib/mixin/EntityMixin.java index b47d6e6..55ee54d 100644 --- a/src/main/java/io/github/eggohito/eggolib/mixin/EntityMixin.java +++ b/src/main/java/io/github/eggohito/eggolib/mixin/EntityMixin.java @@ -1,18 +1,24 @@ package io.github.eggohito.eggolib.mixin; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import io.github.eggohito.eggolib.component.EggolibComponents; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import io.github.eggohito.eggolib.Eggolib; +import io.github.eggohito.eggolib.data.EggolibDataHandlers; import io.github.eggohito.eggolib.power.ModifyPassengerPositionPower; import io.github.eggohito.eggolib.power.ModifyRidingPositionPower; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.data.DataTracker; +import net.minecraft.entity.data.TrackedData; import net.minecraft.world.World; import org.joml.Vector3f; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Set; @@ -20,32 +26,66 @@ public abstract class EntityMixin { @Shadow - private World world; + @Final + protected DataTracker dataTracker; - @Inject(method = "addCommandTag", at = @At("TAIL")) - private void eggolib$onAddCommandTag(String tag, CallbackInfoReturnable cir) { - if (cir.getReturnValue()) { - EggolibComponents.MISC.get(this).addCommandTag(tag); + @Shadow + protected boolean firstUpdate; + + @Shadow + public abstract World getWorld(); + + @Shadow + @Final + public Set commandTags; + + @Unique + private static final TrackedData> COMMAND_TAGS = DataTracker.registerData(Entity.class, EggolibDataHandlers.STRING_SET); + + @Unique + private boolean eggolib$dirtiedCommandTags; + + @Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;initDataTracker()V")) + private void eggolib$registerCommandTagsDataTracker(EntityType type, World world, CallbackInfo ci) { + + try { + this.dataTracker.startTracking(COMMAND_TAGS, Set.of()); } - } - @Inject(method = "removeScoreboardTag", at = @At("TAIL")) - private void eggolib$onRemoveCommandTag(String tag, CallbackInfoReturnable cir) { - EggolibComponents.MISC.get(this).removeCommandTag(tag); - } + catch (Exception e) { + Eggolib.LOGGER.warn("Couldn't register data tracker for command tags", e); + } - @Inject(method = "getCommandTags", at = @At("RETURN")) - private void eggolib$onGetCommandTag(CallbackInfoReturnable> cir) { - EggolibComponents.MISC.get(this).setCommandTags(cir.getReturnValue()); + } + + @ModifyReturnValue(method = "addCommandTag", at = @At("RETURN")) + private boolean eggolib$trackAddedCommandTag(boolean original) { + return original + && (this.eggolib$dirtiedCommandTags = true); + } + + @ModifyReturnValue(method = "removeScoreboardTag", at = @At("RETURN")) + private boolean eggolib$trackRemovedCommandTag(boolean original) { + return original + && (this.eggolib$dirtiedCommandTags = true); + } + + @ModifyReturnValue(method = "getCommandTags", at = @At("RETURN")) + private Set eggolib$queryTrackedCommandTags(Set original) { + return this.dataTracker.containsKey(COMMAND_TAGS) + ? this.dataTracker.get(COMMAND_TAGS) + : original; } - @Inject(method = "baseTick", at = @At("TAIL")) - private void eggolib$syncCommandTags(CallbackInfo ci) { + @Inject(method = "baseTick", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;firstUpdate:Z")) + private void eggolib$updateTrackedCommandTags(CallbackInfo ci) { - if (!this.world.isClient) { - EggolibComponents.MISC.get(this).sync(false); + if (this.dataTracker.containsKey(COMMAND_TAGS) && ((this.firstUpdate && !this.getWorld().isClient) || this.eggolib$dirtiedCommandTags)) { + this.dataTracker.set(COMMAND_TAGS, Set.copyOf(this.commandTags)); } + this.eggolib$dirtiedCommandTags = false; + } @ModifyExpressionValue(method = "getPassengerRidingPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getPassengerAttachmentPos(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/EntityDimensions;F)Lorg/joml/Vector3f;")) diff --git a/src/main/java/io/github/eggohito/eggolib/registry/factory/EggolibEntityComponents.java b/src/main/java/io/github/eggohito/eggolib/registry/factory/EggolibEntityComponents.java deleted file mode 100644 index ca4c921..0000000 --- a/src/main/java/io/github/eggohito/eggolib/registry/factory/EggolibEntityComponents.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.eggohito.eggolib.registry.factory; - -import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry; -import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer; -import dev.onyxstudios.cca.api.v3.entity.RespawnCopyStrategy; -import io.github.eggohito.eggolib.component.EggolibComponents; -import io.github.eggohito.eggolib.component.entity.MiscComponent; -import net.minecraft.entity.Entity; - -public class EggolibEntityComponents implements EntityComponentInitializer { - - @Override - public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) { - - registry - .beginRegistration(Entity.class, EggolibComponents.MISC) - .impl(MiscComponent.class) - .respawnStrategy(RespawnCopyStrategy.ALWAYS_COPY) - .end(MiscComponent::new); - - } - -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index a94a488..af98144 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -22,9 +22,6 @@ "client": [ "io.github.eggohito.eggolib.EggolibClient" ], - "cardinal-components-entity": [ - "io.github.eggohito.eggolib.registry.factory.EggolibEntityComponents" - ], "modmenu": [ "io.github.eggohito.eggolib.integration.EggolibModMenuIntegration" ],