Merge and fix

This commit is contained in:
paulevsGitch 2020-11-08 15:07:19 +03:00
parent b91c85529d
commit ce9f4add97
548 changed files with 17517 additions and 16862 deletions

View file

@ -1,22 +1,22 @@
package ru.betterend.mixin.client;
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 net.minecraft.client.recipebook.ClientRecipeBook;
import net.minecraft.client.recipebook.RecipeBookGroup;
import net.minecraft.recipe.Recipe;
import ru.betterend.recipe.builders.AlloyingRecipe;
@Mixin(ClientRecipeBook.class)
public abstract class ClientRecipeBookMixin {
@Inject(method = "getGroupForRecipe", at = @At("HEAD"), cancellable = true)
private static void getGroupForRecipe(Recipe<?> recipe, CallbackInfoReturnable<RecipeBookGroup> cinfo) {
if (recipe instanceof AlloyingRecipe) {
cinfo.setReturnValue(RecipeBookGroup.BLAST_FURNACE_MISC);
cinfo.cancel();
}
}
}
package ru.betterend.mixin.client;
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 net.minecraft.client.recipebook.ClientRecipeBook;
import net.minecraft.client.recipebook.RecipeBookGroup;
import net.minecraft.recipe.Recipe;
import ru.betterend.recipe.builders.AlloyingRecipe;
@Mixin(ClientRecipeBook.class)
public abstract class ClientRecipeBookMixin {
@Inject(method = "getGroupForRecipe", at = @At("HEAD"), cancellable = true)
private static void getGroupForRecipe(Recipe<?> recipe, CallbackInfoReturnable<RecipeBookGroup> cinfo) {
if (recipe instanceof AlloyingRecipe) {
cinfo.setReturnValue(RecipeBookGroup.BLAST_FURNACE_MISC);
cinfo.cancel();
}
}
}

View file

@ -1,23 +1,23 @@
package ru.betterend.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.client.render.model.json.ModelVariantMap.DeserializationContext;
import net.minecraft.util.Identifier;
import ru.betterend.interfaces.IdentifiedContext;
@Mixin(DeserializationContext.class)
public class DeserializationContextMixin implements IdentifiedContext {
private Identifier contextId;
@Override
public Identifier getContextId() {
return this.contextId;
}
@Override
public void setContextId(Identifier id) {
this.contextId = id;
}
}
package ru.betterend.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.client.render.model.json.ModelVariantMap.DeserializationContext;
import net.minecraft.util.Identifier;
import ru.betterend.interfaces.IdentifiedContext;
@Mixin(DeserializationContext.class)
public class DeserializationContextMixin implements IdentifiedContext {
private Identifier contextId;
@Override
public Identifier getContextId() {
return this.contextId;
}
@Override
public void setContextId(Identifier id) {
this.contextId = id;
}
}

View file

@ -1,47 +1,47 @@
package ru.betterend.mixin.client;
import java.util.List;
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.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.google.common.collect.Lists;
import net.minecraft.block.Block;
import net.minecraft.resource.NamespaceResourceManager;
import net.minecraft.resource.Resource;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import ru.betterend.BetterEnd;
import ru.betterend.interfaces.Patterned;
@Mixin(NamespaceResourceManager.class)
public abstract class NamespaceResourceManagerMixin {
@Shadow
public abstract Resource getResource(Identifier id);
@Inject(method = "getAllResources", cancellable = true, at = @At(
value = "NEW",
target = "java/io/FileNotFoundException",
shift = Shift.BEFORE))
public void getStatesPattern(Identifier id, CallbackInfoReturnable<List<Resource>> info) {
if (id.getNamespace().contains(BetterEnd.MOD_ID)) {
String[] data = id.getPath().split("/");
if (data.length > 1) {
Identifier blockId = BetterEnd.makeID(data[1].replace(".json", ""));
Block block = Registry.BLOCK.get(blockId);
if (block instanceof Patterned) {
List<Resource> resources = Lists.newArrayList();
resources.add(this.getResource(((Patterned) block).statePatternId()));
info.setReturnValue(resources);
info.cancel();
}
}
}
}
}
package ru.betterend.mixin.client;
import java.util.List;
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.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.google.common.collect.Lists;
import net.minecraft.block.Block;
import net.minecraft.resource.NamespaceResourceManager;
import net.minecraft.resource.Resource;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import ru.betterend.BetterEnd;
import ru.betterend.interfaces.Patterned;
@Mixin(NamespaceResourceManager.class)
public abstract class NamespaceResourceManagerMixin {
@Shadow
public abstract Resource getResource(Identifier id);
@Inject(method = "getAllResources", cancellable = true, at = @At(
value = "NEW",
target = "java/io/FileNotFoundException",
shift = Shift.BEFORE))
public void getStatesPattern(Identifier id, CallbackInfoReturnable<List<Resource>> info) {
if (id.getNamespace().contains(BetterEnd.MOD_ID)) {
String[] data = id.getPath().split("/");
if (data.length > 1) {
Identifier blockId = BetterEnd.makeID(data[1].replace(".json", ""));
Block block = Registry.BLOCK.get(blockId);
if (block instanceof Patterned) {
List<Resource> resources = Lists.newArrayList();
resources.add(this.getResource(((Patterned) block).statePatternId()));
info.setReturnValue(resources);
info.cancel();
}
}
}
}
}

View file

@ -1,51 +1,51 @@
package ru.betterend.mixin.common;
import java.util.List;
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.google.common.collect.Lists;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.util.math.MathHelper;
import ru.betterend.item.EndHammer;
import ru.betterend.util.MHelper;
@Mixin(AbstractBlock.class)
public abstract class AbstractBlockMixin {
@Inject(method = "getDroppedStacks", at = @At("HEAD"), cancellable = true)
public void getDroppedStacks(BlockState state, LootContext.Builder builder, CallbackInfoReturnable<List<ItemStack>> info) {
if (state.isOf(Blocks.GLOWSTONE)) {
ItemStack tool = builder.get(LootContextParameters.TOOL);
if (tool != null && tool.getItem() instanceof EndHammer) {
int min = 3;
int max = 4;
int count = 0;
int fortune = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);
if (fortune > 0) {
fortune /= Enchantments.FORTUNE.getMaxLevel();
min = MathHelper.clamp(min + fortune, min, max);
if (min == max) {
info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, max)));
info.cancel();
}
}
count = MHelper.randRange(min, max, MHelper.RANDOM);
info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, count)));
info.cancel();
}
}
}
}
package ru.betterend.mixin.common;
import java.util.List;
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.google.common.collect.Lists;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.util.math.MathHelper;
import ru.betterend.item.EndHammer;
import ru.betterend.util.MHelper;
@Mixin(AbstractBlock.class)
public abstract class AbstractBlockMixin {
@Inject(method = "getDroppedStacks", at = @At("HEAD"), cancellable = true)
public void getDroppedStacks(BlockState state, LootContext.Builder builder, CallbackInfoReturnable<List<ItemStack>> info) {
if (state.isOf(Blocks.GLOWSTONE)) {
ItemStack tool = builder.get(LootContextParameters.TOOL);
if (tool != null && tool.getItem() instanceof EndHammer) {
int min = 3;
int max = 4;
int count = 0;
int fortune = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);
if (fortune > 0) {
fortune /= Enchantments.FORTUNE.getMaxLevel();
min = MathHelper.clamp(min + fortune, min, max);
if (min == max) {
info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, max)));
info.cancel();
}
}
count = MHelper.randRange(min, max, MHelper.RANDOM);
info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, count)));
info.cancel();
}
}
}
}

View file

@ -1,92 +1,92 @@
package ru.betterend.mixin.common;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.AnvilBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.screen.AnvilScreenHandler;
import net.minecraft.screen.ForgingScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.tag.BlockTags;
import net.minecraft.world.World;
import ru.betterend.recipe.builders.AnvilSmithingRecipe;
@Mixin(AnvilScreenHandler.class)
public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler {
private final World world = this.player.world;
private final RecipeManager recipeManager = this.world.getRecipeManager();
private AnvilSmithingRecipe currentRecipe;
public AnvilScreenHandlerMixin(ScreenHandlerType<?> type, int syncId, PlayerInventory playerInventory,
ScreenHandlerContext context) {
super(type, syncId, playerInventory, context);
}
@Shadow
public abstract void updateResult();
@Inject(method = "canTakeOutput", at = @At("HEAD"), cancellable = true)
protected void canTakeOutput(PlayerEntity player, boolean present, CallbackInfoReturnable<Boolean> info) {
if (currentRecipe != null) {
ItemStack output = this.currentRecipe.craft(input, player);
if (!output.isEmpty()) {
info.setReturnValue(true);
info.cancel();
}
}
}
@Inject(method = "onTakeOutput", at = @At("HEAD"), cancellable = true)
protected void onTakeOutput(PlayerEntity player, ItemStack stack, CallbackInfoReturnable<ItemStack> info) {
if (currentRecipe != null) {
this.input.getStack(1).decrement(1);
this.updateResult();
this.context.run((world, blockPos) -> {
BlockState anvilState = world.getBlockState(blockPos);
if (!player.abilities.creativeMode && anvilState.isIn(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
BlockState landingState = AnvilBlock.getLandingState(anvilState);
if (landingState == null) {
world.removeBlock(blockPos, false);
world.syncWorldEvent(1029, blockPos, 0);
} else {
world.setBlockState(blockPos, landingState, 2);
world.syncWorldEvent(1030, blockPos, 0);
}
} else {
world.syncWorldEvent(1030, blockPos, 0);
}
});
info.setReturnValue(stack);
info.cancel();
}
}
@Inject(method = "updateResult", at = @At("HEAD"), cancellable = true)
public void updateOutput(CallbackInfo info) {
this.currentRecipe = this.recipeManager.getFirstMatch(AnvilSmithingRecipe.TYPE, input, world).orElse(null);
if (currentRecipe != null) {
this.output.setStack(0, currentRecipe.craft(input));
this.sendContentUpdates();
info.cancel();
}
}
@Inject(method = "setNewItemName", at = @At("HEAD"), cancellable = true)
public void setNewItemName(String string, CallbackInfo info) {
if (currentRecipe != null) {
info.cancel();
}
}
}
package ru.betterend.mixin.common;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.AnvilBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.screen.AnvilScreenHandler;
import net.minecraft.screen.ForgingScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.tag.BlockTags;
import net.minecraft.world.World;
import ru.betterend.recipe.builders.AnvilSmithingRecipe;
@Mixin(AnvilScreenHandler.class)
public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler {
private final World world = this.player.world;
private final RecipeManager recipeManager = this.world.getRecipeManager();
private AnvilSmithingRecipe currentRecipe;
public AnvilScreenHandlerMixin(ScreenHandlerType<?> type, int syncId, PlayerInventory playerInventory,
ScreenHandlerContext context) {
super(type, syncId, playerInventory, context);
}
@Shadow
public abstract void updateResult();
@Inject(method = "canTakeOutput", at = @At("HEAD"), cancellable = true)
protected void canTakeOutput(PlayerEntity player, boolean present, CallbackInfoReturnable<Boolean> info) {
if (currentRecipe != null) {
ItemStack output = this.currentRecipe.craft(input, player);
if (!output.isEmpty()) {
info.setReturnValue(true);
info.cancel();
}
}
}
@Inject(method = "onTakeOutput", at = @At("HEAD"), cancellable = true)
protected void onTakeOutput(PlayerEntity player, ItemStack stack, CallbackInfoReturnable<ItemStack> info) {
if (currentRecipe != null) {
this.input.getStack(1).decrement(1);
this.updateResult();
this.context.run((world, blockPos) -> {
BlockState anvilState = world.getBlockState(blockPos);
if (!player.abilities.creativeMode && anvilState.isIn(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
BlockState landingState = AnvilBlock.getLandingState(anvilState);
if (landingState == null) {
world.removeBlock(blockPos, false);
world.syncWorldEvent(1029, blockPos, 0);
} else {
world.setBlockState(blockPos, landingState, 2);
world.syncWorldEvent(1030, blockPos, 0);
}
} else {
world.syncWorldEvent(1030, blockPos, 0);
}
});
info.setReturnValue(stack);
info.cancel();
}
}
@Inject(method = "updateResult", at = @At("HEAD"), cancellable = true)
public void updateOutput(CallbackInfo info) {
this.currentRecipe = this.recipeManager.getFirstMatch(AnvilSmithingRecipe.TYPE, input, world).orElse(null);
if (currentRecipe != null) {
this.output.setStack(0, currentRecipe.craft(input));
this.sendContentUpdates();
info.cancel();
}
}
@Inject(method = "setNewItemName", at = @At("HEAD"), cancellable = true)
public void setNewItemName(String string, CallbackInfo info) {
if (currentRecipe != null) {
info.cancel();
}
}
}

View file

@ -1,16 +1,16 @@
package ru.betterend.mixin.common;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.item.Item;
import net.minecraft.potion.Potion;
import net.minecraft.recipe.BrewingRecipeRegistry;
@Mixin(BrewingRecipeRegistry.class)
public interface BrewingAccessor {
@Invoker
static void callRegisterPotionRecipe(Potion input, Item item, Potion output) {
throw new AssertionError("@Invoker dummy body called");
}
}
package ru.betterend.mixin.common;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.item.Item;
import net.minecraft.potion.Potion;
import net.minecraft.recipe.BrewingRecipeRegistry;
@Mixin(BrewingRecipeRegistry.class)
public interface BrewingAccessor {
@Invoker
static void callRegisterPotionRecipe(Potion input, Item item, Potion output) {
throw new AssertionError("@Invoker dummy body called");
}
}

View file

@ -1,26 +1,26 @@
package ru.betterend.mixin.common;
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 net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.mob.EndermanEntity;
import net.minecraft.entity.player.PlayerEntity;
import ru.betterend.effects.EndEnchantments;
import ru.betterend.effects.EndStatusEffects;
@Mixin(EndermanEntity.class)
public abstract class EndermanEntityMixin {
@Inject(method = "isPlayerStaring", at = @At("HEAD"), cancellable = true)
private void isPlayerStaring(PlayerEntity player, CallbackInfoReturnable<Boolean> info) {
if (player.isCreative() || player.hasStatusEffect(EndStatusEffects.END_VEIL) ||
EnchantmentHelper.getLevel(EndEnchantments.END_VEIL, player.getEquippedStack(EquipmentSlot.HEAD)) > 0) {
info.setReturnValue(false);
info.cancel();
}
}
}
package ru.betterend.mixin.common;
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 net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.mob.EndermanEntity;
import net.minecraft.entity.player.PlayerEntity;
import ru.betterend.effects.EndEnchantments;
import ru.betterend.effects.EndStatusEffects;
@Mixin(EndermanEntity.class)
public abstract class EndermanEntityMixin {
@Inject(method = "isPlayerStaring", at = @At("HEAD"), cancellable = true)
private void isPlayerStaring(PlayerEntity player, CallbackInfoReturnable<Boolean> info) {
if (player.isCreative() || player.hasStatusEffect(EndStatusEffects.END_VEIL) ||
EnchantmentHelper.getLevel(EndEnchantments.END_VEIL, player.getEquippedStack(EquipmentSlot.HEAD)) > 0) {
info.setReturnValue(false);
info.cancel();
}
}
}

View file

@ -1,116 +1,116 @@
package ru.betterend.mixin.common;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.TeleportTarget;
import net.minecraft.world.World;
import ru.betterend.interfaces.TeleportingEntity;
@Mixin(Entity.class)
public abstract class EntityMixin implements TeleportingEntity {
private BlockPos beExitPos;
private long beCooldown;
@Shadow
public float yaw;
@Shadow
public float pitch;
@Shadow
public boolean removed;
@Shadow
public World world;
@Final
@Shadow
public abstract void detach();
@Shadow
public abstract Vec3d getVelocity();
@Shadow
public abstract EntityType<?> getType();
@Shadow
public abstract void copyFrom(Entity original);
@Shadow
public abstract Entity moveToWorld(ServerWorld destination);
@Shadow
protected abstract TeleportTarget getTeleportTarget(ServerWorld destination);
@Inject(method = "moveToWorld", at = @At("HEAD"), cancellable = true)
public void moveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity> info) {
if (!removed && beExitPos != null && world instanceof ServerWorld) {
this.detach();
this.world.getProfiler().push("changeDimension");
this.world.getProfiler().push("reposition");
TeleportTarget teleportTarget = this.getTeleportTarget(destination);
if (teleportTarget != null) {
this.world.getProfiler().swap("reloading");
Entity entity = this.getType().create(destination);
if (entity != null) {
entity.copyFrom(Entity.class.cast(this));
entity.refreshPositionAndAngles(teleportTarget.position.x, teleportTarget.position.y, teleportTarget.position.z, teleportTarget.yaw, entity.pitch);
entity.setVelocity(teleportTarget.velocity);
destination.onDimensionChanged(entity);
}
this.removed = true;
this.world.getProfiler().pop();
((ServerWorld) this.world).resetIdleTimeout();
destination.resetIdleTimeout();
this.world.getProfiler().pop();
this.beExitPos = null;
info.setReturnValue(entity);
info.cancel();
}
}
}
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
protected void getTeleportTarget(ServerWorld destination, CallbackInfoReturnable<TeleportTarget> info) {
if (beExitPos != null) {
info.setReturnValue(new TeleportTarget(new Vec3d(beExitPos.getX() + 0.5D, beExitPos.getY(), beExitPos.getZ() + 0.5D), getVelocity(), yaw, pitch));
info.cancel();
}
}
@Inject(method = "baseTick", at = @At("TAIL"))
public void baseTick(CallbackInfo info) {
if (hasCooldown()) {
this.beCooldown--;
}
}
@Override
public long beGetCooldown() {
return this.beCooldown;
}
@Override
public void beSetCooldown(long time) {
this.beCooldown = time;
}
@Override
public void beSetExitPos(BlockPos pos) {
this.beExitPos = pos;
}
@Override
public BlockPos beGetExitPos() {
return this.beExitPos;
}
}
package ru.betterend.mixin.common;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.TeleportTarget;
import net.minecraft.world.World;
import ru.betterend.interfaces.TeleportingEntity;
@Mixin(Entity.class)
public abstract class EntityMixin implements TeleportingEntity {
private BlockPos beExitPos;
private long beCooldown;
@Shadow
public float yaw;
@Shadow
public float pitch;
@Shadow
public boolean removed;
@Shadow
public World world;
@Final
@Shadow
public abstract void detach();
@Shadow
public abstract Vec3d getVelocity();
@Shadow
public abstract EntityType<?> getType();
@Shadow
public abstract void copyFrom(Entity original);
@Shadow
public abstract Entity moveToWorld(ServerWorld destination);
@Shadow
protected abstract TeleportTarget getTeleportTarget(ServerWorld destination);
@Inject(method = "moveToWorld", at = @At("HEAD"), cancellable = true)
public void moveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity> info) {
if (!removed && beExitPos != null && world instanceof ServerWorld) {
this.detach();
this.world.getProfiler().push("changeDimension");
this.world.getProfiler().push("reposition");
TeleportTarget teleportTarget = this.getTeleportTarget(destination);
if (teleportTarget != null) {
this.world.getProfiler().swap("reloading");
Entity entity = this.getType().create(destination);
if (entity != null) {
entity.copyFrom(Entity.class.cast(this));
entity.refreshPositionAndAngles(teleportTarget.position.x, teleportTarget.position.y, teleportTarget.position.z, teleportTarget.yaw, entity.pitch);
entity.setVelocity(teleportTarget.velocity);
destination.onDimensionChanged(entity);
}
this.removed = true;
this.world.getProfiler().pop();
((ServerWorld) this.world).resetIdleTimeout();
destination.resetIdleTimeout();
this.world.getProfiler().pop();
this.beExitPos = null;
info.setReturnValue(entity);
info.cancel();
}
}
}
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
protected void getTeleportTarget(ServerWorld destination, CallbackInfoReturnable<TeleportTarget> info) {
if (beExitPos != null) {
info.setReturnValue(new TeleportTarget(new Vec3d(beExitPos.getX() + 0.5D, beExitPos.getY(), beExitPos.getZ() + 0.5D), getVelocity(), yaw, pitch));
info.cancel();
}
}
@Inject(method = "baseTick", at = @At("TAIL"))
public void baseTick(CallbackInfo info) {
if (hasCooldown()) {
this.beCooldown--;
}
}
@Override
public long beGetCooldown() {
return this.beCooldown;
}
@Override
public void beSetCooldown(long time) {
this.beCooldown = time;
}
@Override
public void beSetExitPos(BlockPos pos) {
this.beExitPos = pos;
}
@Override
public BlockPos beGetExitPos() {
return this.beExitPos;
}
}

View file

@ -1,46 +1,46 @@
package ru.betterend.mixin.common;
import java.util.Arrays;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.recipe.Ingredient;
import ru.betterend.interfaces.CompoundSerializer;
@Mixin(Ingredient.class)
public abstract class IngredientMixin implements CompoundSerializer<Ingredient> {
@Shadow
private ItemStack[] matchingStacks;
@Shadow
protected abstract void cacheMatchingStacks();
@Override
public CompoundTag toTag(CompoundTag tag) {
this.cacheMatchingStacks();
int i = 0;
tag.putInt("length", matchingStacks.length);
for (ItemStack stack : matchingStacks) {
String key = Integer.toString(i);
tag.put(key, stack.toTag(new CompoundTag()));
i++;
}
return tag;
}
@Override
public Ingredient fromTag(CompoundTag tag) {
int length = tag.getInt("length");
ItemStack[] stacks = new ItemStack[length];
for (int i = 0; i < length; i++) {
String key = Integer.toString(i);
stacks[i] = ItemStack.fromTag(tag.getCompound(key));
}
return Ingredient.ofStacks(Arrays.stream(stacks));
}
}
package ru.betterend.mixin.common;
import java.util.Arrays;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.recipe.Ingredient;
import ru.betterend.interfaces.CompoundSerializer;
@Mixin(Ingredient.class)
public abstract class IngredientMixin implements CompoundSerializer<Ingredient> {
@Shadow
private ItemStack[] matchingStacks;
@Shadow
protected abstract void cacheMatchingStacks();
@Override
public CompoundTag toTag(CompoundTag tag) {
this.cacheMatchingStacks();
int i = 0;
tag.putInt("length", matchingStacks.length);
for (ItemStack stack : matchingStacks) {
String key = Integer.toString(i);
tag.put(key, stack.toTag(new CompoundTag()));
i++;
}
return tag;
}
@Override
public Ingredient fromTag(CompoundTag tag) {
int length = tag.getInt("length");
ItemStack[] stacks = new ItemStack[length];
for (int i = 0; i < length; i++) {
String key = Integer.toString(i);
stacks[i] = ItemStack.fromTag(tag.getCompound(key));
}
return Ingredient.ofStacks(Arrays.stream(stacks));
}
}

View file

@ -1,47 +1,47 @@
package ru.betterend.mixin.common;
import java.util.Collection;
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.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.item.Item;
@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {
private Entity lastAttacker;
@Inject(method = "damage", at = @At("HEAD"))
public void damage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> info) {
this.lastAttacker = source.getAttacker();
}
@ModifyArg(method = "damage", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;takeKnockback(FDD)V"))
private float increaseKnockback(float value, double x, double z) {
if (lastAttacker != null && lastAttacker instanceof LivingEntity) {
LivingEntity attacker = (LivingEntity) lastAttacker;
value += this.getKnockback(attacker.getMainHandStack().getItem());
}
return value;
}
private double getKnockback(Item tool) {
if (tool == null) return 0.0D;
Collection<EntityAttributeModifier> modifiers = tool.getAttributeModifiers(EquipmentSlot.MAINHAND)
.get(EntityAttributes.GENERIC_ATTACK_KNOCKBACK);
if (modifiers.size() > 0) {
return modifiers.iterator().next().getValue();
}
return 0.0D;
}
}
package ru.betterend.mixin.common;
import java.util.Collection;
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.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.item.Item;
@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {
private Entity lastAttacker;
@Inject(method = "damage", at = @At("HEAD"))
public void damage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> info) {
this.lastAttacker = source.getAttacker();
}
@ModifyArg(method = "damage", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;takeKnockback(FDD)V"))
private float increaseKnockback(float value, double x, double z) {
if (lastAttacker != null && lastAttacker instanceof LivingEntity) {
LivingEntity attacker = (LivingEntity) lastAttacker;
value += this.getKnockback(attacker.getMainHandStack().getItem());
}
return value;
}
private double getKnockback(Item tool) {
if (tool == null) return 0.0D;
Collection<EntityAttributeModifier> modifiers = tool.getAttributeModifiers(EquipmentSlot.MAINHAND)
.get(EntityAttributes.GENERIC_ATTACK_KNOCKBACK);
if (modifiers.size() > 0) {
return modifiers.iterator().next().getValue();
}
return 0.0D;
}
}

View file

@ -1,41 +1,41 @@
package ru.betterend.mixin.common;
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.CallbackInfo;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import ru.betterend.interfaces.TeleportingEntity;
@Mixin(ServerPlayerEntity.class)
public abstract class ServerPlayerEntityMixin implements TeleportingEntity {
private long beCooldown;
@Inject(method = "tick", at = @At("TAIL"))
public void baseTick(CallbackInfo info) {
if (hasCooldown()) {
this.beCooldown--;
}
}
@Override
public long beGetCooldown() {
return this.beCooldown;
}
@Override
public void beSetCooldown(long time) {
this.beCooldown = time;
}
@Override
public void beSetExitPos(BlockPos pos) {}
@Override
public BlockPos beGetExitPos() {
return null;
}
}
package ru.betterend.mixin.common;
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.CallbackInfo;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import ru.betterend.interfaces.TeleportingEntity;
@Mixin(ServerPlayerEntity.class)
public abstract class ServerPlayerEntityMixin implements TeleportingEntity {
private long beCooldown;
@Inject(method = "tick", at = @At("TAIL"))
public void baseTick(CallbackInfo info) {
if (hasCooldown()) {
this.beCooldown--;
}
}
@Override
public long beGetCooldown() {
return this.beCooldown;
}
@Override
public void beSetCooldown(long time) {
this.beCooldown = time;
}
@Override
public void beSetExitPos(BlockPos pos) {}
@Override
public BlockPos beGetExitPos() {
return null;
}
}