mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 06:26:43 +01:00
Expand on spell crafting
This commit is contained in:
parent
7949ccff2e
commit
338491d052
8 changed files with 298 additions and 42 deletions
|
@ -0,0 +1,71 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.crafting;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
|
||||
public class IngredientWithSpell implements Predicate<ItemStack> {
|
||||
|
||||
private Optional<Ingredient> stack = Optional.empty();
|
||||
private Optional<SpellType<?>> spell = Optional.empty();
|
||||
|
||||
private IngredientWithSpell() {}
|
||||
|
||||
@Override
|
||||
public boolean test(ItemStack t) {
|
||||
boolean stackMatch = stack.map(m -> m.test(t)).orElse(true);
|
||||
boolean spellMatch = spell.map(m -> GemstoneItem.getSpellKey(t).equals(m)).orElse(true);
|
||||
return stackMatch && spellMatch;
|
||||
}
|
||||
|
||||
public void write(PacketByteBuf buf) {
|
||||
stack.ifPresentOrElse(i -> {
|
||||
buf.writeBoolean(true);
|
||||
i.write(buf);
|
||||
}, () -> buf.writeBoolean(false));
|
||||
spell.ifPresentOrElse(i -> {
|
||||
buf.writeBoolean(true);
|
||||
buf.writeIdentifier(i.getId());
|
||||
}, () -> buf.writeBoolean(false));
|
||||
}
|
||||
|
||||
public static IngredientWithSpell fromPacket(PacketByteBuf buf) {
|
||||
IngredientWithSpell ingredient = new IngredientWithSpell();
|
||||
|
||||
if (buf.readBoolean()) {
|
||||
ingredient.stack = Optional.ofNullable(Ingredient.fromPacket(buf));
|
||||
}
|
||||
if (buf.readBoolean()) {
|
||||
ingredient.spell = Optional.of(SpellType.getKey(buf.readIdentifier()));
|
||||
}
|
||||
|
||||
return ingredient;
|
||||
}
|
||||
|
||||
public static IngredientWithSpell fromJson(JsonObject json) {
|
||||
|
||||
IngredientWithSpell ingredient = new IngredientWithSpell();
|
||||
|
||||
if (json.has("item") || json.has("spell")) {
|
||||
if (json.has("item")) {
|
||||
ingredient.stack = Optional.ofNullable(Ingredient.fromJson(JsonHelper.getObject(json, "item")));
|
||||
}
|
||||
if (json.has("spell")) {
|
||||
ingredient.spell = Optional.ofNullable(Identifier.tryParse(JsonHelper.getString(json, "spell"))).map(SpellType::getKey);
|
||||
}
|
||||
} else {
|
||||
ingredient.stack = Optional.ofNullable(Ingredient.fromJson(json));
|
||||
}
|
||||
|
||||
return ingredient;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.crafting;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
|
||||
public class TraitIngredient implements Predicate<SpellTraits> {
|
||||
|
||||
private Optional<SpellTraits> min = Optional.empty();
|
||||
private Optional<SpellTraits> max = Optional.empty();
|
||||
|
||||
private TraitIngredient() {}
|
||||
|
||||
@Override
|
||||
public boolean test(SpellTraits t) {
|
||||
boolean minMatch = min.map(m -> t.includes(m)).orElse(true);
|
||||
boolean maxMatch = max.map(m -> m.includes(t)).orElse(true);
|
||||
return minMatch && maxMatch;
|
||||
}
|
||||
|
||||
public void write(PacketByteBuf buf) {
|
||||
min.ifPresentOrElse(m -> {
|
||||
buf.writeBoolean(true);
|
||||
m.write(buf);
|
||||
}, () -> buf.writeBoolean(false));
|
||||
max.ifPresentOrElse(m -> {
|
||||
buf.writeBoolean(true);
|
||||
m.write(buf);
|
||||
}, () -> buf.writeBoolean(false));
|
||||
}
|
||||
|
||||
public static TraitIngredient fromPacket(PacketByteBuf buf) {
|
||||
TraitIngredient ingredient = new TraitIngredient();
|
||||
|
||||
if (buf.readBoolean()) {
|
||||
ingredient.min = SpellTraits.fromPacket(buf);
|
||||
}
|
||||
if (buf.readBoolean()) {
|
||||
ingredient.max = SpellTraits.fromPacket(buf);
|
||||
}
|
||||
|
||||
return ingredient;
|
||||
}
|
||||
|
||||
public static TraitIngredient fromJson(JsonObject json) {
|
||||
|
||||
TraitIngredient ingredient = new TraitIngredient();
|
||||
|
||||
if (json.has("min") || json.has("max")) {
|
||||
if (json.has("min")) {
|
||||
ingredient.min = SpellTraits.fromJson(JsonHelper.getObject(json, "min"));
|
||||
}
|
||||
if (json.has("max")) {
|
||||
ingredient.max = SpellTraits.fromJson(JsonHelper.getObject(json, "max"));
|
||||
}
|
||||
} else {
|
||||
ingredient.min = SpellTraits.fromJson(json);
|
||||
}
|
||||
|
||||
return ingredient;
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.item.URecipes;
|
|||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.ShapedRecipe;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -17,13 +16,12 @@ import net.minecraft.util.JsonHelper;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
public class TraitRequirementRecipe implements SpellbookRecipe {
|
||||
|
||||
private final Identifier id;
|
||||
private final Ingredient requirement;
|
||||
private final SpellTraits requiredTraits;
|
||||
private final IngredientWithSpell requirement;
|
||||
private final TraitIngredient requiredTraits;
|
||||
private final ItemStack output;
|
||||
|
||||
private TraitRequirementRecipe(Identifier id, Ingredient requirement, SpellTraits requiredTraits, ItemStack output) {
|
||||
private TraitRequirementRecipe(Identifier id, IngredientWithSpell requirement, TraitIngredient requiredTraits, ItemStack output) {
|
||||
this.id = id;
|
||||
this.requirement = requirement;
|
||||
this.requiredTraits = requiredTraits;
|
||||
|
@ -33,14 +31,18 @@ public class TraitRequirementRecipe implements SpellbookRecipe {
|
|||
@Override
|
||||
public boolean matches(SpellbookInventory inventory, World world) {
|
||||
return requirement.test(inventory.getItemToModify())
|
||||
&& SpellTraits.of(inventory).includes(requiredTraits);
|
||||
&& requiredTraits.test(SpellTraits.union(
|
||||
SpellTraits.of(inventory.getItemToModify()),
|
||||
inventory.getTraits(),
|
||||
SpellTraits.of(output)
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack craft(SpellbookInventory inventory) {
|
||||
return SpellTraits.union(
|
||||
SpellTraits.of(inventory.getItemToModify()),
|
||||
SpellTraits.of(inventory),
|
||||
inventory.getTraits(),
|
||||
SpellTraits.of(output)
|
||||
).applyTo(output);
|
||||
}
|
||||
|
@ -81,16 +83,16 @@ public class TraitRequirementRecipe implements SpellbookRecipe {
|
|||
@Override
|
||||
public TraitRequirementRecipe read(Identifier id, JsonObject json) {
|
||||
return new TraitRequirementRecipe(id,
|
||||
Ingredient.fromJson(JsonHelper.getObject(json, "material")),
|
||||
SpellTraits.fromJson(JsonHelper.getObject(json, "traits")).get(),
|
||||
IngredientWithSpell.fromJson(JsonHelper.getObject(json, "material")),
|
||||
TraitIngredient.fromJson(JsonHelper.getObject(json, "traits")),
|
||||
outputFromJson(JsonHelper.getObject(json, "result")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraitRequirementRecipe read(Identifier id, PacketByteBuf buf) {
|
||||
return new TraitRequirementRecipe(id,
|
||||
Ingredient.fromPacket(buf),
|
||||
SpellTraits.fromPacket(buf).get(),
|
||||
IngredientWithSpell.fromPacket(buf),
|
||||
TraitIngredient.fromPacket(buf),
|
||||
buf.readItemStack()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,11 +4,14 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -26,7 +29,7 @@ import net.minecraft.text.LiteralText;
|
|||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class SpellTraits {
|
||||
public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||
public static final SpellTraits EMPTY = new SpellTraits(Map.of());
|
||||
|
||||
private final Map<Trait, Float> traits;
|
||||
|
@ -35,20 +38,47 @@ public final class SpellTraits {
|
|||
this.traits = traits;
|
||||
}
|
||||
|
||||
SpellTraits(SpellTraits from) {
|
||||
this(new EnumMap<>(from.traits));
|
||||
}
|
||||
|
||||
public SpellTraits multiply(float factor) {
|
||||
return factor == 0 ? EMPTY : map(v -> v * factor);
|
||||
}
|
||||
|
||||
public SpellTraits map(Function<Float, Float> function) {
|
||||
if (isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Map<Trait, Float> newMap = new EnumMap<>(traits);
|
||||
newMap.entrySet().forEach(entry -> entry.setValue(function.apply(entry.getValue())));
|
||||
return fromEntries(newMap.entrySet().stream()).orElse(EMPTY);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return traits.isEmpty();
|
||||
}
|
||||
|
||||
public boolean includes(SpellTraits other) {
|
||||
return other.entries().stream().allMatch(pair -> {
|
||||
return other.stream().allMatch(pair -> {
|
||||
return getAmount(pair.getKey()) >= pair.getValue();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Entry<Trait, Float>> iterator() {
|
||||
return entries().iterator();
|
||||
}
|
||||
|
||||
public Set<Map.Entry<Trait, Float>> entries() {
|
||||
return traits.entrySet();
|
||||
}
|
||||
|
||||
public Stream<Map.Entry<Trait, Float>> stream() {
|
||||
return entries().stream();
|
||||
}
|
||||
|
||||
public float getAmount(Trait trait) {
|
||||
return traits.getOrDefault(trait, 0F);
|
||||
}
|
||||
|
@ -179,12 +209,15 @@ public final class SpellTraits {
|
|||
|
||||
static void combine(Map<Trait, Float> to, Map<Trait, Float> from) {
|
||||
from.forEach((trait, value) -> {
|
||||
to.compute(trait, (k, v) -> v == null ? value : (v + value));
|
||||
if (value != 0) {
|
||||
to.compute(trait, (k, v) -> v == null ? value : (v + value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static Map<Trait, Float> collect(Stream<Map.Entry<Trait, Float>> entries) {
|
||||
return entries.filter(Objects::nonNull)
|
||||
.filter(e -> e.getValue() != 0)
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a + b, () -> new EnumMap<>(Trait.class)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> {
|
|||
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);
|
||||
// drawStringWithShadow(matrices, this.textRenderer, ((SpellbookSlot)slot).getRing() + "", slot.x, slot.y, 0x000000FF);
|
||||
}
|
||||
}
|
||||
RenderSystem.disableBlend();
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.item.URecipes;
|
||||
|
@ -18,14 +19,13 @@ import net.minecraft.inventory.Inventory;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
import net.minecraft.screen.slot.CraftingResultSlot;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SpellbookScreenHandler extends ScreenHandler {
|
||||
|
||||
|
@ -42,12 +42,19 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
|
||||
private final PlayerInventory inventory;
|
||||
|
||||
private final ScreenHandlerContext context;
|
||||
|
||||
protected SpellbookScreenHandler(int syncId, PlayerInventory inv) {
|
||||
this(syncId, inv, ScreenHandlerContext.EMPTY);
|
||||
}
|
||||
|
||||
public SpellbookScreenHandler(int syncId, PlayerInventory inv, ScreenHandlerContext context) {
|
||||
super(UScreenHandlers.SPELL_BOOK, syncId);
|
||||
inventory = inv;
|
||||
this.context = context;
|
||||
|
||||
List<Pair<Integer, Integer>> grid = new ArrayList<>();
|
||||
List<Pair<Integer, Integer>> gemPos = new ArrayList<>();
|
||||
List<int[]> grid = new ArrayList<>();
|
||||
List<int[]> gemPos = new ArrayList<>();
|
||||
createGrid(grid, gemPos);
|
||||
|
||||
GEM_SLOT_INDEX = MAX_INGREDIENTS = grid.size();
|
||||
|
@ -58,10 +65,10 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
|
||||
for (int i = 0; i < MAX_INGREDIENTS; i++) {
|
||||
var pos = grid.get(i);
|
||||
addSlot(new InputSlot(input, i, pos.getLeft(), pos.getRight()));
|
||||
addSlot(new InputSlot(input, i, pos));
|
||||
}
|
||||
|
||||
addSlot(gemSlot = new OutputSlot(inventory.player, input, result, 0, gemPos.get(0).getLeft(), gemPos.get(0).getRight()));
|
||||
addSlot(gemSlot = new OutputSlot(inventory.player, input, result, 0, gemPos.get(0)));
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
addSlot(new Slot(inventory, i, 121 + i * 18, 195));
|
||||
|
@ -77,16 +84,16 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
|
||||
@Override
|
||||
public void onContentChanged(Inventory inventory) {
|
||||
World world = this.inventory.player.world;
|
||||
if (!world.isClient && !gemSlot.getStack().isEmpty()) {
|
||||
world.getServer().getRecipeManager().getFirstMatch(URecipes.SPELLBOOK, input, world)
|
||||
.filter(recipe -> result.shouldCraftRecipe(world, (ServerPlayerEntity)this.inventory.player, recipe))
|
||||
.map(recipe -> {
|
||||
this.inventory.player.playSound(SoundEvents.BLOCK_END_PORTAL_FRAME_FILL, SoundCategory.MASTER, 1, 0.3F);
|
||||
return recipe.craft(input);
|
||||
})
|
||||
.ifPresentOrElse(gemSlot::setCrafted, gemSlot::setUncrafted);
|
||||
}
|
||||
context.run((world, pos) -> {
|
||||
if (!world.isClient && !gemSlot.getStack().isEmpty()) {
|
||||
world.getServer().getRecipeManager().getFirstMatch(URecipes.SPELLBOOK, input, world)
|
||||
.filter(recipe -> result.shouldCraftRecipe(world, (ServerPlayerEntity)this.inventory.player, recipe))
|
||||
.map(recipe -> recipe.craft(input))
|
||||
.ifPresentOrElse(gemSlot::setCrafted, gemSlot::setUncrafted);
|
||||
|
||||
((ServerPlayerEntity)this.inventory.player).networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(syncId, GEM_SLOT_INDEX, gemSlot.getStack()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -190,11 +197,18 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
public void close(PlayerEntity playerEntity) {
|
||||
gemSlot.setUncrafted();
|
||||
super.close(playerEntity);
|
||||
dropInventory(playerEntity, input);
|
||||
dropInventory(playerEntity, result);
|
||||
context.run((world, pos) -> {
|
||||
dropInventory(playerEntity, input);
|
||||
dropInventory(playerEntity, result);
|
||||
});
|
||||
}
|
||||
|
||||
private static void createGrid(List<Pair<Integer, Integer>> grid, List<Pair<Integer, Integer>> gemPos) {
|
||||
/**
|
||||
* Creates a hexagonal crafting grid.
|
||||
* @param grid Output for normal slot positions.
|
||||
* @param gemPos Output for the gem slot position.
|
||||
*/
|
||||
private static void createGrid(List<int[]> grid, List<int[]> gemPos) {
|
||||
int cols = 4;
|
||||
int spacing = 23;
|
||||
|
||||
|
@ -203,7 +217,25 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
|
||||
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));
|
||||
|
||||
int ring = 3;
|
||||
if (row == 0 || row == 6) {
|
||||
ring = 1;
|
||||
} else if ((row == 1 || row == 5) && i > 0 && i < cols - 1) {
|
||||
ring = 2;
|
||||
} else {
|
||||
if (i == 0 || i == cols - 1) {
|
||||
ring = 1;
|
||||
} else if (i == 1 || i == cols - 2) {
|
||||
ring = 2;
|
||||
}
|
||||
}
|
||||
|
||||
(row == 3 && i == 3 ? gemPos : grid).add(new int[] {
|
||||
left + (i * spacing),
|
||||
top,
|
||||
row == 3 && i == 3 ? 4 : ring
|
||||
});
|
||||
}
|
||||
top += spacing * 0.9;
|
||||
left -= (spacing / 2) * (row > 2 ? -1 : 1);
|
||||
|
@ -211,7 +243,9 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
}
|
||||
}
|
||||
|
||||
public interface SpellbookSlot {}
|
||||
public interface SpellbookSlot {
|
||||
int getRing();
|
||||
}
|
||||
|
||||
public class SpellbookInventory extends CraftingInventory {
|
||||
|
||||
|
@ -220,38 +254,74 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
}
|
||||
|
||||
public ItemStack getItemToModify() {
|
||||
return gemSlot.getStack();
|
||||
return gemSlot.uncrafted.orElse(gemSlot.getStack());
|
||||
}
|
||||
|
||||
public int getRing(int slot) {
|
||||
Slot s = slots.get(slot);
|
||||
return s instanceof SpellbookSlot ? ((SpellbookSlot)s).getRing() : 0;
|
||||
}
|
||||
|
||||
public SpellTraits getTraits() {
|
||||
return SpellTraits.union(InventoryUtil.slots(this)
|
||||
.map(slot -> SpellTraits.of(getStack(slot)).multiply(getRingFactor(getRing(slot))))
|
||||
.toArray(SpellTraits[]::new)
|
||||
);
|
||||
}
|
||||
|
||||
public static float getRingFactor(int ring) {
|
||||
switch (ring) {
|
||||
case 1: return 1;
|
||||
case 2: return 0.6F;
|
||||
case 3: return 0.3F;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InputSlot extends Slot implements SpellbookSlot {
|
||||
public InputSlot(Inventory inventory, int index, int xPosition, int yPosition) {
|
||||
super(inventory, index, xPosition, yPosition);
|
||||
private final int ring;
|
||||
|
||||
public InputSlot(Inventory inventory, int index, int[] params) {
|
||||
super(inventory, index, params[0], params[1]);
|
||||
ring = params[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxItemCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRing() {
|
||||
return ring;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OutputSlot extends CraftingResultSlot implements SpellbookSlot {
|
||||
|
||||
private Optional<ItemStack> uncrafted = Optional.empty();
|
||||
|
||||
private final PlayerEntity player;
|
||||
private final SpellbookInventory input;
|
||||
|
||||
public OutputSlot(PlayerEntity player, SpellbookInventory input, Inventory inventory, int index, int x, int y) {
|
||||
super(player, input, inventory, index, x, y);
|
||||
private final int ring;
|
||||
|
||||
public OutputSlot(PlayerEntity player, SpellbookInventory input, Inventory inventory, int index, int[] params) {
|
||||
super(player, input, inventory, index, params[0], params[1]);
|
||||
this.player = player;
|
||||
this.input = input;
|
||||
this.ring = params[2];
|
||||
}
|
||||
|
||||
public void setCrafted(ItemStack crafted) {
|
||||
uncrafted = uncrafted.or(() -> Optional.of(getStack()));
|
||||
setStack(crafted);
|
||||
player.playSound(SoundEvents.BLOCK_END_PORTAL_FRAME_FILL, SoundCategory.MASTER, 1, 0.3F);
|
||||
}
|
||||
|
||||
public void setUncrafted() {
|
||||
player.playSound(SoundEvents.BLOCK_END_PORTAL_FRAME_FILL, SoundCategory.MASTER, 0.2F, 0.2F);
|
||||
uncrafted = uncrafted.filter(stack -> {
|
||||
setStack(stack);
|
||||
return false;
|
||||
|
@ -268,6 +338,11 @@ public class SpellbookScreenHandler extends ScreenHandler {
|
|||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRing() {
|
||||
return ring;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeItem(PlayerEntity player, ItemStack stack) {
|
||||
if (uncrafted.isPresent()) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.entity;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.container.UScreenHandlers;
|
||||
import com.minelittlepony.unicopia.container.SpellbookScreenHandler;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
|
@ -18,6 +18,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
import net.minecraft.screen.SimpleNamedScreenHandlerFactory;
|
||||
import net.minecraft.sound.BlockSoundGroup;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
|
@ -197,7 +198,7 @@ public class SpellbookEntity extends MobEntity {
|
|||
|
||||
if (isOpen() && EquinePredicates.PLAYER_UNICORN.test(player)) {
|
||||
setBored(false);
|
||||
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((syncId, inv, ply) -> UScreenHandlers.SPELL_BOOK.create(syncId, inv), getDisplayName()));
|
||||
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((syncId, inv, ply) -> new SpellbookScreenHandler(syncId, inv, ScreenHandlerContext.create(world, getBlockPos())), getDisplayName()));
|
||||
player.playSound(SoundEvents.ITEM_BOOK_PAGE_TURN, 2, 1);
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.minelittlepony.unicopia.util;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.AbstractIterator;
|
||||
|
||||
import net.minecraft.inventory.Inventory;
|
||||
|
@ -19,4 +21,8 @@ public interface InventoryUtil {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
static Stream<Integer> slots(Inventory inventory) {
|
||||
return Stream.iterate(0, i -> i < inventory.size(), i -> i + 1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue