This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
SorceryCraft/src/main/java/com/thebrokenrail/sorcerycraft/gui/CastingTableScreenHandler.java

254 lines
9.7 KiB
Java

package com.thebrokenrail.sorcerycraft.gui;
import com.thebrokenrail.sorcerycraft.SorceryCraft;
import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import com.thebrokenrail.sorcerycraft.spell.util.SpellPlayerEntity;
import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.screen.slot.Slot;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
public class CastingTableScreenHandler extends ScreenHandler {
private final Inventory inventory;
private final Inventory result;
private Spell[] spells = new Spell[0];
private final ScreenHandlerContext context;
private int index = 0;
public CastingTableScreenHandler(int syncId, PlayerInventory playerInventory, ScreenHandlerContext blockContext) {
super(ScreenHandlerType.STONECUTTER, syncId);
inventory = new SimpleInventory(2) {
public void markDirty() {
super.markDirty();
CastingTableScreenHandler.this.onContentChanged(this);
}
};
context = blockContext;
result = new CraftingResultInventory();
setSpells(playerInventory.player);
addSlot(new Slot(inventory, 0, 136, 37) {
@Override
public boolean canInsert(ItemStack stack) {
return stack.getItem().equals(SorceryCraft.SPELL_ITEM);
}
@Override
public int getMaxItemCount() {
return 1;
}
@Override
public void onStackChanged(ItemStack originalItem, ItemStack itemStack) {
super.onStackChanged(originalItem, itemStack);
markDirty();
}
});
addSlot(new Slot(inventory, 1, 162, 37) {
@Override
public void onStackChanged(ItemStack originalItem, ItemStack itemStack) {
super.onStackChanged(originalItem, itemStack);
markDirty();
}
});
addSlot(new Slot(result, 2, 220, 37) {
public boolean canInsert(ItemStack stack) {
return false;
}
public boolean canTakeItems(PlayerEntity playerEntity) {
return canTakeResult(playerEntity) && hasStack();
}
public ItemStack onTakeItem(PlayerEntity player, ItemStack stack) {
if (!player.isCreative()) {
player.addExperienceLevels(-spells[index].getXPCost());
}
context.run((world, blockPos) -> {
SorceryCraft.playSpellSound(world, blockPos);
if (!world.isClient()) {
SorceryCraft.CREATE_SPELL_CRITERION.trigger((ServerPlayerEntity) player);
}
});
CastingTableScreenHandler.this.inventory.setStack(0, ItemStack.EMPTY);
CastingTableScreenHandler.this.inventory.removeStack(1, spells[index].getItemCost().getCount());
return stack;
}
});
int k;
for (k = 0; k < 3; ++k) {
for (int j = 0; j < 9; ++j) {
addSlot(new Slot(playerInventory, j + k * 9 + 9, 108 + j * 18, 84 + k * 18));
}
}
for (k = 0; k < 9; ++k) {
addSlot(new Slot(playerInventory, k, 108 + k * 18, 142));
}
}
private void resetIndex() {
index = 0;
onContentChanged(inventory);
}
public void setSpells(PlayerEntity player) {
if (player.isCreative() ? SorceryCraft.getConfig().limitCastingTable.creative : SorceryCraft.getConfig().limitCastingTable.survival) {
SpellPlayerEntity spellPlayer = (SpellPlayerEntity) player;
Map<Identifier, Integer> spellsMap = spellPlayer.getDiscoveredSpells();
List<Spell> spellsArray = new ArrayList<>();
Spell[] allSpells = SpellRegistry.getSpells();
for (Spell spell : allSpells) {
if (spellsMap.containsKey(spell.getID()) && spellsMap.get(spell.getID()) >= spell.getLevel()) {
spellsArray.add(spell);
}
}
spells = spellsArray.toArray(new Spell[0]);
} else {
spells = SpellRegistry.getSpells();
}
resetIndex();
}
public boolean canTakeResult(PlayerEntity playerEntity) {
return playerEntity.isCreative() || playerEntity.experienceLevel >= spells[index].getXPCost();
}
public void setIndex(int index) {
this.index = index;
onContentChanged(inventory);
if (inventory.getStack(0).isEmpty() && inventory.getStack(1).isEmpty()) {
ItemStack spellItem = new ItemStack(SorceryCraft.SPELL_ITEM);
autoFill(0, spellItem, true);
ItemStack paymentItem = getRecipes()[index].getItemCost();
autoFill(1, paymentItem, false);
}
}
public ItemStack transferSlot(PlayerEntity player, int invSlot) {
ItemStack itemStack = ItemStack.EMPTY;
Slot slot = slots.get(invSlot);
if (slot != null && slot.hasStack()) {
ItemStack itemStack2 = slot.getStack();
itemStack = itemStack2.copy();
if (invSlot == 2) {
if (!insertItem(itemStack2, 3, 39, true)) {
return ItemStack.EMPTY;
}
slot.onStackChanged(itemStack2, itemStack);
} else if (invSlot != 0 && invSlot != 1) {
if (invSlot < 30) {
if (!insertItem(itemStack2, 30, 39, false)) {
return ItemStack.EMPTY;
}
} else if (invSlot < 39 && !insertItem(itemStack2, 3, 30, false)) {
return ItemStack.EMPTY;
}
} else if (!insertItem(itemStack2, 3, 39, false)) {
return ItemStack.EMPTY;
}
if (itemStack2.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
} else {
slot.markDirty();
}
if (itemStack2.getCount() == itemStack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTakeItem(player, itemStack2);
}
return itemStack;
}
@Override
public void close(PlayerEntity player) {
super.close(player);
context.run((BiConsumer<World, BlockPos>) (world, blockPos) -> dropInventory(player, world, inventory));
}
@Override
public void onContentChanged(Inventory inventory) {
super.onContentChanged(inventory);
ItemStack item = inventory.getStack(0);
ItemStack cost = inventory.getStack(1);
if (inventory == this.inventory) {
if (spells.length > 0 &&
!item.isEmpty() &&
cost.getItem() == spells[index].getItemCost().getItem() &&
cost.getCount() >= spells[index].getItemCost().getCount()) {
ItemStack resultItem = item.copy();
Map<Identifier, Integer> resultSpells = SpellHelper.getSpells(resultItem);
if (!resultSpells.containsKey(spells[index].getID()) || resultSpells.get(spells[index].getID()) <= spells[index].getLevel()) {
resultSpells.put(spells[index].getID(), spells[index].getLevel());
}
SpellHelper.setSpells(resultItem, resultSpells);
result.setStack(2, resultItem);
} else {
result.setStack(2, ItemStack.EMPTY);
}
}
}
private void autoFill(int slot, ItemStack stack, boolean onlyOne) {
if (!stack.isEmpty()) {
for (int i = 3; i < 39; ++i) {
ItemStack itemStack = slots.get(i).getStack();
if (!itemStack.isEmpty() && itemCompatible(stack, itemStack)) {
ItemStack invSlot = inventory.getStack(slot);
int count = invSlot.isEmpty() ? 0 : invSlot.getCount();
int requiredCount = Math.min((onlyOne ? 1 : stack.getMaxCount()) - count, itemStack.getCount());
ItemStack modifiedItem = itemStack.copy();
int totalCount = count + requiredCount;
itemStack.decrement(requiredCount);
modifiedItem.setCount(totalCount);
inventory.setStack(slot, modifiedItem);
if (totalCount >= stack.getMaxCount() || onlyOne) {
break;
}
}
}
}
}
private boolean itemCompatible(ItemStack itemStack, ItemStack otherItemStack) {
return itemStack.getItem() == otherItemStack.getItem();
}
@Override
public boolean canUse(PlayerEntity player) {
return context.run((world, blockPos) -> world.getBlockState(blockPos).getBlock().equals(SorceryCraft.CASTING_TABLE_BLOCK) && player.squaredDistanceTo((double) blockPos.getX() + 0.5D, (double) blockPos.getY() + 0.5D, (double) blockPos.getZ() + 0.5D) <= 64.0D, true);
}
public Spell[] getRecipes() {
return spells;
}
}