mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-09 17:26:07 +00:00
Growing
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
package com.dfsek.terra.fabric;
|
||||
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmInitializer;
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmRegistry;
|
||||
|
||||
import com.dfsek.terra.fabric.util.FabricLoaderUtil;
|
||||
import com.dfsek.terra.lifecycle.asm.FertilizableASM;
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
|
||||
|
||||
public class FabricASMEntryPoint implements AsmInitializer {
|
||||
@Override
|
||||
public void onInitializeAsm() {
|
||||
LoaderUtil.INSTANCE = new FabricLoaderUtil();
|
||||
AsmRegistry.getInstance().registerTransformer(new FertilizableASM());
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.dfsek.terra.fabric.util;
|
||||
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
|
||||
public class FabricLoaderUtil extends LoaderUtil {
|
||||
@Override
|
||||
public String mapClassName(String namespace, String className) {
|
||||
return FabricLoader.getInstance().getMappingResolver().mapClassName(namespace, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapMethodName(String namespace, String owner, String name, String descriptor) {
|
||||
return FabricLoader.getInstance().getMappingResolver().mapMethodName(namespace, owner, name, descriptor);
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,6 @@
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"com.dfsek.terra.fabric.FabricEntryPoint"
|
||||
],
|
||||
"gud_asm": [
|
||||
"com.dfsek.terra.fabric.FabricASMEntryPoint"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.dfsek.terra.mod.config.BiomeAdditionsSoundTemplate;
|
||||
import com.dfsek.terra.mod.config.BiomeMoodSoundTemplate;
|
||||
import com.dfsek.terra.mod.config.BiomeParticleConfigTemplate;
|
||||
import com.dfsek.terra.mod.config.EntityTypeTemplate;
|
||||
import com.dfsek.terra.mod.config.FertilizableConfig;
|
||||
import com.dfsek.terra.mod.config.MusicSoundTemplate;
|
||||
import com.dfsek.terra.mod.config.ProtoPlatformBiome;
|
||||
import com.dfsek.terra.mod.config.SoundEventTemplate;
|
||||
@@ -95,7 +96,8 @@ public abstract class ModPlatform extends AbstractPlatform {
|
||||
.registerLoader(SpawnEntry.class, SpawnEntryTemplate::new)
|
||||
.registerLoader(SpawnTypeConfig.class, SpawnTypeConfig::new)
|
||||
.registerLoader(SpawnSettings.class, SpawnSettingsTemplate::new)
|
||||
.registerLoader(VillagerType.class, VillagerTypeTemplate::new);
|
||||
.registerLoader(VillagerType.class, VillagerTypeTemplate::new)
|
||||
.registerLoader(FertilizableConfig.class, FertilizableConfig::new);
|
||||
}
|
||||
|
||||
private ProtoPlatformBiome parseBiome(String id, DepthTracker tracker) throws LoadException {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.dfsek.terra.mod.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class FertilizableConfig implements ObjectTemplate<FertilizableConfig> {
|
||||
@Value("strucutres")
|
||||
@Default
|
||||
private ProbabilityCollection<ConfiguredStructure> structures = null;
|
||||
|
||||
@Value("cooldowns")
|
||||
@Default
|
||||
private Map<Identifier, Double> cooldowns = null;
|
||||
|
||||
@Value("can-grow")
|
||||
@Default
|
||||
private ConfiguredStructure canGrow = null;
|
||||
|
||||
@Value("villager-fertilizable")
|
||||
@Default
|
||||
private Boolean villagerFertilizable = null;
|
||||
|
||||
public ProbabilityCollection<ConfiguredStructure> getStructures() {
|
||||
return structures;
|
||||
}
|
||||
|
||||
public Map<Identifier, Double> getCooldowns() {
|
||||
return cooldowns;
|
||||
}
|
||||
|
||||
public ConfiguredStructure getCanGrow() {
|
||||
return canGrow;
|
||||
}
|
||||
|
||||
public Boolean isVillagerFertilizable() {
|
||||
return villagerFertilizable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FertilizableConfig get() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -20,15 +20,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
|
||||
@Value("minecraft.fertilizables")
|
||||
@Default
|
||||
private Map<Identifier, ProbabilityCollection<ConfiguredStructure>> fertilizables = Collections.emptyMap();
|
||||
private Map<Identifier, FertilizableConfig> fertilizables = Collections.emptyMap();
|
||||
|
||||
@Value("minecraft.tags")
|
||||
@Default
|
||||
@@ -106,7 +104,7 @@ public class VanillaBiomeProperties implements ConfigTemplate, Properties {
|
||||
@Default
|
||||
private VillagerType villagerType = null;
|
||||
|
||||
public Map<Identifier, ProbabilityCollection<ConfiguredStructure>> getFertilizables() {
|
||||
public Map<Identifier, FertilizableConfig> getFertilizables() {
|
||||
return fertilizables;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.dfsek.terra.mod.CommonPlatform;
|
||||
MoveToHiveGoal.class,
|
||||
MoveToFlowerGoal.class
|
||||
})
|
||||
public class BeeMoveGoalsUnsynchronizedRandomAccessFix {
|
||||
public class BeeMoveGoalsUnsynchronizedRandomAccessFixMixin {
|
||||
@Redirect(method = "<init>",
|
||||
at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;random:Lnet/minecraft/util/math/random/Random;"))
|
||||
public Random redirectRandomAccess(World instance) {
|
||||
@@ -20,7 +20,7 @@ import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper;
|
||||
* nether.
|
||||
*/
|
||||
@Mixin(NetherFossilStructure.class)
|
||||
public class NetherFossilOptimization {
|
||||
public class NetherFossilOptimizationMixin {
|
||||
@Inject(method = "getStructurePosition", at = @At("HEAD"), cancellable = true)
|
||||
public void injectFossilPositions(Context context, CallbackInfoReturnable<Optional<StructurePosition>> cir) {
|
||||
if(context.chunkGenerator() instanceof MinecraftChunkGeneratorWrapper) {
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.mod.mixin.gameplay;
|
||||
|
||||
|
||||
import net.minecraft.item.BoneMealItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
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;
|
||||
|
||||
import com.dfsek.terra.mod.util.FertilizableUtil;
|
||||
|
||||
|
||||
@Mixin(BoneMealItem.class)
|
||||
public class BoneMealItemMixin {
|
||||
private static final Identifier cooldownId = new Identifier("terra", "bone_meal_cooldown");
|
||||
|
||||
@Inject(method = "useOnFertilizable", at = @At("HEAD"), cancellable = true)
|
||||
private static void injectUseOnFertilizable(ItemStack stack, World world, BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
|
||||
if(world instanceof ServerWorld) {
|
||||
Boolean value = FertilizableUtil.grow((ServerWorld) world, pos, world.getBlockState(pos), cooldownId);
|
||||
stack.decrement(1);
|
||||
if(value != null) {
|
||||
cir.setReturnValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.dfsek.terra.mod.mixin.gameplay;
|
||||
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.ai.brain.task.BoneMealTask;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
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;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
import com.dfsek.terra.api.world.WritableWorld;
|
||||
import com.dfsek.terra.mod.config.FertilizableConfig;
|
||||
import com.dfsek.terra.mod.util.BiomeUtil;
|
||||
|
||||
|
||||
@Mixin(BoneMealTask.class)
|
||||
public class BoneMealTaskMixin {
|
||||
|
||||
@Inject(method = "canBoneMeal", at = @At("HEAD"), cancellable = true)
|
||||
public void injectCanBoneMeal(BlockPos pos, ServerWorld world, CallbackInfoReturnable<Boolean> cir) {
|
||||
Map<Identifier, FertilizableConfig> map = BiomeUtil.TERRA_BIOME_FERTILIZABLE_MAP.get(world.getBiome(pos));
|
||||
if(map != null) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
Block block = blockState.getBlock();
|
||||
FertilizableConfig config = map.get(Registry.BLOCK.getId(block));
|
||||
if(config != null) {
|
||||
Boolean villagerFertilizable = config.isVillagerFertilizable();
|
||||
if(villagerFertilizable != null) {
|
||||
if(villagerFertilizable) {
|
||||
ConfiguredStructure canGrow = config.getCanGrow();
|
||||
if(canGrow != null) {
|
||||
Random random = (Random) world.getRandom();
|
||||
cir.setReturnValue(canGrow.getStructure().get(random).generate(
|
||||
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, random, Rotation.NONE));
|
||||
return;
|
||||
}
|
||||
cir.setReturnValue(true);
|
||||
return;
|
||||
}
|
||||
cir.setReturnValue(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.mod.mixin.gameplay;
|
||||
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import com.dfsek.terra.mod.util.FertilizableUtil;
|
||||
|
||||
|
||||
@Mixin(ServerWorld.class)
|
||||
public class ServerWorldMixin {
|
||||
private static final Identifier cooldownId = new Identifier("terra", "random_cooldown");
|
||||
|
||||
@Redirect(method = "tickChunk",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/BlockState;randomTick(Lnet/minecraft/server/world/ServerWorld;" +
|
||||
"Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/random/Random;)V"))
|
||||
public void injectTickChunk(BlockState instance, ServerWorld serverWorld, BlockPos blockPos, Random random) {
|
||||
Boolean value = FertilizableUtil.grow(serverWorld, blockPos, instance, cooldownId);
|
||||
if(value != null) {
|
||||
if(!value) {
|
||||
instance.randomTick(serverWorld, blockPos, random);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,10 +17,9 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.mod.CommonPlatform;
|
||||
import com.dfsek.terra.mod.config.FertilizableConfig;
|
||||
import com.dfsek.terra.mod.config.ProtoPlatformBiome;
|
||||
import com.dfsek.terra.mod.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.mod.mixin.access.VillagerTypeAccessor;
|
||||
@@ -29,7 +28,7 @@ import com.dfsek.terra.mod.mixin.access.VillagerTypeAccessor;
|
||||
public class BiomeUtil {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BiomeUtil.class);
|
||||
|
||||
public static final Map<RegistryEntry<net.minecraft.world.biome.Biome>, Map<Identifier, ProbabilityCollection<ConfiguredStructure>>>
|
||||
public static final Map<RegistryEntry<net.minecraft.world.biome.Biome>, Map<Identifier, FertilizableConfig>>
|
||||
TERRA_BIOME_FERTILIZABLE_MAP = new HashMap<>();
|
||||
|
||||
public static final Map<TagKey<net.minecraft.world.biome.Biome>, List<Identifier>>
|
||||
|
||||
@@ -1,34 +1,54 @@
|
||||
package com.dfsek.terra.mod.util;
|
||||
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
|
||||
import com.dfsek.terra.api.world.WritableWorld;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
import com.dfsek.terra.api.world.WritableWorld;
|
||||
import com.dfsek.terra.mod.config.FertilizableConfig;
|
||||
|
||||
|
||||
public class FertilizableUtil {
|
||||
public static boolean grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
|
||||
Map<Identifier, ProbabilityCollection<ConfiguredStructure>> fertilizables = BiomeUtil.TERRA_BIOME_FERTILIZABLE_MAP.get(world.getBiome(pos));
|
||||
if (fertilizables != null) {
|
||||
ProbabilityCollection<ConfiguredStructure> probabilityCollection = fertilizables.get(Registry.BLOCK.getId(state.getBlock()));
|
||||
if (probabilityCollection != null) {
|
||||
ConfiguredStructure structure = probabilityCollection.get((java.util.Random) random);
|
||||
structure.getStructure().get((java.util.Random) random).generate(Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, (java.util.Random) random, Rotation.NONE);
|
||||
|
||||
private static final Random mojankRandom = new Random();
|
||||
|
||||
public static Boolean grow(ServerWorld world, BlockPos pos, BlockState state, Identifier cooldownId) {
|
||||
return grow(world, mojankRandom, pos, state, cooldownId);
|
||||
}
|
||||
|
||||
public static Boolean grow(ServerWorld world, Random random, BlockPos pos, BlockState state, Identifier cooldownId) {
|
||||
Map<Identifier, FertilizableConfig> map = BiomeUtil.TERRA_BIOME_FERTILIZABLE_MAP.get(world.getBiome(pos));
|
||||
if(map != null) {
|
||||
Block block = state.getBlock();
|
||||
FertilizableConfig config = map.get(Registry.BLOCK.getId(block));
|
||||
if(config != null) {
|
||||
ConfiguredStructure canGrow = config.getCanGrow();
|
||||
if(canGrow != null) {
|
||||
if(!canGrow.getStructure().get(random).generate(
|
||||
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, random, Rotation.NONE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Double cooldown = config.getCooldowns().get(cooldownId);
|
||||
if(cooldown != null) {
|
||||
if(random.nextFloat() > cooldown) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
config.getStructures().get(random).getStructure().get(random).generate(
|
||||
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, random, Rotation.NONE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
"access.StateAccessor",
|
||||
"access.StructureAccessorAccessor",
|
||||
"access.VillagerTypeAccessor",
|
||||
"fix.BeeMoveGoalsUnsynchronizedRandomAccessFix",
|
||||
"fix.NetherFossilOptimization",
|
||||
"fix.BeeMoveGoalsUnsynchronizedRandomAccessFixMixin",
|
||||
"fix.NetherFossilOptimizationMixin",
|
||||
"gameplay.BoneMealItemMixin",
|
||||
"gameplay.BoneMealTaskMixin",
|
||||
"gameplay.ServerWorldMixin",
|
||||
"implementations.compat.GenerationSettingsFloraFeaturesMixin",
|
||||
"implementations.terra.BiomeMixin",
|
||||
"implementations.terra.HandleImplementationMixin",
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.dfsek.terra.lifecycle.asm;
|
||||
|
||||
import net.gudenau.minecraft.asm.api.v1.Identifier;
|
||||
import net.gudenau.minecraft.asm.api.v1.Transformer;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.JumpInsnNode;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.VarInsnNode;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.dfsek.terra.lifecycle.util.ASMUtil;
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
import com.dfsek.terra.mod.util.FertilizableUtil;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
|
||||
|
||||
public class FertilizableASM implements Transformer {
|
||||
|
||||
private static String fertilizableClassName = LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_2256");
|
||||
|
||||
private static String fertilizableGrowMethodSignatureBase = String.format("(L%1$s;L%2$s;L%3$s;L%4$s;)",
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_3218").replace(".", "/"),
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_5819").replace(".", "/"),
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_2338").replace(".", "/"),
|
||||
LoaderUtil.INSTANCE.mapClassName("intermediary", "net.minecraft.class_2680").replace(".", "/"));
|
||||
|
||||
private static String fertilizableGrowMethodSignature = fertilizableGrowMethodSignatureBase + "V";
|
||||
|
||||
private static String fertilizableGrowMethodName = LoaderUtil.INSTANCE.mapMethodName("intermediary", "net.minecraft.class_2256", "method_9652", "(Lnet/minecraft/class_3218;Lnet/minecraft/class_5819;Lnet/minecraft/class_2338;Lnet/minecraft/class_2680;)V");
|
||||
|
||||
@Override
|
||||
public Identifier getName() {
|
||||
return new Identifier("terra", "asm_test");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlesClass(String name, String transformedName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform(ClassNode classNode, Flags flags) {
|
||||
try {
|
||||
if (ASMUtil.inheritsFrom(classNode, fertilizableClassName.replace(".", "/"))) {
|
||||
for (MethodNode method : classNode.methods) {
|
||||
if (method.name.equals(fertilizableGrowMethodName)) {
|
||||
if ((method.access & ACC_STATIC) == 0) {
|
||||
if(method.desc.equals(fertilizableGrowMethodSignature)) {
|
||||
InsnList list = new InsnList();
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 1));
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 2));
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 3));
|
||||
list.add(new VarInsnNode(Opcodes.ALOAD, 4));
|
||||
list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, FertilizableUtil.class.getName().replace(".", "/"), "grow", fertilizableGrowMethodSignatureBase + "Z", false));
|
||||
LabelNode jmp = new LabelNode();
|
||||
list.add(new JumpInsnNode(Opcodes.IFNE, jmp));
|
||||
list.add(new InsnNode(Opcodes.RETURN));
|
||||
list.add(jmp);
|
||||
method.instructions.insertBefore(method.instructions.getFirst(), list);
|
||||
flags.requestFrames();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.dfsek.terra.lifecycle.util;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import static org.objectweb.asm.ClassReader.SKIP_CODE;
|
||||
import static org.objectweb.asm.ClassReader.SKIP_DEBUG;
|
||||
import static org.objectweb.asm.ClassReader.SKIP_FRAMES;
|
||||
|
||||
|
||||
public class ASMUtil {
|
||||
static final ThreadLocal<WeakHashMap<String, WeakHashMap<String, Boolean>>> INHERITANCE_CACHE = new ThreadLocal<>();
|
||||
|
||||
public static boolean inheritsFrom(ClassNode classNode, String interfaceName) throws IOException {
|
||||
if (INHERITANCE_CACHE.get() == null) {
|
||||
INHERITANCE_CACHE.set(new WeakHashMap<>());
|
||||
}
|
||||
return inheritsFromInternal(classNode, interfaceName);
|
||||
}
|
||||
|
||||
protected static boolean inheritsFromInternal(ClassNode classNode, String interfaceName) throws IOException {
|
||||
if (INHERITANCE_CACHE.get().containsKey(classNode.name)) {
|
||||
if (INHERITANCE_CACHE.get().get(classNode.name).containsKey(interfaceName)) {
|
||||
return INHERITANCE_CACHE.get().get(classNode.name).get(interfaceName);
|
||||
}
|
||||
}
|
||||
for (String parent : classNode.interfaces) {
|
||||
if (checkClass(parent, interfaceName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (checkClass(classNode.superName, interfaceName)) {
|
||||
return true;
|
||||
}
|
||||
INHERITANCE_CACHE.get().getOrDefault(classNode.name, new WeakHashMap<>()).put(interfaceName, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static boolean checkClass(String name, String interfaceName) throws IOException {
|
||||
if (name.startsWith("java/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isClass = name.equals(interfaceName);
|
||||
INHERITANCE_CACHE.get().getOrDefault(name, new WeakHashMap<>()).put(interfaceName, isClass);
|
||||
if (isClass) {
|
||||
return true;
|
||||
}
|
||||
ClassNode node = new ClassNode();
|
||||
new ClassReader(name).accept(node, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
||||
return inheritsFromInternal(node, interfaceName);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.dfsek.terra.quilt;
|
||||
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmInitializer;
|
||||
import net.gudenau.minecraft.asm.api.v1.AsmRegistry;
|
||||
|
||||
import com.dfsek.terra.lifecycle.asm.FertilizableASM;
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
import com.dfsek.terra.quilt.util.QuiltLoaderUtil;
|
||||
|
||||
|
||||
public class QuiltASMEntryPoint implements AsmInitializer {
|
||||
@Override
|
||||
public void onInitializeAsm() {
|
||||
LoaderUtil.INSTANCE = new QuiltLoaderUtil();
|
||||
AsmRegistry.getInstance().registerTransformer(new FertilizableASM());
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.dfsek.terra.quilt.util;
|
||||
|
||||
import com.dfsek.terra.lifecycle.util.LoaderUtil;
|
||||
|
||||
import org.quiltmc.loader.api.QuiltLoader;
|
||||
|
||||
|
||||
public class QuiltLoaderUtil extends LoaderUtil {
|
||||
@Override
|
||||
public String mapClassName(String namespace, String className) {
|
||||
return QuiltLoader.getMappingResolver().mapClassName(namespace, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapMethodName(String namespace, String owner, String name, String descriptor) {
|
||||
return QuiltLoader.getMappingResolver().mapMethodName(namespace, owner, name, descriptor);
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,6 @@
|
||||
],
|
||||
"pre_launch": [
|
||||
"com.dfsek.terra.quilt.QuiltPreLaunchEntryPoint"
|
||||
],
|
||||
"gud_asm": [
|
||||
"com.dfsek.terra.quilt.QuiltASMEntryPoint"
|
||||
]
|
||||
},
|
||||
"depends": [
|
||||
|
||||
Reference in New Issue
Block a user