Fix spell book for crystals trade not working
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package electroblob.wizardry.client;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import electroblob.wizardry.WizardData;
|
||||
@@ -9,6 +11,7 @@ import electroblob.wizardry.item.ItemSpectralBow;
|
||||
import electroblob.wizardry.item.ItemWand;
|
||||
import electroblob.wizardry.packet.PacketControlInput;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.spell.Flight;
|
||||
import electroblob.wizardry.spell.ShadowWard;
|
||||
@@ -17,19 +20,27 @@ import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiMerchant;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityArmorStand;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.village.MerchantRecipe;
|
||||
import net.minecraftforge.client.event.FOVUpdateEvent;
|
||||
import net.minecraftforge.client.event.GuiContainerEvent;
|
||||
import net.minecraftforge.client.event.MouseEvent;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import net.minecraftforge.client.event.RenderLivingEvent;
|
||||
@@ -39,6 +50,7 @@ import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.ReflectionHelper;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
/**
|
||||
@@ -59,6 +71,12 @@ public final class WizardryClientEventHandler {
|
||||
private static final ResourceLocation pointerTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/pointer.png");
|
||||
private static final ResourceLocation targetPointerTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/target_pointer.png");
|
||||
|
||||
private static final Field ITEM_RENDERER;
|
||||
|
||||
static {
|
||||
ITEM_RENDERER = ReflectionHelper.findField(GuiScreen.class, "itemRender", "");
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
|
||||
event.getMap().registerSprite(ContainerArcaneWorkbench.EMPTY_SLOT_CRYSTAL);
|
||||
@@ -115,6 +133,66 @@ public final class WizardryClientEventHandler {
|
||||
event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F);
|
||||
}
|
||||
}
|
||||
|
||||
// Brute-force fix for crystals not showing up when a wizard is given a spell book in the trade GUI.
|
||||
@SubscribeEvent
|
||||
public static void onGuiDrawForegroundEvent(GuiContainerEvent.DrawForeground event){
|
||||
|
||||
if(event.getGuiContainer() instanceof GuiMerchant){
|
||||
|
||||
GuiMerchant gui = (GuiMerchant)event.getGuiContainer();
|
||||
// Note that gui.getMerchant() returns an NpcMerchant, not an EntityWizard.
|
||||
|
||||
// Using == the specific item rather than instanceof because that's how trades do it.
|
||||
if(gui.inventorySlots.getSlot(0).getStack().getItem() == WizardryItems.spell_book
|
||||
|| gui.inventorySlots.getSlot(1).getStack().getItem() == WizardryItems.spell_book){
|
||||
|
||||
for(MerchantRecipe trade : gui.getMerchant().getRecipes(Minecraft.getMinecraft().player)){
|
||||
if(trade.getItemToBuy().getItem() == WizardryItems.spell_book && trade.getSecondItemToBuy().isEmpty()){
|
||||
Slot slot = gui.inventorySlots.getSlot(2);
|
||||
// Uses reflection to draw the itemstack
|
||||
// It still doesn't look quite right because the slot highlight is behind the item, but it'll do
|
||||
// until/unless I find a better solution.
|
||||
renderItemAndTooltip(gui, trade.getItemToSell(), slot.xPos, slot.yPos, event.getMouseX(), event.getMouseY(),
|
||||
gui.getSlotUnderMouse() == slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderItemAndTooltip(GuiContainer gui, ItemStack stack, int x, int y, int mouseX, int mouseY, boolean tooltip){
|
||||
|
||||
try {
|
||||
|
||||
RenderItem renderItem = (RenderItem)ITEM_RENDERER.get(gui);
|
||||
GlStateManager.pushMatrix();
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableRescaleNormal();
|
||||
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
|
||||
GlStateManager.enableLighting();
|
||||
renderItem.zLevel = 100.0F;
|
||||
|
||||
if(!stack.isEmpty()){
|
||||
renderItem.renderItemAndEffectIntoGUI(stack, x, y);
|
||||
renderItem.renderItemOverlays(Minecraft.getMinecraft().fontRenderer, stack, x, y);
|
||||
|
||||
if(tooltip){
|
||||
gui.drawHoveringText(gui.getItemToolTip(stack), mouseX + gui.getXSize()/2 - gui.width/2,
|
||||
mouseY + gui.getYSize()/2 - gui.height/2);
|
||||
}
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.enableLighting();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Third person
|
||||
@SubscribeEvent
|
||||
|
||||
@@ -23,6 +23,7 @@ import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.util.WildcardTradeList;
|
||||
import electroblob.wizardry.util.WizardryParticleType;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -91,6 +92,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
* are overriding something, in which case it should be fine). */
|
||||
|
||||
// Extending EntityVillager turned out to be a pretty neat thing to do, since now zombies will attack wizards
|
||||
// TODO: Perhaps we should be implementing IMerchant now instead?
|
||||
|
||||
private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50);
|
||||
|
||||
@@ -369,7 +371,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
|
||||
if(nbt.hasKey("trades")){
|
||||
NBTTagCompound nbttagcompound1 = nbt.getCompoundTag("trades");
|
||||
this.trades = new MerchantRecipeList(nbttagcompound1);
|
||||
this.trades = new WildcardTradeList(nbttagcompound1);
|
||||
}
|
||||
|
||||
this.setElement(Element.values()[nbt.getInteger("element")]);
|
||||
@@ -428,7 +430,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
|
||||
if(this.trades == null){
|
||||
|
||||
this.trades = new MerchantRecipeList();
|
||||
this.trades = new WildcardTradeList();
|
||||
|
||||
// All wizards will buy spell books
|
||||
ItemStack anySpellBook = new ItemStack(WizardryItems.spell_book, 1, OreDictionary.WILDCARD_VALUE);
|
||||
@@ -509,7 +511,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
Collections.shuffle(merchantrecipelist);
|
||||
|
||||
if(this.trades == null){
|
||||
this.trades = new MerchantRecipeList();
|
||||
this.trades = new WildcardTradeList();
|
||||
}
|
||||
|
||||
for(int j1 = 0; j1 < merchantrecipelist.size(); ++j1){
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.village.MerchantRecipe;
|
||||
import net.minecraft.village.MerchantRecipeList;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
/** Custom version of {@link MerchantRecipeList} which allows wildcard recipes (i.e. trades which accept items with any
|
||||
* damage value). Function is otherwise identical. For some reason this feature was removed in 1.11.
|
||||
* @author Electroblob
|
||||
* @since Wizardry 4.1 */
|
||||
@SuppressWarnings("serial")
|
||||
public class WildcardTradeList extends MerchantRecipeList {
|
||||
|
||||
public WildcardTradeList(){
|
||||
super();
|
||||
}
|
||||
|
||||
public WildcardTradeList(NBTTagCompound tag){
|
||||
super(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantRecipe canRecipeBeUsed(ItemStack offer1, ItemStack offer2, int index){
|
||||
|
||||
if(index > 0 && index < this.size()){
|
||||
|
||||
MerchantRecipe merchantrecipe1 = (MerchantRecipe)this.get(index);
|
||||
return !this.areItemStacksExactlyEqual(offer1, merchantrecipe1.getItemToBuy()) || (!offer2.isEmpty() || merchantrecipe1.hasSecondItemToBuy()) && (!merchantrecipe1.hasSecondItemToBuy() || !this.areItemStacksExactlyEqual(offer2, merchantrecipe1.getSecondItemToBuy())) || offer1.getCount() < merchantrecipe1.getItemToBuy().getCount() || merchantrecipe1.hasSecondItemToBuy() && offer2.getCount() < merchantrecipe1.getSecondItemToBuy().getCount() ? null : merchantrecipe1;
|
||||
|
||||
}else{
|
||||
|
||||
for(int i = 0; i < this.size(); ++i){
|
||||
|
||||
MerchantRecipe merchantrecipe = (MerchantRecipe)this.get(i);
|
||||
|
||||
if (this.areItemStacksExactlyEqual(offer1, merchantrecipe.getItemToBuy()) && offer1.getCount() >= merchantrecipe.getItemToBuy().getCount() && (!merchantrecipe.hasSecondItemToBuy() && offer2.isEmpty() || merchantrecipe.hasSecondItemToBuy() && this.areItemStacksExactlyEqual(offer2, merchantrecipe.getSecondItemToBuy()) && offer2.getCount() >= merchantrecipe.getSecondItemToBuy().getCount())){
|
||||
return merchantrecipe;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areItemStacksExactlyEqual(ItemStack stack1, ItemStack stack2){
|
||||
// Added to allow wildcards; this line is the only actual change.
|
||||
if((stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE)
|
||||
// Can't use ItemStack.areItemsEqualIgnoreDurability because that only works for items with durability, not subtypes.
|
||||
&& stack1.getItem() == stack2.getItem()) return true;
|
||||
|
||||
return ItemStack.areItemsEqual(stack1, stack2) && (!stack2.hasTagCompound() || stack1.hasTagCompound() && NBTUtil.areNBTEquals(stack2.getTagCompound(), stack1.getTagCompound(), false));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user