From 0facf0b639226d8f9848eaa1a0b7e2a7f9c6305f Mon Sep 17 00:00:00 2001 From: Ellie Date: Mon, 5 Feb 2024 19:16:50 -0300 Subject: [PATCH] add optimizedTNTEdgeCases --- build.gradle | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle | 3 +- .../java/me/lntricate/intricarpet/Rules.java | 6 + .../helpers/OptimizedExplosion.java | 377 ++++++++++++++++++ .../mixins/ExplosionDamageAccessor.java | 18 + .../mixins/OptimizedExplosionMixin.java | 33 ++ .../mixins/interactions/ChunkMapMixin.java | 16 +- src/main/resources/intricarpet.mixins.json | 3 + versions/1.17.1/.factorypath | 50 +-- versions/1.18.2/.factorypath | 50 +-- versions/1.19.2/.factorypath | 66 +-- versions/1.19.3/.factorypath | 67 +--- versions/1.19.4/.factorypath | 66 +-- versions/1.20.1/.factorypath | 66 +-- versions/1.20.2/.factorypath | 67 ++++ versions/1.20.2/gradle.properties | 16 + 17 files changed, 581 insertions(+), 331 deletions(-) create mode 100644 src/main/java/me/lntricate/intricarpet/helpers/OptimizedExplosion.java create mode 100644 src/main/java/me/lntricate/intricarpet/mixins/ExplosionDamageAccessor.java create mode 100644 src/main/java/me/lntricate/intricarpet/mixins/OptimizedExplosionMixin.java create mode 100644 versions/1.20.2/.factorypath create mode 100644 versions/1.20.2/gradle.properties diff --git a/build.gradle b/build.gradle index 7f63046..787d84a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'maven-publish' - id 'fabric-loom' version '1.1-SNAPSHOT' apply false - id 'com.replaymod.preprocess' version 'e1050f4d72' + id 'fabric-loom' version '1.3-SNAPSHOT' apply false + id 'com.replaymod.preprocess' version '20c7ec554a' } preprocess { @@ -14,6 +14,7 @@ preprocess { def mc1193 = createNode('1.19.3' , 1_19_03, 'yarn') def mc1194 = createNode('1.19.4' , 1_19_04, 'yarn') def mc1201 = createNode('1.20.1' , 1_20_01, 'yarn') + def mc1202 = createNode('1.20.2' , 1_20_02, 'yarn') // def mcSnapshot = createNode('snapshot', 1_19_00, 'yarn') // mc115.link(mc114, null) @@ -25,6 +26,7 @@ preprocess { mc1192.link(mc1193, null) mc1193.link(mc1194, null) mc1194.link(mc1201, null) + mc1201.link(mc1202, null) // mc119.link(mcSnapshot, null) } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e1bef7e..db9a6b8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index 2852c08..b1c68fa 100644 --- a/settings.gradle +++ b/settings.gradle @@ -32,7 +32,8 @@ def versions = Arrays.asList( "1.19.2", "1.19.3", "1.19.4", - "1.20.1" + "1.20.1", + "1.20.2" // "snapshot", ) for (String version : versions) { diff --git a/src/main/java/me/lntricate/intricarpet/Rules.java b/src/main/java/me/lntricate/intricarpet/Rules.java index a0de80e..77d3a4e 100644 --- a/src/main/java/me/lntricate/intricarpet/Rules.java +++ b/src/main/java/me/lntricate/intricarpet/Rules.java @@ -10,4 +10,10 @@ public class Rules options = {"true", "false", "ops"} ) public static String commandInteraction = "ops"; + + @Rule( + desc = "Enables edge case fixes in optimizedTNT, at the cost of a bit less optimization", + category = {"COMMAND", "intricarpet"} + ) + public static boolean optimizedTNTEdgeCases = false; } diff --git a/src/main/java/me/lntricate/intricarpet/helpers/OptimizedExplosion.java b/src/main/java/me/lntricate/intricarpet/helpers/OptimizedExplosion.java new file mode 100644 index 0000000..28c7025 --- /dev/null +++ b/src/main/java/me/lntricate/intricarpet/helpers/OptimizedExplosion.java @@ -0,0 +1,377 @@ +package me.lntricate.intricarpet.helpers; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.lang3.tuple.Pair; + +import com.google.common.collect.Sets; + +import carpet.mixins.ExplosionAccessor; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import me.lntricate.intricarpet.logging.logHelpers.ExplosionLogHelper; +import me.lntricate.intricarpet.mixins.ExplosionDamageAccessor; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.item.PrimedTnt; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.ProtectionEnchantment; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.ExplosionDamageCalculator; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; + +/* + * WIP optimizedTNT rewrite + */ +public class OptimizedExplosion +{ + private static Explosion explosion; + private static ExplosionAccessor eAccess; + private static ExplosionDamageAccessor eAccess2; + + // Explosion data + private static double ex, ey, ez; + private static Vec3 pos; + private static Level level; + private static float power; + private static List toBlow = new ArrayList<>(); + + // For checking + private static long memTick = 0; + private static Vec3 memPos; + private static float memPower; + private static ExplosionDamageCalculator memDamageCalculator; + + // For using + private static List memEntities; + private static Map memVelocity = new HashMap<>(); + private static Map> memBlocks = new HashMap<>(); + + private static final Vec3[] RAYS = new Vec3[1352]; + + static + { + int i = 0; + for(int x = 0; x < 16; ++x) + for(int y = 0; y < 16; ++y) + for(int z = 0; z < 16; ++z) + if(x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) + { + double dx = x / 15f * 2f - 1f; + double dy = y / 15f * 2f - 1f; + double dz = z / 15f * 2f - 1f; + double mag = Math.sqrt(dx*dx + dy*dy + dz*dz); + RAYS[i++] = new Vec3(dx / mag * 0.3f, dy / mag * 0.3f, dz / mag * 0.3f); + } + } + + private static final class EntityKey + { + private final ExposureKey exposureKey; + private final float eyeHeight; + private final Integer hash; + + EntityKey(Entity entity) + { + exposureKey = new ExposureKey(entity); + eyeHeight = entity.getEyeHeight(); + hash = entity instanceof LivingEntity ? entity.hashCode() : null; + } + } + + private static final class ExposureKey + { + public final double x, y, z; + public final AABB aabb; + + ExposureKey(Entity entity) + { + x = entity.getX(); + y = entity.getY(); + z = entity.getZ(); + aabb = entity.getBoundingBox(); + } + } + + public static void doExplosionA(Explosion e, ExplosionLogHelper logger) + { + setExplosion(e); + checkMem(); + collectBlocks(); + pushEntities(); + } + + public static void setExplosion(Explosion e) + { + explosion = e; + eAccess = (ExplosionAccessor)explosion; + eAccess2 = (ExplosionDamageAccessor)explosion; + + ex = eAccess.getX(); ey = eAccess.getY(); eAccess.getZ(); + pos = new Vec3(ex, ey, ez); + level = eAccess.getWorld(); + power = eAccess.getPower(); + toBlow.clear(); + } + + public static void checkMem() + { + if(memPos.equals(pos) && memTick == level.getGameTime() && memPower == power) + return; + + if(memTick != level.getGameTime() || eAccess2.getDamageCalculator() != memDamageCalculator) + { + memBlocks.clear(); + memDamageCalculator = eAccess2.getDamageCalculator(); + } + + memPos = pos; + memTick = level.getGameTime(); + memPower = power; + + memVelocity.clear(); + + double x = eAccess.getX(); double y = eAccess.getY(); double z = eAccess.getZ(); + int minX = Mth.floor(x - power - 1d); + int maxX = Mth.floor(x - power - 1d); + int minY = Mth.floor(y - power - 1d); + int maxY = Mth.floor(y - power - 1d); + int minZ = Mth.floor(z - power - 1d); + int maxZ = Mth.floor(z - power - 1d); + + Entity tnt = eAccess2.getSource(); + memEntities = level.getEntities(tnt, new AABB(minX, minY, minZ, maxX, maxY, maxZ)); + + Iterator iter = memEntities.iterator(); + while(iter.hasNext()) + if(iter.next().ignoreExplosion()) + iter.remove(); + + if(tnt != null) + { + memEntities.remove(tnt); + if(tnt instanceof PrimedTnt && tnt.isOnGround()) + { + iter = memEntities.iterator(); + while(iter.hasNext()) + { + Entity entity = iter.next(); + if(entity instanceof PrimedTnt && + entity.getX() == tnt.getX() && + entity.getY() == tnt.getY() && + entity.getZ() == tnt.getZ()) + { + iter.remove(); + } + } + } + } + } + + private static void doRay(HashSet blocks, Vec3 rayPos, Vec3 delta, ExplosionDamageCalculator damageCalculator, float rand) + { + for(float rayStrength = power * (0.7F + rand * 0.6F); rayStrength > 0F; rayStrength -= 0.22500001F, rayPos = rayPos.add(delta)) + { + BlockPos pos = new BlockPos(rayPos); + if(memBlocks.containsKey(pos)) + { + Pair entry = memBlocks.get(pos); + rayStrength -= entry.getLeft(); + if(rayStrength > 0F && damageCalculator.shouldBlockExplode(explosion, level, pos, entry.getRight(), rayStrength)) + blocks.add(pos); + } + else + { + BlockState blockState = level.getBlockState(pos); + FluidState fluidState = level.getFluidState(pos); + if(!level.isInWorldBounds(pos)) + break; + + Optional blastResistance = damageCalculator.getBlockExplosionResistance(explosion, level, pos, blockState, fluidState); + + if(blastResistance.isPresent()) + { + float decrement = (blastResistance.get() + 0.3F) * 0.3F; + rayStrength -= decrement; + memBlocks.put(pos, Pair.of(decrement, blockState)); + } + else + memBlocks.put(pos, Pair.of(0f, blockState)); + + if(rayStrength > 0F && damageCalculator.shouldBlockExplode(explosion, level, pos, blockState, rayStrength)) + blocks.add(pos); + } + } + } + + public static void collectBlocks() + { + toBlow.clear(); + HashSet blocks = Sets.newHashSet(); + ExplosionDamageCalculator damageCalculator = eAccess2.getDamageCalculator(); + + for(Vec3 ray : RAYS) + doRay(blocks, pos, ray, damageCalculator, level.random.nextFloat()); + + toBlow.addAll(blocks); + } + + public static void pushEntities() + { + for(Entity entity : memEntities) + { + EntityKey entityKey = new EntityKey(entity); + if(memVelocity.containsKey(entityKey)) + { + entity.setDeltaMovement(entity.getDeltaMovement().add(memVelocity.get(entityKey))); + continue; + } + + double x = entity.getX(), y = entity.getY(), z = entity.getZ(); + double dx = x - ex, dy = y - ey, dz = z - ez; + double magSq = dx*dx + dy*dy + dz*dz; + + double distance = Math.sqrt(magSq); + if(distance > power) + continue; + + distance /= power; + double mag = distance; + + if(!(entity instanceof PrimedTnt)) + { + dy = entity.getEyeY() - y; + magSq = dx*dx + dy*dy + dz*dz; + + if(magSq == 0d) + continue; + + mag = Math.sqrt(magSq); + } + else if(magSq == 0d) + continue; + + dx /= mag; + dy /= mag; + dz /= mag; + + double knockback = (1d - distance) * getExposure(entity); + entity.hurt(explosion.getDamageSource(), (int)((knockback * knockback + knockback) / 2d * 7d * (double)power + 1d)); + + if(entity instanceof Player player && !player.isSpectator() && (!player.isCreative() || !player.getAbilities().flying)) + explosion.getHitPlayers().put(player, new Vec3(dx*knockback, dy*knockback, dz*knockback)); + + if(entity instanceof LivingEntity livingEntity) + knockback = ProtectionEnchantment.getExplosionKnockbackAfterDampener(livingEntity, knockback); + + Vec3 velocity = new Vec3(dx*knockback, dy*knockback, dz*knockback); + entity.setDeltaMovement(entity.getDeltaMovement().add(velocity)); + memVelocity.put(entityKey, velocity); + } + } + + private static float getExposure(Entity entity) + { + AABB aabb = entity.getBoundingBox(); + double xw = 1d / ((aabb.maxX - aabb.minX) * 2d + 1d); + double yw = 1d / ((aabb.maxY - aabb.minY) * 2d + 1d); + double zw = 1d / ((aabb.maxZ - aabb.minZ) * 2d + 1d); + double xh = (1d - Math.floor(1d/xw) * xw) / 2d; + double zh = (1d - Math.floor(1d/zw) * zw) / 2d; + + int hit = 0, total = 0; + + if(xw < 0d || yw < 0d || zw < 0d) + return 0f; + + for(float dx = 0f; dx <= 1f; dx += xw) + for(float dy = 0f; dy <= 1f; dy += yw) + for(float dz = 0f; dz <= 1f; dz += zw) + { + double x = Mth.lerp((double)dx, aabb.minX, aabb.maxX); + double y = Mth.lerp((double)dy, aabb.minY, aabb.maxY); + double z = Mth.lerp((double)dz, aabb.minZ, aabb.maxZ); + Vec3 vec3 = new Vec3(x + xh, y, z + zh); + BlockHitResult result = level.clip(new ClipContext(vec3, pos, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)); + if(result.getType() == HitResult.Type.MISS) + ++hit; + + ++total; + } + + return (float)hit / (float)total; + } + + public static void doExplosionB(boolean spawnParticles) + { + ObjectArrayList> list = new ObjectArrayList<>(); + Collections.shuffle(toBlow, level.random); + for(BlockPos pos : toBlow) + { + BlockState state = memBlocks.get(pos).getRight(); + Block block = state.getBlock(); + if(!state.isAir()) + { + BlockPos pos1 = pos.immutable(); + level.getProfiler().push("explosion_blocks"); + if(block.dropFromExplosion(explosion) && level instanceof ServerLevel serverLevel) + { + BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(pos) : null; + LootContext.Builder builder = new LootContext.Builder(serverLevel) + .withRandom(level.random) + .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos)) + .withParameter(LootContextParams.TOOL, ItemStack.EMPTY) + .withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity) + .withOptionalParameter(LootContextParams.THIS_ENTITY, eAccess2.getSource()); + if(eAccess.getDestructionType() == Explosion.BlockInteraction.DESTROY) + builder.withParameter(LootContextParams.EXPLOSION_RADIUS, power); + state.getDrops(builder).forEach((ItemStack stack) -> addBlockDrops(list, stack, pos1)); + } + level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3); + block.wasExploded(level, pos, explosion); + level.getProfiler().pop(); + } + } + } + + private static void addBlockDrops(ObjectArrayList> list, ItemStack stack, BlockPos pos) + { + int s = list.size(); + for(int i = 0; i < s; ++i) + { + com.mojang.datafixers.util.Pair pair = list.get(i); + ItemStack stack2 = pair.getFirst(); + if(ItemEntity.areMergable(stack2, stack)) + { + ItemStack stack3 = ItemEntity.merge(stack2, stack, 16); + list.set(i, com.mojang.datafixers.util.Pair.of(stack3, pair.getSecond())); + if(stack.isEmpty()) + return; + } + } + list.add(com.mojang.datafixers.util.Pair.of(stack, pos)); + } +} diff --git a/src/main/java/me/lntricate/intricarpet/mixins/ExplosionDamageAccessor.java b/src/main/java/me/lntricate/intricarpet/mixins/ExplosionDamageAccessor.java new file mode 100644 index 0000000..02e1190 --- /dev/null +++ b/src/main/java/me/lntricate/intricarpet/mixins/ExplosionDamageAccessor.java @@ -0,0 +1,18 @@ +package me.lntricate.intricarpet.mixins; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.ExplosionDamageCalculator; + +@Mixin(Explosion.class) +public interface ExplosionDamageAccessor +{ + @Accessor + ExplosionDamageCalculator getDamageCalculator(); + + @Accessor + Entity getSource(); +} diff --git a/src/main/java/me/lntricate/intricarpet/mixins/OptimizedExplosionMixin.java b/src/main/java/me/lntricate/intricarpet/mixins/OptimizedExplosionMixin.java new file mode 100644 index 0000000..ec54a98 --- /dev/null +++ b/src/main/java/me/lntricate/intricarpet/mixins/OptimizedExplosionMixin.java @@ -0,0 +1,33 @@ +package me.lntricate.intricarpet.mixins; + +import org.spongepowered.asm.mixin.Mixin; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import carpet.helpers.OptimizedExplosion; +import carpet.logging.logHelpers.ExplosionLogHelper; +import carpet.mixins.ExplosionAccessor; +import me.lntricate.intricarpet.Rules; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.phys.Vec3; + +@Mixin(OptimizedExplosion.class) +public class OptimizedExplosionMixin +{ + @Unique private static final double SAME_POSITION_VELOCITY = 0.9923437498509884; + + @Inject(method = "doExplosionA", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getZ()D", ordinal = 1, shift = Shift.BY, by = 3), locals = LocalCapture.CAPTURE_FAILHARD) + private static void onSamePosition(Explosion e, ExplosionLogHelper eLogger, CallbackInfo ci, ExplosionAccessor eAccess, boolean eventNeeded, float f3, int k1, int l1, int i2, int i1, int j2, int j1, Vec3 vec3d, Entity explodingEntity, int k2, Entity entity) + { + if(Rules.optimizedTNTEdgeCases || !entity.isOnGround()) + { + Vec3 vel = entity.getDeltaMovement(); + entity.setDeltaMovement(vel.x, vel.y - SAME_POSITION_VELOCITY, vel.z); + } + } +} diff --git a/src/main/java/me/lntricate/intricarpet/mixins/interactions/ChunkMapMixin.java b/src/main/java/me/lntricate/intricarpet/mixins/interactions/ChunkMapMixin.java index dbeef2f..a02a75c 100644 --- a/src/main/java/me/lntricate/intricarpet/mixins/interactions/ChunkMapMixin.java +++ b/src/main/java/me/lntricate/intricarpet/mixins/interactions/ChunkMapMixin.java @@ -22,17 +22,25 @@ public class ChunkMapMixin implements IChunkMap @Shadow private static double euclideanDistanceSquared(ChunkPos chunkPos, Entity entity){return 0.0;} @Shadow @Final private PlayerMap playerMap; + private boolean playerValid(ServerPlayer player, ChunkPos chunkPos, Interaction interaction) + { + return ((IServerPlayer)player).getInteraction(interaction) && euclideanDistanceSquared(chunkPos, player) < 16384d; + } + @Override public boolean anyPlayerCloseWithInteraction(ChunkPos chunkPos, Interaction interaction) { //#if MC >= 11800 - //$$ for(ServerPlayer player : playerMap.getPlayers(chunkPos.toLong())) - //$$ if(((IServerPlayer)player).getInteraction(interaction) && euclideanDistanceSquared(chunkPos, player) < 16384.0) + //#if MC >= 12002 + //$$ for(ServerPlayer player : playerMap.getAllPlayers()) + //#else + //$$ for(ServerPlayer player : playerMap.getPlayers(chunkPos.toLong())) + //#endif + //$$ if(playerValid(player, chunkPos, interaction)) //$$ return true; //$$ return false; //#else - return playerMap.getPlayers(chunkPos.toLong()).anyMatch(player -> - ((IServerPlayer)player).getInteraction(interaction) && euclideanDistanceSquared(chunkPos, player) < 16384.0); + return playerMap.getPlayers(chunkPos.toLong()).anyMatch(player -> playerValid(player, chunkPos, interaction)); //#endif } diff --git a/src/main/resources/intricarpet.mixins.json b/src/main/resources/intricarpet.mixins.json index dc8f125..3a4c1e7 100644 --- a/src/main/resources/intricarpet.mixins.json +++ b/src/main/resources/intricarpet.mixins.json @@ -4,6 +4,9 @@ "package": "me.lntricate.intricarpet.mixins", "compatibilityLevel": "JAVA_8", "mixins": [ + "ExplosionDamageAccessor", + "OptimizedExplosionMixin", + "logger.ExplosionLogHelperMixin", "logger.ServerLevelMixin", diff --git a/versions/1.17.1/.factorypath b/versions/1.17.1/.factorypath index 7f664d8..5c42b76 100644 --- a/versions/1.17.1/.factorypath +++ b/versions/1.17.1/.factorypath @@ -1,51 +1,15 @@ - - - + + - + + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/versions/1.18.2/.factorypath b/versions/1.18.2/.factorypath index 6a4d1ca..6fa37e6 100644 --- a/versions/1.18.2/.factorypath +++ b/versions/1.18.2/.factorypath @@ -1,51 +1,15 @@ - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/versions/1.19.2/.factorypath b/versions/1.19.2/.factorypath index 4004dd6..71b0ed7 100644 --- a/versions/1.19.2/.factorypath +++ b/versions/1.19.2/.factorypath @@ -1,67 +1,15 @@ - - - + + + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/versions/1.19.3/.factorypath b/versions/1.19.3/.factorypath index 75b4c33..ae8e16d 100644 --- a/versions/1.19.3/.factorypath +++ b/versions/1.19.3/.factorypath @@ -1,68 +1,15 @@ - - - - - + + - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/versions/1.19.4/.factorypath b/versions/1.19.4/.factorypath index ade8b01..49acc0d 100644 --- a/versions/1.19.4/.factorypath +++ b/versions/1.19.4/.factorypath @@ -1,67 +1,15 @@ - - - - + + + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/versions/1.20.1/.factorypath b/versions/1.20.1/.factorypath index 34add73..ae3a9bb 100644 --- a/versions/1.20.1/.factorypath +++ b/versions/1.20.1/.factorypath @@ -1,67 +1,15 @@ - - - - - + + + - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/versions/1.20.2/.factorypath b/versions/1.20.2/.factorypath new file mode 100644 index 0000000..34add73 --- /dev/null +++ b/versions/1.20.2/.factorypath @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/versions/1.20.2/gradle.properties b/versions/1.20.2/gradle.properties new file mode 100644 index 0000000..53f03e2 --- /dev/null +++ b/versions/1.20.2/gradle.properties @@ -0,0 +1,16 @@ +# Fabric Properties + # check these on https://fabricmc.net/versions.html?&version=1.19.4 + minecraft_version=1.20.2 + yarn_mappings=1.20.2+build.4 + +# Fabric Mod Metadata + minecraft_dependency=1.20.2 + carpet_dependency=>=1.4.119 + +# Build Information + # The target mc versions for the mod during mod publishing, separated with \n + game_versions=1.20.2 + +# Dependencies + # fabric_api_version=0.75.3+1.19.4 + carpet_version=1.20.2-1.4.119+v230928