mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-17 10:24:23 +01:00
Migrate to TLA. Closes #263
This commit is contained in:
parent
79030b43c7
commit
3b1fab888f
16 changed files with 618 additions and 663 deletions
|
@ -102,6 +102,19 @@ public class ItemTraitsTooltipRenderer implements Text, OrderedText, TooltipComp
|
|||
}
|
||||
}
|
||||
|
||||
public static void renderStackSingleTrait(Trait trait, float amount, DrawContext context, float x, float y, float weight, float delta, int seed, boolean revealAll) {
|
||||
float time = MathHelper.cos((MinecraftClient.getInstance().player.age + delta + seed) / 2F) * 0.7F;
|
||||
|
||||
float angle = 0.7F + (time / 30F) % MathHelper.TAU;
|
||||
float r = 9 + 2 * MathHelper.sin(delta / 20F);
|
||||
|
||||
ItemTraitsTooltipRenderer.renderTraitIcon(trait, amount * weight, context,
|
||||
x + r * MathHelper.sin(angle),
|
||||
y + r * MathHelper.cos(angle),
|
||||
revealAll || isKnown(trait)
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean isKnown(Trait trait) {
|
||||
return MinecraftClient.getInstance().player == null
|
||||
|| Pony.of(MinecraftClient.getInstance().player).getDiscoveries().isKnown(trait);
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package com.minelittlepony.unicopia.compat.emi;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||
|
||||
import dev.emi.emi.api.recipe.EmiCraftingRecipe;
|
||||
import dev.emi.emi.api.stack.EmiIngredient;
|
||||
import dev.emi.emi.api.stack.EmiStack;
|
||||
import dev.emi.emi.recipe.EmiShapedRecipe;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.CraftingRecipe;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
|
||||
public class MagicalShapedEmiRecipe extends EmiCraftingRecipe {
|
||||
public MagicalShapedEmiRecipe(RecipeEntry<? extends CraftingRecipe> recipe, CustomisedSpellType<?> spellEffect, ItemStack output) {
|
||||
super(padIngredients(recipe, spellEffect), EmiStack.of(output),
|
||||
recipe.id().withPath(p -> p + "/" + spellEffect.type().getId().getPath()), false);
|
||||
EmiShapedRecipe.setRemainders(input, recipe.value());
|
||||
}
|
||||
|
||||
private static List<EmiIngredient> padIngredients(RecipeEntry<? extends CraftingRecipe> recipe, CustomisedSpellType<?> spellEffect) {
|
||||
List<EmiIngredient> list = recipe.value().getIngredients().stream()
|
||||
.map(ingredient -> remapIngredient(ingredient, spellEffect))
|
||||
.collect(Collectors.toList());
|
||||
while (list.size() < 9) {
|
||||
list.add(EmiStack.EMPTY);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static EmiIngredient remapIngredient(Ingredient ingredient, CustomisedSpellType<?> spellEffect) {
|
||||
ItemStack[] stacks = ingredient.getMatchingStacks();
|
||||
|
||||
for (int i = 0; i < stacks.length; i++) {
|
||||
if (stacks[i].getItem() instanceof EnchantableItem) {
|
||||
stacks = Arrays.copyOf(stacks, stacks.length);
|
||||
stacks[i] = EnchantableItem.enchant(stacks[i].copy(), spellEffect.type());
|
||||
return EmiIngredient.of(Arrays.stream(stacks).map(EmiStack::of).toList());
|
||||
}
|
||||
}
|
||||
|
||||
return EmiIngredient.of(ingredient);
|
||||
}
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
package com.minelittlepony.unicopia.compat.emi;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellDuplicatingRecipe;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellEnhancingRecipe;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellShapedCraftingRecipe;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.block.state.Schematic;
|
||||
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.item.group.MultiItem;
|
||||
import com.minelittlepony.unicopia.recipe.TransformCropsRecipe;
|
||||
import com.minelittlepony.unicopia.recipe.URecipes;
|
||||
|
||||
import dev.emi.emi.api.EmiPlugin;
|
||||
import dev.emi.emi.api.EmiRegistry;
|
||||
import dev.emi.emi.api.recipe.EmiRecipeCategory;
|
||||
import dev.emi.emi.api.render.EmiTexture;
|
||||
import dev.emi.emi.api.stack.Comparison;
|
||||
import dev.emi.emi.api.stack.EmiStack;
|
||||
import dev.emi.emi.recipe.EmiStonecuttingRecipe;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.recipe.RecipeType;
|
||||
import net.minecraft.registry.DynamicRegistryManager;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class Main implements EmiPlugin {
|
||||
static final EmiStack SPELL_BOOK_STATION = EmiStack.of(UItems.SPELLBOOK);
|
||||
static final EmiStack CLOUD_SHAPING_STATION = EmiStack.of(UBlocks.SHAPING_BENCH);
|
||||
static final EmiStack GROWING_STATION = EmiStack.of(Blocks.FARMLAND);
|
||||
static final EmiStack ALTAR_STATION = EmiStack.of(Blocks.CRYING_OBSIDIAN);
|
||||
static final EmiRecipeCategory SPELL_BOOK_CATEGORY = new EmiRecipeCategory(Unicopia.id("spellbook"), SPELL_BOOK_STATION, SPELL_BOOK_STATION);
|
||||
static final EmiRecipeCategory CLOUD_SHAPING_CATEGORY = new EmiRecipeCategory(Unicopia.id("cloud_shaping"), CLOUD_SHAPING_STATION, CLOUD_SHAPING_STATION);
|
||||
static final EmiRecipeCategory GROWING_CATEGORY = new EmiRecipeCategory(Unicopia.id("growing"), GROWING_STATION, GROWING_STATION);
|
||||
static final EmiRecipeCategory ALTAR_CATEGORY = new EmiRecipeCategory(Unicopia.id("altar"), ALTAR_STATION, ALTAR_STATION);
|
||||
|
||||
static final Identifier WIDGETS = Unicopia.id("textures/gui/widgets.png");
|
||||
static final EmiTexture EMPTY_ARROW = new EmiTexture(WIDGETS, 44, 0, 24, 17);
|
||||
|
||||
@Override
|
||||
public void register(EmiRegistry registry) {
|
||||
registry.addCategory(SPELL_BOOK_CATEGORY);
|
||||
registry.addWorkstation(SPELL_BOOK_CATEGORY, SPELL_BOOK_STATION);
|
||||
registry.getRecipeManager().listAllOfType(URecipes.SPELLBOOK).forEach(recipe -> {
|
||||
|
||||
if (recipe.value() instanceof SpellDuplicatingRecipe) {
|
||||
registry.addRecipe(new SpellDuplicatingEmiRecipe(recipe));
|
||||
} else if (recipe.value() instanceof SpellEnhancingRecipe enhancingRecipe) {
|
||||
Trait.all().forEach(trait -> {
|
||||
registry.addRecipe(new SpellDuplicatingEmiRecipe(recipe) {
|
||||
private final Identifier id;
|
||||
|
||||
{
|
||||
id = recipe.id().withPath(p -> p + "/" + trait.getId().getPath());
|
||||
input(trait);
|
||||
this.getOutputs().addAll(
|
||||
Arrays.stream(enhancingRecipe.getBaseMaterial().getMatchingStacks())
|
||||
.map(stack -> EmiStack.of(SpellTraits.of(stack).add(new SpellTraits.Builder().with(trait, 1).build()).applyTo(stack)).comparison(c -> Comparison.DEFAULT_COMPARISON))
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
registry.addRecipe(new SpellbookEmiRecipe(recipe));
|
||||
}
|
||||
});
|
||||
|
||||
registry.addCategory(CLOUD_SHAPING_CATEGORY);
|
||||
registry.addWorkstation(CLOUD_SHAPING_CATEGORY, CLOUD_SHAPING_STATION);
|
||||
registry.getRecipeManager().listAllOfType(URecipes.CLOUD_SHAPING).forEach(recipe -> {
|
||||
registry.addRecipe(new EmiStonecuttingRecipe(recipe.value()) {
|
||||
@Override
|
||||
public EmiRecipeCategory getCategory() {
|
||||
return CLOUD_SHAPING_CATEGORY;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Stream.of(UItems.GEMSTONE, UItems.BOTCHED_GEM, UItems.MAGIC_STAFF, UItems.FILLED_JAR).forEach(item -> {
|
||||
registry.setDefaultComparison(item, comparison -> Comparison.compareComponents());
|
||||
});
|
||||
|
||||
DynamicRegistryManager registries = DynamicRegistryManager.of(Registries.REGISTRIES);
|
||||
registry.getRecipeManager().listAllOfType(RecipeType.CRAFTING).stream()
|
||||
.filter(recipe -> recipe.value() instanceof SpellShapedCraftingRecipe)
|
||||
.forEach(recipe -> {
|
||||
ItemStack output = recipe.value().getResult(registries);
|
||||
if (output.getItem() instanceof MultiItem multiItem) {
|
||||
multiItem.getDefaultStacks().forEach(outputVariation -> {
|
||||
if (EnchantableItem.isEnchanted(outputVariation)) {
|
||||
registry.addRecipe(new MagicalShapedEmiRecipe(recipe, EnchantableItem.getSpellEffect(outputVariation), outputVariation));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
registry.addCategory(GROWING_CATEGORY);
|
||||
registry.addWorkstation(GROWING_CATEGORY, GROWING_STATION);
|
||||
registry.getRecipeManager().listAllOfType(URecipes.GROWING).forEach(recipe -> {
|
||||
registry.addRecipe(new StructureInteractionEmiRecipe(
|
||||
GROWING_CATEGORY,
|
||||
recipe.id(),
|
||||
new Schematic.Builder()
|
||||
.fill(0, 0, 0, 6, 0, 6, recipe.value().getCatalystState())
|
||||
.set(3, 0, 3, Blocks.FARMLAND.getDefaultState())
|
||||
.set(3, 1, 3, recipe.value().getTargetState())
|
||||
.build(),
|
||||
List.of(EmiStack.of(recipe.value().getTarget()), EmiStack.of(recipe.value().getCatalyst(), TransformCropsRecipe.AREA)),
|
||||
EmiStack.of(recipe.value().getOutput()),
|
||||
Unicopia.id("textures/gui/ability/grow.png")
|
||||
));
|
||||
});
|
||||
|
||||
registry.addCategory(ALTAR_CATEGORY);
|
||||
registry.addWorkstation(ALTAR_CATEGORY, ALTAR_STATION);
|
||||
registry.addRecipe(new StructureInteractionEmiRecipe(
|
||||
ALTAR_CATEGORY,
|
||||
Unicopia.id("altar/spectral_clock"),
|
||||
Schematic.ALTAR,
|
||||
List.of(
|
||||
EmiStack.of(Items.CLOCK),
|
||||
EmiStack.of(UItems.SPELLBOOK),
|
||||
EmiStack.of(Blocks.SOUL_SAND),
|
||||
EmiStack.of(Blocks.LODESTONE),
|
||||
EmiStack.of(Blocks.OBSIDIAN, 8 * 4 + 8)
|
||||
),
|
||||
EmiStack.of(UItems.SPECTRAL_CLOCK),
|
||||
Unicopia.id("textures/gui/race/alicorn.png")
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package com.minelittlepony.unicopia.compat.emi;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellbookRecipe;
|
||||
|
||||
import dev.emi.emi.EmiPort;
|
||||
import dev.emi.emi.EmiRenderHelper;
|
||||
import dev.emi.emi.api.stack.EmiIngredient;
|
||||
import dev.emi.emi.api.stack.EmiStack;
|
||||
import dev.emi.emi.api.stack.ListEmiIngredient;
|
||||
import dev.emi.emi.runtime.EmiDrawContext;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
|
||||
public class SpellDuplicatingEmiRecipe extends SpellbookEmiRecipe {
|
||||
|
||||
public SpellDuplicatingEmiRecipe(RecipeEntry<SpellbookRecipe> recipe) {
|
||||
super(recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(ItemStack... stacks) {
|
||||
getInputs().add(new CyclingRecipeIngredient(Arrays.stream(stacks).map(EmiStack::of).toList(), 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EmiIngredient getOutput() {
|
||||
return new CyclingRecipeIngredient(getOutputs(), 2);
|
||||
}
|
||||
|
||||
static class CyclingRecipeIngredient extends ListEmiIngredient {
|
||||
|
||||
private final List<? extends EmiIngredient> ingredients;
|
||||
private final int maxCount;
|
||||
|
||||
public CyclingRecipeIngredient(List<? extends EmiIngredient> ingredients, long amount) {
|
||||
super(ingredients, amount);
|
||||
this.ingredients = ingredients;
|
||||
this.maxCount = ingredients.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int x, int y, float delta, int flags) {
|
||||
|
||||
if (maxCount < 2 || MinecraftClient.getInstance().player == null) {
|
||||
super.render(context, x, y, delta, flags);
|
||||
} else {
|
||||
int tick = (MinecraftClient.getInstance().player.age / 12) % maxCount;
|
||||
if ((flags & RENDER_AMOUNT) != 0) {
|
||||
String count = "";
|
||||
if (getAmount() != 1) {
|
||||
count += getAmount();
|
||||
}
|
||||
EmiRenderHelper.renderAmount(EmiDrawContext.wrap(context), x, y, EmiPort.literal(count));
|
||||
}
|
||||
ingredients.get(tick).render(context, x, y, delta, flags & ~RENDER_AMOUNT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
package com.minelittlepony.unicopia.compat.emi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellbookRecipe;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen;
|
||||
import com.minelittlepony.unicopia.container.inventory.HexagonalCraftingGrid;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import dev.emi.emi.api.recipe.EmiRecipe;
|
||||
import dev.emi.emi.api.recipe.EmiRecipeCategory;
|
||||
import dev.emi.emi.api.stack.EmiIngredient;
|
||||
import dev.emi.emi.api.stack.EmiStack;
|
||||
import dev.emi.emi.api.widget.TextureWidget;
|
||||
import dev.emi.emi.api.widget.WidgetHolder;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
class SpellbookEmiRecipe implements EmiRecipe, SpellbookRecipe.CraftingTreeBuilder {
|
||||
|
||||
private final RecipeEntry<SpellbookRecipe> recipe;
|
||||
|
||||
private final List<EmiIngredient> inputs = new ArrayList<>();
|
||||
private final List<EmiStack> outputs = new ArrayList<>();
|
||||
|
||||
public SpellbookEmiRecipe(RecipeEntry<SpellbookRecipe> recipe) {
|
||||
this.recipe = recipe;
|
||||
recipe.value().buildCraftingTree(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmiRecipeCategory getCategory() {
|
||||
return Main.SPELL_BOOK_CATEGORY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return recipe.id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmiIngredient> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmiStack> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayWidth() {
|
||||
return 150;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayHeight() {
|
||||
return 75;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWidgets(WidgetHolder widgets) {
|
||||
widgets.addTexture(SpellbookScreen.TEXTURE, 0, 0, getDisplayWidth(), getDisplayHeight(), 50, 50, 128, 128, 512, 256);
|
||||
widgets.addTexture(Main.EMPTY_ARROW, 85, 30);
|
||||
|
||||
List<HexagonalCraftingGrid.Slot> grid = new ArrayList<>();
|
||||
List<HexagonalCraftingGrid.Slot> gem = new ArrayList<>();
|
||||
HexagonalCraftingGrid.create(-34, -5, 3, grid, gem);
|
||||
|
||||
int currentInput = 1;
|
||||
|
||||
for (int i = 0; i < grid.size(); i++) {
|
||||
var slot = grid.get(i);
|
||||
|
||||
if (currentInput < inputs.size() && slot.weight() == 1) {
|
||||
widgets.add(new SlotTexture(slot));
|
||||
widgets.addSlot(inputs.get(currentInput++), slot.left(), slot.top()).drawBack(false);
|
||||
} else if (slot.weight() == 1) {
|
||||
widgets.add(new SlotTexture(slot));
|
||||
widgets.addSlot(slot.left(), slot.top()).drawBack(false);
|
||||
}
|
||||
}
|
||||
widgets.addSlot(inputs.get(0), gem.get(0).left(), gem.get(0).top()).drawBack(false);
|
||||
widgets.addSlot(getOutput(), 120, 25).large(true).recipeContext(this);
|
||||
}
|
||||
|
||||
protected EmiIngredient getOutput() {
|
||||
return EmiIngredient.of(outputs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(ItemStack... stacks) {
|
||||
inputs.add(EmiIngredient.of(Arrays.stream(stacks).map(EmiStack::of).toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(Trait... traits) {
|
||||
inputs.add(EmiIngredient.of(Arrays.stream(traits).map(trait -> new TraitEmiStack(trait, 1)).toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(Trait trait, float value) {
|
||||
inputs.add(new TraitEmiStack(trait, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void result(ItemStack... stack) {
|
||||
outputs.addAll(Arrays.stream(stack).map(EmiStack::of).toList());
|
||||
}
|
||||
|
||||
static class SlotTexture extends TextureWidget {
|
||||
|
||||
public SlotTexture(HexagonalCraftingGrid.Slot slot) {
|
||||
super(SpellbookScreen.SLOT, slot.left() - 7, slot.top() - 7, 32, 32, 0, 0, 32, 32, 32, 32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
RenderSystem.enableBlend();
|
||||
context.drawTexture(texture, x, y, 0, u, v, width, height, textureWidth, textureHeight);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
package com.minelittlepony.unicopia.compat.emi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.block.state.Schematic;
|
||||
import dev.emi.emi.api.recipe.EmiRecipe;
|
||||
import dev.emi.emi.api.recipe.EmiRecipeCategory;
|
||||
import dev.emi.emi.api.render.EmiTexture;
|
||||
import dev.emi.emi.api.stack.EmiIngredient;
|
||||
import dev.emi.emi.api.stack.EmiStack;
|
||||
import dev.emi.emi.api.widget.WidgetHolder;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.DiffuseLighting;
|
||||
import net.minecraft.client.render.LightmapTextureManager;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class StructureInteractionEmiRecipe implements EmiRecipe {
|
||||
|
||||
private final EmiRecipeCategory category;
|
||||
private final Identifier id;
|
||||
private final Schematic schematic;
|
||||
|
||||
private final List<EmiIngredient> inputs;
|
||||
private final List<EmiStack> output;
|
||||
|
||||
private final Identifier processIcon;
|
||||
|
||||
private int age;
|
||||
|
||||
public StructureInteractionEmiRecipe(EmiRecipeCategory category, Identifier id, Schematic schematic, List<EmiIngredient> inputs, EmiStack output, Identifier processIcon) {
|
||||
this.category = category;
|
||||
this.id = id;
|
||||
this.schematic = schematic;
|
||||
this.inputs = inputs;
|
||||
this.output = List.of(output);
|
||||
this.processIcon = processIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmiRecipeCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmiIngredient> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmiStack> getOutputs() {
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayWidth() {
|
||||
return 130;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayHeight() {
|
||||
return schematic.dy() * 8 + 80 + 20 * (inputs.size() - 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWidgets(WidgetHolder widgets) {
|
||||
int y = schematic.dy() * 8;
|
||||
int row = 0;
|
||||
age = 0;
|
||||
widgets.addDrawable(10, y / 2, 100, 100, this::renderSchematic);
|
||||
int x = 10;
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
if (i > 1) {
|
||||
x -= 40;
|
||||
row += 20;
|
||||
}
|
||||
if (i > 0) {
|
||||
widgets.addTexture(EmiTexture.PLUS, x + 3, y + 53 + row);
|
||||
x += 20;
|
||||
}
|
||||
widgets.addSlot(inputs.get(i), x, y + 50 + row).catalyst(i > 0);
|
||||
x += 20;
|
||||
}
|
||||
widgets.addTexture(EmiTexture.EMPTY_ARROW, 73, y + 52);
|
||||
widgets.addSlot(output.get(0), 100, y + 47).large(true).recipeContext(this);
|
||||
widgets.addTexture(processIcon, 73, y + 45, 13, 13, 0, 0, 16, 16, 16, 16).tooltipText(List.of(Text.translatable(
|
||||
Util.createTranslationKey("recipe", category.getId()) + "." + "instruction"
|
||||
)));
|
||||
}
|
||||
|
||||
private void renderSchematic(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
if (schematic.volume() == 0) {
|
||||
return;
|
||||
}
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
Immediate immediate = context.getVertexConsumers();
|
||||
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
||||
matrices.push();
|
||||
float minSize = (Math.max(schematic.dz(), Math.max(schematic.dx(), schematic.dy())) + 1) * 16;
|
||||
float scale = 60 / minSize;
|
||||
matrices.scale(scale, scale, 1);
|
||||
matrices.translate(95, 40, 100);
|
||||
matrices.scale(16, -16, 16);
|
||||
|
||||
matrices.peek().getNormalMatrix().scale(1, -1, 1);
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(20));
|
||||
matrices.peek().getPositionMatrix().rotate(RotationAxis.POSITIVE_Y.rotationDegrees(40));
|
||||
matrices.translate(
|
||||
(-schematic.dx() - 1) / 2F,
|
||||
(-schematic.dy() - 1) / 2F,
|
||||
(-schematic.dz() - 1) / 2F
|
||||
);
|
||||
DiffuseLighting.disableGuiDepthLighting();
|
||||
|
||||
age++;
|
||||
|
||||
for (var entry : schematic.states()) {
|
||||
int x = entry.x() - schematic.dx() / 2;
|
||||
int z = entry.z() - schematic.dz() / 2;
|
||||
int distance = x * x + z * z;
|
||||
if (age >= distance * 2) {
|
||||
matrices.push();
|
||||
matrices.translate(entry.x(), entry.y(), entry.z());
|
||||
client.getBlockRenderManager().renderBlockAsEntity(entry.state(), matrices, immediate, LightmapTextureManager.MAX_LIGHT_COORDINATE, OverlayTexture.DEFAULT_UV);
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
package com.minelittlepony.unicopia.compat.emi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.compress.utils.Lists;
|
||||
import com.minelittlepony.common.client.gui.Tooltip;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer;
|
||||
|
||||
import dev.emi.emi.api.render.EmiRender;
|
||||
import dev.emi.emi.api.stack.Comparison;
|
||||
import dev.emi.emi.api.stack.EmiStack;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.tooltip.TooltipComponent;
|
||||
import net.minecraft.component.ComponentChanges;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class TraitEmiStack extends EmiStack {
|
||||
|
||||
private final Trait trait;
|
||||
private final float amount;
|
||||
private final SpellTraits traits;
|
||||
|
||||
public TraitEmiStack(Trait trait, float amount) {
|
||||
this.trait = trait;
|
||||
this.amount = amount;
|
||||
traits = new SpellTraits.Builder().with(trait, amount).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return amount == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentChanges getComponentChanges() {
|
||||
return ComponentChanges.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKey() {
|
||||
return trait;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return trait.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Text> getTooltipText() {
|
||||
return trait.getTooltipLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TooltipComponent> getTooltip() {
|
||||
List<TooltipComponent> list = Lists.newArrayList();
|
||||
if (!isEmpty()) {
|
||||
for (Text line : Tooltip.of(trait.getTooltip(), 200).getLines()) {
|
||||
list.add(TooltipComponent.of(line.asOrderedText()));
|
||||
}
|
||||
list.addAll(super.getTooltip());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return trait.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int x, int y, float delta, int flags) {
|
||||
if ((flags & RENDER_ICON) != 0) {
|
||||
List<Item> knownItems = trait.getItems();
|
||||
if (knownItems.isEmpty() || MinecraftClient.getInstance().player == null) {
|
||||
ItemTraitsTooltipRenderer.renderTraitIcon(trait, amount, context, x, y, true);
|
||||
} else {
|
||||
int tick = (MinecraftClient.getInstance().player.age / 12) % knownItems.size();
|
||||
ItemStack stack = knownItems.get(tick).getDefaultStack();
|
||||
EmiStack.of(stack).render(context, x, y, delta, flags);
|
||||
ItemTraitsTooltipRenderer.renderStackTraits(traits, context, x, y, 1, delta, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & RENDER_REMAINDER) != 0) {
|
||||
EmiRender.renderRemainderIcon(this, context, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmiStack copy() {
|
||||
return new TraitEmiStack(trait, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEqual(EmiStack stack) {
|
||||
return super.isEqual(stack) && equalTo(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEqual(EmiStack stack, Comparison comparison) {
|
||||
return super.isEqual(stack, comparison) && equalTo(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals(obj) && obj instanceof EmiStack s && equalTo(s);
|
||||
}
|
||||
|
||||
private boolean equalTo(EmiStack stack) {
|
||||
return stack instanceof TraitEmiStack t && t.trait == trait && MathHelper.approximatelyEquals(t.amount, amount);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.minelittlepony.unicopia.compat.tla;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.recipe.URecipes;
|
||||
|
||||
import io.github.mattidragon.tlaapi.api.gui.GuiBuilder;
|
||||
import io.github.mattidragon.tlaapi.api.plugin.PluginContext;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaIngredient;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaRecipe;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaStack;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
import net.minecraft.recipe.StonecuttingRecipe;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class CloudShapingTlaRecipe implements TlaRecipe {
|
||||
private final Identifier id;
|
||||
private final RecipeCategory category;
|
||||
private final TlaIngredient input;
|
||||
private final TlaStack output;
|
||||
|
||||
static void generate(RecipeCategory category, PluginContext context) {
|
||||
context.addRecipeGenerator(URecipes.CLOUD_SHAPING, recipe -> new CloudShapingTlaRecipe(category, recipe));
|
||||
}
|
||||
|
||||
public CloudShapingTlaRecipe(RecipeCategory category, RecipeEntry<StonecuttingRecipe> recipe) {
|
||||
this.id = recipe.id();
|
||||
this.category = category;
|
||||
input = TlaIngredient.ofIngredient(recipe.value().getIngredients().get(0));
|
||||
output = TlaStack.of(recipe.value().getResult(MinecraftClient.getInstance().world.getRegistryManager()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaIngredient> getInputs() {
|
||||
return List.of(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaStack> getOutputs() {
|
||||
return List.of(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaIngredient> getCatalysts() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildGui(GuiBuilder builder) {
|
||||
builder.addArrow(26, 1, false);
|
||||
builder.addSlot(input, 0, 0).markInput();
|
||||
builder.addSlot(output, 58, 0).markOutput();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.minelittlepony.unicopia.compat.tla;
|
||||
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import io.github.mattidragon.tlaapi.api.plugin.PluginContext;
|
||||
import io.github.mattidragon.tlaapi.api.plugin.TlaApiPlugin;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaStackComparison;
|
||||
|
||||
public class Main implements TlaApiPlugin {
|
||||
@Override
|
||||
public void register(PluginContext registry) {
|
||||
RecipeCategory.bootstrap(registry);
|
||||
registry.getItemComparisons().register(TlaStackComparison.compareComponents(),
|
||||
UItems.GEMSTONE, UItems.BOTCHED_GEM, UItems.MAGIC_STAFF, UItems.FILLED_JAR
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.minelittlepony.unicopia.compat.tla;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import io.github.mattidragon.tlaapi.api.plugin.PluginContext;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.CategoryIcon;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaCategory;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaIngredient;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaStack;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public record RecipeCategory(Identifier id, CategoryIcon icon, TlaIngredient stations, int width, int height) implements TlaCategory {
|
||||
static final Map<RecipeCategory, @Nullable BiConsumer<RecipeCategory, PluginContext>> REGISTRY = new HashMap<>();
|
||||
|
||||
static final RecipeCategory SPELL_BOOK = register("spellbook", UItems.SPELLBOOK, 150, 75, SpellbookTlaRecipe::generate);
|
||||
static final RecipeCategory CLOUD_SHAPING = register("cloud_shaping", UBlocks.SHAPING_BENCH, 76, 18, CloudShapingTlaRecipe::generate);
|
||||
static final RecipeCategory GROWING = register("growing", Blocks.FARMLAND, 130, 85, StructureInteractionTlaRecipe::generateFarmingRecipes);
|
||||
static final RecipeCategory ALTAR = register("altar", Blocks.CRYING_OBSIDIAN, 130, 160, StructureInteractionTlaRecipe::generateAltarRecipes);
|
||||
|
||||
static RecipeCategory register(String name, ItemConvertible item, int width, int height, @Nullable BiConsumer<RecipeCategory, PluginContext> recipeConstructor) {
|
||||
return register(new RecipeCategory(Unicopia.id(name), CategoryIcon.item(item), TlaStack.of(item).asIngredient(), width, height), recipeConstructor);
|
||||
}
|
||||
|
||||
static RecipeCategory register(RecipeCategory category, @Nullable BiConsumer<RecipeCategory, PluginContext> recipeConstructor) {
|
||||
REGISTRY.put(category, recipeConstructor);
|
||||
return category;
|
||||
}
|
||||
|
||||
static void bootstrap(PluginContext registry) {
|
||||
REGISTRY.forEach((category, recipeConstructor) -> {
|
||||
registry.addCategory(category);
|
||||
registry.addWorkstation(category, category.stations());
|
||||
try {
|
||||
if (recipeConstructor != null) {
|
||||
recipeConstructor.accept(category, registry);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Unicopia.LOGGER.fatal("Error occured whilst registering recipes for category " + category.getId(), t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CategoryIcon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CategoryIcon getSimpleIcon() {
|
||||
return icon;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.minelittlepony.unicopia.compat.tla;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellbookRecipe;
|
||||
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaIngredient;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
|
||||
class SpellDuplicatingTlaRecipe extends SpellbookTlaRecipe {
|
||||
public SpellDuplicatingTlaRecipe(RecipeEntry<SpellbookRecipe> recipe) {
|
||||
super(recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TlaIngredient getOutput() {
|
||||
return super.getOutput().withAmount(2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package com.minelittlepony.unicopia.compat.tla;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellDuplicatingRecipe;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellEnhancingRecipe;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellbookRecipe;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen;
|
||||
import com.minelittlepony.unicopia.container.inventory.HexagonalCraftingGrid;
|
||||
import com.minelittlepony.unicopia.recipe.URecipes;
|
||||
import io.github.mattidragon.tlaapi.api.gui.GuiBuilder;
|
||||
import io.github.mattidragon.tlaapi.api.gui.TextureConfig;
|
||||
import io.github.mattidragon.tlaapi.api.gui.TlaBounds;
|
||||
import io.github.mattidragon.tlaapi.api.plugin.PluginContext;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaIngredient;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaRecipe;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
class SpellbookTlaRecipe implements TlaRecipe, SpellbookRecipe.CraftingTreeBuilder {
|
||||
static final Identifier WIDGETS = Unicopia.id("textures/gui/widgets.png");
|
||||
static final TextureConfig EMPTY_ARROW = TextureConfig.builder().texture(WIDGETS).uv(44, 0).size(24, 17).build();
|
||||
|
||||
private final RecipeEntry<SpellbookRecipe> recipe;
|
||||
|
||||
protected final List<TraitedTlaIngredient> inputs = new ArrayList<>();
|
||||
private final List<TlaStack> outputs = new ArrayList<>();
|
||||
|
||||
private final Supplier<List<TlaIngredient>> ingredients;
|
||||
|
||||
static void generate(RecipeCategory category, PluginContext context) {
|
||||
context.addGenerator(client -> client.world.getRecipeManager().listAllOfType(URecipes.SPELLBOOK).stream().flatMap(recipe -> {
|
||||
if (recipe.value() instanceof SpellDuplicatingRecipe) {
|
||||
return Stream.of(new SpellDuplicatingTlaRecipe(recipe));
|
||||
}
|
||||
|
||||
if (recipe.value() instanceof SpellEnhancingRecipe enhancingRecipe) {
|
||||
return Trait.all().stream().map(trait -> {
|
||||
return new SpellDuplicatingTlaRecipe(recipe) {
|
||||
private final Identifier id = recipe.id().withPath(p -> p + "/" + trait.getId().getPath());
|
||||
|
||||
{
|
||||
input(trait);
|
||||
getOutputs().addAll(
|
||||
Arrays.stream(enhancingRecipe.getBaseMaterial().getMatchingStacks())
|
||||
.map(stack -> TlaStack.of(SpellTraits.of(stack).add(new SpellTraits.Builder().with(trait, 1).build()).applyTo(stack)))
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return Stream.of((TlaRecipe)new SpellbookTlaRecipe(recipe));
|
||||
}).toList());
|
||||
}
|
||||
|
||||
public SpellbookTlaRecipe(RecipeEntry<SpellbookRecipe> recipe) {
|
||||
this.recipe = recipe;
|
||||
this.ingredients = Suppliers.memoize(() -> inputs.stream().map(TraitedTlaIngredient::ingredient).toList());
|
||||
recipe.value().buildCraftingTree(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeCategory getCategory() {
|
||||
return RecipeCategory.SPELL_BOOK;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return recipe.id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaIngredient> getInputs() {
|
||||
return ingredients.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaStack> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaIngredient> getCatalysts() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildGui(GuiBuilder builder) {
|
||||
TlaBounds bounds = builder.getBounds();
|
||||
builder.addTexture(TextureConfig.builder().texture(SpellbookScreen.TEXTURE)
|
||||
.size(bounds.width(), bounds.height())
|
||||
.uv(50, 50)
|
||||
.regionSize(128, 128)
|
||||
.textureSize(512, 256)
|
||||
.build(), 0, 0);
|
||||
builder.addTexture(EMPTY_ARROW, 85, 30);
|
||||
|
||||
List<HexagonalCraftingGrid.Slot> grid = new ArrayList<>();
|
||||
List<HexagonalCraftingGrid.Slot> gem = new ArrayList<>();
|
||||
HexagonalCraftingGrid.create(-34, -5, 3, grid, gem);
|
||||
|
||||
int currentInput = 1;
|
||||
|
||||
for (int i = 0; i < grid.size(); i++) {
|
||||
var slot = grid.get(i);
|
||||
|
||||
if (currentInput < inputs.size() && slot.weight() == 1) {
|
||||
inputs.get(currentInput++).buildGui(slot, builder);
|
||||
} else if (slot.weight() == 1) {
|
||||
inputs.get(0).buildGui(TlaIngredient.EMPTY, slot, builder);
|
||||
}
|
||||
}
|
||||
|
||||
inputs.get(0).buildGui(gem.get(0), builder);
|
||||
builder.addSlot(getOutput(), 120, 25).makeLarge().markOutput();
|
||||
}
|
||||
|
||||
protected TlaIngredient getOutput() {
|
||||
return TlaIngredient.ofStacks(outputs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(ItemStack... stacks) {
|
||||
inputs.add(TraitedTlaIngredient.of(TlaIngredient.ofStacks(Arrays.stream(stacks).map(TlaStack::of).toList())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(Trait... traits) {
|
||||
inputs.add(TraitedTlaIngredient.of(List.of(traits), 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(Trait trait, float value) {
|
||||
inputs.add(TraitedTlaIngredient.of(trait, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void result(ItemStack... stack) {
|
||||
outputs.addAll(Arrays.stream(stack).map(TlaStack::of).toList());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
package com.minelittlepony.unicopia.compat.tla;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.block.state.Schematic;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.recipe.TransformCropsRecipe;
|
||||
import com.minelittlepony.unicopia.recipe.URecipes;
|
||||
|
||||
import io.github.mattidragon.tlaapi.api.gui.GuiBuilder;
|
||||
import io.github.mattidragon.tlaapi.api.gui.TextureConfig;
|
||||
import io.github.mattidragon.tlaapi.api.plugin.PluginContext;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaIngredient;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaRecipe;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaStack;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.DiffuseLighting;
|
||||
import net.minecraft.client.render.LightmapTextureManager;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class StructureInteractionTlaRecipe implements TlaRecipe {
|
||||
static final TextureConfig PLUS = TextureConfig.builder().texture(Identifier.of("emi", "textures/gui/widgets.png")).size(13, 13).uv(82, 0).build();
|
||||
|
||||
private final RecipeCategory category;
|
||||
private final Identifier id;
|
||||
private final Schematic schematic;
|
||||
|
||||
private final List<TlaIngredient> allInputs;
|
||||
private final List<TlaIngredient> inputs;
|
||||
private final List<TlaIngredient> catalysts;
|
||||
private final List<TlaStack> output;
|
||||
|
||||
private final TextureConfig processIcon;
|
||||
|
||||
private int age;
|
||||
|
||||
static void generateFarmingRecipes(RecipeCategory category, PluginContext context) {
|
||||
context.addRecipeGenerator(URecipes.GROWING, recipe -> {
|
||||
return new StructureInteractionTlaRecipe(
|
||||
category,
|
||||
recipe.id(),
|
||||
new Schematic.Builder()
|
||||
.fill(0, 0, 0, 6, 0, 6, recipe.value().getCatalystState())
|
||||
.set(3, 0, 3, Blocks.FARMLAND.getDefaultState())
|
||||
.set(3, 1, 3, recipe.value().getTargetState())
|
||||
.build(),
|
||||
List.of(
|
||||
TlaStack.of(recipe.value().getTarget()).asIngredient(),
|
||||
TlaStack.of(ItemVariant.of(recipe.value().getCatalyst()), TransformCropsRecipe.AREA).asIngredient()
|
||||
),
|
||||
TlaStack.of(recipe.value().getOutput()),
|
||||
Unicopia.id("textures/gui/ability/grow.png")
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
static void generateAltarRecipes(RecipeCategory category, PluginContext context) {
|
||||
context.addGenerator(client -> List.of(new StructureInteractionTlaRecipe(
|
||||
category,
|
||||
Unicopia.id("altar/spectral_clock"),
|
||||
Schematic.ALTAR,
|
||||
List.of(
|
||||
TlaStack.of(Items.CLOCK).asIngredient(),
|
||||
TlaStack.of(UItems.SPELLBOOK).asIngredient(),
|
||||
TlaStack.of(Blocks.SOUL_SAND).asIngredient(),
|
||||
TlaStack.of(Blocks.LODESTONE).asIngredient(),
|
||||
TlaStack.of(Blocks.OBSIDIAN, 8 * 4 + 8).asIngredient()
|
||||
),
|
||||
TlaStack.of(UItems.SPECTRAL_CLOCK),
|
||||
Unicopia.id("textures/gui/race/alicorn.png")
|
||||
)));
|
||||
}
|
||||
|
||||
public StructureInteractionTlaRecipe(RecipeCategory category, Identifier id, Schematic schematic, List<TlaIngredient> inputs, TlaStack output, Identifier processIcon) {
|
||||
this.category = category;
|
||||
this.id = id;
|
||||
this.schematic = schematic;
|
||||
this.allInputs = inputs;
|
||||
this.inputs = inputs.stream().limit(1).toList();
|
||||
this.catalysts = inputs.stream().skip(1).toList();
|
||||
this.output = List.of(output);
|
||||
this.processIcon = TextureConfig.builder().texture(processIcon).size(13, 13).regionSize(16, 16).textureSize(16, 16).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaIngredient> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TlaStack> getOutputs() {
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<TlaIngredient> getCatalysts() {
|
||||
return catalysts;
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public int getDisplayHeight() {
|
||||
return schematic.dy() * 8 + 80 + 20 * (inputs.size() - 2);
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void buildGui(GuiBuilder widgets) {
|
||||
int y = schematic.dy() * 8;
|
||||
int row = 0;
|
||||
age = 0;
|
||||
widgets.addCustomWidget(10, y / 2, 100, 100, this::renderSchematic);
|
||||
int x = 10;
|
||||
for (int i = 0; i < allInputs.size(); i++) {
|
||||
if (i > 1) {
|
||||
x -= 40;
|
||||
row += 20;
|
||||
}
|
||||
if (i > 0) {
|
||||
widgets.addTexture(PLUS, x + 3, y + 53 + row);
|
||||
x += 20;
|
||||
}
|
||||
var slot = widgets.addSlot(allInputs.get(i), x, y + 50 + row);
|
||||
if (i > 0) {
|
||||
slot.markCatalyst();
|
||||
}
|
||||
x += 20;
|
||||
}
|
||||
widgets.addArrow(73, y + 52, false);
|
||||
widgets.addSlot(output.get(0), 100, y + 47).makeLarge().markOutput();
|
||||
widgets.addTexture(processIcon, 73, y + 45).addTooltip(List.of(Text.translatable(
|
||||
Util.createTranslationKey("recipe", category.getId()) + "." + "instruction"
|
||||
)));
|
||||
}
|
||||
|
||||
private void renderSchematic(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
if (schematic.volume() == 0) {
|
||||
return;
|
||||
}
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
Immediate immediate = context.getVertexConsumers();
|
||||
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
||||
matrices.push();
|
||||
float minSize = (Math.max(schematic.dz(), Math.max(schematic.dx(), schematic.dy())) + 1) * 16;
|
||||
float scale = 60 / minSize;
|
||||
matrices.scale(scale, scale, 1);
|
||||
matrices.translate(95, 40, 100);
|
||||
matrices.scale(16, -16, 16);
|
||||
|
||||
matrices.peek().getNormalMatrix().scale(1, -1, 1);
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(20));
|
||||
matrices.peek().getPositionMatrix().rotate(RotationAxis.POSITIVE_Y.rotationDegrees(40));
|
||||
matrices.translate(
|
||||
(-schematic.dx() - 1) / 2F,
|
||||
(-schematic.dy() - 1) / 2F,
|
||||
(-schematic.dz() - 1) / 2F
|
||||
);
|
||||
DiffuseLighting.disableGuiDepthLighting();
|
||||
|
||||
age++;
|
||||
|
||||
for (var entry : schematic.states()) {
|
||||
int x = entry.x() - schematic.dx() / 2;
|
||||
int z = entry.z() - schematic.dz() / 2;
|
||||
int distance = x * x + z * z;
|
||||
if (age >= distance * 2) {
|
||||
matrices.push();
|
||||
matrices.translate(entry.x(), entry.y(), entry.z());
|
||||
client.getBlockRenderManager().renderBlockAsEntity(entry.state(), matrices, immediate, LightmapTextureManager.MAX_LIGHT_COORDINATE, OverlayTexture.DEFAULT_UV);
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.minelittlepony.unicopia.compat.tla;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen;
|
||||
import com.minelittlepony.unicopia.container.inventory.HexagonalCraftingGrid;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import io.github.mattidragon.tlaapi.api.gui.GuiBuilder;
|
||||
import io.github.mattidragon.tlaapi.api.gui.TlaBounds;
|
||||
import io.github.mattidragon.tlaapi.api.recipe.TlaIngredient;
|
||||
import io.github.mattidragon.tlaapi.impl.SimpleCustomTlaWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
public record TraitedTlaIngredient(Optional<TraitEntry> trait, TlaIngredient ingredient) {
|
||||
|
||||
public static TraitedTlaIngredient of(Trait trait, float amount) {
|
||||
return of(List.of(trait), amount);
|
||||
}
|
||||
|
||||
public static TraitedTlaIngredient of(List<Trait> traits, float amount) {
|
||||
return new TraitedTlaIngredient(Optional.of(new TraitEntry(traits, amount)),
|
||||
TlaIngredient.ofItems(traits.stream().flatMap(SpellTraits::getItems).distinct().toList())
|
||||
);
|
||||
}
|
||||
|
||||
public static TraitedTlaIngredient of(TlaIngredient ingredient) {
|
||||
return new TraitedTlaIngredient(Optional.empty(), ingredient);
|
||||
}
|
||||
|
||||
public void buildGui(HexagonalCraftingGrid.Slot slot, GuiBuilder builder) {
|
||||
buildGui(ingredient(), slot, builder);
|
||||
}
|
||||
|
||||
public void buildGui(TlaIngredient ingredientOverride, HexagonalCraftingGrid.Slot slot, GuiBuilder builder) {
|
||||
builder.addCustomWidget(new SlotTexture(slot));
|
||||
builder.addSlot(ingredientOverride, slot.left(), slot.top()).disableBackground();
|
||||
trait.ifPresent(traitEntry -> {
|
||||
builder.addCustomWidget(slot.left(), slot.top(), 16, 16, (context, mouseX, mouseY, delta) -> {
|
||||
int tick = (MinecraftClient.getInstance().player.age / 12) % traitEntry.traits().size();
|
||||
Trait currentDisplayedTrait = traitEntry.traits().get(tick);
|
||||
if (currentDisplayedTrait.getItems().isEmpty() || MinecraftClient.getInstance().player == null) {
|
||||
ItemTraitsTooltipRenderer.renderTraitIcon(currentDisplayedTrait, traitEntry.amount(), context, 0, 0, true);
|
||||
} else {
|
||||
ItemTraitsTooltipRenderer.renderStackSingleTrait(currentDisplayedTrait, traitEntry.amount(), context, 0, 0, 1, delta, 0, true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
record TraitEntry(List<Trait> traits, float amount) { }
|
||||
|
||||
static class SlotTexture extends SimpleCustomTlaWidget {
|
||||
public SlotTexture(HexagonalCraftingGrid.Slot slot) {
|
||||
super((context, mouseX, mouseY, delta) -> {
|
||||
RenderSystem.enableBlend();
|
||||
context.drawTexture(SpellbookScreen.SLOT, 0, 0, 0, 0, 0, 32, 32, 32, 32);
|
||||
RenderSystem.disableBlend();
|
||||
}, new TlaBounds(slot.left() - 7, slot.top() - 7, 32, 32));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,10 +46,10 @@
|
|||
"item.unicopia.spellbook": "Spellbook",
|
||||
"item.unicopia.spectral_clock": "Spectral Clock",
|
||||
|
||||
"emi.category.unicopia.spellbook": "Spellbook",
|
||||
"emi.category.unicopia.cloud_shaping": "Shaping",
|
||||
"emi.category.unicopia.growing": "Growing",
|
||||
"emi.category.unicopia.altar": "Dark Ritual",
|
||||
"tla.category.unicopia.spellbook": "Spellbook",
|
||||
"tla.category.unicopia.cloud_shaping": "Shaping",
|
||||
"tla.category.unicopia.growing": "Growing",
|
||||
"tla.category.unicopia.altar": "Dark Ritual",
|
||||
"recipe.unicopia.altar.instruction": "Cast item into flames",
|
||||
"recipe.unicopia.growing.instruction": "Focus Earth Pony Magic",
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
"modmenu": [
|
||||
"com.minelittlepony.unicopia.modmenu.UMenuFactory"
|
||||
],
|
||||
"emi": [
|
||||
"com.minelittlepony.unicopia.compat.emi.Main"
|
||||
"tla-api": [
|
||||
"com.minelittlepony.unicopia.compat.tla.Main"
|
||||
],
|
||||
"minelittlepony": [
|
||||
"com.minelittlepony.unicopia.client.minelittlepony.Main"
|
||||
|
|
Loading…
Reference in a new issue