generated from FabricMC/fabric-example-mod
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simplified impl. of syncing command tags
- Loading branch information
Showing
11 changed files
with
113 additions
and
192 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 0 additions & 12 deletions
12
src/main/java/io/github/eggohito/eggolib/component/EggolibComponents.java
This file was deleted.
Oops, something went wrong.
22 changes: 0 additions & 22 deletions
22
src/main/java/io/github/eggohito/eggolib/component/entity/IMiscComponent.java
This file was deleted.
Oops, something went wrong.
93 changes: 0 additions & 93 deletions
93
src/main/java/io/github/eggohito/eggolib/component/entity/MiscComponent.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/main/java/io/github/eggohito/eggolib/data/EggolibTrackedDataHandlers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 EggolibTrackedDataHandlers { | ||
|
||
public static final TrackedDataHandler<Set<String>> 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); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 80 additions & 25 deletions
105
src/main/java/io/github/eggohito/eggolib/mixin/EntityMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,123 @@ | ||
package io.github.eggohito.eggolib.mixin; | ||
|
||
import com.llamalad7.mixinextras.injector.ModifyReturnValue; | ||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation; | ||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; | ||
import io.github.apace100.apoli.component.PowerHolderComponent; | ||
import io.github.eggohito.eggolib.component.EggolibComponents; | ||
import io.github.eggohito.eggolib.Eggolib; | ||
import io.github.eggohito.eggolib.data.EggolibTrackedDataHandlers; | ||
import io.github.eggohito.eggolib.power.GameEventListenerPower; | ||
import io.github.eggohito.eggolib.power.InvisibilityPower; | ||
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.entity.player.PlayerEntity; | ||
import net.minecraft.server.world.ServerWorld; | ||
import net.minecraft.world.World; | ||
import net.minecraft.world.event.listener.EntityGameEventHandler; | ||
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.LinkedList; | ||
import java.util.Set; | ||
import java.util.function.BiConsumer; | ||
|
||
@Mixin(Entity.class) | ||
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<Boolean> cir) { | ||
if (cir.getReturnValue()) { | ||
EggolibComponents.MISC.get(this).addCommandTag(tag); | ||
@Shadow | ||
protected boolean firstUpdate; | ||
|
||
@Shadow | ||
public abstract World getWorld(); | ||
|
||
@Shadow | ||
@Final | ||
public Set<String> commandTags; | ||
|
||
@Unique | ||
private static final TrackedData<Set<String>> COMMAND_TAGS = DataTracker.registerData(Entity.class, EggolibTrackedDataHandlers.STRING_SET); | ||
|
||
@Unique | ||
private boolean eggolib$dirtiedCommandTags; | ||
|
||
@Inject(method = "<init>", 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<Boolean> 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<Set<String>> 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<String> eggolib$queryTrackedCommandTags(Set<String> 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; | ||
|
||
} | ||
|
||
@Inject(method = "isInvisibleTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getScoreboardTeam()Lnet/minecraft/scoreboard/AbstractTeam;"), cancellable = true) | ||
private void eggolib$invisibilityException(PlayerEntity playerEntity, CallbackInfoReturnable<Boolean> cir) { | ||
if (PowerHolderComponent.hasPower((Entity) (Object) this, InvisibilityPower.class, eip -> !eip.doesApply(playerEntity))) { | ||
cir.setReturnValue(false); | ||
@WrapOperation(method = "isInvisibleTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;isInvisible()Z")) | ||
private boolean eggolib$specificallyInvisibleTo(Entity entity, Operation<Boolean> original, PlayerEntity viewer) { | ||
|
||
if (viewer == null) { | ||
return original.call(entity); | ||
} | ||
|
||
return PowerHolderComponent.KEY.maybeGet(entity) | ||
.map(pc -> pc.getPowers(InvisibilityPower.class, true)) | ||
.orElseGet(LinkedList::new) | ||
.stream() | ||
.anyMatch(p -> p.isActive() && p.doesApply(viewer)); | ||
|
||
} | ||
|
||
@Inject(method = "updateEventHandler", at = @At("HEAD")) | ||
private void eggolib$updateCustomEventHandlers(BiConsumer<EntityGameEventHandler<?>, ServerWorld> callback, CallbackInfo ci) { | ||
if (world instanceof ServerWorld serverWorld) { | ||
PowerHolderComponent.getPowers((Entity) (Object) this, GameEventListenerPower.class).forEach(p -> callback.accept(p.getGameEventHandler(), serverWorld)); | ||
|
||
if (this.getWorld() instanceof ServerWorld serverWorld) { | ||
PowerHolderComponent | ||
.getPowers((Entity) (Object) this, GameEventListenerPower.class) | ||
.forEach(p -> callback.accept(p.getGameEventHandler(), serverWorld)); | ||
} | ||
|
||
} | ||
|
||
} |
Oops, something went wrong.