/*******************************************************************************
* AbyssalCraft
* Copyright (c) 2012 - 2017 Shinoow.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Contributors:
* Shinoow - implementation
******************************************************************************/
package com.shinoow.abyssalcraft.common.entity;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentData;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.IMerchant;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackMelee;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIOpenDoor;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITasks.EntityAITaskEntry;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.village.MerchantRecipeList;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import com.shinoow.abyssalcraft.api.APIUtils;
import com.shinoow.abyssalcraft.api.entity.EntityUtil;
import com.shinoow.abyssalcraft.api.entity.IAntiEntity;
import com.shinoow.abyssalcraft.api.entity.ICoraliumEntity;
import com.shinoow.abyssalcraft.api.entity.IDreadEntity;
import com.shinoow.abyssalcraft.api.item.ACItems;
import com.shinoow.abyssalcraft.common.items.ItemDrainStaff;
import com.shinoow.abyssalcraft.common.items.ItemNecronomicon;
import com.shinoow.abyssalcraft.lib.ACConfig;
import com.shinoow.abyssalcraft.lib.ACLoot;
import com.shinoow.abyssalcraft.lib.ACSounds;
public class EntityRemnant extends EntityMob implements IMerchant, IAntiEntity, ICoraliumEntity, IDreadEntity {
private static final DataParameter<Integer> PROFESSION = EntityDataManager.<Integer>createKey(EntityRemnant.class, DataSerializers.VARINT);
private EntityPlayer tradingPlayer;
private MerchantRecipeList tradingList;
private int timeUntilReset;
private boolean needsInitilization;
private int wealth;
private int timer;
private float field_82191_bN;
public static final Map<Item, Tuple> itemSellingList = new HashMap<Item, Tuple>();
public static final Map<Item, Tuple> coinSellingList = new HashMap<Item, Tuple>();
public EntityRemnant(World par1World) {
super(par1World);
tasks.addTask(0, new EntityAISwimming(this));
tasks.addTask(3, new EntityAIAttackMelee(this, 0.35D, false));
tasks.addTask(4, new EntityAIOpenDoor(this, true));
tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 0.35D));
tasks.addTask(6, new EntityAIWander(this, 0.35D));
tasks.addTask(7, new EntityAILookIdle(this));
tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
tasks.addTask(7, new EntityAIWatchClosest(this, EntityRemnant.class, 8.0F));
tasks.addTask(7, new EntityAIWatchClosest(this, EntityGatekeeperMinion.class, 8.0F));
targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
}
@Override
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(64.0D);
getEntityAttribute(SharedMonsterAttributes.KNOCKBACK_RESISTANCE).setBaseValue(0.2D);
if(ACConfig.hardcoreMode){
getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(200.0D);
getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(20.0D);
} else {
getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(100.0D);
getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(10.0D);
}
}
@Override
public boolean canBreatheUnderwater() {
return true;
}
@Override
public boolean attackEntityAsMob(Entity par1Entity)
{
swingArm(EnumHand.MAIN_HAND);
swingArm(EnumHand.OFF_HAND);
boolean flag = super.attackEntityAsMob(par1Entity);
if(ACConfig.hardcoreMode && par1Entity instanceof EntityPlayer)
par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this).setDamageBypassesArmor().setDamageIsAbsolute(), 3 * (float)(ACConfig.damageAmpl > 1.0D ? ACConfig.damageAmpl : 1));
return flag;
}
@Override
@SuppressWarnings("rawtypes")
protected void updateAITasks() {
if (!isTrading() && timeUntilReset > 0)
{
--timeUntilReset;
if (timeUntilReset <= 0)
{
if (needsInitilization)
{
if (tradingList.size() > 1)
{
Iterator iterator = tradingList.iterator();
while (iterator.hasNext())
{
MerchantRecipe merchantrecipe = (MerchantRecipe)iterator.next();
if (merchantrecipe.isRecipeDisabled())
merchantrecipe.increaseMaxTradeUses(rand.nextInt(6) + rand.nextInt(6) + 2);
}
}
addDefaultEquipmentAndRecipies(1);
needsInitilization = false;
}
addPotionEffect(new PotionEffect(MobEffects.REGENERATION, 200, 0));
}
}
super.updateAITasks();
}
@Override
public boolean processInteract(EntityPlayer par1EntityPlayer, EnumHand hand)
{
if(isEntityAlive() && !par1EntityPlayer.isSneaking() && !isAngry())
if(EntityUtil.hasNecronomicon(par1EntityPlayer) && ownsTheirBook(par1EntityPlayer)){
if(!isTrading()){
if(!world.isRemote){
setCustomer(par1EntityPlayer);
par1EntityPlayer.displayVillagerTradeGui(this);
return true;
}
} else if(!tradingPlayer.getUniqueID().equals(par1EntityPlayer.getUniqueID())) par1EntityPlayer.sendMessage(new TextComponentString(getName()+": "+I18n.translateToLocal("message.remnant.busy")));
} else {
insult(par1EntityPlayer);
return true;
}
return super.processInteract(par1EntityPlayer, hand);
}
private boolean ownsTheirBook(EntityPlayer player){
for(ItemStack stack : player.inventory.mainInventory)
if(stack != null && stack.getItem() instanceof ItemNecronomicon && !((ItemNecronomicon)stack.getItem()).isOwner(player, stack))
return false;
return true;
}
@Override
protected void entityInit()
{
super.entityInit();
dataManager.register(PROFESSION, Integer.valueOf(0));
}
/**
* Used by Remnants to insult oblivious Players
* @param player The target to insult
*/
private void insult(EntityPlayer player){
int insultNum = world.rand.nextInt(3);
String insult = getName()+": "+String.format(getInsult(insultNum), player.getName());
String translated = getName()+": "+String.format(I18n.translateToLocal("message.remnant.insult."+insultNum), player.getName());
if(world.isRemote){
List<EntityPlayer> players = world.getEntitiesWithinAABB(EntityPlayer.class, player.getEntityBoundingBox().expand(16D, 16D, 16D));
if(players != null){
Iterator<EntityPlayer> i = players.iterator();
while(i.hasNext()){
EntityPlayer player1 = i.next();
if(EntityUtil.hasNecronomicon(player1))
player1.sendMessage(new TextComponentString(translated));
else player1.sendMessage(new TextComponentString(insult));
}
}
}
}
/**
* Insult generator
* @param num Which insult to pick, number should be generated through Random.nextInt(3)
* @return A insult that humans don't understand
*/
private String getInsult(int num){
switch(num){
case 0:
return "%s, Aklo g'ai ftrr nfto lagln f'tifh mtli ot aishgft 'ai.";
case 1:
return "%s ukhoyah g'ka-dish-tu.";
case 2:
return "%s go-tha ukhoyah Necronomicon g'mnahn'.";
// case 3:
// return "test %s";
// case 4:
// return "test %s";
default:
return getInsult(0);
}
}
/**
* Used by Minions of The Gatekeeper to set the attack target and enrage the Remnant
* @param call If the Remnant should call for backup
* @param enemy The target
*/
public void enrage(boolean call, EntityLivingBase enemy){
setAttackTarget(enemy);
enrage(call);
}
/**
* Calling this method will make the Remnant hostile.
* Ever wanted to see a angry Remnant? No you don't.
* @param call If the Remnant should call for backup
*/
public void enrage(boolean call){
if(call){
List<EntityRemnant> friends = world.getEntitiesWithinAABB(getClass(), getEntityBoundingBox().expand(16D, 16D, 16D));
if(friends != null){
Iterator<EntityRemnant> iter = friends.iterator();
while(iter.hasNext())
iter.next().enrage(false, getAttackTarget());
}
playSound(ACSounds.remnant_scream, 3F, 1F);
}
setAngry();
setAttackAI();
}
@Override
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
{
if(par1DamageSource.getSourceOfDamage() instanceof EntityLivingBase){
if(getAttackTarget() != par1DamageSource.getSourceOfDamage()){
setAttackTarget((EntityLivingBase) par1DamageSource.getEntity());
enrage(true, getAttackTarget());
}
if(!isAngry()) enrage(true);
else enrage(rand.nextInt(10) == 0);
}
return super.attackEntityFrom(par1DamageSource, par2);
}
@Override
public void onLivingUpdate(){
super.onLivingUpdate();
if(isAngry()){
setAttackAI();
timer--;
if(timer <= 0)
timer = 0;
}
if(!isAngry()) clearAttackAI();
}
@Override
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeEntityToNBT(par1NBTTagCompound);
par1NBTTagCompound.setInteger("Profession", getProfession());
par1NBTTagCompound.setInteger("Money", wealth);
par1NBTTagCompound.setInteger("AngerTimer", timer);
if (tradingList != null)
par1NBTTagCompound.setTag("Offers", tradingList.getRecipiesAsTags());
}
@Override
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readEntityFromNBT(par1NBTTagCompound);
setProfession(par1NBTTagCompound.getInteger("Profession"));
wealth = par1NBTTagCompound.getInteger("Money");
timer = par1NBTTagCompound.getInteger("AngerTimer");
if (par1NBTTagCompound.hasKey("Offers", 10))
{
NBTTagCompound nbttagcompound1 = par1NBTTagCompound.getCompoundTag("Offers");
tradingList = new MerchantRecipeList(nbttagcompound1);
}
}
public boolean isAngry(){
return timer > 0;
}
public void setAngry(){
timer = 600;
}
private void clearAttackAI(){
if(getAttackTarget() != null)
setAttackTarget(null);
EntityAINearestAttackableTarget ai = fetchAI();
if(ai == null) return;
else targetTasks.removeTask(ai);
if(targetTasks.taskEntries.size() > 1)
clearAttackAI();
}
private void setAttackAI(){
if(getAttackTarget() != null){
Class temp = getAttackTarget().getClass();
EntityAINearestAttackableTarget ai = fetchAI();
if(ai != null){
if(temp != ReflectionHelper.findField(ai.getClass(), "targetClass", "field_75307_b").getDeclaringClass()){
targetTasks.removeTask(ai);
targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, temp, true));
}
} else targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, temp, true));
}
}
private EntityAINearestAttackableTarget fetchAI(){
for(EntityAITaskEntry entry : targetTasks.taskEntries)
if(entry.action instanceof EntityAINearestAttackableTarget)
return (EntityAINearestAttackableTarget) entry.action;
return null;
}
@Override
protected Item getDropItem()
{
return ACItems.eldritch_scale;
}
@Override
protected ResourceLocation getLootTable(){
return ACLoot.ENTITY_REMNANT;
}
@Override
protected boolean canDespawn()
{
return false;
}
@Override
protected SoundEvent getAmbientSound(){
return getProfession() == 2 && rand.nextBoolean() ? ACSounds.remnant_priest_chant : null;
}
@Override
protected SoundEvent getDeathSound()
{
return ACSounds.shadow_death;
}
@Override
protected void playStepSound(BlockPos pos, Block par4)
{
playSound(SoundEvents.ENTITY_SPIDER_STEP, 0.15F, 1.0F);
}
public void setProfession(int par1)
{
dataManager.set(PROFESSION, Integer.valueOf(par1));
}
public int getProfession()
{
return dataManager.get(PROFESSION);
}
@Override
public void setCustomer(EntityPlayer var1) {
tradingPlayer = var1;
}
@Override
public EntityPlayer getCustomer() {
return tradingPlayer;
}
public boolean isTrading(){
return tradingPlayer != null;
}
@Override
public MerchantRecipeList getRecipes(EntityPlayer var1) {
if(tradingList == null)
addDefaultEquipmentAndRecipies(1);
return tradingList;
}
private float adjustProbability(float par1)
{
float f1 = par1 + field_82191_bN;
return f1 > 0.9F ? 0.9F - (f1 - 0.9F) : f1;
}
@SuppressWarnings("unchecked")
private void addDefaultEquipmentAndRecipies(int par1)
{
if (tradingList != null)
field_82191_bN = MathHelper.sqrt(tradingList.size()) * 0.2F;
else
field_82191_bN = 0.0F;
MerchantRecipeList list;
list = new MerchantRecipeList();
int k;
label50:
switch (getProfession())
{
case 0:
addItemTrade(list, Items.WHEAT, rand, adjustProbability(0.9F));
addItemTrade(list, Item.getItemFromBlock(Blocks.WOOL), rand, adjustProbability(0.5F));
addItemTrade(list, Items.CHICKEN, rand, adjustProbability(0.5F));
addItemTrade(list, Items.COOKED_FISH, rand, adjustProbability(0.4F));
addCoinTrade(list, Items.BREAD, rand, adjustProbability(0.9F));
addCoinTrade(list, Items.MELON, rand, adjustProbability(0.3F));
addCoinTrade(list, Items.APPLE, rand, adjustProbability(0.3F));
addCoinTrade(list, Items.COOKIE, rand, adjustProbability(0.3F));
addCoinTrade(list, Items.SHEARS, rand, adjustProbability(0.3F));
addCoinTrade(list, Items.FLINT_AND_STEEL, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.fish_on_a_plate, rand, adjustProbability(0.3F));
addCoinTrade(list, Items.ARROW, rand, adjustProbability(0.5F));
if (rand.nextFloat() < adjustProbability(0.5F))
list.add(new MerchantRecipe(new ItemStack(Blocks.GRAVEL, 10), new ItemStack(ACItems.elder_engraved_coin), new ItemStack(Items.FLINT, 4 + rand.nextInt(2), 0)));
break;
case 1:
addItemTrade(list, Items.PAPER, rand, adjustProbability(0.8F));
addItemTrade(list, Items.BOOK, rand, adjustProbability(0.8F));
addItemTrade(list, Items.WRITTEN_BOOK, rand, adjustProbability(0.3F));
addItemTrade(list, Items.ROTTEN_FLESH, rand, adjustProbability(0.7F));
addItemTrade(list, ACItems.coralium_plagued_flesh, rand, adjustProbability(0.7F));
addItemTrade(list, ACItems.dread_fragment, rand, adjustProbability(0.7F));
addItemTrade(list, ACItems.omothol_flesh, rand, adjustProbability(0.7F));
addItemTrade(list, ACItems.rotten_anti_flesh, rand, adjustProbability(0.3F));
addCoinTrade(list, Item.getItemFromBlock(Blocks.BOOKSHELF), rand, adjustProbability(0.8F));
addCoinTrade(list, Item.getItemFromBlock(Blocks.GLASS), rand, adjustProbability(0.2F));
addCoinTrade(list, Items.COMPASS, rand, adjustProbability(0.2F));
addCoinTrade(list, Items.CLOCK, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.necronomicon, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.abyssal_wasteland_necronomicon, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.dreadlands_necronomicon, rand, adjustProbability(0.1F));
if (rand.nextFloat() < adjustProbability(0.07F))
{
Enchantment enchantment = Enchantment.REGISTRY.getRandomObject(rand);
int i1 = MathHelper.getInt(rand, enchantment.getMinLevel(), enchantment.getMaxLevel());
ItemStack itemstack = Items.ENCHANTED_BOOK.getEnchantedItemStack(new EnchantmentData(enchantment, i1));
k = 2 + rand.nextInt(5 + i1 * 10) + 3 * i1;
list.add(new MerchantRecipe(new ItemStack(Items.BOOK), new ItemStack(ACItems.elder_engraved_coin, k), itemstack));
}
break;
case 2:
addCoinTrade(list, Items.ENDER_EYE, rand, adjustProbability(0.3F));
addCoinTrade(list, Items.EXPERIENCE_BOTTLE, rand, adjustProbability(0.2F));
addCoinTrade(list, Items.REDSTONE, rand, adjustProbability(0.4F));
addCoinTrade(list, Item.getItemFromBlock(Blocks.GLOWSTONE), rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.ritual_charm, rand, adjustProbability(0.4F));
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.cthulhu_charm, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.hastur_charm, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.jzahar_charm, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.azathoth_charm, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.nyarlathotep_charm, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.yog_sothoth_charm, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.shub_niggurath_charm, 1);
addCoinTrade(list, ACItems.staff_of_rending, rand, adjustProbability(0.1F));
Item[] aitem = new Item[] {ACItems.ethaxium_sword, ACItems.ethaxium_chestplate, ACItems.ethaxium_axe, ACItems.ethaxium_pickaxe, ACItems.ethaxium_shovel};
Item[] aitem1 = aitem;
int j = aitem.length;
k = 0;
while (true)
{
if (k >= j)
break label50;
Item item = aitem1[k];
if (rand.nextFloat() < adjustProbability(0.05F))
list.add(new MerchantRecipe(new ItemStack(item, 1, 0), new ItemStack(ACItems.elder_engraved_coin, 2 + rand.nextInt(3), 0), EnchantmentHelper.addRandomEnchantment(rand, new ItemStack(item, 1, 0), 5 + rand.nextInt(15), true)));
++k;
}
case 3:
addItemTrade(list, Items.COAL, rand, adjustProbability(0.7F));
addItemTrade(list, ACItems.abyssalnite_ingot, rand, adjustProbability(0.5F));
addItemTrade(list, ACItems.refined_coralium_ingot, rand, adjustProbability(0.5F));
addItemTrade(list, ACItems.dreadium_ingot, rand, adjustProbability(0.5F));
addItemTrade(list, ACItems.ethaxium_ingot, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.ethaxium_sword, rand, adjustProbability(0.5F));
addCoinTrade(list, ACItems.ethaxium_axe, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.ethaxium_pickaxe, rand, adjustProbability(0.5F));
addCoinTrade(list, ACItems.ethaxium_shovel, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.ethaxium_hoe, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.ethaxium_boots, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.ethaxium_helmet, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.ethaxium_chestplate, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.ethaxium_leggings, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.blank_engraving, rand, adjustProbability(0.2F));
break;
case 4:
addItemTrade(list, Items.COAL, rand, adjustProbability(0.7F));
addItemTrade(list, Items.PORKCHOP, rand, adjustProbability(0.5F));
addItemTrade(list, Items.BEEF, rand, adjustProbability(0.5F));
addItemTrade(list, Items.CHICKEN, rand, adjustProbability(0.5F));
addCoinTrade(list, ACItems.washcloth, rand, adjustProbability(0.4F));
addCoinTrade(list, ACItems.mre, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.pork_on_a_plate, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.beef_on_a_plate, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.chicken_on_a_plate, rand, adjustProbability(0.3F));
break;
case 5:
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.cthulhu_engraved_coin, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.hastur_engraved_coin, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.jzahar_engraved_coin, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.azathoth_engraved_coin, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.nyarlathotep_engraved_coin, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.yog_sothoth_engraved_coin, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 8, ACItems.shub_niggurath_engraved_coin, 1);
addCoinTrade(list, ACItems.elder_engraved_coin, 16, ACItems.cthulhu_engraved_coin, 2);
addCoinTrade(list, ACItems.elder_engraved_coin, 16, ACItems.hastur_engraved_coin, 2);
addCoinTrade(list, ACItems.elder_engraved_coin, 16, ACItems.jzahar_engraved_coin, 2);
addCoinTrade(list, ACItems.elder_engraved_coin, 16, ACItems.azathoth_engraved_coin, 2);
addCoinTrade(list, ACItems.elder_engraved_coin, 16, ACItems.nyarlathotep_engraved_coin, 2);
addCoinTrade(list, ACItems.elder_engraved_coin, 16, ACItems.yog_sothoth_engraved_coin, 2);
addCoinTrade(list, ACItems.elder_engraved_coin, 16, ACItems.shub_niggurath_engraved_coin, 2);
addCoinTrade(list, ACItems.elder_engraved_coin, 24, ACItems.cthulhu_engraved_coin, 3);
addCoinTrade(list, ACItems.elder_engraved_coin, 24, ACItems.hastur_engraved_coin, 3);
addCoinTrade(list, ACItems.elder_engraved_coin, 24, ACItems.jzahar_engraved_coin, 3);
addCoinTrade(list, ACItems.elder_engraved_coin, 24, ACItems.azathoth_engraved_coin, 3);
addCoinTrade(list, ACItems.elder_engraved_coin, 24, ACItems.nyarlathotep_engraved_coin, 3);
addCoinTrade(list, ACItems.elder_engraved_coin, 24, ACItems.yog_sothoth_engraved_coin, 3);
addCoinTrade(list, ACItems.elder_engraved_coin, 24, ACItems.shub_niggurath_engraved_coin, 3);
break;
case 6:
addItemTrade(list, Items.COAL, rand, adjustProbability(0.7F));
addItemTrade(list, ACItems.abyssalnite_ingot, rand, adjustProbability(0.5F));
addItemTrade(list, ACItems.refined_coralium_ingot, rand, adjustProbability(0.5F));
addItemTrade(list, ACItems.dreadium_ingot, rand, adjustProbability(0.5F));
addItemTrade(list, ACItems.ethaxium_ingot, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.ethaxium_sword, rand, adjustProbability(0.5F));
addCoinTrade(list, ACItems.ethaxium_axe, rand, adjustProbability(0.3F));
addCoinTrade(list, ACItems.ethaxium_pickaxe, rand, adjustProbability(0.5F));
addCoinTrade(list, ACItems.ethaxium_shovel, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.ethaxium_hoe, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.plated_coralium_boots, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.dreadium_samurai_boots, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.plated_coralium_helmet, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.dreadium_samurai_helmet, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.plated_coralium_chestplate, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.dreadium_samurai_chestplate, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.plated_coralium_leggings, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.dreadium_samurai_leggings, rand, adjustProbability(0.2F));
addCoinTrade(list, ACItems.ethaxium_boots, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.ethaxium_helmet, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.ethaxium_chestplate, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.ethaxium_leggings, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.cthulhu_engraving, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.hastur_engraving, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.jzahar_engraving, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.azathoth_engraving, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.nyarlathotep_engraving, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.yog_sothoth_engraving, rand, adjustProbability(0.1F));
addCoinTrade(list, ACItems.shub_niggurath_engraving, rand, adjustProbability(0.1F));
}
if (list.isEmpty())
addItemTrade(list, Items.GOLD_INGOT, rand, 1.0F);
Collections.shuffle(list);
if (tradingList == null)
tradingList = new MerchantRecipeList();
for (int l = 0; l < par1 && l < list.size(); ++l)
addToListWithCheck(tradingList,list.get(l));
}
@Override
@SideOnly(Side.CLIENT)
public void setRecipes(MerchantRecipeList var1) {}
@Override
public World getWorld()
{
return world;
}
@Override
public BlockPos getPos()
{
return new BlockPos(this);
}
@Override
public void useRecipe(MerchantRecipe var1) {
var1.incrementToolUses();
if(var1.getItemToSell().getItem() instanceof ItemTool ||
var1.getItemToSell().getItem() instanceof ItemArmor){
var1.incrementToolUses();
var1.incrementToolUses();
var1.incrementToolUses();
}
if(var1.getItemToBuy().getItem() instanceof ItemNecronomicon ||
var1.getItemToBuy().getItem() instanceof ItemDrainStaff)
var1.compensateToolUses();
livingSoundTime = -getTalkInterval();
playSound(ACSounds.remnant_yes, getSoundVolume(), getSoundPitch());
if (hasSameIDsAs(var1, tradingList.get(tradingList.size() - 1)))
{
timeUntilReset = 40;
needsInitilization = true;
}
if (APIUtils.isCoin(var1.getItemToBuy()))
wealth += var1.getItemToBuy().getCount();
}
/****************** START OF VANILLA CODE FROM 1.7.10 ******************/
private void addToListWithCheck(MerchantRecipeList list, MerchantRecipe recipe)
{
for (int i = 0; i < list.size(); ++i)
{
MerchantRecipe merchantrecipe1 = list.get(i);
if (hasSameIDsAs(recipe, merchantrecipe1))
{
if (hasSameItemsAs(recipe, merchantrecipe1))
list.set(i, recipe);
return;
}
}
list.add(recipe);
}
private boolean hasSameIDsAs(MerchantRecipe r1, MerchantRecipe r2)
{
return r1.getItemToBuy().getItem() == r2.getItemToBuy().getItem() && r1.getItemToSell().getItem() == r2.getItemToSell().getItem() ?
r1.getSecondItemToBuy().isEmpty() && r2.getSecondItemToBuy().isEmpty() || !r1.getSecondItemToBuy().isEmpty() && !r2.getSecondItemToBuy().isEmpty()
&& r1.getSecondItemToBuy().getItem() == r2.getSecondItemToBuy().getItem() : false;
}
private boolean hasSameItemsAs(MerchantRecipe r1, MerchantRecipe r2)
{
return hasSameIDsAs(r1, r2) && (r1.getItemToBuy().getCount() < r2.getItemToBuy().getCount() ||
!r1.getSecondItemToBuy().isEmpty() && r1.getSecondItemToBuy().getCount() < r2.getSecondItemToBuy().getCount());
}
/****************** END OF VANILLA CODE FROM 1.7.10 ******************/
@SuppressWarnings("unchecked")
public static void addItemTrade(MerchantRecipeList list, Item item, Random rand, float probability)
{
if (rand.nextFloat() < probability)
list.add(new MerchantRecipe(getItemStackWithQuantity(item, rand), ACItems.elder_engraved_coin));
}
private static ItemStack getItemStackWithQuantity(Item item, Random rand)
{
return new ItemStack(item, getQuantity(item, rand), 0);
}
private static int getQuantity(Item item, Random rand)
{
Tuple tuple = itemSellingList.get(item);
return tuple == null ? 1 : ((Integer)tuple.getFirst()).intValue() >= ((Integer)tuple.getSecond()).intValue() ? ((Integer)tuple.getFirst()).intValue() : ((Integer)tuple.getFirst()).intValue() + rand.nextInt(((Integer)tuple.getSecond()).intValue() - ((Integer)tuple.getFirst()).intValue());
}
@SuppressWarnings("unchecked")
public static void addCoinTrade(MerchantRecipeList list, Item item, Random rand, float probability)
{
if (rand.nextFloat() < probability)
{
int i = getRarity(item, rand);
ItemStack itemstack;
ItemStack itemstack1;
if (i < 0)
{
itemstack = new ItemStack(ACItems.elder_engraved_coin, 1, 0);
itemstack1 = new ItemStack(item, -i, 0);
}
else
{
itemstack = new ItemStack(ACItems.elder_engraved_coin, i, 0);
itemstack1 = new ItemStack(item, 1, 0);
}
list.add(new MerchantRecipe(itemstack, itemstack1));
}
}
private static int getRarity(Item par1, Random par2)
{
Tuple tuple = coinSellingList.get(par1);
return tuple == null ? 1 : ((Integer)tuple.getFirst()).intValue() >= ((Integer)tuple.getSecond()).intValue() ? ((Integer)tuple.getFirst()).intValue() : ((Integer)tuple.getFirst()).intValue() + par2.nextInt(((Integer)tuple.getSecond()).intValue() - ((Integer)tuple.getFirst()).intValue());
}
@Override
public void verifySellingItem(ItemStack par1ItemStack)
{
if (!world.isRemote && livingSoundTime > -getTalkInterval() + 20)
{
livingSoundTime = -getTalkInterval();
if (!par1ItemStack.isEmpty())
playSound(ACSounds.remnant_yes, getSoundVolume(), getSoundPitch());
else
playSound(ACSounds.remnant_no, getSoundVolume(), getSoundPitch());
}
}
public void addCoinTrade(MerchantRecipeList list, Item buy, int q1, Item sell, int q2){
addCoinTrade(list, new ItemStack(buy, q1), new ItemStack(sell, q2));
}
public void addCoinTrade(MerchantRecipeList list, Item buy1, int q1, Item buy2, int q2, Item sell, int q3){
addCoinTrade(list, new ItemStack(buy1, q1), new ItemStack(buy2, q2), new ItemStack(sell, q3));
}
public void addCoinTrade(MerchantRecipeList list, ItemStack buy, ItemStack sell){
addCoinTrade(list, buy, ItemStack.EMPTY, sell);
}
@SuppressWarnings("unchecked")
public void addCoinTrade(MerchantRecipeList list, ItemStack buy1, ItemStack buy2, ItemStack sell){
list.add(new MerchantRecipe(buy1, buy2, sell));
}
@Override
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData data){
data = super.onInitialSpawn(difficulty, data);
applyRandomTrade(world.rand);
if (getItemStackFromSlot(EntityEquipmentSlot.HEAD).isEmpty())
{
Calendar calendar = world.getCurrentDate();
if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && rand.nextFloat() < 0.25F)
{
setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(rand.nextFloat() < 0.1F ? Blocks.LIT_PUMPKIN : Blocks.PUMPKIN));
inventoryArmorDropChances[EntityEquipmentSlot.HEAD.getIndex()] = 0.0F;
}
}
return data;
}
static
{
itemSellingList.put(Items.COAL, new Tuple(Integer.valueOf(16), Integer.valueOf(24)));
itemSellingList.put(ACItems.abyssalnite_ingot, new Tuple(Integer.valueOf(8), Integer.valueOf(10)));
itemSellingList.put(ACItems.refined_coralium_ingot, new Tuple(Integer.valueOf(8), Integer.valueOf(10)));
itemSellingList.put(ACItems.dreadium_ingot, new Tuple(Integer.valueOf(8), Integer.valueOf(10)));
itemSellingList.put(ACItems.ethaxium_ingot, new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
itemSellingList.put(Items.PAPER, new Tuple(Integer.valueOf(24), Integer.valueOf(36)));
itemSellingList.put(Items.BOOK, new Tuple(Integer.valueOf(11), Integer.valueOf(13)));
itemSellingList.put(Items.WRITTEN_BOOK, new Tuple(Integer.valueOf(1), Integer.valueOf(1)));
itemSellingList.put(Items.ENDER_PEARL, new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
itemSellingList.put(Items.ENDER_EYE, new Tuple(Integer.valueOf(2), Integer.valueOf(3)));
itemSellingList.put(Items.PORKCHOP, new Tuple(Integer.valueOf(14), Integer.valueOf(18)));
itemSellingList.put(Items.BEEF, new Tuple(Integer.valueOf(14), Integer.valueOf(18)));
itemSellingList.put(Items.CHICKEN, new Tuple(Integer.valueOf(14), Integer.valueOf(18)));
itemSellingList.put(Items.COOKED_FISH, new Tuple(Integer.valueOf(9), Integer.valueOf(13)));
itemSellingList.put(Items.WHEAT_SEEDS, new Tuple(Integer.valueOf(34), Integer.valueOf(48)));
itemSellingList.put(Items.MELON_SEEDS, new Tuple(Integer.valueOf(30), Integer.valueOf(38)));
itemSellingList.put(Items.PUMPKIN_SEEDS, new Tuple(Integer.valueOf(30), Integer.valueOf(38)));
itemSellingList.put(Items.WHEAT, new Tuple(Integer.valueOf(18), Integer.valueOf(22)));
itemSellingList.put(Item.getItemFromBlock(Blocks.WOOL), new Tuple(Integer.valueOf(14), Integer.valueOf(22)));
itemSellingList.put(Items.ROTTEN_FLESH, new Tuple(Integer.valueOf(16), Integer.valueOf(28)));
itemSellingList.put(ACItems.coralium_plagued_flesh, new Tuple(Integer.valueOf(16), Integer.valueOf(28)));
itemSellingList.put(ACItems.dread_fragment, new Tuple(Integer.valueOf(16), Integer.valueOf(28)));
itemSellingList.put(ACItems.omothol_flesh, new Tuple(Integer.valueOf(32), Integer.valueOf(60)));
itemSellingList.put(ACItems.rotten_anti_flesh, new Tuple(Integer.valueOf(8), Integer.valueOf(14)));
coinSellingList.put(Items.FLINT_AND_STEEL, new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
coinSellingList.put(Items.SHEARS, new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
coinSellingList.put(ACItems.ethaxium_sword, new Tuple(Integer.valueOf(12), Integer.valueOf(14)));
coinSellingList.put(ACItems.ethaxium_axe, new Tuple(Integer.valueOf(9), Integer.valueOf(12)));
coinSellingList.put(ACItems.ethaxium_pickaxe, new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
coinSellingList.put(ACItems.ethaxium_shovel, new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
coinSellingList.put(ACItems.ethaxium_hoe, new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
coinSellingList.put(ACItems.ethaxium_boots, new Tuple(Integer.valueOf(5), Integer.valueOf(7)));
coinSellingList.put(ACItems.ethaxium_helmet, new Tuple(Integer.valueOf(5), Integer.valueOf(7)));
coinSellingList.put(ACItems.ethaxium_chestplate, new Tuple(Integer.valueOf(11), Integer.valueOf(15)));
coinSellingList.put(ACItems.ethaxium_leggings, new Tuple(Integer.valueOf(9), Integer.valueOf(11)));
coinSellingList.put(Items.BREAD, new Tuple(Integer.valueOf(-4), Integer.valueOf(-2)));
coinSellingList.put(Items.MELON, new Tuple(Integer.valueOf(-8), Integer.valueOf(-4)));
coinSellingList.put(Items.APPLE, new Tuple(Integer.valueOf(-8), Integer.valueOf(-4)));
coinSellingList.put(Items.COOKIE, new Tuple(Integer.valueOf(-10), Integer.valueOf(-7)));
coinSellingList.put(Item.getItemFromBlock(Blocks.GLASS), new Tuple(Integer.valueOf(-5), Integer.valueOf(-3)));
coinSellingList.put(Item.getItemFromBlock(Blocks.BOOKSHELF), new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
coinSellingList.put(ACItems.washcloth, new Tuple(Integer.valueOf(2), Integer.valueOf(4)));
coinSellingList.put(ACItems.mre, new Tuple(Integer.valueOf(6), Integer.valueOf(8)));
coinSellingList.put(Items.EXPERIENCE_BOTTLE, new Tuple(Integer.valueOf(-4), Integer.valueOf(-1)));
coinSellingList.put(Items.REDSTONE, new Tuple(Integer.valueOf(-4), Integer.valueOf(-1)));
coinSellingList.put(Items.COMPASS, new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
coinSellingList.put(Items.CLOCK, new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
coinSellingList.put(ACItems.necronomicon, new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
coinSellingList.put(ACItems.abyssal_wasteland_necronomicon, new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
coinSellingList.put(ACItems.dreadlands_necronomicon, new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
coinSellingList.put(Item.getItemFromBlock(Blocks.GLOWSTONE), new Tuple(Integer.valueOf(-3), Integer.valueOf(-1)));
coinSellingList.put(ACItems.pork_on_a_plate, new Tuple(Integer.valueOf(-7), Integer.valueOf(-5)));
coinSellingList.put(ACItems.beef_on_a_plate, new Tuple(Integer.valueOf(-7), Integer.valueOf(-5)));
coinSellingList.put(ACItems.chicken_on_a_plate, new Tuple(Integer.valueOf(-7), Integer.valueOf(-5)));
coinSellingList.put(ACItems.fish_on_a_plate, new Tuple(Integer.valueOf(-7), Integer.valueOf(-5)));
coinSellingList.put(Items.COOKED_CHICKEN, new Tuple(Integer.valueOf(-8), Integer.valueOf(-6)));
coinSellingList.put(Items.ENDER_EYE, new Tuple(Integer.valueOf(7), Integer.valueOf(11)));
coinSellingList.put(Items.ARROW, new Tuple(Integer.valueOf(-12), Integer.valueOf(-8)));
coinSellingList.put(ACItems.plated_coralium_boots, new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
coinSellingList.put(ACItems.dreadium_samurai_boots, new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
coinSellingList.put(ACItems.plated_coralium_helmet, new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
coinSellingList.put(ACItems.dreadium_samurai_helmet, new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
coinSellingList.put(ACItems.plated_coralium_chestplate, new Tuple(Integer.valueOf(10), Integer.valueOf(14)));
coinSellingList.put(ACItems.dreadium_samurai_chestplate, new Tuple(Integer.valueOf(16), Integer.valueOf(19)));
coinSellingList.put(ACItems.plated_coralium_leggings, new Tuple(Integer.valueOf(8), Integer.valueOf(10)));
coinSellingList.put(ACItems.dreadium_samurai_leggings, new Tuple(Integer.valueOf(11), Integer.valueOf(14)));
coinSellingList.put(ACItems.staff_of_rending, new Tuple(Integer.valueOf(20), Integer.valueOf(25)));
}
public void applyRandomTrade(Random rand){
int trade = rand.nextInt(7);
setProfession(trade);
}
}