Joshie comment!
This commit is contained in:
parent
1c0deadfc6
commit
ac943e9d38
753 changed files with 8715 additions and 1184 deletions
|
@ -0,0 +1,493 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
|
||||
import net.minecraft.entity.ai.EntityAIFollowOwner;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAIWander;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
|
||||
public class EntityBileDemon extends EntityDemon
|
||||
{
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 100.0F;
|
||||
private static float maxUntamedHealth = 200.0F;
|
||||
private int attackTimer;
|
||||
|
||||
public EntityBileDemon(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entityBileDemonID);
|
||||
this.setSize(1.3F, 2.0F);
|
||||
this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
//this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
this.tasks.addTask(2, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(3, this.aiSit);
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
attackTimer = 0;
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.20000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
par1NBTTagCompound.setByte("attackTimer", (byte) attackTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
attackTimer = par1NBTTagCompound.getByte("attackTimer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "mob.irongolem.hit";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "mob.irongolem.death";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
|
||||
if (attackTimer > 0)
|
||||
{
|
||||
attackTimer--;
|
||||
}
|
||||
}
|
||||
|
||||
public int getAttackTimer()
|
||||
{
|
||||
return attackTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
this.attackTimer = 10;
|
||||
this.worldObj.setEntityState(this, (byte) 4);
|
||||
boolean flag = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) (7 + this.rand.nextInt(15)));
|
||||
|
||||
if (flag)
|
||||
{
|
||||
par1Entity.motionY += 0.4000000059604645D;
|
||||
}
|
||||
|
||||
this.playSound("mob.irongolem.throw", 1.0F, 1.0F);
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityBileDemon)
|
||||
{
|
||||
EntityBileDemon entitywolf = (EntityBileDemon) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,499 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.EntityAITargetAggro;
|
||||
import WayofTime.alchemicalWizardry.common.entity.projectile.HolyProjectile;
|
||||
import net.minecraft.block.BlockColored;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.*;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityBoulderFist extends EntityDemon
|
||||
{
|
||||
//private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 40, 40, 15.0F);
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 60.0F;
|
||||
private static float maxUntamedHealth = 50.0F;
|
||||
|
||||
public EntityBoulderFist(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entityBoulderFistID);
|
||||
this.setSize(0.8F, 1.2F);
|
||||
this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(2, this.aiSit);
|
||||
this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targetTasks.addTask(4, new EntityAITargetAggro(this, EntityPlayer.class, 0, false));
|
||||
this.setAggro(false);
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
|
||||
if (par1World != null && !par1World.isRemote)
|
||||
{
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
//TODO change sounds
|
||||
return this.isAngry() ? "mob.wolf.growl" : (this.rand.nextInt(3) == 0 ? (this.isTamed() && this.dataWatcher.getWatchableObjectFloat(18) < 10.0F ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "mob.wolf.hurt";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "mob.wolf.death";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
int i = this.isTamed() ? 6 : 7;
|
||||
return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) i);
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityBoulderFist)
|
||||
{
|
||||
EntityBoulderFist entitywolf = (EntityBoulderFist) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attack the specified entity using a ranged attack.
|
||||
*/
|
||||
public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2)
|
||||
{
|
||||
double xCoord;
|
||||
double yCoord;
|
||||
double zCoord;
|
||||
HolyProjectile hol = new HolyProjectile(worldObj, this, par1EntityLivingBase, 1.8f, 0f, 5, 600);
|
||||
this.worldObj.spawnEntityInWorld(hol);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets this entity's combat AI.
|
||||
*/
|
||||
public void setCombatTask()
|
||||
{
|
||||
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||
//this.tasks.removeTask(this.aiArrowAttack);
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.tasks.addTask(4, this.aiAttackOnCollide);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.passive.EntityTameable;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.IDemon;
|
||||
import WayofTime.alchemicalWizardry.common.items.DemonPlacer;
|
||||
|
||||
public class EntityDemon extends EntityTameable implements IDemon
|
||||
{
|
||||
private boolean isAggro;
|
||||
private int demonID;
|
||||
|
||||
public EntityDemon(World par1World, int demonID)
|
||||
{
|
||||
super(par1World);
|
||||
this.demonID = demonID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSummonedConditions()
|
||||
{
|
||||
this.setAggro(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAggro()
|
||||
{
|
||||
return this.isAggro;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAggro(boolean aggro)
|
||||
{
|
||||
this.isAggro = aggro;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAgeable createChild(EntityAgeable entityageable)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void dropFewItems(boolean par1, int par2)
|
||||
{
|
||||
ItemStack drop = new ItemStack(ModItems.demonPlacer, 1, this.getDemonID());
|
||||
DemonPlacer.setOwnerName(drop, this.getOwnerName());
|
||||
|
||||
if (this.hasCustomNameTag())
|
||||
{
|
||||
drop.setStackDisplayName(this.getCustomNameTag());
|
||||
}
|
||||
|
||||
this.entityDropItem(drop, 0.0f);
|
||||
}
|
||||
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
|
||||
if (!this.isAggro() && worldObj.getWorldTime() % 100 == 0)
|
||||
{
|
||||
this.heal(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendSittingMessageToPlayer(EntityPlayer owner, boolean isSitting)
|
||||
{
|
||||
if (owner != null && owner.worldObj.isRemote)
|
||||
{
|
||||
ChatComponentText chatmessagecomponent;
|
||||
|
||||
if (isSitting)
|
||||
{
|
||||
chatmessagecomponent = new ChatComponentText("I will stay here for now, Master.");
|
||||
} else
|
||||
{
|
||||
chatmessagecomponent = new ChatComponentText("I shall follow and protect you!");
|
||||
}
|
||||
|
||||
owner.addChatComponentMessage(chatmessagecomponent);
|
||||
}
|
||||
}
|
||||
|
||||
public int getDemonID()
|
||||
{
|
||||
return this.demonID;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityEarthElemental extends EntityElemental implements IMob
|
||||
{
|
||||
public EntityEarthElemental(World world)
|
||||
{
|
||||
super(world, AlchemicalWizardry.entityEarthElementalID);
|
||||
}
|
||||
|
||||
public void inflictEffectOnEntity(Entity target)
|
||||
{
|
||||
if (target instanceof EntityLivingBase)
|
||||
{
|
||||
((EntityLivingBase) target).attackEntityFrom(DamageSource.causeMobDamage(this), 10);
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 4));
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionInhibit.id, 150, 0));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,750 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockColored;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EntityElemental extends EntityDemon
|
||||
{
|
||||
//private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 40, 40, 15.0F);
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 100.0F;
|
||||
private static float maxUntamedHealth = 100.0F;
|
||||
|
||||
public EntityElemental(World par1World, int demonID)
|
||||
{
|
||||
super(par1World, demonID);
|
||||
this.setSize(0.5F, 1.0F);
|
||||
this.setAggro(false);
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
|
||||
if (par1World != null && !par1World.isRemote)
|
||||
{
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
public int courseChangeCooldown;
|
||||
public double waypointX;
|
||||
public double waypointY;
|
||||
public double waypointZ;
|
||||
private Entity targetedEntity;
|
||||
|
||||
/**
|
||||
* Cooldown time between target loss and new target aquirement.
|
||||
*/
|
||||
private int aggroCooldown;
|
||||
public int prevAttackCounter;
|
||||
public int attackCounter;
|
||||
|
||||
/**
|
||||
* The explosion radius of spawned fireballs.
|
||||
*/
|
||||
//private int explosionStrength = 1;
|
||||
//
|
||||
// private int heightOffsetUpdateTime;
|
||||
// private float heightOffset = 0.5F;
|
||||
// private int field_70846_g;
|
||||
protected void dropFewItems(boolean par1, int par2)
|
||||
{
|
||||
if (worldObj.rand.nextFloat() < (1 - Math.pow(0.6f, par2 + 1)))
|
||||
{
|
||||
this.entityDropItem(new ItemStack(ModItems.demonBloodShard, 1, 0), 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fall(float par1)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance
|
||||
* and deal fall damage if landing on the ground. Args: distanceFallenThisTick, onGround
|
||||
*/
|
||||
protected void updateFallState(double par1, boolean par3)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the entity based on the specified heading. Args: strafe, forward
|
||||
*/
|
||||
public void moveEntityWithHeading(float par1, float par2)
|
||||
{
|
||||
if (this.isInWater())
|
||||
{
|
||||
this.moveFlying(par1, par2, 0.02F);
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.800000011920929D;
|
||||
this.motionY *= 0.800000011920929D;
|
||||
this.motionZ *= 0.800000011920929D;
|
||||
} else if (this.handleLavaMovement())
|
||||
{
|
||||
this.moveFlying(par1, par2, 0.02F);
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.5D;
|
||||
this.motionY *= 0.5D;
|
||||
this.motionZ *= 0.5D;
|
||||
} else
|
||||
{
|
||||
float f2 = 0.91F;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
f2 = 0.54600006F;
|
||||
Block i = this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ));
|
||||
|
||||
if (i != null)
|
||||
{
|
||||
f2 = i.slipperiness * 0.91F;
|
||||
}
|
||||
}
|
||||
|
||||
float f3 = 0.16277136F / (f2 * f2 * f2);
|
||||
this.moveFlying(par1, par2, this.onGround ? 0.1F * f3 : 0.02F);
|
||||
f2 = 0.91F;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
f2 = 0.54600006F;
|
||||
Block j = this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ));
|
||||
|
||||
if (j != null)
|
||||
{
|
||||
f2 = j.slipperiness * 0.91F;
|
||||
}
|
||||
}
|
||||
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= (double) f2;
|
||||
this.motionY *= (double) f2;
|
||||
this.motionZ *= (double) f2;
|
||||
}
|
||||
|
||||
double d0 = this.posX - this.prevPosX;
|
||||
double d1 = this.posZ - this.prevPosZ;
|
||||
float f4 = MathHelper.sqrt_double(d0 * d0 + d1 * d1) * 4.0F;
|
||||
|
||||
if (f4 > 1.0F)
|
||||
{
|
||||
f4 = 1.0F;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if this entity is by a ladder, false otherwise
|
||||
*/
|
||||
public boolean isOnLadder()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean func_110182_bF()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(25) != 0;
|
||||
}
|
||||
|
||||
protected void updateEntityActionState()
|
||||
{
|
||||
// if (!this.worldObj.isRemote && this.worldObj.difficultySetting == 0)
|
||||
// {
|
||||
// this.setDead();
|
||||
// }
|
||||
|
||||
//this.despawnEntity();
|
||||
if (this.getHealth() <= this.getMaxHealth() / 2.0f && worldObj.rand.nextInt(200) == 0)
|
||||
{
|
||||
this.addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionReciprocation.id, 100, 1));
|
||||
}
|
||||
|
||||
this.prevAttackCounter = this.attackCounter;
|
||||
double d0 = this.waypointX - this.posX;
|
||||
double d1 = this.waypointY - this.posY;
|
||||
double d2 = this.waypointZ - this.posZ;
|
||||
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
|
||||
|
||||
if (d3 < 1.0D || d3 > 3600.0D)
|
||||
{
|
||||
this.waypointX = this.posX + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
this.waypointY = this.posY + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
this.waypointZ = this.posZ + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
}
|
||||
|
||||
if (this.courseChangeCooldown-- <= 0)
|
||||
{
|
||||
this.courseChangeCooldown += this.rand.nextInt(5) + 2;
|
||||
d3 = (double) MathHelper.sqrt_double(d3);
|
||||
|
||||
if (this.isCourseTraversable(this.waypointX, this.waypointY, this.waypointZ, d3))
|
||||
{
|
||||
this.motionX += d0 / d3 * 0.1D;
|
||||
this.motionY += d1 / d3 * 0.1D;
|
||||
this.motionZ += d2 / d3 * 0.1D;
|
||||
} else
|
||||
{
|
||||
this.waypointX = this.posX + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
this.waypointY = this.posY + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
this.waypointZ = this.posZ + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.targetedEntity != null && this.targetedEntity.isDead)
|
||||
{
|
||||
this.targetedEntity = null;
|
||||
}
|
||||
|
||||
if (this.targetedEntity == null || this.aggroCooldown-- <= 0)
|
||||
{
|
||||
this.targetedEntity = getClosestVulnerableMonsterToEntity(this, 100.0D);
|
||||
|
||||
if (this.targetedEntity != null)
|
||||
{
|
||||
this.aggroCooldown = 20;
|
||||
}
|
||||
}
|
||||
|
||||
double d4 = 64.0D;
|
||||
|
||||
if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < d4 * d4)
|
||||
{
|
||||
double d5 = this.targetedEntity.posX - this.posX;
|
||||
double d6 = this.targetedEntity.boundingBox.minY + (double) (this.targetedEntity.height / 2.0F) - (this.posY + (double) (this.height / 2.0F));
|
||||
double d7 = this.targetedEntity.posZ - this.posZ;
|
||||
this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(d5, d7)) * 180.0F / (float) Math.PI;
|
||||
|
||||
if (this.courseChangeCooldown <= 0)
|
||||
{
|
||||
if (isCourseTraversable(this.targetedEntity.posX, this.targetedEntity.posY, this.targetedEntity.posZ, Math.sqrt(d5 * d5 + d6 * d6 + d7 * d7)))
|
||||
{
|
||||
this.waypointX = this.targetedEntity.posX;
|
||||
this.waypointY = this.targetedEntity.posY;
|
||||
this.waypointZ = this.targetedEntity.posZ;
|
||||
this.motionX += d5 / d3 * 0.1D;
|
||||
this.motionY += d6 / d3 * 0.1D;
|
||||
this.motionZ += d7 / d3 * 0.1D;
|
||||
} else
|
||||
{
|
||||
this.waypointX = this.posX + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
this.waypointY = this.posY + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
this.waypointZ = this.posZ + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F);
|
||||
this.motionX += d5 / d3 * 0.1D;
|
||||
this.motionY += d6 / d3 * 0.1D;
|
||||
this.motionZ += d7 / d3 * 0.1D;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.canEntityBeSeen(this.targetedEntity))
|
||||
{
|
||||
if (Math.sqrt(d5 * d5 + d6 * d6 + d7 * d7) < 4)
|
||||
{
|
||||
// if (this.attackCounter == 10)
|
||||
// {
|
||||
// this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1007, (int)this.posX, (int)this.posY, (int)this.posZ, 0);
|
||||
// }
|
||||
++this.attackCounter;
|
||||
|
||||
if (this.attackCounter >= 10)
|
||||
{
|
||||
this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1008, (int) this.posX, (int) this.posY, (int) this.posZ, 0);
|
||||
this.inflictEffectOnEntity(this.targetedEntity);
|
||||
this.attackCounter = -40;
|
||||
}
|
||||
}
|
||||
} else if (this.attackCounter > 0)
|
||||
{
|
||||
--this.attackCounter;
|
||||
}
|
||||
} else
|
||||
{
|
||||
this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float) Math.PI;
|
||||
|
||||
if (this.attackCounter > 0)
|
||||
{
|
||||
--this.attackCounter;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(25);
|
||||
byte b1 = (byte) (this.attackCounter > 10 ? 1 : 0);
|
||||
|
||||
if (b0 != b1)
|
||||
{
|
||||
this.dataWatcher.updateObject(25, Byte.valueOf(b1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the ghast has an unobstructed line of travel to the waypoint.
|
||||
*/
|
||||
private boolean isCourseTraversable(double par1, double par3, double par5, double par7)
|
||||
{
|
||||
double d4 = (this.waypointX - this.posX) / par7;
|
||||
double d5 = (this.waypointY - this.posY) / par7;
|
||||
double d6 = (this.waypointZ - this.posZ) / par7;
|
||||
AxisAlignedBB axisalignedbb = this.boundingBox.copy();
|
||||
|
||||
for (int i = 1; (double) i < par7; ++i)
|
||||
{
|
||||
axisalignedbb.offset(d4, d5, d6);
|
||||
|
||||
if (!this.worldObj.getCollidingBoundingBoxes(this, axisalignedbb).isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return how many at most can spawn in a chunk at once.
|
||||
*/
|
||||
public int getMaxSpawnedInChunk()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
this.dataWatcher.addObject(25, Byte.valueOf((byte) 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
//TODO change sounds
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
int i = this.isTamed() ? 6 : 7;
|
||||
return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) i);
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityBoulderFist)
|
||||
{
|
||||
EntityBoulderFist entitywolf = (EntityBoulderFist) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
//return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer)par2EntityLivingBase).func_96122_a((EntityPlayer)par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse)par1EntityLivingBase).func_110248_bS();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets this entity's combat AI.
|
||||
*/
|
||||
public void setCombatTask()
|
||||
{
|
||||
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||
//this.tasks.removeTask(this.aiArrowAttack);
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.tasks.addTask(4, this.aiAttackOnCollide);
|
||||
}
|
||||
|
||||
public void inflictEffectOnEntity(Entity target)
|
||||
{
|
||||
if (target instanceof EntityLivingBase)
|
||||
{
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionDrowning.id, 100, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public static Entity getClosestVulnerableMonsterToEntity(Entity par1Entity, double par2)
|
||||
{
|
||||
double d4 = -1.0D;
|
||||
double par1 = par1Entity.posX;
|
||||
double par3 = par1Entity.posY;
|
||||
double par5 = par1Entity.posZ;
|
||||
|
||||
EntityLivingBase entityLiving = null;
|
||||
World world = par1Entity.worldObj;
|
||||
|
||||
double range = Math.sqrt(par2);
|
||||
double verticalRange = Math.sqrt(par2);
|
||||
List<EntityLivingBase> entities = world.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(par1 - 0.5f, par3 - 0.5f, par5 - 0.5f, par1 + 0.5f, par3 + 0.5f, par5 + 0.5f).expand(range, verticalRange, range));
|
||||
if (entities == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < entities.size(); ++i)
|
||||
{
|
||||
EntityLivingBase entityLiving1 = entities.get(i);
|
||||
|
||||
if (!(entityLiving1 instanceof EntityPlayer && ((EntityPlayer) entityLiving1).capabilities.disableDamage) && entityLiving1.isEntityAlive())
|
||||
{
|
||||
double d5 = entityLiving1.getDistanceSq(par1, par3, par5);
|
||||
double d6 = par2;
|
||||
|
||||
if (entityLiving1.isSneaking())
|
||||
{
|
||||
d6 = par2 * 0.800000011920929D;
|
||||
}
|
||||
|
||||
if (entityLiving1.isInvisible())
|
||||
{
|
||||
float f = entityLiving1 instanceof EntityPlayer ? ((EntityPlayer) entityLiving1).getArmorVisibility() : 1.0f;
|
||||
|
||||
if (f < 0.1F)
|
||||
{
|
||||
f = 0.1F;
|
||||
}
|
||||
|
||||
d6 *= (double) (0.7F * f);
|
||||
}
|
||||
|
||||
if ((par2 < 0.0D || d5 < d6 * d6) && (d4 == -1.0D || d5 < d4))
|
||||
{
|
||||
if (par1Entity != entityLiving1)
|
||||
{
|
||||
d4 = d5;
|
||||
entityLiving = entityLiving1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entityLiving;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalArmorValue() //TODO
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,507 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import net.minecraft.block.BlockColored;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.IRangedAttackMob;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIArrowAttack;
|
||||
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
|
||||
import net.minecraft.entity.ai.EntityAIFollowOwner;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAIWander;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.EntityAITargetAggro;
|
||||
import WayofTime.alchemicalWizardry.common.entity.projectile.HolyProjectile;
|
||||
|
||||
public class EntityFallenAngel extends EntityDemon implements IRangedAttackMob
|
||||
{
|
||||
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 40, 40, 15.0F);
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 50.0F;
|
||||
private static float maxUntamedHealth = 50.0F;
|
||||
|
||||
public EntityFallenAngel(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entityFallenAngelID);
|
||||
this.setSize(0.7F, 1.8F);
|
||||
this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(2, this.aiSit);
|
||||
//this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
//this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targetTasks.addTask(4, new EntityAITargetAggro(this, EntityPlayer.class, 0, false));
|
||||
this.setAggro(false);
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
|
||||
if (par1World != null && !par1World.isRemote)
|
||||
{
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
//TODO change sounds
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "mob.wolf.death";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
int i = this.isTamed() ? 4 : 2;
|
||||
return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) i);
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityFallenAngel)
|
||||
{
|
||||
EntityFallenAngel entitywolf = (EntityFallenAngel) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attack the specified entity using a ranged attack.
|
||||
*/
|
||||
public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2)
|
||||
{
|
||||
double xCoord;
|
||||
double yCoord;
|
||||
double zCoord;
|
||||
HolyProjectile hol = new HolyProjectile(worldObj, this, par1EntityLivingBase, 1.8f, 0f, 5, 600);
|
||||
this.worldObj.spawnEntityInWorld(hol);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets this entity's combat AI.
|
||||
*/
|
||||
public void setCombatTask()
|
||||
{
|
||||
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||
this.tasks.removeTask(this.aiArrowAttack);
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.tasks.addTask(4, this.aiArrowAttack);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityFireElemental extends EntityElemental implements IMob
|
||||
{
|
||||
public EntityFireElemental(World world)
|
||||
{
|
||||
super(world, AlchemicalWizardry.entityFireElementalID);
|
||||
this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
public void inflictEffectOnEntity(Entity target)
|
||||
{
|
||||
if (target instanceof EntityLivingBase)
|
||||
{
|
||||
((EntityLivingBase) target).setFire(10);
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionInhibit.id, 150, 0));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityHolyElemental extends EntityElemental implements IMob
|
||||
{
|
||||
public EntityHolyElemental(World world)
|
||||
{
|
||||
super(world, AlchemicalWizardry.entityHolyElementalID);
|
||||
}
|
||||
|
||||
public void inflictEffectOnEntity(Entity target)
|
||||
{
|
||||
if (target instanceof EntityLivingBase)
|
||||
{
|
||||
((EntityLivingBase) target).attackEntityFrom(DamageSource.causeMobDamage(this), 15);
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionInhibit.id, 150, 0));
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(Potion.poison.id, 100, 1));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,529 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import net.minecraft.block.BlockColored;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.IRangedAttackMob;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIArrowAttack;
|
||||
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
|
||||
import net.minecraft.entity.ai.EntityAIFollowOwner;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAIWander;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.EntityAITargetAggro;
|
||||
import WayofTime.alchemicalWizardry.common.entity.projectile.IceProjectile;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
|
||||
public class EntityIceDemon extends EntityDemon implements IRangedAttackMob
|
||||
{
|
||||
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 30, 50, 15.0F);
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 50.0F;
|
||||
private static float maxUntamedHealth = 30.0F;
|
||||
|
||||
public EntityIceDemon(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entityIceDemonID);
|
||||
this.setSize(0.5F, 2.0F);
|
||||
//this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(2, this.aiSit);
|
||||
//this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
//this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targetTasks.addTask(4, new EntityAITargetAggro(this, EntityPlayer.class, 0, false));
|
||||
this.setAggro(false);
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
|
||||
if (par1World != null && !par1World.isRemote)
|
||||
{
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.40000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "mob.irongolem.hit";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "mob.irongolem.death";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
int range = 2;
|
||||
|
||||
Vec3 blockVector = SpellHelper.getEntityBlockVector(this);
|
||||
|
||||
int xCoord = (int)(blockVector.xCoord);
|
||||
int yCoord = (int)(blockVector.yCoord);
|
||||
int zCoord = (int)(blockVector.zCoord);
|
||||
|
||||
for (int i = -range; i <= range; i++)
|
||||
{
|
||||
for (int j = -range; j <= range; j++)
|
||||
{
|
||||
for (int k = -range; k <= range; k++)
|
||||
{
|
||||
if (worldObj.rand.nextFloat() < 0.25f)
|
||||
{
|
||||
SpellHelper.freezeWaterBlock(worldObj, xCoord + i, yCoord + j, zCoord + k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
int i = this.isTamed() ? 4 : 2;
|
||||
return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) i);
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityIceDemon)
|
||||
{
|
||||
EntityIceDemon entitywolf = (EntityIceDemon) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attack the specified entity using a ranged attack.
|
||||
*/
|
||||
public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2)
|
||||
{
|
||||
double xCoord;
|
||||
double yCoord;
|
||||
double zCoord;
|
||||
IceProjectile hol = new IceProjectile(worldObj, this, par1EntityLivingBase, 1.8f, 0f, 3, 600);
|
||||
this.worldObj.spawnEntityInWorld(hol);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets this entity's combat AI.
|
||||
*/
|
||||
public void setCombatTask()
|
||||
{
|
||||
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||
this.tasks.removeTask(this.aiArrowAttack);
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.tasks.addTask(4, this.aiArrowAttack);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,491 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.EntityAITargetAggro;
|
||||
import net.minecraft.block.BlockColored;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.*;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityLowerGuardian extends EntityDemon
|
||||
{
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 50.0F;
|
||||
private static float maxUntamedHealth = 30.0F;
|
||||
private int attackTimer;
|
||||
private boolean isAggro;
|
||||
|
||||
public EntityLowerGuardian(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entityLowerGuardianID);
|
||||
this.setSize(0.7F, 1.8F);
|
||||
this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
//this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
this.tasks.addTask(2, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(3, this.aiSit);
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targetTasks.addTask(4, new EntityAITargetAggro(this, EntityPlayer.class, 0, false));
|
||||
this.setAggro(false);
|
||||
this.setTamed(false);
|
||||
attackTimer = 0;
|
||||
//isAggro = false;
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
par1NBTTagCompound.setByte("attackTimer", (byte) attackTimer);
|
||||
par1NBTTagCompound.setBoolean("isAggro", this.isAggro());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
attackTimer = par1NBTTagCompound.getByte("attackTimer");
|
||||
isAggro = par1NBTTagCompound.getBoolean("isAggro");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "mob.irongolem.hit";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "mob.irongolem.death";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
|
||||
if (attackTimer > 0)
|
||||
{
|
||||
attackTimer--;
|
||||
}
|
||||
}
|
||||
|
||||
public int getAttackTimer()
|
||||
{
|
||||
return attackTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
this.attackTimer = 10;
|
||||
this.worldObj.setEntityState(this, (byte) 4);
|
||||
boolean flag = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) (7 + this.rand.nextInt(15)));
|
||||
|
||||
if (flag)
|
||||
{
|
||||
par1Entity.motionY += 0.4000000059604645D;
|
||||
}
|
||||
|
||||
this.playSound("mob.irongolem.throw", 1.0F, 1.0F);
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityLowerGuardian)
|
||||
{
|
||||
EntityLowerGuardian entitywolf = (EntityLowerGuardian) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,498 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.EntityAITargetAggro;
|
||||
import WayofTime.alchemicalWizardry.common.entity.projectile.HolyProjectile;
|
||||
import net.minecraft.block.BlockColored;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.*;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityShade extends EntityDemon
|
||||
{
|
||||
//private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 40, 40, 15.0F);
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 50.0F;
|
||||
private static float maxUntamedHealth = 100.0F;
|
||||
|
||||
public EntityShade(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entityShadeID);
|
||||
this.setSize(0.8F, 2.0F);
|
||||
this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(2, this.aiSit);
|
||||
//this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targetTasks.addTask(4, new EntityAITargetAggro(this, EntityPlayer.class, 0, false));
|
||||
this.setAggro(false);
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
|
||||
if (par1World != null && !par1World.isRemote)
|
||||
{
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
//TODO change sounds
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
int i = this.isTamed() ? 6 : 7;
|
||||
return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) i);
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityBoulderFist)
|
||||
{
|
||||
EntityBoulderFist entitywolf = (EntityBoulderFist) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attack the specified entity using a ranged attack.
|
||||
*/
|
||||
public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2)
|
||||
{
|
||||
double xCoord;
|
||||
double yCoord;
|
||||
double zCoord;
|
||||
HolyProjectile hol = new HolyProjectile(worldObj, this, par1EntityLivingBase, 1.8f, 0f, 5, 600);
|
||||
this.worldObj.spawnEntityInWorld(hol);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets this entity's combat AI.
|
||||
*/
|
||||
public void setCombatTask()
|
||||
{
|
||||
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||
//this.tasks.removeTask(this.aiArrowAttack);
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.tasks.addTask(4, this.aiAttackOnCollide);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityShadeElemental extends EntityElemental implements IMob
|
||||
{
|
||||
public EntityShadeElemental(World world)
|
||||
{
|
||||
super(world, AlchemicalWizardry.entityShadeElementalID);
|
||||
}
|
||||
|
||||
public void inflictEffectOnEntity(Entity target)
|
||||
{
|
||||
if (target instanceof EntityLivingBase)
|
||||
{
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(Potion.blindness.id, 100, 1));
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionInhibit.id, 150, 0));
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(Potion.nightVision.id, 100, 0));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,505 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.IRangedAttackMob;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIArrowAttack;
|
||||
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
|
||||
import net.minecraft.entity.ai.EntityAIFollowOwner;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAIWander;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.EntityAITargetAggro;
|
||||
import WayofTime.alchemicalWizardry.common.entity.projectile.MudProjectile;
|
||||
|
||||
public class EntitySmallEarthGolem extends EntityDemon implements IRangedAttackMob
|
||||
{
|
||||
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 25, 25, 15.0F);
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 20.0F;
|
||||
private static float maxUntamedHealth = 10.0F;
|
||||
|
||||
public EntitySmallEarthGolem(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entitySmallEarthGolemID);
|
||||
this.setSize(0.2F, 1.0F);
|
||||
this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(2, this.aiSit);
|
||||
//this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
//this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targetTasks.addTask(4, new EntityAITargetAggro(this, EntityPlayer.class, 0, false));
|
||||
this.setAggro(false);
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
|
||||
if (par1World != null && !par1World.isRemote)
|
||||
{
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
//this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.40000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "mob.irongolem.hit";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "mob.irongolem.death";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
int i = this.isTamed() ? 4 : 2;
|
||||
return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) i);
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntitySmallEarthGolem)
|
||||
{
|
||||
EntitySmallEarthGolem entitywolf = (EntitySmallEarthGolem) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attack the specified entity using a ranged attack.
|
||||
*/
|
||||
public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2)
|
||||
{
|
||||
double xCoord;
|
||||
double yCoord;
|
||||
double zCoord;
|
||||
MudProjectile hol = new MudProjectile(worldObj, this, par1EntityLivingBase, 1.8f, 0f, 3, 600, false);
|
||||
this.worldObj.spawnEntityInWorld(hol);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets this entity's combat AI.
|
||||
*/
|
||||
public void setCombatTask()
|
||||
{
|
||||
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||
this.tasks.removeTask(this.aiArrowAttack);
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.tasks.addTask(4, this.aiArrowAttack);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityWaterElemental extends EntityElemental implements IMob
|
||||
{
|
||||
public EntityWaterElemental(World world)
|
||||
{
|
||||
super(world, AlchemicalWizardry.entityWaterElementalID);
|
||||
}
|
||||
|
||||
public void inflictEffectOnEntity(Entity target)
|
||||
{
|
||||
if (target instanceof EntityLivingBase)
|
||||
{
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionDrowning.id, 100, 2));
|
||||
((EntityLivingBase) target).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionInhibit.id, 150, 0));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,508 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.mob;
|
||||
|
||||
import net.minecraft.block.BlockColored;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.IRangedAttackMob;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIArrowAttack;
|
||||
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
|
||||
import net.minecraft.entity.ai.EntityAIFollowOwner;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAIWander;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.monster.EntityGhast;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.EntityWolf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemFood;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.pathfinding.PathEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.ModItems;
|
||||
import WayofTime.alchemicalWizardry.common.EntityAITargetAggro;
|
||||
import WayofTime.alchemicalWizardry.common.entity.projectile.FireProjectile;
|
||||
|
||||
public class EntityWingedFireDemon extends EntityDemon implements IRangedAttackMob
|
||||
{
|
||||
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 40, 40, 15.0F);
|
||||
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false);
|
||||
|
||||
private static float maxTamedHealth = 100.0F;
|
||||
private static float maxUntamedHealth = 200.0F;
|
||||
|
||||
public EntityWingedFireDemon(World par1World)
|
||||
{
|
||||
super(par1World, AlchemicalWizardry.entityWingedFireDemonID);
|
||||
this.setSize(0.7F, 1.8F);
|
||||
this.getNavigator().setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(2, this.aiSit);
|
||||
//this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
//this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true));
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F));
|
||||
//this.tasks.addTask(6, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
||||
//this.tasks.addTask(8, new EntityAIBeg(this, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targetTasks.addTask(4, new EntityAITargetAggro(this, EntityPlayer.class, 0, false));
|
||||
this.setAggro(false);
|
||||
//this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 200, false));
|
||||
this.setTamed(false);
|
||||
|
||||
if (par1World != null && !par1World.isRemote)
|
||||
{
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
this.isImmuneToFire = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
//This line affects the speed of the monster
|
||||
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);
|
||||
|
||||
//My guess is that this will alter the max health
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
|
||||
//this.func_110148_a(SharedMonsterAttributes.field_111267_a).func_111128_a(10.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the newer Entity AI code should be run
|
||||
*/
|
||||
public boolean isAIEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLivingBase par1EntityLivingBase)
|
||||
{
|
||||
super.setAttackTarget(par1EntityLivingBase);
|
||||
|
||||
if (par1EntityLivingBase == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
} else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main AI tick function, replaces updateEntityActionState
|
||||
*/
|
||||
protected void updateAITick()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, new Float(this.getHealth()));
|
||||
this.dataWatcher.addObject(19, new Byte((byte) 0));
|
||||
//this.dataWatcher.addObject(20, new Byte((byte) BlockColored.getBlockFromDye(1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays step sound at given x, y, z for the entity
|
||||
*/
|
||||
protected void playStepSound(int par1, int par2, int par3, int par4)
|
||||
{
|
||||
this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("Angry", this.isAngry());
|
||||
par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
|
||||
|
||||
if (par1NBTTagCompound.hasKey("CollarColor"))
|
||||
{
|
||||
this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));
|
||||
}
|
||||
|
||||
this.setCombatTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected String getLivingSound()
|
||||
{
|
||||
return "mob.blaze.breathe";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected String getHurtSound()
|
||||
{
|
||||
return "mob.blaze.hit";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected String getDeathSound()
|
||||
{
|
||||
return "mob.blaze.death";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item ID for the item the mob drops on death.
|
||||
*/
|
||||
protected int getDropItemId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
|
||||
* use this to react to sunlight and start to burn.
|
||||
*/
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.8F;
|
||||
}
|
||||
|
||||
/**
|
||||
* The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently
|
||||
* use in wolves.
|
||||
*/
|
||||
public int getVerticalFaceSpeed()
|
||||
{
|
||||
return this.isSitting() ? 20 : super.getVerticalFaceSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
|
||||
{
|
||||
if (this.isEntityInvulnerable())
|
||||
{
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
Entity entity = par1DamageSource.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
|
||||
{
|
||||
par2 = (par2 + 1.0F) / 2.0F;
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity par1Entity)
|
||||
{
|
||||
int i = this.isTamed() ? 4 : 2;
|
||||
return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), (float) i);
|
||||
}
|
||||
|
||||
public void setTamed(boolean par1)
|
||||
{
|
||||
super.setTamed(par1);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxTamedHealth);
|
||||
} else
|
||||
{
|
||||
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.maxUntamedHealth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
*/
|
||||
@Override
|
||||
public boolean interact(EntityPlayer par1EntityPlayer)
|
||||
{
|
||||
ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood) itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < this.maxTamedHealth)
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
this.heal((float) itemfood.func_150905_g(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.isJumping = false;
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setTarget((Entity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
}
|
||||
|
||||
this.sendSittingMessageToPlayer(par1EntityPlayer, !this.isSitting());
|
||||
}
|
||||
} else if (itemstack != null && itemstack.getItem().equals(ModItems.weakBloodOrb) && !this.isAngry())
|
||||
{
|
||||
if (!par1EntityPlayer.capabilities.isCreativeMode)
|
||||
{
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack) null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.isRemote)
|
||||
{
|
||||
if (this.rand.nextInt(1) == 0)
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setPathToEntity((PathEntity) null);
|
||||
this.setAttackTarget((EntityLivingBase) null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(this.maxTamedHealth);
|
||||
this.setOwner(par1EntityPlayer.getCommandSenderName());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte) 7);
|
||||
} else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte) 6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(par1EntityPlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
|
||||
* the animal type)
|
||||
*/
|
||||
public boolean isBreedingItem(ItemStack par1ItemStack)
|
||||
{
|
||||
return false;
|
||||
//return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this wolf is angry or not.
|
||||
*/
|
||||
public boolean isAngry()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this wolf is angry or not.
|
||||
*/
|
||||
public void setAngry(boolean par1)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 2)));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this wolf's collar color.
|
||||
*/
|
||||
public int getCollarColor()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(20) & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wolf's collar color.
|
||||
*/
|
||||
public void setCollarColor(int par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.
|
||||
*/
|
||||
public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void func_70918_i(boolean par1)
|
||||
{
|
||||
if (par1)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1));
|
||||
} else
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal par1EntityAnimal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_70922_bv()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(19) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an entity can be despawned, used on idle far away entities
|
||||
*/
|
||||
protected boolean canDespawn()
|
||||
{
|
||||
//return !this.isTamed() && this.ticksExisted > 2400;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)
|
||||
{
|
||||
if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))
|
||||
{
|
||||
if (par1EntityLivingBase instanceof EntityWingedFireDemon)
|
||||
{
|
||||
EntityWingedFireDemon entitywolf = (EntityWingedFireDemon) par1EntityLivingBase;
|
||||
|
||||
if (entitywolf.isTamed() && entitywolf.getOwner() == par2EntityLivingBase)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer) par2EntityLivingBase).canAttackPlayer((EntityPlayer) par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse) par1EntityLivingBase).isTame();
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityAgeable createChild(EntityAgeable par1EntityAgeable)
|
||||
{
|
||||
return this.spawnBabyAnimal(par1EntityAgeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attack the specified entity using a ranged attack.
|
||||
*/
|
||||
public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2)
|
||||
{
|
||||
double xCoord;
|
||||
double yCoord;
|
||||
double zCoord;
|
||||
this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1009, (int) this.posX, (int) this.posY, (int) this.posZ, 0);
|
||||
FireProjectile hol = new FireProjectile(worldObj, this, par1EntityLivingBase, 1.8f, 0f, 20, 600);
|
||||
this.worldObj.spawnEntityInWorld(hol);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets this entity's combat AI.
|
||||
*/
|
||||
public void setCombatTask()
|
||||
{
|
||||
this.tasks.removeTask(this.aiAttackOnCollide);
|
||||
this.tasks.removeTask(this.aiArrowAttack);
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.tasks.addTask(4, this.aiArrowAttack);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,526 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.IProjectile;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import cpw.mods.fml.common.registry.IThrowableEntity;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
//Shamelessly ripped off from x3n0ph0b3
|
||||
public class EnergyBlastProjectile extends Entity implements IProjectile, IThrowableEntity
|
||||
{
|
||||
protected int xTile = -1;
|
||||
protected int yTile = -1;
|
||||
protected int zTile = -1;
|
||||
protected int inTile = 0;
|
||||
protected int inData = 0;
|
||||
protected boolean inGround = false;
|
||||
/**
|
||||
* The owner of this arrow.
|
||||
*/
|
||||
public EntityLivingBase shootingEntity;
|
||||
protected int ticksInAir = 0;
|
||||
protected int maxTicksInAir = 600;
|
||||
private int ricochetCounter = 0;
|
||||
private boolean scheduledForDeath = false;
|
||||
protected int projectileDamage;
|
||||
|
||||
public EnergyBlastProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.maxTicksInAir = 600;
|
||||
}
|
||||
|
||||
public EnergyBlastProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World);
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setPosition(par2, par4, par6);
|
||||
yOffset = 0.0F;
|
||||
this.maxTicksInAir = 600;
|
||||
}
|
||||
|
||||
public EnergyBlastProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World);
|
||||
shootingEntity = par2EntityPlayer;
|
||||
float par3 = 0.8F;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setLocationAndAngles(par2EntityPlayer.posX, par2EntityPlayer.posY + par2EntityPlayer.getEyeHeight(), par2EntityPlayer.posZ, par2EntityPlayer.rotationYaw, par2EntityPlayer.rotationPitch);
|
||||
posX -= MathHelper.cos(rotationYaw / 180.0F * (float) Math.PI) * 0.16F;
|
||||
posY -= 0.2D;
|
||||
posZ -= MathHelper.sin(rotationYaw / 180.0F * (float) Math.PI) * 0.16F;
|
||||
this.setPosition(posX, posY, posZ);
|
||||
yOffset = 0.0F;
|
||||
motionX = -MathHelper.sin(rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(rotationPitch / 180.0F * (float) Math.PI);
|
||||
motionZ = MathHelper.cos(rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(rotationPitch / 180.0F * (float) Math.PI);
|
||||
motionY = -MathHelper.sin(rotationPitch / 180.0F * (float) Math.PI);
|
||||
this.setThrowableHeading(motionX, motionY, motionZ, par3 * 1.5F, 1.0F);
|
||||
this.projectileDamage = damage;
|
||||
this.maxTicksInAir = 600;
|
||||
}
|
||||
|
||||
public EnergyBlastProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World);
|
||||
shootingEntity = par2EntityPlayer;
|
||||
float par3 = 0.8F;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setLocationAndAngles(posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
posX -= MathHelper.cos(rotationYaw / 180.0F * (float) Math.PI) * 0.16F;
|
||||
posY -= 0.2D;
|
||||
posZ -= MathHelper.sin(rotationYaw / 180.0F * (float) Math.PI) * 0.16F;
|
||||
this.setPosition(posX, posY, posZ);
|
||||
yOffset = 0.0F;
|
||||
motionX = -MathHelper.sin(rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(rotationPitch / 180.0F * (float) Math.PI);
|
||||
motionZ = MathHelper.cos(rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(rotationPitch / 180.0F * (float) Math.PI);
|
||||
motionY = -MathHelper.sin(rotationPitch / 180.0F * (float) Math.PI);
|
||||
this.setThrowableHeading(motionX, motionY, motionZ, par3 * 1.5F, 1.0F);
|
||||
this.projectileDamage = damage;
|
||||
this.maxTicksInAir = maxTicksInAir;
|
||||
}
|
||||
|
||||
public EnergyBlastProjectile(World par1World, EntityLivingBase par2EntityLivingBase, EntityLivingBase par3EntityLivingBase, float par4, float par5, int damage, int maxTicksInAir)
|
||||
{
|
||||
super(par1World);
|
||||
this.renderDistanceWeight = 10.0D;
|
||||
this.shootingEntity = par2EntityLivingBase;
|
||||
this.posY = par2EntityLivingBase.posY + (double) par2EntityLivingBase.getEyeHeight() - 0.10000000149011612D;
|
||||
double d0 = par3EntityLivingBase.posX - par2EntityLivingBase.posX;
|
||||
double d1 = par3EntityLivingBase.boundingBox.minY + (double) (par3EntityLivingBase.height / 1.5F) - this.posY;
|
||||
double d2 = par3EntityLivingBase.posZ - par2EntityLivingBase.posZ;
|
||||
double d3 = (double) MathHelper.sqrt_double(d0 * d0 + d2 * d2);
|
||||
|
||||
if (d3 >= 1.0E-7D)
|
||||
{
|
||||
float f2 = (float) (Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
|
||||
float f3 = (float) (-(Math.atan2(d1, d3) * 180.0D / Math.PI));
|
||||
double d4 = d0 / d3;
|
||||
double d5 = d2 / d3;
|
||||
this.setLocationAndAngles(par2EntityLivingBase.posX + d4, this.posY, par2EntityLivingBase.posZ + d5, f2, f3);
|
||||
this.yOffset = 0.0F;
|
||||
float f4 = (float) d3 * 0.2F;
|
||||
this.setThrowableHeading(d0, d1, d2, par4, par5);
|
||||
}
|
||||
|
||||
this.projectileDamage = damage;
|
||||
this.maxTicksInAir = maxTicksInAir;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit()
|
||||
{
|
||||
dataWatcher.addObject(16, Byte.valueOf((byte) 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to setArrowHeading, it's point the throwable entity to a x, y, z
|
||||
* direction.
|
||||
*/
|
||||
@Override
|
||||
public void setThrowableHeading(double var1, double var3, double var5, float var7, float var8)
|
||||
{
|
||||
float var9 = MathHelper.sqrt_double(var1 * var1 + var3 * var3 + var5 * var5);
|
||||
var1 /= var9;
|
||||
var3 /= var9;
|
||||
var5 /= var9;
|
||||
var1 += rand.nextGaussian() * 0.007499999832361937D * var8;
|
||||
var3 += rand.nextGaussian() * 0.007499999832361937D * var8;
|
||||
var5 += rand.nextGaussian() * 0.007499999832361937D * var8;
|
||||
var1 *= var7;
|
||||
var3 *= var7;
|
||||
var5 *= var7;
|
||||
motionX = var1;
|
||||
motionY = var3;
|
||||
motionZ = var5;
|
||||
float var10 = MathHelper.sqrt_double(var1 * var1 + var5 * var5);
|
||||
prevRotationYaw = rotationYaw = (float) (Math.atan2(var1, var5) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch = (float) (Math.atan2(var3, var10) * 180.0D / Math.PI);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
/**
|
||||
* Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
|
||||
* posY, posZ, yaw, pitch
|
||||
*/
|
||||
public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
|
||||
{
|
||||
this.setPosition(par1, par3, par5);
|
||||
this.setRotation(par7, par8);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double par1, double par3, double par5)
|
||||
{
|
||||
motionX = par1;
|
||||
motionY = par3;
|
||||
motionZ = par5;
|
||||
|
||||
if (prevRotationPitch == 0.0F && prevRotationYaw == 0.0F)
|
||||
{
|
||||
float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5);
|
||||
prevRotationYaw = rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch = (float) (Math.atan2(par3, var7) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch;
|
||||
prevRotationYaw = rotationYaw;
|
||||
this.setLocationAndAngles(posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
@Override
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (ticksInAir > maxTicksInAir)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
if (shootingEntity == null)
|
||||
{
|
||||
List players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(posX - 1, posY - 1, posZ - 1, posX + 1, posY + 1, posZ + 1));
|
||||
Iterator i = players.iterator();
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
EntityPlayer closestPlayer = null;
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
EntityPlayer e = (EntityPlayer) i.next();
|
||||
double distance = e.getDistanceToEntity(this);
|
||||
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
closestPlayer = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (closestPlayer != null)
|
||||
{
|
||||
shootingEntity = closestPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevRotationPitch == 0.0F && prevRotationYaw == 0.0F)
|
||||
{
|
||||
float var1 = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ);
|
||||
prevRotationYaw = rotationYaw = (float) (Math.atan2(motionX, motionZ) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch = (float) (Math.atan2(motionY, var1) * 180.0D / Math.PI);
|
||||
}
|
||||
|
||||
Block var16 = worldObj.getBlock(xTile, yTile, zTile);
|
||||
|
||||
if (var16 != null)
|
||||
{
|
||||
var16.setBlockBoundsBasedOnState(worldObj, xTile, yTile, zTile);
|
||||
AxisAlignedBB var2 = var16.getCollisionBoundingBoxFromPool(worldObj, xTile, yTile, zTile);
|
||||
|
||||
if (var2 != null && var2.isVecInside(worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ)))
|
||||
{
|
||||
inGround = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (inGround)
|
||||
{
|
||||
Block var18 = worldObj.getBlock(xTile, yTile, zTile);
|
||||
int var19 = worldObj.getBlockMetadata(xTile, yTile, zTile);
|
||||
|
||||
if (var18.equals(Block.getBlockById(inTile)) && var19 == inData)
|
||||
{
|
||||
// this.groundImpact();
|
||||
// this.setDead();
|
||||
}
|
||||
} else
|
||||
{
|
||||
++ticksInAir;
|
||||
|
||||
if (ticksInAir > 1 && ticksInAir < 3)
|
||||
{
|
||||
//worldObj.spawnParticle("flame", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0D, 0D, 0D);
|
||||
for (int particles = 0; particles < 3; particles++)
|
||||
{
|
||||
this.doFiringParticles();
|
||||
}
|
||||
}
|
||||
|
||||
Vec3 var17 = worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ);
|
||||
Vec3 var3 = worldObj.getWorldVec3Pool().getVecFromPool(posX + motionX, posY + motionY, posZ + motionZ);
|
||||
MovingObjectPosition var4 = worldObj.func_147447_a(var17, var3, true, false, false);
|
||||
var17 = worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ);
|
||||
var3 = worldObj.getWorldVec3Pool().getVecFromPool(posX + motionX, posY + motionY, posZ + motionZ);
|
||||
|
||||
if (var4 != null)
|
||||
{
|
||||
var3 = worldObj.getWorldVec3Pool().getVecFromPool(var4.hitVec.xCoord, var4.hitVec.yCoord, var4.hitVec.zCoord);
|
||||
}
|
||||
|
||||
Entity var5 = null;
|
||||
List var6 = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
double var7 = 0.0D;
|
||||
Iterator var9 = var6.iterator();
|
||||
float var11;
|
||||
|
||||
while (var9.hasNext())
|
||||
{
|
||||
Entity var10 = (Entity) var9.next();
|
||||
|
||||
if (var10.canBeCollidedWith() && (var10 != shootingEntity || ticksInAir >= 5))
|
||||
{
|
||||
var11 = 0.3F;
|
||||
AxisAlignedBB var12 = var10.boundingBox.expand(var11, var11, var11);
|
||||
MovingObjectPosition var13 = var12.calculateIntercept(var17, var3);
|
||||
|
||||
if (var13 != null)
|
||||
{
|
||||
double var14 = var17.distanceTo(var13.hitVec);
|
||||
|
||||
if (var14 < var7 || var7 == 0.0D)
|
||||
{
|
||||
var5 = var10;
|
||||
var7 = var14;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (var5 != null)
|
||||
{
|
||||
var4 = new MovingObjectPosition(var5);
|
||||
}
|
||||
|
||||
if (var4 != null)
|
||||
{
|
||||
this.onImpact(var4);
|
||||
|
||||
if (scheduledForDeath)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
posX += motionX;
|
||||
posY += motionY;
|
||||
posZ += motionZ;
|
||||
MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ);
|
||||
this.setPosition(posX, posY, posZ);
|
||||
//this.doBlockCollisions();
|
||||
}
|
||||
}
|
||||
|
||||
public void doFiringParticles()
|
||||
{
|
||||
worldObj.spawnParticle("mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
worldObj.spawnParticle("flame", posX, posY, posZ, gaussian(motionX), gaussian(motionY), gaussian(motionZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
par1NBTTagCompound.setShort("xTile", (short) xTile);
|
||||
par1NBTTagCompound.setShort("yTile", (short) yTile);
|
||||
par1NBTTagCompound.setShort("zTile", (short) zTile);
|
||||
par1NBTTagCompound.setByte("inTile", (byte) inTile);
|
||||
par1NBTTagCompound.setByte("inData", (byte) inData);
|
||||
par1NBTTagCompound.setByte("inGround", (byte) (inGround ? 1 : 0));
|
||||
par1NBTTagCompound.setInteger("ticksInAir", ticksInAir);
|
||||
par1NBTTagCompound.setInteger("maxTicksInAir", maxTicksInAir);
|
||||
par1NBTTagCompound.setInteger("projectileDamage", this.projectileDamage);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
xTile = par1NBTTagCompound.getShort("xTile");
|
||||
yTile = par1NBTTagCompound.getShort("yTile");
|
||||
zTile = par1NBTTagCompound.getShort("zTile");
|
||||
inTile = par1NBTTagCompound.getByte("inTile") & 255;
|
||||
inData = par1NBTTagCompound.getByte("inData") & 255;
|
||||
inGround = par1NBTTagCompound.getByte("inGround") == 1;
|
||||
ticksInAir = par1NBTTagCompound.getInteger("ticksInAir");
|
||||
maxTicksInAir = par1NBTTagCompound.getInteger("maxTicksInAir");
|
||||
projectileDamage = par1NBTTagCompound.getInteger("projectileDamage");
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they
|
||||
* walk on. used for spiders and wolves to prevent them from trampling crops
|
||||
*/
|
||||
@Override
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public float getShadowSize()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of knockback the arrow applies when it hits a mob.
|
||||
*/
|
||||
public void setKnockbackStrength(int par1)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* If returns false, the item will not inflict any damage against entities.
|
||||
*/
|
||||
@Override
|
||||
public boolean canAttackWithItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the arrow has a stream of critical hit particles flying behind
|
||||
* it.
|
||||
*/
|
||||
public void setIsCritical(boolean par1)
|
||||
{
|
||||
byte var2 = dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1)));
|
||||
} else
|
||||
{
|
||||
dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the arrow has a stream of critical hit particles flying behind
|
||||
* it.
|
||||
*/
|
||||
public boolean getIsCritical()
|
||||
{
|
||||
byte var1 = dataWatcher.getWatchableObjectByte(16);
|
||||
return (var1 & 1) != 0;
|
||||
}
|
||||
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
worldObj.createExplosion(shootingEntity, this.posX, this.posY, this.posZ, (float) (0.1), true);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
((EntityLivingBase) mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60, 2));
|
||||
}
|
||||
|
||||
doDamage(projectileDamage, mop);
|
||||
worldObj.createExplosion(shootingEntity, this.posX, this.posY, this.posZ, (float) (0.1), true);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
private int d6()
|
||||
{
|
||||
return rand.nextInt(6) + 1;
|
||||
}
|
||||
|
||||
protected void spawnHitParticles(String string, int i)
|
||||
{
|
||||
for (int particles = 0; particles < i; particles++)
|
||||
{
|
||||
worldObj.spawnParticle(string, posX, posY - (string == "portal" ? 1 : 0), posZ, gaussian(motionX), gaussian(motionY), gaussian(motionZ));
|
||||
}
|
||||
}
|
||||
|
||||
protected void doDamage(int i, Entity mop)
|
||||
{
|
||||
mop.attackEntityFrom(this.getDamageSource(), i);
|
||||
}
|
||||
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
public double smallGauss(double d)
|
||||
{
|
||||
return (worldObj.rand.nextFloat() - 0.5D) * d;
|
||||
}
|
||||
|
||||
public double gaussian(double d)
|
||||
{
|
||||
return d + d * ((rand.nextFloat() - 0.5D) / 4);
|
||||
}
|
||||
|
||||
private int getRicochetMax()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getThrower()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return this.shootingEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThrower(Entity entity)
|
||||
{
|
||||
if(entity instanceof EntityLivingBase)
|
||||
this.shootingEntity = (EntityLivingBase)entity;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.ModBlocks;
|
||||
|
||||
|
||||
public class EntityBloodLightProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
public EntityBloodLightProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public EntityBloodLightProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public EntityBloodLightProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
}
|
||||
|
||||
public EntityBloodLightProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
|
||||
public EntityBloodLightProjectile(World par1World, EntityLivingBase par2EntityLivingBase, EntityLivingBase par3EntityLivingBase, float par4, float par5, int damage, int maxTicksInAir)
|
||||
{
|
||||
super(par1World, par2EntityLivingBase, par3EntityLivingBase, par4, par5, damage, maxTicksInAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
int sideHit = mop.sideHit;
|
||||
int blockX = mop.blockX;
|
||||
int blockY = mop.blockY;
|
||||
int blockZ = mop.blockZ;
|
||||
|
||||
if (sideHit == 0 && this.worldObj.isAirBlock(blockX, blockY - 1, blockZ))
|
||||
{
|
||||
this.worldObj.setBlock(blockX, blockY - 1, blockZ, ModBlocks.blockBloodLight);
|
||||
}
|
||||
|
||||
if (sideHit == 1 && this.worldObj.isAirBlock(blockX, blockY + 1, blockZ))
|
||||
{
|
||||
this.worldObj.setBlock(blockX, blockY + 1, blockZ, ModBlocks.blockBloodLight);
|
||||
}
|
||||
|
||||
if (sideHit == 2 && this.worldObj.isAirBlock(blockX, blockY, blockZ - 1))
|
||||
{
|
||||
this.worldObj.setBlock(blockX, blockY, blockZ - 1, ModBlocks.blockBloodLight);
|
||||
}
|
||||
|
||||
if (sideHit == 3 && this.worldObj.isAirBlock(blockX, blockY, blockZ + 1))
|
||||
{
|
||||
this.worldObj.setBlock(blockX, blockY, blockZ + 1, ModBlocks.blockBloodLight);
|
||||
}
|
||||
|
||||
if (sideHit == 4 && this.worldObj.isAirBlock(blockX - 1, blockY, blockZ))
|
||||
{
|
||||
this.worldObj.setBlock(blockX - 1, blockY, blockZ, ModBlocks.blockBloodLight);
|
||||
}
|
||||
|
||||
if (sideHit == 5 && this.worldObj.isAirBlock(blockX + 1, blockY, blockZ))
|
||||
{
|
||||
this.worldObj.setBlock(blockX + 1, blockY, blockZ, ModBlocks.blockBloodLight);
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
|
||||
((EntityLivingBase) mop).setRevengeTarget(shootingEntity);
|
||||
|
||||
doDamage(1, mop);
|
||||
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
if (worldObj.isAirBlock((int) this.posX, (int) this.posY, (int) this.posZ))
|
||||
{
|
||||
worldObj.setBlock((int) this.posX, (int) this.posY, (int) this.posZ, Blocks.fire);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityEnergyBazookaMainProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
public EntityEnergyBazookaMainProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public EntityEnergyBazookaMainProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public EntityEnergyBazookaMainProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
}
|
||||
|
||||
public EntityEnergyBazookaMainProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
|
||||
public EntityEnergyBazookaMainProjectile(World par1World, EntityLivingBase par2EntityLivingBase, EntityLivingBase par3EntityLivingBase, float par4, float par5, int damage, int maxTicksInAir)
|
||||
{
|
||||
super(par1World, par2EntityLivingBase, par3EntityLivingBase, par4, par5, damage, maxTicksInAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
worldObj.createExplosion(this.shootingEntity, this.posX, this.posY, this.posZ, (float) (5.0f), false);
|
||||
this.spawnSecondaryProjectiles();
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
spawnSecondaryProjectiles();
|
||||
}
|
||||
|
||||
worldObj.createExplosion(this.shootingEntity, this.posX, this.posY, this.posZ, (float) (5.0f), false);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
public void spawnSecondaryProjectiles()
|
||||
{
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
EntityEnergyBazookaSecondaryProjectile secProj = new EntityEnergyBazookaSecondaryProjectile(worldObj, this.posX, this.posY, this.posZ, 15);
|
||||
secProj.shootingEntity = this.shootingEntity;
|
||||
float xVel = rand.nextFloat() - rand.nextFloat();
|
||||
float yVel = rand.nextFloat() - rand.nextFloat();
|
||||
float zVel = rand.nextFloat() - rand.nextFloat();
|
||||
float wantedVel = 0.5f;
|
||||
secProj.motionX = xVel * wantedVel;
|
||||
secProj.motionY = yVel * wantedVel;
|
||||
secProj.motionZ = zVel * wantedVel;
|
||||
worldObj.spawnEntityInWorld(secProj);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,508 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.IProjectile;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class EntityEnergyBazookaSecondaryProjectile extends EnergyBlastProjectile implements IProjectile
|
||||
{
|
||||
private int xTile = -1;
|
||||
private int yTile = -1;
|
||||
private int zTile = -1;
|
||||
private int inTile = 0;
|
||||
private int inData = 0;
|
||||
private boolean inGround = false;
|
||||
/**
|
||||
* The owner of this arrow.
|
||||
*/
|
||||
public EntityLivingBase shootingEntity;
|
||||
private int ticksInAir = 0;
|
||||
private int ricochetCounter = 0;
|
||||
private boolean scheduledForDeath = false;
|
||||
public int damage;
|
||||
|
||||
public EntityEnergyBazookaSecondaryProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
this.setSize(0.5F, 0.5F);
|
||||
damage = 5;
|
||||
}
|
||||
|
||||
public EntityEnergyBazookaSecondaryProjectile(World par1World, double par2, double par4, double par6, int damage)
|
||||
{
|
||||
super(par1World);
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setPosition(par2, par4, par6);
|
||||
yOffset = 0.0F;
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
public EntityEnergyBazookaSecondaryProjectile(World par1World, EntityPlayer par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World);
|
||||
shootingEntity = par2EntityPlayer;
|
||||
float par3 = 0.8F;
|
||||
this.setSize(0.1F, 0.1F);
|
||||
this.setLocationAndAngles(par2EntityPlayer.posX, par2EntityPlayer.posY + par2EntityPlayer.getEyeHeight(), par2EntityPlayer.posZ, par2EntityPlayer.rotationYaw, par2EntityPlayer.rotationPitch);
|
||||
posX -= MathHelper.cos(rotationYaw / 180.0F * (float) Math.PI) * 0.16F;
|
||||
posY -= 0.2D;
|
||||
posZ -= MathHelper.sin(rotationYaw / 180.0F * (float) Math.PI) * 0.16F;
|
||||
this.setPosition(posX, posY, posZ);
|
||||
yOffset = 0.0F;
|
||||
motionX = -MathHelper.sin(rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(rotationPitch / 180.0F * (float) Math.PI);
|
||||
motionZ = MathHelper.cos(rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(rotationPitch / 180.0F * (float) Math.PI);
|
||||
motionY = -MathHelper.sin(rotationPitch / 180.0F * (float) Math.PI);
|
||||
this.setThrowableHeading(motionX, motionY, motionZ, par3 * 1.5F, 1.0F);
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit()
|
||||
{
|
||||
dataWatcher.addObject(16, Byte.valueOf((byte) 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to setArrowHeading, it's point the throwable entity to a x, y, z
|
||||
* direction.
|
||||
*/
|
||||
@Override
|
||||
public void setThrowableHeading(double var1, double var3, double var5, float var7, float var8)
|
||||
{
|
||||
float var9 = MathHelper.sqrt_double(var1 * var1 + var3 * var3 + var5 * var5);
|
||||
var1 /= var9;
|
||||
var3 /= var9;
|
||||
var5 /= var9;
|
||||
var1 += rand.nextGaussian() * 0.007499999832361937D * var8;
|
||||
var3 += rand.nextGaussian() * 0.007499999832361937D * var8;
|
||||
var5 += rand.nextGaussian() * 0.007499999832361937D * var8;
|
||||
var1 *= var7;
|
||||
var3 *= var7;
|
||||
var5 *= var7;
|
||||
motionX = var1;
|
||||
motionY = var3;
|
||||
motionZ = var5;
|
||||
float var10 = MathHelper.sqrt_double(var1 * var1 + var5 * var5);
|
||||
prevRotationYaw = rotationYaw = (float) (Math.atan2(var1, var5) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch = (float) (Math.atan2(var3, var10) * 180.0D / Math.PI);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
/**
|
||||
* Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
|
||||
* posY, posZ, yaw, pitch
|
||||
*/
|
||||
public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
|
||||
{
|
||||
this.setPosition(par1, par3, par5);
|
||||
this.setRotation(par7, par8);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double par1, double par3, double par5)
|
||||
{
|
||||
motionX = par1;
|
||||
motionY = par3;
|
||||
motionZ = par5;
|
||||
|
||||
if (prevRotationPitch == 0.0F && prevRotationYaw == 0.0F)
|
||||
{
|
||||
float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5);
|
||||
prevRotationYaw = rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch = (float) (Math.atan2(par3, var7) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch;
|
||||
prevRotationYaw = rotationYaw;
|
||||
this.setLocationAndAngles(posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
@Override
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (ticksInAir > maxTicksInAir)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
if (shootingEntity == null)
|
||||
{
|
||||
List players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(posX - 1, posY - 1, posZ - 1, posX + 1, posY + 1, posZ + 1));
|
||||
Iterator i = players.iterator();
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
EntityPlayer closestPlayer = null;
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
EntityPlayer e = (EntityPlayer) i.next();
|
||||
double distance = e.getDistanceToEntity(this);
|
||||
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
closestPlayer = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (closestPlayer != null)
|
||||
{
|
||||
shootingEntity = closestPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevRotationPitch == 0.0F && prevRotationYaw == 0.0F)
|
||||
{
|
||||
float var1 = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ);
|
||||
prevRotationYaw = rotationYaw = (float) (Math.atan2(motionX, motionZ) * 180.0D / Math.PI);
|
||||
prevRotationPitch = rotationPitch = (float) (Math.atan2(motionY, var1) * 180.0D / Math.PI);
|
||||
}
|
||||
|
||||
Block var16 = worldObj.getBlock(xTile, yTile, zTile);
|
||||
|
||||
if (var16 != null)
|
||||
{
|
||||
var16.setBlockBoundsBasedOnState(worldObj, xTile, yTile, zTile);
|
||||
AxisAlignedBB var2 = var16.getCollisionBoundingBoxFromPool(worldObj, xTile, yTile, zTile);
|
||||
|
||||
if (var2 != null && var2.isVecInside(worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ)))
|
||||
{
|
||||
inGround = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (inGround)
|
||||
{
|
||||
Block var18 = worldObj.getBlock(xTile, yTile, zTile);
|
||||
int var19 = worldObj.getBlockMetadata(xTile, yTile, zTile);
|
||||
|
||||
if (var18.equals(Block.getBlockById(inTile)) && var19 == inData)
|
||||
{
|
||||
// this.groundImpact();
|
||||
// this.setDead();
|
||||
}
|
||||
} else
|
||||
{
|
||||
++ticksInAir;
|
||||
|
||||
if (ticksInAir > 1 && ticksInAir < 3)
|
||||
{
|
||||
//worldObj.spawnParticle("flame", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0D, 0D, 0D);
|
||||
for (int particles = 0; particles < 3; particles++)
|
||||
{
|
||||
this.doFiringParticles();
|
||||
}
|
||||
}
|
||||
|
||||
Vec3 var17 = worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ);
|
||||
Vec3 var3 = worldObj.getWorldVec3Pool().getVecFromPool(posX + motionX, posY + motionY, posZ + motionZ);
|
||||
MovingObjectPosition var4 = worldObj.func_147447_a(var17, var3, true, false, false);
|
||||
var17 = worldObj.getWorldVec3Pool().getVecFromPool(posX, posY, posZ);
|
||||
var3 = worldObj.getWorldVec3Pool().getVecFromPool(posX + motionX, posY + motionY, posZ + motionZ);
|
||||
|
||||
if (var4 != null)
|
||||
{
|
||||
var3 = worldObj.getWorldVec3Pool().getVecFromPool(var4.hitVec.xCoord, var4.hitVec.yCoord, var4.hitVec.zCoord);
|
||||
}
|
||||
|
||||
Entity var5 = null;
|
||||
List var6 = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
double var7 = 0.0D;
|
||||
Iterator var9 = var6.iterator();
|
||||
float var11;
|
||||
|
||||
while (var9.hasNext())
|
||||
{
|
||||
Entity var10 = (Entity) var9.next();
|
||||
|
||||
if (var10.canBeCollidedWith() && (var10 != shootingEntity || ticksInAir >= 5))
|
||||
{
|
||||
var11 = 0.3F;
|
||||
AxisAlignedBB var12 = var10.boundingBox.expand(var11, var11, var11);
|
||||
MovingObjectPosition var13 = var12.calculateIntercept(var17, var3);
|
||||
|
||||
if (var13 != null)
|
||||
{
|
||||
double var14 = var17.distanceTo(var13.hitVec);
|
||||
|
||||
if (var14 < var7 || var7 == 0.0D)
|
||||
{
|
||||
var5 = var10;
|
||||
var7 = var14;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (var5 != null)
|
||||
{
|
||||
var4 = new MovingObjectPosition(var5);
|
||||
}
|
||||
|
||||
if (var4 != null)
|
||||
{
|
||||
this.onImpact(var4);
|
||||
|
||||
if (scheduledForDeath)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
posX += motionX;
|
||||
posY += motionY;
|
||||
posZ += motionZ;
|
||||
MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ);
|
||||
this.setPosition(posX, posY, posZ);
|
||||
//this.doBlockCollisions();
|
||||
}
|
||||
}
|
||||
|
||||
public void doFiringParticles()
|
||||
{
|
||||
worldObj.spawnParticle("mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
worldObj.spawnParticle("flame", posX, posY, posZ, gaussian(motionX), gaussian(motionY), gaussian(motionZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
par1NBTTagCompound.setShort("xTile", (short) xTile);
|
||||
par1NBTTagCompound.setShort("yTile", (short) yTile);
|
||||
par1NBTTagCompound.setShort("zTile", (short) zTile);
|
||||
par1NBTTagCompound.setByte("inTile", (byte) inTile);
|
||||
par1NBTTagCompound.setByte("inData", (byte) inData);
|
||||
par1NBTTagCompound.setByte("inGround", (byte) (inGround ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
xTile = par1NBTTagCompound.getShort("xTile");
|
||||
yTile = par1NBTTagCompound.getShort("yTile");
|
||||
zTile = par1NBTTagCompound.getShort("zTile");
|
||||
inTile = par1NBTTagCompound.getByte("inTile") & 255;
|
||||
inData = par1NBTTagCompound.getByte("inData") & 255;
|
||||
inGround = par1NBTTagCompound.getByte("inGround") == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they
|
||||
* walk on. used for spiders and wolves to prevent them from trampling crops
|
||||
*/
|
||||
@Override
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public float getShadowSize()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of knockback the arrow applies when it hits a mob.
|
||||
*/
|
||||
public void setKnockbackStrength(int par1)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* If returns false, the item will not inflict any damage against entities.
|
||||
*/
|
||||
@Override
|
||||
public boolean canAttackWithItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the arrow has a stream of critical hit particles flying behind
|
||||
* it.
|
||||
*/
|
||||
public void setIsCritical(boolean par1)
|
||||
{
|
||||
byte var2 = dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (par1)
|
||||
{
|
||||
dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1)));
|
||||
} else
|
||||
{
|
||||
dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the arrow has a stream of critical hit particles flying behind
|
||||
* it.
|
||||
*/
|
||||
public boolean getIsCritical()
|
||||
{
|
||||
byte var1 = dataWatcher.getWatchableObjectByte(16);
|
||||
return (var1 & 1) != 0;
|
||||
}
|
||||
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
this.groundImpact(mop.sideHit);
|
||||
worldObj.createExplosion(shootingEntity, posX, posY, posZ, 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
doDamage(this.damage + d6(), mop);
|
||||
worldObj.createExplosion(shootingEntity, posX, posY, posZ, 2, false);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
private int d6()
|
||||
{
|
||||
return rand.nextInt(6) + 1;
|
||||
}
|
||||
|
||||
public void spawnHitParticles(String string, int i)
|
||||
{
|
||||
for (int particles = 0; particles < i; particles++)
|
||||
{
|
||||
worldObj.spawnParticle(string, posX, posY - (string == "portal" ? 1 : 0), posZ, gaussian(motionX), gaussian(motionY), gaussian(motionZ));
|
||||
}
|
||||
}
|
||||
|
||||
public void doDamage(int i, Entity mop)
|
||||
{
|
||||
mop.attackEntityFrom(this.getDamageSource(), i);
|
||||
}
|
||||
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
public void groundImpact(int sideHit)
|
||||
{
|
||||
this.ricochet(sideHit);
|
||||
}
|
||||
|
||||
public double smallGauss(double d)
|
||||
{
|
||||
return (worldObj.rand.nextFloat() - 0.5D) * d;
|
||||
}
|
||||
|
||||
public double gaussian(double d)
|
||||
{
|
||||
return d + d * ((rand.nextFloat() - 0.5D) / 4);
|
||||
}
|
||||
|
||||
private void ricochet(int sideHit)
|
||||
{
|
||||
switch (sideHit)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
// topHit, bottomHit, reflect Y
|
||||
motionY = motionY * -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
// westHit, eastHit, reflect Z
|
||||
motionZ = motionZ * -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
// southHit, northHit, reflect X
|
||||
motionX = motionX * -1;
|
||||
break;
|
||||
}
|
||||
|
||||
ricochetCounter++;
|
||||
|
||||
if (ricochetCounter > this.getRicochetMax())
|
||||
{
|
||||
scheduledForDeath = true;
|
||||
|
||||
for (int particles = 0; particles < 4; particles++)
|
||||
{
|
||||
switch (sideHit)
|
||||
{
|
||||
case 0:
|
||||
worldObj.spawnParticle("smoke", posX, posY, posZ, gaussian(0.1D), -gaussian(0.1D), gaussian(0.1D));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
worldObj.spawnParticle("smoke", posX, posY, posZ, gaussian(0.1D), gaussian(0.1D), gaussian(0.1D));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
worldObj.spawnParticle("smoke", posX, posY, posZ, gaussian(0.1D), gaussian(0.1D), -gaussian(0.1D));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
worldObj.spawnParticle("smoke", posX, posY, posZ, gaussian(0.1D), gaussian(0.1D), gaussian(0.1D));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
worldObj.spawnParticle("smoke", posX, posY, posZ, -gaussian(0.1D), gaussian(0.1D), gaussian(0.1D));
|
||||
break;
|
||||
|
||||
case 5:
|
||||
worldObj.spawnParticle("smoke", posX, posY, posZ, gaussian(0.1D), gaussian(0.1D), gaussian(0.1D));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getRicochetMax()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorRegistry;
|
||||
|
||||
public class EntityMeteor extends EnergyBlastProjectile
|
||||
{
|
||||
private int meteorID;
|
||||
|
||||
public EntityMeteor(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
this.meteorID = 0;
|
||||
}
|
||||
|
||||
public EntityMeteor(World par1World, double par2, double par4, double par6, int meteorID)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
this.meteorID = meteorID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.fallingBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (worldObj.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
MeteorRegistry.createMeteorImpact(worldObj, mop.blockX, mop.blockY, mop.blockZ, this.meteorID);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
MeteorRegistry.createMeteorImpact(worldObj, (int) this.posX, (int) this.posY, (int) this.posZ, meteorID);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ExplosionProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
protected boolean causesEnvDamage;
|
||||
|
||||
public ExplosionProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public ExplosionProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public ExplosionProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
causesEnvDamage = flag;
|
||||
}
|
||||
|
||||
public ExplosionProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
causesEnvDamage = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float) (2), causesEnvDamage);
|
||||
//this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
// for(int i=-1;i<=1;i++)
|
||||
// {
|
||||
// for(int j=-1;j<=1;j++)
|
||||
// {
|
||||
// for(int k=-1;k<=1;k++)
|
||||
// {
|
||||
// if(worldObj.isAirBlock((int)this.posX+i, (int)this.posY+j, (int)this.posZ+k))
|
||||
// {
|
||||
// worldObj.setBlock( (int)this.posX+i, (int)this.posY+j, (int)this.posZ+k,Block.fire.blockID);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float) (2), causesEnvDamage);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
if (((EntityLivingBase) mop).isImmuneToFire())
|
||||
{
|
||||
doDamage((int) (projectileDamage), mop);
|
||||
} else
|
||||
{
|
||||
doDamage(projectileDamage, mop);
|
||||
}
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
if (worldObj.isAirBlock((int) this.posX, (int) this.posY, (int) this.posZ))
|
||||
{
|
||||
//worldObj.setBlock((int)this.posX, (int)this.posY, (int)this.posZ,Block.fire.blockID);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
worldObj.spawnParticle("mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
worldObj.spawnParticle("explode", posX, posY, posZ, gaussian(motionX), gaussian(motionY), gaussian(motionZ));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("causesEnvDamage", causesEnvDamage);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
causesEnvDamage = par1NBTTagCompound.getBoolean("causesEnvDamage");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class FireProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
public FireProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public FireProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public FireProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
}
|
||||
|
||||
public FireProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
|
||||
public FireProjectile(World par1World, EntityLivingBase par2EntityLivingBase, EntityLivingBase par3EntityLivingBase, float par4, float par5, int damage, int maxTicksInAir)
|
||||
{
|
||||
super(par1World, par2EntityLivingBase, par3EntityLivingBase, par4, par5, damage, maxTicksInAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
for (int i = -1; i <= 1; i++)
|
||||
{
|
||||
for (int j = -1; j <= 1; j++)
|
||||
{
|
||||
for (int k = -1; k <= 1; k++)
|
||||
{
|
||||
if (worldObj.isAirBlock((int) this.posX + i, (int) this.posY + j, (int) this.posZ + k))
|
||||
{
|
||||
worldObj.setBlock((int) this.posX + i, (int) this.posY + j, (int) this.posZ + k, Blocks.fire);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
((EntityLivingBase) mop).setFire(50);
|
||||
((EntityLivingBase) mop).setRevengeTarget(shootingEntity);
|
||||
|
||||
if (((EntityLivingBase) mop).isPotionActive(Potion.fireResistance) || ((EntityLivingBase) mop).isImmuneToFire())
|
||||
{
|
||||
((EntityLivingBase) mop).attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
} else
|
||||
{
|
||||
doDamage(projectileDamage, mop);
|
||||
((EntityLivingBase) mop).hurtResistantTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
if (worldObj.isAirBlock((int) this.posX, (int) this.posY, (int) this.posZ))
|
||||
{
|
||||
worldObj.setBlock((int) this.posX, (int) this.posY, (int) this.posZ, Blocks.fire);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.common.PacketHandler;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
|
||||
public class HolyProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
public HolyProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public HolyProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public HolyProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
}
|
||||
|
||||
public HolyProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
|
||||
public HolyProjectile(World par1World, EntityLivingBase par2EntityLivingBase, EntityLivingBase par3EntityLivingBase, float par4, float par5, int damage, int maxTicksInAir)
|
||||
{
|
||||
super(par1World, par2EntityLivingBase, par3EntityLivingBase, par4, par5, damage, maxTicksInAir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
// for(int i=-1;i<=1;i++)
|
||||
// {
|
||||
// for(int j=-1;j<=1;j++)
|
||||
// {
|
||||
// for(int k=-1;k<=1;k++)
|
||||
// {
|
||||
// if(worldObj.isAirBlock((int)this.posX+i, (int)this.posY+j, (int)this.posZ+k))
|
||||
// {
|
||||
// worldObj.setBlock( (int)this.posX+i, (int)this.posY+j, (int)this.posZ+k,Block.fire.blockID);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
if (((EntityLivingBase) mop).isEntityUndead())
|
||||
{
|
||||
doDamage((int) (projectileDamage * 2), mop);
|
||||
} else
|
||||
{
|
||||
doDamage(projectileDamage, mop);
|
||||
}
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
if (worldObj.isAirBlock((int) this.posX, (int) this.posY, (int) this.posZ))
|
||||
{
|
||||
//worldObj.setBlock((int)this.posX, (int)this.posY, (int)this.posZ,Block.fire.blockID);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpell", posX, posY, posZ, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.common.PacketHandler;
|
||||
import WayofTime.alchemicalWizardry.common.entity.mob.EntityIceDemon;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
|
||||
public class IceProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
public IceProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public IceProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public IceProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
}
|
||||
|
||||
public IceProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
|
||||
public IceProjectile(World worldObj, EntityIceDemon entityIceDemon, EntityLivingBase par1EntityLivingBase, float f, float g, int i, int j)
|
||||
{
|
||||
super(worldObj, entityIceDemon, par1EntityLivingBase, f, g, i, j);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
// for(int i=-1;i<=1;i++)
|
||||
// {
|
||||
// for(int j=-1;j<=1;j++)
|
||||
// {
|
||||
// for(int k=-1;k<=1;k++)
|
||||
// {
|
||||
// if(worldObj.isAirBlock((int)this.posX+i, (int)this.posY+j, (int)this.posZ+k))
|
||||
// {
|
||||
// worldObj.setBlock( (int)this.posX+i, (int)this.posY+j, (int)this.posZ+k,Block.fire.blockID);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
shootingEntity.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
if (((EntityLivingBase) mop).isImmuneToFire())
|
||||
{
|
||||
doDamage((int) (projectileDamage * 2), mop);
|
||||
((EntityLivingBase) mop).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 200, 2));
|
||||
} else
|
||||
{
|
||||
doDamage(projectileDamage, mop);
|
||||
((EntityLivingBase) mop).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 1));
|
||||
}
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
if (worldObj.isAirBlock((int) this.posX, (int) this.posY, (int) this.posZ))
|
||||
{
|
||||
//worldObj.setBlock((int)this.posX, (int)this.posY, (int)this.posZ,Block.fire.blockID);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "explode", posX, posY, posZ, gaussian(motionX), gaussian(motionY), gaussian(motionZ));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
|
||||
public class LightningBoltProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
private boolean causeLightning;
|
||||
|
||||
public LightningBoltProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public LightningBoltProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public LightningBoltProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
causeLightning = flag;
|
||||
}
|
||||
|
||||
public LightningBoltProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
causeLightning = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
if (causeLightning)
|
||||
{
|
||||
this.worldObj.addWeatherEffect(new EntityLightningBolt(this.worldObj, this.posX, this.posY, this.posZ));
|
||||
}
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
//shootingEntity.attackEntityFrom(DamageSource.causePlayerDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
// if(((EntityLivingBase)mop).isEntityUndead())
|
||||
// {
|
||||
// doDamage((int)(projectileDamage*2),mop);
|
||||
// }else
|
||||
// {
|
||||
// doDamage(projectileDamage, mop);
|
||||
// }
|
||||
if (causeLightning)
|
||||
{
|
||||
this.worldObj.addWeatherEffect(new EntityLightningBolt(this.worldObj, ((EntityLivingBase) mop).posX, ((EntityLivingBase) mop).posY, ((EntityLivingBase) mop).posZ));
|
||||
} else
|
||||
{
|
||||
doDamage(projectileDamage, mop);
|
||||
}
|
||||
|
||||
//((EntityLivingBase)mop).setVelocity(this.motionX*2, ((EntityLivingBase)mop).motionY+1.5, this.motionZ*2);
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpell", posX, posY, posZ, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("causeLightning", causeLightning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
causeLightning = par1NBTTagCompound.getBoolean("causeLightning");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.common.PacketHandler;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
|
||||
public class MudProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
private boolean doesBlindness; //True for when it applies blindness, false for slowness
|
||||
|
||||
public MudProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public MudProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public MudProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
doesBlindness = flag;
|
||||
}
|
||||
|
||||
public MudProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
doesBlindness = flag;
|
||||
}
|
||||
|
||||
public MudProjectile(World par1World, EntityLivingBase par2EntityLivingBase, EntityLivingBase par3EntityLivingBase, float par4, float par5, int damage, int maxTicksInAir, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityLivingBase, par3EntityLivingBase, par4, par5, damage, maxTicksInAir);
|
||||
doesBlindness = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
//shootingEntity.attackEntityFrom(DamageSource.causePlayerDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
// if(((EntityLivingBase)mop).isEntityUndead())
|
||||
// {
|
||||
// doDamage((int)(projectileDamage*2),mop);
|
||||
// }else
|
||||
// {
|
||||
// doDamage(projectileDamage, mop);
|
||||
// }
|
||||
if (doesBlindness)
|
||||
{
|
||||
((EntityLivingBase) mop).addPotionEffect(new PotionEffect(Potion.blindness.id, 100, 0));
|
||||
} else
|
||||
{
|
||||
((EntityLivingBase) mop).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 2));
|
||||
}
|
||||
|
||||
doDamage(projectileDamage, mop);
|
||||
//((EntityLivingBase)mop).setVelocity(this.motionX*2, ((EntityLivingBase)mop).motionY+1.5, this.motionZ*2);
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpell", posX, posY, posZ, 0.5F, 0.297F, 0.0664F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("doesBlindness", doesBlindness);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
doesBlindness = par1NBTTagCompound.getBoolean("doesBlindness");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.living.EnderTeleportEvent;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
import WayofTime.alchemicalWizardry.common.spell.simple.SpellTeleport;
|
||||
|
||||
public class TeleportProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
private boolean isEntityTeleport; //True if the entity firing teleports on hit
|
||||
|
||||
public TeleportProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
this.motionX *= 3;
|
||||
this.motionY *= 3;
|
||||
this.motionZ *= 3;
|
||||
}
|
||||
|
||||
public TeleportProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
this.motionX *= 3;
|
||||
this.motionY *= 3;
|
||||
this.motionZ *= 3;
|
||||
}
|
||||
|
||||
public TeleportProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
isEntityTeleport = flag;
|
||||
this.motionX *= 3;
|
||||
this.motionY *= 3;
|
||||
this.motionZ *= 3;
|
||||
}
|
||||
|
||||
public TeleportProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch, boolean flag)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
isEntityTeleport = flag;
|
||||
this.motionX *= 3;
|
||||
this.motionY *= 3;
|
||||
this.motionZ *= 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
if (isEntityTeleport)
|
||||
{
|
||||
if (shootingEntity != null && shootingEntity instanceof EntityPlayerMP)
|
||||
{
|
||||
EntityPlayerMP entityplayermp = (EntityPlayerMP) shootingEntity;
|
||||
|
||||
if(entityplayermp.worldObj == this.worldObj)
|
||||
//if (!entityplayermp.playerNetServerHandler.connectionClosed && entityplayermp.worldObj == this.worldObj)
|
||||
{
|
||||
EnderTeleportEvent event = new EnderTeleportEvent(entityplayermp, this.posX, this.posY, this.posZ, 5.0F);
|
||||
|
||||
if (!MinecraftForge.EVENT_BUS.post(event))
|
||||
{
|
||||
if (shootingEntity.isRiding())
|
||||
{
|
||||
shootingEntity.mountEntity((Entity) null);
|
||||
}
|
||||
|
||||
shootingEntity.setPositionAndUpdate(event.targetX, event.targetY, event.targetZ);
|
||||
// this.getThrower().fallDistance = 0.0F;
|
||||
// this.getThrower().attackEntityFrom(DamageSource.fall, event.attackDamage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
//shootingEntity.attackEntityFrom(DamageSource.causePlayerDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
// if(((EntityLivingBase)mop).isEntityUndead())
|
||||
// {
|
||||
// doDamage((int)(projectileDamage*2),mop);
|
||||
// }else
|
||||
// {
|
||||
// doDamage(projectileDamage, mop);
|
||||
// }
|
||||
if (isEntityTeleport)
|
||||
{
|
||||
if (shootingEntity != null && shootingEntity instanceof EntityPlayerMP)
|
||||
{
|
||||
EntityPlayerMP entityplayermp = (EntityPlayerMP) shootingEntity;
|
||||
|
||||
if(entityplayermp.worldObj == this.worldObj)
|
||||
//if (!entityplayermp.playerNetServerHandler.connectionClosed && entityplayermp.worldObj == this.worldObj)
|
||||
{
|
||||
EnderTeleportEvent event = new EnderTeleportEvent(entityplayermp, this.posX, this.posY, this.posZ, 5.0F);
|
||||
|
||||
if (!MinecraftForge.EVENT_BUS.post(event))
|
||||
{
|
||||
if (shootingEntity.isRiding())
|
||||
{
|
||||
shootingEntity.mountEntity((Entity) null);
|
||||
}
|
||||
|
||||
shootingEntity.setPositionAndUpdate(event.targetX, event.targetY, event.targetZ);
|
||||
// this.getThrower().fallDistance = 0.0F;
|
||||
// this.getThrower().attackEntityFrom(DamageSource.fall, event.attackDamage);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
// int x = (int)this.posX + mop.worldObj.rand.nextInt(100) - mop.worldObj.rand.nextInt(100);
|
||||
// int y = (int)this.posY + mop.worldObj.rand.nextInt(10) - mop.worldObj.rand.nextInt(10);
|
||||
// int z = (int)this.posZ + mop.worldObj.rand.nextInt(100) - mop.worldObj.rand.nextInt(100);
|
||||
//
|
||||
// boolean bool = false;
|
||||
// int i = 0;
|
||||
//
|
||||
// while(!bool&&i<100)
|
||||
// {
|
||||
// if(worldObj.isAirBlock(x, y, z)||worldObj.isAirBlock(x, y+1, z))
|
||||
// {
|
||||
// ((EntityLivingBase) mop).setPositionAndUpdate(x, y, z);
|
||||
// bool=true;
|
||||
// }else
|
||||
// {
|
||||
// x = (int)this.posX + mop.worldObj.rand.nextInt(100) - mop.worldObj.rand.nextInt(100);
|
||||
// y = (int)this.posY + mop.worldObj.rand.nextInt(10) - mop.worldObj.rand.nextInt(10);
|
||||
// z = (int)this.posZ + mop.worldObj.rand.nextInt(100) - mop.worldObj.rand.nextInt(100);
|
||||
// i++;
|
||||
// }
|
||||
// }
|
||||
SpellTeleport.teleportRandomly((EntityLivingBase) mop, 64);
|
||||
}
|
||||
|
||||
//doDamage(projectileDamage, mop);
|
||||
//((EntityLivingBase)mop).setVelocity(this.motionX*2, ((EntityLivingBase)mop).motionY+1.5, this.motionZ*2);
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "portal", posX, posY, posZ, -motionX, -motionY, -motionZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(par1NBTTagCompound);
|
||||
par1NBTTagCompound.setBoolean("isEntityTeleport", isEntityTeleport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
|
||||
{
|
||||
super.readEntityFromNBT(par1NBTTagCompound);
|
||||
isEntityTeleport = par1NBTTagCompound.getBoolean("isEntityTeleport");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
|
||||
import WayofTime.alchemicalWizardry.common.PacketHandler;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
|
||||
public class WaterProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
public WaterProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public WaterProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public WaterProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
}
|
||||
|
||||
public WaterProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
//shootingEntity.attackEntityFrom(DamageSource.causePlayerDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
// if(((EntityLivingBase)mop).isEntityUndead())
|
||||
// {
|
||||
// doDamage((int)(projectileDamage*2),mop);
|
||||
// }else
|
||||
// {
|
||||
// doDamage(projectileDamage, mop);
|
||||
// }
|
||||
if (((EntityLivingBase) mop).isImmuneToFire())
|
||||
{
|
||||
doDamage(projectileDamage * 2, mop);
|
||||
((EntityLivingBase) mop).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionDrowning.id, 80, 1));
|
||||
} else
|
||||
{
|
||||
doDamage(projectileDamage, mop);
|
||||
((EntityLivingBase) mop).addPotionEffect(new PotionEffect(AlchemicalWizardry.customPotionDrowning.id, 80, 0));
|
||||
}
|
||||
|
||||
//((EntityLivingBase)mop).setVelocity(this.motionX*2, ((EntityLivingBase)mop).motionY+1.5, this.motionZ*2);
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "portal", posX, posY, posZ, -motionX, -motionY, -motionZ);
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package WayofTime.alchemicalWizardry.common.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper;
|
||||
|
||||
public class WindGustProjectile extends EnergyBlastProjectile
|
||||
{
|
||||
public WindGustProjectile(World par1World)
|
||||
{
|
||||
super(par1World);
|
||||
}
|
||||
|
||||
public WindGustProjectile(World par1World, double par2, double par4, double par6)
|
||||
{
|
||||
super(par1World, par2, par4, par6);
|
||||
}
|
||||
|
||||
public WindGustProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage);
|
||||
}
|
||||
|
||||
public WindGustProjectile(World par1World, EntityLivingBase par2EntityPlayer, int damage, int maxTicksInAir, double posX, double posY, double posZ, float rotationYaw, float rotationPitch)
|
||||
{
|
||||
super(par1World, par2EntityPlayer, damage, maxTicksInAir, posX, posY, posZ, rotationYaw, rotationPitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource getDamageSource()
|
||||
{
|
||||
return DamageSource.causeMobDamage(shootingEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MovingObjectPosition mop)
|
||||
{
|
||||
if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null)
|
||||
{
|
||||
if (mop.entityHit == shootingEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onImpact(mop.entityHit);
|
||||
} else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK)
|
||||
{
|
||||
// for(int i=-1;i<=1;i++)
|
||||
// {
|
||||
// for(int j=-1;j<=1;j++)
|
||||
// {
|
||||
// for(int k=-1;k<=1;k++)
|
||||
// {
|
||||
// if(worldObj.isAirBlock((int)this.posX+i, (int)this.posY+j, (int)this.posZ+k))
|
||||
// {
|
||||
// worldObj.setBlock( (int)this.posX+i, (int)this.posY+j, (int)this.posZ+k,Block.fire.blockID);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(Entity mop)
|
||||
{
|
||||
if (mop == shootingEntity && ticksInAir > 3)
|
||||
{
|
||||
//shootingEntity.attackEntityFrom(DamageSource.causePlayerDamage(shootingEntity), 1);
|
||||
this.setDead();
|
||||
} else
|
||||
{
|
||||
//doDamage(8 + d6(), mop);
|
||||
if (mop instanceof EntityLivingBase)
|
||||
{
|
||||
//((EntityLivingBase)mop).addPotionEffect(new PotionEffect(Potion.weakness.id, 60,2));
|
||||
//((EntityLivingBase)mop).setFire(50);
|
||||
//((EntityLivingBase)mop).setRevengeTarget(shootingEntity);
|
||||
// if(((EntityLivingBase)mop).isEntityUndead())
|
||||
// {
|
||||
// doDamage((int)(projectileDamage*2),mop);
|
||||
// }else
|
||||
// {
|
||||
// doDamage(projectileDamage, mop);
|
||||
// }
|
||||
((EntityLivingBase) mop).motionX = this.motionX * 2;
|
||||
((EntityLivingBase) mop).motionY = 1.5;
|
||||
((EntityLivingBase) mop).motionZ = this.motionZ * 2;
|
||||
//((EntityLivingBase)mop).setVelocity(this.motionX*2, ((EntityLivingBase)mop).motionY+1.5, this.motionZ*2);
|
||||
}
|
||||
|
||||
//worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(0.1), true);
|
||||
}
|
||||
|
||||
spawnHitParticles("magicCrit", 8);
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFiringParticles()
|
||||
{
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpellAmbient", posX + smallGauss(0.1D), posY + smallGauss(0.1D), posZ + smallGauss(0.1D), 0.5D, 0.5D, 0.5D);
|
||||
SpellHelper.sendParticleToAllAround(worldObj, posX, posY, posZ, 30, worldObj.provider.dimensionId, "mobSpell", posX, posY, posZ, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue