Mixin scrubbing

- Move all client mixins to separate package
- Prefix all mixin injector callback methods and added fields
- Remove unnecessary code from EntityContraptionInteractionMixin
- Remove EnchantmentMixin and use IForgeItem#canApplyAtEnchantingTable
instead
- Do not sync fire immune tag to client
- Bump network version to 3
- Remove 0.5.0j from Github issue template
This commit is contained in:
PepperCode1 2023-05-16 06:08:10 -07:00
parent 9c0c058fc0
commit bb5d0fedee
31 changed files with 287 additions and 424 deletions

View file

@ -50,7 +50,6 @@ body:
description: The version of the mod you were using when the bug occured
options:
- "0.5.1a"
- "0.5.0j"
- "0.5.0i"
- "0.5.0h"
- "0.5.0g"

View file

@ -575,15 +575,6 @@ public class ContraptionCollider {
return true;
}
public static Vec3 getWorldToLocalTranslation(Entity entity, AbstractContraptionEntity contraptionEntity) {
return getWorldToLocalTranslation(entity, contraptionEntity.getAnchorVec(),
contraptionEntity.getRotationState());
}
public static Vec3 getWorldToLocalTranslation(Entity entity, Vec3 anchorVec, ContraptionRotationState rotation) {
return getWorldToLocalTranslation(entity, anchorVec, rotation.asMatrix(), rotation.getYawOffset());
}
public static Vec3 getWorldToLocalTranslation(Entity entity, Vec3 anchorVec, Matrix3d rotationMatrix,
float yawOffset) {
Vec3 entityPosition = entity.position();
@ -591,35 +582,29 @@ public class ContraptionCollider {
.getYsize() / 2, 0);
Vec3 position = entityPosition;
position = position.add(centerY);
position = position.subtract(VecHelper.CENTER_OF_ORIGIN);
position = position.subtract(anchorVec);
position = VecHelper.rotate(position, -yawOffset, Axis.Y);
position = rotationMatrix.transform(position);
position = position.add(VecHelper.CENTER_OF_ORIGIN);
position = worldToLocalPos(position, anchorVec, rotationMatrix, yawOffset);
position = position.subtract(centerY);
position = position.subtract(entityPosition);
return position;
}
public static Vec3 getWorldToLocalTranslation(Vec3 entity, AbstractContraptionEntity contraptionEntity) {
return getWorldToLocalTranslation(entity, contraptionEntity.getAnchorVec(),
public static Vec3 worldToLocalPos(Vec3 worldPos, AbstractContraptionEntity contraptionEntity) {
return worldToLocalPos(worldPos, contraptionEntity.getAnchorVec(),
contraptionEntity.getRotationState());
}
public static Vec3 getWorldToLocalTranslation(Vec3 inPos, Vec3 anchorVec, ContraptionRotationState rotation) {
return getWorldToLocalTranslation(inPos, anchorVec, rotation.asMatrix(), rotation.getYawOffset());
public static Vec3 worldToLocalPos(Vec3 worldPos, Vec3 anchorVec, ContraptionRotationState rotation) {
return worldToLocalPos(worldPos, anchorVec, rotation.asMatrix(), rotation.getYawOffset());
}
public static Vec3 getWorldToLocalTranslation(Vec3 inPos, Vec3 anchorVec, Matrix3d rotationMatrix,
float yawOffset) {
Vec3 position = inPos;
position = position.subtract(VecHelper.CENTER_OF_ORIGIN);
position = position.subtract(anchorVec);
position = VecHelper.rotate(position, -yawOffset, Axis.Y);
position = rotationMatrix.transform(position);
position = position.add(VecHelper.CENTER_OF_ORIGIN);
position = position.subtract(inPos);
return position;
public static Vec3 worldToLocalPos(Vec3 worldPos, Vec3 anchorVec, Matrix3d rotationMatrix, float yawOffset) {
Vec3 localPos = worldPos;
localPos = localPos.subtract(anchorVec);
localPos = localPos.subtract(VecHelper.CENTER_OF_ORIGIN);
localPos = VecHelper.rotate(localPos, -yawOffset, Axis.Y);
localPos = rotationMatrix.transform(localPos);
localPos = localPos.add(VecHelper.CENTER_OF_ORIGIN);
return localPos;
}
/** From Entity#collide **/

View file

@ -6,12 +6,10 @@ import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.phys.Vec3;
public class ContraptionWorld extends WrappedWorld {
final Contraption contraption;
@ -45,18 +43,8 @@ public class ContraptionWorld extends WrappedWorld {
}
@Override
public void playSound(Player player, double x, double y, double z, SoundEvent soundIn, SoundSource category, float volume, float pitch) {
Vec3 worldPos = ContraptionCollider.getWorldToLocalTranslation(new Vec3(x, y, z), this.contraption.entity);
worldPos = worldPos.add(x, y, z);
world.playSound(player, worldPos.x, worldPos.y, worldPos.z, soundIn, category, volume, pitch);
}
@Override
public void playLocalSound(double x, double y, double z, SoundEvent p_184134_7_, SoundSource p_184134_8_, float p_184134_9_, float p_184134_10_, boolean p_184134_11_) {
world.playLocalSound(x, y, z, p_184134_7_, p_184134_8_, p_184134_9_, p_184134_10_, p_184134_11_);
public void playLocalSound(double x, double y, double z, SoundEvent sound, SoundSource category, float volume, float pitch, boolean distanceDelay) {
world.playLocalSound(x, y, z, sound, category, volume, pitch, distanceDelay);
}
// Ensure that we provide accurate information about ContraptionWorld height to mods (such as Starlight) which

View file

@ -85,12 +85,12 @@ public class DivingBootsItem extends BaseArmorItem {
return true;
}
public static Vec3 getMovementMultiplier(Entity entity) {
public static Vec3 getMovementMultiplier(LivingEntity entity) {
double yMotion = entity.getDeltaMovement().y;
double vMultiplier = yMotion < 0 ? Math.max(0, 2.5 - Math.abs(yMotion) * 2) : 1;
if (!entity.isOnGround()) {
if (entity instanceof LivingEntity le && le.jumping && entity.getPersistentData()
if (entity.jumping && entity.getPersistentData()
.contains("LavaGrounded")) {
vMultiplier = yMotion == 0 ? 0 : 1 / yMotion;
} else if (yMotion > 0)
@ -101,9 +101,8 @@ public class DivingBootsItem extends BaseArmorItem {
return new Vec3(1.75, vMultiplier, 1.75);
}
if (entity instanceof LivingEntity)
entity.getPersistentData()
.putBoolean("LavaGrounded", true);
entity.getPersistentData()
.putBoolean("LavaGrounded", true);
double hMultiplier = entity.isSprinting() ? 1.85 : 1.75;
return new Vec3(hMultiplier, vMultiplier, hMultiplier);
}

View file

@ -15,6 +15,8 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.Level;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@ -28,6 +30,14 @@ public class DivingHelmetItem extends BaseArmorItem {
super(material, SLOT, properties, textureLoc);
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
if (enchantment == Enchantments.AQUA_AFFINITY) {
return false;
}
return super.canApplyAtEnchantingTable(stack, enchantment);
}
public static boolean isWornBy(Entity entity, boolean fireproof) {
ItemStack stack = getWornItem(entity);
if (stack == null)

View file

@ -1,25 +1,16 @@
package com.simibubi.create.content.curiosities.armor;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.ArmorMaterials;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.network.PacketDistributor;
@EventBusSubscriber
public final class NetheriteDivingHandler {
@ -64,10 +55,14 @@ public final class NetheriteDivingHandler {
public static void setBit(LivingEntity entity, EquipmentSlot slot) {
CompoundTag nbt = entity.getPersistentData();
byte bits = nbt.getByte(NETHERITE_DIVING_BITS_KEY);
if ((bits & 0b1111) == 0b1111) {
return;
}
bits |= 1 << slot.getIndex();
nbt.putByte(NETHERITE_DIVING_BITS_KEY, bits);
if ((bits & 0xF) == 0xF) {
if ((bits & 0b1111) == 0b1111) {
setFireImmune(entity, true);
}
}
@ -79,7 +74,7 @@ public final class NetheriteDivingHandler {
}
byte bits = nbt.getByte(NETHERITE_DIVING_BITS_KEY);
boolean prevFullSet = (bits & 0xF) == 0xF;
boolean prevFullSet = (bits & 0b1111) == 0b1111;
bits &= ~(1 << slot.getIndex());
nbt.putByte(NETHERITE_DIVING_BITS_KEY, bits);
@ -88,59 +83,10 @@ public final class NetheriteDivingHandler {
}
}
// TODO: sync to the client
// The feature works without syncing because health and burning are calculated server-side and synced through vanilla code.
// This method will not be called when the entity is wearing a full diving set on creation because the NBT values are persistent.
public static void setFireImmune(LivingEntity entity, boolean fireImmune) {
entity.getPersistentData().putBoolean(FIRE_IMMUNE_KEY, fireImmune);
AllPackets.getChannel().send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity), SetFireImmunePacket.create(entity));
}
@SubscribeEvent
public static void onStartTrackingEntity(PlayerEvent.StartTracking event) {
if (!(event.getPlayer() instanceof ServerPlayer player)) {
return;
}
if (!(event.getTarget() instanceof LivingEntity entity)) {
return;
}
AllPackets.getChannel().send(PacketDistributor.PLAYER.with(() -> player), SetFireImmunePacket.create(entity));
}
public static class SetFireImmunePacket extends SimplePacketBase {
private final int entityId;
private final boolean fireImmune;
public SetFireImmunePacket(int entityId, boolean fireImmune) {
this.entityId = entityId;
this.fireImmune = fireImmune;
}
public static SetFireImmunePacket create(Entity entity) {
int entityId = entity.getId();
boolean fireImmune = entity.getPersistentData().getBoolean(FIRE_IMMUNE_KEY);
return new SetFireImmunePacket(entityId, fireImmune);
}
public SetFireImmunePacket(FriendlyByteBuf buffer) {
entityId = buffer.readVarInt();
fireImmune = buffer.readBoolean();
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeVarInt(entityId);
buffer.writeBoolean(fireImmune);
}
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> {
Entity entity = Minecraft.getInstance().level.getEntity(entityId);
if (entity != null) {
entity.getPersistentData().putBoolean(FIRE_IMMUNE_KEY, fireImmune);
}
});
return true;
}
}
}

View file

@ -30,14 +30,15 @@ public class ClientboundMapItemDataPacketMixin {
private List<MapDecoration> decorations;
@Unique
private int[] stationIndices;
private int[] create$stationIndices;
@Inject(method = "<init>(IBZLjava/util/Collection;Lnet/minecraft/world/level/saveddata/maps/MapItemSavedData$MapPatch;)V", at = @At("RETURN"))
private void onInit(int mapId, byte scale, boolean locked, @Nullable Collection<MapDecoration> decorations, @Nullable MapItemSavedData.MapPatch colorPatch, CallbackInfo ci) {
stationIndices = getStationIndices(this.decorations);
private void create$onInit(int mapId, byte scale, boolean locked, @Nullable Collection<MapDecoration> decorations, @Nullable MapItemSavedData.MapPatch colorPatch, CallbackInfo ci) {
create$stationIndices = create$getStationIndices(this.decorations);
}
private static int[] getStationIndices(List<MapDecoration> decorations) {
@Unique
private static int[] create$getStationIndices(List<MapDecoration> decorations) {
if (decorations == null) {
return new int[0];
}
@ -53,11 +54,11 @@ public class ClientboundMapItemDataPacketMixin {
}
@Inject(method = "<init>(Lnet/minecraft/network/FriendlyByteBuf;)V", at = @At("RETURN"))
private void onInit(FriendlyByteBuf buf, CallbackInfo ci) {
stationIndices = buf.readVarIntArray();
private void create$onInit(FriendlyByteBuf buf, CallbackInfo ci) {
create$stationIndices = buf.readVarIntArray();
if (decorations != null) {
for (int i : stationIndices) {
for (int i : create$stationIndices) {
if (i >= 0 && i < decorations.size()) {
MapDecoration decoration = decorations.get(i);
decorations.set(i, StationMarker.Decoration.from(decoration));
@ -67,7 +68,7 @@ public class ClientboundMapItemDataPacketMixin {
}
@Inject(method = "write(Lnet/minecraft/network/FriendlyByteBuf;)V", at = @At("RETURN"))
private void onWrite(FriendlyByteBuf buf, CallbackInfo ci) {
buf.writeVarIntArray(stationIndices);
private void create$onWrite(FriendlyByteBuf buf, CallbackInfo ci) {
buf.writeVarIntArray(create$stationIndices);
}
}

View file

@ -17,7 +17,6 @@ import net.minecraftforge.common.extensions.IForgeEntity;
@Mixin(Entity.class)
@Implements(@Interface(iface = IForgeEntity.class, prefix = "iForgeEntity$"))
public abstract class ContraptionDriverInteractMixin extends CapabilityProvider<Entity> {
private ContraptionDriverInteractMixin(Class<Entity> baseClass) {
super(baseClass);
}
@ -30,5 +29,4 @@ public abstract class ContraptionDriverInteractMixin extends CapabilityProvider<
public boolean iForgeEntity$canRiderInteract() {
return getRootVehicle() instanceof AbstractContraptionEntity;
}
}

View file

@ -26,7 +26,7 @@ public abstract class CustomItemUseEffectsMixin extends Entity {
public abstract ItemStack getUseItem();
@Inject(method = "shouldTriggerItemUseEffects()Z", at = @At("HEAD"), cancellable = true)
private void onShouldTriggerUseEffects(CallbackInfoReturnable<Boolean> cir) {
private void create$onShouldTriggerUseEffects(CallbackInfoReturnable<Boolean> cir) {
ItemStack using = getUseItem();
Item item = using.getItem();
if (item instanceof CustomUseEffectsItem handler) {
@ -38,7 +38,7 @@ public abstract class CustomItemUseEffectsMixin extends Entity {
}
@Inject(method = "triggerItemUseEffects(Lnet/minecraft/world/item/ItemStack;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;getUseAnimation()Lnet/minecraft/world/item/UseAnim;", ordinal = 0), cancellable = true)
private void onTriggerUseEffects(ItemStack stack, int count, CallbackInfo ci) {
private void create$onTriggerUseEffects(ItemStack stack, int count, CallbackInfo ci) {
Item item = stack.getItem();
if (item instanceof CustomUseEffectsItem handler) {
if (handler.triggerUseEffects(stack, (LivingEntity) (Object) this, count, random)) {

View file

@ -15,7 +15,7 @@ import net.minecraft.world.item.enchantment.Enchantments;
@Mixin(EnchantmentHelper.class)
public class EnchantmentHelperMixin {
@Inject(method = "getItemEnchantmentLevel(Lnet/minecraft/world/item/enchantment/Enchantment;Lnet/minecraft/world/item/ItemStack;)I", at = @At("HEAD"), cancellable = true)
private static void onGetItemEnchantmentLevel(Enchantment enchantment, ItemStack stack, CallbackInfoReturnable<Integer> cir) {
private static void create$onGetItemEnchantmentLevel(Enchantment enchantment, ItemStack stack, CallbackInfoReturnable<Integer> cir) {
if (enchantment == Enchantments.AQUA_AFFINITY && stack.getItem() instanceof DivingHelmetItem) {
cir.setReturnValue(1);
}

View file

@ -1,22 +0,0 @@
package com.simibubi.create.foundation.mixin;
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.simibubi.create.content.curiosities.armor.DivingHelmetItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
@Mixin(Enchantment.class)
public class EnchantmentMixin {
@Inject(method = "canEnchant(Lnet/minecraft/world/item/ItemStack;)Z", at = @At("HEAD"), cancellable = true)
private void onCanEnchant(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if ((Object) this == Enchantments.AQUA_AFFINITY && stack.getItem() instanceof DivingHelmetItem) {
cir.setReturnValue(false);
}
}
}

View file

@ -1,194 +0,0 @@
package com.simibubi.create.foundation.mixin;
import java.lang.ref.Reference;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.logging.log4j.util.TriConsumer;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.CapabilityProvider;
@Mixin(Entity.class)
public abstract class EntityContraptionInteractionMixin extends CapabilityProvider<Entity> {
private EntityContraptionInteractionMixin(Class<Entity> baseClass) {
super(baseClass);
}
private final Entity self = (Entity) (Object) this;
private AbstractContraptionEntity contraption;
@Final
@Shadow
protected Random random;
@Shadow
private float nextStep;
@Shadow
protected abstract float nextStep();
@Shadow
protected abstract void playStepSound(BlockPos p_180429_1_, BlockState p_180429_2_);
private Set<AbstractContraptionEntity> getIntersectingContraptions() {
Set<AbstractContraptionEntity> contraptions = getIntersectionContraptionsStream().collect(Collectors.toSet());
contraptions.addAll(self.level.getEntitiesOfClass(AbstractContraptionEntity.class, self.getBoundingBox()
.inflate(1f)));
return contraptions;
}
private Stream<AbstractContraptionEntity> getIntersectionContraptionsStream() {
return ContraptionHandler.loadedContraptions.get(self.level)
.values()
.stream()
.map(Reference::get)
.filter(cEntity -> cEntity != null && cEntity.collidingEntities.containsKey(self));
}
private void forCollision(Vec3 anchorPos, TriConsumer<Contraption, BlockState, BlockPos> action) {
getIntersectingContraptions().forEach(cEntity -> {
Vec3 localPos = ContraptionCollider.getWorldToLocalTranslation(anchorPos, cEntity);
localPos = anchorPos.add(localPos);
BlockPos blockPos = new BlockPos(localPos);
Contraption contraption = cEntity.getContraption();
StructureTemplate.StructureBlockInfo info = contraption.getBlocks()
.get(blockPos);
if (info != null) {
BlockState blockstate = info.state;
action.accept(contraption, blockstate, blockPos);
}
});
}
@Inject(at = @At(value = "JUMP", opcode = 154, // IFNE line 661 injecting before `!blockstate.isAir(this.world, blockpos)`
ordinal = 7), method = "move")
private void movementStepMixin(MoverType mover, Vec3 movement, CallbackInfo ci) { // involves block step sounds on contraptions
Vec3 worldPos = self.position()
.add(0, -0.2, 0);
AtomicBoolean stepped = new AtomicBoolean(false);
forCollision(worldPos, (contraption, blockstate, blockPos) -> {
bindContraption(contraption);
playStepSound(blockPos, blockstate);
unbindContraption();
stepped.set(true);
});
if (stepped.get())
this.nextStep = this.nextStep();
}
@Inject(at = @At(value = "TAIL"), method = "move")
private void movementMixin(MoverType mover, Vec3 movement, CallbackInfo ci) {
// involves client-side view bobbing animation on contraptions
if (!self.level.isClientSide)
return;
if (self.isOnGround())
return;
if (self.isPassenger())
return;
Vec3 worldPos = self.position()
.add(0, -0.2, 0);
boolean onAtLeastOneContraption = getIntersectionContraptionsStream().anyMatch(cEntity -> {
Vec3 localPos = ContraptionCollider.getWorldToLocalTranslation(worldPos, cEntity);
localPos = worldPos.add(localPos);
BlockPos blockPos = new BlockPos(localPos);
Contraption contraption = cEntity.getContraption();
StructureTemplate.StructureBlockInfo info = contraption.getBlocks()
.get(blockPos);
if (info == null)
return false;
cEntity.registerColliding(self);
return true;
});
if (!onAtLeastOneContraption)
return;
self.setOnGround(true);
self.getPersistentData()
.putBoolean("ContraptionGrounded", true);
}
@Inject(method = { "spawnSprintParticle" }, at = @At(value = "TAIL"))
private void createRunningParticlesMixin(CallbackInfo ci) {
Vec3 worldPos = self.position()
.add(0, -0.2, 0);
BlockPos pos = new BlockPos(worldPos); // pos where particles are spawned
forCollision(worldPos, (contraption, blockstate, blockpos) -> {
if (!blockstate.addRunningEffects(self.level, blockpos, self)
&& blockstate.getRenderShape() != RenderShape.INVISIBLE) {
Vec3 vec3d = self.getDeltaMovement();
self.level.addParticle(new BlockParticleOption(ParticleTypes.BLOCK, blockstate).setPos(pos),
self.getX() + ((double) random.nextFloat() - 0.5D) * (double) self.getBbWidth(), self.getY() + 0.1D,
self.getZ() + ((double) random.nextFloat() - 0.5D) * (double) self.getBbWidth(), vec3d.x * -4.0D, 1.5D,
vec3d.z * -4.0D);
}
});
}
@Inject(method = "playSound", at = @At("HEAD"), cancellable = true)
private void playSoundShifted(SoundEvent event, float pitch, float volume, CallbackInfo ci) {
if (this.contraption != null && (!self.isSilent() || self instanceof Player)) {
double x = self.getX();
double y = self.getY();
double z = self.getZ();
Vec3 worldPos = ContraptionCollider.getWorldToLocalTranslation(new Vec3(x, y, z), this.contraption);
worldPos = worldPos.add(x, y, z);
self.level.playSound(null, worldPos.x + x, worldPos.y + y, worldPos.z + z, event, self.getSoundSource(),
pitch, volume);
ci.cancel();
}
}
private void bindContraption(Contraption contraption) {
bindContraption(contraption.entity);
}
private void bindContraption(AbstractContraptionEntity contraption) {
this.contraption = contraption;
}
private void unbindContraption() {
this.contraption = null;
}
}

View file

@ -12,7 +12,7 @@ import net.minecraft.world.entity.Entity;
@Mixin(Entity.class)
public class EntityMixin {
@Inject(method = "fireImmune()Z", at = @At("RETURN"), cancellable = true)
public void fireImmune(CallbackInfoReturnable<Boolean> cir) {
public void create$onFireImmune(CallbackInfoReturnable<Boolean> cir) {
if (!cir.getReturnValueZ()) {
Entity self = (Entity) (Object) this;
boolean immune = self.getPersistentData().getBoolean(NetheriteDivingHandler.FIRE_IMMUNE_KEY);

View file

@ -19,14 +19,14 @@ import net.minecraft.world.phys.Vec3;
@Mixin(LivingEntity.class)
public abstract class LavaSwimmingMixin extends Entity {
public LavaSwimmingMixin(EntityType<?> type, Level level) {
private LavaSwimmingMixin(EntityType<?> type, Level level) {
super(type, level);
}
@Inject(method = "travel(Lnet/minecraft/world/phys/Vec3;)V", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;isInLava()Z")), at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;move(Lnet/minecraft/world/entity/MoverType;Lnet/minecraft/world/phys/Vec3;)V", shift = Shift.AFTER, ordinal = 0))
private void onLavaTravel(Vec3 travelVector, CallbackInfo ci) {
private void create$onLavaTravel(Vec3 travelVector, CallbackInfo ci) {
ItemStack bootsStack = DivingBootsItem.getWornItem(this);
if (bootsStack != null && AllItems.NETHERITE_DIVING_BOOTS.isIn(bootsStack))
setDeltaMovement(getDeltaMovement().multiply(DivingBootsItem.getMovementMultiplier(this)));
setDeltaMovement(getDeltaMovement().multiply(DivingBootsItem.getMovementMultiplier((LivingEntity) (Object) this)));
}
}

View file

@ -19,7 +19,6 @@ import java.util.Collection;
@Mixin(Main.class)
public class MainMixin {
/**
* Forge completely bypasses vanilla's
* {@link GameTestServer#create(Thread, LevelStorageAccess, PackRepository, Collection, BlockPos)},

View file

@ -53,13 +53,13 @@ public class MapItemSavedDataMixin implements StationMapData {
private int trackedDecorationCount;
@Unique
private final Map<String, StationMarker> stationMarkers = Maps.newHashMap();
private final Map<String, StationMarker> create$stationMarkers = Maps.newHashMap();
@Inject(
method = "load(Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/world/level/saveddata/maps/MapItemSavedData;",
at = @At("RETURN")
)
private static void onLoad(CompoundTag compound, CallbackInfoReturnable<MapItemSavedData> cir) {
private static void create$onLoad(CompoundTag compound, CallbackInfoReturnable<MapItemSavedData> cir) {
MapItemSavedData mapData = cir.getReturnValue();
StationMapData stationMapData = (StationMapData) mapData;
@ -74,9 +74,9 @@ public class MapItemSavedDataMixin implements StationMapData {
method = "save(Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/nbt/CompoundTag;",
at = @At("RETURN")
)
public void onSave(CompoundTag compound, CallbackInfoReturnable<CompoundTag> cir) {
public void create$onSave(CompoundTag compound, CallbackInfoReturnable<CompoundTag> cir) {
ListTag listTag = new ListTag();
for (StationMarker stationMarker : stationMarkers.values()) {
for (StationMarker stationMarker : create$stationMarkers.values()) {
listTag.add(stationMarker.save());
}
compound.put(STATION_MARKERS_KEY, listTag);
@ -84,7 +84,7 @@ public class MapItemSavedDataMixin implements StationMapData {
@Override
public void addStationMarker(StationMarker marker) {
stationMarkers.put(marker.getId(), marker);
create$stationMarkers.put(marker.getId(), marker);
int scaleMultiplier = 1 << scale;
float localX = (marker.getTarget().getX() - x) / (float) scaleMultiplier;
@ -144,7 +144,7 @@ public class MapItemSavedDataMixin implements StationMapData {
if (marker == null)
return false;
if (stationMarkers.remove(marker.getId(), marker)) {
if (create$stationMarkers.remove(marker.getId(), marker)) {
removeDecoration(marker.getId());
return true;
}
@ -161,12 +161,13 @@ public class MapItemSavedDataMixin implements StationMapData {
method = "checkBanners(Lnet/minecraft/world/level/BlockGetter;II)V",
at = @At("RETURN")
)
public void checkBanners(BlockGetter blockGetter, int x, int z, CallbackInfo ci) {
checkStations(blockGetter, x, z);
public void create$onCheckBanners(BlockGetter blockGetter, int x, int z, CallbackInfo ci) {
create$checkStations(blockGetter, x, z);
}
private void checkStations(BlockGetter blockGetter, int x, int z) {
Iterator<StationMarker> iterator = stationMarkers.values().iterator();
@Unique
private void create$checkStations(BlockGetter blockGetter, int x, int z) {
Iterator<StationMarker> iterator = create$stationMarkers.values().iterator();
List<StationMarker> newMarkers = new ArrayList<>();
while (iterator.hasNext()) {

View file

@ -20,9 +20,8 @@ import net.minecraft.world.level.material.FluidState;
@Mixin(FlowingFluid.class)
public class WaterWheelFluidSpreadMixin {
@Inject(at = @At("HEAD"), cancellable = true, method = "canPassThrough(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/world/level/material/Fluid;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/material/FluidState;)Z")
protected void canPassThroughOnWaterWheel(BlockGetter pLevel, Fluid pFluid, BlockPos pFromPos, BlockState p_75967_,
@Inject(method = "canPassThrough(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/world/level/material/Fluid;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/material/FluidState;)Z", at = @At("HEAD"), cancellable = true)
protected void create$canPassThroughOnWaterWheel(BlockGetter pLevel, Fluid pFluid, BlockPos pFromPos, BlockState p_75967_,
Direction pDirection, BlockPos p_75969_, BlockState p_75970_, FluidState p_75971_,
CallbackInfoReturnable<Boolean> cir) {
@ -43,5 +42,4 @@ public class WaterWheelFluidSpreadMixin {
&& irotate.getRotationAxis(belowState) == pDirection.getAxis())
cir.setReturnValue(false);
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import java.util.Set;
@ -13,15 +13,15 @@ import net.minecraft.server.level.BlockDestructionProgress;
@Mixin(BlockDestructionProgress.class)
public class BlockDestructionProgressMixin implements BlockDestructionProgressExtension {
@Unique
private Set<BlockPos> extraPositions;
private Set<BlockPos> create$extraPositions;
@Override
public Set<BlockPos> getExtraPositions() {
return extraPositions;
return create$extraPositions;
}
@Override
public void setExtraPositions(Set<BlockPos> positions) {
extraPositions = positions;
create$extraPositions = positions;
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -15,7 +15,7 @@ public abstract class CameraMixin {
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;getMaxZoom(D)D"),
index = 0
)
public double modifyCameraOffset(double originalValue) {
public double create$modifyCameraOffset(double originalValue) {
return originalValue * CameraDistanceModifier.getMultiplier();
}
}

View file

@ -0,0 +1,172 @@
package com.simibubi.create.foundation.mixin.client;
import java.lang.ref.Reference;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.logging.log4j.util.TriConsumer;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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.callback.CallbackInfo;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.CapabilityProvider;
@Mixin(Entity.class)
public abstract class EntityContraptionInteractionMixin extends CapabilityProvider<Entity> {
private EntityContraptionInteractionMixin(Class<Entity> baseClass) {
super(baseClass);
}
@Shadow
public Level level;
@Shadow
private Vec3 position;
@Shadow
private float nextStep;
@Shadow
@Final
protected Random random;
@Shadow
private EntityDimensions dimensions;
@Shadow
protected abstract float nextStep();
@Shadow
protected abstract void playStepSound(BlockPos pos, BlockState state);
@Unique
private Stream<AbstractContraptionEntity> create$getIntersectionContraptionsStream() {
return ContraptionHandler.loadedContraptions.get(level)
.values()
.stream()
.map(Reference::get)
.filter(cEntity -> cEntity != null && cEntity.collidingEntities.containsKey((Entity) (Object) this));
}
@Unique
private Set<AbstractContraptionEntity> create$getIntersectingContraptions() {
Set<AbstractContraptionEntity> contraptions = create$getIntersectionContraptionsStream().collect(Collectors.toSet());
contraptions.addAll(level.getEntitiesOfClass(AbstractContraptionEntity.class, ((Entity) (Object) this).getBoundingBox()
.inflate(1f)));
return contraptions;
}
@Unique
private void forCollision(Vec3 worldPos, TriConsumer<Contraption, BlockState, BlockPos> action) {
create$getIntersectingContraptions().forEach(cEntity -> {
Vec3 localPos = ContraptionCollider.worldToLocalPos(worldPos, cEntity);
BlockPos blockPos = new BlockPos(localPos);
Contraption contraption = cEntity.getContraption();
StructureTemplate.StructureBlockInfo info = contraption.getBlocks()
.get(blockPos);
if (info != null) {
BlockState blockstate = info.state;
action.accept(contraption, blockstate, blockPos);
}
});
}
// involves block step sounds on contraptions
// IFNE line 661 injecting before `!blockstate.isAir(this.world, blockpos)`
@Inject(method = "move", at = @At(value = "JUMP", opcode = Opcodes.IFNE, ordinal = 7))
private void create$contraptionStepSounds(MoverType mover, Vec3 movement, CallbackInfo ci) {
Vec3 worldPos = position.add(0, -0.2, 0);
MutableBoolean stepped = new MutableBoolean(false);
forCollision(worldPos, (contraption, state, pos) -> {
playStepSound(pos, state);
stepped.setTrue();
});
if (stepped.booleanValue())
nextStep = nextStep();
}
// involves client-side view bobbing animation on contraptions
@Inject(method = "move", at = @At(value = "TAIL"))
private void create$onMove(MoverType mover, Vec3 movement, CallbackInfo ci) {
if (!level.isClientSide)
return;
Entity self = (Entity) (Object) this;
if (self.isOnGround())
return;
if (self.isPassenger())
return;
Vec3 worldPos = position.add(0, -0.2, 0);
boolean onAtLeastOneContraption = create$getIntersectionContraptionsStream().anyMatch(cEntity -> {
Vec3 localPos = ContraptionCollider.worldToLocalPos(worldPos, cEntity);
BlockPos blockPos = new BlockPos(localPos);
Contraption contraption = cEntity.getContraption();
StructureTemplate.StructureBlockInfo info = contraption.getBlocks()
.get(blockPos);
if (info == null)
return false;
cEntity.registerColliding(self);
return true;
});
if (!onAtLeastOneContraption)
return;
self.setOnGround(true);
self.getPersistentData()
.putBoolean("ContraptionGrounded", true);
}
@Inject(method = "spawnSprintParticle", at = @At(value = "TAIL"))
private void create$onSpawnSprintParticle(CallbackInfo ci) {
Entity self = (Entity) (Object) this;
Vec3 worldPos = position.add(0, -0.2, 0);
BlockPos particlePos = new BlockPos(worldPos); // pos where particles are spawned
forCollision(worldPos, (contraption, state, pos) -> {
if (!state.addRunningEffects(level, pos, self)
&& state.getRenderShape() != RenderShape.INVISIBLE) {
Vec3 speed = self.getDeltaMovement();
level.addParticle(
new BlockParticleOption(ParticleTypes.BLOCK, state).setPos(particlePos),
self.getX() + ((double) random.nextFloat() - 0.5D) * (double) dimensions.width,
self.getY() + 0.1D,
self.getZ() + ((double) random.nextFloat() - 0.5D) * (double) dimensions.height,
speed.x * -4.0D, 1.5D, speed.z * -4.0D
);
}
});
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -18,7 +18,7 @@ public class FixNormalScalingMixin {
* same as in the beginning.
*/
@Inject(at = @At(value = "INVOKE", target = "Lcom/mojang/math/Matrix3f;mul(F)V", shift = Shift.AFTER), method = "scale(FFF)V", cancellable = true)
private void returnAfterNegate(float x, float y, float z, CallbackInfo ci) {
private void create$returnAfterNegate(float x, float y, float z, CallbackInfo ci) {
ci.cancel();
}
@ -30,7 +30,7 @@ public class FixNormalScalingMixin {
* does not work for negative numbers.
*/
@ModifyArg(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;fastInvCubeRoot(F)F"), method = "scale(FFF)V")
private float absInvCbrtInput(float input) {
private float create$absInvCbrtInput(float input) {
return Math.abs(input);
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -9,14 +9,11 @@ import com.simibubi.create.content.logistics.trains.track.TrackBlockOutline;
import com.simibubi.create.foundation.block.BigOutlines;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@Mixin(GameRenderer.class)
public class GameRendererMixin {
@Inject(at = @At("TAIL"), method = "pick")
private void bigShapePick(CallbackInfo ci) {
@Inject(method = "pick(F)V", at = @At("TAIL"))
private void create$bigShapePick(CallbackInfo ci) {
BigOutlines.pick();
TrackBlockOutline.pickCurves();
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -11,22 +11,17 @@ import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@Mixin(LocalPlayer.class)
public abstract class HeavyBootsOnPlayerMixin extends AbstractClientPlayer {
private HeavyBootsOnPlayerMixin(ClientLevel level, GameProfile profile) {
super(level, profile);
}
@Inject(method = "isUnderWater()Z", at = @At("HEAD"), cancellable = true)
public void noSwimmingWithHeavyBootsOn(CallbackInfoReturnable<Boolean> cir) {
public void create$noSwimmingWithHeavyBootsOn(CallbackInfoReturnable<Boolean> cir) {
CompoundTag persistentData = getPersistentData();
if (persistentData.contains("HeavyBoots"))
cir.setReturnValue(false);
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -19,7 +19,7 @@ import net.minecraft.world.item.ItemStack;
@Mixin(HumanoidArmorLayer.class)
public class HumanoidArmorLayerMixin {
@Inject(method = "renderArmorPiece(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/entity/EquipmentSlot;ILnet/minecraft/client/model/HumanoidModel;)V", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/entity/LivingEntity;getItemBySlot(Lnet/minecraft/world/entity/EquipmentSlot;)Lnet/minecraft/world/item/ItemStack;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
private void onRenderArmorPiece(PoseStack poseStack, MultiBufferSource bufferSource, LivingEntity entity, EquipmentSlot slot, int light, HumanoidModel<?> model, CallbackInfo ci, ItemStack stack) {
private void create$onRenderArmorPiece(PoseStack poseStack, MultiBufferSource bufferSource, LivingEntity entity, EquipmentSlot slot, int light, HumanoidModel<?> model, CallbackInfo ci, ItemStack stack) {
if (stack.getItem() instanceof CustomRenderedArmorItem renderer) {
renderer.renderArmorPiece((HumanoidArmorLayer<?, ?, ?>) (Object) this, poseStack, bufferSource, entity, slot, light, model, stack);
ci.cancel();

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import java.util.Set;
import java.util.SortedSet;
@ -35,7 +35,7 @@ public class LevelRendererMixin {
private Long2ObjectMap<SortedSet<BlockDestructionProgress>> destructionProgress;
@Inject(method = "destroyBlockProgress(ILnet/minecraft/core/BlockPos;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/BlockDestructionProgress;updateTick(I)V", shift = Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD)
private void onDestroyBlockProgress(int breakerId, BlockPos pos, int progress, CallbackInfo ci, BlockDestructionProgress progressObj) {
private void create$onDestroyBlockProgress(int breakerId, BlockPos pos, int progress, CallbackInfo ci, BlockDestructionProgress progressObj) {
BlockState state = level.getBlockState(pos);
IBlockRenderProperties properties = RenderProperties.get(state);
if (properties instanceof MultiPosDestructionHandler handler) {
@ -51,7 +51,7 @@ public class LevelRendererMixin {
}
@Inject(method = "removeProgress(Lnet/minecraft/server/level/BlockDestructionProgress;)V", at = @At("RETURN"))
private void onRemoveProgress(BlockDestructionProgress progress, CallbackInfo ci) {
private void create$onRemoveProgress(BlockDestructionProgress progress, CallbackInfo ci) {
Set<BlockPos> extraPositions = ((BlockDestructionProgressExtension) progress).getExtraPositions();
if (extraPositions != null) {
for (BlockPos extraPos : extraPositions) {

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import java.util.Iterator;
@ -27,7 +27,7 @@ public class MapRendererMapInstanceMixin {
@Group(name = "custom_decoration_rendering", min = 1, max = 1)
@Inject(method = "draw(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ZI)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/saveddata/maps/MapDecoration;render(I)Z", remap = false), locals = LocalCapture.CAPTURE_FAILHARD)
private void onDraw(PoseStack poseStack, MultiBufferSource bufferSource, boolean active, int packedLight, CallbackInfo ci, int i, int j, float f, Matrix4f matrix4f, VertexConsumer vertexConsumer, int index, Iterator<MapDecoration> iterator, MapDecoration decoration) {
private void create$onDraw(PoseStack poseStack, MultiBufferSource bufferSource, boolean active, int packedLight, CallbackInfo ci, int i, int j, float f, Matrix4f matrix4f, VertexConsumer vertexConsumer, int index, Iterator<MapDecoration> iterator, MapDecoration decoration) {
if (decoration instanceof CustomRenderedMapDecoration renderer) {
renderer.render(poseStack, bufferSource, active, packedLight, data, index);
}
@ -35,7 +35,7 @@ public class MapRendererMapInstanceMixin {
@Group(name = "custom_decoration_rendering")
@Inject(method = "draw(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ZI)V", at = @At(value = "FIELD", target = "net/optifine/reflect/Reflector.ForgeMapDecoration_render:Lnet/optifine/reflect/ReflectorMethod;", opcode = Opcodes.GETSTATIC, ordinal = 1, remap = false), locals = LocalCapture.CAPTURE_FAILHARD)
private void onDrawOptifine(PoseStack poseStack, MultiBufferSource bufferSource, boolean active, int packedLight, CallbackInfo ci, int i, int j, float f, Matrix4f matrix4f, VertexConsumer vertexConsumer, int index, Iterator<MapDecoration> iterator, MapDecoration decoration) {
private void create$onDrawOptifine(PoseStack poseStack, MultiBufferSource bufferSource, boolean active, int packedLight, CallbackInfo ci, int i, int j, float f, Matrix4f matrix4f, VertexConsumer vertexConsumer, int index, Iterator<MapDecoration> iterator, MapDecoration decoration) {
if (decoration instanceof CustomRenderedMapDecoration renderer) {
renderer.render(poseStack, bufferSource, active, packedLight, data, index);
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -17,20 +17,18 @@ import net.minecraftforge.client.model.ModelDataManager;
@OnlyIn(Dist.CLIENT)
@Mixin(ModelDataManager.class)
public class ModelDataRefreshMixin {
/**
* Normally ModelDataManager will throw an exception if a block entity tries
* to refresh its model data from a world the client isn't currently in,
* but we need that to not happen for block entities in fake schematic
* worlds, so in those cases just do nothing instead.
*/
@Inject(at = @At("HEAD"), method = "requestModelDataRefresh", cancellable = true, remap = false)
private static void requestModelDataRefresh(BlockEntity be, CallbackInfo ci) {
@Inject(method = "requestModelDataRefresh", at = @At("HEAD"), cancellable = true, remap = false)
private static void create$requestModelDataRefresh(BlockEntity be, CallbackInfo ci) {
if (be != null) {
Level world = be.getLevel();
if (world != Minecraft.getInstance().level && world instanceof SchematicWorld)
ci.cancel();
}
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -17,7 +17,7 @@ import net.minecraft.world.item.ItemStack;
@Mixin(PlayerRenderer.class)
public class PlayerRendererMixin {
@Inject(method = "getArmPose(Lnet/minecraft/client/player/AbstractClientPlayer;Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/client/model/HumanoidModel$ArmPose;", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/player/AbstractClientPlayer;getItemInHand(Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/world/item/ItemStack;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
private static void onGetArmPose(AbstractClientPlayer player, InteractionHand hand, CallbackInfoReturnable<ArmPose> cir, ItemStack stack) {
private static void create$onGetArmPose(AbstractClientPlayer player, InteractionHand hand, CallbackInfoReturnable<ArmPose> cir, ItemStack stack) {
if (stack.getItem() instanceof CustomArmPoseItem armPoseProvider) {
ArmPose pose = armPoseProvider.getArmPose(stack, player, hand);
if (pose != null) {

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.mixin;
package com.simibubi.create.foundation.mixin.client;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -11,18 +11,15 @@ import com.mojang.blaze3d.platform.Window;
import com.simibubi.create.foundation.gui.UIRenderHelper;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@Mixin(Minecraft.class)
public class WindowResizeMixin {
@Shadow
@Final
private Window window;
@Shadow @Final private Window window;
@Inject(at = @At("TAIL"), method = "resizeDisplay")
private void updateWindowSize(CallbackInfo ci) {
@Inject(method = "resizeDisplay()V", at = @At("TAIL"))
private void create$updateWindowSize(CallbackInfo ci) {
UIRenderHelper.updateWindowSize(window);
}
}

View file

@ -38,7 +38,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.tra
import com.simibubi.create.content.contraptions.fluids.actors.FluidSplashPacket;
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
import com.simibubi.create.content.contraptions.relays.gauge.GaugeObservedPacket;
import com.simibubi.create.content.curiosities.armor.NetheriteDivingHandler;
import com.simibubi.create.content.curiosities.bell.SoulPulseEffectPacket;
import com.simibubi.create.content.curiosities.clipboard.ClipboardEditPacket;
import com.simibubi.create.content.curiosities.symmetry.ConfigureSymmetryWandPacket;
@ -200,15 +199,13 @@ public enum AllPackets {
TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket::new, PLAY_TO_CLIENT),
UPDATE_ELEVATOR_FLOORS(ElevatorFloorListPacket.class, ElevatorFloorListPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket::new, PLAY_TO_CLIENT),
SET_FIRE_IMMUNE(NetheriteDivingHandler.SetFireImmunePacket.class, NetheriteDivingHandler.SetFireImmunePacket::new,
PLAY_TO_CLIENT),
CONTRAPTION_COLLIDER_LOCK(ContraptionColliderLockPacket.class, ContraptionColliderLockPacket::new, PLAY_TO_CLIENT),
ATTACHED_COMPUTER(AttachedComputerPacket.class, AttachedComputerPacket::new, PLAY_TO_CLIENT),
;
public static final ResourceLocation CHANNEL_NAME = Create.asResource("main");
public static final int NETWORK_VERSION = 2;
public static final int NETWORK_VERSION = 3;
public static final String NETWORK_VERSION_STR = String.valueOf(NETWORK_VERSION);
private static SimpleChannel channel;

View file

@ -10,7 +10,6 @@
"WaterWheelFluidSpreadMixin",
"CustomItemUseEffectsMixin",
"EnchantmentHelperMixin",
"EnchantmentMixin",
"EntityMixin",
"LavaSwimmingMixin",
"MainMixin",
@ -25,18 +24,18 @@
"accessor.ServerLevelAccessor"
],
"client": [
"BlockDestructionProgressMixin",
"CameraMixin",
"EntityContraptionInteractionMixin",
"FixNormalScalingMixin",
"GameRendererMixin",
"HeavyBootsOnPlayerMixin",
"HumanoidArmorLayerMixin",
"LevelRendererMixin",
"MapRendererMapInstanceMixin",
"ModelDataRefreshMixin",
"PlayerRendererMixin",
"WindowResizeMixin",
"client.BlockDestructionProgressMixin",
"client.CameraMixin",
"client.EntityContraptionInteractionMixin",
"client.FixNormalScalingMixin",
"client.GameRendererMixin",
"client.HeavyBootsOnPlayerMixin",
"client.HumanoidArmorLayerMixin",
"client.LevelRendererMixin",
"client.MapRendererMapInstanceMixin",
"client.ModelDataRefreshMixin",
"client.PlayerRendererMixin",
"client.WindowResizeMixin",
"accessor.AgeableListModelAccessor",
"accessor.GameRendererAccessor",
"accessor.HumanoidArmorLayerAccessor",