From 3a0d01633c37676a234a99782af5f28ca9159e3e Mon Sep 17 00:00:00 2001 From: gnembon Date: Mon, 20 May 2019 16:16:44 -0300 Subject: [PATCH] home and plop fail --- .../java/carpet/fakes/MobEntityInterface.java | 13 ++ .../carpet/mixins/ChunkGeneratorMixin.java | 28 +++++ src/main/java/carpet/mixins/ChunkMixin.java | 25 ++++ .../java/carpet/mixins/MobEntityMixin.java | 34 +++++ .../carpet/mixins/StructureFeatureMixin.javax | 119 ++++++++++++++++++ .../java/carpet/script/value/EntityValue.java | 30 ++--- src/main/resources/carpet.mixins.json | 2 + 7 files changed, 237 insertions(+), 14 deletions(-) create mode 100644 src/main/java/carpet/fakes/MobEntityInterface.java create mode 100644 src/main/java/carpet/mixins/ChunkGeneratorMixin.java create mode 100644 src/main/java/carpet/mixins/ChunkMixin.java create mode 100644 src/main/java/carpet/mixins/MobEntityMixin.java create mode 100644 src/main/java/carpet/mixins/StructureFeatureMixin.javax diff --git a/src/main/java/carpet/fakes/MobEntityInterface.java b/src/main/java/carpet/fakes/MobEntityInterface.java new file mode 100644 index 00000000..ddab20fc --- /dev/null +++ b/src/main/java/carpet/fakes/MobEntityInterface.java @@ -0,0 +1,13 @@ +package carpet.fakes; + +import net.minecraft.entity.ai.goal.Goal; +import net.minecraft.entity.ai.goal.GoalSelector; + +import java.util.Map; + +public interface MobEntityInterface +{ + public GoalSelector getAI(boolean target); + + public Map getTemporaryTasks(); +} diff --git a/src/main/java/carpet/mixins/ChunkGeneratorMixin.java b/src/main/java/carpet/mixins/ChunkGeneratorMixin.java new file mode 100644 index 00000000..a30e002c --- /dev/null +++ b/src/main/java/carpet/mixins/ChunkGeneratorMixin.java @@ -0,0 +1,28 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.FeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ChunkGenerator.class) +public abstract class ChunkGeneratorMixin +{ + + ///used for plop - changed in 1.14 - feature needs reimplemnting + + @Inject(method = "hasStructure", at = @At("HEAD"), cancellable = true) + private void skipGenerationBiomeChecks(Biome biome_1, StructureFeature structureFeature_1, CallbackInfoReturnable cir) + { + if (CarpetSettings.skipGenerationChecks) + { + cir.setReturnValue(true); + cir.cancel(); + } + } +} diff --git a/src/main/java/carpet/mixins/ChunkMixin.java b/src/main/java/carpet/mixins/ChunkMixin.java new file mode 100644 index 00000000..75994ed6 --- /dev/null +++ b/src/main/java/carpet/mixins/ChunkMixin.java @@ -0,0 +1,25 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.Chunk; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Chunk.class) +public abstract class ChunkMixin +{ + + ///used for plop - changed in 1.14 - feature needs reimplemnting + + + @Inject(method = "markBlockForPostProcessing(Lnet/minecraft/util/math/BlockPos;)V", + at =@At("HEAD"), cancellable = true) + private void squashWarnings(BlockPos blockPos_1, CallbackInfo ci) + { + if (CarpetSettings.skipGenerationChecks) ci.cancel(); + } + +} diff --git a/src/main/java/carpet/mixins/MobEntityMixin.java b/src/main/java/carpet/mixins/MobEntityMixin.java new file mode 100644 index 00000000..daa3cee4 --- /dev/null +++ b/src/main/java/carpet/mixins/MobEntityMixin.java @@ -0,0 +1,34 @@ +package carpet.mixins; + +import carpet.fakes.MobEntityInterface; +import net.minecraft.entity.ai.goal.Goal; +import net.minecraft.entity.ai.goal.GoalSelector; +import net.minecraft.entity.mob.MobEntity; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.HashMap; +import java.util.Map; + +@Mixin(MobEntity.class) +public abstract class MobEntityMixin implements MobEntityInterface +{ + @Shadow @Final protected GoalSelector targetSelector; + @Shadow @Final protected GoalSelector goalSelector; + public final Map temporaryTasks = new HashMap<>(); + + @Override + public GoalSelector getAI(boolean target) + { + return target?targetSelector:goalSelector; + } + + @Override + public Map getTemporaryTasks() + { + return temporaryTasks; + } + + +} diff --git a/src/main/java/carpet/mixins/StructureFeatureMixin.javax b/src/main/java/carpet/mixins/StructureFeatureMixin.javax new file mode 100644 index 00000000..c9de4164 --- /dev/null +++ b/src/main/java/carpet/mixins/StructureFeatureMixin.javax @@ -0,0 +1,119 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import net.minecraft.structure.StructureStart; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.IWorld; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.chunk.ChunkGeneratorConfig; +import net.minecraft.world.gen.feature.StructureFeature; +import org.spongepowered.asm.mixin.Mixin; + +import java.util.Random; + +@Mixin(StructureFeature.class) +public class StructureFeatureMixin +{ + //problem is that is seems that now chunks deal with its portion of the strucuture + //on its own. + + public boolean plopAnywhere(IWorld world, BlockPos pos) + { + return plopAnywhere(world, pos, world.getChunkManager().getChunkGenerator()); + } + public boolean plopAnywhere(IWorld world, BlockPos pos, ChunkGenerator generator) + { + CarpetSettings.skipGenerationChecks = true; + try + { + Random rand = new Random(world.getRandom().nextInt()); + int j = pos.getX() >> 4; + int k = pos.getZ() >> 4; + long chId = ChunkPos.toLong(j, k); + StructureStart structurestart = forceStructureStart(world, generator, rand, chId); + if (structurestart == null || structurestart == StructureStart.DEFAULT) + { + CarpetSettings.skipGenerationChecks = false; + return false; + } + generator.ge getStructurePositionToReferenceMap(this).computeIfAbsent(chId, (x) -> new LongOpenHashSet()).add(chId); + world.getChunkManager().getChunkOrPrimer(j, k, true).addStructureReference(this.getStructureName(), chId); + MutableBoundingBox box = structurestart.getBoundingBox(); + structurestart.generateStructure( + world, + rand, + new MutableBoundingBox( + pos.getX() - this.getSize()*16, + pos.getZ() - this.getSize()*16, + pos.getX() + (this.getSize()+1)*16, + pos.getZ() + (1+this.getSize())*16), + new ChunkPos(j, k) + ); + structurestart.notifyPostProcessAt(new ChunkPos(j, k)); + + int i = this.getSize(); + for (int k1 = j - i; k1 <= j + i; ++k1) + { + for (int l1 = k - i; l1 <= k + i; ++l1) + { + if (k1 == j && l1 == k) continue; + long nbchkid = ChunkPos.toLong(k1, l1); + if (box.intersectsWith(k1<<4, l1<<4, (k1<<4) + 15, (l1<<4) + 15)) + { + generator.getStructurePositionToReferenceMap(this).computeIfAbsent(nbchkid, (__) -> new LongOpenHashSet()).add(chId); + world.getChunkManager().getChunkOrPrimer(k1, l1, true).addStructureReference(this.getStructureName(), chId); + structurestart.notifyPostProcessAt(new ChunkPos(k1, l1)); + } + } + } + } + catch (Exception ignored) + { + CarpetSettings.LOG.error("Unknown Exception while plopping structure: "+ignored); + ignored.printStackTrace(); + CarpetSettings.skipGenerationChecks = false; + return false; + } + CarpetSettings.skipGenerationChecks = false; + return true; + } + + private StructureStart forceStructureStart(IWorld worldIn, ChunkGenerator generator, Random rand, long packedChunkPos) + { + + Long2ObjectMap long2objectmap = generator.getStructureReferenceToStartMap(this); + StructureStart structurestart = long2objectmap.get(packedChunkPos); + + if (structurestart != null) + { + return structurestart; // structure already exist, will skip + } + ChunkPos chunkpos = new ChunkPos(packedChunkPos); + IChunk ichunk = worldIn.getChunkManager().getChunkOrPrimer(chunkpos.x, chunkpos.z, false); + + if (ichunk != null) + { + structurestart = ichunk.getStructureStart(this.getStructureName()); + + if (structurestart != null) + { + long2objectmap.put(packedChunkPos, structurestart); + return structurestart; + } + } + + StructureStart structurestart1 = this.makeStart(worldIn, generator, rand, chunkpos.x, chunkpos.z); + structurestart = structurestart1.isValid() ? structurestart1 : NO_STRUCTURE; + + if (structurestart.isValid()) + { + worldIn.getChunkManager().getChunkOrPrimer(chunkpos.x, chunkpos.z, true).putStructureStart(this.getStructureName(), structurestart); + } + + long2objectmap.put(packedChunkPos, structurestart); + return structurestart; + } +} diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index bc4863d1..de752ca2 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -1,5 +1,6 @@ package carpet.script.value; +import carpet.fakes.MobEntityInterface; import carpet.script.exception.InternalExpressionException; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -192,13 +193,13 @@ public class EntityValue extends Value } return Value.NULL; }); - /*put("home", (e, a) -> { - if (e instanceof MobEntityWithAi) + put("home", (e, a) -> { + if (e instanceof MobEntity) { - return ((MobEntityWithAi) e).has hasHome()?new BlockValue(null, e.getEntityWorld(), ((MobEntityWithAi) e).getHomePosition()):Value.FALSE; + return (((MobEntity) e).getWalkTargetRange () > 0)?new BlockValue(null, e.getEntityWorld(), ((MobEntityWithAi) e).getWalkTarget()):Value.FALSE; } return Value.NULL; - });*/ + }); put("sneaking", (e, a) -> e.isSneaking()?Value.TRUE:Value.FALSE); put("sprinting", (e, a) -> e.isSprinting()?Value.TRUE:Value.FALSE); put("swimming", (e, a) -> e.isSwimming()?Value.TRUE:Value.FALSE); @@ -523,7 +524,7 @@ public class EntityValue extends Value // if (e instanceof MobEntity) // { // LivingEntity elb = assertEntityArgType(LivingEntity.class, v); - // ((MobEntity) e).setAttackTarget(elb); + // ((MobEntity) e).setTarget(elb); // } //}); put("talk", (e, v) -> { @@ -533,7 +534,6 @@ public class EntityValue extends Value ((MobEntity) e).playAmbientSound(); } }); - /* put("home", (e, v) -> { if (!(e instanceof MobEntityWithAi)) return; @@ -542,9 +542,10 @@ public class EntityValue extends Value throw new InternalExpressionException("home requires at least one position argument, and optional distance, or null to cancel"); if (v instanceof NullValue) { - ec.detachHome(); - ec.getAI(false).removeTask(ec.temporaryTasks.get("home")); - ec.temporaryTasks.remove("home"); + ec.setWalkTarget(BlockPos.ORIGIN, -1); + Map tasks = ((MobEntityInterface)ec).getTemporaryTasks(); + ((MobEntityInterface)ec).getAI(false).remove(tasks.get("home")); + tasks.remove("home"); return; } @@ -582,14 +583,15 @@ public class EntityValue extends Value } else throw new InternalExpressionException("home requires at least one position argument, and optional distance"); - ec.setHomePosAndDistance(pos, distance); - if (!ec.temporaryTasks.containsKey("home")) + ec.setWalkTarget(pos, distance); + Map tasks = ((MobEntityInterface)ec).getTemporaryTasks(); + if (!tasks.containsKey("home")) { Goal task = new GoToWalkTargetGoal(ec, 1.0D); - ec.temporaryTasks.put("home", task); - ec.getAI(false).addTask(10, task); + tasks.put("home", task); + ((MobEntityInterface)ec).getAI(false).add(10, task); } - });*/ //requires mixing + }); //requires mixing // gamemode // spectate diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index c9262b34..99c3d47c 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -21,6 +21,8 @@ "ServerWorld_tickMixin", "ServerChunkManager_tickMixin", + "MobEntityMixin", + "MinecraftServer_motdMixin", "ServerPlayNetworkHandlerMixin", "MinecraftServer_scarpetMixin",