Continue mapping migration
This commit is contained in:
parent
99ade39404
commit
f03fd03bd0
499 changed files with 12567 additions and 12723 deletions
|
@ -1,10 +1,9 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import net.minecraft.client.resources.sounds.AbstractSoundInstance;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.sound.AbstractSoundInstance;
|
||||
|
||||
@Mixin(AbstractSoundInstance.class)
|
||||
public interface AbstractSoundInstanceAccessor {
|
||||
@Accessor("volume")
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.screens.inventory.AnvilScreen;
|
||||
import net.minecraft.client.gui.screens.inventory.ItemCombinerScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.AnvilMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -9,32 +20,19 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.ForgingScreen;
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.screen.AnvilScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import ru.betterend.interfaces.AnvilScreenHandlerExtended;
|
||||
|
||||
@Mixin(AnvilScreen.class)
|
||||
public class AnvilScreenMixin extends ForgingScreen<AnvilScreenHandler> {
|
||||
public class AnvilScreenMixin extends ItemCombinerScreen<AnvilMenu> {
|
||||
|
||||
@Shadow
|
||||
private TextFieldWidget nameField;
|
||||
|
||||
private final List<AbstractButtonWidget> be_buttons = Lists.newArrayList();
|
||||
private EditBox nameField;
|
||||
|
||||
private final List<AbstractWidget> be_buttons = Lists.newArrayList();
|
||||
private AnvilScreenHandlerExtended anvilHandler;
|
||||
|
||||
public AnvilScreenMixin(AnvilScreenHandler handler, PlayerInventory playerInventory, Text title,
|
||||
|
||||
public AnvilScreenMixin(AnvilMenu handler, Inventory playerInventory, Component title,
|
||||
ResourceLocation texture) {
|
||||
super(handler, playerInventory, title, texture);
|
||||
}
|
||||
|
@ -42,22 +40,22 @@ public class AnvilScreenMixin extends ForgingScreen<AnvilScreenHandler> {
|
|||
@Inject(method = "setup", at = @At("TAIL"))
|
||||
protected void be_setup(CallbackInfo info) {
|
||||
this.be_buttons.clear();
|
||||
int x = (width - backgroundWidth) / 2;
|
||||
int y = (height - backgroundHeight) / 2;
|
||||
this.anvilHandler = (AnvilScreenHandlerExtended) this.handler;
|
||||
this.be_buttons.add(new ButtonWidget(x + 8, y + 45, 15, 20, new LiteralText("<"), (b) -> be_previousRecipe()));
|
||||
this.be_buttons.add(new ButtonWidget(x + 154, y + 45, 15, 20, new LiteralText(">"), (b) -> be_nextRecipe()));
|
||||
int x = (width - imageWidth) / 2;
|
||||
int y = (height - imageHeight) / 2;
|
||||
this.anvilHandler = (AnvilScreenHandlerExtended) this.menu;
|
||||
this.be_buttons.add(new Button(x + 8, y + 45, 15, 20, new TextComponent("<"), (b) -> be_previousRecipe()));
|
||||
this.be_buttons.add(new Button(x + 154, y + 45, 15, 20, new TextComponent(">"), (b) -> be_nextRecipe()));
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "renderForeground", at = @At("TAIL"))
|
||||
protected void be_renderForeground(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo info) {
|
||||
protected void be_renderForeground(PoseStack matrices, int mouseX, int mouseY, float delta, CallbackInfo info) {
|
||||
this.be_buttons.forEach(button -> {
|
||||
button.render(matrices, mouseX, mouseY, delta);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "onSlotUpdate", at = @At("HEAD"), cancellable = true)
|
||||
public void be_onSlotUpdate(ScreenHandler handler, int slotId, ItemStack stack, CallbackInfo info) {
|
||||
public void be_onSlotUpdate(AbstractContainerMenu handler, int slotId, ItemStack stack, CallbackInfo info) {
|
||||
AnvilScreenHandlerExtended anvilHandler = (AnvilScreenHandlerExtended) handler;
|
||||
if (anvilHandler.be_getCurrentRecipe() != null) {
|
||||
if (anvilHandler.be_getRecipes().size() > 1) {
|
||||
|
@ -65,29 +63,29 @@ public class AnvilScreenMixin extends ForgingScreen<AnvilScreenHandler> {
|
|||
} else {
|
||||
this.be_buttons.forEach(button -> button.visible = false);
|
||||
}
|
||||
this.nameField.setText("");
|
||||
this.nameField.setValue("");
|
||||
info.cancel();
|
||||
} else {
|
||||
this.be_buttons.forEach(button -> button.visible = false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void be_nextRecipe() {
|
||||
this.anvilHandler.be_nextRecipe();
|
||||
}
|
||||
|
||||
|
||||
private void be_previousRecipe() {
|
||||
this.anvilHandler.be_previousRecipe();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (client != null) {
|
||||
for (AbstractButtonWidget elem : be_buttons) {
|
||||
if (minecraft != null) {
|
||||
for (AbstractWidget elem : be_buttons) {
|
||||
if (elem.visible && elem.mouseClicked(mouseX, mouseY, button)) {
|
||||
if (client.interactionManager != null) {
|
||||
if (minecraft.gameMode != null) {
|
||||
int i = be_buttons.indexOf(elem);
|
||||
this.client.interactionManager.clickButton(handler.syncId, i);
|
||||
this.minecraft.gameMode.handleInventoryButtonClick(menu.containerId, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,54 +8,51 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.render.BackgroundRenderer;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biome.Category;
|
||||
import net.minecraft.world.level.biome.Biome.BiomeCategory;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import ru.betterend.client.ClientOptions;
|
||||
import ru.betterend.registry.EndBiomes;
|
||||
import ru.betterend.util.BackgroundInfo;
|
||||
import ru.betterend.world.biome.EndBiome;
|
||||
|
||||
@Mixin(BackgroundRenderer.class)
|
||||
@Mixin(FogRenderer.class)
|
||||
public class BackgroundRendererMixin {
|
||||
private static float lastFogDensity;
|
||||
private static float fogDensity;
|
||||
private static float lerp;
|
||||
private static long time;
|
||||
|
||||
|
||||
@Shadow
|
||||
private static float red;
|
||||
@Shadow
|
||||
private static float green;
|
||||
@Shadow
|
||||
private static float blue;
|
||||
|
||||
|
||||
@Inject(method = "render", at = @At("RETURN"))
|
||||
private static void be_onRender(Camera camera, float tickDelta, ClientLevel world, int i, float f,
|
||||
CallbackInfo info) {
|
||||
long l = Util.getMeasuringTimeMs() - time;
|
||||
private static void be_onRender(Camera camera, float tickDelta, ClientLevel world, int i, float f, CallbackInfo info) {
|
||||
long l = Util.getMillis() - time;
|
||||
time += l;
|
||||
lerp += l * 0.001F;
|
||||
if (lerp > 1)
|
||||
lerp = 1;
|
||||
|
||||
FluidState fluidState = camera.getSubmergedFluidState();
|
||||
if (lerp > 1) lerp = 1;
|
||||
|
||||
FluidState fluidState = camera.getFluidInCamera();
|
||||
if (fluidState.isEmpty() && world.dimension().equals(Level.END)) {
|
||||
Entity entity = camera.getFocusedEntity();
|
||||
Entity entity = camera.getEntity();
|
||||
boolean skip = false;
|
||||
if (entity instanceof LivingEntity) {
|
||||
MobEffectInstance effect = ((LivingEntity) entity).getMobEffect(MobEffects.NIGHT_VISION);
|
||||
MobEffectInstance effect = ((LivingEntity) entity).getEffect(MobEffects.NIGHT_VISION);
|
||||
skip = effect != null && effect.getDuration() > 0;
|
||||
}
|
||||
if (!skip) {
|
||||
|
@ -64,21 +61,20 @@ public class BackgroundRendererMixin {
|
|||
blue *= 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BackgroundInfo.red = red;
|
||||
BackgroundInfo.green = green;
|
||||
BackgroundInfo.blue = blue;
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "applyFog", at = @At("HEAD"), cancellable = true)
|
||||
private static void be_fogDensity(Camera camera, BackgroundRenderer.FogType fogType, float viewDistance,
|
||||
boolean thickFog, CallbackInfo info) {
|
||||
Entity entity = camera.getFocusedEntity();
|
||||
Biome biome = entity.world.getBiome(entity.getBlockPos());
|
||||
FluidState fluidState = camera.getSubmergedFluidState();
|
||||
if (ClientOptions.useFogDensity() && biome.getCategory() == Category.THEEND && fluidState.isEmpty()) {
|
||||
private static void be_fogDensity(Camera camera, FogRenderer.FogMode fogType, float viewDistance, boolean thickFog, CallbackInfo info) {
|
||||
Entity entity = camera.getEntity();
|
||||
Biome biome = entity.level.getBiome(entity.blockPosition());
|
||||
FluidState fluidState = camera.getFluidInCamera();
|
||||
if (ClientOptions.useFogDensity() && biome.getBiomeCategory() == BiomeCategory.THEEND && fluidState.isEmpty()) {
|
||||
EndBiome endBiome = EndBiomes.getRenderBiome(biome);
|
||||
|
||||
|
||||
if (fogDensity == 0) {
|
||||
fogDensity = endBiome.getFogDensity();
|
||||
lastFogDensity = fogDensity;
|
||||
|
@ -88,32 +84,34 @@ public class BackgroundRendererMixin {
|
|||
fogDensity = endBiome.getFogDensity();
|
||||
lerp = 0;
|
||||
}
|
||||
|
||||
|
||||
float fog = Mth.lerp(lerp, lastFogDensity, fogDensity);
|
||||
BackgroundInfo.fog = fog;
|
||||
float start = viewDistance * 0.75F / fog;
|
||||
float end = viewDistance / fog;
|
||||
|
||||
|
||||
if (entity instanceof LivingEntity) {
|
||||
LivingEntity le = (LivingEntity) entity;
|
||||
MobEffectInstance effect = le.getMobEffect(MobEffects.BLINDNESS);
|
||||
MobEffectInstance effect = le.getEffect(MobEffects.BLINDNESS);
|
||||
if (effect != null) {
|
||||
int duration = effect.getDuration();
|
||||
if (duration > 20) {
|
||||
start = 0;
|
||||
end *= 0.03F;
|
||||
BackgroundInfo.blindness = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
float delta = (float) duration / 20F;
|
||||
BackgroundInfo.blindness = delta;
|
||||
start = Mth.lerp(delta, start, 0);
|
||||
end = Mth.lerp(delta, end, end * 0.03F);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
BackgroundInfo.blindness = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RenderSystem.fogStart(start);
|
||||
RenderSystem.fogEnd(end);
|
||||
RenderSystem.fogMode(GlStateManager.FogMode.LINEAR);
|
||||
|
|
|
@ -9,11 +9,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.color.world.BiomeColors;
|
||||
import net.minecraft.client.renderer.BiomeColors;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import ru.betterend.client.ClientOptions;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
|
@ -25,11 +25,11 @@ public class BiomeColorsMixin {
|
|||
private static final int STREAM_COLOR = MHelper.color(105, 213, 244);
|
||||
private static final Point[] OFFSETS;
|
||||
private static final boolean HAS_SODIUM;
|
||||
|
||||
|
||||
@Inject(method = "getWaterColor", at = @At("RETURN"), cancellable = true)
|
||||
private static void be_getWaterColor(BlockRenderView world, BlockPos pos, CallbackInfoReturnable<Integer> info) {
|
||||
private static void be_getWaterColor(BlockAndTintGetter world, BlockPos pos, CallbackInfoReturnable<Integer> info) {
|
||||
if (ClientOptions.useSulfurWaterColor()) {
|
||||
BlockRenderView view = HAS_SODIUM ? Minecraft.getInstance().world : world;
|
||||
BlockAndTintGetter view = HAS_SODIUM ? Minecraft.getInstance().level : world;
|
||||
MutableBlockPos mut = new MutableBlockPos();
|
||||
mut.setY(pos.getY());
|
||||
for (int i = 0; i < OFFSETS.length; i++) {
|
||||
|
@ -43,10 +43,10 @@ public class BiomeColorsMixin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
HAS_SODIUM = FabricLoader.getInstance().isModLoaded("sodium");
|
||||
|
||||
|
||||
OFFSETS = new Point[20];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
int p = i - 1;
|
||||
|
@ -55,13 +55,13 @@ public class BiomeColorsMixin {
|
|||
OFFSETS[i + 6] = new Point(-2, p);
|
||||
OFFSETS[i + 9] = new Point(2, p);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int inner = i + 16;
|
||||
Direction dir = BlocksHelper.HORIZONTAL[i];
|
||||
OFFSETS[inner] = new Point(dir.getOffsetX(), dir.getOffsetZ());
|
||||
OFFSETS[inner] = new Point(dir.getStepX(), dir.getStepZ());
|
||||
dir = BlocksHelper.HORIZONTAL[(i + 1) & 3];
|
||||
OFFSETS[i + 12] = new Point(OFFSETS[inner].x + dir.getOffsetX(), OFFSETS[inner].y + dir.getOffsetZ());
|
||||
OFFSETS[i + 12] = new Point(OFFSETS[inner].x + dir.getStepX(), OFFSETS[inner].y + dir.getStepZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.network.protocol.PacketUtils;
|
||||
import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
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 net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.network.NetworkThreadUtils;
|
||||
import net.minecraft.network.packet.s2c.play.SignEditorOpenS2CPacket;
|
||||
import ru.betterend.blocks.entities.ESignBlockEntity;
|
||||
import ru.betterend.client.gui.BlockSignEditScreen;
|
||||
|
||||
@Mixin(ClientPlayNetworkHandler.class)
|
||||
public class ClientPlayNetworkHandlerMixin {
|
||||
@Mixin(ClientPacketListener.class)
|
||||
public class ClientPlayNetworkHandlerMixin
|
||||
{
|
||||
@Shadow
|
||||
private Minecraft client;
|
||||
|
||||
|
@ -24,12 +24,12 @@ public class ClientPlayNetworkHandlerMixin {
|
|||
private ClientLevel world;
|
||||
|
||||
@Inject(method = "onSignEditorOpen", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void be_openSignEditor(SignEditorOpenS2CPacket packet, CallbackInfo info) {
|
||||
NetworkThreadUtils.forceMainThread(packet, ClientPlayNetworkHandler.class.cast(this), client);
|
||||
public void be_openSignEditor(ClientboundOpenSignEditorPacket packet, CallbackInfo info) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, ClientPacketListener.class.cast(this), client);
|
||||
BlockEntity blockEntity = world.getBlockEntity(packet.getPos());
|
||||
if (blockEntity instanceof ESignBlockEntity) {
|
||||
ESignBlockEntity sign = (ESignBlockEntity) blockEntity;
|
||||
client.openScreen(new BlockSignEditScreen(sign));
|
||||
client.setScreen(new BlockSignEditScreen(sign));
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import net.minecraft.client.ClientRecipeBook;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
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.world.item.crafting.Recipe;
|
||||
import ru.betterend.interfaces.BetterEndRecipe;
|
||||
import ru.betterend.recipe.builders.AlloyingRecipe;
|
||||
|
||||
@Mixin(ClientRecipeBook.class)
|
||||
public abstract class ClientRecipeBookMixin {
|
||||
@Inject(method = "getGroupForRecipe", at = @At("HEAD"), cancellable = true)
|
||||
private static void be_getGroupForRecipe(Recipe<?> recipe, CallbackInfoReturnable<RecipeBookGroup> cinfo) {
|
||||
private static void be_getGroupForRecipe(Recipe<?> recipe, CallbackInfoReturnable<RecipeBookCategories> cinfo) {
|
||||
if (recipe instanceof AlloyingRecipe) {
|
||||
cinfo.setReturnValue(RecipeBookGroup.BLAST_FURNACE_MISC);
|
||||
cinfo.setReturnValue(RecipeBookCategories.BLAST_FURNACE_MISC);
|
||||
} else if (recipe instanceof BetterEndRecipe) {
|
||||
cinfo.setReturnValue(RecipeBookGroup.UNKNOWN);
|
||||
cinfo.setReturnValue(RecipeBookCategories.UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,9 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import net.minecraft.client.renderer.block.model.BlockModelDefinition;
|
||||
|
||||
import net.minecraft.client.render.model.json.ModelVariantMap;
|
||||
|
||||
@Mixin(ModelVariantMap.DeserializationContext.class)
|
||||
@Mixin(BlockModelDefinition.Context.class)
|
||||
public interface ContextGsonAccessor {
|
||||
@Accessor
|
||||
public Gson getGson();
|
||||
|
|
|
@ -1,27 +1,25 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EnchantmentTableBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
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.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.EnchantingTableBlock;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import ru.betterend.registry.EndTags;
|
||||
|
||||
@Mixin(EnchantingTableBlock.class)
|
||||
@Mixin(EnchantmentTableBlock.class)
|
||||
public abstract class EnchantingTableBlockMixin extends Block {
|
||||
public EnchantingTableBlockMixin(Properties settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Inject(method = "animateTick", at = @At(value = "TAIL"))
|
||||
@Inject(method = "randomDisplayTick", at = @At(value = "TAIL"))
|
||||
private void be_onRandomDisplayTick(BlockState state, Level world, BlockPos pos, Random random, CallbackInfo info) {
|
||||
for (int px = -2; px <= 2; ++px) {
|
||||
for (int pz = -2; pz <= 2; ++pz) {
|
||||
|
@ -31,13 +29,11 @@ public abstract class EnchantingTableBlockMixin extends Block {
|
|||
if (random.nextInt(16) == 0) {
|
||||
for (int py = 0; py <= 1; ++py) {
|
||||
BlockPos blockPos = pos.offset(px, py, pz);
|
||||
if (world.getBlockState(blockPos).isIn(EndTags.BOOKSHELVES)) {
|
||||
if (!world.isAir(pos.offset(px / 2, 0, pz / 2))) {
|
||||
if (world.getBlockState(blockPos).is(EndTags.BOOKSHELVES)) {
|
||||
if (!world.isEmptyBlock(pos.offset(px / 2, 0, pz / 2))) {
|
||||
break;
|
||||
}
|
||||
world.addParticle(ParticleTypes.ENCHANT, pos.getX() + 0.5, pos.getY() + 2.0,
|
||||
pos.getZ() + 0.5, px + random.nextFloat() - 0.5, py - random.nextFloat() - 1.0,
|
||||
pz + random.nextFloat() - 0.5);
|
||||
world.addParticle(ParticleTypes.ENCHANT, pos.getX() + 0.5, pos.getY() + 2.0, pos.getZ() + 0.5, px + random.nextFloat() - 0.5, py - random.nextFloat() - 1.0, pz + random.nextFloat() - 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,19 +7,18 @@ 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.client.Minecraft;
|
||||
import net.minecraft.client.RunArgs;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.color.item.ItemColors;
|
||||
import net.minecraft.client.gui.hud.InGameHud;
|
||||
import net.minecraft.client.gui.screen.CreditsScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.sound.MusicType;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.WinScreen;
|
||||
import net.minecraft.client.main.GameConfig;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.sound.MusicSound;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.sounds.Music;
|
||||
import net.minecraft.sounds.Musics;
|
||||
import net.minecraft.world.level.Level;
|
||||
import ru.betterend.interfaces.IColorProvider;
|
||||
import ru.betterend.util.MHelper;
|
||||
|
@ -27,18 +26,18 @@ import ru.betterend.util.MHelper;
|
|||
@Mixin(Minecraft.class)
|
||||
public class MinecraftClientMixin {
|
||||
@Shadow
|
||||
public ClientPlayerEntity player;
|
||||
|
||||
public LocalPlayer player;
|
||||
|
||||
@Shadow
|
||||
public Screen currentScreen;
|
||||
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
public InGameHud inGameHud;
|
||||
|
||||
public Gui inGameHud;
|
||||
|
||||
@Shadow
|
||||
public ClientLevel world;
|
||||
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private BlockColors blockColors;
|
||||
|
@ -46,28 +45,27 @@ public class MinecraftClientMixin {
|
|||
@Shadow
|
||||
@Final
|
||||
private ItemColors itemColors;
|
||||
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void be_onInit(RunArgs args, CallbackInfo info) {
|
||||
private void be_onInit(GameConfig args, CallbackInfo info) {
|
||||
Registry.BLOCK.forEach(block -> {
|
||||
if (block instanceof IColorProvider) {
|
||||
IColorProvider provider = (IColorProvider) block;
|
||||
blockColors.registerColorProvider(provider.getBlockProvider(), block);
|
||||
blockColors.register(provider.getProvider(), block);
|
||||
itemColors.register(provider.getItemProvider(), block.asItem());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "getMusicType", at = @At("HEAD"), cancellable = true)
|
||||
private void be_getEndMusic(CallbackInfoReturnable<MusicSound> info) {
|
||||
if (!(this.currentScreen instanceof CreditsScreen) && this.player != null) {
|
||||
if (this.player.world.dimension() == Level.END) {
|
||||
if (this.inGameHud.getBossBarHud().shouldPlayDragonMusic()
|
||||
&& MHelper.lengthSqr(this.player.getX(), this.player.getZ()) < 250000) {
|
||||
info.setReturnValue(MusicType.DRAGON);
|
||||
} else {
|
||||
MusicSound sound = (MusicSound) this.world.getBiomeAccess().method_27344(this.player.getBlockPos())
|
||||
.getMusic().orElse(MusicType.END);
|
||||
private void be_getEndMusic(CallbackInfoReturnable<Music> info) {
|
||||
if (!(this.currentScreen instanceof WinScreen) && this.player != null) {
|
||||
if (this.player.level.dimension() == Level.END) {
|
||||
if (this.inGameHud.getBossOverlay().shouldPlayMusic() && MHelper.lengthSqr(this.player.getX(), this.player.getZ()) < 250000) {
|
||||
info.setReturnValue(Musics.END_BOSS);
|
||||
}
|
||||
else {
|
||||
Music sound = (Music) this.world.getBiomeManager().getNoiseBiomeAtPosition(this.player.blockPosition()).getBackgroundMusic().orElse(Musics.END);
|
||||
info.setReturnValue(sound);
|
||||
}
|
||||
info.cancel();
|
||||
|
|
|
@ -4,7 +4,14 @@ import java.io.InputStreamReader;
|
|||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -12,40 +19,31 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.client.render.model.ModelLoader;
|
||||
import net.minecraft.client.render.model.json.JsonUnbakedModel;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.core.Registry;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.patterns.Patterned;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
@Mixin(ModelLoader.class)
|
||||
@Mixin(ModelBakery.class)
|
||||
public class ModelLoaderMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private ResourceManager resourceManager;
|
||||
|
||||
|
||||
@Inject(method = "loadModelFromJson", at = @At("HEAD"), cancellable = true)
|
||||
private void be_loadModelPattern(ResourceLocation id, CallbackInfoReturnable<JsonUnbakedModel> info) {
|
||||
private void be_loadModelPattern(ResourceLocation id, CallbackInfoReturnable<BlockModel> info) {
|
||||
if (id.getNamespace().equals(BetterEnd.MOD_ID)) {
|
||||
ResourceLocation modelId = new ResourceLocation(id.getNamespace(), "models/" + id.getPath() + ".json");
|
||||
JsonUnbakedModel model;
|
||||
BlockModel model;
|
||||
try (Resource resource = this.resourceManager.getResource(modelId)) {
|
||||
Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8);
|
||||
model = JsonUnbakedModel.deserialize(reader);
|
||||
model.id = id.toString();
|
||||
model = BlockModel.fromStream(reader);
|
||||
model.name = id.toString();
|
||||
info.setReturnValue(model);
|
||||
} catch (Exception ex) {
|
||||
String data[] = id.getPath().split("/");
|
||||
if (data.length > 1) {
|
||||
ResourceLocation itemId = new ResourceLocation(id.getNamespace(), data[1]);
|
||||
Optional<Block> block = Registry.BLOCK.getOrEmpty(itemId);
|
||||
Optional<Block> block = Registry.BLOCK.getOptional(itemId);
|
||||
if (block.isPresent()) {
|
||||
if (block.get() instanceof Patterned) {
|
||||
Patterned patterned = (Patterned) block.get();
|
||||
|
@ -53,7 +51,7 @@ public class ModelLoaderMixin {
|
|||
info.setReturnValue(model);
|
||||
}
|
||||
} else {
|
||||
Optional<Item> item = Registry.ITEM.getOrEmpty(itemId);
|
||||
Optional<Item> item = Registry.ITEM.getOptional(itemId);
|
||||
if (item.isPresent() && item.get() instanceof Patterned) {
|
||||
Patterned patterned = (Patterned) item.get();
|
||||
model = this.be_getModel(data, id, patterned);
|
||||
|
@ -64,8 +62,8 @@ public class ModelLoaderMixin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JsonUnbakedModel be_getModel(String data[], ResourceLocation id, Patterned patterned) {
|
||||
|
||||
private BlockModel be_getModel(String data[], ResourceLocation id, Patterned patterned) {
|
||||
String pattern;
|
||||
if (id.getPath().contains("item")) {
|
||||
pattern = patterned.getModelPattern(id.getPath());
|
||||
|
@ -76,17 +74,15 @@ public class ModelLoaderMixin {
|
|||
pattern = patterned.getModelPattern(data[1]);
|
||||
}
|
||||
}
|
||||
JsonUnbakedModel model = JsonUnbakedModel.deserialize(pattern);
|
||||
model.id = id.toString();
|
||||
|
||||
BlockModel model = BlockModel.fromString(pattern);
|
||||
model.name = id.toString();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
@ModifyVariable(method = "loadModel", ordinal = 2, at = @At(value = "INVOKE"))
|
||||
public ResourceLocation be_SwitchModel(ResourceLocation id) {
|
||||
if (GeneratorOptions.changeChorusPlant() && id.getNamespace().equals("minecraft")
|
||||
&& id.getPath().startsWith("blockstates/") && id.getPath().contains("chorus")
|
||||
&& !id.getPath().contains("custom_")) {
|
||||
if (GeneratorOptions.changeChorusPlant() && id.getNamespace().equals("minecraft") && id.getPath().startsWith("blockstates/") && id.getPath().contains("chorus") && !id.getPath().contains("custom_")) {
|
||||
id = new ResourceLocation(id.getPath().replace("chorus", "custom_chorus"));
|
||||
}
|
||||
return id;
|
||||
|
|
|
@ -2,30 +2,27 @@ package ru.betterend.mixin.client;
|
|||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BlockModelDefinition;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
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.gson.Gson;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.client.render.model.json.ModelVariantMap;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import ru.betterend.patterns.BlockPatterned;
|
||||
|
||||
@Mixin(ModelVariantMap.class)
|
||||
@Mixin(BlockModelDefinition.class)
|
||||
public abstract class ModelVariantMapMixin {
|
||||
|
||||
|
||||
@Inject(method = "deserialize", at = @At("HEAD"), cancellable = true)
|
||||
private static void be_deserializeBlockState(ModelVariantMap.DeserializationContext context, Reader reader,
|
||||
CallbackInfoReturnable<ModelVariantMap> info) {
|
||||
Block block = context.getStateFactory().defaultBlockState().getBlock();
|
||||
private static void be_deserializeBlockState(BlockModelDefinition.Context context, Reader reader, CallbackInfoReturnable<BlockModelDefinition> info) {
|
||||
Block block = context.getDefinition().any().getBlock();
|
||||
if (block instanceof BlockPatterned) {
|
||||
String pattern = ((BlockPatterned) block).getStatesPattern(reader);
|
||||
Gson gson = ContextGsonAccessor.class.cast(context).getGson();
|
||||
ModelVariantMap map = JsonHelper.deserialize(gson, new StringReader(pattern), ModelVariantMap.class);
|
||||
BlockModelDefinition map = GsonHelper.fromJson(gson, new StringReader(pattern), BlockModelDefinition.class);
|
||||
info.setReturnValue(map);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,45 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.sounds.AbstractSoundInstance;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.client.sounds.MusicManager;
|
||||
import net.minecraft.sounds.Music;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.Level;
|
||||
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 net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.sound.AbstractSoundInstance;
|
||||
import net.minecraft.client.sound.MusicTracker;
|
||||
import net.minecraft.client.sound.SoundInstance;
|
||||
import net.minecraft.sound.MusicSound;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.Level;
|
||||
import ru.betterend.client.ClientOptions;
|
||||
|
||||
@Mixin(MusicTracker.class)
|
||||
@Mixin(MusicManager.class)
|
||||
public class MusicTrackerMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private Minecraft client;
|
||||
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Random random;
|
||||
|
||||
|
||||
@Shadow
|
||||
private SoundInstance current;
|
||||
|
||||
|
||||
@Shadow
|
||||
private int timeUntilNextSong;
|
||||
|
||||
|
||||
private static float volume = 1;
|
||||
private static float srcVolume = 0;
|
||||
private static long time;
|
||||
|
||||
|
||||
@Inject(method = "tick", at = @At("HEAD"), cancellable = true)
|
||||
public void be_onTick(CallbackInfo info) {
|
||||
if (ClientOptions.blendBiomeMusic()) {
|
||||
MusicSound musicSound = client.getMusicType();
|
||||
Music musicSound = client.getSituationalMusic();
|
||||
if (be_checkNullSound(musicSound) && volume > 0 && be_isInEnd() && be_shouldChangeSound(musicSound)) {
|
||||
if (volume > 0) {
|
||||
if (srcVolume < 0) {
|
||||
|
@ -50,7 +48,7 @@ public class MusicTrackerMixin {
|
|||
if (current instanceof AbstractSoundInstance) {
|
||||
((AbstractSoundInstanceAccessor) current).setVolume(volume);
|
||||
}
|
||||
client.getSoundManager().updateSoundVolume(current.getCategory(), current.getVolume() * volume);
|
||||
client.getSoundManager().updateSourceVolume(current.getSource(), current.getVolume() * volume);
|
||||
long t = System.currentTimeMillis();
|
||||
if (volume == 1 && time == 0) {
|
||||
time = t;
|
||||
|
@ -74,26 +72,25 @@ public class MusicTrackerMixin {
|
|||
this.play(musicSound);
|
||||
}
|
||||
info.cancel();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
volume = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean be_isInEnd() {
|
||||
return client.world != null && client.world.dimension().equals(Level.END);
|
||||
return client.level != null && client.level.dimension().equals(Level.END);
|
||||
}
|
||||
|
||||
private boolean be_shouldChangeSound(MusicSound musicSound) {
|
||||
return current != null && !musicSound.getSound().getId().equals(this.current.getId())
|
||||
&& musicSound.shouldReplaceCurrentMusic();
|
||||
|
||||
private boolean be_shouldChangeSound(Music musicSound) {
|
||||
return current != null && !musicSound.getEvent().getLocation().equals(this.current.getLocation()) && musicSound.replaceCurrentMusic();
|
||||
}
|
||||
|
||||
private boolean be_checkNullSound(MusicSound musicSound) {
|
||||
return musicSound != null && musicSound.getSound() != null;
|
||||
|
||||
private boolean be_checkNullSound(Music musicSound) {
|
||||
return musicSound != null && musicSound.getEvent() != null;
|
||||
}
|
||||
|
||||
|
||||
@Shadow
|
||||
public void play(MusicSound type) {
|
||||
}
|
||||
public void play(Music type) {}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.FallbackResourceManager;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -10,22 +14,19 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.resource.NamespaceResourceManager;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.core.Registry;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.patterns.BlockPatterned;
|
||||
|
||||
@Mixin(NamespaceResourceManager.class)
|
||||
@Mixin(FallbackResourceManager.class)
|
||||
public abstract class NamespaceResourceManagerMixin {
|
||||
|
||||
|
||||
@Shadow
|
||||
public abstract Resource getResource(ResourceLocation id);
|
||||
|
||||
@Inject(method = "getAllResources", cancellable = true, at = @At(value = "NEW", target = "java/io/FileNotFoundException", shift = Shift.BEFORE))
|
||||
|
||||
@Inject(method = "getAllResources", cancellable = true, at = @At(
|
||||
value = "NEW",
|
||||
target = "java/io/FileNotFoundException",
|
||||
shift = Shift.BEFORE))
|
||||
public void be_getStatesPattern(ResourceLocation id, CallbackInfoReturnable<List<Resource>> info) {
|
||||
if (id.getNamespace().equals(BetterEnd.MOD_ID)) {
|
||||
String[] data = id.getPath().split("/");
|
||||
|
|
|
@ -11,37 +11,36 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexBuffer;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.math.Quaternion;
|
||||
import com.mojang.math.Vector3f;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gl.VertexBuffer;
|
||||
import net.minecraft.client.render.BackgroundRenderer;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.BufferBuilderStorage;
|
||||
import net.minecraft.client.render.SkyProperties;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import net.minecraft.client.texture.TextureManager;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import com.mojang.math.Vector3f;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.DimensionSpecialEffects;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.client.ClientOptions;
|
||||
import ru.betterend.util.BackgroundInfo;
|
||||
import ru.betterend.util.MHelper;
|
||||
|
||||
@Mixin(WorldRenderer.class)
|
||||
@Mixin(LevelRenderer.class)
|
||||
public class WorldRendererMixin {
|
||||
private static final ResourceLocation NEBULA_1 = BetterEnd.makeID("textures/sky/nebula_2.png");
|
||||
private static final ResourceLocation NEBULA_2 = BetterEnd.makeID("textures/sky/nebula_3.png");
|
||||
private static final ResourceLocation HORIZON = BetterEnd.makeID("textures/sky/nebula_1.png");
|
||||
private static final ResourceLocation STARS = BetterEnd.makeID("textures/sky/stars.png");
|
||||
private static final ResourceLocation FOG = BetterEnd.makeID("textures/sky/fog.png");
|
||||
|
||||
|
||||
private static VertexBuffer stars1;
|
||||
private static VertexBuffer stars2;
|
||||
private static VertexBuffer stars3;
|
||||
|
@ -60,23 +59,23 @@ public class WorldRendererMixin {
|
|||
private static float blind02;
|
||||
private static float blind06;
|
||||
private static boolean directOpenGL = false;
|
||||
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Minecraft client;
|
||||
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private TextureManager textureManager;
|
||||
|
||||
|
||||
@Shadow
|
||||
private ClientLevel world;
|
||||
|
||||
|
||||
@Shadow
|
||||
private int ticks;
|
||||
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void be_onInit(Minecraft client, BufferBuilderStorage bufferBuilders, CallbackInfo info) {
|
||||
private void be_onInit(Minecraft client, RenderBuffers bufferBuilders, CallbackInfo info) {
|
||||
be_initStars();
|
||||
Random random = new Random(131);
|
||||
axis1 = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat());
|
||||
|
@ -87,110 +86,107 @@ public class WorldRendererMixin {
|
|||
axis2.normalize();
|
||||
axis3.normalize();
|
||||
axis4.normalize();
|
||||
|
||||
directOpenGL = FabricLoader.getInstance().isModLoaded("optifabric")
|
||||
|| FabricLoader.getInstance().isModLoaded("immersive_portals");
|
||||
|
||||
directOpenGL = FabricLoader.getInstance().isModLoaded("optifabric") || FabricLoader.getInstance().isModLoaded("immersive_portals");
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "renderSky", at = @At("HEAD"), cancellable = true)
|
||||
private void be_renderBetterEndSky(MatrixStack matrices, float tickDelta, CallbackInfo info) {
|
||||
if (ClientOptions.isCustomSky() && client.world.getSkyProperties().getSkyType() == SkyProperties.SkyType.END) {
|
||||
private void be_renderBetterEndSky(PoseStack matrices, float tickDelta, CallbackInfo info) {
|
||||
if (ClientOptions.isCustomSky() && client.level.effects().skyType() == DimensionSpecialEffects.SkyType.END) {
|
||||
time = (ticks % 360000) * 0.000017453292F;
|
||||
time2 = time * 2;
|
||||
time3 = time * 3;
|
||||
|
||||
BackgroundRenderer.setFogBlack();
|
||||
|
||||
FogRenderer.levelFogColor();
|
||||
RenderSystem.enableTexture();
|
||||
|
||||
|
||||
if (directOpenGL) {
|
||||
GL11.glEnable(GL11.GL_ALPHA_TEST);
|
||||
GL11.glAlphaFunc(516, 0.0F);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
RenderSystem.depthMask(false);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
RenderSystem.enableAlphaTest();
|
||||
RenderSystem.alphaFunc(516, 0.0F);
|
||||
RenderSystem.enableBlend();
|
||||
}
|
||||
|
||||
|
||||
float blindA = 1F - BackgroundInfo.blindness;
|
||||
blind02 = blindA * 0.2F;
|
||||
blind06 = blindA * 0.6F;
|
||||
|
||||
|
||||
if (blindA > 0) {
|
||||
matrices.push();
|
||||
matrices.multiply(new Quaternion(0, time, 0, false));
|
||||
textureManager.bindTexture(HORIZON);
|
||||
be_renderBuffer(matrices, horizon, VertexFormats.POSITION_TEXTURE, 0.77F, 0.31F, 0.73F, 0.7F * blindA);
|
||||
matrices.pop();
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(new Quaternion(0, -time, 0, false));
|
||||
textureManager.bindTexture(NEBULA_1);
|
||||
be_renderBuffer(matrices, nebulas1, VertexFormats.POSITION_TEXTURE, 0.77F, 0.31F, 0.73F, blind02);
|
||||
matrices.pop();
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(new Quaternion(0, time2, 0, false));
|
||||
textureManager.bindTexture(NEBULA_2);
|
||||
be_renderBuffer(matrices, nebulas2, VertexFormats.POSITION_TEXTURE, 0.77F, 0.31F, 0.73F, blind02);
|
||||
matrices.pop();
|
||||
|
||||
textureManager.bindTexture(STARS);
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(axis3.getRadialQuaternion(time));
|
||||
be_renderBuffer(matrices, stars3, VertexFormats.POSITION_TEXTURE, 0.77F, 0.31F, 0.73F, blind06);
|
||||
matrices.pop();
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(axis4.getRadialQuaternion(time2));
|
||||
be_renderBuffer(matrices, stars4, VertexFormats.POSITION_TEXTURE, 1F, 1F, 1F, blind06);
|
||||
matrices.pop();
|
||||
matrices.pushPose();
|
||||
matrices.mulPose(new Quaternion(0, time, 0, false));
|
||||
textureManager.bind(HORIZON);
|
||||
be_renderBuffer(matrices, horizon, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, 0.7F * blindA);
|
||||
matrices.popPose();
|
||||
|
||||
matrices.pushPose();
|
||||
matrices.mulPose(new Quaternion(0, -time, 0, false));
|
||||
textureManager.bind(NEBULA_1);
|
||||
be_renderBuffer(matrices, nebulas1, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, blind02);
|
||||
matrices.popPose();
|
||||
|
||||
matrices.pushPose();
|
||||
matrices.mulPose(new Quaternion(0, time2, 0, false));
|
||||
textureManager.bind(NEBULA_2);
|
||||
be_renderBuffer(matrices, nebulas2, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, blind02);
|
||||
matrices.popPose();
|
||||
|
||||
textureManager.bind(STARS);
|
||||
|
||||
matrices.pushPose();
|
||||
matrices.mulPose(axis3.rotation(time));
|
||||
be_renderBuffer(matrices, stars3, DefaultVertexFormat.POSITION_TEX, 0.77F, 0.31F, 0.73F, blind06);
|
||||
matrices.popPose();
|
||||
|
||||
matrices.pushPose();
|
||||
matrices.mulPose(axis4.rotation(time2));
|
||||
be_renderBuffer(matrices, stars4, DefaultVertexFormat.POSITION_TEX, 1F, 1F, 1F, blind06);
|
||||
matrices.popPose();
|
||||
}
|
||||
|
||||
|
||||
float a = (BackgroundInfo.fog - 1F);
|
||||
if (a > 0) {
|
||||
if (a > 1)
|
||||
a = 1;
|
||||
textureManager.bindTexture(FOG);
|
||||
be_renderBuffer(matrices, fog, VertexFormats.POSITION_TEXTURE, BackgroundInfo.red, BackgroundInfo.green,
|
||||
BackgroundInfo.blue, a);
|
||||
if (a > 1) a = 1;
|
||||
textureManager.bind(FOG);
|
||||
be_renderBuffer(matrices, fog, DefaultVertexFormat.POSITION_TEX, BackgroundInfo.red, BackgroundInfo.green, BackgroundInfo.blue, a);
|
||||
}
|
||||
|
||||
RenderSystem.disableTexture();
|
||||
|
||||
|
||||
if (blindA > 0) {
|
||||
matrices.push();
|
||||
matrices.multiply(axis1.getRadialQuaternion(time3));
|
||||
be_renderBuffer(matrices, stars1, VertexFormats.POSITION, 1, 1, 1, blind06);
|
||||
matrices.pop();
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(axis2.getRadialQuaternion(time2));
|
||||
be_renderBuffer(matrices, stars2, VertexFormats.POSITION, 0.95F, 0.64F, 0.93F, blind06);
|
||||
matrices.pop();
|
||||
matrices.pushPose();
|
||||
matrices.mulPose(axis1.rotation(time3));
|
||||
be_renderBuffer(matrices, stars1, DefaultVertexFormat.POSITION, 1, 1, 1, blind06);
|
||||
matrices.popPose();
|
||||
|
||||
matrices.pushPose();
|
||||
matrices.mulPose(axis2.rotation(time2));
|
||||
be_renderBuffer(matrices, stars2, DefaultVertexFormat.POSITION, 0.95F, 0.64F, 0.93F, blind06);
|
||||
matrices.popPose();
|
||||
}
|
||||
|
||||
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.depthMask(true);
|
||||
|
||||
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void be_renderBuffer(MatrixStack matrices, VertexBuffer buffer, VertexFormat format, float r, float g,
|
||||
float b, float a) {
|
||||
|
||||
private void be_renderBuffer(PoseStack matrices, VertexBuffer buffer, VertexFormat format, float r, float g, float b, float a) {
|
||||
RenderSystem.color4f(r, g, b, a);
|
||||
buffer.bind();
|
||||
format.startDrawing(0L);
|
||||
buffer.draw(matrices.peek().getModel(), 7);
|
||||
VertexBuffer.unbind();
|
||||
format.endDrawing();
|
||||
format.setupBufferState(0L);
|
||||
buffer.draw(matrices.last().pose(), 7);
|
||||
VertexBuffer.unbind();
|
||||
format.clearBufferState();
|
||||
}
|
||||
|
||||
private void be_initStars() {
|
||||
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
|
||||
BufferBuilder buffer = Tesselator.getInstance().getBuilder();
|
||||
stars1 = be_buildBufferStars(buffer, stars1, 0.1, 0.30, 3500, 41315);
|
||||
stars2 = be_buildBufferStars(buffer, stars2, 0.1, 0.35, 2000, 35151);
|
||||
stars3 = be_buildBufferUVStars(buffer, stars3, 0.4, 1.2, 1000, 61354);
|
||||
|
@ -200,78 +196,75 @@ public class WorldRendererMixin {
|
|||
horizon = be_buildBufferHorizon(buffer, horizon);
|
||||
fog = be_buildBufferFog(buffer, fog);
|
||||
}
|
||||
|
||||
private VertexBuffer be_buildBufferStars(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize,
|
||||
double maxSize, int count, long seed) {
|
||||
|
||||
private VertexBuffer be_buildBufferStars(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize, double maxSize, int count, long seed) {
|
||||
if (buffer != null) {
|
||||
buffer.close();
|
||||
}
|
||||
|
||||
buffer = new VertexBuffer(VertexFormats.POSITION);
|
||||
buffer = new VertexBuffer(DefaultVertexFormat.POSITION);
|
||||
be_makeStars(bufferBuilder, minSize, maxSize, count, seed);
|
||||
bufferBuilder.end();
|
||||
buffer.upload(bufferBuilder);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private VertexBuffer be_buildBufferUVStars(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize,
|
||||
double maxSize, int count, long seed) {
|
||||
|
||||
private VertexBuffer be_buildBufferUVStars(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize, double maxSize, int count, long seed) {
|
||||
if (buffer != null) {
|
||||
buffer.close();
|
||||
}
|
||||
|
||||
buffer = new VertexBuffer(VertexFormats.POSITION_TEXTURE);
|
||||
buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX);
|
||||
be_makeUVStars(bufferBuilder, minSize, maxSize, count, seed);
|
||||
bufferBuilder.end();
|
||||
buffer.upload(bufferBuilder);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private VertexBuffer be_buildBufferFarFog(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize,
|
||||
double maxSize, int count, long seed) {
|
||||
|
||||
private VertexBuffer be_buildBufferFarFog(BufferBuilder bufferBuilder, VertexBuffer buffer, double minSize, double maxSize, int count, long seed) {
|
||||
if (buffer != null) {
|
||||
buffer.close();
|
||||
}
|
||||
|
||||
buffer = new VertexBuffer(VertexFormats.POSITION_TEXTURE);
|
||||
buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX);
|
||||
be_makeFarFog(bufferBuilder, minSize, maxSize, count, seed);
|
||||
bufferBuilder.end();
|
||||
buffer.upload(bufferBuilder);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
private VertexBuffer be_buildBufferHorizon(BufferBuilder bufferBuilder, VertexBuffer buffer) {
|
||||
if (buffer != null) {
|
||||
buffer.close();
|
||||
}
|
||||
|
||||
buffer = new VertexBuffer(VertexFormats.POSITION_TEXTURE);
|
||||
buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX);
|
||||
be_makeCylinder(bufferBuilder, 16, 50, 100);
|
||||
bufferBuilder.end();
|
||||
buffer.upload(bufferBuilder);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
private VertexBuffer be_buildBufferFog(BufferBuilder bufferBuilder, VertexBuffer buffer) {
|
||||
if (buffer != null) {
|
||||
buffer.close();
|
||||
}
|
||||
|
||||
buffer = new VertexBuffer(VertexFormats.POSITION_TEXTURE);
|
||||
buffer = new VertexBuffer(DefaultVertexFormat.POSITION_TEX);
|
||||
be_makeCylinder(bufferBuilder, 16, 50, 70);
|
||||
bufferBuilder.end();
|
||||
buffer.upload(bufferBuilder);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
private void be_makeStars(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) {
|
||||
Random random = new Random(seed);
|
||||
buffer.begin(7, VertexFormats.POSITION);
|
||||
buffer.begin(7, DefaultVertexFormat.POSITION);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
double posX = random.nextDouble() * 2.0 - 1.0;
|
||||
|
@ -306,15 +299,15 @@ public class WorldRendererMixin {
|
|||
double ae = 0.0 * q - aa * r;
|
||||
double af = ae * n - ab * o;
|
||||
double ah = ab * n + ae * o;
|
||||
buffer.vertex(j + af, k + ad, l + ah).next();
|
||||
buffer.vertex(j + af, k + ad, l + ah).endVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void be_makeUVStars(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) {
|
||||
Random random = new Random(seed);
|
||||
buffer.begin(7, VertexFormats.POSITION_TEXTURE);
|
||||
buffer.begin(7, DefaultVertexFormat.POSITION_TEX);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
double posX = random.nextDouble() * 2.0 - 1.0;
|
||||
|
@ -353,16 +346,16 @@ public class WorldRendererMixin {
|
|||
double ah = ab * n + ae * o;
|
||||
float texU = (pos >> 1) & 1;
|
||||
float texV = (((pos + 1) >> 1) & 1) / 4F + minV;
|
||||
pos++;
|
||||
buffer.vertex(j + af, k + ad, l + ah).texture(texU, texV).next();
|
||||
pos ++;
|
||||
buffer.vertex(j + af, k + ad, l + ah).uv(texU, texV).endVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void be_makeFarFog(BufferBuilder buffer, double minSize, double maxSize, int count, long seed) {
|
||||
Random random = new Random(seed);
|
||||
buffer.begin(7, VertexFormats.POSITION_TEXTURE);
|
||||
buffer.begin(7, DefaultVertexFormat.POSITION_TEX);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
double posX = random.nextDouble() * 2.0 - 1.0;
|
||||
|
@ -404,30 +397,30 @@ public class WorldRendererMixin {
|
|||
double ah = ab * n + ae * o;
|
||||
float texU = (pos >> 1) & 1;
|
||||
float texV = ((pos + 1) >> 1) & 1;
|
||||
pos++;
|
||||
buffer.vertex(j + af, k + ad, l + ah).texture(texU, texV).next();
|
||||
pos ++;
|
||||
buffer.vertex(j + af, k + ad, l + ah).uv(texU, texV).endVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void be_makeCylinder(BufferBuilder buffer, int segments, double height, double radius) {
|
||||
buffer.begin(7, VertexFormats.POSITION_TEXTURE);
|
||||
for (int i = 0; i < segments; i++) {
|
||||
buffer.begin(7, DefaultVertexFormat.POSITION_TEX);
|
||||
for (int i = 0; i < segments; i ++) {
|
||||
double a1 = (double) i * Math.PI * 2.0 / (double) segments;
|
||||
double a2 = (double) (i + 1) * Math.PI * 2.0 / (double) segments;
|
||||
double px1 = Math.sin(a1) * radius;
|
||||
double pz1 = Math.cos(a1) * radius;
|
||||
double px2 = Math.sin(a2) * radius;
|
||||
double pz2 = Math.cos(a2) * radius;
|
||||
|
||||
|
||||
float u0 = (float) i / (float) segments;
|
||||
float u1 = (float) (i + 1) / (float) segments;
|
||||
|
||||
buffer.vertex(px1, -height, pz1).texture(u0, 0).next();
|
||||
buffer.vertex(px1, height, pz1).texture(u0, 1).next();
|
||||
buffer.vertex(px2, height, pz2).texture(u1, 1).next();
|
||||
buffer.vertex(px2, -height, pz2).texture(u1, 0).next();
|
||||
|
||||
buffer.vertex(px1, -height, pz1).uv(u0, 0).endVertex();
|
||||
buffer.vertex(px1, height, pz1).uv(u0, 1).endVertex();
|
||||
buffer.vertex(px2, height, pz2).uv(u1, 1).endVertex();
|
||||
buffer.vertex(px2, -height, pz2).uv(u1, 0).endVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,30 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
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.world.level.block.AbstractBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.util.Mth;
|
||||
import ru.betterend.item.tool.EndHammerItem;
|
||||
import ru.betterend.util.MHelper;
|
||||
|
||||
@Mixin(AbstractBlock.class)
|
||||
@Mixin(BlockBehaviour.class)
|
||||
public abstract class AbstractBlockMixin {
|
||||
|
||||
@Inject(method = "getDrops", at = @At("HEAD"), cancellable = true)
|
||||
public void be_getDroppedStacks(BlockState state, LootContext.Builder builder,
|
||||
CallbackInfoReturnable<List<ItemStack>> info) {
|
||||
|
||||
@Inject(method = "getDroppedStacks", at = @At("HEAD"), cancellable = true)
|
||||
public void be_getDroppedStacks(BlockState state, LootContext.Builder builder, CallbackInfoReturnable<List<ItemStack>> info) {
|
||||
if (state.is(Blocks.GLOWSTONE)) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null && tool.getItem() instanceof EndHammerItem) {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
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.world.level.block.AnvilBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
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 ru.betterend.blocks.basis.EndAnvilBlock;
|
||||
|
||||
@Mixin(AnvilBlock.class)
|
||||
|
@ -15,10 +14,10 @@ public class AnvilBlockMixin {
|
|||
@Inject(method = "getLandingState", at = @At("HEAD"), cancellable = true)
|
||||
private static void be_getLandingState(BlockState fallingState, CallbackInfoReturnable<BlockState> info) {
|
||||
if (fallingState.getBlock() instanceof EndAnvilBlock) {
|
||||
IntegerProperty destructionProperty = ((EndAnvilBlock) fallingState.getBlock()).getDESTRUCTION();
|
||||
int destruction = fallingState.get(destructionProperty);
|
||||
IntegerProperty destructionProperty = ((EndAnvilBlock) fallingState.getBlock()).getDestructionProperty();
|
||||
int destruction = fallingState.getValue(destructionProperty);
|
||||
try {
|
||||
BlockState state = fallingState.with(destructionProperty, destruction + 1);
|
||||
BlockState state = fallingState.setValue(destructionProperty, destruction + 1);
|
||||
info.setReturnValue(state);
|
||||
info.cancel();
|
||||
} catch (Exception ex) {
|
||||
|
|
|
@ -3,103 +3,100 @@ package ru.betterend.mixin.common;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AnvilMenu;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.DataSlot;
|
||||
import net.minecraft.world.inventory.ItemCombinerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.level.block.AnvilBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
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.world.level.block.AnvilBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.screen.AnvilScreenHandler;
|
||||
import net.minecraft.screen.ForgingScreenHandler;
|
||||
import net.minecraft.screen.Property;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import ru.betterend.blocks.basis.EndAnvilBlock;
|
||||
import ru.betterend.interfaces.AnvilScreenHandlerExtended;
|
||||
import ru.betterend.recipe.builders.AnvilRecipe;
|
||||
|
||||
@Mixin(AnvilScreenHandler.class)
|
||||
public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler implements AnvilScreenHandlerExtended {
|
||||
@Mixin(AnvilMenu.class)
|
||||
public abstract class AnvilScreenHandlerMixin extends ItemCombinerMenu implements AnvilScreenHandlerExtended {
|
||||
|
||||
private List<AnvilRecipe> be_recipes = Collections.emptyList();
|
||||
private AnvilRecipe be_currentRecipe;
|
||||
private Property anvilLevel;
|
||||
private DataSlot anvilLevel;
|
||||
|
||||
public AnvilScreenHandlerMixin(int syncId, PlayerInventory playerInventory) {
|
||||
super(ScreenHandlerType.ANVIL, syncId, playerInventory, ScreenHandlerContext.EMPTY);
|
||||
public AnvilScreenHandlerMixin(int syncId, Inventory playerInventory) {
|
||||
super(MenuType.ANVIL, syncId, playerInventory, ContainerLevelAccess.NULL);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>(ILnet/minecraft/entity/player/PlayerInventory;Lnet/minecraft/screen/ScreenHandlerContext;)V", at = @At("TAIL"))
|
||||
public void be_initAnvilLevel(int syncId, PlayerInventory inventory, ScreenHandlerContext context,
|
||||
CallbackInfo info) {
|
||||
if (context != ScreenHandlerContext.EMPTY) {
|
||||
int anvLevel = context.run((world, blockPos) -> {
|
||||
@Inject(method = "<init>(ILnet/minecraft/entity/player/PlayerInventory;Lnet/minecraft/screen/ScreenHandlerContext;)V",
|
||||
at = @At("TAIL"))
|
||||
public void be_initAnvilLevel(int syncId, Inventory inventory, ContainerLevelAccess context, CallbackInfo info) {
|
||||
if (context != ContainerLevelAccess.NULL) {
|
||||
int anvLevel = context.evaluate((world, blockPos) -> {
|
||||
Block anvilBlock = world.getBlockState(blockPos).getBlock();
|
||||
if (anvilBlock instanceof EndAnvilBlock) {
|
||||
return ((EndAnvilBlock) anvilBlock).getCraftingLevel();
|
||||
}
|
||||
return 1;
|
||||
}, 1);
|
||||
Property anvilLevel = Property.create();
|
||||
DataSlot anvilLevel = DataSlot.standalone();
|
||||
anvilLevel.set(anvLevel);
|
||||
this.anvilLevel = addProperty(anvilLevel);
|
||||
this.anvilLevel = addDataSlot(anvilLevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Shadow
|
||||
public abstract void updateResult();
|
||||
|
||||
public abstract void createResult();
|
||||
|
||||
@Inject(method = "canTakeOutput", at = @At("HEAD"), cancellable = true)
|
||||
protected void be_canTakeOutput(Player player, boolean present, CallbackInfoReturnable<Boolean> info) {
|
||||
if (be_currentRecipe != null) {
|
||||
info.setReturnValue(be_currentRecipe.checkHammerDurability(input, player));
|
||||
info.setReturnValue(be_currentRecipe.checkHammerDurability(inputSlots, player));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "onTakeOutput", at = @At("HEAD"), cancellable = true)
|
||||
protected void be_onTakeOutput(Player player, ItemStack stack, CallbackInfoReturnable<ItemStack> info) {
|
||||
if (be_currentRecipe != null) {
|
||||
this.input.getStack(0).decrement(be_currentRecipe.getInputCount());
|
||||
stack = be_currentRecipe.craft(input, player);
|
||||
this.onContentChanged(input);
|
||||
this.context.run((world, blockPos) -> {
|
||||
this.inputSlots.getItem(0).shrink(be_currentRecipe.getInputCount());
|
||||
stack = be_currentRecipe.craft(inputSlots, player);
|
||||
this.slotsChanged(inputSlots);
|
||||
this.access.execute((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 (!player.abilities.instabuild && anvilState.is(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
|
||||
BlockState landingState = AnvilBlock.damage(anvilState);
|
||||
if (landingState == null) {
|
||||
world.removeBlock(blockPos, false);
|
||||
world.syncWorldEvent(1029, blockPos, 0);
|
||||
world.levelEvent(1029, blockPos, 0);
|
||||
} else {
|
||||
world.setBlockAndUpdate(blockPos, landingState, 2);
|
||||
world.syncWorldEvent(1030, blockPos, 0);
|
||||
world.setBlock(blockPos, landingState, 2);
|
||||
world.levelEvent(1030, blockPos, 0);
|
||||
}
|
||||
} else {
|
||||
world.syncWorldEvent(1030, blockPos, 0);
|
||||
world.levelEvent(1030, blockPos, 0);
|
||||
}
|
||||
});
|
||||
info.setReturnValue(stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "updateResult", at = @At("HEAD"), cancellable = true)
|
||||
public void be_updateOutput(CallbackInfo info) {
|
||||
RecipeManager recipeManager = this.player.world.getRecipeManager();
|
||||
be_recipes = recipeManager.getAllMatches(AnvilRecipe.TYPE, input, player.world);
|
||||
RecipeManager recipeManager = this.player.level.getRecipeManager();
|
||||
be_recipes = recipeManager.getRecipesFor(AnvilRecipe.TYPE, inputSlots, player.level);
|
||||
if (be_recipes.size() > 0) {
|
||||
int anvilLevel = this.anvilLevel.get();
|
||||
be_recipes = be_recipes.stream().filter(recipe -> anvilLevel >= recipe.getAnvilLevel())
|
||||
.collect(Collectors.toList());
|
||||
be_recipes = be_recipes.stream().filter(recipe ->
|
||||
anvilLevel >= recipe.getAnvilLevel()).collect(Collectors.toList());
|
||||
if (be_recipes.size() > 0) {
|
||||
if (be_currentRecipe == null || !be_recipes.contains(be_currentRecipe)) {
|
||||
be_currentRecipe = be_recipes.get(0);
|
||||
|
@ -111,16 +108,16 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler imple
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "setNewItemName", at = @At("HEAD"), cancellable = true)
|
||||
public void be_setNewItemName(String string, CallbackInfo info) {
|
||||
if (be_currentRecipe != null) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onButtonClick(Player player, int id) {
|
||||
public boolean clickMenuButton(Player player, int id) {
|
||||
if (id == 0) {
|
||||
this.be_previousRecipe();
|
||||
return true;
|
||||
|
@ -128,27 +125,26 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler imple
|
|||
this.be_nextRecipe();
|
||||
return true;
|
||||
}
|
||||
return super.onButtonClick(player, id);
|
||||
return super.clickMenuButton(player, id);
|
||||
}
|
||||
|
||||
|
||||
private void be_updateResult() {
|
||||
if (be_currentRecipe == null)
|
||||
return;
|
||||
this.output.setStack(0, be_currentRecipe.craft(input));
|
||||
this.sendContentUpdates();
|
||||
if (be_currentRecipe == null) return;
|
||||
this.resultSlots.setItem(0, be_currentRecipe.assemble(inputSlots));
|
||||
this.broadcastChanges();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void be_updateCurrentRecipe(AnvilRecipe recipe) {
|
||||
this.be_currentRecipe = recipe;
|
||||
this.be_updateResult();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AnvilRecipe be_getCurrentRecipe() {
|
||||
return this.be_currentRecipe;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<AnvilRecipe> be_getRecipes() {
|
||||
return this.be_recipes;
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.world.item.ArmorItem;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.world.item.ArmorItem;
|
||||
|
||||
@Mixin(ArmorItem.class)
|
||||
public interface ArmorItemAccessor {
|
||||
@Accessor("MODIFIERS")
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.biome.source.BiomeArray;
|
||||
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import ru.betterend.interfaces.IBiomeArray;
|
||||
|
||||
@Mixin(BiomeArray.class)
|
||||
@Mixin(ChunkBiomeContainer.class)
|
||||
public class BiomeArrayMixin implements IBiomeArray {
|
||||
@Final
|
||||
@Shadow
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.item.BoneMealItem;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome.BiomeCategory;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
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.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.item.BoneMealItem;
|
||||
import net.minecraft.world.item.ItemUsageContext;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome.Category;
|
||||
import ru.betterend.registry.EndBiomes;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndTags;
|
||||
|
@ -31,14 +29,14 @@ public class BoneMealItemMixin {
|
|||
private static final MutableBlockPos POS = new MutableBlockPos();
|
||||
|
||||
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
|
||||
private void be_onUse(ItemUsageContext context, CallbackInfoReturnable<ActionResult> info) {
|
||||
private void be_onUse(UseOnContext context, CallbackInfoReturnable<InteractionResult> info) {
|
||||
Level world = context.getLevel();
|
||||
BlockPos blockPos = context.getBlockPos();
|
||||
BlockPos blockPos = context.getClickedPos();
|
||||
if (!world.isClientSide) {
|
||||
BlockPos offseted = blockPos.offset(context.getSide());
|
||||
boolean endBiome = world.getBiome(offseted).getCategory() == Category.THEEND;
|
||||
|
||||
if (world.getBlockState(blockPos).isIn(EndTags.END_GROUND)) {
|
||||
BlockPos offseted = blockPos.relative(context.getClickedFace());
|
||||
boolean endBiome = world.getBiome(offseted).getBiomeCategory() == BiomeCategory.THEEND;
|
||||
|
||||
if (world.getBlockState(blockPos).is(EndTags.END_GROUND)) {
|
||||
boolean consume = false;
|
||||
if (world.getBlockState(blockPos).is(Blocks.END_STONE)) {
|
||||
BlockState nylium = beGetNylium(world, blockPos);
|
||||
|
@ -46,32 +44,35 @@ public class BoneMealItemMixin {
|
|||
BlocksHelper.setWithoutUpdate(world, blockPos, nylium);
|
||||
consume = true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!world.getFluidState(offseted).isEmpty() && endBiome) {
|
||||
if (world.getBlockState(offseted).getBlock().equals(Blocks.WATER)) {
|
||||
consume = beGrowWaterGrass(world, blockPos);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
consume = beGrowGrass(world, blockPos);
|
||||
}
|
||||
}
|
||||
if (consume) {
|
||||
if (!context.getPlayer().isCreative()) {
|
||||
context.getStack().decrement(1);
|
||||
context.getItemInHand().shrink(1);
|
||||
}
|
||||
world.syncWorldEvent(2005, blockPos, 0);
|
||||
info.setReturnValue(ActionResult.SUCCESS);
|
||||
world.levelEvent(2005, blockPos, 0);
|
||||
info.setReturnValue(InteractionResult.SUCCESS);
|
||||
info.cancel();
|
||||
}
|
||||
} else if (!world.getFluidState(offseted).isEmpty() && endBiome) {
|
||||
}
|
||||
else if (!world.getFluidState(offseted).isEmpty() && endBiome) {
|
||||
if (world.getBlockState(offseted).getBlock().equals(Blocks.WATER)) {
|
||||
info.setReturnValue(ActionResult.FAIL);
|
||||
info.setReturnValue(InteractionResult.FAIL);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean beGrowGrass(Level world, BlockPos pos) {
|
||||
int y1 = pos.getY() + 3;
|
||||
int y2 = pos.getY() - 3;
|
||||
|
@ -84,7 +85,7 @@ public class BoneMealItemMixin {
|
|||
for (int y = y1; y >= y2; y--) {
|
||||
POS.setY(y);
|
||||
BlockPos down = POS.below();
|
||||
if (world.isAir(POS) && !world.isAir(down)) {
|
||||
if (world.isEmptyBlock(POS) && !world.isEmptyBlock(down)) {
|
||||
BlockState grass = beGetGrassState(world, down);
|
||||
if (grass != null) {
|
||||
BlocksHelper.setWithoutUpdate(world, POS, grass);
|
||||
|
@ -96,7 +97,7 @@ public class BoneMealItemMixin {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private boolean beGrowWaterGrass(Level world, BlockPos pos) {
|
||||
int y1 = pos.getY() + 3;
|
||||
int y2 = pos.getY() - 3;
|
||||
|
@ -109,7 +110,7 @@ public class BoneMealItemMixin {
|
|||
for (int y = y1; y >= y2; y--) {
|
||||
POS.setY(y);
|
||||
BlockPos down = POS.below();
|
||||
if (world.getBlockState(POS).is(Blocks.WATER) && world.getBlockState(down).isIn(EndTags.END_GROUND)) {
|
||||
if (world.getBlockState(POS).is(Blocks.WATER) && world.getBlockState(down).is(EndTags.END_GROUND)) {
|
||||
BlockState grass = beGetWaterGrassState(world, down);
|
||||
if (grass != null) {
|
||||
BlocksHelper.setWithoutUpdate(world, POS, grass);
|
||||
|
@ -121,26 +122,26 @@ public class BoneMealItemMixin {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private BlockState beGetGrassState(Level world, BlockPos pos) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
Block block = state.getBlock();
|
||||
block = BonemealUtil.getGrass(EndBiomes.getBiomeID(world.getBiome(pos)), block, world.getRandom());
|
||||
return block == null ? null : block.defaultBlockState();
|
||||
}
|
||||
|
||||
|
||||
private BlockState beGetWaterGrassState(Level world, BlockPos pos) {
|
||||
EndBiome biome = EndBiomes.getFromBiome(world.getBiome(pos));
|
||||
if (world.random.nextInt(16) == 0) {
|
||||
return EndBlocks.CHARNIA_RED.defaultBlockState();
|
||||
} else if (biome == EndBiomes.FOGGY_MUSHROOMLAND || biome == EndBiomes.MEGALAKE
|
||||
|| biome == EndBiomes.MEGALAKE_GROVE) {
|
||||
return world.random.nextBoolean() ? EndBlocks.CHARNIA_LIGHT_BLUE.defaultBlockState()
|
||||
: EndBlocks.CHARNIA_LIGHT_BLUE.defaultBlockState();
|
||||
} else if (biome == EndBiomes.AMBER_LAND) {
|
||||
return world.random.nextBoolean() ? EndBlocks.CHARNIA_ORANGE.defaultBlockState()
|
||||
: EndBlocks.CHARNIA_RED.defaultBlockState();
|
||||
} else if (biome == EndBiomes.CHORUS_FOREST || biome == EndBiomes.SHADOW_FOREST) {
|
||||
}
|
||||
else if (biome == EndBiomes.FOGGY_MUSHROOMLAND || biome == EndBiomes.MEGALAKE || biome == EndBiomes.MEGALAKE_GROVE) {
|
||||
return world.random.nextBoolean() ? EndBlocks.CHARNIA_LIGHT_BLUE.defaultBlockState() : EndBlocks.CHARNIA_LIGHT_BLUE.defaultBlockState();
|
||||
}
|
||||
else if (biome == EndBiomes.AMBER_LAND) {
|
||||
return world.random.nextBoolean() ? EndBlocks.CHARNIA_ORANGE.defaultBlockState() : EndBlocks.CHARNIA_RED.defaultBlockState();
|
||||
}
|
||||
else if (biome == EndBiomes.CHORUS_FOREST || biome == EndBiomes.SHADOW_FOREST) {
|
||||
return EndBlocks.CHARNIA_PURPLE.defaultBlockState();
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.alchemy.Potion;
|
||||
import net.minecraft.world.item.crafting.BrewingRecipeRegistry;
|
||||
import net.minecraft.world.item.alchemy.PotionBrewing;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(BrewingRecipeRegistry.class)
|
||||
@Mixin(PotionBrewing.class)
|
||||
public interface BrewingAccessor {
|
||||
@Invoker
|
||||
static void callRegisterPotionRecipe(Potion input, Item item, Potion output) {
|
||||
|
|
|
@ -1,7 +1,21 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChorusFlowerBlock;
|
||||
import net.minecraft.world.level.block.ChorusPlantBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -10,22 +24,6 @@ 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.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChorusFlowerBlock;
|
||||
import net.minecraft.world.level.block.ChorusPlantBlock;
|
||||
import net.minecraft.world.level.block.ShapeContext;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.WorldView;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndTags;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
|
@ -33,83 +31,78 @@ import ru.betterend.world.generator.GeneratorOptions;
|
|||
|
||||
@Mixin(value = ChorusFlowerBlock.class, priority = 100)
|
||||
public abstract class ChorusFlowerBlockMixin extends Block {
|
||||
private static final VoxelShape SHAPE_FULL = Block.createCuboidShape(0, 0, 0, 16, 16, 16);
|
||||
private static final VoxelShape SHAPE_HALF = Block.createCuboidShape(0, 0, 0, 16, 4, 16);
|
||||
|
||||
public ChorusFlowerBlockMixin(net.minecraft.world.level.block.state.BlockBehaviour.Properties settings) {
|
||||
private static final VoxelShape SHAPE_FULL = Block.box(0, 0, 0, 16, 16, 16);
|
||||
private static final VoxelShape SHAPE_HALF = Block.box(0, 0, 0, 16, 4, 16);
|
||||
|
||||
public ChorusFlowerBlockMixin(Properties settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ChorusPlantBlock plantBlock;
|
||||
|
||||
|
||||
@Inject(method = "canPlaceAt", at = @At("HEAD"), cancellable = true)
|
||||
private void beCanPlace(BlockState state, WorldView world, BlockPos pos, CallbackInfoReturnable<Boolean> info) {
|
||||
private void beCanPlace(BlockState state, LevelReader world, BlockPos pos, CallbackInfoReturnable<Boolean> info) {
|
||||
if (world.getBlockState(pos.below()).is(EndBlocks.CHORUS_NYLIUM)) {
|
||||
info.setReturnValue(true);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "randomTick", at = @At("HEAD"), cancellable = true)
|
||||
private void beOnTick(BlockState state, ServerLevel world, BlockPos pos, Random random, CallbackInfo info) {
|
||||
if (world.getBlockState(pos.below()).isIn(EndTags.END_GROUND)) {
|
||||
BlockPos up = pos.up();
|
||||
if (world.isAir(up) && up.getY() < 256) {
|
||||
if (world.getBlockState(pos.below()).is(EndTags.END_GROUND)) {
|
||||
BlockPos up = pos.above();
|
||||
if (world.isEmptyBlock(up) && up.getY() < 256) {
|
||||
int i = state.getValue(ChorusFlowerBlock.AGE);
|
||||
if (i < 5) {
|
||||
this.grow(world, up, i + 1);
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
BlocksHelper.setWithoutUpdate(world, pos,
|
||||
plantBlock.defaultBlockState().with(ChorusPlantBlock.UP, true)
|
||||
.with(ChorusPlantBlock.DOWN, true).with(BlocksHelper.ROOTS, true));
|
||||
} else {
|
||||
BlocksHelper.setWithoutUpdate(world, pos, plantBlock.defaultBlockState()
|
||||
.with(ChorusPlantBlock.UP, true).with(ChorusPlantBlock.DOWN, true));
|
||||
BlocksHelper.setWithoutUpdate(world, pos, plantBlock.defaultBlockState().setValue(ChorusPlantBlock.UP, true).setValue(ChorusPlantBlock.DOWN, true).setValue(BlocksHelper.ROOTS, true));
|
||||
}
|
||||
else {
|
||||
BlocksHelper.setWithoutUpdate(world, pos, plantBlock.defaultBlockState().setValue(ChorusPlantBlock.UP, true).setValue(ChorusPlantBlock.DOWN, true));
|
||||
}
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "generate", at = @At("RETURN"), cancellable = true)
|
||||
private static void beOnGenerate(LevelAccessor world, BlockPos pos, Random random, int size, CallbackInfo info) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (GeneratorOptions.changeChorusPlant() && state.is(Blocks.CHORUS_PLANT)) {
|
||||
BlocksHelper.setWithoutUpdate(world, pos, state.with(BlocksHelper.ROOTS, true));
|
||||
BlocksHelper.setWithoutUpdate(world, pos, state.setValue(BlocksHelper.ROOTS, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Shadow
|
||||
private static boolean isSurroundedByAir(WorldView world, BlockPos pos, @Nullable Direction exceptDirection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isSurroundedByAir(LevelReader world, BlockPos pos, @Nullable Direction exceptDirection) { return false; }
|
||||
|
||||
@Shadow
|
||||
private void grow(Level world, BlockPos pos, int age) {
|
||||
}
|
||||
|
||||
private void grow(Level world, BlockPos pos, int age) {}
|
||||
|
||||
@Shadow
|
||||
private void die(Level world, BlockPos pos) {
|
||||
}
|
||||
|
||||
private void die(Level world, BlockPos pos) {}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
return state.getValue(ChorusFlowerBlock.AGE) == 5 ? SHAPE_HALF : SHAPE_FULL;
|
||||
} else {
|
||||
return super.getOutlineShape(state, world, pos, context);
|
||||
}
|
||||
else {
|
||||
return super.getShape(state, world, pos, context);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "die", at = @At("HEAD"), cancellable = true)
|
||||
private void beOnDie(Level world, BlockPos pos, CallbackInfo info) {
|
||||
BlockState down = world.getBlockState(pos.below());
|
||||
if (down.is(Blocks.CHORUS_PLANT) || down.isIn(EndTags.GEN_TERRAIN)) {
|
||||
world.setBlockAndUpdate(pos, this.defaultBlockState().with(Properties.AGE_5, 5), 2);
|
||||
world.syncWorldEvent(1034, pos, 0);
|
||||
if (down.is(Blocks.CHORUS_PLANT) || down.is(EndTags.GEN_TERRAIN)) {
|
||||
world.setBlock(pos, this.defaultBlockState().setValue(BlockStateProperties.AGE_5, 5), 2);
|
||||
world.levelEvent(1034, pos, 0);
|
||||
}
|
||||
info.cancel();
|
||||
}
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChorusPlantBlock;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.world.level.block.AbstractBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChorusPlantBlock;
|
||||
import net.minecraft.world.item.ItemPlacementContext;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.WorldView;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndTags;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
|
@ -27,69 +26,72 @@ import ru.betterend.world.generator.GeneratorOptions;
|
|||
|
||||
@Mixin(value = ChorusPlantBlock.class, priority = 100)
|
||||
public abstract class ChorusPlantBlockMixin extends Block {
|
||||
public ChorusPlantBlockMixin(net.minecraft.world.level.block.state.BlockBehaviour.Properties settings) {
|
||||
public ChorusPlantBlockMixin(Properties settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void beOnInit(AbstractBlock.Properties settings, CallbackInfo info) {
|
||||
private void beOnInit(BlockBehaviour.Properties settings, CallbackInfo info) {
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
this.setDefaultState(this.defaultBlockState().with(BlocksHelper.ROOTS, false));
|
||||
this.registerDefaultState(this.defaultBlockState().setValue(BlocksHelper.ROOTS, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "createBlockStateDefinition", at = @At("TAIL"))
|
||||
|
||||
@Inject(method = "appendProperties", at = @At("TAIL"))
|
||||
private void beAddProperties(StateDefinition.Builder<Block, BlockState> builder, CallbackInfo info) {
|
||||
GeneratorOptions.init();
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
builder.add(BlocksHelper.ROOTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "withConnectionProperties", at = @At("RETURN"), cancellable = true)
|
||||
private void beConnectionProperties(BlockView world, BlockPos pos, CallbackInfoReturnable<BlockState> info) {
|
||||
private void beConnectionProperties(BlockGetter world, BlockPos pos, CallbackInfoReturnable<BlockState> info) {
|
||||
BlockState plant = info.getReturnValue();
|
||||
if (plant.is(Blocks.CHORUS_PLANT)) {
|
||||
if (world.getBlockState(pos.below()).isIn(EndTags.END_GROUND)) {
|
||||
if (world.getBlockState(pos.below()).is(EndTags.END_GROUND)) {
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
info.setReturnValue(plant.with(Properties.DOWN, true).with(BlocksHelper.ROOTS, true));
|
||||
} else {
|
||||
info.setReturnValue(plant.with(Properties.DOWN, true));
|
||||
info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true).setValue(BlocksHelper.ROOTS, true));
|
||||
}
|
||||
else {
|
||||
info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true));
|
||||
}
|
||||
info.cancel();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
info.setReturnValue(plant.with(BlocksHelper.ROOTS, false));
|
||||
info.setReturnValue(plant.setValue(BlocksHelper.ROOTS, false));
|
||||
}
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "canPlaceAt", at = @At("HEAD"), cancellable = true)
|
||||
private void beCanPlace(BlockState state, WorldView world, BlockPos pos, CallbackInfoReturnable<Boolean> info) {
|
||||
private void beCanPlace(BlockState state, LevelReader world, BlockPos pos, CallbackInfoReturnable<Boolean> info) {
|
||||
BlockState down = world.getBlockState(pos.below());
|
||||
if (down.is(EndBlocks.CHORUS_NYLIUM) || down.is(Blocks.END_STONE)) {
|
||||
info.setReturnValue(true);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "updateShape", at = @At("RETURN"), cancellable = true)
|
||||
private void beStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState,
|
||||
LevelAccessor world, BlockPos pos, BlockPos posFrom, CallbackInfoReturnable<BlockState> info) {
|
||||
|
||||
@Inject(method = "getStateForNeighborUpdate", at = @At("RETURN"), cancellable = true)
|
||||
private void beStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom, CallbackInfoReturnable<BlockState> info) {
|
||||
BlockState plant = info.getReturnValue();
|
||||
if (plant.is(Blocks.CHORUS_PLANT)) {
|
||||
if (world.getBlockState(pos.below()).isIn(EndTags.END_GROUND)) {
|
||||
if (world.getBlockState(pos.below()).is(EndTags.END_GROUND)) {
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
plant = plant.with(Properties.DOWN, true).with(BlocksHelper.ROOTS, true);
|
||||
} else {
|
||||
plant = plant.with(Properties.DOWN, true);
|
||||
plant = plant.setValue(BlockStateProperties.DOWN, true).setValue(BlocksHelper.ROOTS, true);
|
||||
}
|
||||
else {
|
||||
plant = plant.setValue(BlockStateProperties.DOWN, true);
|
||||
}
|
||||
info.cancel();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
plant = plant.with(BlocksHelper.ROOTS, false);
|
||||
plant = plant.setValue(BlocksHelper.ROOTS, false);
|
||||
}
|
||||
info.cancel();
|
||||
}
|
||||
|
@ -97,18 +99,18 @@ public abstract class ChorusPlantBlockMixin extends Block {
|
|||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "getPlacementState", at = @At("RETURN"), cancellable = true)
|
||||
private void beGetPlacementState(ItemPlacementContext ctx, CallbackInfoReturnable<BlockState> info) {
|
||||
BlockPos pos = ctx.getBlockPos();
|
||||
private void beGetPlacementState(BlockPlaceContext ctx, CallbackInfoReturnable<BlockState> info) {
|
||||
BlockPos pos = ctx.getClickedPos();
|
||||
Level world = ctx.getLevel();
|
||||
BlockState plant = info.getReturnValue();
|
||||
if (ctx.canPlace() && plant.is(Blocks.CHORUS_PLANT)
|
||||
&& world.getBlockState(pos.below()).isIn(EndTags.END_GROUND)) {
|
||||
if (ctx.canPlace() && plant.is(Blocks.CHORUS_PLANT) && world.getBlockState(pos.below()).is(EndTags.END_GROUND)) {
|
||||
if (GeneratorOptions.changeChorusPlant()) {
|
||||
info.setReturnValue(plant.with(BlocksHelper.ROOTS, true).with(Properties.DOWN, true));
|
||||
} else {
|
||||
info.setReturnValue(plant.with(Properties.DOWN, true));
|
||||
info.setReturnValue(plant.setValue(BlocksHelper.ROOTS, true).setValue(BlockStateProperties.DOWN, true));
|
||||
}
|
||||
else {
|
||||
info.setReturnValue(plant.setValue(BlockStateProperties.DOWN, true));
|
||||
}
|
||||
info.cancel();
|
||||
}
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChorusFlowerBlock;
|
||||
import net.minecraft.world.level.block.PipeBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.feature.ChorusPlantFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
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.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChorusFlowerBlock;
|
||||
import net.minecraft.world.level.block.ConnectingBlock;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.feature.ChorusPlantFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
import ru.betterend.util.MHelper;
|
||||
|
@ -24,19 +22,16 @@ import ru.betterend.world.generator.GeneratorOptions;
|
|||
@Mixin(ChorusPlantFeature.class)
|
||||
public class ChorusPlantFeatureMixin {
|
||||
@Inject(method = "generate", at = @At("HEAD"), cancellable = true)
|
||||
private void be_onGenerate(WorldGenLevel structureWorldAccess, ChunkGenerator chunkGenerator, Random random,
|
||||
BlockPos blockPos, NoneFeatureConfiguration defaultFeatureConfig, CallbackInfoReturnable<Boolean> info) {
|
||||
if (structureWorldAccess.isAir(blockPos)
|
||||
&& structureWorldAccess.getBlockState(blockPos.below()).is(EndBlocks.CHORUS_NYLIUM)) {
|
||||
ChorusFlowerBlock.generate(structureWorldAccess, blockPos, random, MHelper.randRange(8, 16, random));
|
||||
private void be_onGenerate(WorldGenLevel structureWorldAccess, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, NoneFeatureConfiguration defaultFeatureConfig, CallbackInfoReturnable<Boolean> info) {
|
||||
if (structureWorldAccess.isEmptyBlock(blockPos) && structureWorldAccess.getBlockState(blockPos.below()).is(EndBlocks.CHORUS_NYLIUM)) {
|
||||
ChorusFlowerBlock.generatePlant(structureWorldAccess, blockPos, random, MHelper.randRange(8, 16, random));
|
||||
BlockState bottom = structureWorldAccess.getBlockState(blockPos);
|
||||
if (bottom.is(Blocks.CHORUS_PLANT)) {
|
||||
if ((GeneratorOptions.changeChorusPlant())) {
|
||||
BlocksHelper.setWithoutUpdate(structureWorldAccess, blockPos,
|
||||
bottom.with(BlocksHelper.ROOTS, true).with(ConnectingBlock.DOWN, true));
|
||||
} else {
|
||||
BlocksHelper.setWithoutUpdate(structureWorldAccess, blockPos,
|
||||
bottom.with(ConnectingBlock.DOWN, true));
|
||||
BlocksHelper.setWithoutUpdate(structureWorldAccess, blockPos, bottom.setValue(BlocksHelper.ROOTS, true).setValue(PipeBlock.DOWN, true));
|
||||
}
|
||||
else {
|
||||
BlocksHelper.setWithoutUpdate(structureWorldAccess, blockPos, bottom.setValue(PipeBlock.DOWN, true));
|
||||
}
|
||||
}
|
||||
info.setReturnValue(true);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.ComposterBlock;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.world.level.block.ComposterBlock;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
@Mixin(ComposterBlock.class)
|
||||
public interface ComposterBlockAccessor {
|
||||
@Invoker
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.CraftingMenu;
|
||||
import net.minecraft.world.level.block.CraftingTableBlock;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -7,20 +11,16 @@ 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.world.level.block.CraftingTableBlock;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.screen.CraftingScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
|
||||
@Mixin(CraftingScreenHandler.class)
|
||||
public abstract class CraftingScreenHandlerMixin {
|
||||
@Mixin(CraftingMenu.class)
|
||||
public abstract class CraftingScreenHandlerMixin
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private ScreenHandlerContext context;
|
||||
private ContainerLevelAccess context;
|
||||
|
||||
@Inject(method = "canUse", at = @At("HEAD"), cancellable = true)
|
||||
private void be_canUse(Player player, CallbackInfoReturnable<Boolean> info) {
|
||||
if (context.run((world, pos) -> {
|
||||
if (context.evaluate((world, pos) -> {
|
||||
return world.getBlockState(pos).getBlock() instanceof CraftingTableBlock;
|
||||
}, true)) {
|
||||
info.setReturnValue(true);
|
||||
|
|
|
@ -1,31 +1,28 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
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.core.Registry;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||
import net.minecraft.world.gen.chunk.NoiseChunkGenerator;
|
||||
import ru.betterend.world.generator.BetterEndBiomeSource;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
@Mixin(value = DimensionType.class, priority = 100)
|
||||
public class DimensionTypeMixin {
|
||||
@Inject(method = "createEndGenerator", at = @At("HEAD"), cancellable = true)
|
||||
private static void be_replaceGenerator(Registry<Biome> biomeRegistry,
|
||||
Registry<ChunkGeneratorSettings> chunkGeneratorSettingsRegistry, long seed,
|
||||
CallbackInfoReturnable<ChunkGenerator> info) {
|
||||
info.setReturnValue(new NoiseChunkGenerator(new BetterEndBiomeSource(biomeRegistry, seed), seed, () -> {
|
||||
return (ChunkGeneratorSettings) chunkGeneratorSettingsRegistry.getOrThrow(ChunkGeneratorSettings.END);
|
||||
private static void be_replaceGenerator(Registry<Biome> biomeRegistry, Registry<NoiseGeneratorSettings> chunkGeneratorSettingsRegistry, long seed, CallbackInfoReturnable<ChunkGenerator> info) {
|
||||
info.setReturnValue(new NoiseBasedChunkGenerator(new BetterEndBiomeSource(biomeRegistry, seed), seed, () -> {
|
||||
return (NoiseGeneratorSettings) chunkGeneratorSettingsRegistry.getOrThrow(NoiseGeneratorSettings.END);
|
||||
}));
|
||||
info.cancel();
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "hasEnderDragonFight", at = @At("HEAD"), cancellable = true)
|
||||
private void be_hasEnderDragonFight(CallbackInfoReturnable<Boolean> info) {
|
||||
if (!GeneratorOptions.hasDragonFights()) {
|
||||
|
|
|
@ -2,35 +2,33 @@ package ru.betterend.mixin.common;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.DataSlot;
|
||||
import net.minecraft.world.inventory.EnchantmentMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentInstance;
|
||||
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 net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentLevelEntry;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.screen.EnchantmentScreenHandler;
|
||||
import net.minecraft.screen.Property;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.core.Registry;
|
||||
import ru.betterend.registry.EndTags;
|
||||
|
||||
@Mixin(EnchantmentScreenHandler.class)
|
||||
public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
|
||||
@Mixin(EnchantmentMenu.class)
|
||||
public abstract class EnchantmentScreenHandlerMixin extends AbstractContainerMenu {
|
||||
@Shadow
|
||||
@Final
|
||||
private Inventory inventory;
|
||||
private Container inventory;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ScreenHandlerContext context;
|
||||
private ContainerLevelAccess context;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
|
@ -38,7 +36,7 @@ public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
|
|||
|
||||
@Shadow
|
||||
@Final
|
||||
private Property seed;
|
||||
private DataSlot seed;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
|
@ -52,45 +50,44 @@ public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
|
|||
@Final
|
||||
public int[] enchantmentLevel;
|
||||
|
||||
protected EnchantmentScreenHandlerMixin(ScreenHandlerType<?> type, int syncId) {
|
||||
protected EnchantmentScreenHandlerMixin(MenuType<?> type, int syncId) {
|
||||
super(type, syncId);
|
||||
}
|
||||
|
||||
@Inject(method = "onContentChanged", at = @At("HEAD"), cancellable = true)
|
||||
private void beOnContentChanged(Inventory inventory, CallbackInfo info) {
|
||||
private void beOnContentChanged(Container inventory, CallbackInfo info) {
|
||||
if (inventory == this.inventory) {
|
||||
ItemStack itemStack = inventory.getStack(0);
|
||||
ItemStack itemStack = inventory.getItem(0);
|
||||
if (!itemStack.isEmpty() && itemStack.isEnchantable()) {
|
||||
this.context.run((world, blockPos) -> {
|
||||
this.context.execute((world, blockPos) -> {
|
||||
int i = 0;
|
||||
|
||||
int j;
|
||||
for (j = -1; j <= 1; ++j) {
|
||||
for (int k = -1; k <= 1; ++k) {
|
||||
if ((j != 0 || k != 0) && world.isAir(blockPos.add(k, 0, j))
|
||||
&& world.isAir(blockPos.add(k, 1, j))) {
|
||||
if (world.getBlockState(blockPos.add(k * 2, 0, j * 2)).isIn(EndTags.BOOKSHELVES)) {
|
||||
if ((j != 0 || k != 0) && world.isEmptyBlock(blockPos.offset(k, 0, j)) && world.isEmptyBlock(blockPos.offset(k, 1, j))) {
|
||||
if (world.getBlockState(blockPos.offset(k * 2, 0, j * 2)).is(EndTags.BOOKSHELVES)) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (world.getBlockState(blockPos.add(k * 2, 1, j * 2)).isIn(EndTags.BOOKSHELVES)) {
|
||||
if (world.getBlockState(blockPos.offset(k * 2, 1, j * 2)).is(EndTags.BOOKSHELVES)) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (k != 0 && j != 0) {
|
||||
if (world.getBlockState(blockPos.add(k * 2, 0, j)).isIn(EndTags.BOOKSHELVES)) {
|
||||
if (world.getBlockState(blockPos.offset(k * 2, 0, j)).is(EndTags.BOOKSHELVES)) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (world.getBlockState(blockPos.add(k * 2, 1, j)).isIn(EndTags.BOOKSHELVES)) {
|
||||
if (world.getBlockState(blockPos.offset(k * 2, 1, j)).is(EndTags.BOOKSHELVES)) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (world.getBlockState(blockPos.add(k, 0, j * 2)).isIn(EndTags.BOOKSHELVES)) {
|
||||
if (world.getBlockState(blockPos.offset(k, 0, j * 2)).is(EndTags.BOOKSHELVES)) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (world.getBlockState(blockPos.add(k, 1, j * 2)).isIn(EndTags.BOOKSHELVES)) {
|
||||
if (world.getBlockState(blockPos.offset(k, 1, j * 2)).is(EndTags.BOOKSHELVES)) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
@ -101,8 +98,7 @@ public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
|
|||
this.random.setSeed((long) this.seed.get());
|
||||
|
||||
for (j = 0; j < 3; ++j) {
|
||||
this.enchantmentPower[j] = EnchantmentHelper.calculateRequiredExperienceLevel(this.random, j, i,
|
||||
itemStack);
|
||||
this.enchantmentPower[j] = EnchantmentHelper.getEnchantmentCost(this.random, j, i, itemStack);
|
||||
this.enchantmentId[j] = -1;
|
||||
this.enchantmentLevel[j] = -1;
|
||||
if (this.enchantmentPower[j] < j + 1) {
|
||||
|
@ -112,21 +108,19 @@ public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
|
|||
|
||||
for (j = 0; j < 3; ++j) {
|
||||
if (this.enchantmentPower[j] > 0) {
|
||||
List<EnchantmentLevelEntry> list = this.generateEnchantments(itemStack, j,
|
||||
this.enchantmentPower[j]);
|
||||
List<EnchantmentInstance> list = this.generateEnchantments(itemStack, j, this.enchantmentPower[j]);
|
||||
if (list != null && !list.isEmpty()) {
|
||||
EnchantmentLevelEntry enchantmentLevelEntry = (EnchantmentLevelEntry) list
|
||||
.get(this.random.nextInt(list.size()));
|
||||
this.enchantmentId[j] = Registry.ENCHANTMENT
|
||||
.getRawId(enchantmentLevelEntry.enchantment);
|
||||
EnchantmentInstance enchantmentLevelEntry = (EnchantmentInstance) list.get(this.random.nextInt(list.size()));
|
||||
this.enchantmentId[j] = Registry.ENCHANTMENT.getId(enchantmentLevelEntry.enchantment);
|
||||
this.enchantmentLevel[j] = enchantmentLevelEntry.level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.sendContentUpdates();
|
||||
this.broadcastChanges();
|
||||
});
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
this.enchantmentPower[i] = 0;
|
||||
this.enchantmentId[i] = -1;
|
||||
|
@ -138,7 +132,7 @@ public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
|
|||
}
|
||||
|
||||
@Shadow
|
||||
private List<EnchantmentLevelEntry> generateEnchantments(ItemStack stack, int slot, int level) {
|
||||
private List<EnchantmentInstance> generateEnchantments(ItemStack stack, int slot, int level) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,40 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import net.minecraft.world.level.levelgen.feature.EndCityFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.biome.source.BiomeSource;
|
||||
import net.minecraft.world.gen.ChunkRandom;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.EndCityFeature;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
@Mixin(EndCityFeature.class)
|
||||
public class EndCityFeatureMixin {
|
||||
@Inject(method = "shouldStartAt", at = @At("HEAD"), cancellable = true)
|
||||
private void be_shouldStartAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long l,
|
||||
ChunkRandom chunkRandom, int i, int j, Biome biome, ChunkPos chunkPos,
|
||||
NoneFeatureConfiguration defaultFeatureConfig, CallbackInfoReturnable<Boolean> info) {
|
||||
private void be_shouldStartAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long l, WorldgenRandom chunkRandom, int i, int j, Biome biome, ChunkPos chunkPos, NoneFeatureConfiguration defaultFeatureConfig, CallbackInfoReturnable<Boolean> info) {
|
||||
if (GeneratorOptions.useNewGenerator()) {
|
||||
int chance = GeneratorOptions.getEndCityFailChance();
|
||||
if (chance == 0) {
|
||||
info.setReturnValue(getGenerationHeight(i, j, chunkGenerator) >= 60);
|
||||
info.cancel();
|
||||
} else if (chunkRandom.nextInt(chance) == 0) {
|
||||
}
|
||||
else if (chunkRandom.nextInt(chance) == 0){
|
||||
info.setReturnValue(getGenerationHeight(i, j, chunkGenerator) >= 60);
|
||||
info.cancel();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
info.setReturnValue(false);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Shadow
|
||||
private static int getGenerationHeight(int chunkX, int chunkZ, ChunkGenerator chunkGenerator) {
|
||||
return 0;
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.Heightmap.Types;
|
||||
import net.minecraft.world.level.levelgen.feature.EndPodiumFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -9,61 +17,50 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.structure.Structure;
|
||||
import net.minecraft.structure.StructurePlacementData;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.Heightmap.Type;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.EndPortalFeature;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.util.StructureHelper;
|
||||
import ru.betterend.util.WorldDataUtil;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
@Mixin(EndPortalFeature.class)
|
||||
@Mixin(EndPodiumFeature.class)
|
||||
public class EndPortalFeatureMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
private boolean open;
|
||||
|
||||
|
||||
@Inject(method = "generate", at = @At("HEAD"), cancellable = true)
|
||||
private void bePortalGenerate(WorldGenLevel world, ChunkGenerator generator, Random random, BlockPos blockPos,
|
||||
NoneFeatureConfiguration config, CallbackInfoReturnable<Boolean> info) {
|
||||
private void bePortalGenerate(WorldGenLevel world, ChunkGenerator generator, Random random, BlockPos blockPos, NoneFeatureConfiguration config, CallbackInfoReturnable<Boolean> info) {
|
||||
if (!GeneratorOptions.hasPortal()) {
|
||||
info.setReturnValue(false);
|
||||
info.cancel();
|
||||
} else if (GeneratorOptions.replacePortal()) {
|
||||
}
|
||||
else if (GeneratorOptions.replacePortal()) {
|
||||
blockPos = be_updatePos(blockPos, world);
|
||||
Structure structure = StructureHelper
|
||||
.readStructure(BetterEnd.makeID(open ? "portal/end_portal_active" : "portal/end_portal_inactive"));
|
||||
StructureTemplate structure = StructureHelper.readStructure(BetterEnd.makeID(open ? "portal/end_portal_active" : "portal/end_portal_inactive"));
|
||||
BlockPos size = structure.getSize();
|
||||
blockPos = blockPos.add(-(size.getX() >> 1), -3, -(size.getZ() >> 1));
|
||||
structure.place(world, blockPos, new StructurePlacementData(), random);
|
||||
blockPos = blockPos.offset(-(size.getX() >> 1), -3, -(size.getZ() >> 1));
|
||||
structure.placeInWorldChunk(world, blockPos, new StructurePlaceSettings(), random);
|
||||
info.setReturnValue(true);
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ModifyVariable(method = "generate", ordinal = 0, at = @At("HEAD"))
|
||||
private BlockPos be_setPosOnGround(BlockPos blockPos, WorldGenLevel world) {
|
||||
return be_updatePos(blockPos, world);
|
||||
}
|
||||
|
||||
|
||||
private BlockPos be_updatePos(BlockPos blockPos, WorldGenLevel world) {
|
||||
if (GeneratorOptions.useNewGenerator()) {
|
||||
BlockPos pos = GeneratorOptions.getPortalPos();
|
||||
if (pos.equals(BlockPos.ORIGIN)) {
|
||||
int y = world.getChunk(blockPos).sampleHeightmap(Type.WORLD_SURFACE, blockPos.getX(), blockPos.getZ());
|
||||
if (pos.equals(BlockPos.ZERO)) {
|
||||
int y = world.getChunk(blockPos).getHeight(Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ());
|
||||
if (y < 1) {
|
||||
y = 65;
|
||||
}
|
||||
pos = new BlockPos(pos.getX(), y, pos.getZ());
|
||||
GeneratorOptions.setPortalPos(pos);
|
||||
WorldDataUtil.getRootTag().put("portal", NbtHelper.fromBlockPos(pos));
|
||||
WorldDataUtil.getRootTag().put("portal", NbtUtils.writeBlockPos(pos));
|
||||
WorldDataUtil.saveFile();
|
||||
}
|
||||
return pos;
|
||||
|
|
|
@ -7,82 +7,78 @@ 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.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.PaneBlock;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.decoration.EndCrystalEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.structure.Structure;
|
||||
import net.minecraft.structure.StructurePlacementData;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.Heightmap.Type;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.IronBarsBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.feature.EndSpikeFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.EndSpikeFeatureConfig;
|
||||
import net.minecraft.world.level.levelgen.Heightmap.Types;
|
||||
import net.minecraft.world.level.levelgen.feature.SpikeFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.SpikeConfiguration;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
import ru.betterend.util.StructureHelper;
|
||||
import ru.betterend.util.WorldDataUtil;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
@Mixin(EndSpikeFeature.class)
|
||||
@Mixin(SpikeFeature.class)
|
||||
public class EndSpikeFeatureMixin {
|
||||
@Inject(method = "generate", at = @At("HEAD"), cancellable = true)
|
||||
private void beSpikeGenerate(WorldGenLevel structureWorldAccess, ChunkGenerator chunkGenerator, Random random,
|
||||
BlockPos blockPos, EndSpikeFeatureConfig endSpikeFeatureConfig, CallbackInfoReturnable<Boolean> info) {
|
||||
private void beSpikeGenerate(WorldGenLevel structureWorldAccess, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, SpikeConfiguration endSpikeFeatureConfig, CallbackInfoReturnable<Boolean> info) {
|
||||
if (!GeneratorOptions.hasPillars()) {
|
||||
info.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "generateSpike", at = @At("HEAD"), cancellable = true)
|
||||
private void be_generateSpike(ServerLevelAccessor world, Random random, EndSpikeFeatureConfig config,
|
||||
EndSpikeFeature.Spike spike, CallbackInfo info) {
|
||||
private void be_generateSpike(ServerLevelAccessor world, Random random, SpikeConfiguration config, SpikeFeature.EndSpike spike, CallbackInfo info) {
|
||||
int x = spike.getCenterX();
|
||||
int z = spike.getCenterZ();
|
||||
int radius = spike.getRadius();
|
||||
int minY = 0;
|
||||
|
||||
|
||||
long lx = (long) x;
|
||||
long lz = (long) z;
|
||||
if (lx * lx + lz * lz < 10000) {
|
||||
String pillarID = String.format("%d_%d", x, z);
|
||||
CompoundTag pillar = WorldDataUtil.getCompoundTag("pillars");
|
||||
boolean haveValue = pillar.contains(pillarID);
|
||||
minY = haveValue ? pillar.getInt(pillarID)
|
||||
: world.getChunk(x >> 4, z >> 4).sampleHeightmap(Type.WORLD_SURFACE, x & 15, z);
|
||||
minY = haveValue ? pillar.getInt(pillarID) : world.getChunk(x >> 4, z >> 4).getHeight(Types.WORLD_SURFACE, x & 15, z);
|
||||
if (!haveValue) {
|
||||
pillar.putInt(pillarID, minY);
|
||||
WorldDataUtil.saveFile();
|
||||
}
|
||||
} else {
|
||||
minY = world.getChunk(x >> 4, z >> 4).sampleHeightmap(Type.WORLD_SURFACE, x & 15, z);
|
||||
}
|
||||
|
||||
else {
|
||||
minY = world.getChunk(x >> 4, z >> 4).getHeight(Types.WORLD_SURFACE, x & 15, z);
|
||||
}
|
||||
|
||||
int maxY = minY + spike.getHeight() - 64;
|
||||
|
||||
|
||||
if (GeneratorOptions.replacePillars() && be_radiusInRange(radius)) {
|
||||
radius--;
|
||||
Structure base = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_base_" + radius));
|
||||
Structure top = StructureHelper.readStructure(
|
||||
BetterEnd.makeID("pillars/pillar_top_" + radius + (spike.isGuarded() ? "_cage" : "")));
|
||||
StructureTemplate base = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_base_" + radius));
|
||||
StructureTemplate top = StructureHelper.readStructure(BetterEnd.makeID("pillars/pillar_top_" + radius + (spike.isGuarded() ? "_cage" : "")));
|
||||
BlockPos side = base.getSize();
|
||||
BlockPos pos1 = new BlockPos(x - (side.getX() >> 1), minY - 3, z - (side.getZ() >> 1));
|
||||
minY = pos1.getY() + side.getY();
|
||||
side = top.getSize();
|
||||
BlockPos pos2 = new BlockPos(x - (side.getX() >> 1), maxY, z - (side.getZ() >> 1));
|
||||
maxY = pos2.getY();
|
||||
|
||||
StructurePlacementData data = new StructurePlacementData();
|
||||
base.place(world, pos1, data, random);
|
||||
top.place(world, pos2, data, random);
|
||||
|
||||
|
||||
StructurePlaceSettings data = new StructurePlaceSettings();
|
||||
base.placeInWorldChunk(world, pos1, data, random);
|
||||
top.placeInWorldChunk(world, pos2, data, random);
|
||||
|
||||
int r2 = radius * radius + 1;
|
||||
MutableBlockPos mut = new MutableBlockPos();
|
||||
for (int px = -radius; px <= radius; px++) {
|
||||
|
@ -95,10 +91,10 @@ public class EndSpikeFeatureMixin {
|
|||
for (int py = minY; py < maxY; py++) {
|
||||
mut.setY(py);
|
||||
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
|
||||
if ((px == radius || px == -radius || pz == radius || pz == -radius)
|
||||
&& random.nextInt(24) == 0) {
|
||||
if ((px == radius || px == -radius || pz == radius || pz == -radius) && random.nextInt(24) == 0) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.CRYING_OBSIDIAN);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.OBSIDIAN);
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +102,8 @@ public class EndSpikeFeatureMixin {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
minY -= 15;
|
||||
int r2 = radius * radius + 1;
|
||||
MutableBlockPos mut = new MutableBlockPos();
|
||||
|
@ -130,13 +127,13 @@ public class EndSpikeFeatureMixin {
|
|||
mut.setZ(z);
|
||||
mut.setY(maxY);
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.BEDROCK);
|
||||
|
||||
EndCrystalEntity crystal = EntityType.END_CRYSTAL.create(world.toServerWorld());
|
||||
crystal.setBeamTarget(config.getPos());
|
||||
|
||||
EndCrystal crystal = EntityType.END_CRYSTAL.create(world.getLevel());
|
||||
crystal.setBeamTarget(config.getCrystalBeamTarget());
|
||||
crystal.setInvulnerable(config.isCrystalInvulnerable());
|
||||
crystal.refreshPositionAndAngles(x + 0.5D, maxY + 1, z + 0.5D, random.nextFloat() * 360.0F, 0.0F);
|
||||
world.spawnEntity(crystal);
|
||||
|
||||
crystal.moveTo(x + 0.5D, maxY + 1, z + 0.5D, random.nextFloat() * 360.0F, 0.0F);
|
||||
world.addFreshEntity(crystal);
|
||||
|
||||
if (spike.isGuarded()) {
|
||||
for (int px = -2; px <= 2; ++px) {
|
||||
boolean bl = Mth.abs(px) == 2;
|
||||
|
@ -147,13 +144,8 @@ public class EndSpikeFeatureMixin {
|
|||
if (bl || bl2 || bl3) {
|
||||
boolean bl4 = px == -2 || px == 2 || bl3;
|
||||
boolean bl5 = pz == -2 || pz == 2 || bl3;
|
||||
BlockState blockState = (BlockState) ((BlockState) ((BlockState) ((BlockState) Blocks.IRON_BARS
|
||||
.defaultBlockState().with(PaneBlock.NORTH, bl4 && pz != -2))
|
||||
.with(PaneBlock.SOUTH, bl4 && pz != 2)).with(PaneBlock.WEST,
|
||||
bl5 && px != -2)).with(PaneBlock.EAST, bl5 && px != 2);
|
||||
BlocksHelper.setWithoutUpdate(world,
|
||||
mut.set(spike.getCenterX() + px, maxY + py, spike.getCenterZ() + pz),
|
||||
blockState);
|
||||
BlockState blockState = (BlockState) ((BlockState) ((BlockState) ((BlockState) Blocks.IRON_BARS.defaultBlockState().setValue(IronBarsBlock.NORTH, bl4 && pz != -2)).setValue(IronBarsBlock.SOUTH, bl4 && pz != 2)).setValue(IronBarsBlock.WEST, bl5 && px != -2)).setValue(IronBarsBlock.EAST, bl5 && px != 2);
|
||||
BlocksHelper.setWithoutUpdate(world, mut.set(spike.getCenterX() + px, maxY + py, spike.getCenterZ() + pz), blockState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +155,7 @@ public class EndSpikeFeatureMixin {
|
|||
|
||||
info.cancel();
|
||||
}
|
||||
|
||||
|
||||
private boolean be_radiusInRange(int radius) {
|
||||
return radius > 1 && radius < 6;
|
||||
}
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.monster.EnderMan;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
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.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.mob.EndermanEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import ru.betterend.effects.EndEnchantments;
|
||||
import ru.betterend.effects.EndMobEffects;
|
||||
import ru.betterend.effects.EndStatusEffects;
|
||||
|
||||
@Mixin(EndermanEntity.class)
|
||||
@Mixin(EnderMan.class)
|
||||
public abstract class EndermanEntityMixin {
|
||||
|
||||
|
||||
@Inject(method = "isPlayerStaring", at = @At("HEAD"), cancellable = true)
|
||||
private void be_isPlayerStaring(Player player, CallbackInfoReturnable<Boolean> info) {
|
||||
if (player.isCreative() || player.hasMobEffect(EndMobEffects.END_VEIL) || EnchantmentHelper
|
||||
.getLevel(EndEnchantments.END_VEIL, player.getEquippedStack(EquipmentSlot.HEAD)) > 0) {
|
||||
if (player.isCreative() || player.hasEffect(EndStatusEffects.END_VEIL) ||
|
||||
EnchantmentHelper.getItemEnchantmentLevel(EndEnchantments.END_VEIL, player.getItemBySlot(EquipmentSlot.HEAD)) > 0) {
|
||||
info.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.portal.PortalInfo;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.TeleportTarget;
|
||||
import net.minecraft.world.level.Level;
|
||||
import ru.betterend.interfaces.TeleportingEntity;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
|
@ -27,19 +26,19 @@ public abstract class EntityMixin implements TeleportingEntity {
|
|||
public boolean removed;
|
||||
@Shadow
|
||||
public Level world;
|
||||
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
public abstract void detach();
|
||||
|
||||
|
||||
@Shadow
|
||||
public abstract Vec3d getVelocity();
|
||||
|
||||
public abstract Vec3 getVelocity();
|
||||
|
||||
@Shadow
|
||||
public abstract EntityType<?> getType();
|
||||
|
||||
|
||||
@Shadow
|
||||
protected abstract TeleportTarget getTeleportTarget(ServerLevel destination);
|
||||
protected abstract PortalInfo getTeleportTarget(ServerLevel destination);
|
||||
|
||||
private BlockPos exitPos;
|
||||
|
||||
|
@ -49,33 +48,31 @@ public abstract class EntityMixin implements TeleportingEntity {
|
|||
this.detach();
|
||||
this.world.getProfiler().push("changeDimension");
|
||||
this.world.getProfiler().push("reposition");
|
||||
TeleportTarget teleportTarget = this.getTeleportTarget(destination);
|
||||
PortalInfo teleportTarget = this.getTeleportTarget(destination);
|
||||
if (teleportTarget != null) {
|
||||
this.world.getProfiler().swap("reloading");
|
||||
this.world.getProfiler().popPush("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);
|
||||
entity.restoreFrom(Entity.class.cast(this));
|
||||
entity.moveTo(teleportTarget.pos.x, teleportTarget.pos.y, teleportTarget.pos.z, teleportTarget.yRot, entity.xRot);
|
||||
entity.setDeltaMovement(teleportTarget.speed);
|
||||
destination.addFromAnotherDimension(entity);
|
||||
}
|
||||
this.removed = true;
|
||||
this.world.getProfiler().pop();
|
||||
((ServerLevel) world).resetIdleTimeout();
|
||||
destination.resetIdleTimeout();
|
||||
((ServerLevel) world).resetEmptyTime();
|
||||
destination.resetEmptyTime();
|
||||
this.world.getProfiler().pop();
|
||||
this.beResetExitPos();
|
||||
info.setReturnValue(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
|
||||
protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable<TeleportTarget> info) {
|
||||
protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable<PortalInfo> info) {
|
||||
if (beCanTeleport()) {
|
||||
info.setReturnValue(new TeleportTarget(
|
||||
new Vec3d(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getVelocity(), yaw, pitch));
|
||||
info.setReturnValue(new PortalInfo(new Vec3(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getVelocity(), yaw, pitch));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,25 +2,23 @@ package ru.betterend.mixin.common;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.world.biome.GenerationSettings;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
|
||||
|
||||
@Mixin(GenerationSettings.class)
|
||||
@Mixin(BiomeGenerationSettings.class)
|
||||
public interface GenerationSettingsAccessor {
|
||||
@Accessor("features")
|
||||
List<List<Supplier<ConfiguredFeature<?, ?>>>> beGetFeatures();
|
||||
|
||||
|
||||
@Accessor("features")
|
||||
void beSetFeatures(List<List<Supplier<ConfiguredFeature<?, ?>>>> features);
|
||||
|
||||
|
||||
@Accessor("structureFeatures")
|
||||
List<Supplier<ConfiguredStructureFeature<?, ?>>> beGetStructures();
|
||||
|
||||
|
||||
@Accessor("structureFeatures")
|
||||
void beSetStructures(List<Supplier<ConfiguredStructureFeature<?, ?>>> structures);
|
||||
}
|
||||
|
|
|
@ -2,33 +2,26 @@ package ru.betterend.mixin.common;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.monster.EnderMan;
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
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.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.SpawnReason;
|
||||
import net.minecraft.world.entity.mob.EndermanEntity;
|
||||
import net.minecraft.world.entity.mob.HostileEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
|
||||
@Mixin(HostileEntity.class)
|
||||
@Mixin(Monster.class)
|
||||
public class HostileEntityMixin {
|
||||
@Inject(method = "canSpawnInDark", at = @At(value = "RETURN"), cancellable = true)
|
||||
private static void be_endermenCheck(EntityType<? extends HostileEntity> type,
|
||||
ServerLevelAccessor serverWorldAccess, SpawnReason spawnReason, BlockPos pos, Random random,
|
||||
CallbackInfoReturnable<Boolean> info) {
|
||||
private static void be_endermenCheck(EntityType<? extends Monster> type, ServerLevelAccessor serverWorldAccess, MobSpawnType spawnReason, BlockPos pos, Random random, CallbackInfoReturnable<Boolean> info) {
|
||||
boolean canSpawn = info.getReturnValue();
|
||||
if (canSpawn && spawnReason == SpawnReason.NATURAL && type == EntityType.ENDERMAN) {
|
||||
Box box = new Box(pos).expand(16);
|
||||
List<EndermanEntity> entities = serverWorldAccess.getEntitiesByClass(EndermanEntity.class, box,
|
||||
(entity) -> {
|
||||
return true;
|
||||
});
|
||||
if (canSpawn && spawnReason == MobSpawnType.NATURAL && type == EntityType.ENDERMAN) {
|
||||
AABB box = new AABB(pos).inflate(16);
|
||||
List<EnderMan> entities = serverWorldAccess.getEntitiesOfClass(EnderMan.class, box, (entity) -> { return true; });
|
||||
info.setReturnValue(entities.size() < 6);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,30 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.item.Item;
|
||||
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.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
@Mixin(LivingEntity.class)
|
||||
public abstract class LivingEntityMixin {
|
||||
|
||||
private Entity lastAttacker;
|
||||
|
||||
@Inject(method = "hurt", at = @At("HEAD"))
|
||||
|
||||
@Inject(method = "damage", at = @At("HEAD"))
|
||||
public void be_damage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> info) {
|
||||
this.lastAttacker = source.getEntity();
|
||||
}
|
||||
|
||||
@ModifyArg(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;knockback(FDD)V"))
|
||||
|
||||
@ModifyArg(method = "damage", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;takeKnockback(FDD)V"))
|
||||
private float be_increaseKnockback(float value, double x, double z) {
|
||||
if (lastAttacker != null && lastAttacker instanceof LivingEntity) {
|
||||
LivingEntity attacker = (LivingEntity) lastAttacker;
|
||||
|
@ -34,12 +32,11 @@ public abstract class LivingEntityMixin {
|
|||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
private double be_getKnockback(Item tool) {
|
||||
if (tool == null)
|
||||
return 0.0D;
|
||||
if (tool == null) return 0.0D;
|
||||
Collection<AttributeModifier> modifiers = tool.getDefaultAttributeModifiers(EquipmentSlot.MAINHAND)
|
||||
.get(Attributes.ATTACK_KNOCKBACK);
|
||||
.get(Attributes.ATTACK_KNOCKBACK);
|
||||
if (modifiers.size() > 0) {
|
||||
return modifiers.iterator().next().getAmount();
|
||||
}
|
||||
|
|
|
@ -13,15 +13,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.resource.ServerResourceManager;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.WorldGenerationProgressListener;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.SaveProperties;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.ServerResources;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.ServerWorldProperties;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraft.world.level.storage.WorldData;
|
||||
import ru.betterend.recipe.EndRecipeManager;
|
||||
import ru.betterend.registry.EndBiomes;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
@ -29,15 +29,15 @@ import ru.betterend.world.generator.GeneratorOptions;
|
|||
@Mixin(MinecraftServer.class)
|
||||
public class MinecraftServerMixin {
|
||||
@Shadow
|
||||
private ServerResourceManager serverResourceManager;
|
||||
|
||||
private ServerResources serverResourceManager;
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
private Map<ResourceKey<Level>, ServerLevel> worlds;
|
||||
|
||||
|
||||
@Final
|
||||
@Shadow
|
||||
protected SaveProperties saveProperties;
|
||||
protected WorldData saveProperties;
|
||||
|
||||
@Inject(method = "reloadResources", at = @At(value = "RETURN"), cancellable = true)
|
||||
private void beOnReload(Collection<String> collection, CallbackInfoReturnable<CompletableFuture<Void>> info) {
|
||||
|
@ -49,7 +49,7 @@ public class MinecraftServerMixin {
|
|||
beInjectRecipes();
|
||||
EndBiomes.initRegistry((MinecraftServer) (Object) this);
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "getOverworld", at = @At(value = "HEAD"), cancellable = true)
|
||||
private final void beGetOverworld(CallbackInfoReturnable<ServerLevel> info) {
|
||||
if (GeneratorOptions.swapOverworldToEnd()) {
|
||||
|
@ -61,38 +61,34 @@ public class MinecraftServerMixin {
|
|||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "createWorlds", at = @At(value = "TAIL"))
|
||||
private final void be_CreateWorlds(WorldGenerationProgressListener worldGenerationProgressListener,
|
||||
CallbackInfo info) {
|
||||
private final void be_CreateWorlds(ChunkProgressListener worldGenerationProgressListener, CallbackInfo info) {
|
||||
if (GeneratorOptions.swapOverworldToEnd()) {
|
||||
ServerLevel world = worlds.get(Level.END);
|
||||
if (world == null) {
|
||||
world = worlds.get(Level.OVERWORLD);
|
||||
}
|
||||
this.getPlayerManager().setMainWorld(world);
|
||||
ServerWorldProperties serverWorldProperties = saveProperties.getMainWorldProperties();
|
||||
net.minecraft.world.gen.GeneratorOptions generatorOptions = saveProperties.getGeneratorOptions();
|
||||
boolean bl = generatorOptions.isDebugWorld();
|
||||
setupSpawn(world, serverWorldProperties, generatorOptions.hasBonusChest(), bl, true);
|
||||
this.getPlayerManager().setLevel(world);
|
||||
ServerLevelData serverWorldProperties = saveProperties.overworldData();
|
||||
net.minecraft.world.level.levelgen.WorldGenSettings generatorOptions = saveProperties.worldGenSettings();
|
||||
boolean bl = generatorOptions.isDebug();
|
||||
setupSpawn(world, serverWorldProperties, generatorOptions.generateBonusChest(), bl, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "setupSpawn", at = @At(value = "HEAD"), cancellable = true)
|
||||
private static void be_SetupSpawn(ServerLevel world, ServerWorldProperties serverWorldProperties,
|
||||
boolean bonusChest, boolean debugWorld, boolean bl, CallbackInfo info) {
|
||||
private static void be_SetupSpawn(ServerLevel world, ServerLevelData serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl, CallbackInfo info) {
|
||||
if (GeneratorOptions.swapOverworldToEnd() && world.dimension() == Level.OVERWORLD) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Shadow
|
||||
private static void setupSpawn(ServerLevel world, ServerWorldProperties serverWorldProperties, boolean bonusChest,
|
||||
boolean debugWorld, boolean bl) {
|
||||
}
|
||||
|
||||
private static void setupSpawn(ServerLevel world, ServerLevelData serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl) {}
|
||||
|
||||
@Shadow
|
||||
public PlayerManager getPlayerManager() {
|
||||
public PlayerList getPlayerManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,47 +1,43 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.StructureSettings;
|
||||
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 net.minecraft.world.biome.source.BiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||
import net.minecraft.world.gen.chunk.NoiseChunkGenerator;
|
||||
import net.minecraft.world.gen.chunk.StructuresConfig;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
import ru.betterend.world.generator.TerrainGenerator;
|
||||
|
||||
@Mixin(NoiseChunkGenerator.class)
|
||||
@Mixin(NoiseBasedChunkGenerator.class)
|
||||
public abstract class NoiseChunkGeneratorMixin extends ChunkGenerator {
|
||||
@Final
|
||||
@Shadow
|
||||
protected Supplier<ChunkGeneratorSettings> settings;
|
||||
|
||||
public NoiseChunkGeneratorMixin(BiomeSource populationSource, BiomeSource biomeSource,
|
||||
StructuresConfig structuresConfig, long worldSeed) {
|
||||
protected Supplier<NoiseGeneratorSettings> settings;
|
||||
|
||||
public NoiseChunkGeneratorMixin(BiomeSource populationSource, BiomeSource biomeSource, StructureSettings structuresConfig, long worldSeed) {
|
||||
super(populationSource, biomeSource, structuresConfig, worldSeed);
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/biome/source/BiomeSource;Lnet/minecraft/world/biome/source/BiomeSource;JLjava/util/function/Supplier;)V", at = @At("TAIL"))
|
||||
private void beOnInit(BiomeSource populationSource, BiomeSource biomeSource, long seed,
|
||||
Supplier<ChunkGeneratorSettings> settings, CallbackInfo info) {
|
||||
private void beOnInit(BiomeSource populationSource, BiomeSource biomeSource, long seed, Supplier<NoiseGeneratorSettings> settings, CallbackInfo info) {
|
||||
TerrainGenerator.initNoise(seed);
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "sampleNoiseColumn([DII)V", at = @At("HEAD"), cancellable = true, allow = 2)
|
||||
private void beSampleNoiseColumn(double[] buffer, int x, int z, CallbackInfo info) {
|
||||
if (GeneratorOptions.useNewGenerator() && settings.get().equals(ChunkGeneratorSettings.END)) {
|
||||
// System.out.println(TerrainGenerator.canGenerate(x, z));
|
||||
// if (TerrainGenerator.canGenerate(x, z)) {
|
||||
TerrainGenerator.fillTerrainDensity(buffer, x, z, getBiomeSource());
|
||||
info.cancel();
|
||||
// }
|
||||
if (GeneratorOptions.useNewGenerator() && settings.get().stable(NoiseGeneratorSettings.END)) {
|
||||
//System.out.println(TerrainGenerator.canGenerate(x, z));
|
||||
//if (TerrainGenerator.canGenerate(x, z)) {
|
||||
TerrainGenerator.fillTerrainDensity(buffer, x, z, getBiomeSource());
|
||||
info.cancel();
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,26 +2,26 @@ package ru.betterend.mixin.common;
|
|||
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
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 net.minecraft.server.level.ServerPlayer;
|
||||
import ru.betterend.events.PlayerAdvancementsEvents;
|
||||
|
||||
@Mixin(PlayerAdvancements.class)
|
||||
public abstract class PlayerAdvancementTrackerMixin {
|
||||
|
||||
|
||||
@Shadow
|
||||
private ServerPlayer owner;
|
||||
|
||||
@Inject(method = "award", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", shift = Shift.AFTER))
|
||||
public void be_onAdvancementComplete(Advancement advancement, String criterionName,
|
||||
CallbackInfoReturnable<Boolean> info) {
|
||||
PlayerAdvancementsEvents.PLAYER_ADVANCEMENT_COMPLETE.invoker().onAdvancementComplete(owner, advancement,
|
||||
criterionName);
|
||||
|
||||
@Inject(method = "grantCriterion", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/advancement/AdvancementRewards;apply(Lnet/minecraft/server/network/ServerPlayerEntity;)V",
|
||||
shift = Shift.AFTER))
|
||||
public void be_onAdvancementComplete(Advancement advancement, String criterionName, CallbackInfoReturnable<Boolean> info) {
|
||||
PlayerAdvancementsEvents.PLAYER_ADVENCEMENT_COMPLETE.invoker().onAdvancementComplete(owner, advancement, criterionName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
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.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import ru.betterend.blocks.BlockProperties;
|
||||
import ru.betterend.blocks.BlockProperties.TripleShape;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
|
@ -22,10 +20,9 @@ import ru.betterend.util.MHelper;
|
|||
@Mixin(Player.class)
|
||||
public abstract class PlayerEntityMixin {
|
||||
private static Direction[] HORIZONTAL;
|
||||
|
||||
|
||||
@Inject(method = "findRespawnPosition", at = @At(value = "HEAD"), cancellable = true)
|
||||
private static void be_statueRespawn(ServerLevel world, BlockPos pos, float f, boolean bl, boolean bl2,
|
||||
CallbackInfoReturnable<Optional<Vec3d>> info) {
|
||||
private static void be_statueRespawn(ServerLevel world, BlockPos pos, float f, boolean bl, boolean bl2, CallbackInfoReturnable<Optional<Vec3>> info) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if (blockState.is(EndBlocks.RESPAWN_OBELISK)) {
|
||||
info.setReturnValue(beObeliskRespawnPosition(world, pos, blockState));
|
||||
|
@ -33,21 +30,22 @@ public abstract class PlayerEntityMixin {
|
|||
}
|
||||
}
|
||||
|
||||
private static Optional<Vec3d> beObeliskRespawnPosition(ServerLevel world, BlockPos pos, BlockState state) {
|
||||
private static Optional<Vec3> beObeliskRespawnPosition(ServerLevel world, BlockPos pos, BlockState state) {
|
||||
if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.TOP) {
|
||||
pos = pos.down(2);
|
||||
} else if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.MIDDLE) {
|
||||
pos = pos.below(2);
|
||||
}
|
||||
else if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.MIDDLE) {
|
||||
pos = pos.below();
|
||||
}
|
||||
if (HORIZONTAL == null) {
|
||||
HORIZONTAL = BlocksHelper.makeHorizontal();
|
||||
}
|
||||
MHelper.shuffle(HORIZONTAL, world.getRandom());
|
||||
for (Direction dir : HORIZONTAL) {
|
||||
for (Direction dir: HORIZONTAL) {
|
||||
BlockPos p = pos.relative(dir);
|
||||
BlockState state2 = world.getBlockState(p);
|
||||
if (!state2.getMaterial().blocksMovement() && state2.getCollisionShape(world, pos).isEmpty()) {
|
||||
return Optional.of(Vec3d.of(p).add(0.5, 0, 0.5));
|
||||
if (!state2.getMaterial().blocksMotion() && state2.getCollisionShape(world, pos).isEmpty()) {
|
||||
return Optional.of(Vec3.atLowerCornerOf(p).add(0.5, 0, 0.5));
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
|
|
|
@ -19,46 +19,46 @@ import com.mojang.serialization.DataResult;
|
|||
import com.mojang.serialization.Dynamic;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.network.MessageType;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.DifficultyS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.EntityMobEffectS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.HeldItemChangeS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerAbilitiesS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.SynchronizeTagsS2CPacket;
|
||||
import net.minecraft.scoreboard.ServerScoreboard;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.UserCache;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.ChatType;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundUpdateTagsPacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.ServerScoreboard;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.server.players.GameProfileCache;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.WorldProperties;
|
||||
import net.minecraft.world.biome.source.BiomeAccess;
|
||||
import net.minecraft.world.level.biome.BiomeManager;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.storage.LevelData;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
@Mixin(PlayerManager.class)
|
||||
@Mixin(PlayerList.class)
|
||||
public class PlayerManagerMixin {
|
||||
@Final
|
||||
@Shadow
|
||||
|
@ -70,7 +70,7 @@ public class PlayerManagerMixin {
|
|||
|
||||
@Final
|
||||
@Shadow
|
||||
private DynamicRegistryManager.Impl registryManager;
|
||||
private RegistryAccess.RegistryHolder registryManager;
|
||||
|
||||
@Shadow
|
||||
private int viewDistance;
|
||||
|
@ -84,22 +84,22 @@ public class PlayerManagerMixin {
|
|||
private Map<UUID, ServerPlayer> playerMap;
|
||||
|
||||
@Inject(method = "onPlayerConnect", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void be_onPlayerConnect(ClientConnection connection, ServerPlayer player, CallbackInfo info) {
|
||||
public void be_onPlayerConnect(Connection connection, ServerPlayer player, CallbackInfo info) {
|
||||
if (GeneratorOptions.swapOverworldToEnd()) {
|
||||
GameProfile gameProfile = player.getGameProfile();
|
||||
UserCache userCache = this.server.getUserCache();
|
||||
GameProfile gameProfile2 = userCache.getByUuid(gameProfile.getId());
|
||||
GameProfileCache userCache = this.server.getProfileCache();
|
||||
GameProfile gameProfile2 = userCache.get(gameProfile.getId());
|
||||
String string = gameProfile2 == null ? gameProfile.getName() : gameProfile2.getName();
|
||||
userCache.add(gameProfile);
|
||||
CompoundTag compoundTag = this.loadPlayerData(player);
|
||||
ResourceKey<Level> var23;
|
||||
if (compoundTag != null) {
|
||||
DataResult<ResourceKey<Level>> var10000 = DimensionType
|
||||
.method_28521(new Dynamic<Tag>(NbtOps.INSTANCE, compoundTag.get("Dimension")));
|
||||
DataResult<ResourceKey<Level>> var10000 = DimensionType.parseLegacy(new Dynamic<Tag>(NbtOps.INSTANCE, compoundTag.get("Dimension")));
|
||||
Logger var10001 = LOGGER;
|
||||
var10001.getClass();
|
||||
var23 = (ResourceKey<Level>) var10000.resultOrPartial(var10001::error).orElse(Level.END);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
var23 = Level.END;
|
||||
}
|
||||
|
||||
|
@ -108,128 +108,117 @@ public class PlayerManagerMixin {
|
|||
ServerLevel serverWorld3;
|
||||
if (serverWorld == null) {
|
||||
LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", registryKey);
|
||||
serverWorld3 = this.server.getOverworld();
|
||||
} else {
|
||||
serverWorld3 = this.server.overworld();
|
||||
}
|
||||
else {
|
||||
serverWorld3 = serverWorld;
|
||||
}
|
||||
|
||||
player.setWorld(serverWorld3);
|
||||
player.interactionManager.setWorld((ServerLevel) player.world);
|
||||
player.setLevel(serverWorld3);
|
||||
player.gameMode.setLevel((ServerLevel) player.level);
|
||||
String string2 = "local";
|
||||
if (connection.getAddress() != null) {
|
||||
string2 = connection.getAddress().toString();
|
||||
if (connection.getRemoteAddress() != null) {
|
||||
string2 = connection.getRemoteAddress().toString();
|
||||
}
|
||||
|
||||
LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", player.getName().getString(), string2,
|
||||
player.getEntityId(), player.getX(), player.getY(), player.getZ());
|
||||
WorldProperties worldProperties = serverWorld3.getLevelProperties();
|
||||
LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", player.getName().getString(), string2, player.getId(), player.getX(), player.getY(), player.getZ());
|
||||
LevelData worldProperties = serverWorld3.getLevelData();
|
||||
this.setGameMode(player, (ServerPlayer) null, serverWorld3);
|
||||
ServerPlayNetworkHandler serverPlayNetworkHandler = new ServerPlayNetworkHandler(this.server, connection,
|
||||
player);
|
||||
ServerGamePacketListenerImpl serverPlayNetworkHandler = new ServerGamePacketListenerImpl(this.server, connection, player);
|
||||
GameRules gameRules = serverWorld3.getGameRules();
|
||||
boolean bl = gameRules.getBoolean(GameRules.DO_IMMEDIATE_RESPAWN);
|
||||
boolean bl2 = gameRules.getBoolean(GameRules.REDUCED_DEBUG_INFO);
|
||||
serverPlayNetworkHandler.sendPacket(new GameJoinS2CPacket(player.getEntityId(),
|
||||
player.interactionManager.getGameMode(), player.interactionManager.getPreviousGameMode(),
|
||||
BiomeAccess.hashSeed(serverWorld3.getSeed()), worldProperties.isHardcore(),
|
||||
this.server.getWorldRegistryKeys(), this.registryManager, serverWorld3.getDimension(),
|
||||
serverWorld3.dimension(), this.getMaxPlayerCount(), this.viewDistance, bl2, !bl,
|
||||
serverWorld3.isDebugWorld(), serverWorld3.isFlat()));
|
||||
serverPlayNetworkHandler.sendPacket(new CustomPayloadS2CPacket(CustomPayloadS2CPacket.BRAND,
|
||||
(new PacketByteBuf(Unpooled.buffer())).writeString(this.getServer().getServerModName())));
|
||||
serverPlayNetworkHandler.sendPacket(
|
||||
new DifficultyS2CPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked()));
|
||||
serverPlayNetworkHandler.sendPacket(new PlayerAbilitiesS2CPacket(player.abilities));
|
||||
serverPlayNetworkHandler.sendPacket(new HeldItemChangeS2CPacket(player.inventory.selectedSlot));
|
||||
serverPlayNetworkHandler
|
||||
.sendPacket(new SynchronizeRecipesS2CPacket(this.server.getRecipeManager().values()));
|
||||
serverPlayNetworkHandler.sendPacket(new SynchronizeTagsS2CPacket(this.server.getTagManager()));
|
||||
boolean bl = gameRules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN);
|
||||
boolean bl2 = gameRules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO);
|
||||
serverPlayNetworkHandler.send(new ClientboundLoginPacket(player.getId(), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), BiomeManager.obfuscateSeed(serverWorld3.getSeed()),
|
||||
worldProperties.isHardcore(), this.server.levelKeys(), this.registryManager, serverWorld3.dimensionType(), serverWorld3.dimension(), this.getMaxPlayerCount(), this.viewDistance, bl2, !bl,
|
||||
serverWorld3.isDebug(), serverWorld3.isFlat()));
|
||||
serverPlayNetworkHandler.send(new ClientboundCustomPayloadPacket(ClientboundCustomPayloadPacket.BRAND, (new FriendlyByteBuf(Unpooled.buffer())).writeUtf(this.getServer().getServerModName())));
|
||||
serverPlayNetworkHandler.send(new ClientboundChangeDifficultyPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked()));
|
||||
serverPlayNetworkHandler.send(new ClientboundPlayerAbilitiesPacket(player.abilities));
|
||||
serverPlayNetworkHandler.send(new ClientboundSetCarriedItemPacket(player.inventory.selected));
|
||||
serverPlayNetworkHandler.send(new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getRecipes()));
|
||||
serverPlayNetworkHandler.send(new ClientboundUpdateTagsPacket(this.server.getTags()));
|
||||
this.sendCommandTree(player);
|
||||
player.getStatHandler().updateStatSet();
|
||||
player.getRecipeBook().sendInitRecipesPacket(player);
|
||||
player.getStats().markAllDirty();
|
||||
player.getRecipeBook().sendInitialRecipeBook(player);
|
||||
this.sendScoreboard(serverWorld3.getScoreboard(), player);
|
||||
this.server.forcePlayerSampleUpdate();
|
||||
TranslatableText mutableText2;
|
||||
this.server.invalidateStatus();
|
||||
TranslatableComponent mutableText2;
|
||||
if (player.getGameProfile().getName().equalsIgnoreCase(string)) {
|
||||
mutableText2 = new TranslatableText("multiplayer.player.joined",
|
||||
new Object[] { player.getDisplayName() });
|
||||
} else {
|
||||
mutableText2 = new TranslatableText("multiplayer.player.joined.renamed",
|
||||
new Object[] { player.getDisplayName(), string });
|
||||
mutableText2 = new TranslatableComponent("multiplayer.player.joined", new Object[] { player.getDisplayName() });
|
||||
}
|
||||
else {
|
||||
mutableText2 = new TranslatableComponent("multiplayer.player.joined.renamed", new Object[] { player.getDisplayName(), string });
|
||||
}
|
||||
|
||||
this.broadcastChatMessage(mutableText2.formatted(Formatting.YELLOW), MessageType.SYSTEM, Util.NIL_UUID);
|
||||
serverPlayNetworkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.yaw,
|
||||
player.pitch);
|
||||
this.broadcastChatMessage(mutableText2.withStyle(ChatFormatting.YELLOW), ChatType.SYSTEM, Util.NIL_UUID);
|
||||
serverPlayNetworkHandler.teleport(player.getX(), player.getY(), player.getZ(), player.yRot, player.xRot);
|
||||
this.players.add(player);
|
||||
this.playerMap.put(player.getUuid(), player);
|
||||
this.sendToAll(
|
||||
new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER, new ServerPlayer[] { player }));
|
||||
this.playerMap.put(player.getUUID(), player);
|
||||
this.sendToAll(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { player }));
|
||||
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
player.networkHandler.sendPacket(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER,
|
||||
new ServerPlayer[] { (ServerPlayer) this.players.get(i) }));
|
||||
player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { (ServerPlayer) this.players.get(i) }));
|
||||
}
|
||||
|
||||
serverWorld3.onPlayerConnected(player);
|
||||
this.server.getBossBarManager().onPlayerConnect(player);
|
||||
serverWorld3.addNewPlayer(player);
|
||||
this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
this.sendWorldInfo(player, serverWorld3);
|
||||
if (!this.server.getResourcePackUrl().isEmpty()) {
|
||||
player.sendResourcePackUrl(this.server.getResourcePackUrl(), this.server.getResourcePackHash());
|
||||
if (!this.server.getResourcePack().isEmpty()) {
|
||||
player.sendTexturePack(this.server.getResourcePack(), this.server.getResourcePackHash());
|
||||
}
|
||||
|
||||
Iterator<?> var24 = player.getMobEffects().iterator();
|
||||
Iterator<?> var24 = player.getActiveEffects().iterator();
|
||||
|
||||
while (var24.hasNext()) {
|
||||
MobEffectInstance statusEffectInstance = (MobEffectInstance) var24.next();
|
||||
serverPlayNetworkHandler
|
||||
.sendPacket(new EntityMobEffectS2CPacket(player.getEntityId(), statusEffectInstance));
|
||||
serverPlayNetworkHandler.send(new ClientboundUpdateMobEffectPacket(player.getId(), statusEffectInstance));
|
||||
}
|
||||
|
||||
if (compoundTag != null && compoundTag.contains("RootVehicle", 10)) {
|
||||
CompoundTag compoundTag2 = compoundTag.getCompound("RootVehicle");
|
||||
Entity entity = EntityType.loadEntityWithPassengers(compoundTag2.getCompound("Entity"), serverWorld3,
|
||||
(vehicle) -> {
|
||||
return !serverWorld3.tryLoadEntity(vehicle) ? null : vehicle;
|
||||
});
|
||||
Entity entity = EntityType.loadEntityRecursive(compoundTag2.getCompound("Entity"), serverWorld3, (vehicle) -> {
|
||||
return !serverWorld3.addWithUUID(vehicle) ? null : vehicle;
|
||||
});
|
||||
if (entity != null) {
|
||||
UUID uUID2;
|
||||
if (compoundTag2.containsUuid("Attach")) {
|
||||
uUID2 = compoundTag2.getUuid("Attach");
|
||||
} else {
|
||||
if (compoundTag2.hasUUID("Attach")) {
|
||||
uUID2 = compoundTag2.getUUID("Attach");
|
||||
}
|
||||
else {
|
||||
uUID2 = null;
|
||||
}
|
||||
|
||||
Iterator<?> var21;
|
||||
Entity entity3;
|
||||
if (entity.getUuid().equals(uUID2)) {
|
||||
if (entity.getUUID().equals(uUID2)) {
|
||||
player.startRiding(entity, true);
|
||||
} else {
|
||||
var21 = entity.getPassengersDeep().iterator();
|
||||
}
|
||||
else {
|
||||
var21 = entity.getIndirectPassengers().iterator();
|
||||
|
||||
while (var21.hasNext()) {
|
||||
entity3 = (Entity) var21.next();
|
||||
if (entity3.getUuid().equals(uUID2)) {
|
||||
if (entity3.getUUID().equals(uUID2)) {
|
||||
player.startRiding(entity3, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.hasVehicle()) {
|
||||
if (!player.isPassenger()) {
|
||||
LOGGER.warn("Couldn't reattach entity to player");
|
||||
serverWorld3.removeEntity(entity);
|
||||
var21 = entity.getPassengersDeep().iterator();
|
||||
serverWorld3.despawn(entity);
|
||||
var21 = entity.getIndirectPassengers().iterator();
|
||||
|
||||
while (var21.hasNext()) {
|
||||
entity3 = (Entity) var21.next();
|
||||
serverWorld3.removeEntity(entity3);
|
||||
serverWorld3.despawn(entity3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player.onSpawn();
|
||||
player.initMenu();
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
@ -240,12 +229,10 @@ public class PlayerManagerMixin {
|
|||
}
|
||||
|
||||
@Shadow
|
||||
private void setGameMode(ServerPlayer player, @Nullable ServerPlayer oldPlayer, ServerLevel world) {
|
||||
}
|
||||
private void setGameMode(ServerPlayer player, @Nullable ServerPlayer oldPlayer, ServerLevel world) {}
|
||||
|
||||
@Shadow
|
||||
public void sendCommandTree(ServerPlayer player) {
|
||||
}
|
||||
public void sendCommandTree(ServerPlayer player) {}
|
||||
|
||||
@Shadow
|
||||
public int getMaxPlayerCount() {
|
||||
|
@ -258,18 +245,14 @@ public class PlayerManagerMixin {
|
|||
}
|
||||
|
||||
@Shadow
|
||||
protected void sendScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {
|
||||
}
|
||||
protected void sendScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {}
|
||||
|
||||
@Shadow
|
||||
public void broadcastChatMessage(Text message, MessageType type, UUID senderUuid) {
|
||||
}
|
||||
public void broadcastChatMessage(Component message, ChatType type, UUID senderUuid) {}
|
||||
|
||||
@Shadow
|
||||
public void sendToAll(Packet<?> packet) {
|
||||
}
|
||||
public void sendToAll(Packet<?> packet) {}
|
||||
|
||||
@Shadow
|
||||
public void sendWorldInfo(ServerPlayer player, ServerLevel world) {
|
||||
}
|
||||
public void sendWorldInfo(ServerPlayer player, ServerLevel world) {}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(RecipeManager.class)
|
||||
public interface RecipeManagerAccessor {
|
||||
|
|
|
@ -5,7 +5,15 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -14,16 +22,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
import net.minecraft.world.level.Level;
|
||||
import ru.betterend.recipe.EndRecipeManager;
|
||||
|
||||
@Mixin(RecipeManager.class)
|
||||
|
@ -32,26 +30,23 @@ public class RecipeManagerMixin {
|
|||
private Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes;
|
||||
|
||||
@Inject(method = "apply", at = @At(value = "RETURN"))
|
||||
private void beSetRecipes(Map<ResourceLocation, JsonElement> map, ResourceManager resourceManager,
|
||||
Profiler profiler, CallbackInfo info) {
|
||||
private void beSetRecipes(Map<ResourceLocation, JsonElement> map, ResourceManager resourceManager, ProfilerFiller profiler, CallbackInfo info) {
|
||||
recipes = EndRecipeManager.getMap(recipes);
|
||||
}
|
||||
|
||||
@Shadow
|
||||
private <C extends Inventory, T extends Recipe<C>> Map<ResourceLocation, Recipe<C>> getAllOfType(
|
||||
RecipeType<T> type) {
|
||||
private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, Recipe<C>> getAllOfType(RecipeType<T> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author paulevs
|
||||
* @reason Remove conflicts with vanilla tags Change recipe order to show mod
|
||||
* recipes first, helps when block have vanilla tag (example - mod stone
|
||||
* with vanilla tags and furnace from that stone)
|
||||
* @reason Remove conflicts with vanilla tags
|
||||
* Change recipe order to show mod recipes first, helps when block have vanilla tag
|
||||
* (example - mod stone with vanilla tags and furnace from that stone)
|
||||
*/
|
||||
@Overwrite
|
||||
public <C extends Inventory, T extends Recipe<C>> Optional<T> getFirstMatch(RecipeType<T> type, C inventory,
|
||||
Level world) {
|
||||
public <C extends Container, T extends Recipe<C>> Optional<T> getFirstMatch(RecipeType<T> type, C inventory, Level world) {
|
||||
Collection<Recipe<C>> values = getAllOfType(type).values();
|
||||
List<Recipe<C>> list = new ArrayList<Recipe<C>>(values);
|
||||
list.sort((v1, v2) -> {
|
||||
|
@ -61,7 +56,7 @@ public class RecipeManagerMixin {
|
|||
});
|
||||
|
||||
return list.stream().flatMap((recipe) -> {
|
||||
return Util.stream(type.get(recipe, world, inventory));
|
||||
return Util.toStream(type.tryMatch(recipe, world, inventory));
|
||||
}).findFirst();
|
||||
}
|
||||
}
|
|
@ -9,27 +9,26 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.network.packet.s2c.play.DifficultyS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.EntityMobEffectS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerAbilitiesS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.WorldEventS2CPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerPlayerInteractionManager;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.TeleportTarget;
|
||||
import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.WorldProperties;
|
||||
import net.minecraft.world.biome.source.BiomeAccess;
|
||||
import net.minecraft.world.level.biome.BiomeManager;
|
||||
import net.minecraft.world.level.portal.PortalInfo;
|
||||
import net.minecraft.world.level.storage.LevelData;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import ru.betterend.interfaces.TeleportingEntity;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
|
@ -37,10 +36,10 @@ import ru.betterend.world.generator.GeneratorOptions;
|
|||
public abstract class ServerPlayerEntityMixin extends Player implements TeleportingEntity {
|
||||
|
||||
@Shadow
|
||||
public ServerPlayNetworkHandler networkHandler;
|
||||
public ServerGamePacketListenerImpl networkHandler;
|
||||
@Final
|
||||
@Shadow
|
||||
public ServerPlayerInteractionManager interactionManager;
|
||||
public ServerPlayerGameMode interactionManager;
|
||||
@Final
|
||||
@Shadow
|
||||
public MinecraftServer server;
|
||||
|
@ -67,52 +66,47 @@ public abstract class ServerPlayerEntityMixin extends Player implements Teleport
|
|||
}
|
||||
|
||||
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
|
||||
protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable<TeleportTarget> info) {
|
||||
protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable<PortalInfo> info) {
|
||||
if (beCanTeleport()) {
|
||||
info.setReturnValue(new TeleportTarget(
|
||||
new Vec3d(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getVelocity(), yaw, pitch));
|
||||
info.setReturnValue(new PortalInfo(new Vec3(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getDeltaMovement(), yRot, xRot));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "moveToWorld", at = @At("HEAD"), cancellable = true)
|
||||
public void be_moveToWorld(ServerLevel destination, CallbackInfoReturnable<Entity> info) {
|
||||
if (beCanTeleport() && world instanceof ServerLevel) {
|
||||
if (beCanTeleport() && level instanceof ServerLevel) {
|
||||
this.inTeleportationState = true;
|
||||
ServerLevel serverWorld = this.getServerWorld();
|
||||
WorldProperties worldProperties = destination.getLevelProperties();
|
||||
LevelData worldProperties = destination.getLevelData();
|
||||
ServerPlayer player = ServerPlayer.class.cast(this);
|
||||
this.networkHandler.sendPacket(new PlayerRespawnS2CPacket(destination.getDimension(),
|
||||
destination.dimension(), BiomeAccess.hashSeed(destination.getSeed()),
|
||||
interactionManager.getGameMode(), interactionManager.getPreviousGameMode(),
|
||||
destination.isDebugWorld(), destination.isFlat(), true));
|
||||
this.networkHandler.sendPacket(
|
||||
new DifficultyS2CPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked()));
|
||||
PlayerManager playerManager = this.server.getPlayerManager();
|
||||
playerManager.sendCommandTree(player);
|
||||
serverWorld.removePlayer(player);
|
||||
this.networkHandler.send(new ClientboundRespawnPacket(destination.dimensionType(), destination.dimension(), BiomeManager.obfuscateSeed(destination.getSeed()),
|
||||
interactionManager.getGameModeForPlayer(),interactionManager.getPreviousGameModeForPlayer(), destination.isDebug(), destination.isFlat(), true));
|
||||
this.networkHandler.send(new ClientboundChangeDifficultyPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked()));
|
||||
PlayerList playerManager = this.server.getPlayerList();
|
||||
playerManager.sendPlayerPermissionLevel(player);
|
||||
serverWorld.removePlayerImmediately(player);
|
||||
this.removed = false;
|
||||
TeleportTarget teleportTarget = this.getTeleportTarget(destination);
|
||||
PortalInfo teleportTarget = this.findDimensionEntryPoint(destination);
|
||||
if (teleportTarget != null) {
|
||||
serverWorld.getProfiler().push("moving");
|
||||
serverWorld.getProfiler().pop();
|
||||
serverWorld.getProfiler().push("placing");
|
||||
this.setWorld(destination);
|
||||
destination.onPlayerChangeDimension(player);
|
||||
this.setRotation(teleportTarget.yaw, teleportTarget.pitch);
|
||||
this.refreshPositionAfterTeleport(teleportTarget.position.x, teleportTarget.position.y,
|
||||
teleportTarget.position.z);
|
||||
this.setLevel(destination);
|
||||
destination.addDuringPortalTeleport(player);
|
||||
this.setRot(teleportTarget.yRot, teleportTarget.xRot);
|
||||
this.moveTo(teleportTarget.pos.x, teleportTarget.pos.y, teleportTarget.pos.z);
|
||||
serverWorld.getProfiler().pop();
|
||||
this.worldChanged(serverWorld);
|
||||
this.interactionManager.setWorld(destination);
|
||||
this.networkHandler.sendPacket(new PlayerAbilitiesS2CPacket(this.abilities));
|
||||
playerManager.sendWorldInfo(player, destination);
|
||||
playerManager.sendPlayerStatus(player);
|
||||
this.interactionManager.setLevel(destination);
|
||||
this.networkHandler.send(new ClientboundPlayerAbilitiesPacket(this.abilities));
|
||||
playerManager.sendLevelInfo(player, destination);
|
||||
playerManager.sendAllPlayerInfo(player);
|
||||
|
||||
for (MobEffectInstance statusEffectInstance : this.getMobEffects()) {
|
||||
this.networkHandler.sendPacket(new EntityMobEffectS2CPacket(getEntityId(), statusEffectInstance));
|
||||
for (MobEffectInstance statusEffectInstance : this.getActiveEffects()) {
|
||||
this.networkHandler.send(new ClientboundUpdateMobEffectPacket(getId(), statusEffectInstance));
|
||||
}
|
||||
|
||||
this.networkHandler.sendPacket(new WorldEventS2CPacket(1032, BlockPos.ORIGIN, 0, false));
|
||||
this.networkHandler.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false));
|
||||
this.syncedExperience = -1;
|
||||
this.syncedHealth = -1.0F;
|
||||
this.syncedFoodLevel = -1;
|
||||
|
@ -130,7 +124,7 @@ public abstract class ServerPlayerEntityMixin extends Player implements Teleport
|
|||
|
||||
@Shadow
|
||||
@Override
|
||||
protected abstract TeleportTarget getTeleportTarget(ServerLevel destination);
|
||||
protected abstract PortalInfo findDimensionEntryPoint(ServerLevel destination);
|
||||
|
||||
@Override
|
||||
public void beSetExitPos(BlockPos pos) {
|
||||
|
|
|
@ -13,19 +13,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.WorldGenerationProgressListener;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.world.level.CustomSpawner;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.gen.Spawner;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.ServerWorldProperties;
|
||||
import net.minecraft.world.level.storage.LevelStorage;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.util.DataFixerUtil;
|
||||
import ru.betterend.util.WorldDataUtil;
|
||||
|
@ -36,34 +36,31 @@ public class ServerWorldMixin {
|
|||
private static final int DEV_VERSION = be_getVersionInt("63.63.63");
|
||||
private static final int FIX_VERSION = DEV_VERSION;
|
||||
private static String lastWorld = null;
|
||||
|
||||
|
||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||
private void be_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session,
|
||||
ServerWorldProperties properties, ResourceKey<Level> registryKey, DimensionType dimensionType,
|
||||
WorldGenerationProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator,
|
||||
boolean debugWorld, long l, List<Spawner> list, boolean bl, CallbackInfo info) {
|
||||
if (lastWorld != null && lastWorld.equals(session.getDirectoryName())) {
|
||||
private void be_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorageSource.LevelStorageAccess session, ServerLevelData properties, ResourceKey<Level> registryKey, DimensionType dimensionType, ChunkProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<CustomSpawner> list, boolean bl, CallbackInfo info) {
|
||||
if (lastWorld != null && lastWorld.equals(session.getLevelId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastWorld = session.getDirectoryName();
|
||||
|
||||
|
||||
lastWorld = session.getLevelId();
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
ServerLevel world = (ServerLevel) (Object) this;
|
||||
File dir = session.getWorldDirectory(world.dimension());
|
||||
File dir = session.getDimensionPath(world.dimension());
|
||||
if (!new File(dir, "level.dat").exists()) {
|
||||
dir = dir.getParentFile();
|
||||
}
|
||||
File data = new File(dir, "data/betterend_data.nbt");
|
||||
|
||||
|
||||
ModMetadata meta = FabricLoader.getInstance().getModContainer(BetterEnd.MOD_ID).get().getMetadata();
|
||||
int version = BetterEnd.isDevEnvironment() ? DEV_VERSION : be_getVersionInt(meta.getVersion().toString());
|
||||
|
||||
|
||||
WorldDataUtil.load(data);
|
||||
CompoundTag root = WorldDataUtil.getRootTag();
|
||||
int dataVersion = be_getVersionInt(root.getString("version"));
|
||||
GeneratorOptions.setPortalPos(NbtHelper.toBlockPos(root.getCompound("portal")));
|
||||
|
||||
GeneratorOptions.setPortalPos(NbtUtils.readBlockPos(root.getCompound("portal")));
|
||||
|
||||
if (dataVersion < version) {
|
||||
if (version < FIX_VERSION) {
|
||||
DataFixerUtil.fixData(data.getParentFile());
|
||||
|
@ -82,7 +79,7 @@ public class ServerWorldMixin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int be_getVersionInt(String version) {
|
||||
if (version.isEmpty()) {
|
||||
return 0;
|
||||
|
@ -90,11 +87,12 @@ public class ServerWorldMixin {
|
|||
try {
|
||||
String[] values = version.split("\\.");
|
||||
return Integer.parseInt(values[0]) << 12 | Integer.parseInt(values[1]) << 6 | Integer.parseInt(values[1]);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String be_getVersionString(int version) {
|
||||
int a = (version >> 12) & 63;
|
||||
int b = (version >> 6) & 63;
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import net.minecraft.world.entity.monster.Slime;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.minecraft.world.entity.mob.SlimeEntity;
|
||||
import ru.betterend.interfaces.ISlime;
|
||||
|
||||
@Mixin(SlimeEntity.class)
|
||||
@Mixin(Slime.class)
|
||||
public class SlimeEntityMixin implements ISlime {
|
||||
@Shadow
|
||||
protected void setSize(int size, boolean heal) {
|
||||
}
|
||||
|
||||
protected void setSize(int size, boolean heal) {}
|
||||
|
||||
@Override
|
||||
public void beSetSlimeSize(int size, boolean heal) {
|
||||
setSize(size, heal);
|
||||
|
|
|
@ -3,28 +3,25 @@ package ru.betterend.mixin.common;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagGroupLoader;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import ru.betterend.util.TagHelper;
|
||||
|
||||
@Mixin(TagGroupLoader.class)
|
||||
@Mixin(TagLoader.class)
|
||||
public class TagGroupLoaderMixin {
|
||||
|
||||
|
||||
@Shadow
|
||||
private String entryType;
|
||||
|
||||
|
||||
@Inject(method = "prepareReload", at = @At("RETURN"), cancellable = true)
|
||||
public void be_prepareReload(ResourceManager manager, Executor prepareExecutor,
|
||||
CallbackInfoReturnable<CompletableFuture<Map<ResourceLocation, Tag.Builder>>> info) {
|
||||
public void be_prepareReload(ResourceManager manager, Executor prepareExecutor, CallbackInfoReturnable<CompletableFuture<Map<ResourceLocation, Tag.Builder>>> info) {
|
||||
CompletableFuture<Map<ResourceLocation, Tag.Builder>> future = info.getReturnValue();
|
||||
info.setReturnValue(CompletableFuture.supplyAsync(() -> {
|
||||
Map<ResourceLocation, Tag.Builder> map = future.join();
|
||||
|
|
|
@ -19,21 +19,20 @@ import ru.betterend.interfaces.IBiomeList;
|
|||
@Mixin(value = WeightedBiomePicker.class, remap = false)
|
||||
public class WeightedBiomePickerMixin implements IBiomeList {
|
||||
private List<ResourceKey<Biome>> biomes = Lists.newArrayList();
|
||||
|
||||
|
||||
@Inject(method = "addBiome", at = @At("TAIL"))
|
||||
private void be_addBiome(final ResourceKey<Biome> biome, final double weight, CallbackInfo info) {
|
||||
if (be_isCorrectPicker((WeightedBiomePicker) (Object) this)) {
|
||||
biomes.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ResourceKey<Biome>> getBiomes() {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
|
||||
private boolean be_isCorrectPicker(WeightedBiomePicker picker) {
|
||||
return picker == InternalBiomeData.getEndBiomesMap().get(Biomes.SMALL_END_ISLANDS)
|
||||
|| picker == InternalBiomeData.getEndBarrensMap().get(Biomes.END_BARRENS);
|
||||
return picker == InternalBiomeData.getEndBiomesMap().get(Biomes.SMALL_END_ISLANDS) || picker == InternalBiomeData.getEndBarrensMap().get(Biomes.END_BARRENS);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue