mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Display trinket slots in the spellbook
This commit is contained in:
parent
5f8dfe14e9
commit
1ed6ef7a17
10 changed files with 200 additions and 8 deletions
|
@ -16,6 +16,8 @@ import com.minelittlepony.unicopia.container.*;
|
|||
import com.minelittlepony.unicopia.container.inventory.*;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgSpellbookStateChanged;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketSlotBackSprites;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
|
@ -203,6 +205,9 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> imple
|
|||
RenderSystem.enableBlend();
|
||||
}
|
||||
}
|
||||
if (slot.isEnabled() && slot instanceof TrinketsDelegate.SlotWithForeground fg && slot.getStack().isEmpty()) {
|
||||
context.drawTexture(TrinketSlotBackSprites.getBackSprite(fg.getForegroundIdentifier()), slot.x, slot.y, 0, 0, 16, 16, 16, 16);
|
||||
}
|
||||
}
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellbookRecipe;
|
|||
import com.minelittlepony.unicopia.container.inventory.*;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.item.URecipes;
|
||||
import com.minelittlepony.unicopia.trinkets.TrinketsDelegate;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
|
@ -52,7 +53,7 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
|
||||
private final ScreenHandlerContext context;
|
||||
|
||||
public Predicate<SlotType> canShowSlots;
|
||||
private Predicate<SlotType> canShowSlots;
|
||||
|
||||
private final SpellbookState state;
|
||||
|
||||
|
@ -126,6 +127,11 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
});
|
||||
}
|
||||
|
||||
TrinketsDelegate.getInstance().createSlot(this, inv.player, TrinketsDelegate.FACE, 0, 340 + 20, 60).ifPresent(this::addSlot);
|
||||
TrinketsDelegate.getInstance().createSlot(this, inv.player, TrinketsDelegate.NECKLACE, 0, 340 + 20, 60 + 20).ifPresent(this::addSlot);
|
||||
TrinketsDelegate.getInstance().createSlot(this, inv.player, TrinketsDelegate.MAINHAND, 0, 350 - 20, 170).ifPresent(this::addSlot);
|
||||
TrinketsDelegate.getInstance().createSlot(this, inv.player, TrinketsDelegate.OFFHAND, 0, 330 + 20, 170).ifPresent(this::addSlot);
|
||||
|
||||
addSlot(new InventorySlot(this, inventory, PlayerInventory.OFF_HAND_SLOT, 340, 150) {
|
||||
@Override
|
||||
public Pair<Identifier, Identifier> getBackgroundSprite() {
|
||||
|
@ -146,6 +152,10 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
this.canShowSlots = canShowSlots;
|
||||
}
|
||||
|
||||
public boolean canShowSlots(SlotType type) {
|
||||
return canShowSlots == null || canShowSlots.test(type);
|
||||
}
|
||||
|
||||
public int getOutputSlotId() {
|
||||
return outputSlot.id;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,6 @@ public class IngredientSlot extends Slot implements SpellbookSlot {
|
|||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return handler.canShowSlots.test(SlotType.CRAFTING) && super.isEnabled();
|
||||
return handler.canShowSlots(SlotType.CRAFTING) && super.isEnabled();
|
||||
}
|
||||
}
|
|
@ -27,6 +27,6 @@ public class InputSlot extends Slot implements SpellbookSlot {
|
|||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return handler.canShowSlots.test(SlotType.CRAFTING) && !handler.outputSlot.isEnabled();
|
||||
return handler.canShowSlots(SlotType.CRAFTING) && !handler.outputSlot.isEnabled();
|
||||
}
|
||||
}
|
|
@ -15,6 +15,6 @@ public class InventorySlot extends Slot implements SpellbookSlot {
|
|||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return handler.canShowSlots.test(SlotType.INVENTORY);
|
||||
return handler.canShowSlots(SlotType.INVENTORY);
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ public class OutputSlot extends CraftingResultSlot implements SpellbookSlot {
|
|||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return handler.canShowSlots.test(SlotType.CRAFTING) && hasStack();
|
||||
return handler.canShowSlots(SlotType.CRAFTING) && hasStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package com.minelittlepony.unicopia.trinkets;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.container.SpellbookScreenHandler;
|
||||
import com.minelittlepony.unicopia.container.inventory.InventorySlot;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
import dev.emi.trinkets.SurvivalTrinketSlot;
|
||||
import dev.emi.trinkets.api.SlotGroup;
|
||||
import dev.emi.trinkets.api.TrinketInventory;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
class SpellbookTrinketSlot extends InventorySlot implements TrinketsDelegate.SlotWithForeground {
|
||||
private final SurvivalTrinketSlot slot;
|
||||
|
||||
public SpellbookTrinketSlot(SpellbookScreenHandler handler, TrinketInventory inventory, int index, int x, int y, SlotGroup group) {
|
||||
super(handler, inventory, index, x, y);
|
||||
this.slot = new SurvivalTrinketSlot(inventory, index, x, y, group, inventory.getSlotType(), 0, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeItem(PlayerEntity player, ItemStack stack) {
|
||||
this.slot.onTakeItem(player, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsert(ItemStack stack) {
|
||||
return this.slot.canInsert(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack() {
|
||||
return this.slot.getStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStack() {
|
||||
return this.slot.hasStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack(ItemStack stack) {
|
||||
this.slot.setStack(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStackNoCallbacks(ItemStack stack) {
|
||||
this.slot.setStackNoCallbacks(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
this.slot.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxItemCount() {
|
||||
return this.slot.getMaxItemCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxItemCount(ItemStack stack) {
|
||||
return this.slot.getMaxItemCount(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Pair<Identifier, Identifier> getBackgroundSprite() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack takeStack(int amount) {
|
||||
return this.slot.takeStack(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.slot.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeItems(PlayerEntity playerEntity) {
|
||||
return this.slot.canTakeItems(playerEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getForegroundIdentifier() {
|
||||
return slot.getBackgroundIdentifier();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.minelittlepony.unicopia.trinkets;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import net.minecraft.client.texture.NativeImageBackedTexture;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class TrinketSlotBackSprites {
|
||||
private static final Identifier BLANK_FACE = new Identifier("trinkets", "textures/gui/blank_back.png");
|
||||
|
||||
private static final Map<Identifier, Identifier> CACHE = new HashMap<>();
|
||||
|
||||
public static Identifier getBackSprite(Identifier originalSprite) {
|
||||
return CACHE.computeIfAbsent(originalSprite, TrinketSlotBackSprites::generateTransparentSprite);
|
||||
}
|
||||
|
||||
private static Identifier generateTransparentSprite(Identifier originalId) {
|
||||
return readImage(BLANK_FACE, blank -> {
|
||||
return readImage(originalId, original -> {
|
||||
NativeImage generatedImage = new NativeImage(original.getWidth(), original.getHeight(), false);
|
||||
final float widthScale = original.getWidth() / (float)blank.getWidth();
|
||||
final float heightScale = original.getHeight() / (float)blank.getHeight();
|
||||
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
int blankColor = blank.getColor((int)(x * widthScale), (int)(y * heightScale));
|
||||
int originalColor = original.getColor(x, y);
|
||||
|
||||
generatedImage.setColor(x, y, blankColor == originalColor ? 0 : originalColor);
|
||||
}
|
||||
}
|
||||
|
||||
return MinecraftClient.getInstance().getTextureManager().registerDynamicTexture("trinket_slot" + originalId.getPath(), new NativeImageBackedTexture(generatedImage));
|
||||
}).orElse(originalId);
|
||||
}).orElse(originalId);
|
||||
}
|
||||
|
||||
private static <T> Optional<T> readImage(Identifier id, Function<NativeImage, T> consumer) {
|
||||
return MinecraftClient.getInstance().getResourceManager().getResource(id).map(input -> {
|
||||
try (NativeImage image = NativeImage.read(input.getInputStream())) {
|
||||
return consumer.apply(image);
|
||||
} catch (Exception e) {
|
||||
Unicopia.LOGGER.error("Error whilst reading slot background resource " + id, e);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@ import java.util.stream.Collectors;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import com.minelittlepony.unicopia.EntityConvertable;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.container.SpellbookScreenHandler;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
@ -89,6 +90,10 @@ public interface TrinketsDelegate {
|
|||
|
||||
}
|
||||
|
||||
default Optional<Slot> createSlot(SpellbookScreenHandler handler, LivingEntity entity, Identifier slotId, int i, int x, int y) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
default boolean isTrinketSlot(Slot slot) {
|
||||
return false;
|
||||
}
|
||||
|
@ -107,4 +112,10 @@ public interface TrinketsDelegate {
|
|||
TrinketsDelegate.getInstance().setEquippedStack(asEntity(), slot, stack);
|
||||
}
|
||||
}
|
||||
|
||||
interface SlotWithForeground {
|
||||
Identifier EMPTY_TEXTURE = Unicopia.id("transparent");
|
||||
|
||||
Identifier getForegroundIdentifier();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ import java.util.*;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.minelittlepony.unicopia.container.SpellbookScreenHandler;
|
||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||
import com.minelittlepony.unicopia.util.InventoryUtil;
|
||||
|
||||
import dev.emi.trinkets.TrinketSlot;
|
||||
import dev.emi.trinkets.api.*;
|
||||
import dev.emi.trinkets.api.TrinketEnums.DropRule;
|
||||
|
@ -24,6 +24,7 @@ import net.minecraft.world.event.GameEvent;
|
|||
|
||||
public class TrinketsDelegateImpl implements TrinketsDelegate {
|
||||
public static final TrinketsDelegateImpl INSTANCE = new TrinketsDelegateImpl();
|
||||
|
||||
// who tf designed this api?
|
||||
|
||||
@Override
|
||||
|
@ -104,9 +105,25 @@ public class TrinketsDelegateImpl implements TrinketsDelegate {
|
|||
.flatMap(group -> group.values().stream());
|
||||
}
|
||||
|
||||
public Optional<SlotGroup> getGroup(LivingEntity entity, Identifier slotId) {
|
||||
return TrinketsApi.getTrinketComponent(entity)
|
||||
.stream()
|
||||
.map(component -> component.getGroups().get(slotId.getNamespace()))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Slot> createSlot(SpellbookScreenHandler handler, LivingEntity entity, Identifier slotId, int i, int x, int y) {
|
||||
return getGroup(entity, slotId).flatMap(group -> {
|
||||
return getInventory(entity, slotId).map(inventory -> {
|
||||
return new SpellbookTrinketSlot(handler, inventory, i, x, y, group);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrinketSlot(Slot slot) {
|
||||
return slot instanceof TrinketSlot;
|
||||
return slot instanceof TrinketSlot || slot instanceof SpellbookTrinketSlot;
|
||||
}
|
||||
|
||||
private static Identifier getSlotId(SlotType slotType) {
|
||||
|
|
Loading…
Reference in a new issue