parent
541b9cc461
commit
d8e54d4d69
27 changed files with 1621 additions and 1159 deletions
|
@ -30,7 +30,7 @@ public class AIFireballAttack extends EntityAIBase
|
|||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.parentEntity.getNode().getAttackTarget() != null;
|
||||
return this.parentEntity.getAttackTarget() != null;
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
|
@ -45,7 +45,7 @@ public class AIFireballAttack extends EntityAIBase
|
|||
|
||||
public void updateTask()
|
||||
{
|
||||
EntityLiving target = this.parentEntity.getNode().getAttackTarget();
|
||||
EntityLiving target = this.parentEntity.getAttackTarget();
|
||||
// double d0 = 64.0D;
|
||||
|
||||
if (target.getDistanceSqToEntity(this.parentEntity) < this.distance * this.distance && this.parentEntity.canEntityBeSeen(target))
|
||||
|
@ -84,7 +84,7 @@ public class AIFireballAttack extends EntityAIBase
|
|||
world.spawnEntityInWorld(fireball);
|
||||
this.attackTimer = -this.delay * this.parentEntity.getRNG().range(1, 4);
|
||||
}
|
||||
this.parentEntity.getNode().getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f);
|
||||
this.parentEntity.getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f);
|
||||
}
|
||||
else if (this.attackTimer > 0)
|
||||
{
|
||||
|
|
|
@ -166,7 +166,7 @@ public class EntityAIControlledByPlayer extends EntityAIBase
|
|||
|
||||
if (flag && 0 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j, i1, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, i, j + 1, k, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j + 1, i1, j1, k1, l1, false, false, true))
|
||||
{
|
||||
entitycreature.getNode().getJumpHelper().setJumping();
|
||||
entitycreature.getJumpHelper().setJumping();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.DamageSource;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.nbt.NBTTagCompound;
|
||||
|
||||
public interface IEntityLivingNode extends IEntityNode {
|
||||
void update();
|
||||
void updateRenderAngles();
|
||||
void updateLeashedState();
|
||||
void setLeashTag(NBTTagCompound tag);
|
||||
EntityLiving getAttacking();
|
||||
EntityLiving getAttackTarget();
|
||||
void resetCombat();
|
||||
void trackDamage(DamageSource source, int amount);
|
||||
void sendDeathMessage();
|
||||
EntityJumpHelper getJumpHelper();
|
||||
EntityLookHelper getLookHelper();
|
||||
void updateAttacking();
|
||||
void dropExperience();
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public interface IEntityMobNPCNode extends IEntityNPCNode {
|
||||
|
||||
void becomeAngryAt(Entity entity);
|
||||
|
||||
boolean isAngry();
|
||||
|
||||
void setAngerTarget(EntityLiving entity);
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public interface IEntityNPCNode extends IEntityLivingNode {
|
||||
void setCombatTask();
|
||||
boolean canCounter(EntityLiving entity);
|
||||
boolean canAttack(EntityLiving entity);
|
||||
}
|
|
@ -1,10 +1,17 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.DamageSource;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.world.World;
|
||||
|
||||
public interface IEntityNode {
|
||||
void readNbt(NBTTagCompound tag);
|
||||
void writeNbt(NBTTagCompound tag);
|
||||
void setWorld(World world);
|
||||
void update();
|
||||
void updateRenderAngles();
|
||||
void updateLeashedState();
|
||||
void setLeashTag(NBTTagCompound tag);
|
||||
EntityLiving getAttacking();
|
||||
EntityLiving getAttackTarget();
|
||||
void resetCombat();
|
||||
void trackDamage(DamageSource source, int amount);
|
||||
void sendDeathMessage();
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package common.entity;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import common.ai.IEntityLivingNode;
|
||||
import common.ai.IEntityNode;
|
||||
import common.block.Block;
|
||||
import common.block.BlockFence;
|
||||
import common.block.BlockFenceGate;
|
||||
|
@ -47,14 +45,13 @@ import common.world.State;
|
|||
import common.world.World;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public abstract class Entity<T extends IEntityNode>
|
||||
public abstract class Entity
|
||||
{
|
||||
private static final BoundingBox ZERO_AABB = new BoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
|
||||
private static int nextID;
|
||||
|
||||
protected final DataWatcher dataWatcher;
|
||||
protected final Random rand;
|
||||
protected T node;
|
||||
|
||||
private int eid;
|
||||
public World worldObj;
|
||||
|
@ -120,14 +117,6 @@ public abstract class Entity<T extends IEntityNode>
|
|||
public boolean isAirBorne;
|
||||
protected PortalType inPortal;
|
||||
// private boolean invulnerable;
|
||||
|
||||
public T getNode() {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
public void setNode(T node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
|
@ -1141,8 +1130,6 @@ public abstract class Entity<T extends IEntityNode>
|
|||
public void setWorld(World worldIn)
|
||||
{
|
||||
this.worldObj = worldIn;
|
||||
if(this.node != null)
|
||||
this.node.setWorld(worldIn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1536,8 +1523,6 @@ public abstract class Entity<T extends IEntityNode>
|
|||
tagCompund.setBoolean("IgnoreFall", this.ignoreFall);
|
||||
|
||||
this.writeEntityToNBT(tagCompund);
|
||||
if(this.node != null)
|
||||
this.node.writeNbt(tagCompund);
|
||||
|
||||
if (this.vehicle != null && !(this.isPlayer()))
|
||||
{
|
||||
|
@ -1607,8 +1592,6 @@ public abstract class Entity<T extends IEntityNode>
|
|||
// this.setSilent(tagCompund.getBoolean("Silent"));
|
||||
this.ignoreFall = tagCompund.getBoolean("IgnoreFall");
|
||||
this.readEntityFromNBT(tagCompund);
|
||||
if(this.node != null)
|
||||
this.node.readNbt(tagCompund);
|
||||
|
||||
if (this.shouldSetPosAfterLoading())
|
||||
{
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package common.entity.npc;
|
||||
|
||||
import common.ai.EntityAIHurtByTarget;
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class AIHurtByAggressor extends EntityAIHurtByTarget
|
||||
{
|
||||
public AIHurtByAggressor(EntityMobNPC p_i45828_1_)
|
||||
{
|
||||
super(p_i45828_1_, true);
|
||||
}
|
||||
|
||||
protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn)
|
||||
{
|
||||
super.setEntityAttackTarget(creatureIn, entityLivingBaseIn);
|
||||
|
||||
if (creatureIn.getClass() == this.taskOwner.getClass())
|
||||
{
|
||||
((EntityMobNPC)creatureIn).getNode().becomeAngryAt(entityLivingBaseIn);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -108,7 +108,7 @@ public class EntityChaosMarine extends EntityNPC {
|
|||
return 20;
|
||||
}
|
||||
|
||||
public int getAttackSpeed() {
|
||||
protected int getAttackSpeed() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,10 @@ public class EntityGargoyle extends EntityFlyingNPC
|
|||
// this.launchBoxToEntity(target);
|
||||
// }
|
||||
|
||||
public boolean isRangedWeapon(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
// if (this.isEntityInvulnerable(source))
|
||||
|
|
|
@ -1,45 +1,317 @@
|
|||
package common.entity.npc;
|
||||
|
||||
import common.ai.IEntityMobNPCNode;
|
||||
import common.ai.EntityAIHurtByTarget;
|
||||
import common.entity.DamageSource;
|
||||
import common.entity.Entity;
|
||||
import common.entity.attributes.AttributeInstance;
|
||||
import common.entity.attributes.Attributes;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.world.World;
|
||||
|
||||
public abstract class EntityMobNPC<T extends IEntityMobNPCNode> extends EntityNPC<T>
|
||||
public abstract class EntityMobNPC extends EntityNPC
|
||||
{
|
||||
public T getNode() {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
private int angerLevel;
|
||||
// private int randomSoundDelay;
|
||||
private int angerTarget;
|
||||
// private Class<? extends EntityNPC> angerClass;
|
||||
|
||||
public EntityMobNPC(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.targets.addTask(1, new AIHurtByAggressor(this));
|
||||
// this.targets.addTask(2, new AITargetAggressor(this));
|
||||
}
|
||||
|
||||
// public boolean isImmuneToFire()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public void setAttackedBy(EntityLiving livingBase)
|
||||
{
|
||||
super.setAttackedBy(livingBase);
|
||||
|
||||
if (livingBase != null)
|
||||
{
|
||||
this.node.setAngerTarget(livingBase);
|
||||
this.angerTarget = livingBase.getId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// protected void applyEntityAI()
|
||||
// {
|
||||
// this.targets.addTask(1, new EntityMobNPC.AIHurtByAggressor(this));
|
||||
// this.targets.addTask(2, new EntityMobNPC.AITargetAggressor(this));
|
||||
// }
|
||||
|
||||
// protected void applyEntityAttributes()
|
||||
// {
|
||||
// super.applyEntityAttributes();
|
||||
// this.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).setBaseValue(0.0D);
|
||||
// this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D);
|
||||
// this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(5.0D);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Called to update the entity's position/logic.
|
||||
// */
|
||||
// public void onUpdate()
|
||||
// {
|
||||
// super.onUpdate();
|
||||
// }
|
||||
|
||||
protected void updateAITasks()
|
||||
{
|
||||
AttributeInstance iattributeinstance = this.getEntityAttribute(Attributes.MOVEMENT_SPEED);
|
||||
|
||||
if (this.isAngry())
|
||||
{
|
||||
if (/* !this.isChild() && */ !iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD))
|
||||
{
|
||||
iattributeinstance.applyModifier(Attributes.RUSHING_SPEED_MOD);
|
||||
}
|
||||
|
||||
--this.angerLevel;
|
||||
}
|
||||
else if (iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD))
|
||||
{
|
||||
iattributeinstance.removeModifier(Attributes.RUSHING_SPEED_MOD);
|
||||
}
|
||||
|
||||
// if (this.randomSoundDelay > 0 && --this.randomSoundDelay == 0)
|
||||
// {
|
||||
// this.playSound("mob.zombiepig.zpigangry", this.getSoundVolume() * 2.0F, ((this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F) * 1.8F);
|
||||
// }
|
||||
|
||||
if (this.angerLevel > 0 && this.angerTarget != 0 && this.getAttackedBy() == null)
|
||||
{
|
||||
Entity entity = this.worldObj.getEntityByID(this.angerTarget);
|
||||
if(entity instanceof EntityLiving)
|
||||
this.setAttackedBy((EntityLiving)entity);
|
||||
if(entity != null && entity.isPlayer())
|
||||
this.playerAttacker = (EntityNPC)entity;
|
||||
this.recentlyHit = this.getAttackedTime();
|
||||
}
|
||||
|
||||
super.updateAITasks();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Checks if the entity's current position is a valid location to spawn this entity.
|
||||
// */
|
||||
// public boolean getCanSpawnHere()
|
||||
// {
|
||||
// return this.worldObj.getDifficulty() != Difficulty.PEACEFUL;
|
||||
// }
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setShort("Anger", (short)this.angerLevel);
|
||||
|
||||
// if (this.angerTarget != null)
|
||||
// {
|
||||
// tagCompound.setString("HurtBy", this.angerTarget);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// tagCompound.setString("HurtBy", "");
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.angerLevel = tagCompund.getShort("Anger");
|
||||
// String s = tagCompund.getString("HurtBy");
|
||||
//
|
||||
// if (s.length() > 0)
|
||||
// {
|
||||
// this.angerTarget = s;
|
||||
// EntityNPC entityplayer = this.worldObj.getPlayer(this.angerTarget);
|
||||
// this.setAttackedBy(entityplayer);
|
||||
//
|
||||
// if (entityplayer != null)
|
||||
// {
|
||||
// this.playerAttacker = entityplayer;
|
||||
// this.recentlyHit = this.getAttackedTime();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
// if (this.isEntityInvulnerable(source))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
Entity entity = source.getEntity();
|
||||
|
||||
if (entity != null && entity instanceof EntityNPC)
|
||||
{
|
||||
this.node.becomeAngryAt(entity);
|
||||
this.becomeAngryAt(entity);
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(source, amount);
|
||||
// }
|
||||
}
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return this.node.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz);
|
||||
/**
|
||||
* Causes this PigZombie to become angry at the supplied Entity (which will be a player).
|
||||
*/
|
||||
private void becomeAngryAt(Entity p_70835_1_)
|
||||
{
|
||||
this.angerLevel = this.rand.excl(400, 800);
|
||||
// this.randomSoundDelay = this.rand.zrange(40);
|
||||
|
||||
if (p_70835_1_ instanceof EntityLiving)
|
||||
{
|
||||
this.setAttackedBy((EntityLiving)p_70835_1_);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAngry()
|
||||
{
|
||||
return this.angerLevel > 0;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns the sound this mob makes while it's alive.
|
||||
// */
|
||||
// protected String getLivingSound()
|
||||
// {
|
||||
// return "mob.zombiepig.zpig";
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the sound this mob makes when it is hurt.
|
||||
// */
|
||||
// protected String getHurtSound()
|
||||
// {
|
||||
// return "mob.zombiepig.zpighurt";
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the sound this mob makes on death.
|
||||
// */
|
||||
// protected String getDeathSound()
|
||||
// {
|
||||
// return "mob.zombiepig.zpigdeath";
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Drop 0-2 items of this living's type
|
||||
// *
|
||||
// * @param wasRecentlyHit true if this this entity was recently hit by appropriate entity (generally only if player
|
||||
// * or tameable)
|
||||
// * @param lootingModifier level of enchanment to be applied to this drop
|
||||
// */
|
||||
// protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier)
|
||||
// {
|
||||
// int i = this.rand.zrange(2 + lootingModifier);
|
||||
//
|
||||
// for (int j = 0; j < i; ++j)
|
||||
// {
|
||||
// this.dropItem(Items.rotten_flesh, 1);
|
||||
// }
|
||||
//
|
||||
// i = this.rand.zrange(2 + lootingModifier);
|
||||
//
|
||||
// for (int k = 0; k < i; ++k)
|
||||
// {
|
||||
// this.dropItem(Items.gold_nugget, 1);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
||||
// */
|
||||
// public boolean interact(EntityNPC player)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Causes this Entity to drop a random item.
|
||||
// */
|
||||
// protected void addRandomDrop()
|
||||
// {
|
||||
// this.dropItem(Items.gold_ingot, 1);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gives armor or weapon for entity based on given DifficultyInstance
|
||||
// */
|
||||
// protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty)
|
||||
// {
|
||||
// this.setItem(0, new ItemStack(Items.golden_sword));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
|
||||
// * when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
|
||||
// */
|
||||
// public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata)
|
||||
// {
|
||||
// super.onInitialSpawn(difficulty, livingdata);
|
||||
//// this.setVillager(false);
|
||||
// return livingdata;
|
||||
// }
|
||||
|
||||
// public int getColor() {
|
||||
// return 0xff9494;
|
||||
// }
|
||||
|
||||
// public void onStruckByLightning(EntityLightning lightningBolt) {
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return this.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz);
|
||||
}
|
||||
|
||||
static class AIHurtByAggressor extends EntityAIHurtByTarget
|
||||
{
|
||||
public AIHurtByAggressor(EntityMobNPC p_i45828_1_)
|
||||
{
|
||||
super(p_i45828_1_, true);
|
||||
}
|
||||
|
||||
protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn)
|
||||
{
|
||||
super.setEntityAttackTarget(creatureIn, entityLivingBaseIn);
|
||||
|
||||
if (creatureIn.getClass() == this.taskOwner.getClass())
|
||||
{
|
||||
((EntityMobNPC)creatureIn).becomeAngryAt(entityLivingBaseIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static class AITargetAggressor extends EntityAINearestAttackableTarget<EntityLiving>
|
||||
// {
|
||||
// public AITargetAggressor(EntityMobNPC p_i45829_1_)
|
||||
// {
|
||||
// super(p_i45829_1_, EntityLiving.class, 10, true, false, new Predicate<EntityLiving>() {
|
||||
// public boolean test(EntityLiving entity) {
|
||||
// return entity.isPlayer(); // || entity instanceof EntityNPC;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// public boolean shouldExecute()
|
||||
// {
|
||||
// return ((EntityMobNPC)this.taskOwner).isAngry() && super.shouldExecute();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -2,8 +2,24 @@ package common.entity.npc;
|
|||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.IClient;
|
||||
import common.ai.IEntityNPCNode;
|
||||
import common.ai.AIRangedAttack;
|
||||
import common.ai.EntityAIAttackOnCollide;
|
||||
import common.ai.EntityAIAvoidEntity;
|
||||
import common.ai.EntityAIHurtByTarget;
|
||||
import common.ai.EntityAILookAtTalkingPlayer;
|
||||
import common.ai.EntityAINagPlayer;
|
||||
import common.ai.EntityAINearestAttackableTarget;
|
||||
import common.ai.EntityAINpcInteract;
|
||||
import common.ai.EntityAINpcMate;
|
||||
import common.ai.EntityAIOpenDoor;
|
||||
import common.ai.EntityAIPlay;
|
||||
import common.ai.EntityAISwimming;
|
||||
import common.ai.EntityAIWander;
|
||||
import common.ai.EntityAIWatchClosest;
|
||||
import common.ai.EntityAIWatchClosest2;
|
||||
import common.block.Block;
|
||||
import common.block.BlockBed;
|
||||
import common.dimension.Space;
|
||||
|
@ -62,6 +78,7 @@ import common.packet.CPacketInput;
|
|||
import common.packet.CPacketPlayer;
|
||||
import common.packet.SPacketEntityEquipment;
|
||||
import common.packet.SPacketEntityVelocity;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.potion.Potion;
|
||||
import common.potion.PotionEffect;
|
||||
import common.rng.Random;
|
||||
|
@ -81,7 +98,7 @@ import common.world.World;
|
|||
import common.world.WorldClient;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public abstract class EntityNPC<T extends IEntityNPCNode> extends EntityLiving<T>
|
||||
public abstract class EntityNPC extends EntityLiving
|
||||
{
|
||||
public static class CharacterTypeData
|
||||
{
|
||||
|
@ -193,10 +210,6 @@ public abstract class EntityNPC<T extends IEntityNPCNode> extends EntityLiving<T
|
|||
private float horseJumpPower;
|
||||
// public float nausea;
|
||||
// public float prevNausea;
|
||||
|
||||
public T getNode() {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
public EntityNPC(World worldIn)
|
||||
{
|
||||
|
@ -247,20 +260,53 @@ public abstract class EntityNPC<T extends IEntityNPCNode> extends EntityLiving<T
|
|||
return this.connection != null || this.gm != null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public final boolean canInfight(Alignment align) {
|
||||
return this.alignment.chaotic || (!this.alignment.lawful &&
|
||||
((this.alignment.good && align.evil) || (this.alignment.evil && align.good)));
|
||||
}
|
||||
|
||||
public final boolean canMurder(Alignment align) {
|
||||
return this.alignment.chaotic && ((this.alignment.good && align.evil) || (this.alignment.evil && align.good));
|
||||
}
|
||||
|
||||
public boolean canCounter(EntityLiving entity) {
|
||||
return !(entity instanceof EntityNPC) ||
|
||||
(this.getClass() == entity.getClass() ? this.canInfight(((EntityNPC)entity).alignment) :
|
||||
!this.isPeaceful(((EntityNPC)entity).getClass()));
|
||||
}
|
||||
|
||||
public boolean canAttack(EntityLiving entity) {
|
||||
return entity instanceof EntityNPC && (this.getClass() == entity.getClass() ? this.canMurder(((EntityNPC)entity).alignment) :
|
||||
this.isAggressive(((EntityNPC)entity).getClass()));
|
||||
}
|
||||
|
||||
public boolean canAmbush(EntityLiving entity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shouldFlee(EntityLiving entity) {
|
||||
return (this.getHealth() <= (this.getMaxHealth() / 4) || !this.canCounter(entity)) &&
|
||||
((entity instanceof EntityNPC && (((EntityNPC)entity).canAttack(this)) ||
|
||||
(entity == this.getAttackedBy() && ((EntityNPC)entity).canCounter(this))));
|
||||
}
|
||||
|
||||
// public void setCombatTask()
|
||||
// {
|
||||
// }
|
||||
|
||||
public boolean isRangedWeapon(ItemStack stack) {
|
||||
return stack != null && (stack.getItem() == Items.bow || stack.getItem() instanceof ItemGunBase ||
|
||||
stack.getItem() == Items.snowball || stack.getItem() == Items.potion);
|
||||
}
|
||||
|
||||
// public boolean isSneaking()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public int getAttackSpeed() {
|
||||
protected int getAttackSpeed() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
|
@ -678,11 +724,6 @@ public abstract class EntityNPC<T extends IEntityNPCNode> extends EntityLiving<T
|
|||
return Alignment.values()[this.dataWatcher.getWatchableObjectByte(18) % Alignment.values().length];
|
||||
}
|
||||
|
||||
public Alignment getAlignmentCached()
|
||||
{
|
||||
return this.alignment;
|
||||
}
|
||||
|
||||
public void setHeight(float height)
|
||||
{
|
||||
this.dataWatcher.updateObject(29, ExtMath.clampf(height, 0.2f, 10.0f));
|
||||
|
|
|
@ -108,7 +108,7 @@ public class EntitySpaceMarine extends EntityNPC {
|
|||
return 20;
|
||||
}
|
||||
|
||||
public int getAttackSpeed() {
|
||||
protected int getAttackSpeed() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.ai.IEntityLivingNode;
|
||||
import common.ai.IEntityNode;
|
||||
import common.block.Block;
|
||||
import common.block.SoundType;
|
||||
import common.collect.Maps;
|
||||
|
@ -57,10 +57,11 @@ import common.world.State;
|
|||
import common.world.World;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T>
|
||||
public abstract class EntityLiving extends Entity
|
||||
{
|
||||
private static final ItemStack[] EMPTY_INV = new ItemStack[5];
|
||||
|
||||
protected IEntityNode node;
|
||||
private AttributeMap attributes;
|
||||
private final Map<Potion, PotionEffect> effects = Maps.<Potion, PotionEffect>newEnumMap(Potion.class);
|
||||
public int soundTimer;
|
||||
|
@ -104,6 +105,13 @@ public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T
|
|||
public int maxHurtTime;
|
||||
public int deathTime;
|
||||
public int hurtCooldown = 20;
|
||||
protected int lastDamage;
|
||||
protected EntityNPC playerAttacker;
|
||||
protected int recentlyHit;
|
||||
private EntityLiving attackedBy;
|
||||
private int lastAttacked;
|
||||
private EntityLiving attacker;
|
||||
private int lastAttackTime;
|
||||
|
||||
// protected int entityAge;
|
||||
private int absorptionAmount;
|
||||
|
@ -120,10 +128,6 @@ public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T
|
|||
protected int growingAge;
|
||||
private float ageWidth = -1.0F;
|
||||
private float ageHeight;
|
||||
|
||||
public T getNode() {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
public EntityLiving(World worldIn)
|
||||
{
|
||||
|
@ -293,9 +297,37 @@ public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T
|
|||
this.onDeathUpdate();
|
||||
}
|
||||
|
||||
if (this.recentlyHit > 0)
|
||||
{
|
||||
--this.recentlyHit;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.playerAttacker = null;
|
||||
}
|
||||
|
||||
if (this.attacker != null && !this.attacker.isEntityAlive())
|
||||
{
|
||||
this.attacker = null;
|
||||
}
|
||||
|
||||
// if(this.attackedBy.isPlayer() && ((EntityNPC)this.attackedBy).capabilities.isCreativeMode) {
|
||||
// this.attackedBy = null; // FIX Creative
|
||||
// }
|
||||
|
||||
if (this.attackedBy != null)
|
||||
{
|
||||
if (!this.attackedBy.isEntityAlive())
|
||||
{
|
||||
this.setAttackedBy(null);
|
||||
}
|
||||
else if (this.ticksExisted - this.lastAttacked > 100)
|
||||
{
|
||||
this.setAttackedBy(null);
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.worldObj.client) {
|
||||
this.node.updateAttacking();
|
||||
|
||||
if(!this.firstEffectUpdate && Config.radiation) { // &&
|
||||
// (!(this.isPlayer()) || !((EntityNPCMP)this).creative)) {
|
||||
float radiation = this.radiation + (float)this.attributes.getAttributeInstance(Attributes.RADIATION).getAttributeValue();
|
||||
|
@ -357,9 +389,16 @@ public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T
|
|||
|
||||
if (this.deathTime == 20)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
if (!this.worldObj.client && (this.recentlyHit > 0 || this.isPlayer()) && this.canDropLoot() && Config.mobXP)
|
||||
{
|
||||
this.node.dropExperience();
|
||||
int i = this.getExperiencePoints(this.playerAttacker);
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
int j = EntityXp.getXPSplit(i);
|
||||
i -= j;
|
||||
this.worldObj.spawnEntityInWorld(new EntityXp(this.worldObj, this.posX, this.posY, this.posZ, j));
|
||||
}
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
|
@ -413,6 +452,46 @@ public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T
|
|||
return this.rand;
|
||||
}
|
||||
|
||||
public EntityLiving getAttackedBy()
|
||||
{
|
||||
return this.attackedBy;
|
||||
}
|
||||
|
||||
public int getAttackedTime()
|
||||
{
|
||||
return this.lastAttacked;
|
||||
}
|
||||
|
||||
public void setAttackedBy(EntityLiving livingBase)
|
||||
{
|
||||
this.attackedBy = livingBase;
|
||||
this.lastAttacked = this.ticksExisted;
|
||||
}
|
||||
|
||||
public EntityLiving getLastAttack()
|
||||
{
|
||||
return this.attacker;
|
||||
}
|
||||
|
||||
public int getLastAttackTime()
|
||||
{
|
||||
return this.lastAttackTime;
|
||||
}
|
||||
|
||||
public void setLastAttack(Entity entity)
|
||||
{
|
||||
if (entity instanceof EntityLiving)
|
||||
{
|
||||
this.attacker = (EntityLiving)entity;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.attacker = null;
|
||||
}
|
||||
|
||||
this.lastAttackTime = this.ticksExisted;
|
||||
}
|
||||
|
||||
// public int getAge()
|
||||
// {
|
||||
// return this.entityAge;
|
||||
|
@ -1257,6 +1336,11 @@ public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T
|
|||
// }
|
||||
}
|
||||
|
||||
public EntityLiving getAttackingEntity()
|
||||
{
|
||||
return (EntityLiving)(this.node.getAttacking() != null ? this.node.getAttacking() : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null)));
|
||||
}
|
||||
|
||||
public final int getMaxHealth()
|
||||
{
|
||||
return (int)this.getEntityAttribute(Attributes.MAX_HEALTH).getAttributeValue();
|
||||
|
|
|
@ -389,12 +389,4 @@ int utf_len(const char *str) {
|
|||
public static double ftime() {
|
||||
return ((double)rtime()) / 1000000.0;
|
||||
}
|
||||
|
||||
public static String getRegionFolder(int x, int z) {
|
||||
return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9);
|
||||
}
|
||||
|
||||
public static String getRegionName(int x, int z) {
|
||||
return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,9 @@ import common.collect.Lists;
|
|||
import common.collect.Maps;
|
||||
import common.entity.Entity;
|
||||
import common.init.BlockRegistry;
|
||||
import common.init.Config;
|
||||
import common.init.EntityRegistry;
|
||||
import common.init.UniverseRegistry;
|
||||
import common.log.Log;
|
||||
import common.nbt.NBTLoader;
|
||||
import common.nbt.NBTTagCompound;
|
||||
|
@ -31,9 +33,39 @@ import common.tileentity.TileEntity;
|
|||
import common.util.BlockPos;
|
||||
import common.util.NextTickListEntry;
|
||||
import common.util.NibbleArray;
|
||||
import common.util.Util;
|
||||
|
||||
public class Region {
|
||||
public static enum SaveVersion {
|
||||
ALPHA_1_0("Alpha 1.0 - Beta 1.2"),
|
||||
BETA_1_3("Beta 1.3 - Release 1.8.9"),
|
||||
RELEASE_1_9("Release 1.9 - Release 1.12.2"),
|
||||
RELEASE_1_13("Release 1.13 +");
|
||||
|
||||
private final String name;
|
||||
|
||||
private SaveVersion(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FolderInfo {
|
||||
public final long time;
|
||||
public final long lastPlayed;
|
||||
public final SaveVersion legacy;
|
||||
public final String version;
|
||||
|
||||
public FolderInfo(long time, long lastPlayed, SaveVersion legacy, String version) {
|
||||
this.time = time;
|
||||
this.lastPlayed = lastPlayed;
|
||||
this.legacy = legacy;
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ChunkBuffer extends ByteArrayOutputStream {
|
||||
public ChunkBuffer() {
|
||||
super(8096);
|
||||
|
@ -58,7 +90,10 @@ public class Region {
|
|||
|
||||
private static final Map<String, Region> CACHE = Maps.<String, Region>newHashMap();
|
||||
private static final List<WorldServer> QUEUE = Collections.<WorldServer>synchronizedList(Lists.<WorldServer>newArrayList());
|
||||
|
||||
|
||||
// public static long lastPlayed;
|
||||
// public static int version;
|
||||
// public static String owner;
|
||||
private static volatile long queued;
|
||||
private static volatile long saved;
|
||||
private static volatile boolean waiting;
|
||||
|
@ -78,10 +113,10 @@ public class Region {
|
|||
private boolean modified;
|
||||
|
||||
public Region(File dir, int x, int z) {
|
||||
File sdir = new File(dir, Util.getRegionFolder(x << 3, z << 3));
|
||||
File sdir = new File(dir, getRegionFolder(x << 3, z << 3));
|
||||
if(!sdir.exists())
|
||||
sdir.mkdirs();
|
||||
this.regFile = new File(sdir, Util.getRegionName(x << 3, z << 3));
|
||||
this.regFile = new File(sdir, getRegionName(x << 3, z << 3));
|
||||
this.folder = dir;
|
||||
this.xPos = x;
|
||||
this.zPos = z;
|
||||
|
@ -278,6 +313,13 @@ public class Region {
|
|||
this.write(x, z, buf.getData(), buf.size());
|
||||
}
|
||||
|
||||
// public NBTTagCompound readTag(int x, int z) throws IOException {
|
||||
// byte[] data = this.read(x, z);
|
||||
// if(data == null)
|
||||
// return null;
|
||||
// return CompressedStreamTools.read(new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(data)))));
|
||||
// }
|
||||
|
||||
public File getFile() {
|
||||
return this.regFile;
|
||||
}
|
||||
|
@ -294,7 +336,7 @@ public class Region {
|
|||
}
|
||||
|
||||
private static File getExpansionFile(File dir, int x, int z) {
|
||||
File sdir = new File(dir, Util.getRegionFolder(x, z));
|
||||
File sdir = new File(dir, getRegionFolder(x, z));
|
||||
if(!sdir.exists())
|
||||
sdir.mkdirs();
|
||||
return new File(sdir, String.format("c.%c%X%c%X.chk", x < 0 ? 'n' : 'p', (x < 0) ? -x : x, z < 0 ? 'n' : 'p', (z < 0) ? -z : z));
|
||||
|
@ -357,6 +399,14 @@ public class Region {
|
|||
// getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag);
|
||||
}
|
||||
|
||||
public static String getRegionFolder(int x, int z) {
|
||||
return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9);
|
||||
}
|
||||
|
||||
public static String getRegionName(int x, int z) {
|
||||
return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3);
|
||||
}
|
||||
|
||||
public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) {
|
||||
// if(!tag.hasKey("Level", 10)) {
|
||||
// Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe");
|
||||
|
@ -630,4 +680,93 @@ public class Region {
|
|||
public static void killIO() {
|
||||
killed = true;
|
||||
}
|
||||
|
||||
public static void saveWorldInfo(File worldDir, long time) {
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
data.setLong("Time", time);
|
||||
data.setLong("LastAccess", System.currentTimeMillis());
|
||||
data.setString("Version", Config.VERSION);
|
||||
NBTTagCompound cfg = new NBTTagCompound();
|
||||
for(String cvar : Config.VARS.keySet()) {
|
||||
cfg.setString(cvar, Config.VARS.get(cvar).getValue());
|
||||
// Config.Value value = Config.VARS.get(cvar);
|
||||
// switch(value.getType()) {
|
||||
// case BOOLEAN:
|
||||
// cfg.setString(cvar, "" + value.getBoolean());
|
||||
// break;
|
||||
// case INTEGER:
|
||||
// cfg.setString(cvar, "" + value.getInt());
|
||||
// break;
|
||||
// case FLOAT:
|
||||
// cfg.setString(cvar, "" + value.getFloat());
|
||||
// break;
|
||||
// case STRING:
|
||||
// cfg.setString(cvar, value.getString());
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
data.setTag("Config", cfg);
|
||||
data.setTag("Universe", UniverseRegistry.saveNbt());
|
||||
if(worldDir != null)
|
||||
worldDir.mkdirs();
|
||||
File nfile = new File(worldDir, "level.nbt.tmp");
|
||||
File lfile = new File(worldDir, "level.nbt");
|
||||
try {
|
||||
// File ofile = new File(worldDir, "level.nbt_old");
|
||||
NBTLoader.writeGZip(data, nfile);
|
||||
// if(ofile.exists())
|
||||
// ofile.delete();
|
||||
// lfile.renameTo(ofile);
|
||||
if(lfile.exists())
|
||||
lfile.delete();
|
||||
nfile.renameTo(lfile);
|
||||
// if(nfile.exists())
|
||||
// nfile.delete();
|
||||
}
|
||||
catch(Exception e) {
|
||||
Log.JNI.error(e, "Fehler beim Schreiben von " + nfile);
|
||||
}
|
||||
}
|
||||
|
||||
public static FolderInfo loadWorldInfo(File worldDir) {
|
||||
Config.clear();
|
||||
UniverseRegistry.clear();
|
||||
File file = new File(worldDir, "level.nbt");
|
||||
if(!file.exists())
|
||||
file = new File(worldDir, "level.nbt.tmp");
|
||||
if(file.exists()) {
|
||||
try {
|
||||
NBTTagCompound tag = NBTLoader.readGZip(file);
|
||||
NBTTagCompound cfg = tag.getCompoundTag("Config");
|
||||
for(String key : cfg.getKeySet()) {
|
||||
Config.set(key, cfg.getString(key), null);
|
||||
}
|
||||
UniverseRegistry.loadNbt(tag.getCompoundTag("Universe"));
|
||||
// tag.getInteger("Version");
|
||||
long lastPlayed = tag.getLong("LastAccess");
|
||||
String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null;
|
||||
version = version != null && version.isEmpty() ? null : version;
|
||||
long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME;
|
||||
return new FolderInfo(time, lastPlayed, null, version);
|
||||
}
|
||||
catch(Exception e) {
|
||||
Log.JNI.error(e, "Fehler beim Lesen von " + file);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// public static void reloadWorldInfo(File worldDir) {
|
||||
// File file = new File(worldDir, "level.nbt");
|
||||
// if(file.exists()) {
|
||||
// Config.clear();
|
||||
// try {
|
||||
// Config.readFromNbt(NBTLoader.readGZip(file).getCompoundTag("Config"), true);
|
||||
// }
|
||||
// catch(Exception e) {
|
||||
// Log.error("Fehler beim Lesen von " + file, e);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -962,7 +962,6 @@ public final class WorldServer extends World {
|
|||
}
|
||||
|
||||
protected void onEntityAdded(Entity entityIn) {
|
||||
// TODO: add node
|
||||
this.trackEntity(entityIn);
|
||||
this.entityIds.addKey(entityIn.getId(), entityIn);
|
||||
Entity[] aentity = entityIn.getParts();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue