Start migration

This commit is contained in:
Aleksey 2021-04-08 21:55:07 +03:00
parent 6630ce0cab
commit 47ed597358
491 changed files with 12045 additions and 11953 deletions

View file

@ -16,13 +16,13 @@ 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.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
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.util.Identifier;
import net.minecraft.resources.ResourceLocation;
import ru.betterend.interfaces.AnvilScreenHandlerExtended;
@Mixin(AnvilScreen.class)
@ -30,12 +30,12 @@ public class AnvilScreenMixin extends ForgingScreen<AnvilScreenHandler> {
@Shadow
private TextFieldWidget nameField;
private final List<AbstractButtonWidget> be_buttons = Lists.newArrayList();
private AnvilScreenHandlerExtended anvilHandler;
public AnvilScreenMixin(AnvilScreenHandler handler, PlayerInventory playerInventory, Text title,
Identifier texture) {
ResourceLocation texture) {
super(handler, playerInventory, title, texture);
}
@ -43,19 +43,19 @@ public class AnvilScreenMixin extends ForgingScreen<AnvilScreenHandler> {
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()));
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()));
}
@Inject(method = "renderForeground", at = @At("TAIL"))
protected void be_renderForeground(MatrixStack 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) {
AnvilScreenHandlerExtended anvilHandler = (AnvilScreenHandlerExtended) handler;
@ -71,15 +71,15 @@ public class AnvilScreenMixin extends ForgingScreen<AnvilScreenHandler> {
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) {

View file

@ -11,15 +11,15 @@ import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.render.BackgroundRenderer;
import net.minecraft.client.render.Camera;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.effect.StatusEffectInstance;
import net.minecraft.world.entity.effect.StatusEffects;
import net.minecraft.fluid.FluidState;
import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biome.Category;
import ru.betterend.client.ClientOptions;
@ -33,23 +33,25 @@ public class BackgroundRendererMixin {
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, ClientWorld world, int i, float f, CallbackInfo info) {
private static void be_onRender(Camera camera, float tickDelta, ClientLevel world, int i, float f,
CallbackInfo info) {
long l = Util.getMeasuringTimeMs() - time;
time += l;
lerp += l * 0.001F;
if (lerp > 1) lerp = 1;
if (lerp > 1)
lerp = 1;
FluidState fluidState = camera.getSubmergedFluidState();
if (fluidState.isEmpty() && world.getRegistryKey().equals(World.END)) {
if (fluidState.isEmpty() && world.dimension().equals(Level.END)) {
Entity entity = camera.getFocusedEntity();
boolean skip = false;
if (entity instanceof LivingEntity) {
@ -62,20 +64,21 @@ 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) {
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()) {
EndBiome endBiome = EndBiomes.getRenderBiome(biome);
if (fogDensity == 0) {
fogDensity = endBiome.getFogDensity();
lastFogDensity = fogDensity;
@ -85,12 +88,12 @@ public class BackgroundRendererMixin {
fogDensity = endBiome.getFogDensity();
lerp = 0;
}
float fog = MathHelper.lerp(lerp, lastFogDensity, fogDensity);
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;
StatusEffectInstance effect = le.getStatusEffect(StatusEffects.BLINDNESS);
@ -100,19 +103,17 @@ public class BackgroundRendererMixin {
start = 0;
end *= 0.03F;
BackgroundInfo.blindness = 1;
}
else {
} else {
float delta = (float) duration / 20F;
BackgroundInfo.blindness = delta;
start = MathHelper.lerp(delta, start, 0);
end = MathHelper.lerp(delta, end, end * 0.03F);
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);

View file

@ -10,9 +10,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.color.world.BiomeColors;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.Direction;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.BlockRenderView;
import ru.betterend.client.ClientOptions;
import ru.betterend.registry.EndBlocks;
@ -25,17 +25,17 @@ 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) {
if (ClientOptions.useSulfurWaterColor()) {
BlockRenderView view = HAS_SODIUM ? MinecraftClient.getInstance().world : world;
Mutable mut = new Mutable();
MutableBlockPos mut = new MutableBlockPos();
mut.setY(pos.getY());
for (int i = 0; i < OFFSETS.length; i++) {
mut.setX(pos.getX() + OFFSETS[i].x);
mut.setZ(pos.getZ() + OFFSETS[i].y);
if ((view.getBlockState(mut).isOf(EndBlocks.BRIMSTONE))) {
if ((view.getBlockState(mut).is(EndBlocks.BRIMSTONE))) {
info.setReturnValue(i < 16 ? STREAM_COLOR : POISON_COLOR);
info.cancel();
return;
@ -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,7 +55,7 @@ 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];

View file

@ -6,23 +6,22 @@ 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.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.world.ClientWorld;
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
{
public class ClientPlayNetworkHandlerMixin {
@Shadow
private MinecraftClient client;
@Shadow
private ClientWorld world;
private ClientLevel world;
@Inject(method = "onSignEditorOpen", at = @At(value = "HEAD"), cancellable = true)
public void be_openSignEditor(SignEditorOpenS2CPacket packet, CallbackInfo info) {

View file

@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.recipebook.ClientRecipeBook;
import net.minecraft.client.recipebook.RecipeBookGroup;
import net.minecraft.recipe.Recipe;
import net.minecraft.world.item.crafting.Recipe;
import ru.betterend.interfaces.BetterEndRecipe;
import ru.betterend.recipe.builders.AlloyingRecipe;

View file

@ -7,22 +7,22 @@ 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.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.EnchantingTableBlock;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
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)
public abstract class EnchantingTableBlockMixin extends Block {
public EnchantingTableBlockMixin(Settings settings) {
public EnchantingTableBlockMixin(Properties settings) {
super(settings);
}
@Inject(method = "randomDisplayTick", at = @At(value = "TAIL"))
private void be_onRandomDisplayTick(BlockState state, World world, BlockPos pos, Random random, CallbackInfo info) {
@Inject(method = "animateTick", 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) {
if (px > -2 && px < 2 && pz == -1) {
@ -30,12 +30,14 @@ public abstract class EnchantingTableBlockMixin extends Block {
}
if (random.nextInt(16) == 0) {
for (int py = 0; py <= 1; ++py) {
BlockPos blockPos = pos.add(px, py, pz);
BlockPos blockPos = pos.offset(px, py, pz);
if (world.getBlockState(blockPos).isIn(EndTags.BOOKSHELVES)) {
if (!world.isAir(pos.add(px / 2, 0, pz / 2))) {
if (!world.isAir(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);
}
}
}

View file

@ -17,10 +17,10 @@ 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.world.ClientWorld;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.sound.MusicSound;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.core.Registry;
import net.minecraft.world.level.Level;
import ru.betterend.interfaces.IColorProvider;
import ru.betterend.util.MHelper;
@ -28,17 +28,17 @@ import ru.betterend.util.MHelper;
public class MinecraftClientMixin {
@Shadow
public ClientPlayerEntity player;
@Shadow
public Screen currentScreen;
@Shadow
@Final
public InGameHud inGameHud;
@Shadow
public ClientWorld world;
public ClientLevel world;
@Shadow
@Final
private BlockColors blockColors;
@ -46,27 +46,28 @@ public class MinecraftClientMixin {
@Shadow
@Final
private ItemColors itemColors;
@Inject(method = "<init>*", at = @At("TAIL"))
private void be_onInit(RunArgs args, CallbackInfo info) {
Registry.BLOCK.forEach(block -> {
if (block instanceof IColorProvider) {
IColorProvider provider = (IColorProvider) block;
blockColors.registerColorProvider(provider.getProvider(), block);
blockColors.registerColorProvider(provider.getBlockProvider(), 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.getRegistryKey() == World.END) {
if (this.inGameHud.getBossBarHud().shouldPlayDragonMusic() && MHelper.lengthSqr(this.player.getX(), this.player.getZ()) < 250000) {
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);
} else {
MusicSound sound = (MusicSound) this.world.getBiomeAccess().method_27344(this.player.getBlockPos())
.getMusic().orElse(MusicType.END);
info.setReturnValue(sound);
}
info.cancel();

View file

@ -13,14 +13,14 @@ 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.block.Block;
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.item.Item;
import net.minecraft.world.item.Item;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
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;
@ -30,11 +30,11 @@ public class ModelLoaderMixin {
@Final
@Shadow
private ResourceManager resourceManager;
@Inject(method = "loadModelFromJson", at = @At("HEAD"), cancellable = true)
private void be_loadModelPattern(Identifier id, CallbackInfoReturnable<JsonUnbakedModel> info) {
private void be_loadModelPattern(ResourceLocation id, CallbackInfoReturnable<JsonUnbakedModel> info) {
if (id.getNamespace().equals(BetterEnd.MOD_ID)) {
Identifier modelId = new Identifier(id.getNamespace(), "models/" + id.getPath() + ".json");
ResourceLocation modelId = new ResourceLocation(id.getNamespace(), "models/" + id.getPath() + ".json");
JsonUnbakedModel model;
try (Resource resource = this.resourceManager.getResource(modelId)) {
Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8);
@ -44,7 +44,7 @@ public class ModelLoaderMixin {
} catch (Exception ex) {
String data[] = id.getPath().split("/");
if (data.length > 1) {
Identifier itemId = new Identifier(id.getNamespace(), data[1]);
ResourceLocation itemId = new ResourceLocation(id.getNamespace(), data[1]);
Optional<Block> block = Registry.BLOCK.getOrEmpty(itemId);
if (block.isPresent()) {
if (block.get() instanceof Patterned) {
@ -64,8 +64,8 @@ public class ModelLoaderMixin {
}
}
}
private JsonUnbakedModel be_getModel(String data[], Identifier id, Patterned patterned) {
private JsonUnbakedModel be_getModel(String data[], ResourceLocation id, Patterned patterned) {
String pattern;
if (id.getPath().contains("item")) {
pattern = patterned.getModelPattern(id.getPath());
@ -78,14 +78,16 @@ public class ModelLoaderMixin {
}
JsonUnbakedModel model = JsonUnbakedModel.deserialize(pattern);
model.id = id.toString();
return model;
}
@ModifyVariable(method = "loadModel", ordinal = 2, at = @At(value = "INVOKE"))
public Identifier be_SwitchModel(Identifier id) {
if (GeneratorOptions.changeChorusPlant() && id.getNamespace().equals("minecraft") && id.getPath().startsWith("blockstates/") && id.getPath().contains("chorus") && !id.getPath().contains("custom_")) {
id = new Identifier(id.getPath().replace("chorus", "custom_chorus"));
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_")) {
id = new ResourceLocation(id.getPath().replace("chorus", "custom_chorus"));
}
return id;
}

View file

@ -10,17 +10,18 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.google.gson.Gson;
import net.minecraft.block.Block;
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)
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().getDefaultState().getBlock();
private static void be_deserializeBlockState(ModelVariantMap.DeserializationContext context, Reader reader,
CallbackInfoReturnable<ModelVariantMap> info) {
Block block = context.getStateFactory().defaultBlockState().getBlock();
if (block instanceof BlockPatterned) {
String pattern = ((BlockPatterned) block).getStatesPattern(reader);
Gson gson = ContextGsonAccessor.class.cast(context).getGson();

View file

@ -14,8 +14,8 @@ 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.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import ru.betterend.client.ClientOptions;
@Mixin(MusicTracker.class)
@ -23,21 +23,21 @@ public class MusicTrackerMixin {
@Shadow
@Final
private MinecraftClient 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()) {
@ -67,32 +67,33 @@ public class MusicTrackerMixin {
time = 0;
srcVolume = -1;
this.client.getSoundManager().stop(this.current);
this.timeUntilNextSong = MathHelper.nextInt(this.random, 0, musicSound.getMinDelay() / 2);
this.timeUntilNextSong = Mth.nextInt(this.random, 0, musicSound.getMinDelay() / 2);
this.current = null;
}
if (this.current == null && this.timeUntilNextSong-- <= 0) {
this.play(musicSound);
}
info.cancel();
}
else {
} else {
volume = 1;
}
}
}
private boolean be_isInEnd() {
return client.world != null && client.world.getRegistryKey().equals(World.END);
return client.world != null && client.world.dimension().equals(Level.END);
}
private boolean be_shouldChangeSound(MusicSound musicSound) {
return current != null && !musicSound.getSound().getId().equals(this.current.getId()) && musicSound.shouldReplaceCurrentMusic();
return current != null && !musicSound.getSound().getId().equals(this.current.getId())
&& musicSound.shouldReplaceCurrentMusic();
}
private boolean be_checkNullSound(MusicSound musicSound) {
return musicSound != null && musicSound.getSound() != null;
}
@Shadow
public void play(MusicSound type) {}
public void play(MusicSound type) {
}
}

View file

@ -11,32 +11,29 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.google.common.collect.Lists;
import net.minecraft.block.Block;
import net.minecraft.world.level.block.Block;
import net.minecraft.resource.NamespaceResourceManager;
import net.minecraft.resource.Resource;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.Registry;
import ru.betterend.BetterEnd;
import ru.betterend.patterns.BlockPatterned;
@Mixin(NamespaceResourceManager.class)
public abstract class NamespaceResourceManagerMixin {
@Shadow
public abstract Resource getResource(Identifier id);
@Inject(method = "getAllResources", cancellable = true, at = @At(
value = "NEW",
target = "java/io/FileNotFoundException",
shift = Shift.BEFORE))
public void be_getStatesPattern(Identifier id, CallbackInfoReturnable<List<Resource>> info) {
public abstract Resource getResource(ResourceLocation id);
@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("/");
if (data.length > 1) {
Identifier blockId = BetterEnd.makeID(data[1].replace(".json", ""));
ResourceLocation blockId = BetterEnd.makeID(data[1].replace(".json", ""));
Block block = Registry.BLOCK.get(blockId);
if (block instanceof BlockPatterned) {
Identifier stateId = ((BlockPatterned) block).statePatternId();
ResourceLocation stateId = ((BlockPatterned) block).statePatternId();
try {
List<Resource> resources = Lists.newArrayList();
Resource stateRes = this.getResource(stateId);

View file

@ -26,8 +26,8 @@ import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.Identifier;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.math.Quaternion;
import ru.betterend.BetterEnd;
import ru.betterend.client.ClientOptions;
@ -36,12 +36,12 @@ import ru.betterend.util.MHelper;
@Mixin(WorldRenderer.class)
public class WorldRendererMixin {
private static final Identifier NEBULA_1 = BetterEnd.makeID("textures/sky/nebula_2.png");
private static final Identifier NEBULA_2 = BetterEnd.makeID("textures/sky/nebula_3.png");
private static final Identifier HORIZON = BetterEnd.makeID("textures/sky/nebula_1.png");
private static final Identifier STARS = BetterEnd.makeID("textures/sky/stars.png");
private static final Identifier FOG = BetterEnd.makeID("textures/sky/fog.png");
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,21 +60,21 @@ public class WorldRendererMixin {
private static float blind02;
private static float blind06;
private static boolean directOpenGL = false;
@Shadow
@Final
private MinecraftClient client;
@Shadow
@Final
private TextureManager textureManager;
@Shadow
private ClientWorld world;
private ClientLevel world;
@Shadow
private int ticks;
@Inject(method = "<init>*", at = @At("TAIL"))
private void be_onInit(MinecraftClient client, BufferBuilderStorage bufferBuilders, CallbackInfo info) {
be_initStars();
@ -87,103 +87,106 @@ 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) {
time = (ticks % 360000) * 0.000017453292F;
time2 = time * 2;
time3 = time * 3;
BackgroundRenderer.setFogBlack();
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();
}
float a = (BackgroundInfo.fog - 1F);
if (a > 0) {
if (a > 1) a = 1;
if (a > 1)
a = 1;
textureManager.bindTexture(FOG);
be_renderBuffer(matrices, fog, VertexFormats.POSITION_TEXTURE, BackgroundInfo.red, BackgroundInfo.green, BackgroundInfo.blue, a);
be_renderBuffer(matrices, fog, VertexFormats.POSITION_TEXTURE, 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();
}
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(MatrixStack 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();
buffer.draw(matrices.peek().getModel(), 7);
VertexBuffer.unbind();
format.endDrawing();
}
private void be_initStars() {
@ -197,8 +200,9 @@ 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();
}
@ -210,8 +214,9 @@ public class WorldRendererMixin {
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();
}
@ -223,8 +228,9 @@ public class WorldRendererMixin {
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();
}
@ -236,7 +242,7 @@ public class WorldRendererMixin {
return buffer;
}
private VertexBuffer be_buildBufferHorizon(BufferBuilder bufferBuilder, VertexBuffer buffer) {
if (buffer != null) {
buffer.close();
@ -249,7 +255,7 @@ public class WorldRendererMixin {
return buffer;
}
private VertexBuffer be_buildBufferFog(BufferBuilder bufferBuilder, VertexBuffer buffer) {
if (buffer != null) {
buffer.close();
@ -262,7 +268,7 @@ public class WorldRendererMixin {
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);
@ -305,7 +311,7 @@ public class WorldRendererMixin {
}
}
}
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);
@ -347,13 +353,13 @@ public class WorldRendererMixin {
double ah = ab * n + ae * o;
float texU = (pos >> 1) & 1;
float texV = (((pos + 1) >> 1) & 1) / 4F + minV;
pos ++;
pos++;
buffer.vertex(j + af, k + ad, l + ah).texture(texU, texV).next();
}
}
}
}
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);
@ -398,26 +404,26 @@ public class WorldRendererMixin {
double ah = ab * n + ae * o;
float texU = (pos >> 1) & 1;
float texV = ((pos + 1) >> 1) & 1;
pos ++;
pos++;
buffer.vertex(j + af, k + ad, l + ah).texture(texU, texV).next();
}
}
}
}
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 ++) {
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();

View file

@ -9,34 +9,35 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.google.common.collect.Lists;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.util.math.MathHelper;
import 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)
public abstract class AbstractBlockMixin {
@Inject(method = "getDroppedStacks", at = @At("HEAD"), cancellable = true)
public void be_getDroppedStacks(BlockState state, LootContext.Builder builder, CallbackInfoReturnable<List<ItemStack>> info) {
if (state.isOf(Blocks.GLOWSTONE)) {
ItemStack tool = builder.get(LootContextParameters.TOOL);
@Inject(method = "getDrops", 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) {
int min = 3;
int max = 4;
int count = 0;
int fortune = EnchantmentHelper.getLevel(Enchantments.FORTUNE, tool);
int fortune = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool);
if (fortune > 0) {
fortune /= Enchantments.FORTUNE.getMaxLevel();
min = MathHelper.clamp(min + fortune, min, max);
fortune /= Enchantments.BLOCK_FORTUNE.getMaxLevel();
min = Mth.clamp(min + fortune, min, max);
if (min == max) {
info.setReturnValue(Lists.newArrayList(new ItemStack(Items.GLOWSTONE_DUST, max)));
}

View file

@ -5,9 +5,9 @@ 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.block.AnvilBlock;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.IntProperty;
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 ru.betterend.blocks.basis.EndAnvilBlock;
@Mixin(AnvilBlock.class)
@ -15,7 +15,7 @@ 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) {
IntProperty destructionProperty = ((EndAnvilBlock) fallingState.getBlock()).getDestructionProperty();
IntegerProperty destructionProperty = ((EndAnvilBlock) fallingState.getBlock()).getDESTRUCTION();
int destruction = fallingState.get(destructionProperty);
try {
BlockState state = fallingState.with(destructionProperty, destruction + 1);

View file

@ -11,19 +11,19 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.AnvilBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.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.PlayerEntity;
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.tag.BlockTags;
import net.minecraft.tags.BlockTags;
import ru.betterend.blocks.basis.EndAnvilBlock;
import ru.betterend.interfaces.AnvilScreenHandlerExtended;
import ru.betterend.recipe.builders.AnvilRecipe;
@ -39,9 +39,9 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler imple
super(ScreenHandlerType.ANVIL, syncId, playerInventory, ScreenHandlerContext.EMPTY);
}
@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) {
@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) -> {
Block anvilBlock = world.getBlockState(blockPos).getBlock();
@ -55,17 +55,17 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler imple
this.anvilLevel = addProperty(anvilLevel);
}
}
@Shadow
public abstract void updateResult();
@Inject(method = "canTakeOutput", at = @At("HEAD"), cancellable = true)
protected void be_canTakeOutput(PlayerEntity player, boolean present, CallbackInfoReturnable<Boolean> info) {
if (be_currentRecipe != null) {
info.setReturnValue(be_currentRecipe.checkHammerDurability(input, player));
}
}
@Inject(method = "onTakeOutput", at = @At("HEAD"), cancellable = true)
protected void be_onTakeOutput(PlayerEntity player, ItemStack stack, CallbackInfoReturnable<ItemStack> info) {
if (be_currentRecipe != null) {
@ -74,13 +74,14 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler imple
this.onContentChanged(input);
this.context.run((world, blockPos) -> {
BlockState anvilState = world.getBlockState(blockPos);
if (!player.abilities.creativeMode && anvilState.isIn(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
if (!player.abilities.creativeMode && anvilState.isIn(BlockTags.ANVIL)
&& player.getRandom().nextFloat() < 0.12F) {
BlockState landingState = AnvilBlock.getLandingState(anvilState);
if (landingState == null) {
world.removeBlock(blockPos, false);
world.syncWorldEvent(1029, blockPos, 0);
} else {
world.setBlockState(blockPos, landingState, 2);
world.setBlockAndUpdate(blockPos, landingState, 2);
world.syncWorldEvent(1030, blockPos, 0);
}
} else {
@ -90,15 +91,15 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler imple
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);
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);
@ -110,14 +111,14 @@ 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(PlayerEntity player, int id) {
if (id == 0) {
@ -129,24 +130,25 @@ public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler imple
}
return super.onButtonClick(player, id);
}
private void be_updateResult() {
if (be_currentRecipe == null) return;
if (be_currentRecipe == null)
return;
this.output.setStack(0, be_currentRecipe.craft(input));
this.sendContentUpdates();
}
@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;

View file

@ -7,9 +7,9 @@ import org.spongepowered.asm.mixin.gen.Accessor;
import com.google.common.collect.Multimap;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ArmorItem;
import net.minecraft.world.entity.attribute.EntityAttribute;
import net.minecraft.world.entity.attribute.EntityAttributeModifier;
import net.minecraft.world.item.ArmorItem;
@Mixin(ArmorItem.class)
public interface ArmorItemAccessor {

View file

@ -4,8 +4,8 @@ import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.BiomeArray;
import ru.betterend.interfaces.IBiomeArray;
@ -39,7 +39,7 @@ public class BiomeArrayMixin implements IBiomeArray {
private int be_getArrayIndex(int biomeX, int biomeY, int biomeZ) {
int i = biomeX & HORIZONTAL_BIT_MASK;
int j = MathHelper.clamp(biomeY, 0, VERTICAL_BIT_MASK);
int j = Mth.clamp(biomeY, 0, VERTICAL_BIT_MASK);
int k = biomeZ & HORIZONTAL_BIT_MASK;
return j << HORIZONTAL_SECTION_COUNT + HORIZONTAL_SECTION_COUNT | k << HORIZONTAL_SECTION_COUNT | i;
}

View file

@ -7,16 +7,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.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.BoneMealItem;
import net.minecraft.item.ItemUsageContext;
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.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
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.biome.Biome.Category;
import ru.betterend.registry.EndBiomes;
import ru.betterend.registry.EndBlocks;
@ -28,32 +28,30 @@ import ru.betterend.world.biome.EndBiome;
@Mixin(BoneMealItem.class)
public class BoneMealItemMixin {
private static final Direction[] DIR = BlocksHelper.makeHorizontal();
private static final Mutable POS = new Mutable();
private static final MutableBlockPos POS = new MutableBlockPos();
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
private void be_onUse(ItemUsageContext context, CallbackInfoReturnable<ActionResult> info) {
World world = context.getWorld();
Level world = context.getLevel();
BlockPos blockPos = context.getBlockPos();
if (!world.isClient) {
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)) {
boolean consume = false;
if (world.getBlockState(blockPos).isOf(Blocks.END_STONE)) {
if (world.getBlockState(blockPos).is(Blocks.END_STONE)) {
BlockState nylium = beGetNylium(world, blockPos);
if (nylium != null) {
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);
}
}
@ -65,8 +63,7 @@ public class BoneMealItemMixin {
info.setReturnValue(ActionResult.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.cancel();
@ -74,8 +71,8 @@ public class BoneMealItemMixin {
}
}
}
private boolean beGrowGrass(World world, BlockPos pos) {
private boolean beGrowGrass(Level world, BlockPos pos) {
int y1 = pos.getY() + 3;
int y2 = pos.getY() - 3;
boolean result = false;
@ -86,7 +83,7 @@ public class BoneMealItemMixin {
POS.setZ(z);
for (int y = y1; y >= y2; y--) {
POS.setY(y);
BlockPos down = POS.down();
BlockPos down = POS.below();
if (world.isAir(POS) && !world.isAir(down)) {
BlockState grass = beGetGrassState(world, down);
if (grass != null) {
@ -99,8 +96,8 @@ public class BoneMealItemMixin {
}
return result;
}
private boolean beGrowWaterGrass(World world, BlockPos pos) {
private boolean beGrowWaterGrass(Level world, BlockPos pos) {
int y1 = pos.getY() + 3;
int y2 = pos.getY() - 3;
boolean result = false;
@ -111,8 +108,8 @@ public class BoneMealItemMixin {
POS.setZ(z);
for (int y = y1; y >= y2; y--) {
POS.setY(y);
BlockPos down = POS.down();
if (world.getBlockState(POS).isOf(Blocks.WATER) && world.getBlockState(down).isIn(EndTags.END_GROUND)) {
BlockPos down = POS.below();
if (world.getBlockState(POS).is(Blocks.WATER) && world.getBlockState(down).isIn(EndTags.END_GROUND)) {
BlockState grass = beGetWaterGrassState(world, down);
if (grass != null) {
BlocksHelper.setWithoutUpdate(world, POS, grass);
@ -124,27 +121,27 @@ public class BoneMealItemMixin {
}
return result;
}
private BlockState beGetGrassState(World world, BlockPos pos) {
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.getDefaultState();
return block == null ? null : block.defaultBlockState();
}
private BlockState beGetWaterGrassState(World world, BlockPos pos) {
private BlockState beGetWaterGrassState(Level world, BlockPos pos) {
EndBiome biome = EndBiomes.getFromBiome(world.getBiome(pos));
if (world.random.nextInt(16) == 0) {
return EndBlocks.CHARNIA_RED.getDefaultState();
}
else if (biome == EndBiomes.FOGGY_MUSHROOMLAND || biome == EndBiomes.MEGALAKE || biome == EndBiomes.MEGALAKE_GROVE) {
return world.random.nextBoolean() ? EndBlocks.CHARNIA_LIGHT_BLUE.getDefaultState() : EndBlocks.CHARNIA_LIGHT_BLUE.getDefaultState();
}
else if (biome == EndBiomes.AMBER_LAND) {
return world.random.nextBoolean() ? EndBlocks.CHARNIA_ORANGE.getDefaultState() : EndBlocks.CHARNIA_RED.getDefaultState();
}
else if (biome == EndBiomes.CHORUS_FOREST || biome == EndBiomes.SHADOW_FOREST) {
return EndBlocks.CHARNIA_PURPLE.getDefaultState();
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) {
return EndBlocks.CHARNIA_PURPLE.defaultBlockState();
}
return null;
}
@ -158,10 +155,10 @@ public class BoneMealItemMixin {
}
}
private BlockState beGetNylium(World world, BlockPos pos) {
private BlockState beGetNylium(Level world, BlockPos pos) {
beShuffle(world.random);
for (Direction dir : DIR) {
BlockState state = world.getBlockState(pos.offset(dir));
BlockState state = world.getBlockState(pos.relative(dir));
if (BlocksHelper.isEndNylium(state))
return state;
}

View file

@ -3,9 +3,9 @@ package ru.betterend.mixin.common;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.item.Item;
import net.minecraft.world.item.Item;
import net.minecraft.potion.Potion;
import net.minecraft.recipe.BrewingRecipeRegistry;
import net.minecraft.world.item.crafting.BrewingRecipeRegistry;
@Mixin(BrewingRecipeRegistry.class)
public interface BrewingAccessor {

View file

@ -11,20 +11,20 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ChorusFlowerBlock;
import net.minecraft.block.ChorusPlantBlock;
import net.minecraft.block.ShapeContext;
import net.minecraft.server.world.ServerWorld;
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.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
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;
@ -35,75 +35,80 @@ import ru.betterend.world.generator.GeneratorOptions;
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(Settings settings) {
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) {
if (world.getBlockState(pos.down()).isOf(EndBlocks.CHORUS_NYLIUM)) {
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, ServerWorld world, BlockPos pos, Random random, CallbackInfo info) {
if (world.getBlockState(pos.down()).isIn(EndTags.END_GROUND)) {
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) {
int i = state.get(ChorusFlowerBlock.AGE);
int i = state.getValue(ChorusFlowerBlock.AGE);
if (i < 5) {
this.grow(world, up, i + 1);
if (GeneratorOptions.changeChorusPlant()) {
BlocksHelper.setWithoutUpdate(world, pos, plantBlock.getDefaultState().with(ChorusPlantBlock.UP, true).with(ChorusPlantBlock.DOWN, true).with(BlocksHelper.ROOTS, true));
}
else {
BlocksHelper.setWithoutUpdate(world, pos, plantBlock.getDefaultState().with(ChorusPlantBlock.UP, true).with(ChorusPlantBlock.DOWN, true));
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));
}
info.cancel();
}
}
}
}
@Inject(method = "generate", at = @At("RETURN"), cancellable = true)
private static void beOnGenerate(WorldAccess world, BlockPos pos, Random random, int size, CallbackInfo info) {
private static void beOnGenerate(LevelAccessor world, BlockPos pos, Random random, int size, CallbackInfo info) {
BlockState state = world.getBlockState(pos);
if (GeneratorOptions.changeChorusPlant() && state.isOf(Blocks.CHORUS_PLANT)) {
if (GeneratorOptions.changeChorusPlant() && state.is(Blocks.CHORUS_PLANT)) {
BlocksHelper.setWithoutUpdate(world, pos, state.with(BlocksHelper.ROOTS, true));
}
}
@Shadow
private static boolean isSurroundedByAir(WorldView world, BlockPos pos, @Nullable Direction exceptDirection) { return false; }
private static boolean isSurroundedByAir(WorldView world, BlockPos pos, @Nullable Direction exceptDirection) {
return false;
}
@Shadow
private void grow(World world, BlockPos pos, int age) {}
private void grow(Level world, BlockPos pos, int age) {
}
@Shadow
private void die(World world, BlockPos pos) {}
private void die(Level world, BlockPos pos) {
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
if (GeneratorOptions.changeChorusPlant()) {
return state.get(ChorusFlowerBlock.AGE) == 5 ? SHAPE_HALF : SHAPE_FULL;
}
else {
return state.getValue(ChorusFlowerBlock.AGE) == 5 ? SHAPE_HALF : SHAPE_FULL;
} else {
return super.getOutlineShape(state, world, pos, context);
}
}
@Inject(method = "die", at = @At("HEAD"), cancellable = true)
private void beOnDie(World world, BlockPos pos, CallbackInfo info) {
BlockState down = world.getBlockState(pos.down());
if (down.isOf(Blocks.CHORUS_PLANT) || down.isIn(EndTags.GEN_TERRAIN)) {
world.setBlockState(pos, this.getDefaultState().with(Properties.AGE_5, 5), 2);
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);
}
info.cancel();

View file

@ -6,19 +6,19 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ChorusPlantBlock;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager;
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.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
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;
@ -27,39 +27,37 @@ import ru.betterend.world.generator.GeneratorOptions;
@Mixin(value = ChorusPlantBlock.class, priority = 100)
public abstract class ChorusPlantBlockMixin extends Block {
public ChorusPlantBlockMixin(Settings settings) {
public ChorusPlantBlockMixin(Properties settings) {
super(settings);
}
@Inject(method = "<init>*", at = @At("TAIL"))
private void beOnInit(AbstractBlock.Settings settings, CallbackInfo info) {
private void beOnInit(AbstractBlock.Properties settings, CallbackInfo info) {
if (GeneratorOptions.changeChorusPlant()) {
this.setDefaultState(this.getDefaultState().with(BlocksHelper.ROOTS, false));
this.setDefaultState(this.defaultBlockState().with(BlocksHelper.ROOTS, false));
}
}
@Inject(method = "appendProperties", at = @At("TAIL"))
private void beAddProperties(StateManager.Builder<Block, BlockState> builder, CallbackInfo info) {
@Inject(method = "createBlockStateDefinition", 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) {
BlockState plant = info.getReturnValue();
if (plant.isOf(Blocks.CHORUS_PLANT)) {
if (world.getBlockState(pos.down()).isIn(EndTags.END_GROUND)) {
if (plant.is(Blocks.CHORUS_PLANT)) {
if (world.getBlockState(pos.below()).isIn(EndTags.END_GROUND)) {
if (GeneratorOptions.changeChorusPlant()) {
info.setReturnValue(plant.with(Properties.DOWN, true).with(BlocksHelper.ROOTS, true));
}
else {
} else {
info.setReturnValue(plant.with(Properties.DOWN, true));
}
info.cancel();
}
else {
} else {
if (GeneratorOptions.changeChorusPlant()) {
info.setReturnValue(plant.with(BlocksHelper.ROOTS, false));
}
@ -67,30 +65,29 @@ public abstract class ChorusPlantBlockMixin extends Block {
}
}
}
@Inject(method = "canPlaceAt", at = @At("HEAD"), cancellable = true)
private void beCanPlace(BlockState state, WorldView world, BlockPos pos, CallbackInfoReturnable<Boolean> info) {
BlockState down = world.getBlockState(pos.down());
if (down.isOf(EndBlocks.CHORUS_NYLIUM) || down.isOf(Blocks.END_STONE)) {
BlockState down = world.getBlockState(pos.below());
if (down.is(EndBlocks.CHORUS_NYLIUM) || down.is(Blocks.END_STONE)) {
info.setReturnValue(true);
info.cancel();
}
}
@Inject(method = "getStateForNeighborUpdate", at = @At("RETURN"), cancellable = true)
private void beStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom, CallbackInfoReturnable<BlockState> info) {
@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) {
BlockState plant = info.getReturnValue();
if (plant.isOf(Blocks.CHORUS_PLANT)) {
if (world.getBlockState(pos.down()).isIn(EndTags.END_GROUND)) {
if (plant.is(Blocks.CHORUS_PLANT)) {
if (world.getBlockState(pos.below()).isIn(EndTags.END_GROUND)) {
if (GeneratorOptions.changeChorusPlant()) {
plant = plant.with(Properties.DOWN, true).with(BlocksHelper.ROOTS, true);
}
else {
} else {
plant = plant.with(Properties.DOWN, true);
}
info.cancel();
}
else {
} else {
if (GeneratorOptions.changeChorusPlant()) {
plant = plant.with(BlocksHelper.ROOTS, false);
}
@ -100,17 +97,17 @@ 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();
World world = ctx.getWorld();
Level world = ctx.getLevel();
BlockState plant = info.getReturnValue();
if (ctx.canPlace() && plant.isOf(Blocks.CHORUS_PLANT) && world.getBlockState(pos.down()).isIn(EndTags.END_GROUND)) {
if (ctx.canPlace() && plant.is(Blocks.CHORUS_PLANT)
&& world.getBlockState(pos.below()).isIn(EndTags.END_GROUND)) {
if (GeneratorOptions.changeChorusPlant()) {
info.setReturnValue(plant.with(BlocksHelper.ROOTS, true).with(Properties.DOWN, true));
}
else {
} else {
info.setReturnValue(plant.with(Properties.DOWN, true));
}
info.cancel();

View file

@ -7,11 +7,11 @@ 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.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ChorusFlowerBlock;
import net.minecraft.block.ConnectingBlock;
import net.minecraft.util.math.BlockPos;
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.StructureWorldAccess;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.ChorusPlantFeature;
@ -24,16 +24,19 @@ import ru.betterend.world.generator.GeneratorOptions;
@Mixin(ChorusPlantFeature.class)
public class ChorusPlantFeatureMixin {
@Inject(method = "generate", at = @At("HEAD"), cancellable = true)
private void be_onGenerate(StructureWorldAccess structureWorldAccess, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, DefaultFeatureConfig defaultFeatureConfig, CallbackInfoReturnable<Boolean> info) {
if (structureWorldAccess.isAir(blockPos) && structureWorldAccess.getBlockState(blockPos.down()).isOf(EndBlocks.CHORUS_NYLIUM)) {
private void be_onGenerate(StructureWorldAccess structureWorldAccess, ChunkGenerator chunkGenerator, Random random,
BlockPos blockPos, DefaultFeatureConfig 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));
BlockState bottom = structureWorldAccess.getBlockState(blockPos);
if (bottom.isOf(Blocks.CHORUS_PLANT)) {
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.with(BlocksHelper.ROOTS, true).with(ConnectingBlock.DOWN, true));
} else {
BlocksHelper.setWithoutUpdate(structureWorldAccess, blockPos,
bottom.with(ConnectingBlock.DOWN, true));
}
}
info.setReturnValue(true);

View file

@ -3,8 +3,8 @@ package ru.betterend.mixin.common;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.block.ComposterBlock;
import net.minecraft.item.ItemConvertible;
import net.minecraft.world.level.block.ComposterBlock;
import net.minecraft.world.item.ItemConvertible;
@Mixin(ComposterBlock.class)
public interface ComposterBlockAccessor {

View file

@ -7,14 +7,13 @@ 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.block.CraftingTableBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.level.block.CraftingTableBlock;
import net.minecraft.world.entity.player.PlayerEntity;
import net.minecraft.screen.CraftingScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
@Mixin(CraftingScreenHandler.class)
public abstract class CraftingScreenHandlerMixin
{
public abstract class CraftingScreenHandlerMixin {
@Shadow
@Final
private ScreenHandlerContext context;

View file

@ -5,9 +5,9 @@ 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.registry.Registry;
import net.minecraft.core.Registry;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
import net.minecraft.world.gen.chunk.NoiseChunkGenerator;
@ -17,13 +17,15 @@ 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) {
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);
}));
info.cancel();
}
@Inject(method = "hasEnderDragonFight", at = @At("HEAD"), cancellable = true)
private void be_hasEnderDragonFight(CallbackInfoReturnable<Boolean> info) {
if (!GeneratorOptions.hasDragonFights()) {

View file

@ -10,16 +10,16 @@ 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.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentLevelEntry;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.EnchantmentLevelEntry;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
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.util.registry.Registry;
import net.minecraft.core.Registry;
import ru.betterend.registry.EndTags;
@Mixin(EnchantmentScreenHandler.class)
@ -67,7 +67,8 @@ public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
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 ((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)) {
++i;
}
@ -100,7 +101,8 @@ 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.calculateRequiredExperienceLevel(this.random, j, i,
itemStack);
this.enchantmentId[j] = -1;
this.enchantmentLevel[j] = -1;
if (this.enchantmentPower[j] < j + 1) {
@ -110,10 +112,13 @@ 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<EnchantmentLevelEntry> 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);
EnchantmentLevelEntry enchantmentLevelEntry = (EnchantmentLevelEntry) list
.get(this.random.nextInt(list.size()));
this.enchantmentId[j] = Registry.ENCHANTMENT
.getRawId(enchantmentLevelEntry.enchantment);
this.enchantmentLevel[j] = enchantmentLevelEntry.level;
}
}
@ -121,8 +126,7 @@ public abstract class EnchantmentScreenHandlerMixin extends ScreenHandler {
this.sendContentUpdates();
});
}
else {
} else {
for (int i = 0; i < 3; ++i) {
this.enchantmentPower[i] = 0;
this.enchantmentId[i] = -1;

View file

@ -13,7 +13,7 @@ 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.util.math.BlockPos;
import net.minecraft.core.BlockPos;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.gen.chunk.ChunkGenerator;
@ -29,16 +29,17 @@ public class EndPortalFeatureMixin {
@Final
@Shadow
private boolean open;
@Inject(method = "generate", at = @At("HEAD"), cancellable = true)
private void bePortalGenerate(StructureWorldAccess world, ChunkGenerator generator, Random random, BlockPos blockPos, DefaultFeatureConfig config, CallbackInfoReturnable<Boolean> info) {
private void bePortalGenerate(StructureWorldAccess world, ChunkGenerator generator, Random random,
BlockPos blockPos, DefaultFeatureConfig 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"));
Structure 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);
@ -46,12 +47,12 @@ public class EndPortalFeatureMixin {
info.cancel();
}
}
@ModifyVariable(method = "generate", ordinal = 0, at = @At("HEAD"))
private BlockPos be_setPosOnGround(BlockPos blockPos, StructureWorldAccess world) {
return be_updatePos(blockPos, world);
}
private BlockPos be_updatePos(BlockPos blockPos, StructureWorldAccess world) {
if (GeneratorOptions.useNewGenerator()) {
BlockPos pos = GeneratorOptions.getPortalPos();

View file

@ -8,17 +8,17 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.PaneBlock;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.decoration.EndCrystalEntity;
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.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.MathHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.Heightmap.Type;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.StructureWorldAccess;
@ -34,54 +34,58 @@ import ru.betterend.world.generator.GeneratorOptions;
@Mixin(EndSpikeFeature.class)
public class EndSpikeFeatureMixin {
@Inject(method = "generate", at = @At("HEAD"), cancellable = true)
private void beSpikeGenerate(StructureWorldAccess structureWorldAccess, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, EndSpikeFeatureConfig endSpikeFeatureConfig, CallbackInfoReturnable<Boolean> info) {
private void beSpikeGenerate(StructureWorldAccess structureWorldAccess, ChunkGenerator chunkGenerator,
Random random, BlockPos blockPos, EndSpikeFeatureConfig endSpikeFeatureConfig,
CallbackInfoReturnable<Boolean> info) {
if (!GeneratorOptions.hasPillars()) {
info.setReturnValue(false);
}
}
@Inject(method = "generateSpike", at = @At("HEAD"), cancellable = true)
private void be_generateSpike(ServerWorldAccess world, Random random, EndSpikeFeatureConfig config, EndSpikeFeature.Spike spike, CallbackInfo info) {
private void be_generateSpike(ServerWorldAccess world, Random random, EndSpikeFeatureConfig config,
EndSpikeFeature.Spike 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).sampleHeightmap(Type.WORLD_SURFACE, x & 15, z);
if (!haveValue) {
pillar.putInt(pillarID, minY);
WorldDataUtil.saveFile();
}
}
else {
} else {
minY = world.getChunk(x >> 4, z >> 4).sampleHeightmap(Type.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" : "")));
Structure 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);
int r2 = radius * radius + 1;
Mutable mut = new Mutable();
MutableBlockPos mut = new MutableBlockPos();
for (int px = -radius; px <= radius; px++) {
mut.setX(x + px);
int x2 = px * px;
@ -92,10 +96,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);
}
}
@ -103,11 +107,10 @@ public class EndSpikeFeatureMixin {
}
}
}
}
else {
} else {
minY -= 15;
int r2 = radius * radius + 1;
Mutable mut = new Mutable();
MutableBlockPos mut = new MutableBlockPos();
for (int px = -radius; px <= radius; px++) {
mut.setX(x + px);
int x2 = px * px;
@ -128,25 +131,30 @@ 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());
crystal.setInvulnerable(config.isCrystalInvulnerable());
crystal.refreshPositionAndAngles(x + 0.5D, maxY + 1, z + 0.5D, random.nextFloat() * 360.0F, 0.0F);
world.spawnEntity(crystal);
if (spike.isGuarded()) {
for (int px = -2; px <= 2; ++px) {
boolean bl = MathHelper.abs(px) == 2;
boolean bl = Mth.abs(px) == 2;
for (int pz = -2; pz <= 2; ++pz) {
boolean bl2 = MathHelper.abs(pz) == 2;
boolean bl2 = Mth.abs(pz) == 2;
for (int py = 0; py <= 3; ++py) {
boolean bl3 = py == 3;
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.getDefaultState().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().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);
}
}
}
@ -156,7 +164,7 @@ public class EndSpikeFeatureMixin {
info.cancel();
}
private boolean be_radiusInRange(int radius) {
return radius > 1 && radius < 6;
}

View file

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

View file

@ -7,13 +7,13 @@ 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.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
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.World;
import net.minecraft.world.level.Level;
import ru.betterend.interfaces.TeleportingEntity;
@Mixin(Entity.class)
@ -26,26 +26,26 @@ public abstract class EntityMixin implements TeleportingEntity {
@Shadow
public boolean removed;
@Shadow
public World world;
public Level world;
@Final
@Shadow
public abstract void detach();
@Shadow
public abstract Vec3d getVelocity();
@Shadow
public abstract EntityType<?> getType();
@Shadow
protected abstract TeleportTarget getTeleportTarget(ServerWorld destination);
protected abstract TeleportTarget getTeleportTarget(ServerLevel destination);
private BlockPos exitPos;
@Inject(method = "moveToWorld", at = @At("HEAD"), cancellable = true)
public void be_moveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity> info) {
if (!removed && beCanTeleport() && world instanceof ServerWorld) {
public void be_moveToWorld(ServerLevel destination, CallbackInfoReturnable<Entity> info) {
if (!removed && beCanTeleport() && world instanceof ServerLevel) {
this.detach();
this.world.getProfiler().push("changeDimension");
this.world.getProfiler().push("reposition");
@ -55,13 +55,14 @@ public abstract class EntityMixin implements TeleportingEntity {
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.refreshPositionAndAngles(teleportTarget.position.x, teleportTarget.position.y,
teleportTarget.position.z, teleportTarget.yaw, entity.pitch);
entity.setVelocity(teleportTarget.velocity);
destination.onDimensionChanged(entity);
}
this.removed = true;
this.world.getProfiler().pop();
((ServerWorld) world).resetIdleTimeout();
((ServerLevel) world).resetIdleTimeout();
destination.resetIdleTimeout();
this.world.getProfiler().pop();
this.beResetExitPos();
@ -69,11 +70,12 @@ public abstract class EntityMixin implements TeleportingEntity {
}
}
}
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
protected void be_getTeleportTarget(ServerWorld destination, CallbackInfoReturnable<TeleportTarget> info) {
protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable<TeleportTarget> 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 TeleportTarget(
new Vec3d(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getVelocity(), yaw, pitch));
}
}

View file

@ -8,22 +8,26 @@ 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.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.mob.EndermanEntity;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.util.math.BlockPos;
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.util.math.Box;
import net.minecraft.world.ServerWorldAccess;
@Mixin(HostileEntity.class)
public class HostileEntityMixin {
@Inject(method = "canSpawnInDark", at = @At(value = "RETURN"), cancellable = true)
private static void be_endermenCheck(EntityType<? extends HostileEntity> type, ServerWorldAccess serverWorldAccess, SpawnReason spawnReason, BlockPos pos, Random random, CallbackInfoReturnable<Boolean> info) {
private static void be_endermenCheck(EntityType<? extends HostileEntity> type, ServerWorldAccess serverWorldAccess,
SpawnReason 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; });
List<EndermanEntity> entities = serverWorldAccess.getEntitiesByClass(EndermanEntity.class, box,
(entity) -> {
return true;
});
info.setReturnValue(entities.size() < 6);
}
}

View file

@ -8,24 +8,24 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.item.Item;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.attribute.EntityAttributeModifier;
import net.minecraft.world.entity.attribute.EntityAttributes;
import net.minecraft.world.entity.damage.DamageSource;
import net.minecraft.world.item.Item;
@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {
private Entity lastAttacker;
@Inject(method = "damage", at = @At("HEAD"))
public void be_damage(DamageSource source, float amount, CallbackInfoReturnable<Boolean> info) {
this.lastAttacker = source.getAttacker();
}
@ModifyArg(method = "damage", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;takeKnockback(FDD)V"))
private float be_increaseKnockback(float value, double x, double z) {
if (lastAttacker != null && lastAttacker instanceof LivingEntity) {
@ -34,11 +34,12 @@ 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<EntityAttributeModifier> modifiers = tool.getAttributeModifiers(EquipmentSlot.MAINHAND)
.get(EntityAttributes.GENERIC_ATTACK_KNOCKBACK);
.get(EntityAttributes.GENERIC_ATTACK_KNOCKBACK);
if (modifiers.size() > 0) {
return modifiers.iterator().next().getValue();
}

View file

@ -17,10 +17,10 @@ import net.minecraft.resource.ServerResourceManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.SaveProperties;
import net.minecraft.world.World;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerWorldProperties;
import ru.betterend.recipe.EndRecipeManager;
import ru.betterend.registry.EndBiomes;
@ -30,11 +30,11 @@ import ru.betterend.world.generator.GeneratorOptions;
public class MinecraftServerMixin {
@Shadow
private ServerResourceManager serverResourceManager;
@Final
@Shadow
private Map<RegistryKey<World>, ServerWorld> worlds;
private Map<RegistryKey<Level>, ServerLevel> worlds;
@Final
@Shadow
protected SaveProperties saveProperties;
@ -49,25 +49,26 @@ public class MinecraftServerMixin {
beInjectRecipes();
EndBiomes.initRegistry((MinecraftServer) (Object) this);
}
@Inject(method = "getOverworld", at = @At(value = "HEAD"), cancellable = true)
private final void beGetOverworld(CallbackInfoReturnable<ServerWorld> info) {
private final void beGetOverworld(CallbackInfoReturnable<ServerLevel> info) {
if (GeneratorOptions.swapOverworldToEnd()) {
ServerWorld world = worlds.get(World.END);
ServerLevel world = worlds.get(Level.END);
if (world == null) {
world = worlds.get(World.OVERWORLD);
world = worlds.get(Level.OVERWORLD);
}
info.setReturnValue(world);
info.cancel();
}
}
@Inject(method = "createWorlds", at = @At(value = "TAIL"))
private final void be_CreateWorlds(WorldGenerationProgressListener worldGenerationProgressListener, CallbackInfo info) {
private final void be_CreateWorlds(WorldGenerationProgressListener worldGenerationProgressListener,
CallbackInfo info) {
if (GeneratorOptions.swapOverworldToEnd()) {
ServerWorld world = worlds.get(World.END);
ServerLevel world = worlds.get(Level.END);
if (world == null) {
world = worlds.get(World.OVERWORLD);
world = worlds.get(Level.OVERWORLD);
}
this.getPlayerManager().setMainWorld(world);
ServerWorldProperties serverWorldProperties = saveProperties.getMainWorldProperties();
@ -76,17 +77,20 @@ public class MinecraftServerMixin {
setupSpawn(world, serverWorldProperties, generatorOptions.hasBonusChest(), bl, true);
}
}
@Inject(method = "setupSpawn", at = @At(value = "HEAD"), cancellable = true)
private static void be_SetupSpawn(ServerWorld world, ServerWorldProperties serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl, CallbackInfo info) {
if (GeneratorOptions.swapOverworldToEnd() && world.getRegistryKey() == World.OVERWORLD) {
private static void be_SetupSpawn(ServerLevel world, ServerWorldProperties serverWorldProperties,
boolean bonusChest, boolean debugWorld, boolean bl, CallbackInfo info) {
if (GeneratorOptions.swapOverworldToEnd() && world.dimension() == Level.OVERWORLD) {
info.cancel();
}
}
@Shadow
private static void setupSpawn(ServerWorld world, ServerWorldProperties serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl) {}
private static void setupSpawn(ServerLevel world, ServerWorldProperties serverWorldProperties, boolean bonusChest,
boolean debugWorld, boolean bl) {
}
@Shadow
public PlayerManager getPlayerManager() {
return null;

View file

@ -1,5 +1,7 @@
package ru.betterend.mixin.common;
import net.minecraft.advancements.Advancement;
import net.minecraft.server.PlayerAdvancements;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -7,22 +9,19 @@ 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.advancement.Advancement;
import net.minecraft.advancement.PlayerAdvancementTracker;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.level.ServerPlayer;
import ru.betterend.events.PlayerAdvancementsEvents;
@Mixin(PlayerAdvancementTracker.class)
@Mixin(PlayerAdvancements.class)
public abstract class PlayerAdvancementTrackerMixin {
@Shadow
private ServerPlayerEntity owner;
@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);
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);
}
}

View file

@ -7,11 +7,11 @@ 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.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.entity.player.PlayerEntity;
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;
@ -22,29 +22,29 @@ import ru.betterend.util.MHelper;
@Mixin(PlayerEntity.class)
public abstract class PlayerEntityMixin {
private static Direction[] HORIZONTAL;
@Inject(method = "findRespawnPosition", at = @At(value = "HEAD"), cancellable = true)
private static void be_statueRespawn(ServerWorld 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<Vec3d>> info) {
BlockState blockState = world.getBlockState(pos);
if (blockState.isOf(EndBlocks.RESPAWN_OBELISK)) {
if (blockState.is(EndBlocks.RESPAWN_OBELISK)) {
info.setReturnValue(beObeliskRespawnPosition(world, pos, blockState));
info.cancel();
}
}
private static Optional<Vec3d> beObeliskRespawnPosition(ServerWorld world, BlockPos pos, BlockState state) {
if (state.get(BlockProperties.TRIPLE_SHAPE) == TripleShape.TOP) {
private static Optional<Vec3d> beObeliskRespawnPosition(ServerLevel world, BlockPos pos, BlockState state) {
if (state.getValue(BlockProperties.TRIPLE_SHAPE) == TripleShape.TOP) {
pos = pos.down(2);
}
else if (state.get(BlockProperties.TRIPLE_SHAPE) == TripleShape.MIDDLE) {
pos = pos.down();
} 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) {
BlockPos p = pos.offset(dir);
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));

View file

@ -19,9 +19,9 @@ import com.mojang.serialization.DataResult;
import com.mojang.serialization.Dynamic;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.effect.StatusEffectInstance;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
@ -42,8 +42,8 @@ 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.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
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;
@ -52,10 +52,10 @@ import net.minecraft.util.Util;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import net.minecraft.world.level.Level;
import net.minecraft.world.WorldProperties;
import net.minecraft.world.biome.source.BiomeAccess;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.level.dimension.DimensionType;
import ru.betterend.world.generator.GeneratorOptions;
@Mixin(PlayerManager.class)
@ -77,14 +77,14 @@ public class PlayerManagerMixin {
@Final
@Shadow
private List<ServerPlayerEntity> players;
private List<ServerPlayer> players;
@Final
@Shadow
private Map<UUID, ServerPlayerEntity> playerMap;
private Map<UUID, ServerPlayer> playerMap;
@Inject(method = "onPlayerConnect", at = @At(value = "HEAD"), cancellable = true)
public void be_onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo info) {
public void be_onPlayerConnect(ClientConnection connection, ServerPlayer player, CallbackInfo info) {
if (GeneratorOptions.swapOverworldToEnd()) {
GameProfile gameProfile = player.getGameProfile();
UserCache userCache = this.server.getUserCache();
@ -92,50 +92,57 @@ public class PlayerManagerMixin {
String string = gameProfile2 == null ? gameProfile.getName() : gameProfile2.getName();
userCache.add(gameProfile);
CompoundTag compoundTag = this.loadPlayerData(player);
RegistryKey<World> var23;
RegistryKey<Level> var23;
if (compoundTag != null) {
DataResult<RegistryKey<World>> var10000 = DimensionType.method_28521(new Dynamic<Tag>(NbtOps.INSTANCE, compoundTag.get("Dimension")));
DataResult<RegistryKey<Level>> var10000 = DimensionType
.method_28521(new Dynamic<Tag>(NbtOps.INSTANCE, compoundTag.get("Dimension")));
Logger var10001 = LOGGER;
var10001.getClass();
var23 = (RegistryKey<World>) var10000.resultOrPartial(var10001::error).orElse(World.END);
}
else {
var23 = World.END;
var23 = (RegistryKey<Level>) var10000.resultOrPartial(var10001::error).orElse(Level.END);
} else {
var23 = Level.END;
}
RegistryKey<World> registryKey = var23;
ServerWorld serverWorld = this.server.getWorld(registryKey);
ServerWorld serverWorld3;
RegistryKey<Level> registryKey = var23;
ServerLevel serverWorld = this.server.getLevel(registryKey);
ServerLevel serverWorld3;
if (serverWorld == null) {
LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", registryKey);
serverWorld3 = this.server.getOverworld();
}
else {
} else {
serverWorld3 = serverWorld;
}
player.setWorld(serverWorld3);
player.interactionManager.setWorld((ServerWorld) player.world);
player.interactionManager.setWorld((ServerLevel) player.world);
String string2 = "local";
if (connection.getAddress() != null) {
string2 = connection.getAddress().toString();
}
LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", player.getName().getString(), string2, player.getEntityId(), player.getX(), player.getY(), player.getZ());
LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", player.getName().getString(), string2,
player.getEntityId(), player.getX(), player.getY(), player.getZ());
WorldProperties worldProperties = serverWorld3.getLevelProperties();
this.setGameMode(player, (ServerPlayerEntity) null, serverWorld3);
ServerPlayNetworkHandler serverPlayNetworkHandler = new ServerPlayNetworkHandler(this.server, connection, player);
this.setGameMode(player, (ServerPlayer) null, serverWorld3);
ServerPlayNetworkHandler serverPlayNetworkHandler = new ServerPlayNetworkHandler(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.getRegistryKey(), this.getMaxPlayerCount(), this.viewDistance, bl2, !bl,
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 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 SynchronizeRecipesS2CPacket(this.server.getRecipeManager().values()));
serverPlayNetworkHandler.sendPacket(new SynchronizeTagsS2CPacket(this.server.getTagManager()));
this.sendCommandTree(player);
player.getStatHandler().updateStatSet();
@ -144,20 +151,24 @@ public class PlayerManagerMixin {
this.server.forcePlayerSampleUpdate();
TranslatableText 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 TranslatableText("multiplayer.player.joined",
new Object[] { player.getDisplayName() });
} else {
mutableText2 = new TranslatableText("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);
serverPlayNetworkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.yaw,
player.pitch);
this.players.add(player);
this.playerMap.put(player.getUuid(), player);
this.sendToAll(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER, new ServerPlayerEntity[] { player }));
this.sendToAll(
new PlayerListS2CPacket(PlayerListS2CPacket.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 ServerPlayerEntity[] { (ServerPlayerEntity) this.players.get(i) }));
player.networkHandler.sendPacket(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER,
new ServerPlayer[] { (ServerPlayer) this.players.get(i) }));
}
serverWorld3.onPlayerConnected(player);
@ -171,20 +182,21 @@ public class PlayerManagerMixin {
while (var24.hasNext()) {
StatusEffectInstance statusEffectInstance = (StatusEffectInstance) var24.next();
serverPlayNetworkHandler.sendPacket(new EntityStatusEffectS2CPacket(player.getEntityId(), statusEffectInstance));
serverPlayNetworkHandler
.sendPacket(new EntityStatusEffectS2CPacket(player.getEntityId(), 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.loadEntityWithPassengers(compoundTag2.getCompound("Entity"), serverWorld3,
(vehicle) -> {
return !serverWorld3.tryLoadEntity(vehicle) ? null : vehicle;
});
if (entity != null) {
UUID uUID2;
if (compoundTag2.containsUuid("Attach")) {
uUID2 = compoundTag2.getUuid("Attach");
}
else {
} else {
uUID2 = null;
}
@ -192,8 +204,7 @@ public class PlayerManagerMixin {
Entity entity3;
if (entity.getUuid().equals(uUID2)) {
player.startRiding(entity, true);
}
else {
} else {
var21 = entity.getPassengersDeep().iterator();
while (var21.hasNext()) {
@ -224,15 +235,17 @@ public class PlayerManagerMixin {
}
@Shadow
public CompoundTag loadPlayerData(ServerPlayerEntity player) {
public CompoundTag loadPlayerData(ServerPlayer player) {
return null;
}
@Shadow
private void setGameMode(ServerPlayerEntity player, @Nullable ServerPlayerEntity oldPlayer, ServerWorld world) {}
private void setGameMode(ServerPlayer player, @Nullable ServerPlayer oldPlayer, ServerLevel world) {
}
@Shadow
public void sendCommandTree(ServerPlayerEntity player) {}
public void sendCommandTree(ServerPlayer player) {
}
@Shadow
public int getMaxPlayerCount() {
@ -245,14 +258,18 @@ public class PlayerManagerMixin {
}
@Shadow
protected void sendScoreboard(ServerScoreboard scoreboard, ServerPlayerEntity player) {}
protected void sendScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {
}
@Shadow
public void broadcastChatMessage(Text message, MessageType type, UUID senderUuid) {}
public void broadcastChatMessage(Text message, MessageType type, UUID senderUuid) {
}
@Shadow
public void sendToAll(Packet<?> packet) {}
public void sendToAll(Packet<?> packet) {
}
@Shadow
public void sendWorldInfo(ServerPlayerEntity player, ServerWorld world) {}
public void sendWorldInfo(ServerPlayer player, ServerLevel world) {
}
}

View file

@ -5,16 +5,16 @@ import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.recipe.RecipeType;
import net.minecraft.util.Identifier;
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;
@Mixin(RecipeManager.class)
public interface RecipeManagerAccessor {
@Accessor("recipes")
Map<RecipeType<?>, Map<Identifier, Recipe<?>>> getRecipes();
Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> getRecipes();
@Accessor("recipes")
void setRecipes(Map<RecipeType<?>, Map<Identifier, Recipe<?>>> recipes);
void setRecipes(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes);
}

View file

@ -16,39 +16,42 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.google.gson.JsonElement;
import net.minecraft.inventory.Inventory;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.recipe.RecipeType;
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.util.Identifier;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Util;
import net.minecraft.util.profiler.Profiler;
import net.minecraft.world.World;
import net.minecraft.world.level.Level;
import ru.betterend.recipe.EndRecipeManager;
@Mixin(RecipeManager.class)
public class RecipeManagerMixin {
@Shadow
private Map<RecipeType<?>, Map<Identifier, Recipe<?>>> recipes;
private Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes;
@Inject(method = "apply", at = @At(value = "RETURN"))
private void beSetRecipes(Map<Identifier, JsonElement> map, ResourceManager resourceManager, Profiler profiler, CallbackInfo info) {
private void beSetRecipes(Map<ResourceLocation, JsonElement> map, ResourceManager resourceManager,
Profiler profiler, CallbackInfo info) {
recipes = EndRecipeManager.getMap(recipes);
}
@Shadow
private <C extends Inventory, T extends Recipe<C>> Map<Identifier, Recipe<C>> getAllOfType(RecipeType<T> type) {
private <C extends Inventory, 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, World world) {
public <C extends Inventory, 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) -> {

View file

@ -10,9 +10,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.authlib.GameProfile;
import net.minecraft.entity.Entity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.effect.StatusEffectInstance;
import net.minecraft.world.entity.player.PlayerEntity;
import net.minecraft.network.packet.s2c.play.DifficultyS2CPacket;
import net.minecraft.network.packet.s2c.play.EntityStatusEffectS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerAbilitiesS2CPacket;
@ -21,19 +21,19 @@ 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.network.ServerPlayerEntity;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
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.World;
import net.minecraft.world.level.Level;
import net.minecraft.world.WorldProperties;
import net.minecraft.world.biome.source.BiomeAccess;
import ru.betterend.interfaces.TeleportingEntity;
import ru.betterend.world.generator.GeneratorOptions;
@Mixin(ServerPlayerEntity.class)
@Mixin(ServerPlayer.class)
public abstract class ServerPlayerEntityMixin extends PlayerEntity implements TeleportingEntity {
@Shadow
@ -55,34 +55,38 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntity implements Te
private BlockPos exitPos;
public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) {
public ServerPlayerEntityMixin(Level world, BlockPos pos, float yaw, GameProfile profile) {
super(world, pos, yaw, profile);
}
@Inject(method = "createEndSpawnPlatform", at = @At("HEAD"), cancellable = true)
private void be_createEndSpawnPlatform(ServerWorld world, BlockPos centerPos, CallbackInfo info) {
private void be_createEndSpawnPlatform(ServerLevel world, BlockPos centerPos, CallbackInfo info) {
if (!GeneratorOptions.generateObsidianPlatform()) {
info.cancel();
}
}
@Inject(method = "getTeleportTarget", at = @At("HEAD"), cancellable = true)
protected void be_getTeleportTarget(ServerWorld destination, CallbackInfoReturnable<TeleportTarget> info) {
protected void be_getTeleportTarget(ServerLevel destination, CallbackInfoReturnable<TeleportTarget> 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 TeleportTarget(
new Vec3d(exitPos.getX() + 0.5, exitPos.getY(), exitPos.getZ() + 0.5), getVelocity(), yaw, pitch));
}
}
@Inject(method = "moveToWorld", at = @At("HEAD"), cancellable = true)
public void be_moveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity> info) {
if (beCanTeleport() && world instanceof ServerWorld) {
public void be_moveToWorld(ServerLevel destination, CallbackInfoReturnable<Entity> info) {
if (beCanTeleport() && world instanceof ServerLevel) {
this.inTeleportationState = true;
ServerWorld serverWorld = this.getServerWorld();
ServerLevel serverWorld = this.getServerWorld();
WorldProperties worldProperties = destination.getLevelProperties();
ServerPlayerEntity player = ServerPlayerEntity.class.cast(this);
this.networkHandler.sendPacket(new PlayerRespawnS2CPacket(destination.getDimension(), destination.getRegistryKey(), BiomeAccess.hashSeed(destination.getSeed()),
interactionManager.getGameMode(),interactionManager.getPreviousGameMode(), destination.isDebugWorld(), destination.isFlat(), true));
this.networkHandler.sendPacket(new DifficultyS2CPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked()));
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);
@ -95,7 +99,8 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntity implements Te
this.setWorld(destination);
destination.onPlayerChangeDimension(player);
this.setRotation(teleportTarget.yaw, teleportTarget.pitch);
this.refreshPositionAfterTeleport(teleportTarget.position.x, teleportTarget.position.y, teleportTarget.position.z);
this.refreshPositionAfterTeleport(teleportTarget.position.x, teleportTarget.position.y,
teleportTarget.position.z);
serverWorld.getProfiler().pop();
this.worldChanged(serverWorld);
this.interactionManager.setWorld(destination);
@ -104,7 +109,8 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntity implements Te
playerManager.sendPlayerStatus(player);
for (StatusEffectInstance statusEffectInstance : this.getStatusEffects()) {
this.networkHandler.sendPacket(new EntityStatusEffectS2CPacket(getEntityId(), statusEffectInstance));
this.networkHandler
.sendPacket(new EntityStatusEffectS2CPacket(getEntityId(), statusEffectInstance));
}
this.networkHandler.sendPacket(new WorldEventS2CPacket(1032, BlockPos.ORIGIN, 0, false));
@ -118,14 +124,14 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntity implements Te
}
@Shadow
abstract ServerWorld getServerWorld();
abstract ServerLevel getServerWorld();
@Shadow
abstract void worldChanged(ServerWorld origin);
abstract void worldChanged(ServerLevel origin);
@Shadow
@Override
protected abstract TeleportTarget getTeleportTarget(ServerWorld destination);
protected abstract TeleportTarget getTeleportTarget(ServerLevel destination);
@Override
public void beSetExitPos(BlockPos pos) {

View file

@ -17,11 +17,11 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.gen.Spawner;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.level.ServerWorldProperties;
@ -31,36 +31,39 @@ import ru.betterend.util.DataFixerUtil;
import ru.betterend.util.WorldDataUtil;
import ru.betterend.world.generator.GeneratorOptions;
@Mixin(ServerWorld.class)
@Mixin(ServerLevel.class)
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, RegistryKey<World> registryKey, DimensionType dimensionType, WorldGenerationProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<Spawner> list, boolean bl, CallbackInfo info) {
private void be_onServerWorldInit(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session,
ServerWorldProperties properties, RegistryKey<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())) {
return;
}
lastWorld = session.getDirectoryName();
@SuppressWarnings("resource")
ServerWorld world = (ServerWorld) (Object) this;
File dir = session.getWorldDirectory(world.getRegistryKey());
ServerLevel world = (ServerLevel) (Object) this;
File dir = session.getWorldDirectory(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")));
if (dataVersion < version) {
if (version < FIX_VERSION) {
DataFixerUtil.fixData(data.getParentFile());
@ -73,13 +76,13 @@ public class ServerWorldMixin {
@Inject(method = "getSpawnPos", at = @At("HEAD"), cancellable = true)
private void be_getSpawnPos(CallbackInfoReturnable<BlockPos> info) {
if (GeneratorOptions.changeSpawn()) {
if (((ServerWorld) (Object) this).getRegistryKey() == World.END) {
if (((ServerLevel) (Object) this).dimension() == Level.END) {
info.setReturnValue(GeneratorOptions.getSpawn());
info.cancel();
}
}
}
private static int be_getVersionInt(String version) {
if (version.isEmpty()) {
return 0;
@ -87,12 +90,11 @@ 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;

View file

@ -3,14 +3,15 @@ package ru.betterend.mixin.common;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.entity.mob.SlimeEntity;
import net.minecraft.world.entity.mob.SlimeEntity;
import ru.betterend.interfaces.ISlime;
@Mixin(SlimeEntity.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);

View file

@ -11,22 +11,23 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.resource.ResourceManager;
import net.minecraft.tag.Tag;
import net.minecraft.tag.TagGroupLoader;
import net.minecraft.util.Identifier;
import net.minecraft.tags.Tag;
import net.minecraft.tags.TagGroupLoader;
import net.minecraft.resources.ResourceLocation;
import ru.betterend.util.TagHelper;
@Mixin(TagGroupLoader.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<Identifier, Tag.Builder>>> info) {
CompletableFuture<Map<Identifier, Tag.Builder>> future = info.getReturnValue();
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<Identifier, Tag.Builder> map = future.join();
Map<ResourceLocation, Tag.Builder> map = future.join();
TagHelper.apply(entryType, map);
return map;
}));