Skip to content

Commit

Permalink
Improve mod compatibility by setting the attributes instead of redire…
Browse files Browse the repository at this point in the history
…cting their access
  • Loading branch information
RaphiMC committed Jun 26, 2024
1 parent 13e55b2 commit 9c15f48
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,68 @@

import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.util.EnchantmentUtil;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.BlockTags;

import java.util.Optional;

public class EnchantmentAttributesEmulation1_20_6 {

public static void init() {
ClientTickEvents.START_WORLD_TICK.register(world -> {
final ClientPlayerEntity player = MinecraftClient.getInstance().player;
if (player != null && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
final int efficiencyLevel = EnchantmentUtil.getEquipmentLevel(Enchantments.EFFICIENCY, player);
if (efficiencyLevel > 0) {
player.getAttributeInstance(EntityAttributes.PLAYER_MINING_EFFICIENCY).setBaseValue(efficiencyLevel * efficiencyLevel + 1);
} else {
player.getAttributeInstance(EntityAttributes.PLAYER_MINING_EFFICIENCY).setBaseValue(0);
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
// Update generic attributes for all entities
for (Entity entity : world.getEntities()) {
if (entity.isLogicalSideForUpdatingMovement() && entity instanceof LivingEntity livingEntity) {
livingEntity.getAttributeInstance(EntityAttributes.GENERIC_WATER_MOVEMENT_EFFICIENCY).setBaseValue(getEquipmentLevel(Enchantments.DEPTH_STRIDER, livingEntity) / 3F);
setGenericMovementEfficiencyAttribute(livingEntity);
}
}

// Update player specific attributes for all players
for (PlayerEntity player : world.getPlayers()) {
if (player.isLogicalSideForUpdatingMovement()) {
final int efficiencyLevel = getEquipmentLevel(Enchantments.EFFICIENCY, player);
if (efficiencyLevel > 0) {
player.getAttributeInstance(EntityAttributes.PLAYER_MINING_EFFICIENCY).setBaseValue(efficiencyLevel * efficiencyLevel + 1);
} else {
player.getAttributeInstance(EntityAttributes.PLAYER_MINING_EFFICIENCY).setBaseValue(0);
}

player.getAttributeInstance(EntityAttributes.PLAYER_SNEAKING_SPEED).setBaseValue(0.3F + getEquipmentLevel(Enchantments.SWIFT_SNEAK, player) * 0.15F);
player.getAttributeInstance(EntityAttributes.PLAYER_SUBMERGED_MINING_SPEED).setBaseValue(getEquipmentLevel(Enchantments.AQUA_AFFINITY, player) <= 0 ? 0.2F : 1F);
}
}
player.getAttributeInstance(EntityAttributes.PLAYER_SNEAKING_SPEED).setBaseValue(0.3F + EnchantmentUtil.getEquipmentLevel(Enchantments.SWIFT_SNEAK, player) * 0.15F);
player.getAttributeInstance(EntityAttributes.GENERIC_WATER_MOVEMENT_EFFICIENCY).setBaseValue(EnchantmentUtil.getEquipmentLevel(Enchantments.DEPTH_STRIDER, player) / 3F);
player.getAttributeInstance(EntityAttributes.PLAYER_SUBMERGED_MINING_SPEED).setBaseValue(EnchantmentUtil.getEquipmentLevel(Enchantments.AQUA_AFFINITY, player) <= 0 ? 0.2F : 1F);
}
});
}

/**
* Called from MixinLivingEntity as well to ensure the attribute value is set at the correct place in the entity tick logic.
* Called above just as a fallback if a mod accesses the raw attribute value directly.
*/
public static void setGenericMovementEfficiencyAttribute(final LivingEntity entity) {
final boolean isOnSoulSpeedBlock = entity.getWorld().getBlockState(entity.getVelocityAffectingPos()).isIn(BlockTags.SOUL_SPEED_BLOCKS);
if (isOnSoulSpeedBlock && getEquipmentLevel(Enchantments.SOUL_SPEED, entity) > 0) {
entity.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_EFFICIENCY).setBaseValue(1);
} else {
entity.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_EFFICIENCY).setBaseValue(0);
}
}

private static int getEquipmentLevel(final RegistryKey<Enchantment> enchantment, final LivingEntity entity) {
final Optional<RegistryEntry.Reference<Enchantment>> enchantmentRef = entity.getWorld().getRegistryManager().getWrapperOrThrow(RegistryKeys.ENCHANTMENT).getOptional(enchantment);
return enchantmentRef.map(e -> EnchantmentHelper.getEquipmentLevel(e, entity)).orElse(0);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.versioned.EnchantmentAttributesEmulation1_20_6;
import de.florianmichael.viafabricplus.fixes.versioned.visual.EntityRidingOffsetsPre1_20_2;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import de.florianmichael.viafabricplus.util.EnchantmentUtil;
import net.minecraft.block.BlockState;
import net.minecraft.block.TrapdoorBlock;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.*;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffects;
Expand All @@ -48,7 +47,6 @@
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
Expand Down Expand Up @@ -80,10 +78,10 @@ public MixinLivingEntity(EntityType<?> type, World world) {
super(type, world);
}

@Inject(method = "getVelocityMultiplier", at = @At("HEAD"), cancellable = true)
private void getVelocityMultiplier1_20_6(CallbackInfoReturnable<Float> cir) {
@Inject(method = "getVelocityMultiplier", at = @At("HEAD"))
private void setGenericMovementEfficiencyAttribute(CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
cir.setReturnValue(this.isOnSoulSpeedBlock() && EnchantmentUtil.getEquipmentLevel(Enchantments.SOUL_SPEED, (LivingEntity) (Object) this) > 0 ? 1F : super.getVelocityMultiplier());
EnchantmentAttributesEmulation1_20_6.setGenericMovementEfficiencyAttribute((LivingEntity) (Object) this);
}
}

Expand Down Expand Up @@ -255,13 +253,4 @@ private void allowGappedLadderClimb(CallbackInfoReturnable<Boolean> cir) {
}
}

@Unique
protected boolean isOnSoulSpeedBlock() {
if ((Object) this instanceof PlayerEntity player && player.getAbilities().flying) {
return false;
}

return this.getWorld().getBlockState(this.getVelocityAffectingPos()).isIn(BlockTags.SOUL_SPEED_BLOCKS);
}

}

This file was deleted.

0 comments on commit 9c15f48

Please sign in to comment.