diff --git a/arclight-forge-1.15/build.gradle b/arclight-forge-1.15/build.gradle index 7432aebb..ac9b3882 100644 --- a/arclight-forge-1.15/build.gradle +++ b/arclight-forge-1.15/build.gradle @@ -119,7 +119,7 @@ remapSpigotJar { } mixin { - // add sourceSets.main, 'mixins.arclight.impl.refmap.1_14.json' + add sourceSets.main, 'mixins.arclight.impl.refmap.1_15.json' } compileJava { diff --git a/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_15.java b/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_15.java index e0ba2341..51ecb4de 100644 --- a/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_15.java +++ b/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_15.java @@ -1,6 +1,8 @@ package io.izzel.arclight.impl; import io.izzel.arclight.common.mod.ArclightConnector; +import io.izzel.arclight.i18n.ArclightConfig; +import org.spongepowered.asm.mixin.Mixins; @SuppressWarnings("unused") public class ArclightConnector_1_15 extends ArclightConnector { @@ -8,12 +10,9 @@ public class ArclightConnector_1_15 extends ArclightConnector { @Override public void connect() { super.connect(); - /* - Mixins.addConfiguration("mixins.arclight.impl.core.1_14.json"); - Mixins.addConfiguration("mixins.arclight.optimization.1_14.json"); - if (ArclightConfig.INSTANCE.optimizations.removeStreams) { - Mixins.addConfiguration("mixins.arclight.optimization.stream.1_14.json"); - }*/ - // LOGGER.info("Arclight optimization mixin added."); + if (ArclightConfig.spec().getOptimization().isRemoveStream()) { + Mixins.addConfiguration("mixins.arclight.impl.optimization.stream.1_15.json"); + } + LOGGER.info("mixin-load.optimization"); } } diff --git a/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/mixin/v1_15/optimization/stream/GoalSelectorMixin.java b/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/mixin/v1_15/optimization/stream/GoalSelectorMixin.java new file mode 100644 index 00000000..5e0207ab --- /dev/null +++ b/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/mixin/v1_15/optimization/stream/GoalSelectorMixin.java @@ -0,0 +1,119 @@ +package io.izzel.arclight.impl.mixin.v1_15.optimization.stream; + +import net.minecraft.entity.ai.goal.Goal; +import net.minecraft.entity.ai.goal.GoalSelector; +import net.minecraft.entity.ai.goal.PrioritizedGoal; +import net.minecraft.profiler.IProfiler; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.EnumSet; +import java.util.Map; +import java.util.Set; + +@Mixin(GoalSelector.class) +public abstract class GoalSelectorMixin { + + // @formatter:off + @Shadow @Final private Set goals; + @Shadow @Final private IProfiler profiler; + @Shadow @Final private EnumSet disabledFlags; + @Shadow @Final private Map flagGoals; + @Shadow @Final private static PrioritizedGoal DUMMY; + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public void removeGoal(Goal task) { + for (PrioritizedGoal p_220882_1_ : this.goals) { + if (p_220882_1_.getGoal() == task) { + if (p_220882_1_.isRunning()) { + p_220882_1_.resetTask(); + } + } + } + this.goals.removeIf((p_220884_1_) -> { + return p_220884_1_.getGoal() == task; + }); + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public void tick() { + this.profiler.startSection("goalCleanup"); + for (PrioritizedGoal p_220881_1_ : this.goals) { + if (p_220881_1_.isRunning()) { + EnumSet flags = this.disabledFlags; + boolean b = false; + for (Goal.Flag flag : p_220881_1_.getMutexFlags()) { + if (flags.contains(flag)) { + b = true; + break; + } + } + if (b) { + p_220881_1_.resetTask(); + } else if (!p_220881_1_.isRunning() || !p_220881_1_.shouldContinueExecuting()) { + p_220881_1_.resetTask(); + } + } + } + for (Map.Entry entry : this.flagGoals.entrySet()) { + Goal.Flag p_220885_1_ = entry.getKey(); + PrioritizedGoal p_220885_2_ = entry.getValue(); + if (!p_220885_2_.isRunning()) { + this.flagGoals.remove(p_220885_1_); + } + + } + this.profiler.endSection(); + this.profiler.startSection("goalUpdate"); + for (PrioritizedGoal p_220883_0_ : this.goals) { + if (!p_220883_0_.isRunning()) { + EnumSet flags = this.disabledFlags; + boolean b = true; + for (Goal.Flag flag : p_220883_0_.getMutexFlags()) { + if (flags.contains(flag)) { + b = false; + break; + } + } + if (b) { + boolean result = true; + for (Goal.Flag p_220887_2_ : p_220883_0_.getMutexFlags()) { + if (!this.flagGoals.getOrDefault(p_220887_2_, DUMMY).isPreemptedBy(p_220883_0_)) { + result = false; + break; + } + } + if (result) { + if (p_220883_0_.shouldExecute()) { + for (Goal.Flag p_220876_2_ : p_220883_0_.getMutexFlags()) { + PrioritizedGoal prioritizedgoal = this.flagGoals.getOrDefault(p_220876_2_, DUMMY); + prioritizedgoal.resetTask(); + this.flagGoals.put(p_220876_2_, p_220883_0_); + } + p_220883_0_.startExecuting(); + } + } + } + } + } + this.profiler.endSection(); + this.profiler.startSection("goalTick"); + for (PrioritizedGoal goal : this.goals) { + if (goal.isRunning()) { + goal.tick(); + } + } + this.profiler.endSection(); + } +} diff --git a/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/mixin/v1_15/optimization/stream/PathFinderMixin.java b/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/mixin/v1_15/optimization/stream/PathFinderMixin.java new file mode 100644 index 00000000..fac8e250 --- /dev/null +++ b/arclight-forge-1.15/src/main/java/io/izzel/arclight/impl/mixin/v1_15/optimization/stream/PathFinderMixin.java @@ -0,0 +1,162 @@ +package io.izzel.arclight.impl.mixin.v1_15.optimization.stream; + +import net.minecraft.entity.MobEntity; +import net.minecraft.pathfinding.FlaggedPathPoint; +import net.minecraft.pathfinding.NodeProcessor; +import net.minecraft.pathfinding.Path; +import net.minecraft.pathfinding.PathFinder; +import net.minecraft.pathfinding.PathHeap; +import net.minecraft.pathfinding.PathPoint; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Region; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +@Mixin(PathFinder.class) +public abstract class PathFinderMixin { + + // @formatter:off + @Shadow protected abstract float func_224776_a(PathPoint p_224776_1_, Set p_224776_2_); + @Shadow @Final private PathHeap path; + @Shadow @Final private Set closedSet; + @Shadow @Final private int field_215751_d; + @Shadow @Final private NodeProcessor nodeProcessor; + @Shadow @Final private PathPoint[] pathOptions; + @Shadow protected abstract Path func_224780_a(PathPoint p_224780_1_, BlockPos p_224780_2_, boolean p_224780_3_); + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + @Nullable + public Path func_227478_a_(Region p_227478_1_, MobEntity p_227478_2_, Set p_227478_3_, float p_227478_4_, int p_227478_5_, float p_227478_6_) { + this.path.clearPath(); + this.nodeProcessor.func_225578_a_(p_227478_1_, p_227478_2_); + PathPoint pathpoint = this.nodeProcessor.getStart(); + Map map = new HashMap<>(); + for (BlockPos p_224782_1_ : p_227478_3_) { + if (map.put(this.nodeProcessor.func_224768_a(p_224782_1_.getX(), p_224782_1_.getY(), p_224782_1_.getZ()), p_224782_1_) != null) { + throw new IllegalStateException("Duplicate key"); + } + } + Path path = this.func_227479_a_(pathpoint, map, p_227478_4_, p_227478_5_, p_227478_6_); + this.nodeProcessor.postProcess(); + return path; + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + @Nullable + private Path func_227479_a_(PathPoint p_227479_1_, Map p_227479_2_, float p_227479_3_, int p_227479_4_, float p_227479_5_) { + Set set = p_227479_2_.keySet(); + p_227479_1_.totalPathDistance = 0.0F; + p_227479_1_.distanceToNext = this.func_224776_a(p_227479_1_, set); + p_227479_1_.distanceToTarget = p_227479_1_.distanceToNext; + this.path.clearPath(); + this.closedSet.clear(); + this.path.addPoint(p_227479_1_); + int i = 0; + int j = (int) ((float) this.field_215751_d * p_227479_5_); + + while (!this.path.isPathEmpty()) { + ++i; + if (i >= j) { + break; + } + + PathPoint pathpoint = this.path.dequeue(); + pathpoint.visited = true; + for (FlaggedPathPoint p_224781_2_ : set) { + if (pathpoint.func_224757_c(p_224781_2_) <= (float) p_227479_4_) { + p_224781_2_.func_224764_e(); + } + } + boolean b = false; + for (FlaggedPathPoint flaggedPathPoint : set) { + if (flaggedPathPoint.func_224762_f()) { + b = true; + break; + } + } + if (b) { + break; + } + + if (!(pathpoint.distanceTo(p_227479_1_) >= p_227479_3_)) { + int k = this.nodeProcessor.func_222859_a(this.pathOptions, pathpoint); + + for (int l = 0; l < k; ++l) { + PathPoint pathpoint1 = this.pathOptions[l]; + float f = pathpoint.distanceTo(pathpoint1); + pathpoint1.field_222861_j = pathpoint.field_222861_j + f; + float f1 = pathpoint.totalPathDistance + f + pathpoint1.costMalus; + if (pathpoint1.field_222861_j < p_227479_3_ && (!pathpoint1.isAssigned() || f1 < pathpoint1.totalPathDistance)) { + pathpoint1.previous = pathpoint; + pathpoint1.totalPathDistance = f1; + pathpoint1.distanceToNext = this.func_224776_a(pathpoint1, set) * 1.5F; + if (pathpoint1.isAssigned()) { + this.path.changeDistance(pathpoint1, pathpoint1.totalPathDistance + pathpoint1.distanceToNext); + } else { + pathpoint1.distanceToTarget = pathpoint1.totalPathDistance + pathpoint1.distanceToNext; + this.path.addPoint(pathpoint1); + } + } + } + } + } + + Optional optional; + if (set.stream().anyMatch(FlaggedPathPoint::func_224762_f)) { + List toSort = new ArrayList<>(); + for (FlaggedPathPoint p_224778_2_ : set) { + if (p_224778_2_.func_224762_f()) { + Path func_224780_a = this.func_224780_a(p_224778_2_.func_224763_d(), p_227479_2_.get(p_224778_2_), true); + toSort.add(func_224780_a); + } + } + toSort.sort(Comparator.comparingInt(Path::getCurrentPathLength)); + Optional found = Optional.empty(); + for (Path func_224780_a : toSort) { + found = Optional.of(func_224780_a); + break; + } + optional = found; + } else { + List toSort = new ArrayList<>(); + for (FlaggedPathPoint p_224777_2_ : set) { + Path func_224780_a = this.func_224780_a(p_224777_2_.func_224763_d(), p_227479_2_.get(p_224777_2_), false); + toSort.add(func_224780_a); + } + toSort.sort(Comparator.comparingDouble(Path::func_224769_l).thenComparingInt(Path::getCurrentPathLength)); + Optional found = Optional.empty(); + for (Path func_224780_a : toSort) { + found = Optional.of(func_224780_a); + break; + } + optional = found; + } + + if (!optional.isPresent()) { + return null; + } else { + Path path = optional.get(); + return path; + } + } +} diff --git a/arclight-forge-1.15/src/main/resources/mixins.arclight.impl.optimization.stream.1_15.json b/arclight-forge-1.15/src/main/resources/mixins.arclight.impl.optimization.stream.1_15.json new file mode 100644 index 00000000..edddd49a --- /dev/null +++ b/arclight-forge-1.15/src/main/resources/mixins.arclight.impl.optimization.stream.1_15.json @@ -0,0 +1,10 @@ +{ + "minVersion": "0.8", + "package": "io.izzel.arclight.impl.mixin.v1_15.optimization.stream", + "target": "@env(DEFAULT)", + "refmap": "mixins.arclight.impl.refmap.1_15.json", + "mixins": [ + "GoalSelectorMixin", + "PathFinderMixin" + ] +} \ No newline at end of file