feat: implement basic Arcane Workbench crafting
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Timo Ley 2022-11-20 20:46:22 +01:00
parent 179eea1f32
commit 7eef7b249b
11 changed files with 438 additions and 30 deletions

View file

@ -2,6 +2,8 @@ package dev.tilera.auracore;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
@ -23,6 +25,7 @@ import dev.tilera.auracore.network.AuraTransferFXPacket;
import dev.tilera.auracore.network.AuraTransferFXPacketHandler;
import dev.tilera.auracore.network.NodeZapPacket;
import dev.tilera.auracore.network.NodeZapPacketHandler;
import dev.tilera.auracore.proxy.CommonProxy;
import dev.tilera.auracore.world.WorldGenerator;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
@ -36,6 +39,10 @@ import thaumcraft.common.config.ConfigItems;
public class AuraCore {
public static SimpleNetworkWrapper CHANNEL;
@Mod.Instance("auracore")
public static AuraCore INSTANCE;
@SidedProxy(modId = "auracore", clientSide = "dev.tilera.auracore.proxy.ClientProxy", serverSide = "dev.tilera.auracore.proxy.CommonProxy")
public static CommonProxy proxy;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent e) {
@ -62,6 +69,11 @@ public class AuraCore {
GameRegistry.registerWorldGenerator(new WorldGenerator(), 100);
}
@Mod.EventHandler
public void init(FMLInitializationEvent ev) {
NetworkRegistry.INSTANCE.registerGuiHandler(this, proxy);
}
@Mod.EventHandler
public void postInit(FMLPostInitializationEvent e) {
ThaumcraftApi.registerObjectTag(new ItemStack(ConfigItems.itemShard, 1, 0), new AspectList().add(Aspect.MAGIC, 2).add(Aspect.AIR, 2).add(Aspect.CRYSTAL, 2).add(Aspect.MOTION, 2));

View file

@ -0,0 +1,98 @@
package dev.tilera.auracore.client.gui;
import org.lwjgl.opengl.GL11;
import dev.tilera.auracore.api.IWand;
import dev.tilera.auracore.container.ContainerWorkbench;
import dev.tilera.auracore.crafting.AuracoreCraftingManager;
import dev.tilera.auracore.helper.Utils;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
import thaumcraft.api.crafting.IArcaneRecipe;
import thaumcraft.common.tiles.TileArcaneWorkbench;
public class GuiArcaneWorkbench extends GuiContainer {
private TileArcaneWorkbench tileEntity;
private InventoryPlayer ip;
public GuiArcaneWorkbench(InventoryPlayer par1InventoryPlayer, TileArcaneWorkbench e) {
super(new ContainerWorkbench(par1InventoryPlayer, e));
this.tileEntity = e;
this.ip = par1InventoryPlayer;
this.ySize += 10;
}
protected void drawGuiContainerForegroundLayer() {
}
@Override
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) {
this.mc.renderEngine.bindTexture(new ResourceLocation("auracore", "textures/gui/gui_arcaneworkbench.png"));
GL11.glColor4f((float)1.0f, (float)1.0f, (float)1.0f, (float)1.0f);
GL11.glEnable((int)3042);
int var5 = (this.width - this.xSize) / 2;
int var6 = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(var5, var6, 0, 0, this.xSize, this.ySize);
GL11.glDisable((int)3042);
if (this.tileEntity.getStackInSlot(10) != null && this.tileEntity.getStackInSlot(10).getItem() instanceof IWand) {
IWand wandImpl = (IWand) this.tileEntity.getStackInSlot(10).getItem();
int charge = wandImpl.getVis(this.tileEntity.getStackInSlot(10));
if (charge > 0) {
GL11.glPushMatrix();
GL11.glTranslatef((float)(var5 + 132), (float)(var6 + 85), (float)505.0f);
GL11.glScalef((float)0.5f, (float)0.5f, (float)0.0f);
String text = charge + " vis";
int ll = this.fontRendererObj.getStringWidth(text) / 2;
this.fontRendererObj.drawStringWithShadow(text, -ll, -16, 0xFFFFFF);
GL11.glScalef((float)1.0f, (float)1.0f, (float)1.0f);
GL11.glPopMatrix();
}
IArcaneRecipe recipe = AuracoreCraftingManager.findMatchingArcaneRecipe(this.tileEntity, this.ip.player);
if (null != null) {
int ll;
String text;
int cost = AuracoreCraftingManager.getArcaneRecipeVisCost(recipe, this.tileEntity);
int discount = 100 - Math.min(50, Utils.getTotalVisDiscount(this.ip.player));
if (charge < (cost = Math.round((float)cost * ((float)discount / 100.0f)))) {
GL11.glPushMatrix();
RenderHelper.enableGUIStandardItemLighting();
GL11.glDisable((int)2896);
GL11.glEnable((int)32826);
GL11.glEnable((int)2903);
GL11.glEnable((int)2896);
itemRender.renderItemIntoGUI(this.mc.fontRenderer, this.mc.renderEngine, recipe.getCraftingResult(this.tileEntity), var5 + 124, var6 + 28);
itemRender.renderItemOverlayIntoGUI(this.mc.fontRenderer, this.mc.renderEngine, recipe.getCraftingResult(this.tileEntity), var5 + 124, var6 + 28);
GL11.glDisable((int)2896);
GL11.glDepthMask((boolean)true);
GL11.glEnable((int)2929);
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glTranslatef((float)(var5 + 132), (float)(var6 + 82), (float)0.0f);
GL11.glScalef((float)0.5f, (float)0.5f, (float)0.0f);
text = "Insufficient charge";
if (cost > wandImpl.getMaxVis(this.tileEntity.getStackInSlot(10))) {
text = "This wand is too weak";
}
ll = this.fontRendererObj.getStringWidth(text) / 2;
this.fontRendererObj.drawString(text, -ll, 0, 0xEE6E6E);
GL11.glScalef((float)1.0f, (float)1.0f, (float)1.0f);
GL11.glPopMatrix();
}
if (cost > 0) {
GL11.glPushMatrix();
GL11.glTranslatef((float)(var5 + 132), (float)(var6 + 81), (float)0.0f);
GL11.glScalef((float)0.5f, (float)0.5f, (float)0.0f);
text = cost + " vis";
ll = this.fontRendererObj.getStringWidth(text) / 2;
this.fontRendererObj.drawStringWithShadow(text, -ll, -64, 0xEEEEEE);
GL11.glScalef((float)1.0f, (float)1.0f, (float)1.0f);
GL11.glPopMatrix();
}
}
}
}
}

View file

@ -0,0 +1,116 @@
package dev.tilera.auracore.container;
import dev.tilera.auracore.api.IWand;
import dev.tilera.auracore.crafting.AuracoreCraftingManager;
import dev.tilera.auracore.helper.Utils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import thaumcraft.api.crafting.IArcaneRecipe;
import thaumcraft.common.container.ContainerDummy;
import thaumcraft.common.items.wands.ItemWandCasting;
import thaumcraft.common.tiles.TileArcaneWorkbench;
public class ContainerWorkbench extends Container {
private TileArcaneWorkbench tileEntity;
private InventoryPlayer ip;
public ContainerWorkbench(InventoryPlayer par1InventoryPlayer, TileArcaneWorkbench e) {
int var7;
int var6;
this.tileEntity = e;
this.tileEntity.eventHandler = this;
this.ip = par1InventoryPlayer;
this.addSlotToContainer((Slot)new SlotCraftingArcaneWorkbench(par1InventoryPlayer.player, this.tileEntity, this.tileEntity, 9, 124, 29));
this.addSlotToContainer(new SlotWorkbenchWand(this.tileEntity, 10, 124, 61));
for (var6 = 0; var6 < 3; ++var6) {
for (var7 = 0; var7 < 3; ++var7) {
this.addSlotToContainer(new Slot(this.tileEntity, var7 + var6 * 3, 30 + var7 * 18, 17 + var6 * 18));
}
}
for (var6 = 0; var6 < 3; ++var6) {
for (var7 = 0; var7 < 9; ++var7) {
this.addSlotToContainer(new Slot(par1InventoryPlayer, var7 + var6 * 9 + 9, 8 + var7 * 18, 94 + var6 * 18));
}
}
for (var6 = 0; var6 < 9; ++var6) {
this.addSlotToContainer(new Slot(par1InventoryPlayer, var6, 8 + var6 * 18, 152));
}
this.onCraftMatrixChanged(this.tileEntity);
}
@Override
public void onCraftMatrixChanged(IInventory par1IInventory) {
InventoryCrafting ic = new InventoryCrafting(new ContainerDummy(), 3, 3);
for (int a = 0; a < 9; ++a) {
ic.setInventorySlotContents(a, this.tileEntity.getStackInSlot(a));
}
this.tileEntity.setInventorySlotContentsSoftly(9, CraftingManager.getInstance().findMatchingRecipe(ic, this.tileEntity.getWorldObj()));
if (this.tileEntity.getStackInSlot(9) == null && this.tileEntity.getStackInSlot(10) != null && this.tileEntity.getStackInSlot(10).getItem() instanceof IWand) {
IArcaneRecipe recipe = AuracoreCraftingManager.findMatchingArcaneRecipe(this.tileEntity, this.ip.player);
if (recipe != null && Utils.hasCharge(this.tileEntity.getStackInSlot(10), this.ip.player, AuracoreCraftingManager.getArcaneRecipeVisCost(recipe, this.tileEntity))) {
this.tileEntity.setInventorySlotContentsSoftly(9, recipe.getCraftingResult(this.tileEntity));
}
}
}
@Override
public void onContainerClosed(EntityPlayer par1EntityPlayer) {
super.onContainerClosed(par1EntityPlayer);
if (!this.tileEntity.getWorldObj().isRemote) {
this.tileEntity.eventHandler = null;
}
}
@Override
public boolean canInteractWith(EntityPlayer par1EntityPlayer) {
return this.tileEntity.getWorldObj().getTileEntity(this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord) != this.tileEntity ? false : par1EntityPlayer.getDistanceSq((double)this.tileEntity.xCoord + 0.5, (double)this.tileEntity.yCoord + 0.5, (double)this.tileEntity.zCoord + 0.5) <= 64.0;
}
@Override
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par1) {
ItemStack var2 = null;
Slot var3 = (Slot)this.inventorySlots.get(par1);
if (var3 != null && var3.getHasStack()) {
ItemStack var4 = var3.getStack();
var2 = var4.copy();
if (par1 == 0) {
if (!this.mergeItemStack(var4, 11, 47, true)) {
return null;
}
var3.onSlotChange(var4, var2);
} else if (par1 >= 11 && par1 < 38) {
if (var4.getItem() instanceof ItemWandCasting || var4.getItem() instanceof IWand) {
if (!this.mergeItemStack(var4, 1, 2, false)) {
return null;
}
var3.onSlotChange(var4, var2);
} else if (!this.mergeItemStack(var4, 38, 47, false)) {
return null;
}
} else if (par1 >= 38 && par1 < 47 ? !this.mergeItemStack(var4, 11, 38, false) : !this.mergeItemStack(var4, 11, 47, false)) {
return null;
}
if (var4.stackSize == 0) {
var3.putStack((ItemStack)null);
} else {
var3.onSlotChanged();
}
if (var4.stackSize == var2.stackSize) {
return null;
}
var3.onPickupFromSlot(this.ip.player, var4);
}
return var2;
}
@Override
public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer par4EntityPlayer) {
return super.slotClick(par1, par2, par3, par4EntityPlayer);
}
}

View file

@ -0,0 +1,50 @@
package dev.tilera.auracore.container;
import cpw.mods.fml.common.FMLCommonHandler;
import dev.tilera.auracore.crafting.AuracoreCraftingManager;
import dev.tilera.auracore.helper.Utils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
import thaumcraft.api.crafting.IArcaneRecipe;
public class SlotCraftingArcaneWorkbench extends SlotCrafting {
private final IInventory craftMatrix;
private EntityPlayer thePlayer;
public SlotCraftingArcaneWorkbench(EntityPlayer par1EntityPlayer, IInventory par2IInventory, IInventory par3IInventory, int par4, int par5, int par6) {
super(par1EntityPlayer, par2IInventory, par3IInventory, par4, par5, par6);
this.thePlayer = par1EntityPlayer;
this.craftMatrix = par2IInventory;
}
public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par1ItemStack) {
FMLCommonHandler.instance().firePlayerCraftingEvent(this.thePlayer, par1ItemStack, this.craftMatrix);
this.onCrafting(par1ItemStack);
IArcaneRecipe recipe = AuracoreCraftingManager.findMatchingArcaneRecipe(this.craftMatrix, this.thePlayer);
int cost = recipe == null ? 0 : AuracoreCraftingManager.getArcaneRecipeVisCost(recipe, this.craftMatrix);
if (cost > 0) {
Utils.spendCharge(this.craftMatrix.getStackInSlot(10), par1EntityPlayer, cost);
}
for (int var2 = 0; var2 < 9; ++var2) {
ItemStack var3 = this.craftMatrix.getStackInSlot(var2);
if (var3 == null) continue;
this.craftMatrix.decrStackSize(var2, 1);
if (!var3.getItem().hasContainerItem()) continue;
ItemStack var4 = var3.getItem().getContainerItem(var3);
if (var4.isItemStackDamageable() && var4.getItemDamage() > var4.getMaxDamage()) {
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this.thePlayer, var4));
var4 = null;
}
if (var4 == null || var3.getItem().doesContainerItemLeaveCraftingGrid(var3) && this.thePlayer.inventory.addItemStackToInventory(var4)) continue;
if (this.craftMatrix.getStackInSlot(var2) == null) {
this.craftMatrix.setInventorySlotContents(var2, var4);
continue;
}
this.thePlayer.dropPlayerItemWithRandomChoice(var4, true);
}
}
}

View file

@ -0,0 +1,18 @@
package dev.tilera.auracore.container;
import dev.tilera.auracore.api.IWand;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import thaumcraft.common.items.wands.ItemWandCasting;
class SlotWorkbenchWand extends Slot {
public SlotWorkbenchWand(IInventory par2IInventory, int par3, int par4, int par5) {
super(par2IInventory, par3, par4, par5);
}
@Override
public boolean isItemValid(ItemStack par1ItemStack) {
return par1ItemStack.getItem() instanceof ItemWandCasting || par1ItemStack.getItem() instanceof IWand;
}
}

View file

@ -0,0 +1,32 @@
package dev.tilera.auracore.crafting;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import thaumcraft.api.ThaumcraftApi;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.crafting.IArcaneRecipe;
public class AuracoreCraftingManager {
public static IArcaneRecipe findMatchingArcaneRecipe(IInventory awb, EntityPlayer player) {
for (Object recipe : ThaumcraftApi.getCraftingRecipes()) {
if (recipe instanceof IArcaneRecipe && ((IArcaneRecipe)recipe).matches(awb, player.worldObj, player)) {
return (IArcaneRecipe) recipe;
}
}
return null;
}
public static int getArcaneRecipeVisCost(IArcaneRecipe recipe, IInventory awb) {
if (recipe == null) return 0;
int sum = 0;
AspectList aspects = recipe.getAspects(awb);
for (Aspect aspect : aspects.getAspects()) {
if (aspect != null) sum += aspects.getAmount(aspect);
}
return sum;
}
}

View file

@ -0,0 +1,69 @@
package dev.tilera.auracore.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import dev.tilera.auracore.AuraCore;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.common.Thaumcraft;
import thaumcraft.common.blocks.BlockTable;
import thaumcraft.common.items.wands.ItemWandCasting;
import thaumcraft.common.tiles.TileArcaneWorkbench;
import thaumcraft.common.tiles.TileDeconstructionTable;
import thaumcraft.common.tiles.TileResearchTable;
@Mixin(BlockTable.class)
public abstract class MixinBlockTable extends BlockContainer {
protected MixinBlockTable(Material p_i45386_1_) {
super(p_i45386_1_);
}
/**
* @author tilera
* @reason Old workbench GUI
*/
@Overwrite(remap = false)
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int idk, float what, float these, float are) {
TileEntity tileEntity = world.getTileEntity(x, y, z);
int md = world.getBlockMetadata(x, y, z);
if (md > 1 && tileEntity != null && !player.isSneaking()) {
if (world.isRemote) {
return true;
} else if (tileEntity instanceof TileArcaneWorkbench) {
TileArcaneWorkbench workbench = (TileArcaneWorkbench) tileEntity;
if (workbench.getStackInSlot(10) != null && workbench.getStackInSlot(10).getItem() instanceof ItemWandCasting) {
player.openGui(Thaumcraft.instance, 13, world, x, y, z);
} else {
player.openGui(AuraCore.INSTANCE, 0, world, x, y, z);
}
return true;
} else if (tileEntity instanceof TileDeconstructionTable) {
player.openGui(Thaumcraft.instance, 8, world, x, y, z);
return true;
} else {
if (tileEntity instanceof TileResearchTable) {
player.openGui(Thaumcraft.instance, 10, world, x, y, z);
} else {
for(int a = 2; a < 6; ++a) {
TileEntity tile = world.getTileEntity(x + ForgeDirection.getOrientation(a).offsetX, y + ForgeDirection.getOrientation(a).offsetY, z + ForgeDirection.getOrientation(a).offsetZ);
if (tile != null && tile instanceof TileResearchTable) {
player.openGui(Thaumcraft.instance, 10, world, x + ForgeDirection.getOrientation(a).offsetX, y + ForgeDirection.getOrientation(a).offsetY, z + ForgeDirection.getOrientation(a).offsetZ);
break;
}
}
}
return true;
}
} else {
return false;
}
}
}

View file

@ -1,29 +0,0 @@
package dev.tilera.auracore.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import dev.tilera.auracore.api.IWand;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import thaumcraft.common.container.SlotLimitedByWand;
import thaumcraft.common.items.wands.ItemWandCasting;
@Mixin(SlotLimitedByWand.class)
public abstract class MixinSlotLimitedByWand extends Slot {
public MixinSlotLimitedByWand(IInventory p_i1824_1_, int p_i1824_2_, int p_i1824_3_, int p_i1824_4_) {
super(p_i1824_1_, p_i1824_2_, p_i1824_3_, p_i1824_4_);
}
/**
* @author tilera
* @reason Allow classic wands in Arcane Worktable
*/
@Overwrite
public boolean isItemValid(final ItemStack stack) {
return stack != null && stack.getItem() != null && ((stack.getItem() instanceof ItemWandCasting && !((ItemWandCasting)stack.getItem()).isStaff(stack)) || stack.getItem() instanceof IWand);
}
}

View file

@ -0,0 +1,18 @@
package dev.tilera.auracore.proxy;
import dev.tilera.auracore.client.gui.GuiArcaneWorkbench;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import thaumcraft.common.tiles.TileArcaneWorkbench;
public class ClientProxy extends CommonProxy {
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
if (id == 0) {
return new GuiArcaneWorkbench(player.inventory, (TileArcaneWorkbench) world.getTileEntity(x, y, z));
}
return null;
}
}

View file

@ -0,0 +1,24 @@
package dev.tilera.auracore.proxy;
import cpw.mods.fml.common.network.IGuiHandler;
import dev.tilera.auracore.container.ContainerWorkbench;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import thaumcraft.common.tiles.TileArcaneWorkbench;
public class CommonProxy implements IGuiHandler {
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
if (id == 0) {
return new ContainerWorkbench(player.inventory, (TileArcaneWorkbench) world.getTileEntity(x, y, z));
}
return null;
}
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
return null;
}
}

View file

@ -13,8 +13,8 @@
"MixinTileAlembic",
"MixinBlockCustomPlant",
"MixinBlockCustomOre",
"MixinBlockTable",
"MixinEventHandlerEntity",
"MixinSlotLimitedByWand",
"MixinThaumcraftWorldGenerator"
],
"client": [