Add Note Block Screen Tweak
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
All checks were successful
SlightlyVanilla/pipeline/head This commit looks good
This commit is contained in:
parent
ed494fd52a
commit
b6614da325
@ -13,6 +13,7 @@ Suggest more tweaks in the issue tracker!
|
|||||||
* Crying Obsidian Nether Portal
|
* Crying Obsidian Nether Portal
|
||||||
* Allow Leashing Villagers
|
* Allow Leashing Villagers
|
||||||
* Disable Instant Nether Portal In Creative
|
* Disable Instant Nether Portal In Creative
|
||||||
|
* Add Note Block Screen
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
[View Changelog](CHANGELOG.md)
|
[View Changelog](CHANGELOG.md)
|
||||||
|
@ -3,6 +3,9 @@ package com.thebrokenrail.slightlyvanilla;
|
|||||||
import me.sargunvohra.mcmods.autoconfig1u.ConfigData;
|
import me.sargunvohra.mcmods.autoconfig1u.ConfigData;
|
||||||
import me.sargunvohra.mcmods.autoconfig1u.annotation.Config;
|
import me.sargunvohra.mcmods.autoconfig1u.annotation.Config;
|
||||||
import me.sargunvohra.mcmods.autoconfig1u.annotation.ConfigEntry;
|
import me.sargunvohra.mcmods.autoconfig1u.annotation.ConfigEntry;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
||||||
|
|
||||||
@Config(name = SlightlyVanilla.NAMESPACE)
|
@Config(name = SlightlyVanilla.NAMESPACE)
|
||||||
public class ModConfig implements ConfigData {
|
public class ModConfig implements ConfigData {
|
||||||
@ -16,6 +19,8 @@ public class ModConfig implements ConfigData {
|
|||||||
public boolean cryingObsidianNetherPortal = true;
|
public boolean cryingObsidianNetherPortal = true;
|
||||||
public boolean allowLeashingVillagers = true;
|
public boolean allowLeashingVillagers = true;
|
||||||
public boolean disableInstantNetherPortalInCreative = true;
|
public boolean disableInstantNetherPortalInCreative = true;
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public boolean noteBlockScreen = true;
|
||||||
|
|
||||||
public static class ThrowableOption {
|
public static class ThrowableOption {
|
||||||
public boolean player;
|
public boolean player;
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
package com.thebrokenrail.slightlyvanilla.client.screen;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
|
||||||
|
import com.thebrokenrail.slightlyvanilla.mixin.ScreenHandlerAccessor;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.client.gui.widget.SliderWidget;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
|
||||||
|
import net.minecraft.screen.ScreenHandlerContext;
|
||||||
|
import net.minecraft.state.property.Properties;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class NoteBlockScreen extends Screen {
|
||||||
|
private static class NoteSliderWidget extends SliderWidget {
|
||||||
|
private final ScreenHandlerContext context;
|
||||||
|
|
||||||
|
public NoteSliderWidget(ScreenHandlerContext context, int x, int y, int width, int height) {
|
||||||
|
super(x, y, width, height, LiteralText.EMPTY, (double) getNote(context) / getMax());
|
||||||
|
this.context = context;
|
||||||
|
updateMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double getMax() {
|
||||||
|
return (double) Properties.NOTE.getValues().size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||||
|
private static int getNote(ScreenHandlerContext context) {
|
||||||
|
return context.run((BiFunction<World, BlockPos, Integer>) (world, pos) -> world.getBlockState(pos).get(Properties.NOTE)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int toNote() {
|
||||||
|
return (int) (value * getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateMessage() {
|
||||||
|
int note = toNote();
|
||||||
|
setMessage(new TranslatableText("text." + SlightlyVanilla.NAMESPACE + ".noteblock_screen_slider", note, new TranslatableText("text." + SlightlyVanilla.NAMESPACE + ".noteblock_note." + note)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyValue() {
|
||||||
|
context.run((world, blockPos) -> {
|
||||||
|
BlockState target = world.getBlockState(blockPos);
|
||||||
|
|
||||||
|
int currentNote = target.get(Properties.NOTE);
|
||||||
|
int targetNote = toNote();
|
||||||
|
|
||||||
|
int amount;
|
||||||
|
if (targetNote >= currentNote) {
|
||||||
|
amount = targetNote - currentNote;
|
||||||
|
} else {
|
||||||
|
amount = ((int) getMax()) - currentNote + 1 + targetNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
assert client != null;
|
||||||
|
assert client.getNetworkHandler() != null;
|
||||||
|
|
||||||
|
BlockHitResult hitResult = new BlockHitResult(Vec3d.ofCenter(blockPos), Direction.UP, blockPos, false);
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
client.getNetworkHandler().sendPacket(new PlayerInteractBlockC2SPacket(Hand.MAIN_HAND, hitResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
world.setBlockState(blockPos, target.with(Properties.NOTE, targetNote));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Identifier TEXTURE = new Identifier(SlightlyVanilla.NAMESPACE, "textures/gui/noteblock.png");
|
||||||
|
|
||||||
|
private final ScreenHandlerContext context;
|
||||||
|
|
||||||
|
public NoteBlockScreen(ScreenHandlerContext context) {
|
||||||
|
super(Blocks.NOTE_BLOCK.getName());
|
||||||
|
passEvents = true;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
int sliderWidth = BACKGROUND_WIDTH - 36;
|
||||||
|
int sliderHeight = 20;
|
||||||
|
addButton(new NoteSliderWidget(context, width / 2 - sliderWidth / 2, (height / 2) - (sliderHeight / 2) + 4, sliderWidth, sliderHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int BACKGROUND_WIDTH = 176;
|
||||||
|
private static final int BACKGROUND_HEIGHT = 60;
|
||||||
|
|
||||||
|
private static final int TITLE_X_OFFSET = 8;
|
||||||
|
private static final int TITLE_Y_OFFSEt = 6;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderBackground(MatrixStack matrices) {
|
||||||
|
super.renderBackground(matrices);
|
||||||
|
|
||||||
|
//noinspection deprecation
|
||||||
|
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
assert client != null;
|
||||||
|
client.getTextureManager().bindTexture(TEXTURE);
|
||||||
|
int centerX = width / 2;
|
||||||
|
int centerY = height / 2;
|
||||||
|
drawTexture(matrices, centerX - (BACKGROUND_WIDTH / 2), centerY - (BACKGROUND_HEIGHT / 2), 0, 0, BACKGROUND_WIDTH, BACKGROUND_HEIGHT);
|
||||||
|
|
||||||
|
int titleX = centerX - (BACKGROUND_WIDTH / 2) + TITLE_X_OFFSET;
|
||||||
|
int titleY = centerY - (BACKGROUND_HEIGHT / 2) + TITLE_Y_OFFSEt;
|
||||||
|
textRenderer.draw(matrices, title, titleX, titleY, 4210752);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
|
renderBackground(matrices);
|
||||||
|
super.render(matrices, mouseX, mouseY, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
assert client != null;
|
||||||
|
if (!ScreenHandlerAccessor.callCanUse(context, client.player, Blocks.NOTE_BLOCK)) {
|
||||||
|
assert client.player != null;
|
||||||
|
client.player.closeScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.thebrokenrail.slightlyvanilla.mixin;
|
||||||
|
|
||||||
|
import com.thebrokenrail.slightlyvanilla.SlightlyVanilla;
|
||||||
|
import com.thebrokenrail.slightlyvanilla.client.screen.NoteBlockScreen;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.network.ClientPlayerInteractionManager;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.screen.ScreenHandlerContext;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
@Mixin(ClientPlayerInteractionManager.class)
|
||||||
|
public class MixinClientPlayerInteractionManager {
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private MinecraftClient client;
|
||||||
|
|
||||||
|
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;", ordinal = 0), method = "interactBlock", cancellable = true)
|
||||||
|
public void interactBlock(ClientPlayerEntity player, ClientWorld world, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable<ActionResult> info) {
|
||||||
|
if (!player.isSpectator() && SlightlyVanilla.getConfig().noteBlockScreen && world.getBlockState(hitResult.getBlockPos()).getBlock() == Blocks.NOTE_BLOCK) {
|
||||||
|
NoteBlockScreen screen = new NoteBlockScreen(ScreenHandlerContext.create(world, hitResult.getBlockPos()));
|
||||||
|
client.openScreen(screen);
|
||||||
|
|
||||||
|
info.setReturnValue(ActionResult.SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.thebrokenrail.slightlyvanilla.mixin;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.screen.ScreenHandlerContext;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
@Mixin(ScreenHandler.class)
|
||||||
|
public interface ScreenHandlerAccessor {
|
||||||
|
@Invoker
|
||||||
|
static boolean callCanUse(ScreenHandlerContext context, PlayerEntity player, Block block) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,33 @@
|
|||||||
"text.autoconfig.slightlyvanilla.option.cryingObsidianNetherPortal": "Crying Obsidian Nether Portal",
|
"text.autoconfig.slightlyvanilla.option.cryingObsidianNetherPortal": "Crying Obsidian Nether Portal",
|
||||||
"text.autoconfig.slightlyvanilla.option.allowLeashingVillagers": "Allow Leashing Villagers",
|
"text.autoconfig.slightlyvanilla.option.allowLeashingVillagers": "Allow Leashing Villagers",
|
||||||
"text.autoconfig.slightlyvanilla.option.disableInstantNetherPortalInCreative": "Disable Instant Nether Portal In Creative",
|
"text.autoconfig.slightlyvanilla.option.disableInstantNetherPortalInCreative": "Disable Instant Nether Portal In Creative",
|
||||||
|
"text.autoconfig.slightlyvanilla.option.noteBlockScreen": "Add Note Block Screen",
|
||||||
"entity.slightlyvanilla.slimeball": "Slimeball",
|
"entity.slightlyvanilla.slimeball": "Slimeball",
|
||||||
"entity.slightlyvanilla.spawn_egg": "Spawn Egg"
|
"entity.slightlyvanilla.spawn_egg": "Spawn Egg",
|
||||||
|
"text.slightlyvanilla.noteblock_screen_slider": "Note: %s (%s)",
|
||||||
|
"text.slightlyvanilla.noteblock_note.0": "F#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.1": "G",
|
||||||
|
"text.slightlyvanilla.noteblock_note.2": "G#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.3": "A",
|
||||||
|
"text.slightlyvanilla.noteblock_note.4": "A#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.5": "B",
|
||||||
|
"text.slightlyvanilla.noteblock_note.6": "C",
|
||||||
|
"text.slightlyvanilla.noteblock_note.7": "C#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.8": "D",
|
||||||
|
"text.slightlyvanilla.noteblock_note.9": "D#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.10": "E",
|
||||||
|
"text.slightlyvanilla.noteblock_note.11": "F",
|
||||||
|
"text.slightlyvanilla.noteblock_note.12": "F#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.13": "G",
|
||||||
|
"text.slightlyvanilla.noteblock_note.14": "G#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.15": "A",
|
||||||
|
"text.slightlyvanilla.noteblock_note.16": "A#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.17": "B",
|
||||||
|
"text.slightlyvanilla.noteblock_note.18": "C",
|
||||||
|
"text.slightlyvanilla.noteblock_note.19": "C#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.20": "D",
|
||||||
|
"text.slightlyvanilla.noteblock_note.21": "D#",
|
||||||
|
"text.slightlyvanilla.noteblock_note.22": "E",
|
||||||
|
"text.slightlyvanilla.noteblock_note.23": "F",
|
||||||
|
"text.slightlyvanilla.noteblock_note.24": "F#"
|
||||||
}
|
}
|
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
@ -3,16 +3,18 @@
|
|||||||
"package": "com.thebrokenrail.slightlyvanilla.mixin",
|
"package": "com.thebrokenrail.slightlyvanilla.mixin",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
"client": [
|
"client": [
|
||||||
"MixinClientPlayNetworkHandler"
|
"MixinClientPlayNetworkHandler",
|
||||||
|
"ScreenHandlerAccessor"
|
||||||
],
|
],
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"MixinRespawnAnchorBlock",
|
"MixinAbstractTraderEntity",
|
||||||
"MixinPlayerEntity",
|
"MixinClientPlayerInteractionManager",
|
||||||
"MixinItem",
|
"MixinItem",
|
||||||
"MixinSpawnEggItem",
|
|
||||||
"MixinLootableContainerBlockEntity",
|
"MixinLootableContainerBlockEntity",
|
||||||
"MixinNetherPortalBlockAreaHelper",
|
"MixinNetherPortalBlockAreaHelper",
|
||||||
"MixinAbstractTraderEntity"
|
"MixinPlayerEntity",
|
||||||
|
"MixinRespawnAnchorBlock",
|
||||||
|
"MixinSpawnEggItem"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
Reference in New Issue
Block a user