2020-03-13 22:05:12 +00:00
|
|
|
package com.thebrokenrail.sorcerycraft.gui;
|
2020-03-01 18:19:59 +00:00
|
|
|
|
|
|
|
import com.thebrokenrail.sorcerycraft.SorceryCraft;
|
2020-03-08 17:45:15 +00:00
|
|
|
import com.thebrokenrail.sorcerycraft.spell.api.Spell;
|
2020-03-06 23:35:29 +00:00
|
|
|
import com.thebrokenrail.sorcerycraft.spell.util.SpellPlayerEntity;
|
2020-03-21 02:05:32 +00:00
|
|
|
import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
|
|
|
|
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
|
2020-03-22 19:29:46 +00:00
|
|
|
import net.minecraft.container.BlockContext;
|
|
|
|
import net.minecraft.container.Container;
|
|
|
|
import net.minecraft.container.ContainerType;
|
|
|
|
import net.minecraft.container.Slot;
|
2020-03-01 18:19:59 +00:00
|
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
|
|
import net.minecraft.entity.player.PlayerInventory;
|
|
|
|
import net.minecraft.inventory.BasicInventory;
|
|
|
|
import net.minecraft.inventory.CraftingResultInventory;
|
|
|
|
import net.minecraft.inventory.Inventory;
|
|
|
|
import net.minecraft.item.ItemStack;
|
2020-03-18 00:42:02 +00:00
|
|
|
import net.minecraft.server.network.ServerPlayerEntity;
|
2020-03-03 23:08:22 +00:00
|
|
|
import net.minecraft.util.Identifier;
|
2020-03-04 01:22:40 +00:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
|
|
|
import net.minecraft.world.World;
|
2020-03-01 18:19:59 +00:00
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2020-03-04 01:22:40 +00:00
|
|
|
import java.util.function.BiConsumer;
|
2020-03-01 18:19:59 +00:00
|
|
|
|
2020-03-22 19:29:46 +00:00
|
|
|
public class CastingTableScreenHandler extends Container {
|
2020-03-01 18:19:59 +00:00
|
|
|
private final Inventory inventory;
|
|
|
|
private final Inventory result;
|
2020-03-24 13:35:42 +00:00
|
|
|
private Spell[] spells = new Spell[0];
|
2020-03-22 19:29:46 +00:00
|
|
|
private final BlockContext context;
|
2020-03-01 18:19:59 +00:00
|
|
|
private int index = 0;
|
|
|
|
|
2020-03-22 19:29:46 +00:00
|
|
|
public CastingTableScreenHandler(int syncId, PlayerInventory playerInventory, BlockContext blockContext) {
|
|
|
|
super(ContainerType.STONECUTTER, syncId);
|
2020-03-01 18:19:59 +00:00
|
|
|
|
|
|
|
inventory = new BasicInventory(2) {
|
|
|
|
public void markDirty() {
|
|
|
|
super.markDirty();
|
2020-03-09 22:47:31 +00:00
|
|
|
CastingTableScreenHandler.this.onContentChanged(this);
|
2020-03-01 18:19:59 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
context = blockContext;
|
|
|
|
result = new CraftingResultInventory();
|
|
|
|
|
2020-03-24 13:35:42 +00:00
|
|
|
setSpells(playerInventory.player);
|
2020-03-01 18:19:59 +00:00
|
|
|
|
|
|
|
addSlot(new Slot(inventory, 0, 136, 37) {
|
|
|
|
@Override
|
|
|
|
public boolean canInsert(ItemStack stack) {
|
|
|
|
return stack.getItem().equals(SorceryCraft.SPELL_ITEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMaxStackAmount() {
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
2020-03-18 00:42:02 +00:00
|
|
|
context.run((world, blockPos) -> {
|
|
|
|
SorceryCraft.playSpellSound(world, blockPos);
|
|
|
|
if (!world.isClient()) {
|
|
|
|
SorceryCraft.CREATE_SPELL_CRITERION.trigger((ServerPlayerEntity) player);
|
|
|
|
}
|
|
|
|
});
|
2020-03-01 18:19:59 +00:00
|
|
|
|
2020-03-09 22:47:31 +00:00
|
|
|
CastingTableScreenHandler.this.inventory.setInvStack(0, ItemStack.EMPTY);
|
|
|
|
CastingTableScreenHandler.this.inventory.takeInvStack(1, spells[index].getItemCost().getCount());
|
2020-03-01 18:19:59 +00:00
|
|
|
return stack;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
int k;
|
|
|
|
for (k = 0; k < 3; ++k) {
|
2020-03-02 22:11:37 +00:00
|
|
|
for (int j = 0; j < 9; ++j) {
|
2020-03-01 18:19:59 +00:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-24 19:29:41 +00:00
|
|
|
private void resetIndex() {
|
|
|
|
index = 0;
|
|
|
|
onContentChanged(inventory);
|
|
|
|
}
|
|
|
|
|
2020-03-24 13:35:42 +00:00
|
|
|
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();
|
|
|
|
}
|
2020-03-24 19:29:41 +00:00
|
|
|
resetIndex();
|
2020-03-24 13:35:42 +00:00
|
|
|
}
|
|
|
|
|
2020-03-01 18:19:59 +00:00
|
|
|
public boolean canTakeResult(PlayerEntity playerEntity) {
|
2020-03-09 22:47:31 +00:00
|
|
|
return playerEntity.isCreative() || playerEntity.experienceLevel >= spells[index].getXPCost();
|
2020-03-01 18:19:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setIndex(int index) {
|
|
|
|
this.index = index;
|
|
|
|
onContentChanged(inventory);
|
|
|
|
|
|
|
|
if (inventory.getInvStack(0).isEmpty() && inventory.getInvStack(1).isEmpty()) {
|
|
|
|
ItemStack spellItem = new ItemStack(SorceryCraft.SPELL_ITEM);
|
|
|
|
autoFill(0, spellItem, true);
|
|
|
|
ItemStack paymentItem = getRecipes()[index].getItemCost();
|
|
|
|
autoFill(1, paymentItem, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-09 02:00:36 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-03-01 18:19:59 +00:00
|
|
|
@Override
|
|
|
|
public void close(PlayerEntity player) {
|
|
|
|
super.close(player);
|
2020-03-04 01:22:40 +00:00
|
|
|
context.run((BiConsumer<World, BlockPos>) (world, blockPos) -> dropInventory(player, world, inventory));
|
2020-03-01 18:19:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onContentChanged(Inventory inventory) {
|
|
|
|
super.onContentChanged(inventory);
|
|
|
|
ItemStack item = inventory.getInvStack(0);
|
|
|
|
ItemStack cost = inventory.getInvStack(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();
|
2020-03-21 02:05:32 +00:00
|
|
|
Map<Identifier, Integer> resultSpells = SpellHelper.getSpells(resultItem);
|
2020-03-01 18:19:59 +00:00
|
|
|
if (!resultSpells.containsKey(spells[index].getID()) || resultSpells.get(spells[index].getID()) <= spells[index].getLevel()) {
|
|
|
|
resultSpells.put(spells[index].getID(), spells[index].getLevel());
|
|
|
|
}
|
2020-03-21 02:05:32 +00:00
|
|
|
SpellHelper.setSpells(resultItem, resultSpells);
|
2020-03-01 18:19:59 +00:00
|
|
|
result.setInvStack(2, resultItem);
|
|
|
|
} else {
|
|
|
|
result.setInvStack(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();
|
2020-03-02 22:11:37 +00:00
|
|
|
if (!itemStack.isEmpty() && itemCompatible(stack, itemStack)) {
|
2020-03-01 18:19:59 +00:00
|
|
|
ItemStack invSlot = inventory.getInvStack(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.setInvStack(slot, modifiedItem);
|
|
|
|
if (totalCount >= stack.getMaxCount() || onlyOne) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-02 22:11:37 +00:00
|
|
|
private boolean itemCompatible(ItemStack itemStack, ItemStack otherItemStack) {
|
|
|
|
return itemStack.getItem() == otherItemStack.getItem();
|
|
|
|
}
|
|
|
|
|
2020-03-01 18:19:59 +00:00
|
|
|
@Override
|
|
|
|
public boolean canUse(PlayerEntity player) {
|
2020-03-11 21:34:52 +00:00
|
|
|
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);
|
2020-03-01 18:19:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public Spell[] getRecipes() {
|
|
|
|
return spells;
|
|
|
|
}
|
|
|
|
}
|