mirror of
https://github.com/GTNewHorizons/Botania.git
synced 2026-11-13 08:44:02 +00:00
Alfhomancy Rebalance: Part 4.
This commit is contained in:
1 parent
c9b7685dc4
commit
707ef12a1f
10 files changed
+411
-43
No files matched your search
@@ -15,16 +15,35 @@ import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.boss.BossStatus;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import org.lwjgl.opengl.ARBShaderObjects;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import vazkii.botania.client.core.helper.ShaderHelper;
|
||||
import vazkii.botania.client.core.helper.ShaderHelper.ShaderCallback;
|
||||
import vazkii.botania.client.lib.LibResources;
|
||||
import vazkii.botania.client.model.ModelPixie;
|
||||
import vazkii.botania.common.entity.EntityDoppleganger;
|
||||
import vazkii.botania.common.entity.EntityPixie;
|
||||
|
||||
public class RenderPixie extends RenderLiving {
|
||||
|
||||
ShaderCallback callback = new ShaderCallback() {
|
||||
|
||||
@Override
|
||||
public void call(int shader) {
|
||||
// Frag Uniforms
|
||||
int disfigurationUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "disfiguration");
|
||||
ARBShaderObjects.glUniform1fARB(disfigurationUniform, 0.025F);
|
||||
|
||||
// Vert Uniforms
|
||||
int grainIntensityUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "grainIntensity");
|
||||
ARBShaderObjects.glUniform1fARB(grainIntensityUniform, 0.05F);
|
||||
}
|
||||
};
|
||||
|
||||
public RenderPixie() {
|
||||
super(new ModelPixie(), 0.25F);
|
||||
setRenderPassModel(new ModelPixie());
|
||||
@@ -36,6 +55,17 @@ public class RenderPixie extends RenderLiving {
|
||||
return new ResourceLocation(LibResources.MODEL_PIXIE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) {
|
||||
EntityPixie pixie = (EntityPixie) par1Entity;
|
||||
|
||||
if(pixie.getType() == 1)
|
||||
ShaderHelper.useShader(ShaderHelper.doppleganger, callback);
|
||||
super.doRender(par1Entity, par2, par4, par6, par8, par9);
|
||||
if(pixie.getType() == 1)
|
||||
ShaderHelper.releaseShader();
|
||||
}
|
||||
|
||||
protected int setPixieBrightness(EntityPixie par1EntityPixie, int par2, float par3) {
|
||||
if (par2 != 0)
|
||||
return -1;
|
||||
|
||||
@@ -36,7 +36,7 @@ public class PixieHandler {
|
||||
if(stack != null && stack.getItem() == ModItems.elementiumSword)
|
||||
dmg += 2;
|
||||
|
||||
pixie.setProps((EntityLivingBase) event.source.getEntity(), player, dmg);
|
||||
pixie.setProps((EntityLivingBase) event.source.getEntity(), player, 0, dmg);
|
||||
player.worldObj.spawnEntityInWorld(pixie);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,36 +11,76 @@
|
||||
*/
|
||||
package vazkii.botania.common.entity;
|
||||
|
||||
import vazkii.botania.common.Botania;
|
||||
import vazkii.botania.common.core.helper.Vector3;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityCreature;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.boss.IBossDisplayData;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeModContainer;
|
||||
import vazkii.botania.common.core.helper.Vector3;
|
||||
import vazkii.botania.common.lib.LibObfuscation;
|
||||
|
||||
public class EntityDoppleganger extends EntityLiving implements IBossDisplayData {
|
||||
public class EntityDoppleganger extends EntityCreature implements IBossDisplayData {
|
||||
|
||||
public static final int SPAWN_TICKS = 100;
|
||||
|
||||
private static final float MAX_HP = 5F; // TODO
|
||||
private static final float MAX_HP = 200F; // TODO
|
||||
|
||||
private static final String TAG_SOURCE_X = "sourceX";
|
||||
private static final String TAG_SOURCE_Y = "sourceY";
|
||||
private static final String TAG_SOURCE_Z = "sourceZ";
|
||||
|
||||
private static final String TAG_INVUL_TIME = "invulTime";
|
||||
private static final String TAG_AGGRO = "aggro";
|
||||
private static final String TAG_TP_DELAY = "tpDelay";
|
||||
|
||||
boolean spawnLandmines = false;
|
||||
boolean spawnPixies = false;
|
||||
|
||||
public EntityDoppleganger(World par1World) {
|
||||
super(par1World);
|
||||
setSize(0.6F, 1.8F);
|
||||
getNavigator().setCanSwim(true);
|
||||
tasks.addTask(0, new EntityAISwimming(this));
|
||||
tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, Float.MAX_VALUE));
|
||||
experienceValue = 100;
|
||||
getNavigator().setCanSwim(true);
|
||||
tasks.addTask(0, new EntityAISwimming(this));
|
||||
tasks.addTask(1, new EntityAIWatchClosest(this, EntityPlayer.class, Float.MAX_VALUE));
|
||||
isImmuneToFire = true;
|
||||
experienceValue = 825;
|
||||
}
|
||||
|
||||
public static boolean spawn(ItemStack par1ItemStack, World par3World, int par4, int par5, int par6) {
|
||||
Block block = par3World.getBlock(par4, par5, par6);
|
||||
if(block == Blocks.beacon && !par3World.isRemote) {
|
||||
par1ItemStack.stackSize--;
|
||||
EntityDoppleganger e = new EntityDoppleganger(par3World);
|
||||
e.setPosition(par4 + 0.5, par5 + 3, par6 + 0.5);
|
||||
e.setInvulTime(EntityDoppleganger.SPAWN_TICKS);
|
||||
e.setHealth(1F);
|
||||
e.setSource(par4, par5, par6);
|
||||
par3World.playSoundAtEntity(e, "mob.enderdragon.growl", 10F, 0.1F);
|
||||
par3World.spawnEntityInWorld(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAIEnabled() {
|
||||
return true;
|
||||
@@ -49,63 +89,143 @@ public class EntityDoppleganger extends EntityLiving implements IBossDisplayData
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
dataWatcher.addObject(20, new Integer(0)); // Invul Time
|
||||
dataWatcher.addObject(20, 0); // Invul Time
|
||||
dataWatcher.addObject(21, (byte) 0); // Aggro
|
||||
dataWatcher.addObject(22, 0); // TP Delay
|
||||
dataWatcher.addObject(23, 0); // Source X
|
||||
dataWatcher.addObject(24, 0); // Source Y
|
||||
dataWatcher.addObject(25, 0); // Source Z
|
||||
}
|
||||
|
||||
public int getInvulTime() {
|
||||
return dataWatcher.getWatchableObjectInt(20);
|
||||
}
|
||||
|
||||
public boolean isAggored() {
|
||||
return dataWatcher.getWatchableObjectByte(21) == 1;
|
||||
}
|
||||
|
||||
public int getTPDelay() {
|
||||
return dataWatcher.getWatchableObjectInt(22);
|
||||
}
|
||||
|
||||
public ChunkCoordinates getSource() {
|
||||
int x = dataWatcher.getWatchableObjectInt(23);
|
||||
int y = dataWatcher.getWatchableObjectInt(24);
|
||||
int z = dataWatcher.getWatchableObjectInt(25);
|
||||
return new ChunkCoordinates(x, y, z);
|
||||
}
|
||||
|
||||
public void setInvulTime(int time) {
|
||||
dataWatcher.updateObject(20, time);
|
||||
}
|
||||
|
||||
public void setAggroed(boolean aggored) {
|
||||
dataWatcher.updateObject(21, (byte) (aggored ? 1 : 0));
|
||||
}
|
||||
|
||||
public void setTPDelay(int delay) {
|
||||
dataWatcher.updateObject(22, delay);
|
||||
}
|
||||
|
||||
public void setSource(int x, int y, int z) {
|
||||
dataWatcher.updateObject(23, x);
|
||||
dataWatcher.updateObject(24, y);
|
||||
dataWatcher.updateObject(25, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound par1nbtTagCompound) {
|
||||
super.writeEntityToNBT(par1nbtTagCompound);
|
||||
par1nbtTagCompound.setInteger(TAG_INVUL_TIME, getInvulTime());
|
||||
par1nbtTagCompound.setBoolean(TAG_AGGRO, isAggored());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound par1nbtTagCompound) {
|
||||
super.readEntityFromNBT(par1nbtTagCompound);
|
||||
setInvulTime(par1nbtTagCompound.getInteger(TAG_INVUL_TIME));
|
||||
setAggroed(par1nbtTagCompound.getBoolean(TAG_AGGRO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) {
|
||||
if(par1DamageSource.damageType.equals("player") && getInvulTime() == 0)
|
||||
if((par1DamageSource.damageType.equals("player") || par1DamageSource.getEntity() instanceof EntityPixie) && getInvulTime() == 0)
|
||||
return super.attackEntityFrom(par1DamageSource, par2);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void damageEntity(DamageSource par1DamageSource, float par2) {
|
||||
super.damageEntity(par1DamageSource, par2);
|
||||
if(par1DamageSource.getEntity() != null) {
|
||||
|
||||
Entity attacker = par1DamageSource.getEntity();
|
||||
if(attacker != null) {
|
||||
Vector3 thisVector = Vector3.fromEntityCenter(this);
|
||||
Vector3 playerVector = Vector3.fromEntityCenter(par1DamageSource.getEntity());
|
||||
Vector3 motionVector = thisVector.copy().sub(playerVector).copy().normalize();
|
||||
Vector3 playerVector = Vector3.fromEntityCenter(attacker);
|
||||
Vector3 motionVector = thisVector.copy().sub(playerVector).copy().normalize().multiply(0.75);
|
||||
|
||||
motionX = motionVector.x;
|
||||
motionY = 0.5;
|
||||
motionZ = motionVector.z;
|
||||
if(getHealth() > 0) {
|
||||
motionX = -motionVector.x;
|
||||
motionY = 0.5;
|
||||
motionZ = -motionVector.z;
|
||||
setTPDelay(4);
|
||||
spawnPixies = isAggored();
|
||||
}
|
||||
|
||||
setAggroed(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(8.0D);
|
||||
getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.4);
|
||||
getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(MAX_HP);
|
||||
getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setBaseValue(1.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLivingUpdate() {
|
||||
super.onLivingUpdate();
|
||||
ChunkCoordinates source = getSource();
|
||||
|
||||
float range = 32F;
|
||||
List<EntityPlayer> players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(source.posX + 0.5 - range, source.posY + 0.5 - range, source.posZ + 0.5 - range, source.posX + 0.5 + range, source.posY + 0.5 + range, source.posZ + 0.5 + range));
|
||||
|
||||
range = 12F;
|
||||
List<EntityPlayer> playersInside = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(source.posX + 0.5 - range, source.posY + 0.5 - range, source.posZ + 0.5 - range, source.posX + 0.5 + range, source.posY + 0.5 + range, source.posZ + 0.5 + range));
|
||||
|
||||
if(players.isEmpty())
|
||||
setDead();
|
||||
else for(EntityPlayer player : players) {
|
||||
List<PotionEffect> remove = new ArrayList();
|
||||
Collection<PotionEffect> active = player.getActivePotionEffects();
|
||||
for(PotionEffect effect : active)
|
||||
if(effect.getDuration() < 200 && !ReflectionHelper.<Boolean, Potion>getPrivateValue(Potion.class, Potion.potionTypes[effect.getPotionID()], LibObfuscation.IS_BAD_EFFECT))
|
||||
remove.add(effect);
|
||||
|
||||
active.removeAll(remove);
|
||||
|
||||
if(!playersInside.contains(player)) {
|
||||
Vector3 sourceVector = new Vector3(source.posX + 0.5, source.posY + 0.5, source.posZ + 0.5);
|
||||
Vector3 playerVector = Vector3.fromEntityCenter(player);
|
||||
Vector3 motion = sourceVector.copy().sub(playerVector).copy().normalize();
|
||||
|
||||
player.motionX = motion.x;
|
||||
player.motionY = 0.2;
|
||||
player.motionZ = motion.z;
|
||||
}
|
||||
}
|
||||
|
||||
if(isDead)
|
||||
return;
|
||||
|
||||
int invul = getInvulTime();
|
||||
if(invul > 0) {
|
||||
if(invul < SPAWN_TICKS && invul > SPAWN_TICKS / 2 && worldObj.rand.nextInt(SPAWN_TICKS - invul + 1) == 0)
|
||||
@@ -115,6 +235,112 @@ public class EntityDoppleganger extends EntityLiving implements IBossDisplayData
|
||||
setHealth(getHealth() + ((MAX_HP - 1F) / SPAWN_TICKS));
|
||||
setInvulTime(invul - 1);
|
||||
motionY = 0;
|
||||
} else {
|
||||
if(isAggored()) {
|
||||
if(getTPDelay() > 0) {
|
||||
setTPDelay(getTPDelay() - 1);
|
||||
if(getTPDelay() == 0 && getHealth() > 0) {
|
||||
while(!teleportRandomly());
|
||||
if(spawnLandmines && !worldObj.isRemote)
|
||||
for(int i = 0; i < 6; i++) {
|
||||
int x = source.posX - 10 + rand.nextInt(20);
|
||||
int z = source.posZ - 10 + rand.nextInt(20);
|
||||
int y = worldObj.getTopSolidOrLiquidBlock(x, z);
|
||||
|
||||
EntityMagicLandmine landmine = new EntityMagicLandmine(worldObj);
|
||||
landmine.setPosition(x + 0.5, y, z + 0.5);
|
||||
landmine.summoner = this;
|
||||
worldObj.spawnEntityInWorld(landmine);
|
||||
}
|
||||
|
||||
if(!worldObj.isRemote)
|
||||
for(int i = 0; i < (spawnPixies ? worldObj.rand.nextInt(3) : 1); i++) {
|
||||
EntityPixie pixie = new EntityPixie(worldObj);
|
||||
pixie.setProps(players.get(rand.nextInt(players.size())), this, 1, 6);
|
||||
pixie.setPosition(posX + width / 2, posY + 2, posZ + width / 2);
|
||||
worldObj.spawnEntityInWorld(pixie);
|
||||
}
|
||||
|
||||
setTPDelay(50);
|
||||
spawnLandmines = true;
|
||||
spawnPixies = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
range = 3F;
|
||||
players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(posX - range, posY - range, posZ - range, posX + range, posY + range, posZ + range));
|
||||
if(!players.isEmpty())
|
||||
damageEntity(DamageSource.causePlayerDamage(players.get(0)), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enderman code
|
||||
protected boolean teleportRandomly() {
|
||||
double d0 = this.posX + (this.rand.nextDouble() - 0.5D) * 64.0D;
|
||||
double d1 = this.posY + (double)(this.rand.nextInt(64) - 32);
|
||||
double d2 = this.posZ + (this.rand.nextDouble() - 0.5D) * 64.0D;
|
||||
return this.teleportTo(d0, d1, d2);
|
||||
}
|
||||
|
||||
protected boolean teleportTo(double par1, double par3, double par5) {
|
||||
double d3 = this.posX;
|
||||
double d4 = this.posY;
|
||||
double d5 = this.posZ;
|
||||
this.posX = par1;
|
||||
this.posY = par3;
|
||||
this.posZ = par5;
|
||||
boolean flag = false;
|
||||
int i = MathHelper.floor_double(this.posX);
|
||||
int j = MathHelper.floor_double(this.posY);
|
||||
int k = MathHelper.floor_double(this.posZ);
|
||||
|
||||
if(this.worldObj.blockExists(i, j, k)) {
|
||||
boolean flag1 = false;
|
||||
|
||||
while(!flag1 && j > 0) {
|
||||
Block block = this.worldObj.getBlock(i, j - 1, k);
|
||||
|
||||
if(block.getMaterial().blocksMovement())
|
||||
flag1 = true;
|
||||
else {
|
||||
--this.posY;
|
||||
--j;
|
||||
}
|
||||
}
|
||||
|
||||
if(flag1) {
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
|
||||
if(this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox))
|
||||
flag = true;
|
||||
|
||||
ChunkCoordinates source = getSource();
|
||||
if(vazkii.botania.common.core.helper.MathHelper.pointDistanceSpace(posX, posY, posZ, source.posX, source.posY, source.posZ) > 15)
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
this.setPosition(d3, d4, d5);
|
||||
return false;
|
||||
} else {
|
||||
short short1 = 128;
|
||||
|
||||
for(int l = 0; l < short1; ++l) {
|
||||
double d6 = (double)l / ((double)short1 - 1.0D);
|
||||
float f = (this.rand.nextFloat() - 0.5F) * 0.2F;
|
||||
float f1 = (this.rand.nextFloat() - 0.5F) * 0.2F;
|
||||
float f2 = (this.rand.nextFloat() - 0.5F) * 0.2F;
|
||||
double d7 = d3 + (this.posX - d3) * d6 + (this.rand.nextDouble() - 0.5D) * (double)this.width * 2.0D;
|
||||
double d8 = d4 + (this.posY - d4) * d6 + this.rand.nextDouble() * (double)this.height;
|
||||
double d9 = d5 + (this.posZ - d5) * d6 + (this.rand.nextDouble() - 0.5D) * (double)this.width * 2.0D;
|
||||
this.worldObj.spawnParticle("portal", d7, d8, d9, (double)f, (double)f1, (double)f2);
|
||||
}
|
||||
|
||||
this.worldObj.playSoundEffect(d3, d4, d5, "mob.endermen.portal", 1.0F, 1.0F);
|
||||
this.playSound("mob.endermen.portal", 1.0F, 1.0F);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* This class was created by <Vazkii>. It's distributed as
|
||||
* part of the Botania Mod. Get the Source Code in github:
|
||||
* https://github.com/Vazkii/Botania
|
||||
*
|
||||
* Botania is Open Source and distributed under a
|
||||
* Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License
|
||||
* (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB)
|
||||
*
|
||||
* File Created @ [Jul 12, 2014, 7:59:00 PM (GMT)]
|
||||
*/
|
||||
package vazkii.botania.common.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
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.world.World;
|
||||
import vazkii.botania.common.Botania;
|
||||
|
||||
public class EntityMagicLandmine extends Entity {
|
||||
|
||||
public EntityDoppleganger summoner;
|
||||
|
||||
public EntityMagicLandmine(World par1World) {
|
||||
super(par1World);
|
||||
setSize(0F, 0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
motionX = 0;
|
||||
motionY = 0;
|
||||
motionZ = 0;
|
||||
super.onUpdate();
|
||||
|
||||
float range = 2.5F;
|
||||
|
||||
float r = 0.2F;
|
||||
float g = 0F;
|
||||
float b = 0.2F;
|
||||
|
||||
Botania.proxy.wispFX(worldObj, posX, posY, posZ, r, g, b, 0.6F, -0.2F, 1);
|
||||
for(int i = 0; i < 4; i++)
|
||||
Botania.proxy.wispFX(worldObj, posX - range + Math.random() * range * 2, posY, posZ - range + Math.random() * range * 2, r, g, b, 0.4F, -0.06F, 1);
|
||||
|
||||
if(ticksExisted >= 45) {
|
||||
worldObj.playSoundEffect(posX, posY, posZ, "random.explode", 0.6F, (1F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.2F) * 1.4F);
|
||||
|
||||
float m = 0.35F;
|
||||
g = 0.4F;
|
||||
for(int i = 0; i < 25; i++)
|
||||
Botania.proxy.wispFX(worldObj, posX, posY + 5, posZ, r, g, b, 0.5F, (float) (Math.random() - 0.5F) * m, (float) (Math.random() - 0.5F) * m, (float) (Math.random() - 0.5F) * m);
|
||||
|
||||
if(!worldObj.isRemote) {
|
||||
List<EntityPlayer> players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(posX - range, posY - range, posZ - range, posX + range, posY + range, posZ + range));
|
||||
for(EntityPlayer player : players) {
|
||||
player.attackEntityFrom(summoner == null ? DamageSource.generic : DamageSource.causeMobDamage(summoner), 8);
|
||||
player.addPotionEffect(new PotionEffect(Potion.blindness.id, 80, 0));
|
||||
player.addPotionEffect(new PotionEffect(Potion.wither.id, 60, 3));
|
||||
}
|
||||
}
|
||||
|
||||
setDead();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readEntityFromNBT(NBTTagCompound var1) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeEntityToNBT(NBTTagCompound var1) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
package vazkii.botania.common.entity;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.world.World;
|
||||
@@ -19,18 +20,40 @@ import vazkii.botania.common.Botania;
|
||||
|
||||
public class EntityPixie extends EntityFlyingCreature {
|
||||
|
||||
EntityPlayer player = null;
|
||||
EntityLivingBase summoner = null;
|
||||
float damage = 0;
|
||||
|
||||
public EntityPixie(World world) {
|
||||
super(world);
|
||||
setSize(1.0F, 1.0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
dataWatcher.addObject(20, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(2.0);
|
||||
}
|
||||
|
||||
public void setProps(EntityLivingBase target, EntityPlayer player, float damage) {
|
||||
|
||||
public void setType(int type) {
|
||||
dataWatcher.updateObject(20, type);
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return dataWatcher.getWatchableObjectInt(20);
|
||||
}
|
||||
|
||||
public void setProps(EntityLivingBase target, EntityLivingBase summoner, int type, float damage) {
|
||||
setAttackTarget(target);
|
||||
this.player = player;
|
||||
this.summoner = summoner;
|
||||
this.damage = damage;
|
||||
setType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,14 +66,22 @@ public class EntityPixie extends EntityFlyingCreature {
|
||||
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
|
||||
|
||||
float mod = 0.45F;
|
||||
if(getType() == 1)
|
||||
mod = 0.1F;
|
||||
|
||||
motionX += d0 / d3 * mod;
|
||||
motionY += d1 / d3 * mod;
|
||||
motionZ += d2 / d3 * mod;
|
||||
|
||||
if(Math.sqrt(d3) < 1F) {
|
||||
if(player != null)
|
||||
target.attackEntityFrom(DamageSource.causePlayerDamage(player), damage);
|
||||
else target.attackEntityFrom(DamageSource.causeMobDamage(this), damage);
|
||||
if(summoner != null) {
|
||||
if(summoner instanceof EntityPlayer)
|
||||
target.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer) summoner), damage);
|
||||
else {
|
||||
target.attackEntityFrom(DamageSource.causeMobDamage(summoner), damage);
|
||||
System.out.println(target + " " + damage);
|
||||
}
|
||||
} else target.attackEntityFrom(DamageSource.causeMobDamage(this), damage);
|
||||
die();
|
||||
}
|
||||
}
|
||||
@@ -65,15 +96,16 @@ public class EntityPixie extends EntityFlyingCreature {
|
||||
if(getAttackTarget() == null && ticksExisted > 100)
|
||||
die();
|
||||
|
||||
boolean dark = getType() == 1;
|
||||
if(worldObj.isRemote)
|
||||
for(int i = 0; i < 4; i++)
|
||||
Botania.proxy.sparkleFX(worldObj, posX + (Math.random() - 0.5) * 0.25, posY + 0.5 + (Math.random() - 0.5) * 0.25, posZ + (Math.random() - 0.5) * 0.25, 1F, 0.25F, 0.9F, 0.1F + (float) Math.random() * 0.25F, 12);
|
||||
Botania.proxy.sparkleFX(worldObj, posX + (Math.random() - 0.5) * 0.25, posY + 0.5 + (Math.random() - 0.5) * 0.25, posZ + (Math.random() - 0.5) * 0.25, dark ? 0.1F : 1F, dark ? 0.025F : 0.25F, dark ? 0.09F : 0.9F, 0.1F + (float) Math.random() * 0.25F, 12);
|
||||
}
|
||||
|
||||
public void die() {
|
||||
setDead();
|
||||
|
||||
if(worldObj.isRemote)
|
||||
if(worldObj.isRemote && getType() == 0)
|
||||
for(int i = 0; i < 12; i++)
|
||||
Botania.proxy.sparkleFX(worldObj, posX + (Math.random() - 0.5) * 0.25, posY + 0.5 + (Math.random() - 0.5) * 0.25, posZ + (Math.random() - 0.5) * 0.25, 1F, 0.25F, 0.9F, 1F + (float) Math.random() * 0.25F, 5);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ public final class ModEntities {
|
||||
EntityRegistry.registerModEntity(EntityFlameRing.class, LibEntityNames.FLAME_RING, id++, Botania.instance, 32, 40, false);
|
||||
EntityRegistry.registerModEntity(EntityVineBall.class, LibEntityNames.VINE_BALL, id++, Botania.instance, 64, 10, true);
|
||||
EntityRegistry.registerModEntity(EntityDoppleganger.class, LibEntityNames.DOPPLEGANGER, id++, Botania.instance, 128, 3, true);
|
||||
EntityRegistry.registerModEntity(EntityMagicLandmine.class, LibEntityNames.MAGIC_LANDMINE, id++, Botania.instance, 128, 40, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,19 +42,9 @@ public class ItemManaResource extends ItemMod implements IFlowerComponent, IElve
|
||||
|
||||
@Override
|
||||
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) {
|
||||
if(par1ItemStack.getItemDamage() == 4) {
|
||||
Block block = par3World.getBlock(par4, par5, par6);
|
||||
if(block == Blocks.beacon && !par3World.isRemote) {
|
||||
par1ItemStack.stackSize--;
|
||||
EntityDoppleganger e = new EntityDoppleganger(par3World);
|
||||
e.setPosition(par4 + 0.5, par5 + 3, par6 + 0.5);
|
||||
e.setInvulTime(EntityDoppleganger.SPAWN_TICKS);
|
||||
e.setHealth(1F);
|
||||
par3World.playSoundAtEntity(e, "mob.enderdragon.growl", 10F, 0.1F);
|
||||
par3World.spawnEntityInWorld(e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(par1ItemStack.getItemDamage() == 4)
|
||||
return EntityDoppleganger.spawn(par1ItemStack, par3World, par4, par5, par6);
|
||||
|
||||
return super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,5 +21,6 @@ public final class LibEntityNames {
|
||||
public static final String FLAME_RING = LibResources.PREFIX_MOD + "flameRing";
|
||||
public static final String VINE_BALL = LibResources.PREFIX_MOD + "vineBall";
|
||||
public static final String DOPPLEGANGER = LibResources.PREFIX_MOD + "doppleganger";
|
||||
public static final String MAGIC_LANDMINE = LibResources.PREFIX_MOD + "magicLandmine";
|
||||
|
||||
}
|
||||
@@ -44,5 +44,7 @@ public final class LibObfuscation {
|
||||
|
||||
// EntityPlayer
|
||||
public static final String[] ITEM_IN_USE = new String[] { "itemInUse", "field_71074_e", "f" };
|
||||
|
||||
|
||||
// Potion
|
||||
public static final String[] IS_BAD_EFFECT = new String[] { "isBadEffect", "field_76418_K", "J" };
|
||||
}
|
||||
@@ -166,6 +166,7 @@ entity.Botania.botania:pixie.name=Pixie
|
||||
entity.Botania.botania:flameRing.name=Flame Ring
|
||||
entity.Botania.botania:vineBall.name=Vine Ball
|
||||
entity.Botania.botania:doppleganger.name=Gaia Guardian
|
||||
entity.Botania.botania:magicLandmine.name=Gaia Trap
|
||||
|
||||
# BLOCK NAMES
|
||||
tile.botania:flower0.name=Mystical White Flower
|
||||
|
||||
Reference in new issue
Block a user