mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Implement a gui for the spellbook
This commit is contained in:
parent
920ded15eb
commit
acd2b9c795
5 changed files with 249 additions and 6 deletions
|
@ -11,11 +11,14 @@ import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.client.gui.LanSettingsScreen;
|
import com.minelittlepony.unicopia.client.gui.LanSettingsScreen;
|
||||||
import com.minelittlepony.unicopia.client.gui.UHud;
|
import com.minelittlepony.unicopia.client.gui.UHud;
|
||||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
|
||||||
|
import com.minelittlepony.unicopia.container.SpellbookScreen;
|
||||||
|
import com.minelittlepony.unicopia.container.UScreenHandlers;
|
||||||
import com.minelittlepony.unicopia.entity.player.PlayerCamera;
|
import com.minelittlepony.unicopia.entity.player.PlayerCamera;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
||||||
|
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.screen.OpenToLanScreen;
|
import net.minecraft.client.gui.screen.OpenToLanScreen;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
@ -59,6 +62,8 @@ public class UnicopiaClient implements ClientModInitializer {
|
||||||
KeyBindingsHandler.bootstrap();
|
KeyBindingsHandler.bootstrap();
|
||||||
URenderers.bootstrap();
|
URenderers.bootstrap();
|
||||||
|
|
||||||
|
ScreenRegistry.register(UScreenHandlers.SPELL_BOOK, SpellbookScreen::new);
|
||||||
|
|
||||||
ClientTickEvents.END_CLIENT_TICK.register(this::onTick);
|
ClientTickEvents.END_CLIENT_TICK.register(this::onTick);
|
||||||
ScreenInitCallback.EVENT.register(this::onScreenInit);
|
ScreenInitCallback.EVENT.register(this::onScreenInit);
|
||||||
ItemTooltipCallback.EVENT.register(new ModifierTooltipRenderer());
|
ItemTooltipCallback.EVENT.register(new ModifierTooltipRenderer());
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.minelittlepony.unicopia.container;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.container.SpellbookScreenHandler.SpellbookSlot;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.screen.slot.Slot;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> {
|
||||||
|
public static final Identifier TEXTURE = new Identifier("unicopia", "textures/gui/container/book.png");
|
||||||
|
|
||||||
|
public SpellbookScreen(SpellbookScreenHandler handler, PlayerInventory inventory, Text title) {
|
||||||
|
super(handler, inventory, title);
|
||||||
|
backgroundWidth = 405;
|
||||||
|
backgroundHeight = 219;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
super.render(matrices, mouseX, mouseY, partialTicks);
|
||||||
|
drawMouseoverTooltip(matrices, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) {
|
||||||
|
renderBackground(matrices, 0);
|
||||||
|
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||||
|
|
||||||
|
int left = (width - backgroundWidth) / 2;
|
||||||
|
int top = (height - backgroundHeight) / 2;
|
||||||
|
|
||||||
|
RenderSystem.setShaderTexture(0, TEXTURE);
|
||||||
|
|
||||||
|
drawTexture(matrices, left, top, 0, 0, backgroundWidth, backgroundHeight, 512, 256);
|
||||||
|
|
||||||
|
matrices.push();
|
||||||
|
matrices.translate(this.x, this.y, 0);
|
||||||
|
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
for (Slot slot : handler.slots) {
|
||||||
|
if (slot.isEnabled() && slot instanceof SpellbookSlot) {
|
||||||
|
drawTexture(matrices, slot.x - 1, slot.y - 1, 74, 223, 18, 18, 512, 256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
drawTexture(matrices, 56, 50, 407, 2, 100, 101, 512, 256);
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
|
||||||
|
matrices.pop();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,196 @@
|
||||||
package com.minelittlepony.unicopia.container;
|
package com.minelittlepony.unicopia.container;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.EquinePredicates;
|
import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.inventory.CraftingInventory;
|
||||||
|
import net.minecraft.inventory.CraftingResultInventory;
|
||||||
|
import net.minecraft.inventory.Inventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.recipe.RecipeType;
|
||||||
import net.minecraft.screen.ScreenHandler;
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.screen.slot.CraftingResultSlot;
|
||||||
|
import net.minecraft.screen.slot.Slot;
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class SpellBookScreenHandler extends ScreenHandler {
|
public class SpellbookScreenHandler extends ScreenHandler {
|
||||||
|
|
||||||
protected SpellBookScreenHandler(int syncId, PlayerInventory inv) {
|
private final int MAX_INGREDIENTS;
|
||||||
|
|
||||||
|
private final int GEM_SLOT_INDEX;
|
||||||
|
private final int HOTBAR_START;
|
||||||
|
private final int HOTBAR_END;
|
||||||
|
|
||||||
|
private final CraftingInventory input;
|
||||||
|
|
||||||
|
private OutputSlot gemSlot;
|
||||||
|
private final CraftingResultInventory result = new CraftingResultInventory();
|
||||||
|
|
||||||
|
private final PlayerInventory inventory;
|
||||||
|
|
||||||
|
protected SpellbookScreenHandler(int syncId, PlayerInventory inv) {
|
||||||
super(UScreenHandlers.SPELL_BOOK, syncId);
|
super(UScreenHandlers.SPELL_BOOK, syncId);
|
||||||
|
inventory = inv;
|
||||||
|
|
||||||
|
List<Pair<Integer, Integer>> grid = new ArrayList<>();
|
||||||
|
List<Pair<Integer, Integer>> gemPos = new ArrayList<>();
|
||||||
|
createGrid(grid, gemPos);
|
||||||
|
|
||||||
|
GEM_SLOT_INDEX = MAX_INGREDIENTS = grid.size();
|
||||||
|
HOTBAR_START = GEM_SLOT_INDEX + 1;
|
||||||
|
HOTBAR_END = HOTBAR_START + 9;
|
||||||
|
|
||||||
|
input = new CraftingInventory(this, MAX_INGREDIENTS, 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_INGREDIENTS; i++) {
|
||||||
|
var pos = grid.get(i);
|
||||||
|
addSlot(new InputSlot(input, i, pos.getLeft(), pos.getRight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
addSlot(gemSlot = new OutputSlot(inventory.player, input, result, 0, gemPos.get(0).getLeft(), gemPos.get(0).getRight()));
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; ++i) {
|
||||||
|
addSlot(new Slot(inventory, i, 121 + i * 18, 195));
|
||||||
|
}
|
||||||
|
|
||||||
|
onContentChanged(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canUse(PlayerEntity player) {
|
public boolean canUse(PlayerEntity player) {
|
||||||
return EquinePredicates.IS_CASTER.test(player);
|
return EquinePredicates.IS_CASTER.test(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onContentChanged(Inventory inventory) {
|
||||||
|
World world = this.inventory.player.world;
|
||||||
|
if (!world.isClient) {
|
||||||
|
world.getServer().getRecipeManager().getFirstMatch(RecipeType.CRAFTING, input, world)
|
||||||
|
.map(recipe -> recipe.craft(input))
|
||||||
|
.ifPresentOrElse(gemSlot::setCrafted, gemSlot::setUncrafted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack transferSlot(PlayerEntity player, int index) {
|
||||||
|
Slot sourceSlot = slots.get(index);
|
||||||
|
|
||||||
|
if (sourceSlot == null || !sourceSlot.hasStack()) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack transferredStack = sourceSlot.getStack();
|
||||||
|
ItemStack stack = transferredStack.copy();
|
||||||
|
|
||||||
|
if (index >= HOTBAR_START) {
|
||||||
|
if (!gemSlot.hasStack() && gemSlot.canInsert(stack)) {
|
||||||
|
if (!insertItem(transferredStack, GEM_SLOT_INDEX, GEM_SLOT_INDEX + 1, false)) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!insertItem(transferredStack, 0, GEM_SLOT_INDEX, false)) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!insertItem(transferredStack, HOTBAR_START, HOTBAR_END, false)) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSlot.onQuickTransfer(transferredStack, stack);
|
||||||
|
onContentChanged(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transferredStack.getCount() == stack.getCount()) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSlot.onTakeItem(player, transferredStack);
|
||||||
|
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(PlayerEntity playerEntity) {
|
||||||
|
gemSlot.setUncrafted();
|
||||||
|
super.close(playerEntity);
|
||||||
|
dropInventory(playerEntity, input);
|
||||||
|
dropInventory(playerEntity, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createGrid(List<Pair<Integer, Integer>> grid, List<Pair<Integer, Integer>> gemPos) {
|
||||||
|
int cols = 4;
|
||||||
|
int spacing = 23;
|
||||||
|
|
||||||
|
int top = 34;
|
||||||
|
int left = 65;
|
||||||
|
|
||||||
|
for (int row = 0; row < 7; row++) {
|
||||||
|
for (int i = 0; i < cols; i++) {
|
||||||
|
(row == 3 && i == 3 ? gemPos : grid).add(new Pair<>(left + (i * spacing), top));
|
||||||
|
}
|
||||||
|
top += spacing * 0.9;
|
||||||
|
left -= (spacing / 2) * (row > 2 ? -1 : 1);
|
||||||
|
cols += row > 2 ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface SpellbookSlot {}
|
||||||
|
|
||||||
|
public class InputSlot extends Slot implements SpellbookSlot {
|
||||||
|
public InputSlot(Inventory inventory, int index, int xPosition, int yPosition) {
|
||||||
|
super(inventory, index, xPosition, yPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxItemCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class OutputSlot extends CraftingResultSlot implements SpellbookSlot {
|
||||||
|
|
||||||
|
private Optional<ItemStack> uncrafted = Optional.empty();
|
||||||
|
|
||||||
|
public OutputSlot(PlayerEntity player, CraftingInventory input, Inventory inventory, int index, int x, int y) {
|
||||||
|
super(player, input, inventory, index, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCrafted(ItemStack crafted) {
|
||||||
|
uncrafted = uncrafted.or(() -> Optional.of(getStack()));
|
||||||
|
setStack(crafted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUncrafted() {
|
||||||
|
uncrafted = uncrafted.filter(stack -> {
|
||||||
|
setStack(stack);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canInsert(ItemStack stack) {
|
||||||
|
return stack.getItem() == UItems.GEMSTONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxItemCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTakeItem(PlayerEntity player, ItemStack stack) {
|
||||||
|
if (uncrafted.isPresent()) {
|
||||||
|
uncrafted = Optional.empty();
|
||||||
|
super.onTakeItem(player, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import net.minecraft.screen.ScreenHandlerType;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public interface UScreenHandlers {
|
public interface UScreenHandlers {
|
||||||
ScreenHandlerType<SpellBookScreenHandler> SPELL_BOOK = register("spell_book", SpellBookScreenHandler::new);
|
ScreenHandlerType<SpellbookScreenHandler> SPELL_BOOK = register("spell_book", SpellbookScreenHandler::new);
|
||||||
|
|
||||||
static <T extends ScreenHandler> ScreenHandlerType<T> register(String name, SimpleClientHandlerFactory<T> factory) {
|
static <T extends ScreenHandler> ScreenHandlerType<T> register(String name, SimpleClientHandlerFactory<T> factory) {
|
||||||
return ScreenHandlerRegistry.registerSimple(new Identifier("unicopia", name), factory);
|
return ScreenHandlerRegistry.registerSimple(new Identifier("unicopia", name), factory);
|
||||||
|
|
|
@ -150,8 +150,6 @@ public class SpellbookEntity extends MobEntity {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!world.isClient) {
|
if (!world.isClient) {
|
||||||
System.out.println(activeTicks);
|
|
||||||
|
|
||||||
if (activeTicks > 0 && --activeTicks <= 0) {
|
if (activeTicks > 0 && --activeTicks <= 0) {
|
||||||
setBored(true);
|
setBored(true);
|
||||||
}
|
}
|
||||||
|
@ -193,13 +191,14 @@ public class SpellbookEntity extends MobEntity {
|
||||||
setBored(false);
|
setBored(false);
|
||||||
setAwake(!isOpen());
|
setAwake(!isOpen());
|
||||||
setLocked(TriState.of(isAwake()));
|
setLocked(TriState.of(isAwake()));
|
||||||
|
player.playSound(SoundEvents.ITEM_BOOK_PAGE_TURN, 2, 1);
|
||||||
return ActionResult.SUCCESS;
|
return ActionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOpen() && EquinePredicates.PLAYER_UNICORN.test(player)) {
|
if (isOpen() && EquinePredicates.PLAYER_UNICORN.test(player)) {
|
||||||
setBored(false);
|
setBored(false);
|
||||||
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((syncId, inv, ply) -> UScreenHandlers.SPELL_BOOK.create(syncId, inv), getDisplayName()));
|
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((syncId, inv, ply) -> UScreenHandlers.SPELL_BOOK.create(syncId, inv), getDisplayName()));
|
||||||
player.playSound(SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, 2, 1);
|
player.playSound(SoundEvents.ITEM_BOOK_PAGE_TURN, 2, 1);
|
||||||
return ActionResult.SUCCESS;
|
return ActionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue