Merge branch 'Sollace:1.20.1' into 1.20.1

This commit is contained in:
横刀天笑(Knife smile) 2024-02-12 11:30:54 +08:00 committed by GitHub
commit f2bc32a90b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 171 additions and 62 deletions

View file

@ -24,7 +24,7 @@ org.gradle.daemon=false
modmenu_version=7.0.0-beta.2 modmenu_version=7.0.0-beta.2
minelp_version=4.10.4+1.20.1 minelp_version=4.10.4+1.20.1
kirin_version=1.15.4+1.20 kirin_version=1.15.4+1.20
reach_attributes_version=2.3.3 reach_attributes_version=2.3.4
trinkets_version=3.7.1 trinkets_version=3.7.1
terraformer_api_version=7.0.0-beta.1 terraformer_api_version=7.0.0-beta.1

Binary file not shown.

View file

@ -38,6 +38,9 @@ public class UnicopiaMixinPlugin implements IMixinConfigPlugin {
if (mixinClassName.indexOf("minelp") != -1) { if (mixinClassName.indexOf("minelp") != -1) {
return FabricLoader.getInstance().isModLoaded("minelp"); return FabricLoader.getInstance().isModLoaded("minelp");
} }
if (mixinClassName.indexOf("forgified") != -1) {
return FabricLoader.getInstance().isModLoaded("connectormod");
}
} }
return true; return true;
} }

View file

@ -17,7 +17,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box; import net.minecraft.util.math.Box;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes; import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.WorldAccess; import net.minecraft.world.EntityView;
public class EntityCollisions { public class EntityCollisions {
@ -40,7 +40,7 @@ public class EntityCollisions {
} }
} }
public static List<VoxelShape> getColissonShapes(@Nullable Entity entity, WorldAccess world, Box box) { public static List<VoxelShape> getColissonShapes(@Nullable Entity entity, EntityView world, Box box) {
ShapeContext ctx = entity == null ? ShapeContext.absent() : ShapeContext.of(entity); ShapeContext ctx = entity == null ? ShapeContext.absent() : ShapeContext.of(entity);
return collectCollisionBoxes(box, collector -> { return collectCollisionBoxes(box, collector -> {
world.getOtherEntities(entity, box.expand(50), e -> { world.getOtherEntities(entity, box.expand(50), e -> {

View file

@ -28,6 +28,7 @@ import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar; import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
import com.minelittlepony.unicopia.item.FriendshipBraceletItem; import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil;
import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
import com.minelittlepony.unicopia.util.*; import com.minelittlepony.unicopia.util.*;
import com.minelittlepony.unicopia.network.*; import com.minelittlepony.unicopia.network.*;
@ -39,7 +40,6 @@ import com.minelittlepony.common.util.animation.Interpolator;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments; import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.*; import net.minecraft.entity.*;
import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.DefaultAttributeContainer;
@ -919,7 +919,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
PlayerInventory inventory = oldPlayer.asEntity().getInventory(); PlayerInventory inventory = oldPlayer.asEntity().getInventory();
for (int i = 0; i < inventory.size(); i++) { for (int i = 0; i < inventory.size(); i++) {
ItemStack stack = inventory.getStack(i); ItemStack stack = inventory.getStack(i);
if (EnchantmentHelper.getLevel(UEnchantments.HEART_BOUND, stack) > 0) { if (EnchantmentUtil.consumeEnchantment(UEnchantments.HEART_BOUND, 1, stack, entity.getWorld().random, EnchantmentUtil.getLuck(3, oldPlayer.asEntity()))) {
asEntity().getInventory().setStack(i, stack); asEntity().getInventory().setStack(i, stack);
} }
} }

View file

@ -16,6 +16,7 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
public interface EnchantmentUtil { public interface EnchantmentUtil {
String HEART_BOUND_CONSUMED_FLAG = "unicopia:heart_bound_consumed";
static boolean consumeEnchantment(Enchantment enchantment, int levels, ItemStack stack) { static boolean consumeEnchantment(Enchantment enchantment, int levels, ItemStack stack) {
return consumeEnchantment(enchantment, levels, stack, null, 0); return consumeEnchantment(enchantment, levels, stack, null, 0);
@ -33,7 +34,7 @@ public interface EnchantmentUtil {
if (level == 0) { if (level == 0) {
enchantments.remove(enchantment); enchantments.remove(enchantment);
} else { } else {
enchantments.put(enchantment, level - 1); enchantments.put(enchantment, level);
} }
EnchantmentHelper.set(enchantments, stack); EnchantmentHelper.set(enchantments, stack);
} }

View file

@ -0,0 +1,51 @@
package com.minelittlepony.unicopia.item.enchantment;
import java.util.List;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.util.collection.DefaultedList;
public interface HeartboundEnchantmentUtil {
static InventorySnapshot createSnapshot(List<DefaultedList<ItemStack>> combinedInventory) {
List<DefaultedList<ItemStack>> storedCombinedInventory = combinedInventory.stream().map(l -> DefaultedList.ofSize(l.size(), ItemStack.EMPTY)).toList();
boolean empty = true;
for (int group = 0; group < combinedInventory.size(); group++) {
var original = combinedInventory.get(group);
for (int i = 0; i < original.size(); i++) {
ItemStack stack = original.get(i);
if (EnchantmentHelper.getLevel(Enchantments.BINDING_CURSE, stack) == 0
&& EnchantmentHelper.getLevel(UEnchantments.HEART_BOUND, stack) > 0) {
original.set(i, ItemStack.EMPTY);
storedCombinedInventory.get(group).set(i, stack);
empty = false;
}
}
}
return empty ? InventorySnapshot.EMPTY : new InventorySnapshot(storedCombinedInventory);
}
public record InventorySnapshot(List<DefaultedList<ItemStack>> combinedInventory) {
public static InventorySnapshot EMPTY = new InventorySnapshot(List.of());
public boolean empty() {
return combinedInventory.isEmpty();
}
public void restoreInto(List<DefaultedList<ItemStack>> combinedInventory) {
if (empty()) {
return;
}
for (int group = 0; group < combinedInventory.size(); group++) {
var original = combinedInventory.get(group);
for (int i = 0; i < original.size(); i++) {
ItemStack stored = this.combinedInventory.get(group).get(i);
if (!stored.isEmpty()) {
original.set(i, stored);
}
}
}
}
}
}

View file

@ -30,12 +30,12 @@ public interface UEnchantments {
/** /**
* Protects against wall collisions and earth pony attacks! * Protects against wall collisions and earth pony attacks!
*/ */
Enchantment PADDED = register("padded", new SimpleEnchantment(Options.armor().rarity(Rarity.COMMON).maxLevel(3))); Enchantment PADDED = register("padded", new SimpleEnchantment(Options.armor().rarity(Rarity.UNCOMMON).maxLevel(3)));
/** /**
* Heavy players move more slowly but are less likely to be flung around wildly. * Heavy players move more slowly but are less likely to be flung around wildly.
*/ */
Enchantment HEAVY = register("heavy", new AttributedEnchantment(Options.armor().rarity(Rarity.COMMON).maxLevel(4))) Enchantment HEAVY = register("heavy", new AttributedEnchantment(Options.armor().rarity(Rarity.UNCOMMON).maxLevel(4)))
.addModifier(EntityAttributes.GENERIC_MOVEMENT_SPEED, (user, level) -> { .addModifier(EntityAttributes.GENERIC_MOVEMENT_SPEED, (user, level) -> {
return new EntityAttributeModifier(UUID.fromString("a3d5a94f-4c40-48f6-a343-558502a13e10"), "Heavyness", (1 - level/(float)10) - 1, Operation.MULTIPLY_TOTAL); return new EntityAttributeModifier(UUID.fromString("a3d5a94f-4c40-48f6-a343-558502a13e10"), "Heavyness", (1 - level/(float)10) - 1, Operation.MULTIPLY_TOTAL);
}); });
@ -83,7 +83,7 @@ public interface UEnchantments {
* Items with loyalty are kept after death. * Items with loyalty are kept after death.
* Only works if they don't also have curse of binding. * Only works if they don't also have curse of binding.
*/ */
Enchantment HEART_BOUND = register("heart_bound", new SimpleEnchantment(Options.create(EnchantmentTarget.VANISHABLE, UEnchantmentValidSlots.ANY).rarity(Rarity.COMMON).maxLevel(5))); Enchantment HEART_BOUND = register("heart_bound", new SimpleEnchantment(Options.create(EnchantmentTarget.VANISHABLE, UEnchantmentValidSlots.ANY).rarity(Rarity.UNCOMMON).maxLevel(5)));
/** /**
* Consumes drops whilst mining and produces experience instead * Consumes drops whilst mining and produces experience instead

View file

@ -31,7 +31,12 @@ abstract class MixinBoatEntity extends Entity implements LavaAffine {
"fall", "fall",
"canAddPassenger" "canAddPassenger"
}, },
at = @At(value = "FIELD", target = "net/minecraft/registry/tag/FluidTags.WATER:Lnet/minecraft/registry/tag/TagKey;", opcode = Opcodes.GETSTATIC) at = @At(
value = "FIELD",
target = "net/minecraft/registry/tag/FluidTags.WATER:Lnet/minecraft/registry/tag/TagKey;",
opcode = Opcodes.GETSTATIC
),
require = 0 // Forge
) )
private TagKey<Fluid> redirectFluidTag() { private TagKey<Fluid> redirectFluidTag() {
return isLavaAffine() ? FluidTags.LAVA : FluidTags.WATER; return isLavaAffine() ? FluidTags.LAVA : FluidTags.WATER;

View file

@ -0,0 +1,32 @@
package com.minelittlepony.unicopia.mixin;
import java.util.List;
import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;
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.minelittlepony.unicopia.entity.collision.EntityCollisions;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.Box;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.EntityView;
@Mixin(EntityView.class)
interface MixinEntityView {
@Inject(method = "getEntityCollisions(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/Box;)Ljava/util/List;", at = @At("RETURN"), cancellable = true)
private void onGetEntityCollisions(@Nullable Entity entity, Box box, CallbackInfoReturnable<List<VoxelShape>> info) {
if (box.getAverageSideLength() < 1.0E-7D) {
return;
}
List<VoxelShape> shapes = EntityCollisions.getColissonShapes(entity, (EntityView)this, box);
if (!shapes.isEmpty()) {
info.setReturnValue(Stream.concat(shapes.stream(), info.getReturnValue().stream()).toList());
}
}
}

View file

@ -11,11 +11,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; import com.minelittlepony.unicopia.item.enchantment.HeartboundEnchantmentUtil;
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
@ -31,37 +27,21 @@ abstract class MixinPlayerInventory implements Inventory, Nameable {
private @Final List<DefaultedList<ItemStack>> combinedInventory; private @Final List<DefaultedList<ItemStack>> combinedInventory;
@Nullable @Nullable
private List<DefaultedList<ItemStack>> storedCombinedInventory; private HeartboundEnchantmentUtil.InventorySnapshot inventorySnapshot;
@Inject(method = "dropAll()V", at = @At("HEAD")) @Inject(method = "dropAll()V", at = @At("HEAD"))
public void beforeDropAll(CallbackInfo info) { public void beforeDropAll(CallbackInfo info) {
storedCombinedInventory = combinedInventory.stream().map(l -> DefaultedList.ofSize(l.size(), ItemStack.EMPTY)).toList(); inventorySnapshot = HeartboundEnchantmentUtil.createSnapshot(combinedInventory);
for (int group = 0; group < combinedInventory.size(); group++) { if (!inventorySnapshot.empty()) {
var original = combinedInventory.get(group);
for (int i = 0; i < original.size(); i++) {
ItemStack stack = original.get(i);
if (EnchantmentHelper.getLevel(Enchantments.BINDING_CURSE, stack) == 0
&& EnchantmentUtil.consumeEnchantment(UEnchantments.HEART_BOUND, 1, stack, player.getWorld().random, EnchantmentUtil.getLuck(3, player))) {
original.set(i, ItemStack.EMPTY);
UCriteria.USE_SOULMATE.trigger(player); UCriteria.USE_SOULMATE.trigger(player);
storedCombinedInventory.get(group).set(i, stack);
}
}
} }
} }
@Inject(method = "dropAll()V", at = @At("TAIL")) @Inject(method = "dropAll()V", at = @At("RETURN"))
public void afterDropAll(CallbackInfo info) { public void afterDropAll(CallbackInfo info) {
if (storedCombinedInventory != null) { if (inventorySnapshot != null) {
for (int group = 0; group < combinedInventory.size(); group++) { inventorySnapshot.restoreInto(combinedInventory);
var original = combinedInventory.get(group); inventorySnapshot = null;
for (int i = 0; i < original.size(); i++) {
ItemStack stored = storedCombinedInventory.get(group).get(i);
if (!stored.isEmpty()) {
original.set(i, stored);
}
}
}
} }
} }
} }

View file

@ -1,26 +1,17 @@
package com.minelittlepony.unicopia.mixin; package com.minelittlepony.unicopia.mixin;
import java.util.List;
import java.util.Stack; import java.util.Stack;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.entity.collision.EntityCollisions;
import com.minelittlepony.unicopia.entity.duck.RotatedView; import com.minelittlepony.unicopia.entity.duck.RotatedView;
import com.minelittlepony.unicopia.server.world.BlockDestructionManager; import com.minelittlepony.unicopia.server.world.BlockDestructionManager;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
@ -47,18 +38,6 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source
return destructions.get(); return destructions.get();
} }
@Override
public List<VoxelShape> getEntityCollisions(@Nullable Entity entity, Box box) {
if (box.getAverageSideLength() >= 1.0E-7D) {
List<VoxelShape> shapes = EntityCollisions.getColissonShapes(entity, this, box);
if (!shapes.isEmpty()) {
return Stream.concat(shapes.stream(), WorldAccess.super.getEntityCollisions(entity, box).stream()).toList();
}
}
return WorldAccess.super.getEntityCollisions(entity, box);
}
@ModifyVariable(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD")) @ModifyVariable(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD"))
private BlockPos modifyBlockPos(BlockPos pos) { private BlockPos modifyBlockPos(BlockPos pos) {
pos = applyRotation(pos); pos = applyRotation(pos);

View file

@ -0,0 +1,54 @@
package com.minelittlepony.unicopia.mixin.forgified;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.*;
import com.minelittlepony.unicopia.entity.duck.LavaAffine;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.registry.tag.FluidTags;
@Pseudo
@Mixin(targets = "net.minecraftforge.common.extensions.IForgeBoat")
interface MixinIForgeBoat {
@ModifyVariable(
method = "canBoatInFluid(Lnet/minecraft/fluid/FluidState;)Z",
at = @At("HEAD"),
ordinal = 0,
argsOnly = true,
require = 0
)
private FluidState modifyFluidState(FluidState incoming) {
if (this instanceof LavaAffine a && a.isLavaAffine()) {
if (incoming.isIn(FluidTags.WATER)) {
return Fluids.LAVA.getDefaultState();
}
if (incoming.isIn(FluidTags.LAVA)) {
return Fluids.WATER.getDefaultState();
}
}
return incoming;
}
@SuppressWarnings("deprecation")
@ModifyVariable(
method = "canBoatInFluid(Lnet/minecraft/fluid/Fluid;)Z",
at = @At("HEAD"),
ordinal = 0,
argsOnly = true,
require = 0
)
private Fluid modifyFluid(Fluid incoming) {
if (this instanceof LavaAffine a && a.isLavaAffine()) {
if (incoming.isIn(FluidTags.WATER)) {
return Fluids.LAVA;
}
if (incoming.isIn(FluidTags.LAVA)) {
return Fluids.WATER;
}
}
return incoming;
}
}

View file

@ -4,7 +4,9 @@
"traits": { "traits": {
"knowledge": 19, "life": 10, "chaos": 4 "knowledge": 19, "life": 10, "chaos": 4
}, },
"ingredients": [], "ingredients": [
{ "item": "unicopia:gemstone", "spell": "unicopia:transformation" }
],
"result": { "result": {
"item": "unicopia:gemstone", "item": "unicopia:gemstone",
"spell": "unicopia:mimic" "spell": "unicopia:mimic"

View file

@ -20,6 +20,7 @@
"MixinEnchantmentHelper", "MixinEnchantmentHelper",
"MixinFallLocation", "MixinFallLocation",
"MixinEntity", "MixinEntity",
"MixinEntityView",
"MixinEntityShapeContext", "MixinEntityShapeContext",
"MixinFallingBlock", "MixinFallingBlock",
"MixinFallingBlockEntity", "MixinFallingBlockEntity",
@ -57,7 +58,8 @@
"trinkets.MixinTrinketInventory", "trinkets.MixinTrinketInventory",
"trinkets.MixinScreenHandler", "trinkets.MixinScreenHandler",
"seasons.MixinFertilizableUtil", "seasons.MixinFertilizableUtil",
"ad_astra.MixinOxygenUtils" "ad_astra.MixinOxygenUtils",
"forgified.MixinIForgeBoat"
], ],
"client": [ "client": [
"client.MixinAnimalModel", "client.MixinAnimalModel",