mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
255 lines
7.0 KiB
Java
255 lines
7.0 KiB
Java
package com.hbm.entity.mob;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
import com.hbm.config.MobConfig;
|
|
import com.hbm.entity.pathfinder.PathFinderUtils;
|
|
import com.hbm.handler.pollution.PollutionHandler;
|
|
import com.hbm.handler.pollution.PollutionHandler.PollutionType;
|
|
import com.hbm.items.ModItems;
|
|
import com.hbm.lib.ModDamageSource;
|
|
import com.hbm.main.ResourceManager;
|
|
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.EnumCreatureAttribute;
|
|
import net.minecraft.entity.SharedMonsterAttributes;
|
|
import net.minecraft.entity.monster.EntityMob;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.potion.Potion;
|
|
import net.minecraft.util.DamageSource;
|
|
import net.minecraft.util.ResourceLocation;
|
|
import net.minecraft.world.World;
|
|
|
|
public class EntityGlyphid extends EntityMob {
|
|
|
|
public EntityGlyphid(World world) {
|
|
super(world);
|
|
/*this.tasks.addTask(0, new EntityAISwimming(this));
|
|
this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false));
|
|
this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D));
|
|
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
|
|
this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
|
|
this.tasks.addTask(8, new EntityAILookIdle(this));
|
|
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
|
|
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));*/
|
|
this.setSize(1.75F, 1F);
|
|
}
|
|
|
|
public ResourceLocation getSkin() {
|
|
return ResourceManager.glyphid_tex;
|
|
}
|
|
|
|
public double getScale() {
|
|
return 1.0D;
|
|
}
|
|
|
|
@Override
|
|
protected void entityInit() {
|
|
super.entityInit();
|
|
this.dataWatcher.addObject(16, new Byte((byte) 0)); //wall climbing
|
|
this.dataWatcher.addObject(17, new Byte((byte) 0b11111)); //armor
|
|
}
|
|
|
|
@Override
|
|
protected void applyEntityAttributes() {
|
|
super.applyEntityAttributes();
|
|
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30D);
|
|
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1D);
|
|
this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5D);
|
|
}
|
|
|
|
@Override
|
|
protected void dropFewItems(boolean byPlayer, int looting) {
|
|
if(rand.nextInt(3) == 0) this.entityDropItem(new ItemStack(ModItems.glyphid_meat, 1 + rand.nextInt(2) + looting), 0F);
|
|
}
|
|
|
|
@Override
|
|
protected Entity findPlayerToAttack() {
|
|
if(this.isPotionActive(Potion.blindness)) return null;
|
|
EntityPlayer entityplayer = this.worldObj.getClosestVulnerablePlayerToEntity(this, useExtendedTargeting() ? 128D : 16D);
|
|
return entityplayer != null && this.canEntityBeSeen(entityplayer) ? entityplayer : null;
|
|
}
|
|
|
|
@Override
|
|
protected void updateEntityActionState() {
|
|
super.updateEntityActionState();
|
|
|
|
if(this.isPotionActive(Potion.blindness)) {
|
|
this.entityToAttack = null;
|
|
this.setPathToEntity(null);
|
|
} else {
|
|
|
|
// hell yeah!!
|
|
if(useExtendedTargeting() && this.entityToAttack != null && !this.hasPath()) {
|
|
this.setPathToEntity(PathFinderUtils.getPathEntityToEntityPartial(worldObj, this, this.entityToAttack, 16F, true, false, false, true));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public boolean useExtendedTargeting() {
|
|
return PollutionHandler.getPollution(worldObj, (int) Math.floor(posX), (int) Math.floor(posY), (int) Math.floor(posZ), PollutionType.SOOT) >= MobConfig.targetingThreshold;
|
|
}
|
|
|
|
@Override
|
|
protected boolean canDespawn() {
|
|
return entityToAttack == null;
|
|
}
|
|
|
|
@Override
|
|
public boolean attackEntityFrom(DamageSource source, float amount) {
|
|
|
|
if(!source.isDamageAbsolute() && !source.isUnblockable() && !worldObj.isRemote && !source.isFireDamage() && !source.getDamageType().equals(ModDamageSource.s_cryolator)) {
|
|
byte armor = this.dataWatcher.getWatchableObjectByte(17);
|
|
|
|
if(armor != 0) { //if at least one bit of armor is present
|
|
|
|
if(amount < getDamageThreshold()) return false;
|
|
|
|
int chance = getArmorBreakChance(amount); //chances of armor being broken off
|
|
if(this.rand.nextInt(chance) == 0 && amount > 1) {
|
|
breakOffArmor();
|
|
amount *= 0.25F;
|
|
}
|
|
|
|
amount -= getDamageThreshold();
|
|
if(amount < 0) return true;
|
|
}
|
|
|
|
amount = this.calculateDamage(amount);
|
|
}
|
|
|
|
if(source.isFireDamage()) amount *= 4F;
|
|
|
|
return super.attackEntityFrom(source, amount);
|
|
}
|
|
|
|
public int getArmorBreakChance(float amount) {
|
|
return amount < 10 ? 5 : amount < 20 ? 3 : 2;
|
|
}
|
|
|
|
public float calculateDamage(float amount) {
|
|
|
|
byte armor = this.dataWatcher.getWatchableObjectByte(17);
|
|
int divisor = 1;
|
|
|
|
for(int i = 0; i < 5; i++) {
|
|
if((armor & (1 << i)) > 0) {
|
|
divisor++;
|
|
}
|
|
}
|
|
|
|
amount /= divisor;
|
|
|
|
return amount;
|
|
}
|
|
|
|
public float getDamageThreshold() {
|
|
return 0.5F;
|
|
}
|
|
|
|
public void breakOffArmor() {
|
|
byte armor = this.dataWatcher.getWatchableObjectByte(17);
|
|
List<Integer> indices = Arrays.asList(0, 1, 2, 3, 4);
|
|
Collections.shuffle(indices);
|
|
|
|
for(Integer i : indices) {
|
|
byte bit = (byte) (1 << i);
|
|
if((armor & bit) > 0) {
|
|
armor &= ~bit;
|
|
armor = (byte) (armor & 0b11111);
|
|
this.dataWatcher.updateObject(17, armor);
|
|
worldObj.playSoundAtEntity(this, "mob.zombie.woodbreak", 1.0F, 1.25F);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean attackEntityAsMob(Entity victum) {
|
|
if(this.isSwingInProgress) return false;
|
|
this.swingItem();
|
|
return super.attackEntityAsMob(victum);
|
|
}
|
|
|
|
@Override
|
|
public void onUpdate() {
|
|
super.onUpdate();
|
|
|
|
if(!this.worldObj.isRemote) {
|
|
this.setBesideClimbableBlock(this.isCollidedHorizontally);
|
|
|
|
if(worldObj.getTotalWorldTime() % 200 == 0) {
|
|
this.swingItem();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void updateArmSwingProgress() {
|
|
int i = this.swingDuration();
|
|
|
|
if(this.isSwingInProgress) {
|
|
++this.swingProgressInt;
|
|
|
|
if(this.swingProgressInt >= i) {
|
|
this.swingProgressInt = 0;
|
|
this.isSwingInProgress = false;
|
|
}
|
|
} else {
|
|
this.swingProgressInt = 0;
|
|
}
|
|
|
|
this.swingProgress = (float) this.swingProgressInt / (float) i;
|
|
}
|
|
|
|
public int swingDuration() {
|
|
return 15;
|
|
}
|
|
|
|
@Override
|
|
public void setInWeb() { }
|
|
|
|
@Override
|
|
public boolean isOnLadder() {
|
|
return this.isBesideClimbableBlock();
|
|
}
|
|
|
|
public boolean isBesideClimbableBlock() {
|
|
return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
|
|
}
|
|
|
|
public void setBesideClimbableBlock(boolean climbable) {
|
|
byte watchable = this.dataWatcher.getWatchableObjectByte(16);
|
|
|
|
if(climbable) {
|
|
watchable = (byte) (watchable | 1);
|
|
} else {
|
|
watchable &= -2;
|
|
}
|
|
|
|
this.dataWatcher.updateObject(16, Byte.valueOf(watchable));
|
|
}
|
|
|
|
@Override
|
|
public EnumCreatureAttribute getCreatureAttribute() {
|
|
return EnumCreatureAttribute.ARTHROPOD;
|
|
}
|
|
|
|
@Override
|
|
public void writeEntityToNBT(NBTTagCompound nbt) {
|
|
super.writeEntityToNBT(nbt);
|
|
nbt.setByte("armor", this.dataWatcher.getWatchableObjectByte(17));
|
|
}
|
|
|
|
@Override
|
|
public void readEntityFromNBT(NBTTagCompound nbt) {
|
|
super.readEntityFromNBT(nbt);
|
|
this.dataWatcher.updateObject(17, nbt.getByte("armor"));
|
|
}
|
|
}
|