initial commit
This commit is contained in:
parent
3c9ee26b06
commit
22186c33b9
1458 changed files with 282792 additions and 0 deletions
249
java/src/game/entity/DamageSource.java
Executable file
249
java/src/game/entity/DamageSource.java
Executable file
|
@ -0,0 +1,249 @@
|
|||
package game.entity;
|
||||
|
||||
import game.color.TextColor;
|
||||
import game.entity.projectile.EntityProjectile;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.world.Explosion;
|
||||
|
||||
public class DamageSource
|
||||
{
|
||||
public static final DamageSource inFire =
|
||||
(new DamageSource(TextColor.ORANGE, "%s ging in Flammen auf", "%s lief ins Feuer, während er mit %s kämpfte", "%s ins Feuer gelaufen")).setFireDamage();
|
||||
public static final DamageSource onFire =
|
||||
(new DamageSource(TextColor.ORANGE, "%s wurde zu heiß und verbrannte", "%s wurde während des Kampfes mit %s geröstet", "%s geröstet")).setDamageBypassesArmor().setFireDamage();
|
||||
public static final DamageSource hotLiquid =
|
||||
(new DamageSource(TextColor.ORANGE, "%s versuchte in einer unangenehm brennenden Flüssigkeit zu schwimmen", "%s fiel beim Versuch %s zu entkommen in eine unangenehm brennende Flüssigkeit", "%s in unangenehm brennender Flüssigkeit gelandet")).setFireDamage();
|
||||
public static final DamageSource molten =
|
||||
(new DamageSource(TextColor.ORANGE, "%s versuchte dem Magmaregen zu trotzen", "%s geriet beim Versuch %s zu entkommen in Magmaregen", "%s in Magmaregen geraten")).setFireDamage();
|
||||
public static final DamageSource inWall =
|
||||
(new DamageSource(TextColor.GRAY, "%s wurde lebendig begraben")).setDamageBypassesArmor();
|
||||
public static final DamageSource dry =
|
||||
(new DamageSource(TextColor.GRAY, "%s ist vertrocknet", "%s ist beim Versuch %s zu entkommen vertrocknet", "%s vertrocknet")).setDamageBypassesArmor();
|
||||
public static final DamageSource cactus =
|
||||
new DamageSource(TextColor.ORK, "%s wurde zu Tode gestochen", "%s rannte beim Versuch %s zu entkommen in einen Kaktus", "%s in Kaktus gerannt");
|
||||
public static final DamageSource fall =
|
||||
(new DamageSource(TextColor.NEON, "%s fiel der Schwerkraft zum Opfer")).setDamageBypassesArmor();
|
||||
public static final DamageSource outOfWorld =
|
||||
(new DamageSource(TextColor.DGRAY, "%s fiel aus der Welt")).setDamageBypassesArmor();
|
||||
public static final DamageSource generic =
|
||||
(new DamageSource(TextColor.LGRAY, "%s starb")).setDamageBypassesArmor();
|
||||
public static final DamageSource magic =
|
||||
(new DamageSource(TextColor.DMAGENTA, "%s wurde durch Magie getötet")).setDamageBypassesArmor().setMagicDamage();
|
||||
public static final DamageSource anvil =
|
||||
new DamageSource(TextColor.DRED, "%s wurde von einem fallenden Amboss zerquetscht");
|
||||
public static final DamageSource fallingBlock =
|
||||
new DamageSource(TextColor.GRAY, "%s wurde von einem fallenden Block zerquetscht");
|
||||
public static final DamageSource radiation =
|
||||
(new DamageSource(TextColor.GREEN, "%s hat seine Halbwertszeit nicht rechtzeitig erreicht")).setDamageBypassesArmor();
|
||||
|
||||
protected final String display;
|
||||
protected final String displayExtra;
|
||||
protected final String displayKill;
|
||||
protected final TextColor color;
|
||||
|
||||
private boolean isUnblockable;
|
||||
private boolean fireDamage;
|
||||
private boolean projectile;
|
||||
private boolean magicDamage;
|
||||
private boolean explosion;
|
||||
|
||||
public static DamageSource causeMobDamage(EntityLiving mob)
|
||||
{
|
||||
return new EntityDamageSource(TextColor.CRIMSON, "%s wurde von %s erschlagen", "%s wurde von %s mit %s erschlagen",
|
||||
"%s erschlagen", "%s mit %s erschlagen", mob);
|
||||
}
|
||||
|
||||
public static DamageSource causeLightningDamage(EntityLiving mob)
|
||||
{
|
||||
return mob == null ? new DamageSource(TextColor.YELLOW, "%s wurde vom Blitz getroffen und gegrillt") :
|
||||
new EntityDamageSource(TextColor.YELLOW, "%s wurde von %s gegrillt", "%s wurde von %s mit %s gegrillt",
|
||||
"%s gegrillt", "%s mit %s gegrillt", mob);
|
||||
}
|
||||
|
||||
public static DamageSource causeExterminatusDamage(EntityLiving mob)
|
||||
{
|
||||
return mob == null ? new DamageSource(TextColor.DRED, "%s wurde vernichtet") :
|
||||
new EntityDamageSource(TextColor.DRED, "%s wurde von %s vernichtet", "%s wurde von %s mit %s vernichtet",
|
||||
"%s vernichtet", "%s mit %s vernichtet", mob);
|
||||
}
|
||||
|
||||
public static DamageSource causeShotDamage(Entity projectile, Entity shooter)
|
||||
{
|
||||
return (new EntityDamageSourceIndirect(TextColor.RED, "%s wurde von %s erschossen", "%s wurde von %s mit %s erschossen", "%s erschossen", "%s mit %s erschossen", projectile, shooter)).setProjectile();
|
||||
}
|
||||
|
||||
public static DamageSource causeFireballDamage(EntityProjectile fireball, Entity shooter)
|
||||
{
|
||||
return shooter == null ? (new EntityDamageSourceIndirect(TextColor.YELLOW, "%s wurde von %s flambiert", fireball)).setFireDamage().setProjectile() : (new EntityDamageSourceIndirect(TextColor.YELLOW, "%s wurde von %s flambiert", "%s wurde von %s mit %s flambiert", "%s flambiert", "%s mit %s flambiert", fireball, shooter)).setFireDamage().setProjectile();
|
||||
}
|
||||
|
||||
public static DamageSource causeThrownDamage(Entity source, Entity thrower)
|
||||
{
|
||||
return (new EntityDamageSourceIndirect(TextColor.DGREEN, "%s wurde von %s zu Tode geprügelt", "%s wurde von %s mit %s zu Tode geprügelt", "%s zu Tode geprügelt", "%s mit %s zu Tode geprügelt", source, thrower)).setProjectile();
|
||||
}
|
||||
|
||||
public static DamageSource causeTeleFragDamage(Entity source, Entity replacer)
|
||||
{
|
||||
return (new EntityDamageSourceIndirect(TextColor.MAGENTA, "%s wurde von %s verdrängt", "%s wurde von %s mit %s verdrängt", "%s verdrängt", "%s mit %s verdrängt", source, replacer)).setDamageBypassesArmor();
|
||||
}
|
||||
|
||||
public static DamageSource causeIndirectMagicDamage(Entity source, Entity mage)
|
||||
{
|
||||
return (new EntityDamageSourceIndirect(TextColor.DMAGENTA, "%s wurde von %s mit Magie getötet", "%s wurde von %s mit %s getötet", "%s mit Magie getötet", "%s mit %s getötet", source, mage)).setDamageBypassesArmor().setMagicDamage();
|
||||
}
|
||||
|
||||
public static DamageSource causeThornsDamage(Entity source)
|
||||
{
|
||||
return (new EntityDamageSource(TextColor.ORK, "%s wurde beim Versuch %s zu verletzen getötet", "%s durch Dornen getötet", source)).setIsThornsDamage().setMagicDamage();
|
||||
}
|
||||
|
||||
public static DamageSource causeExplosionDamage(Explosion explosion)
|
||||
{
|
||||
return explosion != null && explosion.getExplosivePlacedBy() != null ? (new EntityDamageSource(TextColor.YELLOW, "%s wurde durch %s in die Luft gesprengt", "%s in die Luft gesprengt", explosion.getExplosivePlacedBy())).setExplosion() : (new DamageSource(TextColor.YELLOW, "%s wurde in die Luft gesprengt")).setExplosion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the damage is projectile based.
|
||||
*/
|
||||
public boolean isProjectile()
|
||||
{
|
||||
return this.projectile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the damage type as projectile based.
|
||||
*/
|
||||
public DamageSource setProjectile()
|
||||
{
|
||||
this.projectile = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isExplosion()
|
||||
{
|
||||
return this.explosion;
|
||||
}
|
||||
|
||||
public DamageSource setExplosion()
|
||||
{
|
||||
this.explosion = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isUnblockable()
|
||||
{
|
||||
return this.isUnblockable;
|
||||
}
|
||||
|
||||
protected DamageSource(TextColor color, String display, String extra, String kill)
|
||||
{
|
||||
this.color = color;
|
||||
this.display = this.color + display;
|
||||
this.displayExtra = this.color + extra;
|
||||
this.displayKill = this.color + "* " + kill;
|
||||
}
|
||||
|
||||
protected DamageSource(TextColor color, String display)
|
||||
{
|
||||
this(color, display, display, "");
|
||||
}
|
||||
|
||||
public Entity getSourceOfDamage()
|
||||
{
|
||||
return this.getEntity();
|
||||
}
|
||||
|
||||
public Entity getEntity()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DamageSource setDamageBypassesArmor()
|
||||
{
|
||||
this.isUnblockable = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the damage type as fire based.
|
||||
*/
|
||||
protected DamageSource setFireDamage()
|
||||
{
|
||||
this.fireDamage = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the death message that is displayed when the player dies
|
||||
*
|
||||
* @param victim The EntityLivingBase that died
|
||||
*/
|
||||
public String getDeathMessage(EntityLiving victim)
|
||||
{
|
||||
EntityLiving killer = victim.getAttackingEntity();
|
||||
// String s = this.display;
|
||||
// String s1 = s + "Player";
|
||||
return killer != null ? String.format(this.displayExtra, victim.getColoredName(this.color), killer.getColoredName(this.color)) : String.format(this.display, victim.getColoredName(this.color));
|
||||
}
|
||||
|
||||
public String getKillMessage(EntityLiving victim)
|
||||
{
|
||||
return String.format(this.displayKill, victim.getColoredName(this.color));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the damage is fire based.
|
||||
*/
|
||||
public boolean isFireDamage()
|
||||
{
|
||||
return this.fireDamage;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Return the name of damage type.
|
||||
// */
|
||||
// public String getDamageType()
|
||||
// {
|
||||
// return this.damageType;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Set whether this damage source will have its damage amount scaled based on the current difficulty.
|
||||
// */
|
||||
// public DamageSource setDifficultyScaled()
|
||||
// {
|
||||
// this.difficultyScaled = true;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Return whether this damage source will have its damage amount scaled based on the current difficulty.
|
||||
// */
|
||||
// public boolean isDifficultyScaled()
|
||||
// {
|
||||
// return this.difficultyScaled;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns true if the damage is magic based.
|
||||
*/
|
||||
public boolean isMagicDamage()
|
||||
{
|
||||
return this.magicDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the damage type as magic based.
|
||||
*/
|
||||
public DamageSource setMagicDamage()
|
||||
{
|
||||
this.magicDamage = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
// public boolean isCreativePlayer()
|
||||
// {
|
||||
// Entity entity = this.getEntity();
|
||||
// return entity.isPlayer() && ((EntityNPC)entity).creative;
|
||||
// }
|
||||
}
|
353
java/src/game/entity/DataWatcher.java
Executable file
353
java/src/game/entity/DataWatcher.java
Executable file
|
@ -0,0 +1,353 @@
|
|||
package game.entity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import game.collect.Lists;
|
||||
import game.collect.Maps;
|
||||
import game.item.ItemStack;
|
||||
import game.network.PacketBuffer;
|
||||
import game.world.BlockPos;
|
||||
|
||||
public class DataWatcher {
|
||||
private static final Map<Class<?>, Integer> dataTypes = Maps.<Class<?>, Integer>newHashMap();
|
||||
|
||||
private final Entity owner;
|
||||
private final Map<Integer, DataWatcher.WatchableObject> objects = Maps.<Integer, DataWatcher.WatchableObject>newHashMap();
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
private boolean blank = true;
|
||||
private boolean changed;
|
||||
|
||||
public DataWatcher(Entity owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public <T> void addObject(int id, T object) {
|
||||
Integer integer = (Integer)dataTypes.get(object.getClass());
|
||||
|
||||
if(integer == null) {
|
||||
throw new IllegalArgumentException("Unknown data type: " + object.getClass());
|
||||
}
|
||||
else if(id > 31) {
|
||||
throw new IllegalArgumentException("Data value id is too big with " + id + "! (Max is " + 31 + ")");
|
||||
}
|
||||
else if(this.objects.containsKey(Integer.valueOf(id))) {
|
||||
throw new IllegalArgumentException("Duplicate id value for " + id + "!");
|
||||
}
|
||||
else {
|
||||
DataWatcher.WatchableObject datawatcher$watchableobject = new DataWatcher.WatchableObject(integer.intValue(), id, object);
|
||||
this.lock.writeLock().lock();
|
||||
this.objects.put(Integer.valueOf(id), datawatcher$watchableobject);
|
||||
this.lock.writeLock().unlock();
|
||||
this.blank = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void addObjectByDataType(int id, int type) {
|
||||
DataWatcher.WatchableObject datawatcher$watchableobject = new DataWatcher.WatchableObject(type, id, (Object)null);
|
||||
this.lock.writeLock().lock();
|
||||
this.objects.put(Integer.valueOf(id), datawatcher$watchableobject);
|
||||
this.lock.writeLock().unlock();
|
||||
this.blank = false;
|
||||
}
|
||||
|
||||
public byte getWatchableObjectByte(int id) {
|
||||
return ((Byte)this.getWatchedObject(id).getObject()).byteValue();
|
||||
}
|
||||
|
||||
public short getWatchableObjectShort(int id) {
|
||||
return ((Short)this.getWatchedObject(id).getObject()).shortValue();
|
||||
}
|
||||
|
||||
public int getWatchableObjectInt(int id) {
|
||||
return ((Integer)this.getWatchedObject(id).getObject()).intValue();
|
||||
}
|
||||
|
||||
public float getWatchableObjectFloat(int id) {
|
||||
return ((Float)this.getWatchedObject(id).getObject()).floatValue();
|
||||
}
|
||||
|
||||
public String getWatchableObjectString(int id) {
|
||||
return (String)this.getWatchedObject(id).getObject();
|
||||
}
|
||||
|
||||
public ItemStack getWatchableObjectItemStack(int id) {
|
||||
return (ItemStack)this.getWatchedObject(id).getObject();
|
||||
}
|
||||
|
||||
private DataWatcher.WatchableObject getWatchedObject(int id) {
|
||||
this.lock.readLock().lock();
|
||||
DataWatcher.WatchableObject datawatcher$watchableobject = (DataWatcher.WatchableObject)this.objects.get(Integer.valueOf(id));
|
||||
|
||||
this.lock.readLock().unlock();
|
||||
return datawatcher$watchableobject;
|
||||
}
|
||||
|
||||
// public Rotations getWatchableObjectRotations(int id) {
|
||||
// return (Rotations)this.getWatchedObject(id).getObject();
|
||||
// }
|
||||
|
||||
public <T> void updateObject(int id, T newData) {
|
||||
DataWatcher.WatchableObject datawatcher$watchableobject = this.getWatchedObject(id);
|
||||
|
||||
if(!(newData == datawatcher$watchableobject.getObject()
|
||||
|| (newData != null && datawatcher$watchableobject.getObject() != null ? newData.equals(datawatcher$watchableobject.getObject())
|
||||
: false))) {
|
||||
datawatcher$watchableobject.setObject(newData);
|
||||
this.owner.onDataWatcherUpdate(id);
|
||||
datawatcher$watchableobject.setWatched(true);
|
||||
this.changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setObjectWatched(int id) {
|
||||
this.getWatchedObject(id).watched = true;
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
public boolean hasObjectChanged() {
|
||||
return this.changed;
|
||||
}
|
||||
|
||||
public static void writeWatchedListToPacketBuffer(List<DataWatcher.WatchableObject> objectsList, PacketBuffer buffer) throws IOException {
|
||||
if(objectsList != null) {
|
||||
for(DataWatcher.WatchableObject datawatcher$watchableobject : objectsList) {
|
||||
writeWatchableObjectToPacketBuffer(buffer, datawatcher$watchableobject);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.writeByte(127);
|
||||
}
|
||||
|
||||
public List<DataWatcher.WatchableObject> getChanged() {
|
||||
List<DataWatcher.WatchableObject> list = null;
|
||||
|
||||
if(this.changed) {
|
||||
this.lock.readLock().lock();
|
||||
|
||||
for(DataWatcher.WatchableObject datawatcher$watchableobject : this.objects.values()) {
|
||||
if(datawatcher$watchableobject.isWatched()) {
|
||||
datawatcher$watchableobject.setWatched(false);
|
||||
|
||||
if(list == null) {
|
||||
list = Lists.<DataWatcher.WatchableObject>newArrayList();
|
||||
}
|
||||
|
||||
list.add(datawatcher$watchableobject);
|
||||
}
|
||||
}
|
||||
|
||||
this.lock.readLock().unlock();
|
||||
}
|
||||
|
||||
this.changed = false;
|
||||
return list;
|
||||
}
|
||||
|
||||
public void writeTo(PacketBuffer buffer) throws IOException {
|
||||
this.lock.readLock().lock();
|
||||
|
||||
for(DataWatcher.WatchableObject datawatcher$watchableobject : this.objects.values()) {
|
||||
writeWatchableObjectToPacketBuffer(buffer, datawatcher$watchableobject);
|
||||
}
|
||||
|
||||
this.lock.readLock().unlock();
|
||||
buffer.writeByte(127);
|
||||
}
|
||||
|
||||
public List<DataWatcher.WatchableObject> getAllWatched() {
|
||||
List<DataWatcher.WatchableObject> list = null;
|
||||
this.lock.readLock().lock();
|
||||
|
||||
for(DataWatcher.WatchableObject datawatcher$watchableobject : this.objects.values()) {
|
||||
if(list == null) {
|
||||
list = Lists.<DataWatcher.WatchableObject>newArrayList();
|
||||
}
|
||||
|
||||
list.add(datawatcher$watchableobject);
|
||||
}
|
||||
|
||||
this.lock.readLock().unlock();
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void writeWatchableObjectToPacketBuffer(PacketBuffer buffer, DataWatcher.WatchableObject object) throws IOException {
|
||||
int i = (object.getObjectType() << 5 | object.getDataValueId() & 31) & 255;
|
||||
buffer.writeByte(i);
|
||||
|
||||
switch(object.getObjectType()) {
|
||||
case 0:
|
||||
buffer.writeByte(((Byte)object.getObject()).byteValue());
|
||||
break;
|
||||
|
||||
case 1:
|
||||
buffer.writeShort(((Short)object.getObject()).shortValue());
|
||||
break;
|
||||
|
||||
case 2:
|
||||
buffer.writeInt(((Integer)object.getObject()).intValue());
|
||||
break;
|
||||
|
||||
case 3:
|
||||
buffer.writeFloat(((Float)object.getObject()).floatValue());
|
||||
break;
|
||||
|
||||
case 4:
|
||||
buffer.writeString((String)object.getObject());
|
||||
break;
|
||||
|
||||
case 5:
|
||||
ItemStack itemstack = (ItemStack)object.getObject();
|
||||
buffer.writeItemStackToBuffer(itemstack);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
BlockPos blockpos = (BlockPos)object.getObject();
|
||||
buffer.writeInt(blockpos.getX());
|
||||
buffer.writeInt(blockpos.getY());
|
||||
buffer.writeInt(blockpos.getZ());
|
||||
// break;
|
||||
//
|
||||
// case 7:
|
||||
// Rotations rotations = (Rotations)object.getObject();
|
||||
// buffer.writeFloat(rotations.getX());
|
||||
// buffer.writeFloat(rotations.getY());
|
||||
// buffer.writeFloat(rotations.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
public static List<DataWatcher.WatchableObject> readWatchedListFromPacketBuffer(PacketBuffer buffer) throws IOException {
|
||||
List<DataWatcher.WatchableObject> list = null;
|
||||
|
||||
for(int i = buffer.readByte(); i != 127; i = buffer.readByte()) {
|
||||
if(list == null) {
|
||||
list = Lists.<DataWatcher.WatchableObject>newArrayList();
|
||||
}
|
||||
|
||||
int j = (i & 224) >> 5;
|
||||
int k = i & 31;
|
||||
DataWatcher.WatchableObject datawatcher$watchableobject = null;
|
||||
|
||||
switch(j) {
|
||||
case 0:
|
||||
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Byte.valueOf(buffer.readByte()));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Short.valueOf(buffer.readShort()));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Integer.valueOf(buffer.readInt()));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Float.valueOf(buffer.readFloat()));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readStringFromBuffer(32767));
|
||||
break;
|
||||
|
||||
case 5:
|
||||
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readItemStackFromBuffer());
|
||||
break;
|
||||
|
||||
case 6:
|
||||
int l = buffer.readInt();
|
||||
int i1 = buffer.readInt();
|
||||
int j1 = buffer.readInt();
|
||||
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, new BlockPos(l, i1, j1));
|
||||
// break;
|
||||
//
|
||||
// case 7:
|
||||
// float f = buffer.readFloat();
|
||||
// float f1 = buffer.readFloat();
|
||||
// float f2 = buffer.readFloat();
|
||||
// datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, new Rotations(f, f1, f2));
|
||||
}
|
||||
|
||||
list.add(datawatcher$watchableobject);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public void updateWatchedObjectsFromList(List<DataWatcher.WatchableObject> p_75687_1_) {
|
||||
this.lock.writeLock().lock();
|
||||
|
||||
for(DataWatcher.WatchableObject datawatcher$watchableobject : p_75687_1_) {
|
||||
DataWatcher.WatchableObject datawatcher$watchableobject1 = (DataWatcher.WatchableObject)this.objects
|
||||
.get(Integer.valueOf(datawatcher$watchableobject.getDataValueId()));
|
||||
|
||||
if(datawatcher$watchableobject1 != null) {
|
||||
datawatcher$watchableobject1.setObject(datawatcher$watchableobject.getObject());
|
||||
this.owner.onDataWatcherUpdate(datawatcher$watchableobject.getDataValueId());
|
||||
}
|
||||
}
|
||||
|
||||
this.lock.writeLock().unlock();
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
public boolean isBlank() {
|
||||
return this.blank;
|
||||
}
|
||||
|
||||
public void markUnchanged() {
|
||||
this.changed = false;
|
||||
}
|
||||
|
||||
static {
|
||||
dataTypes.put(Byte.class, Integer.valueOf(0));
|
||||
dataTypes.put(Short.class, Integer.valueOf(1));
|
||||
dataTypes.put(Integer.class, Integer.valueOf(2));
|
||||
dataTypes.put(Float.class, Integer.valueOf(3));
|
||||
dataTypes.put(String.class, Integer.valueOf(4));
|
||||
dataTypes.put(ItemStack.class, Integer.valueOf(5));
|
||||
dataTypes.put(BlockPos.class, Integer.valueOf(6));
|
||||
// dataTypes.put(Rotations.class, Integer.valueOf(7));
|
||||
}
|
||||
|
||||
public static class WatchableObject {
|
||||
private final int objectType;
|
||||
private final int dataValueId;
|
||||
private Object watchedObject;
|
||||
private boolean watched;
|
||||
|
||||
public WatchableObject(int type, int id, Object object) {
|
||||
this.dataValueId = id;
|
||||
this.watchedObject = object;
|
||||
this.objectType = type;
|
||||
this.watched = true;
|
||||
}
|
||||
|
||||
public int getDataValueId() {
|
||||
return this.dataValueId;
|
||||
}
|
||||
|
||||
public void setObject(Object object) {
|
||||
this.watchedObject = object;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return this.watchedObject;
|
||||
}
|
||||
|
||||
public int getObjectType() {
|
||||
return this.objectType;
|
||||
}
|
||||
|
||||
public boolean isWatched() {
|
||||
return this.watched;
|
||||
}
|
||||
|
||||
public void setWatched(boolean watched) {
|
||||
this.watched = watched;
|
||||
}
|
||||
}
|
||||
}
|
2673
java/src/game/entity/Entity.java
Executable file
2673
java/src/game/entity/Entity.java
Executable file
File diff suppressed because it is too large
Load diff
68
java/src/game/entity/EntityDamageSource.java
Executable file
68
java/src/game/entity/EntityDamageSource.java
Executable file
|
@ -0,0 +1,68 @@
|
|||
package game.entity;
|
||||
|
||||
import game.color.TextColor;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.item.ItemStack;
|
||||
|
||||
public class EntityDamageSource extends DamageSource
|
||||
{
|
||||
protected final Entity damageSourceEntity;
|
||||
protected final String displayKillItem;
|
||||
|
||||
/**
|
||||
* Whether this EntityDamageSource is from an entity wearing Thorns-enchanted armor.
|
||||
*/
|
||||
private boolean isThornsDamage = false;
|
||||
|
||||
public EntityDamageSource(TextColor color, String display, String item, String kill, String killItem, Entity damageSourceEntityIn)
|
||||
{
|
||||
super(color, display, item, kill);
|
||||
this.damageSourceEntity = damageSourceEntityIn;
|
||||
this.displayKillItem = killItem;
|
||||
}
|
||||
|
||||
public EntityDamageSource(TextColor color, String display, String kill, Entity damageSourceEntityIn)
|
||||
{
|
||||
this(color, display, display, kill, kill, damageSourceEntityIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this EntityDamageSource as originating from Thorns armor
|
||||
*/
|
||||
public EntityDamageSource setIsThornsDamage()
|
||||
{
|
||||
this.isThornsDamage = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean getIsThornsDamage()
|
||||
{
|
||||
return this.isThornsDamage;
|
||||
}
|
||||
|
||||
public Entity getEntity()
|
||||
{
|
||||
return this.damageSourceEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the death message that is displayed when the player dies
|
||||
*
|
||||
* @param victim The EntityLivingBase that died
|
||||
*/
|
||||
public String getDeathMessage(EntityLiving victim)
|
||||
{
|
||||
ItemStack item = this.damageSourceEntity instanceof EntityLiving ? ((EntityLiving)this.damageSourceEntity).getHeldItem() : null;
|
||||
// String s = "death.attack." + this.damageType;
|
||||
// String s1 = s + "Item";
|
||||
return item != null ? String.format(this.displayExtra, victim.getColoredName(this.color), this.damageSourceEntity.getColoredName(this.color), item.getColoredName(this.color)) : String.format(this.display, victim.getColoredName(this.color), this.damageSourceEntity.getColoredName(this.color));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Return whether this damage source will have its damage amount scaled based on the current difficulty.
|
||||
// */
|
||||
// public boolean isDifficultyScaled()
|
||||
// {
|
||||
// return this.damageSourceEntity != null && this.damageSourceEntity instanceof EntityLiving && !(this.damageSourceEntity.isPlayer());
|
||||
// }
|
||||
}
|
45
java/src/game/entity/EntityDamageSourceIndirect.java
Executable file
45
java/src/game/entity/EntityDamageSourceIndirect.java
Executable file
|
@ -0,0 +1,45 @@
|
|||
package game.entity;
|
||||
|
||||
import game.color.TextColor;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.item.ItemStack;
|
||||
|
||||
public class EntityDamageSourceIndirect extends EntityDamageSource
|
||||
{
|
||||
private Entity indirectEntity;
|
||||
|
||||
public EntityDamageSourceIndirect(TextColor color, String display, String item, String kill, String killItem, Entity source, Entity indirectEntityIn)
|
||||
{
|
||||
super(color, display, item, kill, killItem, source);
|
||||
this.indirectEntity = indirectEntityIn;
|
||||
}
|
||||
|
||||
public EntityDamageSourceIndirect(TextColor color, String display, Entity source)
|
||||
{
|
||||
this(color, display, display, "", "", source, source);
|
||||
}
|
||||
|
||||
public Entity getSourceOfDamage()
|
||||
{
|
||||
return this.damageSourceEntity;
|
||||
}
|
||||
|
||||
public Entity getEntity()
|
||||
{
|
||||
return this.indirectEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the death message that is displayed when the player dies
|
||||
*
|
||||
* @param victim The EntityLivingBase that died
|
||||
*/
|
||||
public String getDeathMessage(EntityLiving victim)
|
||||
{
|
||||
String killer = this.indirectEntity == null ? this.damageSourceEntity.getColoredName(this.color) : this.indirectEntity.getColoredName(this.color);
|
||||
ItemStack item = this.indirectEntity instanceof EntityLiving ? ((EntityLiving)this.indirectEntity).getHeldItem() : null;
|
||||
// String s = "death.attack." + this.damageType;
|
||||
// String s1 = s + "Item";
|
||||
return item != null ? String.format(this.displayExtra, victim.getColoredName(this.color), killer, item.getColoredName(this.color)) : String.format(this.display, victim.getColoredName(this.color), killer);
|
||||
}
|
||||
}
|
432
java/src/game/entity/EntityTrackerEntry.java
Executable file
432
java/src/game/entity/EntityTrackerEntry.java
Executable file
|
@ -0,0 +1,432 @@
|
|||
package game.entity;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.Log;
|
||||
import game.collect.Sets;
|
||||
import game.entity.attributes.AttributeInstance;
|
||||
import game.entity.attributes.AttributeMap;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.projectile.EntityArrow;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.network.Packet;
|
||||
import game.packet.S14PacketEntity;
|
||||
import game.packet.S18PacketEntityTeleport;
|
||||
import game.packet.S19PacketEntityHeadLook;
|
||||
import game.packet.S1BPacketEntityAttach;
|
||||
import game.packet.S1CPacketEntityMetadata;
|
||||
import game.packet.S1DPacketEntityEffect;
|
||||
import game.packet.S20PacketEntityProperties;
|
||||
import game.packet.S43PacketUpdateEntityNBT;
|
||||
import game.packet.SPacketEntityEquipment;
|
||||
import game.packet.SPacketEntityVelocity;
|
||||
import game.packet.SPacketSpawnMob;
|
||||
import game.packet.SPacketSpawnObject;
|
||||
import game.packet.SPacketSpawnPlayer;
|
||||
import game.potion.PotionEffect;
|
||||
|
||||
public class EntityTrackerEntry {
|
||||
public final Entity trackedEntity;
|
||||
private final int trackingDistanceThreshold;
|
||||
private final int updateFrequency;
|
||||
private final boolean sendVelocityUpdates;
|
||||
private final Set<EntityNPC> trackingPlayers = Sets.<EntityNPC>newHashSet();
|
||||
|
||||
private Entity lastRiding;
|
||||
private int encodedPosX;
|
||||
private int encodedPosY;
|
||||
private int encodedPosZ;
|
||||
private int encodedRotationYaw;
|
||||
private int encodedRotationPitch;
|
||||
private int lastHeadMotion;
|
||||
private double lastTrackedEntityMotionX;
|
||||
private double lastTrackedEntityMotionY;
|
||||
private double lastTrackedEntityMotionZ;
|
||||
private int updateCounter;
|
||||
private double lastTrackedEntityPosX;
|
||||
private double lastTrackedEntityPosY;
|
||||
private double lastTrackedEntityPosZ;
|
||||
private boolean firstUpdateDone;
|
||||
private int ticksSinceLastForcedTeleport;
|
||||
private boolean ridingEntity;
|
||||
private boolean onGround;
|
||||
private boolean playerEntitiesUpdated;
|
||||
|
||||
public EntityTrackerEntry(Entity trackedEntityIn, int trackingDistanceThresholdIn, int updateFrequencyIn, boolean sendVelocityUpdatesIn) {
|
||||
this.trackedEntity = trackedEntityIn;
|
||||
this.trackingDistanceThreshold = trackingDistanceThresholdIn;
|
||||
this.updateFrequency = updateFrequencyIn;
|
||||
this.sendVelocityUpdates = sendVelocityUpdatesIn;
|
||||
this.encodedPosX = ExtMath.floord(trackedEntityIn.posX * 32.0D);
|
||||
this.encodedPosY = ExtMath.floord(trackedEntityIn.posY * 32.0D);
|
||||
this.encodedPosZ = ExtMath.floord(trackedEntityIn.posZ * 32.0D);
|
||||
this.encodedRotationYaw = ExtMath.floorf(trackedEntityIn.rotYaw * 256.0F / 360.0F);
|
||||
this.encodedRotationPitch = ExtMath.floorf(trackedEntityIn.rotPitch * 256.0F / 360.0F);
|
||||
this.lastHeadMotion = ExtMath.floorf(trackedEntityIn.getRotationYawHead() * 256.0F / 360.0F);
|
||||
this.onGround = trackedEntityIn.onGround;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof EntityTrackerEntry
|
||||
? ((EntityTrackerEntry)obj).trackedEntity.getId() == this.trackedEntity.getId()
|
||||
: false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.trackedEntity.getId();
|
||||
}
|
||||
|
||||
public void updatePlayerList(List<EntityNPC> players) {
|
||||
this.playerEntitiesUpdated = false;
|
||||
|
||||
if(!this.firstUpdateDone
|
||||
|| this.trackedEntity.getDistanceSq(this.lastTrackedEntityPosX, this.lastTrackedEntityPosY, this.lastTrackedEntityPosZ) > 16.0D) {
|
||||
this.lastTrackedEntityPosX = this.trackedEntity.posX;
|
||||
this.lastTrackedEntityPosY = this.trackedEntity.posY;
|
||||
this.lastTrackedEntityPosZ = this.trackedEntity.posZ;
|
||||
this.firstUpdateDone = true;
|
||||
this.playerEntitiesUpdated = true;
|
||||
this.updatePlayerEntities(players);
|
||||
}
|
||||
|
||||
if(this.lastRiding != this.trackedEntity.vehicle || this.trackedEntity.vehicle != null && this.updateCounter % 60 == 0) {
|
||||
this.lastRiding = this.trackedEntity.vehicle;
|
||||
this.sendPacketToTrackedPlayers(new S1BPacketEntityAttach(0, this.trackedEntity, this.trackedEntity.vehicle));
|
||||
}
|
||||
|
||||
// if(this.trackedEntity instanceof EntityFrame && this.updateCounter % 10 == 0) {
|
||||
//// EntityItemFrame entityitemframe = (EntityItemFrame)this.trackedEntity;
|
||||
//// ItemStack itemstack = entityitemframe.getDisplayedItem();
|
||||
////
|
||||
//// if(itemstack != null && itemstack.getItem() instanceof ItemMap) {
|
||||
//// MapData mapdata = Items.filled_map.getMapData(itemstack, this.trackedEntity.worldObj);
|
||||
////
|
||||
//// for(EntityNPC entityplayer : players) {
|
||||
//// EntityNPCMP entityplayermp = (EntityNPCMP)entityplayer;
|
||||
//// mapdata.updateVisiblePlayers(entityplayermp, itemstack);
|
||||
//// Packet packet = Items.filled_map.createMapDataPacket(itemstack, this.trackedEntity.worldObj, entityplayermp);
|
||||
////
|
||||
//// if(packet != null) {
|
||||
//// entityplayermp.netHandler.sendPacket(packet);
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// this.sendMetadataToAllAssociatedPlayers();
|
||||
// }
|
||||
|
||||
if(this.updateCounter % this.updateFrequency == 0 || this.trackedEntity.isAirBorne
|
||||
|| this.trackedEntity.getDataWatcher().hasObjectChanged()) {
|
||||
if(this.trackedEntity.vehicle == null) {
|
||||
++this.ticksSinceLastForcedTeleport;
|
||||
int k = ExtMath.floord(this.trackedEntity.posX * 32.0D);
|
||||
int j1 = ExtMath.floord(this.trackedEntity.posY * 32.0D);
|
||||
int k1 = ExtMath.floord(this.trackedEntity.posZ * 32.0D);
|
||||
int l1 = ExtMath.floorf(this.trackedEntity.rotYaw * 256.0F / 360.0F);
|
||||
int i2 = ExtMath.floorf(this.trackedEntity.rotPitch * 256.0F / 360.0F);
|
||||
int j2 = k - this.encodedPosX;
|
||||
int k2 = j1 - this.encodedPosY;
|
||||
int i = k1 - this.encodedPosZ;
|
||||
Packet packet1 = null;
|
||||
boolean flag = Math.abs(j2) >= 4 || Math.abs(k2) >= 4 || Math.abs(i) >= 4 || this.updateCounter % 60 == 0;
|
||||
boolean flag1 = Math.abs(l1 - this.encodedRotationYaw) >= 4 || Math.abs(i2 - this.encodedRotationPitch) >= 4;
|
||||
|
||||
if(this.updateCounter > 0 || this.trackedEntity instanceof EntityArrow) {
|
||||
if(j2 >= -128 && j2 < 128 && k2 >= -128 && k2 < 128 && i >= -128 && i < 128 && this.ticksSinceLastForcedTeleport <= 400
|
||||
&& !this.ridingEntity && this.onGround == this.trackedEntity.onGround) {
|
||||
if((!flag || !flag1) && !(this.trackedEntity instanceof EntityArrow)) {
|
||||
if(flag) {
|
||||
packet1 = new S14PacketEntity.S15PacketEntityRelMove(this.trackedEntity.getId(), (byte)j2, (byte)k2, (byte)i,
|
||||
this.trackedEntity.onGround);
|
||||
}
|
||||
else if(flag1) {
|
||||
packet1 = new S14PacketEntity.S16PacketEntityLook(this.trackedEntity.getId(), (byte)l1, (byte)i2,
|
||||
this.trackedEntity.onGround);
|
||||
}
|
||||
}
|
||||
else {
|
||||
packet1 = new S14PacketEntity.S17PacketEntityLookMove(this.trackedEntity.getId(), (byte)j2, (byte)k2, (byte)i,
|
||||
(byte)l1, (byte)i2, this.trackedEntity.onGround);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.onGround = this.trackedEntity.onGround;
|
||||
this.ticksSinceLastForcedTeleport = 0;
|
||||
packet1 = new S18PacketEntityTeleport(this.trackedEntity.getId(), k, j1, k1, (byte)l1, (byte)i2,
|
||||
this.trackedEntity.onGround);
|
||||
}
|
||||
}
|
||||
|
||||
if(this.sendVelocityUpdates) {
|
||||
double d0 = this.trackedEntity.motionX - this.lastTrackedEntityMotionX;
|
||||
double d1 = this.trackedEntity.motionY - this.lastTrackedEntityMotionY;
|
||||
double d2 = this.trackedEntity.motionZ - this.lastTrackedEntityMotionZ;
|
||||
double d3 = 0.02D;
|
||||
double d4 = d0 * d0 + d1 * d1 + d2 * d2;
|
||||
|
||||
if(d4 > d3 * d3 || d4 > 0.0D && this.trackedEntity.motionX == 0.0D && this.trackedEntity.motionY == 0.0D
|
||||
&& this.trackedEntity.motionZ == 0.0D) {
|
||||
this.lastTrackedEntityMotionX = this.trackedEntity.motionX;
|
||||
this.lastTrackedEntityMotionY = this.trackedEntity.motionY;
|
||||
this.lastTrackedEntityMotionZ = this.trackedEntity.motionZ;
|
||||
this.sendPacketToTrackedPlayers(new SPacketEntityVelocity(this.trackedEntity.getId(), this.lastTrackedEntityMotionX,
|
||||
this.lastTrackedEntityMotionY, this.lastTrackedEntityMotionZ));
|
||||
}
|
||||
}
|
||||
|
||||
if(packet1 != null) {
|
||||
this.sendPacketToTrackedPlayers(packet1);
|
||||
}
|
||||
|
||||
this.sendMetadataToAllAssociatedPlayers();
|
||||
|
||||
if(flag) {
|
||||
this.encodedPosX = k;
|
||||
this.encodedPosY = j1;
|
||||
this.encodedPosZ = k1;
|
||||
}
|
||||
|
||||
if(flag1) {
|
||||
this.encodedRotationYaw = l1;
|
||||
this.encodedRotationPitch = i2;
|
||||
}
|
||||
|
||||
this.ridingEntity = false;
|
||||
}
|
||||
else {
|
||||
int j = ExtMath.floorf(this.trackedEntity.rotYaw * 256.0F / 360.0F);
|
||||
int i1 = ExtMath.floorf(this.trackedEntity.rotPitch * 256.0F / 360.0F);
|
||||
boolean flag2 = Math.abs(j - this.encodedRotationYaw) >= 4 || Math.abs(i1 - this.encodedRotationPitch) >= 4;
|
||||
|
||||
if(flag2) {
|
||||
this.sendPacketToTrackedPlayers(new S14PacketEntity.S16PacketEntityLook(this.trackedEntity.getId(), (byte)j, (byte)i1,
|
||||
this.trackedEntity.onGround));
|
||||
this.encodedRotationYaw = j;
|
||||
this.encodedRotationPitch = i1;
|
||||
}
|
||||
|
||||
this.encodedPosX = ExtMath.floord(this.trackedEntity.posX * 32.0D);
|
||||
this.encodedPosY = ExtMath.floord(this.trackedEntity.posY * 32.0D);
|
||||
this.encodedPosZ = ExtMath.floord(this.trackedEntity.posZ * 32.0D);
|
||||
this.sendMetadataToAllAssociatedPlayers();
|
||||
this.ridingEntity = true;
|
||||
}
|
||||
|
||||
int l = ExtMath.floorf(this.trackedEntity.getRotationYawHead() * 256.0F / 360.0F);
|
||||
|
||||
if(Math.abs(l - this.lastHeadMotion) >= 4) {
|
||||
this.sendPacketToTrackedPlayers(new S19PacketEntityHeadLook(this.trackedEntity, (byte)l));
|
||||
this.lastHeadMotion = l;
|
||||
}
|
||||
|
||||
this.trackedEntity.isAirBorne = false;
|
||||
}
|
||||
|
||||
++this.updateCounter;
|
||||
|
||||
if(this.trackedEntity.veloChanged) {
|
||||
this.sendPacketToTrackedAndSelf(new SPacketEntityVelocity(this.trackedEntity));
|
||||
this.trackedEntity.veloChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMetadataToAllAssociatedPlayers() {
|
||||
DataWatcher datawatcher = this.trackedEntity.getDataWatcher();
|
||||
|
||||
if(datawatcher.hasObjectChanged()) {
|
||||
this.sendPacketToTrackedAndSelf(new S1CPacketEntityMetadata(this.trackedEntity.getId(), datawatcher, false));
|
||||
}
|
||||
|
||||
if(this.trackedEntity instanceof EntityLiving) {
|
||||
AttributeMap serversideattributemap = ((EntityLiving)this.trackedEntity).getAttributeMap();
|
||||
Set<AttributeInstance> set = serversideattributemap.getDirty();
|
||||
|
||||
if(!set.isEmpty()) {
|
||||
this.sendPacketToTrackedAndSelf(new S20PacketEntityProperties(this.trackedEntity.getId(), set));
|
||||
}
|
||||
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPacketToTrackedPlayers(Packet packetIn) {
|
||||
for(EntityNPC entityplayermp : this.trackingPlayers) {
|
||||
entityplayermp.connection.sendPacket(packetIn);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPacketToTrackedAndSelf(Packet packetIn) {
|
||||
this.sendPacketToTrackedPlayers(packetIn);
|
||||
|
||||
if(this.trackedEntity.isPlayer()) {
|
||||
((EntityNPC)this.trackedEntity).connection.sendPacket(packetIn);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendDestroyEntityPacketToTrackedPlayers() {
|
||||
for(EntityNPC entityplayermp : this.trackingPlayers) {
|
||||
entityplayermp.connection.removeEntity(this.trackedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromTrackedPlayers(EntityNPC playerMP) {
|
||||
if(this.trackingPlayers.contains(playerMP)) {
|
||||
playerMP.connection.removeEntity(this.trackedEntity);
|
||||
this.trackingPlayers.remove(playerMP);
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePlayerEntity(EntityNPC playerMP) {
|
||||
if(playerMP != this.trackedEntity) {
|
||||
if(this.canBeSeen(playerMP)) {
|
||||
if(!this.trackingPlayers.contains(playerMP) && (this.isPlayerWatchingThisChunk(playerMP) || this.trackedEntity.forceSpawn)) {
|
||||
this.trackingPlayers.add(playerMP);
|
||||
Packet packet = this.createSpawnPacket();
|
||||
playerMP.connection.sendPacket(packet);
|
||||
|
||||
if(!this.trackedEntity.getDataWatcher().isBlank()) {
|
||||
playerMP.connection
|
||||
.sendPacket(new S1CPacketEntityMetadata(this.trackedEntity.getId(), this.trackedEntity.getDataWatcher(), true));
|
||||
}
|
||||
|
||||
NBTTagCompound nbttagcompound = this.trackedEntity.getNBTTagCompound();
|
||||
|
||||
if(nbttagcompound != null) {
|
||||
playerMP.connection.sendPacket(new S43PacketUpdateEntityNBT(this.trackedEntity.getId(), nbttagcompound));
|
||||
}
|
||||
|
||||
if(this.trackedEntity instanceof EntityLiving) {
|
||||
AttributeMap serversideattributemap = ((EntityLiving)this.trackedEntity).getAttributeMap();
|
||||
Collection<AttributeInstance> collection = serversideattributemap.getWatchedAttributes();
|
||||
|
||||
if(!collection.isEmpty()) {
|
||||
playerMP.connection.sendPacket(new S20PacketEntityProperties(this.trackedEntity.getId(), collection));
|
||||
}
|
||||
}
|
||||
|
||||
this.lastTrackedEntityMotionX = this.trackedEntity.motionX;
|
||||
this.lastTrackedEntityMotionY = this.trackedEntity.motionY;
|
||||
this.lastTrackedEntityMotionZ = this.trackedEntity.motionZ;
|
||||
|
||||
// if(this.trackedEntity.isPlayer() && !((EntityNPCMP)this.trackedEntity).isVisibleTo(playerMP))
|
||||
// return;
|
||||
|
||||
if(this.sendVelocityUpdates && !(packet instanceof SPacketSpawnMob)) {
|
||||
playerMP.connection.sendPacket(new SPacketEntityVelocity(this.trackedEntity.getId(),
|
||||
this.trackedEntity.motionX, this.trackedEntity.motionY, this.trackedEntity.motionZ));
|
||||
}
|
||||
|
||||
if(this.trackedEntity.vehicle != null) {
|
||||
playerMP.connection.sendPacket(new S1BPacketEntityAttach(0, this.trackedEntity, this.trackedEntity.vehicle));
|
||||
}
|
||||
|
||||
if(this.trackedEntity instanceof EntityLiving && ((EntityLiving)this.trackedEntity).getLeashedTo() != null) {
|
||||
playerMP.connection.sendPacket(
|
||||
new S1BPacketEntityAttach(1, this.trackedEntity, ((EntityLiving)this.trackedEntity).getLeashedTo()));
|
||||
}
|
||||
|
||||
if(this.trackedEntity instanceof EntityLiving) {
|
||||
for(int i = 0; i < 5; ++i) {
|
||||
ItemStack itemstack = ((EntityLiving)this.trackedEntity).getItem(i);
|
||||
|
||||
if(itemstack != null) {
|
||||
playerMP.connection
|
||||
.sendPacket(new SPacketEntityEquipment(this.trackedEntity.getId(), i, itemstack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if(this.trackedEntity.isPlayer()) {
|
||||
// EntityNPC entityplayer = (EntityNPC)this.trackedEntity;
|
||||
//
|
||||
// if(entityplayer.isPlayerSleeping()) {
|
||||
// playerMP.netHandler.sendPacket(new SPacketUseBed(entityplayer, new BlockPos(this.trackedEntity)));
|
||||
// }
|
||||
// }
|
||||
|
||||
if(this.trackedEntity instanceof EntityLiving) {
|
||||
EntityLiving entitylivingbase = (EntityLiving)this.trackedEntity;
|
||||
|
||||
for(PotionEffect potioneffect : entitylivingbase.getEffects()) {
|
||||
playerMP.connection.sendPacket(new S1DPacketEntityEffect(this.trackedEntity.getId(), potioneffect));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(this.trackingPlayers.contains(playerMP)) {
|
||||
this.trackingPlayers.remove(playerMP);
|
||||
playerMP.connection.removeEntity(this.trackedEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canBeSeen(EntityNPC playerMP) {
|
||||
double d0 = playerMP.posX - (double)(this.encodedPosX / 32);
|
||||
double d1 = playerMP.posZ - (double)(this.encodedPosZ / 32);
|
||||
return d0 >= (double)(-this.trackingDistanceThreshold) && d0 <= (double)this.trackingDistanceThreshold
|
||||
&& d1 >= (double)(-this.trackingDistanceThreshold) && d1 <= (double)this.trackingDistanceThreshold
|
||||
; // && this.trackedEntity.isVisibleTo(playerMP);
|
||||
}
|
||||
|
||||
private boolean isPlayerWatchingThisChunk(EntityNPC playerMP) {
|
||||
return playerMP.getServerWorld().isPlayerWatchingChunk(playerMP, this.trackedEntity.chunkCoordX,
|
||||
this.trackedEntity.chunkCoordZ);
|
||||
}
|
||||
|
||||
public void updatePlayerEntities(List<EntityNPC> players) {
|
||||
for(int i = 0; i < players.size(); ++i) {
|
||||
this.updatePlayerEntity(players.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private Packet createSpawnPacket() {
|
||||
if(this.trackedEntity.dead) {
|
||||
Log.JNI.warn("Erstelle Spawn-Paket für entferntes Objekt");
|
||||
}
|
||||
|
||||
SPacketSpawnObject packet = null;
|
||||
// int oid = EntityRegistry.getObjectID(this.trackedEntity);
|
||||
// if(oid != 0) {
|
||||
// }
|
||||
if(this.trackedEntity.isPlayer()) {
|
||||
return new SPacketSpawnPlayer((EntityNPC)this.trackedEntity);
|
||||
}
|
||||
else if(this.trackedEntity instanceof EntityLiving) {
|
||||
this.lastHeadMotion = ExtMath.floorf(this.trackedEntity.getRotationYawHead() * 256.0F / 360.0F);
|
||||
return new SPacketSpawnMob((EntityLiving)this.trackedEntity);
|
||||
}
|
||||
// else if(this.trackedEntity instanceof EntityPainting) {
|
||||
// return new SPacketSpawnPainting((EntityPainting)this.trackedEntity);
|
||||
// }
|
||||
// else if(this.trackedEntity instanceof EntityXPOrb) {
|
||||
// return new SPacketSpawnExperienceOrb((EntityXPOrb)this.trackedEntity);
|
||||
// }
|
||||
// else if(this.trackedEntity instanceof IObjectData) {
|
||||
// packet = new SPacketSpawnObject(this.trackedEntity, ((IObjectData)this.trackedEntity).getPacketData());
|
||||
// }
|
||||
else {
|
||||
return new SPacketSpawnObject(this.trackedEntity);
|
||||
}
|
||||
// else {
|
||||
// throw new IllegalArgumentException("Kann Spawn-Paket für " + this.trackedEntity.getClass() + " nicht erstellen!");
|
||||
// }
|
||||
|
||||
// return packet;
|
||||
}
|
||||
|
||||
public void removeTrackedPlayerSymmetric(EntityNPC playerMP) {
|
||||
if(this.trackingPlayers.contains(playerMP)) {
|
||||
this.trackingPlayers.remove(playerMP);
|
||||
playerMP.connection.removeEntity(this.trackedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUpdated() {
|
||||
return this.playerEntitiesUpdated;
|
||||
}
|
||||
}
|
324
java/src/game/entity/animal/EntityBat.java
Executable file
324
java/src/game/entity/animal/EntityBat.java
Executable file
|
@ -0,0 +1,324 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.Alignment;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.SoundEvent;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.BlockPos;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityBat extends EntityLiving
|
||||
{
|
||||
/** Coordinates of where the bat spawned. */
|
||||
private BlockPos spawnPosition;
|
||||
|
||||
public EntityBat(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.5F, 0.9F);
|
||||
this.setIsBatHanging(true);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(16, (byte)0);
|
||||
}
|
||||
|
||||
public boolean allowLeashing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.1F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pitch of living sounds in living entities.
|
||||
*/
|
||||
protected float getSoundPitch()
|
||||
{
|
||||
return super.getSoundPitch() * 0.95F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return this.getIsBatHanging() && this.rand.rarity(4) ? null : SoundEvent.BAT_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return SoundEvent.BAT_HIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return SoundEvent.BAT_DEATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this entity should push and be pushed by other entities when colliding.
|
||||
*/
|
||||
public boolean canBePushed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void collideWithEntity(Entity entityIn)
|
||||
{
|
||||
}
|
||||
|
||||
protected void collideWithNearbyEntities()
|
||||
{
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(6);
|
||||
}
|
||||
|
||||
public boolean getIsBatHanging()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
|
||||
}
|
||||
|
||||
public void setIsBatHanging(boolean isHanging)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (isHanging)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -2)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.getIsBatHanging())
|
||||
{
|
||||
this.motionX = this.motionY = this.motionZ = 0.0D;
|
||||
this.posY = (double)ExtMath.floord(this.posY) + 1.0D - (double)this.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.motionY *= 0.6000000238418579D;
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateAITasks()
|
||||
{
|
||||
super.updateAITasks();
|
||||
BlockPos blockpos = new BlockPos(this);
|
||||
BlockPos blockpos1 = blockpos.up();
|
||||
|
||||
if (this.getIsBatHanging())
|
||||
{
|
||||
if (!this.worldObj.getState(blockpos1).getBlock().isNormalCube())
|
||||
{
|
||||
this.setIsBatHanging(false);
|
||||
this.worldObj.playAuxSFX(1015, blockpos, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.rand.chance(200))
|
||||
{
|
||||
this.headYaw = (float)this.rand.zrange(360);
|
||||
}
|
||||
|
||||
if (this.worldObj.getClosestPlayerToEntity(this, 4.0D) != null)
|
||||
{
|
||||
this.setIsBatHanging(false);
|
||||
this.worldObj.playAuxSFX(1015, blockpos, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.spawnPosition != null && (!this.worldObj.isAirBlock(this.spawnPosition) || this.spawnPosition.getY() < 1))
|
||||
{
|
||||
this.spawnPosition = null;
|
||||
}
|
||||
|
||||
if (this.spawnPosition == null || this.rand.chance(30) || this.spawnPosition.distanceSq((double)((int)this.posX), (double)((int)this.posY), (double)((int)this.posZ)) < 4.0D)
|
||||
{
|
||||
this.spawnPosition = new BlockPos((int)this.posX + this.rand.zrange(7) - this.rand.zrange(7), (int)this.posY + this.rand.range(-2, 3), (int)this.posZ + this.rand.zrange(7) - this.rand.zrange(7));
|
||||
}
|
||||
|
||||
double d0 = (double)this.spawnPosition.getX() + 0.5D - this.posX;
|
||||
double d1 = (double)this.spawnPosition.getY() + 0.1D - this.posY;
|
||||
double d2 = (double)this.spawnPosition.getZ() + 0.5D - this.posZ;
|
||||
this.motionX += (Math.signum(d0) * 0.5D - this.motionX) * 0.10000000149011612D;
|
||||
this.motionY += (Math.signum(d1) * 0.699999988079071D - this.motionY) * 0.10000000149011612D;
|
||||
this.motionZ += (Math.signum(d2) * 0.5D - this.motionZ) * 0.10000000149011612D;
|
||||
float f = (float)(ExtMath.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F;
|
||||
float f1 = ExtMath.wrapf(f - this.rotYaw);
|
||||
this.moveForward = 0.5F;
|
||||
this.rotYaw += f1;
|
||||
|
||||
if (this.rand.chance(100) && this.worldObj.getState(blockpos1).getBlock().isNormalCube())
|
||||
{
|
||||
this.setIsBatHanging(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
}
|
||||
|
||||
protected void updateFallState(double y, boolean onGroundIn, Block blockIn, BlockPos pos)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this entity should NOT trigger a pressure plate or a tripwire.
|
||||
*/
|
||||
public boolean doesEntityNotTriggerPressurePlate()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.worldObj.client && this.getIsBatHanging())
|
||||
{
|
||||
this.setIsBatHanging(false);
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf(tagCompund.getByte("BatFlags")));
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setByte("BatFlags", this.dataWatcher.getWatchableObjectByte(16));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity's current position is a valid location to spawn this entity.
|
||||
*/
|
||||
public boolean getCanSpawnHere()
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ);
|
||||
|
||||
if (blockpos.getY() >= this.worldObj.getSeaLevel())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = this.worldObj.getLightFromNeighbors(blockpos);
|
||||
int j = 4;
|
||||
|
||||
// if (Config.useHalloween && isDateAroundHalloween(World.getCurrentDate()))
|
||||
// {
|
||||
// j = 7;
|
||||
// }
|
||||
// else
|
||||
if (this.rand.chance())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return i <= this.rand.zrange(j); // ? false : super.getCanSpawnHere();
|
||||
}
|
||||
}
|
||||
|
||||
// private static boolean isDateAroundHalloween(Calendar calendar)
|
||||
// {
|
||||
// return calendar.get(2) + 1 == 10 && calendar.get(5) >= 20 || calendar.get(2) + 1 == 11 && calendar.get(5) <= 3;
|
||||
// }
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height / 2.0F;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x5c5c8a;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return Alignment.NEUTRAL;
|
||||
}
|
||||
}
|
249
java/src/game/entity/animal/EntityChicken.java
Executable file
249
java/src/game/entity/animal/EntityChicken.java
Executable file
|
@ -0,0 +1,249 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIFollowParent;
|
||||
import game.ai.EntityAILookIdle;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIPanic;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Config;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.Item;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityChicken extends EntityAnimal
|
||||
{
|
||||
public float wingRotation;
|
||||
public float destPos;
|
||||
public float field_70884_g;
|
||||
public float field_70888_h;
|
||||
public float wingRotDelta = 1.0F;
|
||||
|
||||
/** The time until the next egg is spawned. */
|
||||
public int timeUntilNextEgg;
|
||||
public boolean chickenJockey;
|
||||
|
||||
public EntityChicken(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.4F, 0.7F);
|
||||
this.timeUntilNextEgg = worldIn.client || Config.eggTimer <= 0 ? 1000 : this.rand.excl(Config.eggTimer, Config.eggTimer * 2);
|
||||
this.tasks.addTask(0, new EntityAISwimming(this));
|
||||
this.tasks.addTask(1, new EntityAIPanic(this, 1.4D));
|
||||
this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Items.wheat, false));
|
||||
this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
|
||||
this.tasks.addTask(5, new EntityAIWander(this, 1.0D));
|
||||
this.tasks.addTask(6, new EntityAIWatchClosest(this, null, 6.0F));
|
||||
this.tasks.addTask(7, new EntityAILookIdle(this));
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height;
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(4);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.25D);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
this.field_70888_h = this.wingRotation;
|
||||
this.field_70884_g = this.destPos;
|
||||
this.destPos = (float)((double)this.destPos + (double)(this.onGround ? -1 : 4) * 0.3D);
|
||||
this.destPos = ExtMath.clampf(this.destPos, 0.0F, 1.0F);
|
||||
|
||||
if (!this.onGround && this.wingRotDelta < 1.0F)
|
||||
{
|
||||
this.wingRotDelta = 1.0F;
|
||||
}
|
||||
|
||||
this.wingRotDelta = (float)((double)this.wingRotDelta * 0.9D);
|
||||
|
||||
if (!this.onGround && this.motionY < 0.0D)
|
||||
{
|
||||
this.motionY *= 0.6D;
|
||||
}
|
||||
|
||||
this.wingRotation += this.wingRotDelta * 2.0F;
|
||||
|
||||
if (!this.worldObj.client && Config.eggTimer > 0 && !this.isChild() && !this.isChickenJockey() && --this.timeUntilNextEgg <= 0)
|
||||
{
|
||||
this.playSound(SoundEvent.PLOP, 1.0F, (this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F);
|
||||
this.dropItem(Items.egg, 1);
|
||||
this.timeUntilNextEgg = this.rand.excl(Config.eggTimer, Config.eggTimer * 2);
|
||||
}
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return SoundEvent.CHICKEN_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return SoundEvent.CHICKEN_HIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return SoundEvent.CHICKEN_HIT;
|
||||
}
|
||||
|
||||
// protected void playStepSound(BlockPos pos, Block blockIn)
|
||||
// {
|
||||
// this.playSound("mob.chicken.step", 0.15F, 1.0F);
|
||||
// }
|
||||
|
||||
protected Item getDropItem()
|
||||
{
|
||||
return Items.feather;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(3) + this.rand.zrange(1 + lootingModifier);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
this.dropItem(Items.feather, 1);
|
||||
}
|
||||
|
||||
if (this.isBurning())
|
||||
{
|
||||
this.dropItem(Items.cooked_chicken, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dropItem(Items.chicken, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityChicken createChild(EntityLiving ageable)
|
||||
{
|
||||
return new EntityChicken(this.worldObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 stack)
|
||||
{
|
||||
return stack != null && stack.getItem() == Items.wheat;
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.chickenJockey = tagCompund.getBoolean("IsChickenJockey");
|
||||
|
||||
if (tagCompund.hasKey("EggLayTime"))
|
||||
{
|
||||
this.timeUntilNextEgg = tagCompund.getInteger("EggLayTime");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the experience points the entity currently has.
|
||||
*/
|
||||
protected int getExperiencePoints(EntityNPC player)
|
||||
{
|
||||
return this.isChickenJockey() ? 10 : super.getExperiencePoints(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setBoolean("IsChickenJockey", this.chickenJockey);
|
||||
tagCompound.setInteger("EggLayTime", this.timeUntilNextEgg);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Determines if an entity can be despawned, used on idle far away entities
|
||||
// */
|
||||
// protected boolean canDespawn()
|
||||
// {
|
||||
// return this.isChickenJockey() && this.passenger == null;
|
||||
// }
|
||||
|
||||
public void updateRiderPosition()
|
||||
{
|
||||
super.updateRiderPosition();
|
||||
float f = ExtMath.sin(this.yawOffset * (float)Math.PI / 180.0F);
|
||||
float f1 = ExtMath.cos(this.yawOffset * (float)Math.PI / 180.0F);
|
||||
float f2 = 0.1F;
|
||||
float f3 = 0.0F;
|
||||
this.passenger.setPosition(this.posX + (double)(f2 * f), this.posY + (double)(this.height * 0.5F) + this.passenger.getYOffset() + (double)f3, this.posZ - (double)(f2 * f1));
|
||||
|
||||
if (this.passenger instanceof EntityLiving)
|
||||
{
|
||||
((EntityLiving)this.passenger).yawOffset = this.yawOffset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this chicken is a jokey with a zombie riding it.
|
||||
*/
|
||||
public boolean isChickenJockey()
|
||||
{
|
||||
return this.chickenJockey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this chicken is a jockey or not.
|
||||
*/
|
||||
public void setChickenJockey(boolean jockey)
|
||||
{
|
||||
this.chickenJockey = jockey;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xdb5152;
|
||||
}
|
||||
}
|
158
java/src/game/entity/animal/EntityCow.java
Executable file
158
java/src/game/entity/animal/EntityCow.java
Executable file
|
@ -0,0 +1,158 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import game.ai.EntityAIFollowParent;
|
||||
import game.ai.EntityAILookIdle;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIPanic;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.Item;
|
||||
import game.item.ItemStack;
|
||||
import game.pathfinding.PathNavigateGround;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityCow extends EntityAnimal
|
||||
{
|
||||
public EntityCow(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.9F, 1.3F);
|
||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
||||
this.tasks.addTask(0, new EntityAISwimming(this));
|
||||
this.tasks.addTask(1, new EntityAIPanic(this, 2.0D));
|
||||
this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(3, new EntityAITempt(this, 1.25D, Items.wheats, false));
|
||||
this.tasks.addTask(4, new EntityAIFollowParent(this, 1.25D));
|
||||
this.tasks.addTask(5, new EntityAIWander(this, 1.0D));
|
||||
this.tasks.addTask(6, new EntityAIWatchClosest(this, null, 6.0F));
|
||||
this.tasks.addTask(7, new EntityAILookIdle(this));
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(10);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return SoundEvent.COW_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return SoundEvent.COW_HIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return SoundEvent.COW_HIT;
|
||||
}
|
||||
|
||||
// protected void playStepSound(BlockPos pos, Block blockIn)
|
||||
// {
|
||||
// this.playSound("mob.cow.step", 0.15F, 1.0F);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
protected Item getDropItem()
|
||||
{
|
||||
return Items.leather;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(3) + this.rand.zrange(1 + lootingModifier);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
this.dropItem(Items.leather, 1);
|
||||
}
|
||||
|
||||
i = this.rand.roll(3) + this.rand.zrange(1 + lootingModifier);
|
||||
|
||||
for (int k = 0; k < i; ++k)
|
||||
{
|
||||
if (this.isBurning())
|
||||
{
|
||||
this.dropItem(Items.cooked_beef, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dropItem(Items.beef, 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)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == Items.bucket /* && !player.creative */ && !this.isChild())
|
||||
{
|
||||
if (itemstack.stackSize-- == 1)
|
||||
{
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, new ItemStack(Items.milk_bucket));
|
||||
}
|
||||
else if (!player.inventory.addItemStackToInventory(new ItemStack(Items.milk_bucket)))
|
||||
{
|
||||
player.dropPlayerItemWithRandomChoice(new ItemStack(Items.milk_bucket, 1, 0), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.interact(player);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityCow createChild(EntityLiving ageable)
|
||||
{
|
||||
return new EntityCow(this.worldObj);
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x8f4f21;
|
||||
}
|
||||
}
|
619
java/src/game/entity/animal/EntityDragon.java
Executable file
619
java/src/game/entity/animal/EntityDragon.java
Executable file
|
@ -0,0 +1,619 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.collect.Lists;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.Alignment;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.IEntityMultiPart;
|
||||
import game.init.Config;
|
||||
import game.init.SoundEvent;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.Vec3;
|
||||
import game.world.World;
|
||||
import game.world.WorldClient;
|
||||
|
||||
public class EntityDragon extends EntityLiving implements IEntityMultiPart
|
||||
{
|
||||
public double targetX;
|
||||
public double targetY;
|
||||
public double targetZ;
|
||||
public double[][] ringBuffer = new double[64][3];
|
||||
public int ringBufferIndex = -1;
|
||||
public EntityDragonPart[] dragonPartArray;
|
||||
public EntityDragonPart dragonPartHead;
|
||||
public EntityDragonPart dragonPartBody;
|
||||
public EntityDragonPart dragonPartTail1;
|
||||
public EntityDragonPart dragonPartTail2;
|
||||
public EntityDragonPart dragonPartTail3;
|
||||
public EntityDragonPart dragonPartWing1;
|
||||
public EntityDragonPart dragonPartWing2;
|
||||
public float prevAnimTime;
|
||||
public float animTime;
|
||||
public boolean forceNewTarget;
|
||||
private Entity target;
|
||||
|
||||
public EntityDragon(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.dragonPartArray = new EntityDragonPart[] {this.dragonPartHead = new EntityDragonPart(this, "head", 6.0F, 6.0F), this.dragonPartBody = new EntityDragonPart(this, "body", 8.0F, 8.0F), this.dragonPartTail1 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), this.dragonPartTail2 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), this.dragonPartTail3 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), this.dragonPartWing1 = new EntityDragonPart(this, "wing", 4.0F, 4.0F), this.dragonPartWing2 = new EntityDragonPart(this, "wing", 4.0F, 4.0F)};
|
||||
this.setHealth(this.getMaxHealth());
|
||||
this.setSize(16.0F, 8.0F);
|
||||
this.noClip = true;
|
||||
// this.fireImmune = true;
|
||||
this.targetY = 100.0D;
|
||||
this.noFrustumCheck = true;
|
||||
this.xpValue = 12000;
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(200);
|
||||
}
|
||||
|
||||
// protected void entityInit()
|
||||
// {
|
||||
// super.entityInit();
|
||||
// }
|
||||
|
||||
public boolean allowLeashing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a double[3] array with movement offsets, used to calculate trailing tail/neck positions. [0] = yaw
|
||||
* offset, [1] = y offset, [2] = unused, always 0. Parameters: buffer index offset, partial ticks.
|
||||
*/
|
||||
public double[] getMovementOffsets(int p_70974_1_, float p_70974_2_)
|
||||
{
|
||||
if (this.getHealth() <= 0)
|
||||
{
|
||||
p_70974_2_ = 0.0F;
|
||||
}
|
||||
|
||||
p_70974_2_ = 1.0F - p_70974_2_;
|
||||
int i = this.ringBufferIndex - p_70974_1_ * 1 & 63;
|
||||
int j = this.ringBufferIndex - p_70974_1_ * 1 - 1 & 63;
|
||||
double[] adouble = new double[3];
|
||||
double d0 = this.ringBuffer[i][0];
|
||||
double d1 = ExtMath.wrapd(this.ringBuffer[j][0] - d0);
|
||||
adouble[0] = d0 + d1 * (double)p_70974_2_;
|
||||
d0 = this.ringBuffer[i][1];
|
||||
d1 = this.ringBuffer[j][1] - d0;
|
||||
adouble[1] = d0 + d1 * (double)p_70974_2_;
|
||||
adouble[2] = this.ringBuffer[i][2] + (this.ringBuffer[j][2] - this.ringBuffer[i][2]) * (double)p_70974_2_;
|
||||
return adouble;
|
||||
}
|
||||
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
if (this.worldObj.client)
|
||||
{
|
||||
float f = ExtMath.cos(this.animTime * (float)Math.PI * 2.0F);
|
||||
float f1 = ExtMath.cos(this.prevAnimTime * (float)Math.PI * 2.0F);
|
||||
|
||||
if (f1 <= -0.3F && f >= -0.3F) // && !this.isSilent())
|
||||
{
|
||||
((WorldClient)this.worldObj).playSound(this.posX, this.posY, this.posZ, SoundEvent.DRAGON_WINGS, 5.0F, 0.8F + this.rand.floatv() * 0.3F);
|
||||
}
|
||||
}
|
||||
|
||||
this.prevAnimTime = this.animTime;
|
||||
|
||||
if (this.getHealth() <= 0)
|
||||
{
|
||||
float f11 = (this.rand.floatv() - 0.5F) * 8.0F;
|
||||
float f13 = (this.rand.floatv() - 0.5F) * 4.0F;
|
||||
float f14 = (this.rand.floatv() - 0.5F) * 8.0F;
|
||||
this.worldObj.spawnParticle(ParticleType.EXPLOSION_LARGE, this.posX + (double)f11, this.posY + 2.0D + (double)f13, this.posZ + (double)f14, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this.updateDragonEnderCrystal();
|
||||
float f10 = 0.2F / (ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ) * 10.0F + 1.0F);
|
||||
f10 = f10 * (float)Math.pow(2.0D, this.motionY);
|
||||
|
||||
this.animTime += f10;
|
||||
|
||||
this.rotYaw = ExtMath.wrapf(this.rotYaw);
|
||||
|
||||
// if (this.isAIDisabled() ||
|
||||
if(!this.worldObj.client && !Config.mobTick) // )
|
||||
{
|
||||
this.animTime = 0.5F;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.ringBufferIndex < 0)
|
||||
{
|
||||
for (int i = 0; i < this.ringBuffer.length; ++i)
|
||||
{
|
||||
this.ringBuffer[i][0] = (double)this.rotYaw;
|
||||
this.ringBuffer[i][1] = this.posY;
|
||||
}
|
||||
}
|
||||
|
||||
if (++this.ringBufferIndex == this.ringBuffer.length)
|
||||
{
|
||||
this.ringBufferIndex = 0;
|
||||
}
|
||||
|
||||
this.ringBuffer[this.ringBufferIndex][0] = (double)this.rotYaw;
|
||||
this.ringBuffer[this.ringBufferIndex][1] = this.posY;
|
||||
|
||||
if (this.worldObj.client)
|
||||
{
|
||||
if (this.moveIncrements > 0)
|
||||
{
|
||||
double d10 = this.posX + (this.newX - this.posX) / (double)this.moveIncrements;
|
||||
double d0 = this.posY + (this.newY - this.posY) / (double)this.moveIncrements;
|
||||
double d1 = this.posZ + (this.newZ - this.posZ) / (double)this.moveIncrements;
|
||||
double d2 = ExtMath.wrapd(this.newYaw - (double)this.rotYaw);
|
||||
this.rotYaw = (float)((double)this.rotYaw + d2 / (double)this.moveIncrements);
|
||||
this.rotPitch = (float)((double)this.rotPitch + (this.newPitch - (double)this.rotPitch) / (double)this.moveIncrements);
|
||||
--this.moveIncrements;
|
||||
this.setPosition(d10, d0, d1);
|
||||
this.setRotation(this.rotYaw, this.rotPitch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double d11 = this.targetX - this.posX;
|
||||
double d12 = this.targetY - this.posY;
|
||||
double d13 = this.targetZ - this.posZ;
|
||||
double d14 = d11 * d11 + d12 * d12 + d13 * d13;
|
||||
|
||||
if (this.target != null)
|
||||
{
|
||||
this.targetX = this.target.posX;
|
||||
this.targetZ = this.target.posZ;
|
||||
double d3 = this.targetX - this.posX;
|
||||
double d5 = this.targetZ - this.posZ;
|
||||
double d7 = Math.sqrt(d3 * d3 + d5 * d5);
|
||||
double d8 = 0.4000000059604645D + d7 / 80.0D - 1.0D;
|
||||
|
||||
if (d8 > 10.0D)
|
||||
{
|
||||
d8 = 10.0D;
|
||||
}
|
||||
|
||||
this.targetY = this.target.getEntityBoundingBox().minY + d8;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.targetX += this.rand.gaussian() * 2.0D;
|
||||
this.targetZ += this.rand.gaussian() * 2.0D;
|
||||
}
|
||||
|
||||
if (this.forceNewTarget || d14 < 100.0D || d14 > 22500.0D || this.collidedHorizontally || this.collidedVertically)
|
||||
{
|
||||
this.setNewTarget();
|
||||
}
|
||||
|
||||
d12 = d12 / (double)ExtMath.sqrtd(d11 * d11 + d13 * d13);
|
||||
float f17 = 0.6F;
|
||||
d12 = ExtMath.clampd(d12, (double)(-f17), (double)f17);
|
||||
this.motionY += d12 * 0.10000000149011612D;
|
||||
this.rotYaw = ExtMath.wrapf(this.rotYaw);
|
||||
double d4 = 180.0D - ExtMath.atan2(d11, d13) * 180.0D / Math.PI;
|
||||
double d6 = ExtMath.wrapd(d4 - (double)this.rotYaw);
|
||||
|
||||
if (d6 > 50.0D)
|
||||
{
|
||||
d6 = 50.0D;
|
||||
}
|
||||
|
||||
if (d6 < -50.0D)
|
||||
{
|
||||
d6 = -50.0D;
|
||||
}
|
||||
|
||||
Vec3 vec3 = (new Vec3(this.targetX - this.posX, this.targetY - this.posY, this.targetZ - this.posZ)).normalize();
|
||||
double d15 = (double)(-ExtMath.cos(this.rotYaw * (float)Math.PI / 180.0F));
|
||||
Vec3 vec31 = (new Vec3((double)ExtMath.sin(this.rotYaw * (float)Math.PI / 180.0F), this.motionY, d15)).normalize();
|
||||
float f5 = ((float)vec31.dotProduct(vec3) + 0.5F) / 1.5F;
|
||||
|
||||
if (f5 < 0.0F)
|
||||
{
|
||||
f5 = 0.0F;
|
||||
}
|
||||
|
||||
this.randomYawVelo *= 0.8F;
|
||||
float f6 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ) * 1.0F + 1.0F;
|
||||
double d9 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ) * 1.0D + 1.0D;
|
||||
|
||||
if (d9 > 40.0D)
|
||||
{
|
||||
d9 = 40.0D;
|
||||
}
|
||||
|
||||
this.randomYawVelo = (float)((double)this.randomYawVelo + d6 * (0.699999988079071D / d9 / (double)f6));
|
||||
this.rotYaw += this.randomYawVelo * 0.1F;
|
||||
float f7 = (float)(2.0D / (d9 + 1.0D));
|
||||
float f8 = 0.06F;
|
||||
this.moveFlying(0.0F, -1.0F, f8 * (f5 * f7 + (1.0F - f7)));
|
||||
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
|
||||
Vec3 vec32 = (new Vec3(this.motionX, this.motionY, this.motionZ)).normalize();
|
||||
float f9 = ((float)vec32.dotProduct(vec31) + 1.0F) / 2.0F;
|
||||
f9 = 0.8F + 0.15F * f9;
|
||||
this.motionX *= (double)f9;
|
||||
this.motionZ *= (double)f9;
|
||||
this.motionY *= 0.9100000262260437D;
|
||||
}
|
||||
|
||||
this.yawOffset = this.rotYaw;
|
||||
this.dragonPartHead.width = this.dragonPartHead.height = 3.0F;
|
||||
this.dragonPartTail1.width = this.dragonPartTail1.height = 2.0F;
|
||||
this.dragonPartTail2.width = this.dragonPartTail2.height = 2.0F;
|
||||
this.dragonPartTail3.width = this.dragonPartTail3.height = 2.0F;
|
||||
this.dragonPartBody.height = 3.0F;
|
||||
this.dragonPartBody.width = 5.0F;
|
||||
this.dragonPartWing1.height = 2.0F;
|
||||
this.dragonPartWing1.width = 4.0F;
|
||||
this.dragonPartWing2.height = 3.0F;
|
||||
this.dragonPartWing2.width = 4.0F;
|
||||
float f12 = (float)(this.getMovementOffsets(5, 1.0F)[1] - this.getMovementOffsets(10, 1.0F)[1]) * 10.0F / 180.0F * (float)Math.PI;
|
||||
float f2 = ExtMath.cos(f12);
|
||||
float f15 = -ExtMath.sin(f12);
|
||||
float f3 = this.rotYaw * (float)Math.PI / 180.0F;
|
||||
float f16 = ExtMath.sin(f3);
|
||||
float f4 = ExtMath.cos(f3);
|
||||
this.dragonPartBody.onUpdate();
|
||||
this.dragonPartBody.setLocationAndAngles(this.posX + (double)(f16 * 0.5F), this.posY, this.posZ - (double)(f4 * 0.5F), 0.0F, 0.0F);
|
||||
this.dragonPartWing1.onUpdate();
|
||||
this.dragonPartWing1.setLocationAndAngles(this.posX + (double)(f4 * 4.5F), this.posY + 2.0D, this.posZ + (double)(f16 * 4.5F), 0.0F, 0.0F);
|
||||
this.dragonPartWing2.onUpdate();
|
||||
this.dragonPartWing2.setLocationAndAngles(this.posX - (double)(f4 * 4.5F), this.posY + 2.0D, this.posZ - (double)(f16 * 4.5F), 0.0F, 0.0F);
|
||||
|
||||
if (!this.worldObj.client && this.hurtTime == 0)
|
||||
{
|
||||
this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.dragonPartWing1.getEntityBoundingBox().expand(4.0D, 2.0D, 4.0D).offset(0.0D, -2.0D, 0.0D)));
|
||||
this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.dragonPartWing2.getEntityBoundingBox().expand(4.0D, 2.0D, 4.0D).offset(0.0D, -2.0D, 0.0D)));
|
||||
if(Config.damageMobs)
|
||||
this.attackEntitiesInList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.dragonPartHead.getEntityBoundingBox().expand(1.0D, 1.0D, 1.0D)));
|
||||
}
|
||||
|
||||
double[] adouble1 = this.getMovementOffsets(5, 1.0F);
|
||||
double[] adouble = this.getMovementOffsets(0, 1.0F);
|
||||
float f18 = ExtMath.sin(this.rotYaw * (float)Math.PI / 180.0F - this.randomYawVelo * 0.01F);
|
||||
float f19 = ExtMath.cos(this.rotYaw * (float)Math.PI / 180.0F - this.randomYawVelo * 0.01F);
|
||||
this.dragonPartHead.onUpdate();
|
||||
this.dragonPartHead.setLocationAndAngles(this.posX + (double)(f18 * 5.5F * f2), this.posY + (adouble[1] - adouble1[1]) * 1.0D + (double)(f15 * 5.5F), this.posZ - (double)(f19 * 5.5F * f2), 0.0F, 0.0F);
|
||||
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
EntityDragonPart entitydragonpart = null;
|
||||
|
||||
if (j == 0)
|
||||
{
|
||||
entitydragonpart = this.dragonPartTail1;
|
||||
}
|
||||
|
||||
if (j == 1)
|
||||
{
|
||||
entitydragonpart = this.dragonPartTail2;
|
||||
}
|
||||
|
||||
if (j == 2)
|
||||
{
|
||||
entitydragonpart = this.dragonPartTail3;
|
||||
}
|
||||
|
||||
double[] adouble2 = this.getMovementOffsets(12 + j * 2, 1.0F);
|
||||
float f20 = this.rotYaw * (float)Math.PI / 180.0F + this.simplifyAngle(adouble2[0] - adouble1[0]) * (float)Math.PI / 180.0F * 1.0F;
|
||||
float f21 = ExtMath.sin(f20);
|
||||
float f22 = ExtMath.cos(f20);
|
||||
float f23 = 1.5F;
|
||||
float f24 = (float)(j + 1) * 2.0F;
|
||||
entitydragonpart.onUpdate();
|
||||
entitydragonpart.setLocationAndAngles(this.posX - (double)((f16 * f23 + f21 * f24) * f2), this.posY + (adouble2[1] - adouble1[1]) * 1.0D - (double)((f24 + f23) * f15) + 1.5D, this.posZ + (double)((f4 * f23 + f22 * f24) * f2), 0.0F, 0.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private void updateDragonEnderCrystal()
|
||||
// {
|
||||
// if (this.healingEnderCrystal != null)
|
||||
// {
|
||||
// if (this.healingEnderCrystal.dead)
|
||||
// {
|
||||
// if (!this.worldObj.client)
|
||||
// {
|
||||
// this.attackEntityFromPart(this.dragonPartHead, DamageSource.setExplosionSource((Explosion)null), 10);
|
||||
// }
|
||||
//
|
||||
// this.healingEnderCrystal = null;
|
||||
// }
|
||||
// else if (this.ticksExisted % 10 == 0 && this.getHealth() < this.getMaxHealth())
|
||||
// {
|
||||
// this.setHealth(this.getHealth() + 1);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (this.rand.chance(10))
|
||||
// {
|
||||
// float f = 32.0F;
|
||||
// List<EntityCrystal> list = this.worldObj.<EntityCrystal>getEntitiesWithinAABB(EntityCrystal.class, this.getEntityBoundingBox().expand((double)f, (double)f, (double)f));
|
||||
// EntityCrystal entityendercrystal = null;
|
||||
// double d0 = Double.MAX_VALUE;
|
||||
//
|
||||
// for (EntityCrystal entityendercrystal1 : list)
|
||||
// {
|
||||
// double d1 = entityendercrystal1.getDistanceSqToEntity(this);
|
||||
//
|
||||
// if (d1 < d0)
|
||||
// {
|
||||
// d0 = d1;
|
||||
// entityendercrystal = entityendercrystal1;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// this.healingEnderCrystal = entityendercrystal;
|
||||
// }
|
||||
// }
|
||||
|
||||
private void collideWithEntities(List<Entity> p_70970_1_)
|
||||
{
|
||||
double d0 = (this.dragonPartBody.getEntityBoundingBox().minX + this.dragonPartBody.getEntityBoundingBox().maxX) / 2.0D;
|
||||
double d1 = (this.dragonPartBody.getEntityBoundingBox().minZ + this.dragonPartBody.getEntityBoundingBox().maxZ) / 2.0D;
|
||||
|
||||
for (Entity entity : p_70970_1_)
|
||||
{
|
||||
if (entity instanceof EntityLiving)
|
||||
{
|
||||
double d2 = entity.posX - d0;
|
||||
double d3 = entity.posZ - d1;
|
||||
double d4 = d2 * d2 + d3 * d3;
|
||||
entity.addKnockback(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void attackEntitiesInList(List<Entity> p_70971_1_)
|
||||
{
|
||||
for (int i = 0; i < p_70971_1_.size(); ++i)
|
||||
{
|
||||
Entity entity = (Entity)p_70971_1_.get(i);
|
||||
|
||||
if (entity instanceof EntityLiving)
|
||||
{
|
||||
entity.attackEntityFrom(DamageSource.causeMobDamage(this), 10);
|
||||
this.applyEnchantments(this, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new target for the flight AI. It can be a random coordinate or a nearby player.
|
||||
*/
|
||||
private void setNewTarget()
|
||||
{
|
||||
this.forceNewTarget = false;
|
||||
List<EntityNPC> list = Lists.newArrayList(this.worldObj.players);
|
||||
// Iterator<EntityNPC> iterator = list.iterator();
|
||||
//
|
||||
// while (iterator.hasNext())
|
||||
// {
|
||||
// if (((EntityNPC)iterator.next()).isSpectator())
|
||||
// {
|
||||
// iterator.remove();
|
||||
// }
|
||||
// }
|
||||
|
||||
if (this.rand.chance(2) && !list.isEmpty())
|
||||
{
|
||||
this.target = this.rand.pick(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
this.targetX = 0.0D;
|
||||
this.targetY = (double)(70.0F + this.rand.floatv() * 50.0F);
|
||||
this.targetZ = 0.0D;
|
||||
this.targetX += (double)(this.rand.floatv() * 120.0F - 60.0F);
|
||||
this.targetZ += (double)(this.rand.floatv() * 120.0F - 60.0F);
|
||||
double d0 = this.posX - this.targetX;
|
||||
double d1 = this.posY - this.targetY;
|
||||
double d2 = this.posZ - this.targetZ;
|
||||
boolean flag = d0 * d0 + d1 * d1 + d2 * d2 > 100.0D;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.target = null;
|
||||
}
|
||||
}
|
||||
|
||||
private float simplifyAngle(double p_70973_1_)
|
||||
{
|
||||
return (float)ExtMath.wrapd(p_70973_1_);
|
||||
}
|
||||
|
||||
public boolean attackEntityFromPart(EntityDragonPart dragonPart, DamageSource source, int amount)
|
||||
{
|
||||
if (dragonPart != this.dragonPartHead)
|
||||
{
|
||||
amount = amount / 4 + 1;
|
||||
}
|
||||
|
||||
float f = this.rotYaw * (float)Math.PI / 180.0F;
|
||||
float f1 = ExtMath.sin(f);
|
||||
float f2 = ExtMath.cos(f);
|
||||
this.targetX = this.posX + (double)(f1 * 5.0F) + (double)((this.rand.floatv() - 0.5F) * 2.0F);
|
||||
this.targetY = this.posY + (double)(this.rand.floatv() * 3.0F) + 1.0D;
|
||||
this.targetZ = this.posZ - (double)(f2 * 5.0F) + (double)((this.rand.floatv() - 0.5F) * 2.0F);
|
||||
this.target = null;
|
||||
|
||||
// if ((source.getEntity() != null && source.getEntity().isPlayer()) || source.isExplosion())
|
||||
// {
|
||||
this.attackEntityFrom(source, amount);
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
// {
|
||||
// if (source instanceof EntityDamageSource && ((EntityDamageSource)source).getIsThornsDamage())
|
||||
// {
|
||||
// this.attackDragonFrom(source, amount);
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// protected boolean attackDragonFrom(DamageSource source, int amount)
|
||||
// {
|
||||
// return super.attackEntityFrom(source, amount);
|
||||
// }
|
||||
|
||||
// protected void onDeathUpdate()
|
||||
// {
|
||||
// super.onDeathUpdate();
|
||||
// if (this.deathTime == 20)
|
||||
// {
|
||||
// float f = (this.rand.floatv() - 0.5F) * 8.0F;
|
||||
// float f1 = (this.rand.floatv() - 0.5F) * 4.0F;
|
||||
// float f2 = (this.rand.floatv() - 0.5F) * 8.0F;
|
||||
// this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_HUGE, this.posX + (double)f, this.posY + 2.0D + (double)f1, this.posZ + (double)f2, 0.0D, 0.0D, 0.0D);
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void generatePortal(BlockPos pos)
|
||||
// {
|
||||
// int i = 4;
|
||||
// double d0 = 12.25D;
|
||||
// double d1 = 6.25D;
|
||||
//
|
||||
// for (int j = -1; j <= 32; ++j)
|
||||
// {
|
||||
// for (int k = -4; k <= 4; ++k)
|
||||
// {
|
||||
// for (int l = -4; l <= 4; ++l)
|
||||
// {
|
||||
// double d2 = (double)(k * k + l * l);
|
||||
//
|
||||
// if (d2 <= 12.25D)
|
||||
// {
|
||||
// BlockPos blockpos = pos.add(k, j, l);
|
||||
//
|
||||
// if (j < 0)
|
||||
// {
|
||||
// if (d2 <= 6.25D)
|
||||
// {
|
||||
// this.worldObj.setBlockState(blockpos, Blocks.obsidian.getDefaultState());
|
||||
// }
|
||||
// }
|
||||
// else if (j > 0)
|
||||
// {
|
||||
// this.worldObj.setBlockState(blockpos, Blocks.air.getDefaultState());
|
||||
// }
|
||||
// else if (d2 > 6.25D)
|
||||
// {
|
||||
// this.worldObj.setBlockState(blockpos, Blocks.obsidian.getDefaultState());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.worldObj.setBlockState(blockpos, Blocks.end_portal.getDefaultState());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// this.worldObj.setBlockState(pos, Blocks.obsidian.getDefaultState());
|
||||
// this.worldObj.setBlockState(pos.up(), Blocks.obsidian.getDefaultState());
|
||||
// BlockPos blockpos1 = pos.up(2);
|
||||
// this.worldObj.setBlockState(blockpos1, Blocks.obsidian.getDefaultState());
|
||||
// this.worldObj.setBlockState(blockpos1.west(), Blocks.torch.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.EAST));
|
||||
// this.worldObj.setBlockState(blockpos1.east(), Blocks.torch.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.WEST));
|
||||
// this.worldObj.setBlockState(blockpos1.north(), Blocks.torch.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.SOUTH));
|
||||
// this.worldObj.setBlockState(blockpos1.south(), Blocks.torch.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.NORTH));
|
||||
// this.worldObj.setBlockState(pos.up(3), Blocks.obsidian.getDefaultState());
|
||||
// this.worldObj.setBlockState(pos.up(4), Blocks.dragon_egg.getDefaultState());
|
||||
// }
|
||||
|
||||
// protected void despawnEntity()
|
||||
// {
|
||||
// }
|
||||
|
||||
public Entity[] getParts()
|
||||
{
|
||||
return this.dragonPartArray;
|
||||
}
|
||||
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return this.worldObj;
|
||||
}
|
||||
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return SoundEvent.DRAGON_IDLE;
|
||||
}
|
||||
|
||||
// protected Sounds getHurtSound()
|
||||
// {
|
||||
// return Sounds.MOB_DRAGON_HIT;
|
||||
// }
|
||||
//
|
||||
// protected Sounds getDeathSound()
|
||||
// {
|
||||
// return Sounds.MOB_DRAGON_HIT;
|
||||
// }
|
||||
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 5.0F;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 160;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xb900ff;
|
||||
}
|
||||
|
||||
public boolean isBoss() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean getCanSpawnHere() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return Alignment.LAWFUL_EVIL;
|
||||
}
|
||||
}
|
75
java/src/game/entity/animal/EntityDragonPart.java
Executable file
75
java/src/game/entity/animal/EntityDragonPart.java
Executable file
|
@ -0,0 +1,75 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.IEntityMultiPart;
|
||||
import game.nbt.NBTTagCompound;
|
||||
|
||||
public class EntityDragonPart extends Entity
|
||||
{
|
||||
/** The dragon entity this dragon part belongs to */
|
||||
public final IEntityMultiPart entityDragonObj;
|
||||
public final String partName;
|
||||
|
||||
public EntityDragonPart(IEntityMultiPart parent, String partName, float base, float sizeHeight)
|
||||
{
|
||||
super(parent.getWorld());
|
||||
this.setSize(base, sizeHeight);
|
||||
this.entityDragonObj = parent;
|
||||
this.partName = partName;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
return this.isEntityInvulnerable(source) ? false : this.entityDragonObj.attackEntityFromPart(this, source, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Entity argument is equal to this Entity
|
||||
*/
|
||||
public boolean isEntityEqual(Entity entityIn)
|
||||
{
|
||||
return this == entityIn || this.entityDragonObj == entityIn;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
}
|
1886
java/src/game/entity/animal/EntityHorse.java
Executable file
1886
java/src/game/entity/animal/EntityHorse.java
Executable file
File diff suppressed because it is too large
Load diff
90
java/src/game/entity/animal/EntityMooshroom.java
Executable file
90
java/src/game/entity/animal/EntityMooshroom.java
Executable file
|
@ -0,0 +1,90 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import game.entity.item.EntityItem;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Blocks;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemShears;
|
||||
import game.item.ItemStack;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityMooshroom extends EntityCow
|
||||
{
|
||||
public EntityMooshroom(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.9F, 1.3F);
|
||||
this.spawnableBlocks.clear();
|
||||
this.spawnableBlocks.add(Blocks.mycelium);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == Items.bowl && !this.isChild())
|
||||
{
|
||||
if (itemstack.stackSize == 1)
|
||||
{
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, new ItemStack(Items.mushroom_stew));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player.inventory.addItemStackToInventory(new ItemStack(Items.mushroom_stew))) // && !player.creative)
|
||||
{
|
||||
player.inventory.decrStackSize(player.inventory.currentItem, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemstack != null && itemstack.getItem() instanceof ItemShears && !this.isChild())
|
||||
{
|
||||
this.setDead();
|
||||
this.worldObj.spawnParticle(ParticleType.EXPLOSION_LARGE, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 0.0D, 0.0D, 0.0D);
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
EntityCow entitycow = new EntityCow(this.worldObj);
|
||||
entitycow.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, this.rotPitch);
|
||||
entitycow.setHealth(this.getHealth());
|
||||
entitycow.yawOffset = this.yawOffset;
|
||||
|
||||
if (this.hasCustomName())
|
||||
{
|
||||
entitycow.setCustomNameTag(this.getCustomNameTag());
|
||||
}
|
||||
|
||||
this.worldObj.spawnEntityInWorld(entitycow);
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.posX, this.posY + (double)this.height, this.posZ, new ItemStack(Blocks.red_mushroom)));
|
||||
}
|
||||
|
||||
itemstack.damageItem(1, player);
|
||||
this.playSound(SoundEvent.CUT, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.interact(player);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityMooshroom createChild(EntityLiving ageable)
|
||||
{
|
||||
return new EntityMooshroom(this.worldObj);
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x7c4c83;
|
||||
}
|
||||
}
|
132
java/src/game/entity/animal/EntityMouse.java
Executable file
132
java/src/game/entity/animal/EntityMouse.java
Executable file
|
@ -0,0 +1,132 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import game.ai.EntityAIFollowParent;
|
||||
import game.ai.EntityAILookIdle;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIPanic;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.block.Block;
|
||||
import game.entity.attributes.AttributeInstance;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Blocks;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemStack;
|
||||
import game.world.BlockPos;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityMouse extends EntityAnimal {
|
||||
public EntityMouse(World world) {
|
||||
super(world);
|
||||
this.setSize(0.3F, 0.2F);
|
||||
this.tasks.addTask(0, new EntityAISwimming(this));
|
||||
this.tasks.addTask(1, new EntityAIPanic(this, 1.4D));
|
||||
this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Items.sugar, false));
|
||||
this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
|
||||
this.tasks.addTask(5, new EntityAIWander(this, 1.0D));
|
||||
this.tasks.addTask(6, new EntityAIWatchClosest(this, null, 6.0F));
|
||||
this.tasks.addTask(7, new EntityAILookIdle(this));
|
||||
this.spawnableBlocks.clear();
|
||||
Collections.addAll(this.spawnableBlocks, Blocks.stone, Blocks.tian);
|
||||
}
|
||||
|
||||
public float getEyeHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(1);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.25D);
|
||||
}
|
||||
|
||||
// protected String getLivingSound() {
|
||||
// return "mob.mouse.idle";
|
||||
// }
|
||||
|
||||
protected SoundEvent getHurtSound() {
|
||||
return SoundEvent.RABBIT_HIT;
|
||||
}
|
||||
|
||||
protected SoundEvent getDeathSound() {
|
||||
return SoundEvent.RABBIT_HIT;
|
||||
}
|
||||
|
||||
protected void playStepSound(BlockPos pos, Block block) {
|
||||
}
|
||||
|
||||
protected float getSoundVolume() {
|
||||
return 0.3F;
|
||||
}
|
||||
|
||||
protected float getSoundPitch() {
|
||||
return (this.rand.floatv() - this.rand.floatv()) * 0.2F + (this.isChild() ? 1.8F : 1.6F);
|
||||
}
|
||||
|
||||
protected void dropFewItems(boolean hit, int looting) {
|
||||
int amt = this.rand.zrange(2);
|
||||
if(looting > 0) {
|
||||
amt += this.rand.zrange(looting + 1);
|
||||
}
|
||||
for(int z = 0; z < amt; z++) {
|
||||
this.dropItem(Items.string, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityMouse createChild(EntityLiving parent) {
|
||||
return new EntityMouse(this.worldObj);
|
||||
}
|
||||
|
||||
public boolean isBreedingItem(ItemStack stack) {
|
||||
return stack != null && stack.getItem() == Items.sugar;
|
||||
}
|
||||
|
||||
protected int getExperiencePoints(EntityNPC player) {
|
||||
return this.worldObj.rand.range(0, 1);
|
||||
}
|
||||
|
||||
public boolean getCanSpawnHere()
|
||||
{
|
||||
if (((int)this.getEntityBoundingBox().minY) >= this.worldObj.getSeaLevel())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.getCanSpawnHere();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isValidLightLevel(int level)
|
||||
{
|
||||
return level < 6;
|
||||
}
|
||||
|
||||
public float getBlockPathWeight(BlockPos pos)
|
||||
{
|
||||
return 0.5F - this.worldObj.getLightBrightness(pos);
|
||||
}
|
||||
|
||||
public void setCustomNameTag(String name) {
|
||||
super.setCustomNameTag(name);
|
||||
if(this.worldObj != null && !this.worldObj.client) {
|
||||
AttributeInstance speed = this.getEntityAttribute(Attributes.MOVEMENT_SPEED);
|
||||
speed.removeModifier(Attributes.MOUSE_SPEEDY_MOD);
|
||||
if(name.equals("Gonzales") || name.equals("Gonzalez"))
|
||||
speed.applyModifier(Attributes.MOUSE_SPEEDY_MOD);
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x888888;
|
||||
}
|
||||
}
|
419
java/src/game/entity/animal/EntityOcelot.java
Executable file
419
java/src/game/entity/animal/EntityOcelot.java
Executable file
|
@ -0,0 +1,419 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import game.ai.EntityAIAvoidEntity;
|
||||
import game.ai.EntityAIFollowOwner;
|
||||
import game.ai.EntityAILeapAtTarget;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIOcelotAttack;
|
||||
import game.ai.EntityAIOcelotSit;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITargetNonTamed;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.npc.Alignment;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityTameable;
|
||||
import game.init.Config;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.Item;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.pathfinding.PathNavigateGround;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityOcelot extends EntityTameable
|
||||
{
|
||||
private EntityAIAvoidEntity<EntityNPC> avoidEntity;
|
||||
|
||||
/**
|
||||
* The tempt AI task for this mob, used to prevent taming while it is fleeing.
|
||||
*/
|
||||
private EntityAITempt aiTempt;
|
||||
private boolean wasTempted;
|
||||
|
||||
public EntityOcelot(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.6F, 0.7F);
|
||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(2, this.aiSit);
|
||||
this.tasks.addTask(3, this.aiTempt = new EntityAITempt(this, 0.6D, Items.fish, true));
|
||||
this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 5.0F));
|
||||
this.tasks.addTask(6, new EntityAIOcelotSit(this, 0.8D));
|
||||
this.tasks.addTask(7, new EntityAILeapAtTarget(this, 0.3F));
|
||||
this.tasks.addTask(8, new EntityAIOcelotAttack(this));
|
||||
this.tasks.addTask(9, new EntityAIMate(this, 0.8D));
|
||||
this.tasks.addTask(10, new EntityAIWander(this, 0.8D));
|
||||
this.tasks.addTask(11, new EntityAIWatchClosest(this, null, 10.0F));
|
||||
this.targets.addTask(1, new EntityAITargetNonTamed(this, EntityAnimal.class, false, new Predicate<EntityAnimal>() {
|
||||
public boolean test(EntityAnimal entity) {
|
||||
return entity instanceof EntityChicken || entity instanceof EntityMouse;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, Byte.valueOf((byte)0));
|
||||
}
|
||||
|
||||
public void updateAITasks()
|
||||
{
|
||||
if (this.getMoveHelper().isUpdating())
|
||||
{
|
||||
double d0 = this.getMoveHelper().getSpeed();
|
||||
|
||||
if (d0 == 0.6D)
|
||||
{
|
||||
this.setSneaking(this.wasTempted);
|
||||
this.setSprinting(false);
|
||||
this.wasTempted = true;
|
||||
}
|
||||
else if (d0 == 1.33D)
|
||||
{
|
||||
this.setSneaking(false);
|
||||
this.setSprinting(true);
|
||||
this.wasTempted = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setSneaking(false);
|
||||
this.setSprinting(false);
|
||||
this.wasTempted = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setSneaking(false);
|
||||
this.setSprinting(false);
|
||||
this.wasTempted = false;
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Determines if an entity can be despawned, used on idle far away entities
|
||||
// */
|
||||
// protected boolean canDespawn()
|
||||
// {
|
||||
// return !this.isTamed() && this.ticksExisted > 2400;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(10);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("CatType", this.getTameSkin());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setTameSkin(tagCompund.getInteger("CatType"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return this.isTamed() ? (this.isInLove() ? SoundEvent.CAT_PURREOW : (this.rand.chance(4) ? SoundEvent.CAT_PURREOW : SoundEvent.CAT_MEOW)) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return SoundEvent.CAT_HIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return SoundEvent.CAT_HIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
protected Item getDropItem()
|
||||
{
|
||||
return Items.leather;
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity entityIn)
|
||||
{
|
||||
if(!this.worldObj.client && !Config.damageMobs)
|
||||
return false;
|
||||
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.aiSit.setSitting(false);
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (this.isOwner(player) && !this.worldObj.client && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
}
|
||||
}
|
||||
else if (this.aiTempt.isRunning() && itemstack != null && itemstack.getItem() == Items.fish && player.getDistanceSqToEntity(this) < 9.0D)
|
||||
{
|
||||
// if (!player.creative)
|
||||
// {
|
||||
--itemstack.stackSize;
|
||||
// }
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
if (this.rand.chance(3))
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.setTameSkin(this.worldObj.rand.roll(3));
|
||||
// this.setOwnerId(player.getUser());
|
||||
this.playTameEffect(true);
|
||||
this.aiSit.setSitting(true);
|
||||
this.worldObj.setEntityState(this, (byte)7);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte)6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(player);
|
||||
}
|
||||
|
||||
public EntityOcelot createChild(EntityLiving ageable)
|
||||
{
|
||||
EntityOcelot entityocelot = new EntityOcelot(this.worldObj);
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
// entityocelot.setOwnerId(this.getOwnerId());
|
||||
entityocelot.setTamed(true);
|
||||
entityocelot.setTameSkin(this.getTameSkin());
|
||||
}
|
||||
|
||||
return entityocelot;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 stack)
|
||||
{
|
||||
return stack != null && stack.getItem() == Items.fish;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal otherAnimal)
|
||||
{
|
||||
if (otherAnimal == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// else if (!this.isTamed())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
else if (!(otherAnimal instanceof EntityOcelot))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntityOcelot entityocelot = (EntityOcelot)otherAnimal;
|
||||
return (entityocelot.isTamed() != this.isTamed()) ? false : this.isInLove() && entityocelot.isInLove();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTameSkin()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(18);
|
||||
}
|
||||
|
||||
public void setTameSkin(int skinId)
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Byte.valueOf((byte)skinId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity's current position is a valid location to spawn this entity.
|
||||
*/
|
||||
public boolean getCanSpawnHere()
|
||||
{
|
||||
return this.worldObj.rand.rarity(3);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Checks that the entity is not colliding with any blocks / liquids
|
||||
// */
|
||||
// public boolean isNotColliding()
|
||||
// {
|
||||
// if (this.worldObj.checkNoEntityCollision(this.getEntityBoundingBox(), this) && this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty() && !this.worldObj.isAnyLiquid(this.getEntityBoundingBox()))
|
||||
// {
|
||||
// BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ);
|
||||
//
|
||||
// if (blockpos.getY() < this.worldObj.getSeaLevel())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// Block block = this.worldObj.getBlockState(blockpos.down()).getBlock();
|
||||
//
|
||||
// if (block == Blocks.grass || block.getMaterial() == Material.leaves)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the name of this object. For players this returns their username
|
||||
*/
|
||||
public String getTypeName()
|
||||
{
|
||||
return this.hasCustomName() ? this.getCustomNameTag() : (this.isTamed() ? "Katze" : super.getTypeName());
|
||||
}
|
||||
|
||||
public void setTamed(boolean tamed)
|
||||
{
|
||||
super.setTamed(tamed);
|
||||
}
|
||||
|
||||
protected void setupTamedAI()
|
||||
{
|
||||
if (this.avoidEntity == null)
|
||||
{
|
||||
this.avoidEntity = new EntityAIAvoidEntity(this, EntityNPC.class,
|
||||
// new Predicate<EntityNPC>() {
|
||||
// public boolean apply(EntityNPC entity) {
|
||||
// return !entity.capabilities.disableTarget;
|
||||
// }
|
||||
// } ,
|
||||
16.0F, 0.8D, 1.33D);
|
||||
}
|
||||
|
||||
this.tasks.removeTask(this.avoidEntity);
|
||||
|
||||
if (!this.isTamed())
|
||||
{
|
||||
this.tasks.addTask(4, this.avoidEntity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Object onInitialSpawn(Object livingdata)
|
||||
{
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
|
||||
if (this.worldObj.rand.chance(7))
|
||||
{
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
EntityOcelot entityocelot = new EntityOcelot(this.worldObj);
|
||||
entityocelot.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, 0.0F);
|
||||
entityocelot.setGrowingAge(-24000);
|
||||
this.worldObj.spawnEntityInWorld(entityocelot);
|
||||
}
|
||||
}
|
||||
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
public int getLeashColor() {
|
||||
return this.isTamed() ? 0xf02020 : super.getLeashColor();
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return this.isTamed() ? 0xdeb059 : 0xffe15b;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return this.isTamed() ? Alignment.CHAOTIC_GOOD : Alignment.CHAOTIC;
|
||||
}
|
||||
}
|
251
java/src/game/entity/animal/EntityPig.java
Executable file
251
java/src/game/entity/animal/EntityPig.java
Executable file
|
@ -0,0 +1,251 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import game.ai.EntityAIControlledByPlayer;
|
||||
import game.ai.EntityAIFollowParent;
|
||||
import game.ai.EntityAILookIdle;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIPanic;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.Item;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.pathfinding.PathNavigateGround;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityPig extends EntityAnimal
|
||||
{
|
||||
/** AI task for player control. */
|
||||
private final EntityAIControlledByPlayer aiControlledByPlayer;
|
||||
|
||||
public EntityPig(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.9F, 0.9F);
|
||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
||||
this.tasks.addTask(0, new EntityAISwimming(this));
|
||||
this.tasks.addTask(1, new EntityAIPanic(this, 1.25D));
|
||||
this.tasks.addTask(2, this.aiControlledByPlayer = new EntityAIControlledByPlayer(this, 0.3F));
|
||||
this.tasks.addTask(3, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(4, new EntityAITempt(this, 1.2D, Items.carrot_on_a_stick, false));
|
||||
this.tasks.addTask(4, new EntityAITempt(this, 1.2D, Items.carrot, false));
|
||||
this.tasks.addTask(5, new EntityAIFollowParent(this, 1.1D));
|
||||
this.tasks.addTask(6, new EntityAIWander(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWatchClosest(this, null, 6.0F));
|
||||
this.tasks.addTask(8, new EntityAILookIdle(this));
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(10);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.25D);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if all the conditions for steering the entity are met. For pigs, this is true if it is being ridden
|
||||
* by a player and the player is holding a carrot-on-a-stick
|
||||
*/
|
||||
public boolean canBeSteered()
|
||||
{
|
||||
ItemStack itemstack = ((EntityNPC)this.passenger).getHeldItem();
|
||||
return itemstack != null && itemstack.getItem() == Items.carrot_on_a_stick;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setBoolean("Saddle", this.getSaddled());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setSaddled(tagCompund.getBoolean("Saddle"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return SoundEvent.PIG_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return SoundEvent.PIG_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return SoundEvent.PIG_DEATH;
|
||||
}
|
||||
|
||||
// protected void playStepSound(BlockPos pos, Block blockIn)
|
||||
// {
|
||||
// this.playSound("mob.pig.step", 0.15F, 1.0F);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (super.interact(player))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!this.getSaddled() || this.worldObj.client || this.passenger != null && this.passenger != player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
player.mountEntity(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected Item getDropItem()
|
||||
{
|
||||
return this.isBurning() ? Items.cooked_porkchop : Items.porkchop;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.roll(3) + this.rand.zrange(1 + lootingModifier);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
if (this.isBurning())
|
||||
{
|
||||
this.dropItem(Items.cooked_porkchop, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dropItem(Items.porkchop, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getSaddled())
|
||||
{
|
||||
this.dropItem(Items.saddle, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the pig is saddled.
|
||||
*/
|
||||
public boolean getSaddled()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or remove the saddle of the pig.
|
||||
*/
|
||||
public void setSaddled(boolean saddled)
|
||||
{
|
||||
if (saddled)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)1));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)0));
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Called when a lightning bolt hits the entity.
|
||||
// */
|
||||
// public void onStruckByLightning(EntityLightning lightningBolt)
|
||||
// {
|
||||
// if (!this.worldObj.client && !this.dead && Config.convertPigman)
|
||||
// {
|
||||
// EntityMobNPC entitypigzombie = new EntityMobNPC(this.worldObj);
|
||||
// entitypigzombie.setItem(0, new ItemStack(Items.golden_sword));
|
||||
// entitypigzombie.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, this.rotPitch);
|
||||
// entitypigzombie.setNoAI(this.isAIDisabled());
|
||||
//
|
||||
// if (this.hasCustomName())
|
||||
// {
|
||||
// entitypigzombie.setCustomNameTag(this.getCustomNameTag());
|
||||
// entitypigzombie.setAlwaysRenderNameTag(this.getAlwaysRenderNameTag());
|
||||
// }
|
||||
//
|
||||
// this.worldObj.spawnEntityInWorld(entitypigzombie);
|
||||
// this.setDead();
|
||||
// }
|
||||
// }
|
||||
|
||||
// public void fall(float distance, float damageMultiplier)
|
||||
// {
|
||||
// super.fall(distance, damageMultiplier);
|
||||
//
|
||||
// if (distance > 5.0F && this.passenger.isPlayer())
|
||||
// {
|
||||
// ((EntityNPC)this.passenger).triggerAchievement(AchievementList.flyPig);
|
||||
// }
|
||||
// }
|
||||
|
||||
public EntityPig createChild(EntityLiving ageable)
|
||||
{
|
||||
return new EntityPig(this.worldObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 stack)
|
||||
{
|
||||
return stack != null && stack.getItem() == Items.carrot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AI task for player control.
|
||||
*/
|
||||
public EntityAIControlledByPlayer getAIControlledByPlayer()
|
||||
{
|
||||
return this.aiControlledByPlayer;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xe78e8e;
|
||||
}
|
||||
}
|
581
java/src/game/entity/animal/EntityRabbit.java
Executable file
581
java/src/game/entity/animal/EntityRabbit.java
Executable file
|
@ -0,0 +1,581 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIAttackOnCollide;
|
||||
import game.ai.EntityAIAvoidEntity;
|
||||
import game.ai.EntityAIHurtByTarget;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIMoveToBlock;
|
||||
import game.ai.EntityAINearestAttackableTarget;
|
||||
import game.ai.EntityAIPanic;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.ai.EntityJumpHelper;
|
||||
import game.ai.EntityMoveHelper;
|
||||
import game.block.Block;
|
||||
import game.block.BlockTallGrass;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.npc.Alignment;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.BlockRegistry;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.ItemRegistry;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.Item;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.pathfinding.PathEntity;
|
||||
import game.pathfinding.PathNavigateGround;
|
||||
import game.potion.Potion;
|
||||
import game.potion.PotionEffect;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.State;
|
||||
import game.world.Vec3;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityRabbit extends EntityAnimal {
|
||||
private static final int TYPES = 10;
|
||||
|
||||
private EntityRabbit.AIAvoidEntity<EntityWolf> aiAvoidWolves;
|
||||
private int jumpRotTimer = 0;
|
||||
private int jumpRotFactor = 0;
|
||||
private boolean jumped = false;
|
||||
private boolean attacking = false;
|
||||
private int moveDuration = 0;
|
||||
private EntityRabbit.EnumMoveType moveType = EntityRabbit.EnumMoveType.HOP;
|
||||
private int foodCooldown = 0;
|
||||
|
||||
public EntityRabbit(World world) {
|
||||
super(world);
|
||||
this.setSize(0.6F, 0.7F);
|
||||
this.jumpHelper = new EntityRabbit.RabbitJumpHelper(this);
|
||||
this.moveHelper = new EntityRabbit.RabbitMoveHelper(this);
|
||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
||||
this.navigator.setHeightRequirement(2.5F);
|
||||
this.tasks.addTask(1, new EntityAISwimming(this));
|
||||
this.tasks.addTask(1, new EntityRabbit.AIPanic(this, 1.33D));
|
||||
this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.carrot, false));
|
||||
this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_carrot, false));
|
||||
this.tasks.addTask(2, new EntityAITempt(this, 1.0D, ItemRegistry.getItemFromBlock(Blocks.flower), false));
|
||||
this.tasks.addTask(3, new EntityAIMate(this, 0.8D) {
|
||||
protected int getMatingCooldown() {
|
||||
return EntityRabbit.this.rand.excl(50, 200);
|
||||
}
|
||||
});
|
||||
this.tasks.addTask(4, new EntityRabbit.AIRaidFarm(this));
|
||||
this.tasks.addTask(5, new EntityAIWander(this, 0.6D));
|
||||
this.tasks.addTask(11, new EntityAIWatchClosest(this, null, 10.0F));
|
||||
this.aiAvoidWolves = new EntityRabbit.AIAvoidEntity(this, EntityWolf.class, 16.0F, 1.33D, 1.33D);
|
||||
this.tasks.addTask(4, this.aiAvoidWolves);
|
||||
this.setMovementSpeed(0.0D);
|
||||
}
|
||||
|
||||
protected float getJumpUpwardsMotion() {
|
||||
return this.moveHelper.isUpdating() && this.moveHelper.getY() > this.posY + 0.5D ? 0.5F : this.moveType.getUpwardsMotion();
|
||||
}
|
||||
|
||||
public void setMoveType(EntityRabbit.EnumMoveType type) {
|
||||
this.moveType = type;
|
||||
}
|
||||
|
||||
public float getJumpRotation(float delta) {
|
||||
return this.jumpRotFactor == 0 ? 0.0F : ((float)this.jumpRotTimer + delta) / (float)this.jumpRotFactor;
|
||||
}
|
||||
|
||||
public void setMovementSpeed(double newSpeed) {
|
||||
this.getNavigator().setSpeed(newSpeed);
|
||||
this.moveHelper.setMoveTo(this.moveHelper.getX(), this.moveHelper.getY(), this.moveHelper.getZ(), newSpeed);
|
||||
}
|
||||
|
||||
public void setJumping(boolean jump, EntityRabbit.EnumMoveType moveTypeIn) {
|
||||
super.setJumping(jump);
|
||||
if(!jump) {
|
||||
if(this.moveType == EntityRabbit.EnumMoveType.ATTACK)
|
||||
this.moveType = EntityRabbit.EnumMoveType.HOP;
|
||||
}
|
||||
else {
|
||||
this.setMovementSpeed(1.5D * (double)moveTypeIn.getSpeed());
|
||||
this.playSound(SoundEvent.RABBIT_JUMP, this.getSoundVolume(), ((this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F) * 0.8F);
|
||||
}
|
||||
this.jumped = jump;
|
||||
}
|
||||
|
||||
public void doMovementAction(EntityRabbit.EnumMoveType movetype) {
|
||||
this.setJumping(true, movetype);
|
||||
this.jumpRotFactor = movetype.getRotationFactor();
|
||||
this.jumpRotTimer = 0;
|
||||
}
|
||||
|
||||
public boolean hasJumped() {
|
||||
return this.jumped;
|
||||
}
|
||||
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, Byte.valueOf((byte)0));
|
||||
}
|
||||
|
||||
public void updateAITasks() {
|
||||
if(this.moveHelper.getSpeed() > 0.8D)
|
||||
this.setMoveType(EntityRabbit.EnumMoveType.SPRINT);
|
||||
else if(this.moveType != EntityRabbit.EnumMoveType.ATTACK)
|
||||
this.setMoveType(EntityRabbit.EnumMoveType.HOP);
|
||||
if(this.moveDuration > 0)
|
||||
--this.moveDuration;
|
||||
if(this.foodCooldown > 0) {
|
||||
this.foodCooldown -= this.rand.zrange(3);
|
||||
if(this.foodCooldown < 0)
|
||||
this.foodCooldown = 0;
|
||||
}
|
||||
if(this.onGround) {
|
||||
if(!this.attacking) {
|
||||
this.setJumping(false, EntityRabbit.EnumMoveType.NONE);
|
||||
this.moveDuration = this.getMoveTypeDuration();
|
||||
((EntityRabbit.RabbitJumpHelper)this.jumpHelper).setWasJumping(false);
|
||||
}
|
||||
if(this.getRabbitType() == 99 && this.moveDuration == 0) {
|
||||
EntityLiving target = this.getAttackTarget();
|
||||
if(target != null && this.getDistanceSqToEntity(target) < 16.0D) {
|
||||
this.calculateRotationYaw(target.posX, target.posZ);
|
||||
this.moveHelper.setMoveTo(target.posX, target.posY, target.posZ, this.moveHelper.getSpeed());
|
||||
this.doMovementAction(EntityRabbit.EnumMoveType.ATTACK);
|
||||
this.attacking = true;
|
||||
}
|
||||
}
|
||||
EntityRabbit.RabbitJumpHelper jumpHelper = (EntityRabbit.RabbitJumpHelper)this.jumpHelper;
|
||||
if(!jumpHelper.getIsJumping()) {
|
||||
if(this.moveHelper.isUpdating() && this.moveDuration == 0) {
|
||||
PathEntity pathentity = this.navigator.getPath();
|
||||
Vec3 vec3 = new Vec3(this.moveHelper.getX(), this.moveHelper.getY(), this.moveHelper.getZ());
|
||||
if(pathentity != null && pathentity.getCurrentPathIndex() < pathentity.getCurrentPathLength()) {
|
||||
vec3 = pathentity.getPosition(this);
|
||||
}
|
||||
this.calculateRotationYaw(vec3.xCoord, vec3.zCoord);
|
||||
this.doMovementAction(this.moveType);
|
||||
}
|
||||
}
|
||||
else if(!jumpHelper.getWasJumping()) {
|
||||
((EntityRabbit.RabbitJumpHelper)this.jumpHelper).setWasJumping(true);
|
||||
}
|
||||
}
|
||||
this.attacking = this.onGround;
|
||||
}
|
||||
|
||||
public void spawnRunningParticles() {
|
||||
}
|
||||
|
||||
private void calculateRotationYaw(double x, double z) {
|
||||
this.rotYaw = (float)(ExtMath.atan2(z - this.posZ, x - this.posX) * 180.0D / Math.PI) - 90.0F;
|
||||
}
|
||||
|
||||
public void onLivingUpdate() {
|
||||
super.onLivingUpdate();
|
||||
if(this.jumpRotTimer != this.jumpRotFactor) {
|
||||
if(this.jumpRotTimer == 0 && !this.worldObj.client)
|
||||
this.worldObj.setEntityState(this, (byte)1);
|
||||
++this.jumpRotTimer;
|
||||
}
|
||||
else if(this.jumpRotFactor != 0) {
|
||||
this.jumpRotTimer = 0;
|
||||
this.jumpRotFactor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(5);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
|
||||
}
|
||||
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound) {
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("RabbitType", this.getRabbitType());
|
||||
tagCompound.setInteger("MoreCarrotTicks", this.foodCooldown);
|
||||
}
|
||||
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund) {
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setRabbitType(tagCompund.getInteger("RabbitType"));
|
||||
this.foodCooldown = tagCompund.getInteger("MoreCarrotTicks");
|
||||
}
|
||||
|
||||
// protected String getJumpingSound() {
|
||||
// return "mob.rabbit.hop";
|
||||
// }
|
||||
|
||||
protected SoundEvent getLivingSound() {
|
||||
return SoundEvent.RABBIT_IDLE;
|
||||
}
|
||||
|
||||
protected SoundEvent getHurtSound() {
|
||||
return SoundEvent.RABBIT_HIT;
|
||||
}
|
||||
|
||||
protected SoundEvent getDeathSound() {
|
||||
return SoundEvent.RABBIT_DEATH;
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity entityIn) {
|
||||
if(!this.worldObj.client && !Config.damageMobs)
|
||||
return false;
|
||||
if(this.getRabbitType() == 99) {
|
||||
// this.playSound("mob.attack", 1.0F, (this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F);
|
||||
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), 8);
|
||||
}
|
||||
else {
|
||||
return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalArmorValue() {
|
||||
return this.getRabbitType() == 99 ? 8 : super.getTotalArmorValue();
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, int amount) {
|
||||
return this.isEntityInvulnerable(source) ? false : super.attackEntityFrom(source, amount);
|
||||
}
|
||||
|
||||
// protected void addRandomDrop() {
|
||||
// this.entityDropItem(new ItemStack(Items.rabbit_foot, 1), 0.0F);
|
||||
// }
|
||||
|
||||
protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) {
|
||||
int amt = this.rand.zrange(2) + this.rand.zrange(1 + lootingModifier);
|
||||
for(int j = 0; j < amt; ++j) {
|
||||
this.dropItem(Items.carrot, 1);
|
||||
}
|
||||
// amt = this.rand.zrange(2);
|
||||
// for(int k = 0; k < amt; ++k) {
|
||||
// if(this.isBurning())
|
||||
// this.dropItem(Items.cooked_rabbit, 1);
|
||||
// else
|
||||
// this.dropItem(Items.rabbit, 1);
|
||||
// }
|
||||
}
|
||||
|
||||
private boolean isRabbitBreedingItem(Item itemIn) {
|
||||
return itemIn == Items.carrot || itemIn == Items.golden_carrot || itemIn == ItemRegistry.getItemFromBlock(Blocks.flower);
|
||||
}
|
||||
|
||||
public EntityRabbit createChild(EntityLiving ageable) {
|
||||
EntityRabbit rabbit = new EntityRabbit(this.worldObj);
|
||||
if(ageable instanceof EntityRabbit)
|
||||
rabbit.setRabbitType(this.rand.chance() ? this.getRabbitType() : ((EntityRabbit)ageable).getRabbitType());
|
||||
return rabbit;
|
||||
}
|
||||
|
||||
public boolean isBreedingItem(ItemStack stack) {
|
||||
return stack != null && this.isRabbitBreedingItem(stack.getItem());
|
||||
}
|
||||
|
||||
public int getRabbitType() {
|
||||
return this.dataWatcher.getWatchableObjectByte(18);
|
||||
}
|
||||
|
||||
public void setRabbitType(int type) {
|
||||
if(type == 99) {
|
||||
this.tasks.removeTask(this.aiAvoidWolves);
|
||||
this.tasks.addTask(4, new EntityRabbit.AIEvilAttack(this));
|
||||
this.targets.addTask(1, new EntityAIHurtByTarget(this, false));
|
||||
this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityNPC.class, true));
|
||||
this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityWolf.class, true));
|
||||
// if(!this.hasCustomName())
|
||||
// this.setCustomNameTag(I18n.formatKey("entity.KillerBunny.name"));
|
||||
}
|
||||
this.dataWatcher.updateObject(18, Byte.valueOf((byte)type));
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return !this.hasCustomName() && this.getRabbitType() == 99 ? "Killer-Kaninchen" : super.getTypeName();
|
||||
}
|
||||
|
||||
public Object onInitialSpawn(Object livingdata) {
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
int type = Config.killerBunnyChance > 0 && this.rand.chance(Config.killerBunnyChance) ? 99 : this.rand.zrange(TYPES);
|
||||
boolean typeSet = false;
|
||||
if(livingdata instanceof EntityRabbit.RabbitTypeData) {
|
||||
type = ((EntityRabbit.RabbitTypeData)livingdata).typeData;
|
||||
typeSet = true;
|
||||
}
|
||||
else {
|
||||
livingdata = new EntityRabbit.RabbitTypeData(type);
|
||||
}
|
||||
this.setRabbitType(type);
|
||||
if(type == 99) {
|
||||
this.setMaxHealth(15);
|
||||
this.setHealth(this.getMaxHealth());
|
||||
}
|
||||
if(typeSet && this.rand.chance())
|
||||
this.setGrowingAge(-24000);
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
private boolean canEatMore() {
|
||||
return this.foodCooldown == 0;
|
||||
}
|
||||
|
||||
protected int getMoveTypeDuration() {
|
||||
return this.moveType.getDuration();
|
||||
}
|
||||
|
||||
protected void consumeBlock(BlockPos pos, State state) {
|
||||
this.worldObj.setEntityState(this, (byte)19);
|
||||
this.foodCooldown = this.rand.excl(10, this.isChild() ? 20 : 50);
|
||||
if(this.isChild())
|
||||
this.grow(this.rand.range(250, 350));
|
||||
if(Config.rabbitMateChance > 0 && this.rand.chance(Config.rabbitMateChance) && this.getGrowingAge() == 0 && !this.isInLove() &&
|
||||
!this.worldObj.getEntitiesWithinAABB(EntityRabbit.class, this.getEntityBoundingBox().expand(15.0f, 15.0f, 15.0f), new Predicate<EntityRabbit>() {
|
||||
public boolean test(EntityRabbit entity) {
|
||||
return entity != EntityRabbit.this && entity.getGrowingAge() == 0;
|
||||
}
|
||||
}).isEmpty())
|
||||
this.setInLove(null);
|
||||
if(state.getBlock() == Blocks.blue_mushroom)
|
||||
this.addEffect(new PotionEffect(Potion.moveSpeed.id, this.rand.range(400, 2600), this.rand.chance(0, 1, 5)));
|
||||
this.worldObj.destroyBlock(pos, false);
|
||||
this.worldObj.setState(pos, Blocks.air.getState(), 2);
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id) {
|
||||
if(id == 1) {
|
||||
this.createRunningParticles();
|
||||
this.jumpRotFactor = 10;
|
||||
this.jumpRotTimer = 0;
|
||||
}
|
||||
else if(id == 19) {
|
||||
this.worldObj.spawnParticle(ParticleType.BLOCK_DUST,
|
||||
this.posX + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width,
|
||||
this.posY + 0.5D + (double)(this.rand.floatv() * this.height),
|
||||
this.posZ + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, 0.0D, 0.0D, 0.0D,
|
||||
BlockRegistry.getStateId(this.worldObj.getState(this.getPosition())));
|
||||
}
|
||||
else {
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xd4d499;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return this.getRabbitType() == 99 ? Alignment.CHAOTIC_EVIL : super.getAlignment();
|
||||
}
|
||||
|
||||
static class AIAvoidEntity<T extends Entity> extends EntityAIAvoidEntity<T> {
|
||||
private EntityRabbit entity;
|
||||
|
||||
public AIAvoidEntity(EntityRabbit rabbit, Class<T> toAvoid, float distance, double farSpeed, double nearSpeed) {
|
||||
super(rabbit, toAvoid, distance, farSpeed, nearSpeed);
|
||||
this.entity = rabbit;
|
||||
}
|
||||
|
||||
// public void updateTask() {
|
||||
// super.updateTask();
|
||||
// }
|
||||
}
|
||||
|
||||
static class AIEvilAttack extends EntityAIAttackOnCollide {
|
||||
public AIEvilAttack(EntityRabbit rabbit) {
|
||||
super(rabbit, EntityLiving.class, 1.4D, true);
|
||||
}
|
||||
|
||||
protected double getAttackRange(EntityLiving attackTarget) {
|
||||
return (double)(4.0F + attackTarget.width);
|
||||
}
|
||||
}
|
||||
|
||||
static class AIPanic extends EntityAIPanic {
|
||||
private EntityRabbit entity;
|
||||
|
||||
public AIPanic(EntityRabbit rabbit, double speedIn) {
|
||||
super(rabbit, speedIn);
|
||||
this.entity = rabbit;
|
||||
}
|
||||
|
||||
public void updateTask() {
|
||||
super.updateTask();
|
||||
this.entity.setMovementSpeed(this.speed);
|
||||
}
|
||||
}
|
||||
|
||||
static class AIRaidFarm extends EntityAIMoveToBlock {
|
||||
private final EntityRabbit entity;
|
||||
private boolean isHungry;
|
||||
private boolean foodFound = false;
|
||||
|
||||
public AIRaidFarm(EntityRabbit rabbitIn) {
|
||||
super(rabbitIn, 0.699999988079071D, 16);
|
||||
this.entity = rabbitIn;
|
||||
this.runDelay = this.entity.getRNG().excl(10, 40);
|
||||
}
|
||||
|
||||
public boolean shouldExecute() {
|
||||
if(this.runDelay <= 0) {
|
||||
if(!Config.mobGrief)
|
||||
return false;
|
||||
this.foodFound = false;
|
||||
this.isHungry = this.entity.canEatMore();
|
||||
}
|
||||
if(this.runDelay > 0) {
|
||||
--this.runDelay;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
this.runDelay = this.entity.getRNG().excl(10, 40);
|
||||
return this.searchForDestination();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean continueExecuting() {
|
||||
return this.foodFound && super.continueExecuting();
|
||||
}
|
||||
|
||||
public void startExecuting() {
|
||||
super.startExecuting();
|
||||
}
|
||||
|
||||
public void resetTask() {
|
||||
super.resetTask();
|
||||
}
|
||||
|
||||
public void updateTask() {
|
||||
super.updateTask();
|
||||
this.entity.getLookHelper().setLookPosition((double)this.destinationBlock.getX() + 0.5D, (double)(this.destinationBlock.getY() + 1),
|
||||
(double)this.destinationBlock.getZ() + 0.5D, 10.0F, (float)this.entity.getVerticalFaceSpeed());
|
||||
if(this.getIsAboveDestination()) {
|
||||
World world = this.entity.worldObj;
|
||||
BlockPos pos = Config.rabidRabbits ? this.destinationBlock : this.destinationBlock.up();
|
||||
State state = world.getState(pos);
|
||||
// Block block = iblockstate.getBlock();
|
||||
if(this.foodFound && canEat(state) && Config.mobGrief) // block instanceof BlockCarrot && ((Integer)iblockstate.getValue(BlockCarrot.AGE)).intValue() == 7) {
|
||||
this.entity.consumeBlock(pos, state);
|
||||
this.foodFound = false;
|
||||
this.runDelay = 10;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldMoveTo(World worldIn, BlockPos pos) {
|
||||
// Block block = worldIn.getBlockState(pos).getBlock();
|
||||
// if(block == Blocks.farmland) {
|
||||
pos = pos.up();
|
||||
State state = worldIn.getState(pos);
|
||||
// block = state.getBlock();
|
||||
if(/* block instanceof BlockCarrot && ((Integer)state.getValue(BlockCarrot.AGE)).intValue() == 7
|
||||
*/ canEat(state) && this.isHungry && !this.foodFound) {
|
||||
this.foodFound = true;
|
||||
return true;
|
||||
}
|
||||
// }
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean canEat(State state) {
|
||||
Block block = state.getBlock();
|
||||
if(Config.rabidRabbits)
|
||||
return block != Blocks.bedrock;
|
||||
return block == Blocks.carrot || block == Blocks.potato || block == Blocks.wheat || block == Blocks.brown_mushroom ||
|
||||
block == Blocks.flower || block == Blocks.blue_mushroom ||
|
||||
(block == Blocks.tallgrass && state.getValue(BlockTallGrass.TYPE) == BlockTallGrass.EnumType.GRASS);
|
||||
}
|
||||
}
|
||||
|
||||
static enum EnumMoveType {
|
||||
NONE(0.0F, 0.0F, 30, 1),
|
||||
HOP(0.8F, 0.2F, 20, 10),
|
||||
STEP(1.0F, 0.45F, 14, 14),
|
||||
SPRINT(1.75F, 0.4F, 1, 8),
|
||||
ATTACK(2.0F, 0.7F, 7, 8);
|
||||
|
||||
private final float speed;
|
||||
private final float upMotion;
|
||||
private final int duration;
|
||||
private final int rotFactor;
|
||||
|
||||
private EnumMoveType(float typeSpeed, float upwardsMotion, int typeDuration, int rotationFactor) {
|
||||
this.speed = typeSpeed;
|
||||
this.upMotion = upwardsMotion;
|
||||
this.duration = typeDuration;
|
||||
this.rotFactor = rotationFactor;
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return this.speed;
|
||||
}
|
||||
|
||||
public float getUpwardsMotion() {
|
||||
return this.upMotion;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public int getRotationFactor() {
|
||||
return this.rotFactor;
|
||||
}
|
||||
}
|
||||
|
||||
public class RabbitJumpHelper extends EntityJumpHelper {
|
||||
private EntityRabbit entity;
|
||||
private boolean wasJumping = false;
|
||||
|
||||
public RabbitJumpHelper(EntityRabbit rabbit) {
|
||||
super(rabbit);
|
||||
this.entity = rabbit;
|
||||
}
|
||||
|
||||
public boolean getIsJumping() {
|
||||
return this.isJumping;
|
||||
}
|
||||
|
||||
public boolean getWasJumping() {
|
||||
return this.wasJumping;
|
||||
}
|
||||
|
||||
public void setWasJumping(boolean jumped) {
|
||||
this.wasJumping = jumped;
|
||||
}
|
||||
|
||||
public void doJump() {
|
||||
if(this.isJumping) {
|
||||
this.entity.doMovementAction(EntityRabbit.EnumMoveType.STEP);
|
||||
this.isJumping = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class RabbitMoveHelper extends EntityMoveHelper {
|
||||
private EntityRabbit entity;
|
||||
|
||||
public RabbitMoveHelper(EntityRabbit rabbit) {
|
||||
super(rabbit);
|
||||
this.entity = rabbit;
|
||||
}
|
||||
|
||||
public void onUpdateMoveHelper() {
|
||||
if(this.entity.onGround && !this.entity.hasJumped())
|
||||
this.entity.setMovementSpeed(0.0D);
|
||||
super.onUpdateMoveHelper();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RabbitTypeData {
|
||||
public int typeData;
|
||||
|
||||
public RabbitTypeData(int type) {
|
||||
this.typeData = type;
|
||||
}
|
||||
}
|
||||
}
|
406
java/src/game/entity/animal/EntitySheep.java
Executable file
406
java/src/game/entity/animal/EntitySheep.java
Executable file
|
@ -0,0 +1,406 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIEatGrass;
|
||||
import game.ai.EntityAIFollowParent;
|
||||
import game.ai.EntityAILookIdle;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIPanic;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.biome.Biome;
|
||||
import game.collect.Maps;
|
||||
import game.color.DyeColor;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.item.EntityItem;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Blocks;
|
||||
import game.init.CraftingRegistry;
|
||||
import game.init.ItemRegistry;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.inventory.Container;
|
||||
import game.inventory.InventoryCrafting;
|
||||
import game.item.Item;
|
||||
import game.item.ItemShears;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.pathfinding.PathNavigateGround;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntitySheep extends EntityAnimal
|
||||
{
|
||||
/**
|
||||
* Internal crafting inventory used to check the result of mixing dyes corresponding to the fleece color when
|
||||
* breeding sheep.
|
||||
*/
|
||||
private final InventoryCrafting inventoryCrafting = new InventoryCrafting(new Container()
|
||||
{
|
||||
public boolean canInteractWith(EntityNPC playerIn)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}, 2, 1);
|
||||
private static final Map<DyeColor, float[]> DYE_TO_RGB = Maps.newEnumMap(DyeColor.class);
|
||||
|
||||
/**
|
||||
* Used to control movement as well as wool regrowth. Set to 40 on handleHealthUpdate and counts down with each
|
||||
* tick.
|
||||
*/
|
||||
private int sheepTimer;
|
||||
private EntityAIEatGrass entityAIEatGrass = new EntityAIEatGrass(this);
|
||||
|
||||
public static float[] getDyeRgb(DyeColor dyeColor)
|
||||
{
|
||||
return (float[])DYE_TO_RGB.get(dyeColor);
|
||||
}
|
||||
|
||||
public EntitySheep(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.9F, 1.3F);
|
||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
||||
this.tasks.addTask(0, new EntityAISwimming(this));
|
||||
this.tasks.addTask(1, new EntityAIPanic(this, 1.25D));
|
||||
this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
|
||||
this.tasks.addTask(3, new EntityAITempt(this, 1.1D, Items.wheats, false));
|
||||
this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
|
||||
this.tasks.addTask(5, this.entityAIEatGrass);
|
||||
this.tasks.addTask(6, new EntityAIWander(this, 1.0D));
|
||||
this.tasks.addTask(7, new EntityAIWatchClosest(this, null, 6.0F));
|
||||
this.tasks.addTask(8, new EntityAILookIdle(this));
|
||||
this.inventoryCrafting.setInventorySlotContents(0, new ItemStack(Items.dye, 1, 0));
|
||||
this.inventoryCrafting.setInventorySlotContents(1, new ItemStack(Items.dye, 1, 0));
|
||||
}
|
||||
|
||||
protected void updateAITasks()
|
||||
{
|
||||
this.sheepTimer = this.entityAIEatGrass.getEatingGrassTimer();
|
||||
super.updateAITasks();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
if (this.worldObj.client)
|
||||
{
|
||||
this.sheepTimer = Math.max(0, this.sheepTimer - 1);
|
||||
}
|
||||
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(8);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(16, (byte)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (!this.getSheared())
|
||||
{
|
||||
this.entityDropItem(new ItemStack(ItemRegistry.getItemFromBlock(Blocks.wool), 1, this.getFleeceColor().getMetadata()), 0.0F);
|
||||
}
|
||||
|
||||
// int i = this.rand.roll(2) + this.rand.zrange(1 + lootingModifier);
|
||||
//
|
||||
// for (int j = 0; j < i; ++j)
|
||||
// {
|
||||
// if (this.isBurning())
|
||||
// {
|
||||
// this.dropItem(Items.cooked_mutton, 1);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.dropItem(Items.mutton, 1);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
protected Item getDropItem()
|
||||
{
|
||||
return ItemRegistry.getItemFromBlock(Blocks.wool);
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
if (id == 10)
|
||||
{
|
||||
this.sheepTimer = 40;
|
||||
}
|
||||
else
|
||||
{
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
public float getHeadRotationPointY(float p_70894_1_)
|
||||
{
|
||||
return this.sheepTimer <= 0 ? 0.0F : (this.sheepTimer >= 4 && this.sheepTimer <= 36 ? 1.0F : (this.sheepTimer < 4 ? ((float)this.sheepTimer - p_70894_1_) / 4.0F : -((float)(this.sheepTimer - 40) - p_70894_1_) / 4.0F));
|
||||
}
|
||||
|
||||
public float getHeadRotationAngleX(float p_70890_1_)
|
||||
{
|
||||
if (this.sheepTimer > 4 && this.sheepTimer <= 36)
|
||||
{
|
||||
float f = ((float)(this.sheepTimer - 4) - p_70890_1_) / 32.0F;
|
||||
return ((float)Math.PI / 5F) + ((float)Math.PI * 7F / 100F) * ExtMath.sin(f * 28.7F);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.sheepTimer > 0 ? ((float)Math.PI / 5F) : this.rotPitch / (180F / (float)Math.PI);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
|
||||
if (itemstack != null && itemstack.getItem() instanceof ItemShears /* && this.worldObj.dimension.getDimensionId() != 2 */ && !this.getSheared() && !this.isChild())
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.setSheared(true);
|
||||
int i = this.rand.roll(3);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
EntityItem entityitem = this.entityDropItem(new ItemStack(ItemRegistry.getItemFromBlock(Blocks.wool), 1, this.getFleeceColor().getMetadata()), 1.0F);
|
||||
entityitem.motionY += (double)(this.rand.floatv() * 0.05F);
|
||||
entityitem.motionX += (double)((this.rand.floatv() - this.rand.floatv()) * 0.1F);
|
||||
entityitem.motionZ += (double)((this.rand.floatv() - this.rand.floatv()) * 0.1F);
|
||||
}
|
||||
}
|
||||
|
||||
itemstack.damageItem(1, player);
|
||||
this.playSound(SoundEvent.CUT, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
return super.interact(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setBoolean("Sheared", this.getSheared());
|
||||
tagCompound.setByte("Color", (byte)this.getFleeceColor().getMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setSheared(tagCompund.getBoolean("Sheared"));
|
||||
this.setFleeceColor(DyeColor.byMetadata(tagCompund.getByte("Color")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return SoundEvent.SHEEP_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return SoundEvent.SHEEP_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return SoundEvent.SHEEP_IDLE;
|
||||
}
|
||||
|
||||
// protected void playStepSound(BlockPos pos, Block blockIn)
|
||||
// {
|
||||
// this.playSound("mob.sheep.step", 0.15F, 1.0F);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Gets the wool color of this sheep.
|
||||
*/
|
||||
public DyeColor getFleeceColor()
|
||||
{
|
||||
return DyeColor.byMetadata(this.dataWatcher.getWatchableObjectByte(16) & 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the wool color of this sheep
|
||||
*/
|
||||
public void setFleeceColor(DyeColor color)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & 240 | color.getMetadata() & 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if a sheeps wool has been sheared
|
||||
*/
|
||||
public boolean getSheared()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 16) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* make a sheep sheared if set to true
|
||||
*/
|
||||
public void setSheared(boolean sheared)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (sheared)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 16)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -17)));
|
||||
}
|
||||
}
|
||||
|
||||
private static final DyeColor[] RARE_COLORS = {
|
||||
DyeColor.BLUE, DyeColor.CYAN, DyeColor.GREEN, DyeColor.LIGHT_BLUE, DyeColor.LIME,
|
||||
DyeColor.MAGENTA, DyeColor.ORANGE, DyeColor.PINK, DyeColor.PURPLE, DyeColor.RED
|
||||
};
|
||||
|
||||
public static DyeColor getRandomSheepColor(Random random, Biome biome)
|
||||
{
|
||||
if(biome == Biome.snowLand)
|
||||
return DyeColor.WHITE;
|
||||
int i = random.zrange(140);
|
||||
return i < 20 ? DyeColor.BLACK :
|
||||
(i < 30 ? DyeColor.GRAY :
|
||||
(i < 40 ? DyeColor.SILVER :
|
||||
(i < 70 ? DyeColor.BROWN :
|
||||
(i < 120 ? DyeColor.WHITE :
|
||||
(i < 130 ? (random.chance(10) ? RARE_COLORS[i - 120] : DyeColor.WHITE) :
|
||||
(random.chance(500) ? DyeColor.YELLOW : DyeColor.WHITE)
|
||||
)))));
|
||||
}
|
||||
|
||||
public EntitySheep createChild(EntityLiving ageable)
|
||||
{
|
||||
EntitySheep entitysheep = (EntitySheep)ageable;
|
||||
EntitySheep entitysheep1 = new EntitySheep(this.worldObj);
|
||||
entitysheep1.setFleeceColor(this.getDyeColorMixFromParents(this, entitysheep));
|
||||
return entitysheep1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function applies the benefits of growing back wool and faster growing up to the acting entity. (This
|
||||
* function is used in the AIEatGrass)
|
||||
*/
|
||||
public void eatGrassBonus()
|
||||
{
|
||||
this.setSheared(false);
|
||||
|
||||
if (this.isChild() && !this.worldObj.client)
|
||||
{
|
||||
this.grow(60);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Object onInitialSpawn(Object livingdata)
|
||||
{
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
this.setFleeceColor(getRandomSheepColor(this.worldObj.rand, this.worldObj.getBiomeGenForCoords(this.getPosition())));
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to mix both parent sheep to come up with a mixed dye color.
|
||||
*/
|
||||
private DyeColor getDyeColorMixFromParents(EntityAnimal father, EntityAnimal mother)
|
||||
{
|
||||
int i = ((EntitySheep)father).getFleeceColor().getDyeDamage();
|
||||
int j = ((EntitySheep)mother).getFleeceColor().getDyeDamage();
|
||||
this.inventoryCrafting.getStackInSlot(0).setItemDamage(i);
|
||||
this.inventoryCrafting.getStackInSlot(1).setItemDamage(j);
|
||||
ItemStack itemstack = CraftingRegistry.getMatching(this.inventoryCrafting, ((EntitySheep)father).worldObj);
|
||||
int k;
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == Items.dye)
|
||||
{
|
||||
k = itemstack.getMetadata();
|
||||
}
|
||||
else
|
||||
{
|
||||
k = this.worldObj.rand.chance() ? i : j;
|
||||
}
|
||||
|
||||
return DyeColor.byDyeDamage(k);
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return 0.95F * this.height;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xd9d9d9;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
DYE_TO_RGB.put(DyeColor.WHITE, new float[] {1.0F, 1.0F, 1.0F});
|
||||
DYE_TO_RGB.put(DyeColor.ORANGE, new float[] {0.85F, 0.5F, 0.2F});
|
||||
DYE_TO_RGB.put(DyeColor.MAGENTA, new float[] {0.7F, 0.3F, 0.85F});
|
||||
DYE_TO_RGB.put(DyeColor.LIGHT_BLUE, new float[] {0.4F, 0.6F, 0.85F});
|
||||
DYE_TO_RGB.put(DyeColor.YELLOW, new float[] {0.9F, 0.9F, 0.2F});
|
||||
DYE_TO_RGB.put(DyeColor.LIME, new float[] {0.5F, 0.8F, 0.1F});
|
||||
DYE_TO_RGB.put(DyeColor.PINK, new float[] {0.95F, 0.5F, 0.65F});
|
||||
DYE_TO_RGB.put(DyeColor.GRAY, new float[] {0.3F, 0.3F, 0.3F});
|
||||
DYE_TO_RGB.put(DyeColor.SILVER, new float[] {0.6F, 0.6F, 0.6F});
|
||||
DYE_TO_RGB.put(DyeColor.CYAN, new float[] {0.3F, 0.5F, 0.6F});
|
||||
DYE_TO_RGB.put(DyeColor.PURPLE, new float[] {0.5F, 0.25F, 0.7F});
|
||||
DYE_TO_RGB.put(DyeColor.BLUE, new float[] {0.2F, 0.3F, 0.7F});
|
||||
DYE_TO_RGB.put(DyeColor.BROWN, new float[] {0.4F, 0.3F, 0.2F});
|
||||
DYE_TO_RGB.put(DyeColor.GREEN, new float[] {0.4F, 0.5F, 0.2F});
|
||||
DYE_TO_RGB.put(DyeColor.RED, new float[] {0.6F, 0.2F, 0.2F});
|
||||
DYE_TO_RGB.put(DyeColor.BLACK, new float[] {0.1F, 0.1F, 0.1F});
|
||||
}
|
||||
}
|
293
java/src/game/entity/animal/EntitySquid.java
Executable file
293
java/src/game/entity/animal/EntitySquid.java
Executable file
|
@ -0,0 +1,293 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIBase;
|
||||
import game.color.DyeColor;
|
||||
import game.entity.npc.Alignment;
|
||||
import game.entity.types.EntityWaterMob;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.Item;
|
||||
import game.item.ItemStack;
|
||||
import game.world.World;
|
||||
|
||||
public class EntitySquid extends EntityWaterMob
|
||||
{
|
||||
public float squidPitch;
|
||||
public float prevSquidPitch;
|
||||
public float squidYaw;
|
||||
public float prevSquidYaw;
|
||||
|
||||
/**
|
||||
* appears to be rotation in radians; we already have pitch & yaw, so this completes the triumvirate.
|
||||
*/
|
||||
public float squidRotation;
|
||||
|
||||
/** previous squidRotation in radians */
|
||||
public float prevSquidRotation;
|
||||
|
||||
/** angle of the tentacles in radians */
|
||||
public float tentacleAngle;
|
||||
|
||||
/** the last calculated angle of the tentacles in radians */
|
||||
public float lastTentacleAngle;
|
||||
private float randomMotionSpeed;
|
||||
|
||||
/** change in squidRotation in radians. */
|
||||
private float rotationVelocity;
|
||||
private float field_70871_bB;
|
||||
private float randomMotionVecX;
|
||||
private float randomMotionVecY;
|
||||
private float randomMotionVecZ;
|
||||
|
||||
public EntitySquid(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.95F, 0.95F);
|
||||
this.rand.setSeed((long)(1 + this.getId()));
|
||||
this.rotationVelocity = 1.0F / (this.rand.floatv() + 1.0F) * 0.2F;
|
||||
this.tasks.addTask(0, new EntitySquid.AIMoveRandom(this));
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.setMaxHealth(10);
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return this.height * 0.5F;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns the sound this mob makes while it's alive.
|
||||
// */
|
||||
// protected String getLivingSound()
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
protected Item getDropItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.roll(3 + lootingModifier);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
this.entityDropItem(new ItemStack(Items.dye, 1, DyeColor.BLACK.getDyeDamage()), 0.0F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this entity is inside water (if inWater field is true as a result of handleWaterMovement() returning
|
||||
* true)
|
||||
*/
|
||||
public boolean isInLiquid()
|
||||
{
|
||||
return this.worldObj.handleLiquidAcceleration(this.getEntityBoundingBox().expand(0.0D, -0.6000000238418579D, 0.0D), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
this.prevSquidPitch = this.squidPitch;
|
||||
this.prevSquidYaw = this.squidYaw;
|
||||
this.prevSquidRotation = this.squidRotation;
|
||||
this.lastTentacleAngle = this.tentacleAngle;
|
||||
this.squidRotation += this.rotationVelocity;
|
||||
|
||||
if ((double)this.squidRotation > (Math.PI * 2D))
|
||||
{
|
||||
if (this.worldObj.client)
|
||||
{
|
||||
this.squidRotation = ((float)Math.PI * 2F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.squidRotation = (float)((double)this.squidRotation - (Math.PI * 2D));
|
||||
|
||||
if (this.rand.chance(10))
|
||||
{
|
||||
this.rotationVelocity = 1.0F / (this.rand.floatv() + 1.0F) * 0.2F;
|
||||
}
|
||||
|
||||
this.worldObj.setEntityState(this, (byte)19);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.inLiquid)
|
||||
{
|
||||
if (this.squidRotation < (float)Math.PI)
|
||||
{
|
||||
float f = this.squidRotation / (float)Math.PI;
|
||||
this.tentacleAngle = ExtMath.sin(f * f * (float)Math.PI) * (float)Math.PI * 0.25F;
|
||||
|
||||
if ((double)f > 0.75D)
|
||||
{
|
||||
this.randomMotionSpeed = 1.0F;
|
||||
this.field_70871_bB = 1.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.field_70871_bB *= 0.8F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tentacleAngle = 0.0F;
|
||||
this.randomMotionSpeed *= 0.9F;
|
||||
this.field_70871_bB *= 0.99F;
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.motionX = (double)(this.randomMotionVecX * this.randomMotionSpeed);
|
||||
this.motionY = (double)(this.randomMotionVecY * this.randomMotionSpeed);
|
||||
this.motionZ = (double)(this.randomMotionVecZ * this.randomMotionSpeed);
|
||||
}
|
||||
|
||||
float f1 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.yawOffset += (-((float)ExtMath.atan2(this.motionX, this.motionZ)) * 180.0F / (float)Math.PI - this.yawOffset) * 0.1F;
|
||||
this.rotYaw = this.yawOffset;
|
||||
this.squidYaw = (float)((double)this.squidYaw + Math.PI * (double)this.field_70871_bB * 1.5D);
|
||||
this.squidPitch += (-((float)ExtMath.atan2((double)f1, this.motionY)) * 180.0F / (float)Math.PI - this.squidPitch) * 0.1F;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tentacleAngle = ExtMath.absf(ExtMath.sin(this.squidRotation)) * (float)Math.PI * 0.25F;
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.motionX = 0.0D;
|
||||
this.motionY -= 0.08D;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ = 0.0D;
|
||||
}
|
||||
|
||||
this.squidPitch = (float)((double)this.squidPitch + (double)(-90.0F - this.squidPitch) * 0.02D);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the entity based on the specified heading. Args: strafe, forward
|
||||
*/
|
||||
public void moveEntityWithHeading(float strafe, float forward)
|
||||
{
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
if (id == 19)
|
||||
{
|
||||
this.squidRotation = 0.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
public void func_175568_b(float randomMotionVecXIn, float randomMotionVecYIn, float randomMotionVecZIn)
|
||||
{
|
||||
this.randomMotionVecX = randomMotionVecXIn;
|
||||
this.randomMotionVecY = randomMotionVecYIn;
|
||||
this.randomMotionVecZ = randomMotionVecZIn;
|
||||
}
|
||||
|
||||
public boolean func_175567_n()
|
||||
{
|
||||
return this.randomMotionVecX != 0.0F || this.randomMotionVecY != 0.0F || this.randomMotionVecZ != 0.0F;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x0000ff;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return Alignment.CHAOTIC_GOOD;
|
||||
}
|
||||
|
||||
static class AIMoveRandom extends EntityAIBase
|
||||
{
|
||||
private EntitySquid squid;
|
||||
|
||||
public AIMoveRandom(EntitySquid p_i45859_1_)
|
||||
{
|
||||
this.squid = p_i45859_1_;
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
// int i = this.squid.getAge();
|
||||
//
|
||||
// if (i > 100)
|
||||
// {
|
||||
// this.squid.func_175568_b(0.0F, 0.0F, 0.0F);
|
||||
// }
|
||||
// else
|
||||
if (this.squid.getRNG().chance(50) || !this.squid.inLiquid || !this.squid.func_175567_n())
|
||||
{
|
||||
float f = this.squid.getRNG().floatv() * (float)Math.PI * 2.0F;
|
||||
float f1 = ExtMath.cos(f) * 0.2F;
|
||||
float f2 = -0.1F + this.squid.getRNG().floatv() * 0.2F;
|
||||
float f3 = ExtMath.sin(f) * 0.2F;
|
||||
this.squid.func_175568_b(f1, f2, f3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
656
java/src/game/entity/animal/EntityWolf.java
Executable file
656
java/src/game/entity/animal/EntityWolf.java
Executable file
|
@ -0,0 +1,656 @@
|
|||
package game.entity.animal;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIAttackOnCollide;
|
||||
import game.ai.EntityAIBeg;
|
||||
import game.ai.EntityAIFollowOwner;
|
||||
import game.ai.EntityAIHurtByTarget;
|
||||
import game.ai.EntityAILeapAtTarget;
|
||||
import game.ai.EntityAILookIdle;
|
||||
import game.ai.EntityAIMate;
|
||||
import game.ai.EntityAIOwnerHurtByTarget;
|
||||
import game.ai.EntityAIOwnerHurtTarget;
|
||||
import game.ai.EntityAISwimming;
|
||||
import game.ai.EntityAITargetNonTamed;
|
||||
import game.ai.EntityAIWander;
|
||||
import game.ai.EntityAIWatchClosest;
|
||||
import game.color.DyeColor;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.npc.Alignment;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityAnimal;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityTameable;
|
||||
import game.init.Config;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.Item;
|
||||
import game.item.ItemFood;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.pathfinding.PathNavigateGround;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityWolf extends EntityTameable
|
||||
{
|
||||
/** Float used to smooth the rotation of the wolf head */
|
||||
private float headRotationCourse;
|
||||
private float headRotationCourseOld;
|
||||
|
||||
/** true is the wolf is wet else false */
|
||||
private boolean isWet;
|
||||
|
||||
/** True if the wolf is shaking else False */
|
||||
private boolean isShaking;
|
||||
|
||||
/**
|
||||
* This time increases while wolf is shaking and emitting water particles.
|
||||
*/
|
||||
private float timeWolfIsShaking;
|
||||
private float prevTimeWolfIsShaking;
|
||||
|
||||
public EntityWolf(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.6F, 0.8F);
|
||||
((PathNavigateGround)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, null, 8.0F));
|
||||
this.tasks.addTask(9, new EntityAILookIdle(this));
|
||||
this.targets.addTask(1, new EntityAIOwnerHurtByTarget(this));
|
||||
this.targets.addTask(2, new EntityAIOwnerHurtTarget(this));
|
||||
this.targets.addTask(3, new EntityAIHurtByTarget(this, true));
|
||||
this.targets.addTask(4, new EntityAITargetNonTamed(this, EntityAnimal.class, false, new Predicate<Entity>()
|
||||
{
|
||||
public boolean test(Entity p_apply_1_)
|
||||
{
|
||||
return p_apply_1_ instanceof EntitySheep || p_apply_1_ instanceof EntityRabbit;
|
||||
}
|
||||
}));
|
||||
// this.targets.addTask(5, new EntityAINearestAttackableTarget(this, EntityUndead.class, false));
|
||||
this.setTamed(false);
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
this.setMaxHealth(20);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setMaxHealth(8);
|
||||
}
|
||||
|
||||
this.getAttributeMap().registerAttribute(Attributes.ATTACK_DAMAGE);
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(2.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active target the Task system uses for tracking
|
||||
*/
|
||||
public void setAttackTarget(EntityLiving entitylivingbaseIn)
|
||||
{
|
||||
super.setAttackTarget(entitylivingbaseIn);
|
||||
|
||||
if (entitylivingbaseIn == null)
|
||||
{
|
||||
this.setAngry(false);
|
||||
}
|
||||
else if (!this.isTamed())
|
||||
{
|
||||
this.setAngry(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateAITasks()
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Integer.valueOf(this.getHealth()));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(18, this.getHealth());
|
||||
this.dataWatcher.addObject(19, (byte)0);
|
||||
this.dataWatcher.addObject(20, (byte)DyeColor.RED.getMetadata());
|
||||
}
|
||||
|
||||
// protected void playStepSound(BlockPos pos, Block blockIn)
|
||||
// {
|
||||
// this.playSound("mob.wolf.step", 0.15F, 1.0F);
|
||||
// }
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setBoolean("Angry", this.isAngry());
|
||||
tagCompound.setByte("CollarColor", (byte)this.getCollarColor().getDyeDamage());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setAngry(tagCompund.getBoolean("Angry"));
|
||||
|
||||
if (tagCompund.hasKey("CollarColor", 99))
|
||||
{
|
||||
this.setCollarColor(DyeColor.byDyeDamage(tagCompund.getByte("CollarColor")));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes while it's alive.
|
||||
*/
|
||||
protected SoundEvent getLivingSound()
|
||||
{
|
||||
return this.isAngry() ? SoundEvent.WOLF_GROWL : (this.rand.chance(3) ? (this.isTamed() && this.dataWatcher.getWatchableObjectInt(18) < 10 ? SoundEvent.WOLF_WHINE : SoundEvent.WOLF_PANTING) : SoundEvent.WOLF_BARK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes when it is hurt.
|
||||
*/
|
||||
protected SoundEvent getHurtSound()
|
||||
{
|
||||
return SoundEvent.WOLF_HURT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound this mob makes on death.
|
||||
*/
|
||||
protected SoundEvent getDeathSound()
|
||||
{
|
||||
return SoundEvent.WOLF_DEATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 0.4F;
|
||||
}
|
||||
|
||||
protected Item getDropItem()
|
||||
{
|
||||
return null; // ItemRegistry.getItemById(-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 (!this.worldObj.client && this.isWet && !this.isShaking && !this.hasPath() && this.onGround)
|
||||
{
|
||||
this.isShaking = true;
|
||||
this.timeWolfIsShaking = 0.0F;
|
||||
this.prevTimeWolfIsShaking = 0.0F;
|
||||
this.worldObj.setEntityState(this, (byte)8);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client && this.getAttackTarget() == null && this.isAngry())
|
||||
{
|
||||
this.setAngry(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
this.headRotationCourseOld = this.headRotationCourse;
|
||||
|
||||
if (this.isBegging())
|
||||
{
|
||||
this.headRotationCourse += (1.0F - this.headRotationCourse) * 0.4F;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.headRotationCourse += (0.0F - this.headRotationCourse) * 0.4F;
|
||||
}
|
||||
|
||||
if (this.isWet())
|
||||
{
|
||||
this.isWet = true;
|
||||
this.isShaking = false;
|
||||
this.timeWolfIsShaking = 0.0F;
|
||||
this.prevTimeWolfIsShaking = 0.0F;
|
||||
}
|
||||
else if ((this.isWet || this.isShaking) && this.isShaking)
|
||||
{
|
||||
if (this.timeWolfIsShaking == 0.0F)
|
||||
{
|
||||
this.playSound(SoundEvent.WOLF_SHAKE, this.getSoundVolume(), (this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F);
|
||||
}
|
||||
|
||||
this.prevTimeWolfIsShaking = this.timeWolfIsShaking;
|
||||
this.timeWolfIsShaking += 0.05F;
|
||||
|
||||
if (this.prevTimeWolfIsShaking >= 2.0F)
|
||||
{
|
||||
this.isWet = false;
|
||||
this.isShaking = false;
|
||||
this.prevTimeWolfIsShaking = 0.0F;
|
||||
this.timeWolfIsShaking = 0.0F;
|
||||
}
|
||||
|
||||
if (this.timeWolfIsShaking > 0.4F)
|
||||
{
|
||||
float f = (float)this.getEntityBoundingBox().minY;
|
||||
int i = (int)(ExtMath.sin((this.timeWolfIsShaking - 0.4F) * (float)Math.PI) * 7.0F);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
float f1 = (this.rand.floatv() * 2.0F - 1.0F) * this.width * 0.5F;
|
||||
float f2 = (this.rand.floatv() * 2.0F - 1.0F) * this.width * 0.5F;
|
||||
this.worldObj.spawnParticle(ParticleType.WATER_SPLASH, this.posX + (double)f1, (double)(f + 0.8F), this.posZ + (double)f2, this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the wolf is wet
|
||||
*/
|
||||
public boolean isWolfWet()
|
||||
{
|
||||
return this.isWet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when calculating the amount of shading to apply while the wolf is wet.
|
||||
*/
|
||||
public float getShadingWhileWet(float p_70915_1_)
|
||||
{
|
||||
return 0.75F + (this.prevTimeWolfIsShaking + (this.timeWolfIsShaking - this.prevTimeWolfIsShaking) * p_70915_1_) / 2.0F * 0.25F;
|
||||
}
|
||||
|
||||
public float getShakeAngle(float p_70923_1_, float p_70923_2_)
|
||||
{
|
||||
float f = (this.prevTimeWolfIsShaking + (this.timeWolfIsShaking - this.prevTimeWolfIsShaking) * p_70923_1_ + p_70923_2_) / 1.8F;
|
||||
|
||||
if (f < 0.0F)
|
||||
{
|
||||
f = 0.0F;
|
||||
}
|
||||
else if (f > 1.0F)
|
||||
{
|
||||
f = 1.0F;
|
||||
}
|
||||
|
||||
return ExtMath.sin(f * (float)Math.PI) * ExtMath.sin(f * (float)Math.PI * 11.0F) * 0.15F * (float)Math.PI;
|
||||
}
|
||||
|
||||
public float getInterestedAngle(float p_70917_1_)
|
||||
{
|
||||
return (this.headRotationCourseOld + (this.headRotationCourse - this.headRotationCourseOld) * p_70917_1_) * 0.15F * (float)Math.PI;
|
||||
}
|
||||
|
||||
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 source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entity entity = source.getEntity();
|
||||
this.aiSit.setSitting(false);
|
||||
|
||||
// if (entity != null && !(entity.isPlayer()) && !(entity instanceof EntityArrow))
|
||||
// {
|
||||
// amount = (amount + 1) / 2;
|
||||
// }
|
||||
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity entityIn)
|
||||
{
|
||||
if(!this.worldObj.client && !Config.damageMobs)
|
||||
return false;
|
||||
boolean flag = entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), ((int)this.getEntityAttribute(Attributes.ATTACK_DAMAGE).getAttributeValue()));
|
||||
|
||||
if (flag)
|
||||
{
|
||||
this.applyEnchantments(this, entityIn);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setTamed(boolean tamed)
|
||||
{
|
||||
super.setTamed(tamed);
|
||||
|
||||
if (tamed)
|
||||
{
|
||||
this.setMaxHealth(20);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setMaxHealth(8);
|
||||
}
|
||||
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(4.0D);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
|
||||
if (this.isTamed())
|
||||
{
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (itemstack.getItem() instanceof ItemFood)
|
||||
{
|
||||
ItemFood itemfood = (ItemFood)itemstack.getItem();
|
||||
|
||||
if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectInt(18) < 20)
|
||||
{
|
||||
// if (!player.creative)
|
||||
// {
|
||||
--itemstack.stackSize;
|
||||
// }
|
||||
|
||||
this.heal(itemfood.getHealAmount(itemstack));
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (itemstack.getItem() == Items.dye)
|
||||
{
|
||||
DyeColor enumdyecolor = DyeColor.byDyeDamage(itemstack.getMetadata());
|
||||
|
||||
if (enumdyecolor != this.getCollarColor())
|
||||
{
|
||||
this.setCollarColor(enumdyecolor);
|
||||
|
||||
if (/* !player.creative && */ --itemstack.stackSize <= 0)
|
||||
{
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isOwner(player) && !this.worldObj.client && !this.isBreedingItem(itemstack))
|
||||
{
|
||||
this.aiSit.setSitting(!this.isSitting());
|
||||
this.jumping = false;
|
||||
this.navigator.clearPathEntity();
|
||||
this.setAttackTarget((EntityLiving)null);
|
||||
}
|
||||
}
|
||||
else if (itemstack != null && itemstack.getItem() == Items.bone && !this.isAngry())
|
||||
{
|
||||
// if (!player.creative)
|
||||
// {
|
||||
--itemstack.stackSize;
|
||||
// }
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
if (this.rand.chance(3))
|
||||
{
|
||||
this.setTamed(true);
|
||||
this.navigator.clearPathEntity();
|
||||
this.setAttackTarget((EntityLiving)null);
|
||||
this.aiSit.setSitting(true);
|
||||
this.setHealth(20);
|
||||
// this.setOwnerId(player.getUser());
|
||||
this.playTameEffect(true);
|
||||
this.worldObj.setEntityState(this, (byte)7);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
this.worldObj.setEntityState(this, (byte)6);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.interact(player);
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
if (id == 8)
|
||||
{
|
||||
this.isShaking = true;
|
||||
this.timeWolfIsShaking = 0.0F;
|
||||
this.prevTimeWolfIsShaking = 0.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
public float getTailRotation()
|
||||
{
|
||||
return this.isAngry() ? 1.5393804F : (this.isTamed() ? (0.55F - (20.0F - (float)this.dataWatcher.getWatchableObjectInt(18)) * 0.02F) * (float)Math.PI : ((float)Math.PI / 5F));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 stack)
|
||||
{
|
||||
return stack == null ? false : (!(stack.getItem() instanceof ItemFood) ? false : ((ItemFood)stack.getItem()).isWolfsFavoriteMeat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return how many at most can spawn in a chunk at once.
|
||||
*/
|
||||
public int getMaxChunkSpawns()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 angry)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (angry)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -3)));
|
||||
}
|
||||
}
|
||||
|
||||
public DyeColor getCollarColor()
|
||||
{
|
||||
return DyeColor.byDyeDamage(this.dataWatcher.getWatchableObjectByte(20) & 15);
|
||||
}
|
||||
|
||||
public void setCollarColor(DyeColor collarcolor)
|
||||
{
|
||||
this.dataWatcher.updateObject(20, Byte.valueOf((byte)(collarcolor.getDyeDamage() & 15)));
|
||||
}
|
||||
|
||||
public EntityWolf createChild(EntityLiving ageable)
|
||||
{
|
||||
EntityWolf entitywolf = new EntityWolf(this.worldObj);
|
||||
// String s = this.getOwnerId();
|
||||
//
|
||||
// if (s != null && s.trim().length() > 0)
|
||||
// {
|
||||
// entitywolf.setOwnerId(s);
|
||||
entitywolf.setTamed(this.isTamed());
|
||||
// }
|
||||
|
||||
return entitywolf;
|
||||
}
|
||||
|
||||
public void setBegging(boolean beg)
|
||||
{
|
||||
if (beg)
|
||||
{
|
||||
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 otherAnimal)
|
||||
{
|
||||
if (otherAnimal == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.isTamed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!(otherAnimal instanceof EntityWolf))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntityWolf entitywolf = (EntityWolf)otherAnimal;
|
||||
return !entitywolf.isTamed() ? false : (entitywolf.isSitting() ? false : this.isInLove() && entitywolf.isInLove());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBegging()
|
||||
{
|
||||
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;
|
||||
// }
|
||||
|
||||
public boolean shouldAttackEntity(EntityLiving p_142018_1_, EntityLiving p_142018_2_)
|
||||
{
|
||||
// if (!(p_142018_1_ instanceof EntityHaunter)) // && !(p_142018_1_ instanceof EntityFireDemon))
|
||||
// {
|
||||
// if (p_142018_1_ instanceof EntityWolf)
|
||||
// {
|
||||
// EntityWolf entitywolf = (EntityWolf)p_142018_1_;
|
||||
//
|
||||
// if (entitywolf.isTamed() && entitywolf.getOwner() == p_142018_2_)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
return /* p_142018_1_.isPlayer() && p_142018_2_.isPlayer() && !((EntityNPC)p_142018_2_).canAttackPlayer((EntityNPC)p_142018_1_) ? false : */ !(p_142018_1_ instanceof EntityHorse) || !((EntityHorse)p_142018_1_).isTame();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
|
||||
public boolean allowLeashing()
|
||||
{
|
||||
return !this.isAngry() && super.allowLeashing();
|
||||
}
|
||||
|
||||
public int getLeashColor() {
|
||||
if(this.isTamed()) {
|
||||
DyeColor color = DyeColor.byMetadata(this.getCollarColor().getMetadata());
|
||||
float[] rgb = EntitySheep.getDyeRgb(color);
|
||||
return (((int)(rgb[0] * 255.0f)) << 16) | (((int)(rgb[1] * 255.0f)) << 8) | ((int)(rgb[2] * 255.0f));
|
||||
}
|
||||
return super.getLeashColor();
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return this.isTamed() ? 0x00ff7a : 0x59de9e;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return this.isTamed() ? Alignment.LAWFUL_GOOD : Alignment.NEUTRAL;
|
||||
}
|
||||
}
|
84
java/src/game/entity/attributes/Attribute.java
Executable file
84
java/src/game/entity/attributes/Attribute.java
Executable file
|
@ -0,0 +1,84 @@
|
|||
package game.entity.attributes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.collect.Maps;
|
||||
|
||||
public class Attribute
|
||||
{
|
||||
private static final Map<String, Attribute> ATTRIBUTES = Maps.newHashMap();
|
||||
|
||||
private final String name;
|
||||
private final String display;
|
||||
private final double defValue;
|
||||
private final double minValue;
|
||||
private final double maxValue;
|
||||
private final boolean shouldWatch;
|
||||
|
||||
public static Attribute getAttribute(String name) {
|
||||
return ATTRIBUTES.get(name);
|
||||
}
|
||||
|
||||
public Attribute(String name, String display, double def, double min, double max, boolean watch)
|
||||
{
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
this.defValue = def;
|
||||
if(name == null)
|
||||
throw new IllegalArgumentException("Name cannot be null!");
|
||||
this.minValue = min;
|
||||
this.maxValue = max;
|
||||
this.shouldWatch = watch;
|
||||
|
||||
if (min > max)
|
||||
{
|
||||
throw new IllegalArgumentException("Minimum value cannot be bigger than maximum value!");
|
||||
}
|
||||
else if (def < min)
|
||||
{
|
||||
throw new IllegalArgumentException("Default value cannot be lower than minimum value!");
|
||||
}
|
||||
else if (def > max)
|
||||
{
|
||||
throw new IllegalArgumentException("Default value cannot be bigger than maximum value!");
|
||||
}
|
||||
|
||||
ATTRIBUTES.put(name, this);
|
||||
}
|
||||
|
||||
public String getUnlocalizedName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getDisplayName()
|
||||
{
|
||||
return this.display;
|
||||
}
|
||||
|
||||
public double getDefaultValue()
|
||||
{
|
||||
return this.defValue;
|
||||
}
|
||||
|
||||
public boolean getShouldWatch()
|
||||
{
|
||||
return this.shouldWatch;
|
||||
}
|
||||
|
||||
public double clampValue(double value)
|
||||
{
|
||||
return ExtMath.clampd(value, this.minValue, this.maxValue);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.name.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return obj instanceof Attribute && this.name.equals(((Attribute)obj).getUnlocalizedName());
|
||||
}
|
||||
}
|
191
java/src/game/entity/attributes/AttributeInstance.java
Executable file
191
java/src/game/entity/attributes/AttributeInstance.java
Executable file
|
@ -0,0 +1,191 @@
|
|||
package game.entity.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import game.collect.Lists;
|
||||
import game.collect.Maps;
|
||||
import game.collect.Sets;
|
||||
|
||||
public class AttributeInstance
|
||||
{
|
||||
private final AttributeMap attributeMap;
|
||||
private final Attribute genericAttribute;
|
||||
private final Set<AttributeModifier> additions = Sets.<AttributeModifier>newHashSet();
|
||||
private final Set<AttributeModifier> multipliers = Sets.<AttributeModifier>newHashSet();
|
||||
private final Map<String, Set<AttributeModifier>> mapByName = Maps.<String, Set<AttributeModifier>>newHashMap();
|
||||
private final Map<Long, AttributeModifier> mapByID = Maps.<Long, AttributeModifier>newHashMap();
|
||||
private double baseValue;
|
||||
private boolean needsUpdate = true;
|
||||
private double cachedValue;
|
||||
|
||||
public AttributeInstance(AttributeMap attributeMapIn, Attribute genericAttributeIn)
|
||||
{
|
||||
this.attributeMap = attributeMapIn;
|
||||
this.genericAttribute = genericAttributeIn;
|
||||
this.baseValue = genericAttributeIn.getDefaultValue();
|
||||
}
|
||||
|
||||
public Attribute getAttribute()
|
||||
{
|
||||
return this.genericAttribute;
|
||||
}
|
||||
|
||||
public double getBaseValue()
|
||||
{
|
||||
return this.baseValue;
|
||||
}
|
||||
|
||||
public void setBaseValue(double baseValue)
|
||||
{
|
||||
if (baseValue != this.getBaseValue())
|
||||
{
|
||||
this.baseValue = baseValue;
|
||||
this.flagForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
// public Collection<AttributeModifier> getModifiersByOperation(AttributeOp operation)
|
||||
// {
|
||||
// return (Collection)this.mapByOperation.get(operation);
|
||||
// }
|
||||
|
||||
public Collection<AttributeModifier> func_111122_c()
|
||||
{
|
||||
Set<AttributeModifier> set = Sets.<AttributeModifier>newHashSet();
|
||||
|
||||
// for (AttributeOp op : AttributeOp.values())
|
||||
// {
|
||||
// set.addAll(this.getModifiersByOperation(op));
|
||||
// }
|
||||
set.addAll(this.additions);
|
||||
set.addAll(this.multipliers);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public AttributeModifier getModifier(long id)
|
||||
{
|
||||
return (AttributeModifier)this.mapByID.get(id);
|
||||
}
|
||||
|
||||
public boolean hasModifier(AttributeModifier modifier)
|
||||
{
|
||||
return this.mapByID.get(modifier.getID()) != null;
|
||||
}
|
||||
|
||||
public void applyModifier(AttributeModifier modifier)
|
||||
{
|
||||
if (this.getModifier(modifier.getID()) != null)
|
||||
{
|
||||
throw new IllegalArgumentException("Modifier is already applied on this attribute!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Set<AttributeModifier> set = (Set)this.mapByName.get(modifier.getName());
|
||||
|
||||
if (set == null)
|
||||
{
|
||||
set = Sets.<AttributeModifier>newHashSet();
|
||||
this.mapByName.put(modifier.getName(), set);
|
||||
}
|
||||
|
||||
(modifier.isMultiplied() ? this.multipliers : this.additions).add(modifier);
|
||||
set.add(modifier);
|
||||
this.mapByID.put(modifier.getID(), modifier);
|
||||
this.flagForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected void flagForUpdate()
|
||||
{
|
||||
this.needsUpdate = true;
|
||||
this.attributeMap.flagDirty(this);
|
||||
}
|
||||
|
||||
public void removeModifier(AttributeModifier modifier)
|
||||
{
|
||||
// for (AttributeOp op : AttributeOp.values())
|
||||
// {
|
||||
// Set<AttributeModifier> set = (Set)this.mapByOperation.get(op);
|
||||
// set.remove(modifier);
|
||||
// }
|
||||
this.additions.remove(modifier);
|
||||
this.multipliers.remove(modifier);
|
||||
|
||||
Set<AttributeModifier> set1 = (Set)this.mapByName.get(modifier.getName());
|
||||
|
||||
if (set1 != null)
|
||||
{
|
||||
set1.remove(modifier);
|
||||
|
||||
if (set1.isEmpty())
|
||||
{
|
||||
this.mapByName.remove(modifier.getName());
|
||||
}
|
||||
}
|
||||
|
||||
this.mapByID.remove(modifier.getID());
|
||||
this.flagForUpdate();
|
||||
}
|
||||
|
||||
public void removeAllModifiers()
|
||||
{
|
||||
Collection<AttributeModifier> collection = this.func_111122_c();
|
||||
|
||||
if (collection != null)
|
||||
{
|
||||
for (AttributeModifier attributemodifier : Lists.newArrayList(collection))
|
||||
{
|
||||
this.removeModifier(attributemodifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double getAttributeValue()
|
||||
{
|
||||
if (this.needsUpdate)
|
||||
{
|
||||
this.cachedValue = this.computeValue();
|
||||
this.needsUpdate = false;
|
||||
}
|
||||
|
||||
return this.cachedValue;
|
||||
}
|
||||
|
||||
private double computeValue()
|
||||
{
|
||||
double base = this.getBaseValue();
|
||||
|
||||
for (AttributeModifier attributemodifier : this.additions)
|
||||
{
|
||||
base += attributemodifier.getAmount();
|
||||
}
|
||||
|
||||
for (AttributeModifier attributemodifier2 : this.multipliers)
|
||||
{
|
||||
base *= 1.0D + attributemodifier2.getAmount();
|
||||
}
|
||||
|
||||
return this.genericAttribute.clampValue(base);
|
||||
}
|
||||
|
||||
// private Collection<AttributeModifier> getModifierList(AttributeOp operation)
|
||||
// {
|
||||
// // Set<AttributeModifier> set =
|
||||
// return Sets.newHashSet(this.getModifiersByOperation(operation));
|
||||
//
|
||||
//// for (BaseAttribute iattribute = this.genericAttribute.func_180372_d(); iattribute != null; iattribute = iattribute.func_180372_d())
|
||||
//// {
|
||||
//// ModifiableAttributeInstance iattributeinstance = this.attributeMap.getAttributeInstance(iattribute);
|
||||
////
|
||||
//// if (iattributeinstance != null)
|
||||
//// {
|
||||
//// set.addAll(iattributeinstance.getModifiersByOperation(operation));
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// // return set;
|
||||
// }
|
||||
}
|
161
java/src/game/entity/attributes/AttributeMap.java
Executable file
161
java/src/game/entity/attributes/AttributeMap.java
Executable file
|
@ -0,0 +1,161 @@
|
|||
package game.entity.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import game.collect.Maps;
|
||||
import game.collect.Sets;
|
||||
|
||||
public class AttributeMap
|
||||
{
|
||||
protected final Map<Attribute, AttributeInstance> attributes = Maps.<Attribute, AttributeInstance>newHashMap();
|
||||
protected final Map<String, AttributeInstance> nameMap = new LowerStringMap();
|
||||
private final Set<AttributeInstance> dirtyAttributes;
|
||||
|
||||
public AttributeMap(boolean client) {
|
||||
this.dirtyAttributes = client ? null : Sets.<AttributeInstance>newHashSet();
|
||||
}
|
||||
|
||||
public AttributeInstance getAttributeInstance(Attribute attribute)
|
||||
{
|
||||
return (AttributeInstance)this.attributes.get(attribute);
|
||||
}
|
||||
|
||||
public AttributeInstance getAttributeInstanceByName(String attributeName)
|
||||
{
|
||||
// AttributeInstance iattributeinstance =
|
||||
return (AttributeInstance)this.nameMap.get(attributeName);
|
||||
|
||||
// if (iattributeinstance == null)
|
||||
// {
|
||||
// iattributeinstance = (AttributeInstance)this.descMap.get(attributeName);
|
||||
// }
|
||||
//
|
||||
// return (AttributeInstance)iattributeinstance;
|
||||
}
|
||||
|
||||
public AttributeInstance registerAttribute(Attribute attribute)
|
||||
{
|
||||
if(this.nameMap.containsKey(attribute.getUnlocalizedName()))
|
||||
throw new IllegalArgumentException("Attribute is already registered!");
|
||||
AttributeInstance inst = new AttributeInstance(this, attribute);
|
||||
this.nameMap.put(attribute.getUnlocalizedName(), inst);
|
||||
this.attributes.put(attribute, inst);
|
||||
// for (BaseAttribute iattribute = attribute.func_180372_d(); iattribute != null; iattribute = iattribute.func_180372_d())
|
||||
// {
|
||||
// this.field_180377_c.put(iattribute, attribute);
|
||||
// }
|
||||
// if(attribute.getDescription() != null)
|
||||
// this.descMap.put(attribute.getDescription(), inst);
|
||||
return inst;
|
||||
}
|
||||
|
||||
public Collection<AttributeInstance> getAllAttributes()
|
||||
{
|
||||
return this.nameMap.values();
|
||||
}
|
||||
|
||||
public void flagDirty(AttributeInstance instance)
|
||||
{
|
||||
if (this.dirtyAttributes != null && instance.getAttribute().getShouldWatch())
|
||||
{
|
||||
this.dirtyAttributes.add(instance);
|
||||
}
|
||||
|
||||
// for (BaseAttribute iattribute : this.field_180377_c.get(instance.getAttribute()))
|
||||
// {
|
||||
// ModifiableAttributeInstance modifiableattributeinstance = this.getAttributeInstance(iattribute);
|
||||
//
|
||||
// if (modifiableattributeinstance != null)
|
||||
// {
|
||||
// modifiableattributeinstance.flagForUpdate();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public Set<AttributeInstance> getDirty()
|
||||
{
|
||||
return this.dirtyAttributes;
|
||||
}
|
||||
|
||||
public Collection<AttributeInstance> getWatchedAttributes()
|
||||
{
|
||||
Set<AttributeInstance> set = Sets.<AttributeInstance>newHashSet();
|
||||
|
||||
for (AttributeInstance iattributeinstance : this.getAllAttributes())
|
||||
{
|
||||
if (iattributeinstance.getAttribute().getShouldWatch())
|
||||
{
|
||||
set.add(iattributeinstance);
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public void removeAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers)
|
||||
{
|
||||
for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
|
||||
{
|
||||
AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());
|
||||
|
||||
if (iattributeinstance != null)
|
||||
{
|
||||
for(AttributeModifier mod : entry.getValue()) {
|
||||
iattributeinstance.removeModifier(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers)
|
||||
{
|
||||
for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
|
||||
{
|
||||
AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());
|
||||
|
||||
if (iattributeinstance != null)
|
||||
{
|
||||
for(AttributeModifier mod : entry.getValue()) {
|
||||
iattributeinstance.removeModifier(mod);
|
||||
iattributeinstance.applyModifier(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers, int slot, int amount)
|
||||
{
|
||||
for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
|
||||
{
|
||||
AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());
|
||||
|
||||
if (iattributeinstance != null)
|
||||
{
|
||||
for(AttributeModifier mod : entry.getValue()) {
|
||||
AttributeModifier nmod = new AttributeModifier(mod, slot+1, amount);
|
||||
iattributeinstance.removeModifier(nmod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyAttributeModifiers(Map<Attribute, Set<AttributeModifier>> modifiers, int slot, int amount)
|
||||
{
|
||||
for (Entry<Attribute, Set<AttributeModifier>> entry : modifiers.entrySet())
|
||||
{
|
||||
AttributeInstance iattributeinstance = this.getAttributeInstanceByName(entry.getKey().getUnlocalizedName());
|
||||
|
||||
if (iattributeinstance != null)
|
||||
{
|
||||
for(AttributeModifier mod : entry.getValue()) {
|
||||
AttributeModifier nmod = new AttributeModifier(mod, slot+1, amount);
|
||||
iattributeinstance.removeModifier(nmod);
|
||||
iattributeinstance.applyModifier(nmod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
134
java/src/game/entity/attributes/AttributeModifier.java
Executable file
134
java/src/game/entity/attributes/AttributeModifier.java
Executable file
|
@ -0,0 +1,134 @@
|
|||
package game.entity.attributes;
|
||||
|
||||
import game.rng.Random;
|
||||
|
||||
public class AttributeModifier
|
||||
{
|
||||
private final double amount;
|
||||
private final boolean multiply;
|
||||
private final String name;
|
||||
private final long id;
|
||||
private final boolean isSaved;
|
||||
private final boolean inventory;
|
||||
|
||||
public static long getModifierId(String name) {
|
||||
if(name.length() > 7)
|
||||
throw new IllegalArgumentException("Name darf höchstens 7 Zeichen enthalten");
|
||||
long id = '@';
|
||||
for(int z = 0; z < name.length(); z++) {
|
||||
id <<= 8;
|
||||
char c = name.charAt(z);
|
||||
if(c > 0xff)
|
||||
throw new IllegalArgumentException("Name darf keine 16-Bit-Zeichen enthalten");
|
||||
id |= (long)c;
|
||||
}
|
||||
// Log.CONFIG.debug(String.format("Modifikator '%s' -> 0x%016x", name, id));
|
||||
return id;
|
||||
}
|
||||
|
||||
public AttributeModifier(String nameIn, double amountIn, boolean multiplyIn)
|
||||
{
|
||||
this(new Random().longv() | 0x8000000000000000L, nameIn, amountIn, multiplyIn, true, false);
|
||||
}
|
||||
|
||||
public AttributeModifier(long idIn, String nameIn, double amountIn, boolean multiplyIn) {
|
||||
this(idIn, nameIn, amountIn, multiplyIn, true, false);
|
||||
}
|
||||
|
||||
public AttributeModifier(long idIn, String nameIn, double amountIn, boolean multiplyIn, boolean saved) {
|
||||
this(idIn, nameIn, amountIn, multiplyIn, saved, false);
|
||||
}
|
||||
|
||||
public AttributeModifier(long idIn, String nameIn, double amountIn, boolean multiplyIn, boolean saved, boolean inv)
|
||||
{
|
||||
this.isSaved = saved;
|
||||
this.inventory = inv;
|
||||
this.id = idIn;
|
||||
this.name = nameIn;
|
||||
this.amount = amountIn;
|
||||
this.multiply = multiplyIn;
|
||||
if (nameIn == null) {
|
||||
throw new NullPointerException("Modifier name cannot be empty");
|
||||
}
|
||||
else if (nameIn.length() == 0) {
|
||||
throw new IllegalArgumentException("Modifier name cannot be empty");
|
||||
}
|
||||
// else if (operationIn == null) {
|
||||
// throw new IllegalArgumentException("Invalid operation");
|
||||
// }
|
||||
}
|
||||
|
||||
public AttributeModifier(AttributeModifier attr, int slot, int amount) {
|
||||
this(attr.id + (long)slot, attr.name, attr.amount * (double)amount, attr.multiply, attr.isSaved);
|
||||
}
|
||||
|
||||
public long getID()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public boolean isMultiplied()
|
||||
{
|
||||
return this.multiply;
|
||||
}
|
||||
|
||||
public double getAmount()
|
||||
{
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public boolean isSaved()
|
||||
{
|
||||
return this.isSaved;
|
||||
}
|
||||
|
||||
public boolean isInventory()
|
||||
{
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && this.getClass() == obj.getClass())
|
||||
{
|
||||
AttributeModifier attributemodifier = (AttributeModifier)obj;
|
||||
|
||||
if (this.id != 0L)
|
||||
{
|
||||
if (this.id != attributemodifier.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (attributemodifier.id != 0L)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.id != 0L ? Long.hashCode(this.id) : 0;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "AttributeModifier{amount=" + this.amount + ", multiply=" + this.multiply + ", name=\'" + this.name + '\'' + ", id=" + this.id + ", serialize=" + this.isSaved + '}';
|
||||
}
|
||||
}
|
161
java/src/game/entity/attributes/Attributes.java
Executable file
161
java/src/game/entity/attributes/Attributes.java
Executable file
|
@ -0,0 +1,161 @@
|
|||
package game.entity.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import game.Log;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.nbt.NBTTagList;
|
||||
|
||||
public class Attributes
|
||||
{
|
||||
public static final Attribute MAX_HEALTH = (new Attribute("generic.maxHealth", "Maximale Gesundheit", 20.0D, 0.0D, 1024.0D, true));
|
||||
public static final Attribute FOLLOW_RANGE = (new Attribute("generic.followRange", "Kreaturen-Folgedistanz", 32.0D, 0.0D, 2048.0D, false));
|
||||
public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockbackResistance", "Standfestigkeit", 0.0D, 0.0D, 1.0D, false));
|
||||
public static final Attribute MOVEMENT_SPEED = (new Attribute("generic.movementSpeed", "Geschwindigkeit", 0.699999988079071D, 0.0D, 1024.0D, true));
|
||||
public static final Attribute ATTACK_DAMAGE = new Attribute("generic.attackDamage", "Angriffsschaden", 2.0D, 0.0D, 2048.0D, false);
|
||||
public static final Attribute RADIATION = new Attribute("generic.radiation", "Strahlung", 0.0D, 0.0D, 16384.0D, false);
|
||||
public static final Attribute RADIATION_RESISTANCE = new Attribute("generic.radiationResistance", "Strahlungsresistenz", 10.0D, 0.0D, 16384.0D, false);
|
||||
public static final Attribute MANA_CAPACITY = new Attribute("generic.manaCapacity", "Mana-Kapazität", 0.0D, 0.0D, 2048.0D, false);
|
||||
public static final Attribute MAGIC_RESISTANCE = new Attribute("generic.magicResistance", "Magieresistenz", 0.0D, 0.0D, 4096.0D, false);
|
||||
public static final Attribute REINFORCEMENT_CHANCE = (new Attribute("zombie.spawnReinforcements", "Zombie-Verstärkung", 0.0D, 0.0D, 1.0D, false));
|
||||
public static final Attribute HORSE_JUMP_STRENGTH = (new Attribute("horse.jumpStrength", "Pferdesprungstärke", 0.7D, 0.0D, 2.0D, true));
|
||||
|
||||
// public static final long ATTACK_SPEED_ID = AttributeModifier.getModifierId("EnderSp");
|
||||
// public static final AttributeModifier ATTACK_SPEED_MOD = (new AttributeModifier(ATTACK_SPEED_ID, "Attacking speed boost", 0.15000000596046448D, false, false));
|
||||
public static final long RUSHING_SPEED_ID = AttributeModifier.getModifierId("RushSpd");
|
||||
public static final AttributeModifier RUSHING_SPEED_MOD = (new AttributeModifier(RUSHING_SPEED_ID, "Attacking speed boost", 0.05D, false, false));
|
||||
public static final long MAGE_POTSPEED_ID = AttributeModifier.getModifierId("MagePot");
|
||||
public static final AttributeModifier MAGE_POTSPEED_MOD = (new AttributeModifier(MAGE_POTSPEED_ID, "Drinking speed penalty", -0.25D, false, false));
|
||||
public static final long ZOMBIE_BABY_ID = AttributeModifier.getModifierId("ZombSpd");
|
||||
public static final AttributeModifier ZOMBIE_BABY_MOD = new AttributeModifier(ZOMBIE_BABY_ID, "Baby speed boost", 0.5D, true);
|
||||
public static final long FLEEING_SPEED_ID = AttributeModifier.getModifierId("FleeSpd");
|
||||
public static final AttributeModifier FLEEING_SPEED_MOD = (new AttributeModifier(FLEEING_SPEED_ID, "Fleeing speed bonus", 2.0D, true, false));
|
||||
public static final long SPRINT_SPEED_ID = AttributeModifier.getModifierId("Sprint");
|
||||
public static final AttributeModifier SPRINT_SPEED_MOD = (new AttributeModifier(SPRINT_SPEED_ID, "Sprinting speed boost", 0.30000001192092896D, true, false));
|
||||
public static final long ITEM_VAL_ID = AttributeModifier.getModifierId("ItemVal");
|
||||
public static final long RADIATION_BASE = AttributeModifier.getModifierId("NukeVal");
|
||||
public static final long MOUSE_SPEEDY_ID = AttributeModifier.getModifierId("SpeedyG");
|
||||
public static final AttributeModifier MOUSE_SPEEDY_MOD = new AttributeModifier(MOUSE_SPEEDY_ID, "Mouse speed boost", 1.0D, true);
|
||||
|
||||
/**
|
||||
* Creates an NBTTagList from a BaseAttributeMap, including all its AttributeInstances
|
||||
*/
|
||||
public static NBTTagList writeBaseAttributeMapToNBT(AttributeMap map)
|
||||
{
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
|
||||
for (AttributeInstance iattributeinstance : map.getAllAttributes())
|
||||
{
|
||||
nbttaglist.appendTag(writeAttributeInstanceToNBT(iattributeinstance));
|
||||
}
|
||||
|
||||
return nbttaglist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an NBTTagCompound from an AttributeInstance, including its AttributeModifiers
|
||||
*/
|
||||
private static NBTTagCompound writeAttributeInstanceToNBT(AttributeInstance instance)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
Attribute iattribute = instance.getAttribute();
|
||||
nbttagcompound.setString("Name", iattribute.getUnlocalizedName());
|
||||
nbttagcompound.setDouble("Base", instance.getBaseValue());
|
||||
Collection<AttributeModifier> collection = instance.func_111122_c();
|
||||
|
||||
if (collection != null && !collection.isEmpty())
|
||||
{
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
|
||||
for (AttributeModifier attributemodifier : collection)
|
||||
{
|
||||
if (attributemodifier.isSaved())
|
||||
{
|
||||
nbttaglist.appendTag(writeAttributeModifierToNBT(attributemodifier));
|
||||
}
|
||||
}
|
||||
|
||||
nbttagcompound.setTag("Modifiers", nbttaglist);
|
||||
}
|
||||
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an NBTTagCompound from an AttributeModifier
|
||||
*/
|
||||
private static NBTTagCompound writeAttributeModifierToNBT(AttributeModifier modifier)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
nbttagcompound.setString("Name", modifier.getName());
|
||||
nbttagcompound.setDouble("Amount", modifier.getAmount());
|
||||
nbttagcompound.setBoolean("Multiply", modifier.isMultiplied());
|
||||
nbttagcompound.setLong("AttrId", modifier.getID());
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
public static void setAttributeModifiers(AttributeMap map, NBTTagList list)
|
||||
{
|
||||
for (int i = 0; i < list.tagCount(); ++i)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = list.getCompoundTagAt(i);
|
||||
AttributeInstance iattributeinstance = map.getAttributeInstanceByName(nbttagcompound.getString("Name"));
|
||||
|
||||
if (iattributeinstance != null)
|
||||
{
|
||||
applyModifiersToAttributeInstance(iattributeinstance, nbttagcompound);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.JNI.warn("Ignoriere unbekannte Attribute \'" + nbttagcompound.getString("Name") + "\'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyModifiersToAttributeInstance(AttributeInstance instance, NBTTagCompound compound)
|
||||
{
|
||||
instance.setBaseValue(compound.getDouble("Base"));
|
||||
|
||||
if (compound.hasKey("Modifiers", 9))
|
||||
{
|
||||
NBTTagList nbttaglist = compound.getTagList("Modifiers", 10);
|
||||
|
||||
for (int i = 0; i < nbttaglist.tagCount(); ++i)
|
||||
{
|
||||
AttributeModifier attributemodifier = readAttributeModifierFromNBT(nbttaglist.getCompoundTagAt(i));
|
||||
|
||||
if (attributemodifier != null)
|
||||
{
|
||||
AttributeModifier attributemodifier1 = instance.getModifier(attributemodifier.getID());
|
||||
|
||||
if (attributemodifier1 != null)
|
||||
{
|
||||
instance.removeModifier(attributemodifier1);
|
||||
}
|
||||
|
||||
instance.applyModifier(attributemodifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AttributeModifier from an NBTTagCompound
|
||||
*/
|
||||
public static AttributeModifier readAttributeModifierFromNBT(NBTTagCompound compound)
|
||||
{
|
||||
long id = compound.getLong("AttrId");
|
||||
if(id == 0L)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return new AttributeModifier(id, compound.getString("Name"), compound.getDouble("Amount"), compound.getBoolean("Multiply"));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.JNI.warn("Konnte Attribute nicht erstellen: " + exception.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
75
java/src/game/entity/attributes/LowerStringMap.java
Executable file
75
java/src/game/entity/attributes/LowerStringMap.java
Executable file
|
@ -0,0 +1,75 @@
|
|||
package game.entity.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import game.collect.Maps;
|
||||
|
||||
public class LowerStringMap<V> implements Map<String, V>
|
||||
{
|
||||
private final Map<String, V> internalMap = Maps.<String, V>newLinkedHashMap();
|
||||
|
||||
public int size()
|
||||
{
|
||||
return this.internalMap.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return this.internalMap.isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object p_containsKey_1_)
|
||||
{
|
||||
return this.internalMap.containsKey(p_containsKey_1_.toString().toLowerCase());
|
||||
}
|
||||
|
||||
public boolean containsValue(Object p_containsValue_1_)
|
||||
{
|
||||
return this.internalMap.containsKey(p_containsValue_1_);
|
||||
}
|
||||
|
||||
public V get(Object p_get_1_)
|
||||
{
|
||||
return this.internalMap.get(p_get_1_.toString().toLowerCase());
|
||||
}
|
||||
|
||||
public V put(String p_put_1_, V p_put_2_)
|
||||
{
|
||||
return this.internalMap.put(p_put_1_.toLowerCase(), p_put_2_);
|
||||
}
|
||||
|
||||
public V remove(Object p_remove_1_)
|
||||
{
|
||||
return this.internalMap.remove(p_remove_1_.toString().toLowerCase());
|
||||
}
|
||||
|
||||
public void putAll(Map <? extends String, ? extends V > p_putAll_1_)
|
||||
{
|
||||
for (Entry <? extends String, ? extends V > entry : p_putAll_1_.entrySet())
|
||||
{
|
||||
this.put((String)entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
this.internalMap.clear();
|
||||
}
|
||||
|
||||
public Set<String> keySet()
|
||||
{
|
||||
return this.internalMap.keySet();
|
||||
}
|
||||
|
||||
public Collection<V> values()
|
||||
{
|
||||
return this.internalMap.values();
|
||||
}
|
||||
|
||||
public Set<Entry<String, V>> entrySet()
|
||||
{
|
||||
return this.internalMap.entrySet();
|
||||
}
|
||||
}
|
96
java/src/game/entity/effect/EntityLightning.java
Executable file
96
java/src/game/entity/effect/EntityLightning.java
Executable file
|
@ -0,0 +1,96 @@
|
|||
package game.entity.effect;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityWeatherEffect;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.SoundEvent;
|
||||
import game.material.Material;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.World;
|
||||
import game.world.WorldClient;
|
||||
|
||||
public class EntityLightning extends EntityWeatherEffect
|
||||
{
|
||||
public final int color;
|
||||
public final int damage;
|
||||
public final boolean fire;
|
||||
public final EntityLiving summoner;
|
||||
|
||||
private int lightningState;
|
||||
public long boltVertex;
|
||||
private int boltLivingTime;
|
||||
|
||||
public EntityLightning(World worldIn, double posX, double posY, double posZ, int color, int damage, boolean fire, EntityLiving summoner)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setLocationAndAngles(posX, posY, posZ, 0.0F, 0.0F);
|
||||
this.lightningState = 2;
|
||||
this.color = color;
|
||||
this.fire = fire;
|
||||
this.damage = damage;
|
||||
this.summoner = summoner;
|
||||
this.boltVertex = this.rand.longv();
|
||||
this.boltLivingTime = this.rand.roll(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.lightningState == 2)
|
||||
{
|
||||
this.worldObj.playSound(SoundEvent.THUNDER, this.posX, this.posY, this.posZ, 10000.0F, 0.8F + this.rand.floatv() * 0.2F);
|
||||
this.worldObj.playSound(SoundEvent.EXPLODE, this.posX, this.posY, this.posZ, 2.0F, 0.5F + this.rand.floatv() * 0.2F);
|
||||
}
|
||||
|
||||
--this.lightningState;
|
||||
|
||||
if (this.lightningState < 0)
|
||||
{
|
||||
if (this.boltLivingTime == 0)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
else if (this.lightningState < -this.rand.zrange(10))
|
||||
{
|
||||
--this.boltLivingTime;
|
||||
this.lightningState = 1;
|
||||
this.boltVertex = this.rand.longv();
|
||||
BlockPos blockpos = new BlockPos(this);
|
||||
|
||||
if (!this.worldObj.client && this.fire && Config.fire && this.worldObj.isAreaLoaded(blockpos, 10) && this.worldObj.getState(blockpos).getBlock().getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this.worldObj, blockpos))
|
||||
{
|
||||
this.worldObj.setState(blockpos, Blocks.fire.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.lightningState >= 0)
|
||||
{
|
||||
if (this.worldObj.client)
|
||||
{
|
||||
((WorldClient)this.worldObj).setLastLightning(2, this.color);
|
||||
}
|
||||
else // if(this.damage > 0)
|
||||
{
|
||||
double d0 = 3.0D;
|
||||
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, new BoundingBox(this.posX - d0, this.posY - d0, this.posZ - d0, this.posX + d0, this.posY + 6.0D + d0, this.posZ + d0));
|
||||
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
Entity entity = (Entity)list.get(i);
|
||||
if(entity != this.summoner)
|
||||
entity.onStruckByLightning(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
644
java/src/game/entity/item/EntityBoat.java
Executable file
644
java/src/game/entity/item/EntityBoat.java
Executable file
|
@ -0,0 +1,644 @@
|
|||
package game.entity.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.EntityDamageSourceIndirect;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.ItemRegistry;
|
||||
import game.init.Items;
|
||||
import game.item.Item;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityBoat extends Entity
|
||||
{
|
||||
/** true if no player in boat */
|
||||
private boolean isBoatEmpty;
|
||||
private double speedMultiplier;
|
||||
private int boatPosRotationIncrements;
|
||||
private double boatX;
|
||||
private double boatY;
|
||||
private double boatZ;
|
||||
private double boatYaw;
|
||||
private double boatPitch;
|
||||
private double velocityX;
|
||||
private double velocityY;
|
||||
private double velocityZ;
|
||||
|
||||
public EntityBoat(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.isBoatEmpty = true;
|
||||
this.speedMultiplier = 0.07D;
|
||||
this.preventSpawning = true;
|
||||
this.setSize(1.5F, 0.6F);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
this.dataWatcher.addObject(17, 0);
|
||||
this.dataWatcher.addObject(18, 1);
|
||||
this.dataWatcher.addObject(19, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
|
||||
* pushable on contact, like boats or minecarts.
|
||||
*/
|
||||
public BoundingBox getCollisionBox(Entity entityIn)
|
||||
{
|
||||
return entityIn.getEntityBoundingBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collision bounding box for this entity
|
||||
*/
|
||||
public BoundingBox getCollisionBoundingBox()
|
||||
{
|
||||
return this.getEntityBoundingBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this entity should push and be pushed by other entities when colliding.
|
||||
*/
|
||||
public boolean canBePushed()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public EntityBoat(World worldIn, double p_i1705_2_, double p_i1705_4_, double p_i1705_6_)
|
||||
{
|
||||
this(worldIn);
|
||||
this.setPosition(p_i1705_2_, p_i1705_4_, p_i1705_6_);
|
||||
this.motionX = 0.0D;
|
||||
this.motionY = 0.0D;
|
||||
this.motionZ = 0.0D;
|
||||
this.prevX = p_i1705_2_;
|
||||
this.prevY = p_i1705_4_;
|
||||
this.prevZ = p_i1705_6_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Y offset from the entity's position for any entity riding this one.
|
||||
*/
|
||||
public double getMountedYOffset()
|
||||
{
|
||||
return -0.3D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.worldObj.client && !this.dead)
|
||||
{
|
||||
if (this.passenger != null && this.passenger == source.getEntity() && source instanceof EntityDamageSourceIndirect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setForwardDirection(-this.getForwardDirection());
|
||||
this.setTimeSinceHit(10);
|
||||
this.setDamageTaken(this.getDamageTaken() + (int)amount * 10);
|
||||
this.setBeenAttacked();
|
||||
// boolean flag = source.getEntity().isPlayer() && ((EntityNPC)source.getEntity()).creative;
|
||||
|
||||
if (/* flag || */ this.getDamageTaken() > 40)
|
||||
{
|
||||
if (this.passenger != null)
|
||||
{
|
||||
this.passenger.mountEntity(this);
|
||||
}
|
||||
|
||||
if (/* !flag && */ Config.objectDrop)
|
||||
{
|
||||
this.dropItemWithOffset(Items.boat, 1, 0.0F);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups the entity to do the hurt animation. Only used by packets in multiplayer.
|
||||
*/
|
||||
public void performHurtAnimation()
|
||||
{
|
||||
this.setForwardDirection(-this.getForwardDirection());
|
||||
this.setTimeSinceHit(10);
|
||||
this.setDamageTaken(this.getDamageTaken() * 11);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return !this.dead;
|
||||
}
|
||||
|
||||
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_)
|
||||
{
|
||||
if (p_180426_10_ && this.passenger != null)
|
||||
{
|
||||
this.prevX = this.posX = x;
|
||||
this.prevY = this.posY = y;
|
||||
this.prevZ = this.posZ = z;
|
||||
this.rotYaw = yaw;
|
||||
this.rotPitch = pitch;
|
||||
this.boatPosRotationIncrements = 0;
|
||||
this.setPosition(x, y, z);
|
||||
this.motionX = this.velocityX = 0.0D;
|
||||
this.motionY = this.velocityY = 0.0D;
|
||||
this.motionZ = this.velocityZ = 0.0D;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.isBoatEmpty)
|
||||
{
|
||||
this.boatPosRotationIncrements = posRotationIncrements + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
double d0 = x - this.posX;
|
||||
double d1 = y - this.posY;
|
||||
double d2 = z - this.posZ;
|
||||
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
|
||||
|
||||
if (d3 <= 1.0D)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.boatPosRotationIncrements = 3;
|
||||
}
|
||||
|
||||
this.boatX = x;
|
||||
this.boatY = y;
|
||||
this.boatZ = z;
|
||||
this.boatYaw = (double)yaw;
|
||||
this.boatPitch = (double)pitch;
|
||||
this.motionX = this.velocityX;
|
||||
this.motionY = this.velocityY;
|
||||
this.motionZ = this.velocityZ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double x, double y, double z)
|
||||
{
|
||||
this.velocityX = this.motionX = x;
|
||||
this.velocityY = this.motionY = y;
|
||||
this.velocityZ = this.motionZ = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.getTimeSinceHit() > 0)
|
||||
{
|
||||
this.setTimeSinceHit(this.getTimeSinceHit() - 1);
|
||||
}
|
||||
|
||||
if (this.getDamageTaken() > 0)
|
||||
{
|
||||
this.setDamageTaken(this.getDamageTaken() - 1);
|
||||
}
|
||||
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
int i = 5;
|
||||
double d0 = 0.0D;
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
double d1 = this.getEntityBoundingBox().minY + (this.getEntityBoundingBox().maxY - this.getEntityBoundingBox().minY) * (double)(j + 0) / (double)i - 0.125D;
|
||||
double d3 = this.getEntityBoundingBox().minY + (this.getEntityBoundingBox().maxY - this.getEntityBoundingBox().minY) * (double)(j + 1) / (double)i - 0.125D;
|
||||
BoundingBox axisalignedbb = new BoundingBox(this.getEntityBoundingBox().minX, d1, this.getEntityBoundingBox().minZ, this.getEntityBoundingBox().maxX, d3, this.getEntityBoundingBox().maxZ);
|
||||
|
||||
if (this.worldObj.isAABBInLiquid(axisalignedbb))
|
||||
{
|
||||
d0 += 1.0D / (double)i;
|
||||
}
|
||||
}
|
||||
|
||||
double d9 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
|
||||
if (d9 > 0.2975D)
|
||||
{
|
||||
double d2 = Math.cos((double)this.rotYaw * Math.PI / 180.0D);
|
||||
double d4 = Math.sin((double)this.rotYaw * Math.PI / 180.0D);
|
||||
|
||||
for (int k = 0; (double)k < 1.0D + d9 * 60.0D; ++k)
|
||||
{
|
||||
double d5 = (double)(this.rand.floatv() * 2.0F - 1.0F);
|
||||
double d6 = (double)(this.rand.zrange(2) * 2 - 1) * 0.7D;
|
||||
|
||||
if (this.rand.chance())
|
||||
{
|
||||
double d7 = this.posX - d2 * d5 * 0.8D + d4 * d6;
|
||||
double d8 = this.posZ - d4 * d5 * 0.8D - d2 * d6;
|
||||
this.worldObj.spawnParticle(ParticleType.WATER_SPLASH, d7, this.posY - 0.125D, d8, this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
double d24 = this.posX + d2 + d4 * d5 * 0.7D;
|
||||
double d25 = this.posZ + d4 - d2 * d5 * 0.7D;
|
||||
this.worldObj.spawnParticle(ParticleType.WATER_SPLASH, d24, this.posY - 0.125D, d25, this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.worldObj.client && this.isBoatEmpty)
|
||||
{
|
||||
if (this.boatPosRotationIncrements > 0)
|
||||
{
|
||||
double d12 = this.posX + (this.boatX - this.posX) / (double)this.boatPosRotationIncrements;
|
||||
double d16 = this.posY + (this.boatY - this.posY) / (double)this.boatPosRotationIncrements;
|
||||
double d19 = this.posZ + (this.boatZ - this.posZ) / (double)this.boatPosRotationIncrements;
|
||||
double d22 = ExtMath.wrapd(this.boatYaw - (double)this.rotYaw);
|
||||
this.rotYaw = (float)((double)this.rotYaw + d22 / (double)this.boatPosRotationIncrements);
|
||||
this.rotPitch = (float)((double)this.rotPitch + (this.boatPitch - (double)this.rotPitch) / (double)this.boatPosRotationIncrements);
|
||||
--this.boatPosRotationIncrements;
|
||||
this.setPosition(d12, d16, d19);
|
||||
this.setRotation(this.rotYaw, this.rotPitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
double d13 = this.posX + this.motionX;
|
||||
double d17 = this.posY + this.motionY;
|
||||
double d20 = this.posZ + this.motionZ;
|
||||
this.setPosition(d13, d17, d20);
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
this.motionX *= 0.5D;
|
||||
this.motionY *= 0.5D;
|
||||
this.motionZ *= 0.5D;
|
||||
}
|
||||
|
||||
this.motionX *= 0.9900000095367432D;
|
||||
this.motionY *= 0.949999988079071D;
|
||||
this.motionZ *= 0.9900000095367432D;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d0 < 1.0D)
|
||||
{
|
||||
double d10 = d0 * 2.0D - 1.0D;
|
||||
this.motionY += 0.03999999910593033D * d10;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.motionY < 0.0D)
|
||||
{
|
||||
this.motionY /= 2.0D;
|
||||
}
|
||||
|
||||
this.motionY += 0.007000000216066837D;
|
||||
}
|
||||
|
||||
if (this.passenger instanceof EntityLiving)
|
||||
{
|
||||
EntityLiving entitylivingbase = (EntityLiving)this.passenger;
|
||||
float f = this.passenger.rotYaw + -entitylivingbase.moveStrafe * 90.0F;
|
||||
this.motionX += -Math.sin((double)(f * (float)Math.PI / 180.0F)) * this.speedMultiplier * (double)entitylivingbase.moveForward * 0.05000000074505806D;
|
||||
this.motionZ += Math.cos((double)(f * (float)Math.PI / 180.0F)) * this.speedMultiplier * (double)entitylivingbase.moveForward * 0.05000000074505806D;
|
||||
}
|
||||
|
||||
double d11 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
|
||||
if (d11 > 0.35D)
|
||||
{
|
||||
double d14 = 0.35D / d11;
|
||||
this.motionX *= d14;
|
||||
this.motionZ *= d14;
|
||||
d11 = 0.35D;
|
||||
}
|
||||
|
||||
if (d11 > d9 && this.speedMultiplier < 0.35D)
|
||||
{
|
||||
this.speedMultiplier += (0.35D - this.speedMultiplier) / 35.0D;
|
||||
|
||||
if (this.speedMultiplier > 0.35D)
|
||||
{
|
||||
this.speedMultiplier = 0.35D;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.speedMultiplier -= (this.speedMultiplier - 0.07D) / 35.0D;
|
||||
|
||||
if (this.speedMultiplier < 0.07D)
|
||||
{
|
||||
this.speedMultiplier = 0.07D;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i1 = 0; i1 < 4; ++i1)
|
||||
{
|
||||
int l1 = ExtMath.floord(this.posX + ((double)(i1 % 2) - 0.5D) * 0.8D);
|
||||
int i2 = ExtMath.floord(this.posZ + ((double)(i1 / 2) - 0.5D) * 0.8D);
|
||||
|
||||
for (int j2 = 0; j2 < 2; ++j2)
|
||||
{
|
||||
int l = ExtMath.floord(this.posY) + j2;
|
||||
BlockPos blockpos = new BlockPos(l1, l, i2);
|
||||
Block block = this.worldObj.getState(blockpos).getBlock();
|
||||
|
||||
if (block == Blocks.snow_layer)
|
||||
{
|
||||
this.worldObj.setBlockToAir(blockpos);
|
||||
this.collidedHorizontally = false;
|
||||
}
|
||||
else if (block == Blocks.waterlily)
|
||||
{
|
||||
this.worldObj.destroyBlock(blockpos, true);
|
||||
this.collidedHorizontally = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
this.motionX *= 0.5D;
|
||||
this.motionY *= 0.5D;
|
||||
this.motionZ *= 0.5D;
|
||||
}
|
||||
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
|
||||
if (this.collidedHorizontally && d9 > 0.2975D)
|
||||
{
|
||||
if (!this.worldObj.client && !this.dead)
|
||||
{
|
||||
this.setDead();
|
||||
|
||||
if (Config.objectDrop)
|
||||
{
|
||||
for (int j1 = 0; j1 < 3; ++j1)
|
||||
{
|
||||
this.dropItemWithOffset(ItemRegistry.getItemFromBlock(Blocks.oak_planks), 1, 0.0F);
|
||||
}
|
||||
|
||||
for (int k1 = 0; k1 < 2; ++k1)
|
||||
{
|
||||
this.dropItemWithOffset(Items.stick, 1, 0.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.motionX *= 0.9900000095367432D;
|
||||
this.motionY *= 0.949999988079071D;
|
||||
this.motionZ *= 0.9900000095367432D;
|
||||
}
|
||||
|
||||
this.rotPitch = 0.0F;
|
||||
double d15 = (double)this.rotYaw;
|
||||
double d18 = this.prevX - this.posX;
|
||||
double d21 = this.prevZ - this.posZ;
|
||||
|
||||
if (d18 * d18 + d21 * d21 > 0.001D)
|
||||
{
|
||||
d15 = (double)((float)(ExtMath.atan2(d21, d18) * 180.0D / Math.PI));
|
||||
}
|
||||
|
||||
double d23 = ExtMath.wrapd(d15 - (double)this.rotYaw);
|
||||
|
||||
if (d23 > 20.0D)
|
||||
{
|
||||
d23 = 20.0D;
|
||||
}
|
||||
|
||||
if (d23 < -20.0D)
|
||||
{
|
||||
d23 = -20.0D;
|
||||
}
|
||||
|
||||
this.rotYaw = (float)((double)this.rotYaw + d23);
|
||||
this.setRotation(this.rotYaw, this.rotPitch);
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
|
||||
|
||||
if (list != null && !list.isEmpty())
|
||||
{
|
||||
for (int k2 = 0; k2 < list.size(); ++k2)
|
||||
{
|
||||
Entity entity = (Entity)list.get(k2);
|
||||
|
||||
if (entity != this.passenger && entity.canBePushed() && entity instanceof EntityBoat)
|
||||
{
|
||||
entity.applyEntityCollision(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.passenger != null && this.passenger.dead)
|
||||
{
|
||||
this.passenger = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateRiderPosition()
|
||||
{
|
||||
if (this.passenger != null)
|
||||
{
|
||||
double d0 = Math.cos((double)this.rotYaw * Math.PI / 180.0D) * 0.4D;
|
||||
double d1 = Math.sin((double)this.rotYaw * Math.PI / 180.0D) * 0.4D;
|
||||
this.passenger.setPosition(this.posX + d0, this.posY + this.getMountedYOffset() + this.passenger.getYOffset(), this.posZ + d1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* First layer of player interaction
|
||||
*/
|
||||
public boolean interactFirst(EntityNPC playerIn)
|
||||
{
|
||||
if (this.passenger != null && /* this.passenger.isPlayer() && */ this.passenger != playerIn)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
playerIn.mountEntity(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateFallState(double y, boolean onGroundIn, Block blockIn, BlockPos pos)
|
||||
{
|
||||
if (onGroundIn)
|
||||
{
|
||||
if (this.fallDistance > 3.0F)
|
||||
{
|
||||
if(this.ignoreFall) {
|
||||
this.ignoreFall = false;
|
||||
}
|
||||
else {
|
||||
this.fall(this.fallDistance, 1.0F);
|
||||
|
||||
if (!this.worldObj.client && !this.dead)
|
||||
{
|
||||
this.setDead();
|
||||
|
||||
if (Config.objectDrop)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
this.dropItemWithOffset(ItemRegistry.getItemFromBlock(Blocks.oak_planks), 1, 0.0F);
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
this.dropItemWithOffset(Items.stick, 1, 0.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.fallDistance = 0.0F;
|
||||
}
|
||||
}
|
||||
else if (!this.worldObj.getState((new BlockPos(this)).down()).getBlock().getMaterial().isColdLiquid() && y < 0.0D)
|
||||
{
|
||||
this.fallDistance = (float)((double)this.fallDistance - y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the damage taken from the last hit.
|
||||
*/
|
||||
public void setDamageTaken(int p_70266_1_)
|
||||
{
|
||||
this.dataWatcher.updateObject(19, Integer.valueOf(p_70266_1_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the damage taken from the last hit.
|
||||
*/
|
||||
public int getDamageTaken()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectInt(19);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time to count down from since the last time entity was hit.
|
||||
*/
|
||||
public void setTimeSinceHit(int p_70265_1_)
|
||||
{
|
||||
this.dataWatcher.updateObject(17, Integer.valueOf(p_70265_1_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time since the last hit.
|
||||
*/
|
||||
public int getTimeSinceHit()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectInt(17);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the forward direction of the entity.
|
||||
*/
|
||||
public void setForwardDirection(int p_70269_1_)
|
||||
{
|
||||
this.dataWatcher.updateObject(18, Integer.valueOf(p_70269_1_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the forward direction of the entity.
|
||||
*/
|
||||
public int getForwardDirection()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectInt(18);
|
||||
}
|
||||
|
||||
/**
|
||||
* true if no player in boat
|
||||
*/
|
||||
public void setIsBoatEmpty(boolean p_70270_1_)
|
||||
{
|
||||
this.isBoatEmpty = p_70270_1_;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return Items.boat;
|
||||
}
|
||||
}
|
1121
java/src/game/entity/item/EntityCart.java
Executable file
1121
java/src/game/entity/item/EntityCart.java
Executable file
File diff suppressed because it is too large
Load diff
287
java/src/game/entity/item/EntityCartContainer.java
Executable file
287
java/src/game/entity/item/EntityCartContainer.java
Executable file
|
@ -0,0 +1,287 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.init.Config;
|
||||
import game.inventory.Container;
|
||||
import game.inventory.InventoryHelper;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.nbt.NBTTagList;
|
||||
import game.tileentity.ILockableContainer;
|
||||
import game.tileentity.LockCode;
|
||||
import game.world.BlockPos;
|
||||
import game.world.PortalType;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityCartContainer extends EntityCart implements ILockableContainer
|
||||
{
|
||||
private ItemStack[] minecartContainerItems = new ItemStack[36];
|
||||
|
||||
/**
|
||||
* When set to true, the minecart will drop all items when setDead() is called. When false (such as when travelling
|
||||
* dimensions) it preserves its contents.
|
||||
*/
|
||||
private boolean dropContentsWhenDead = true;
|
||||
|
||||
public EntityCartContainer(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityCartContainer(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public void killMinecart(DamageSource source)
|
||||
{
|
||||
super.killMinecart(source);
|
||||
|
||||
if (Config.objectDrop)
|
||||
{
|
||||
InventoryHelper.dropInventoryItems(this.worldObj, this, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stack in the given slot.
|
||||
*/
|
||||
public ItemStack getStackInSlot(int index)
|
||||
{
|
||||
return this.minecartContainerItems[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes up to a specified number of items from an inventory slot and returns them in a new stack.
|
||||
*/
|
||||
public ItemStack decrStackSize(int index, int count)
|
||||
{
|
||||
if (this.minecartContainerItems[index] != null)
|
||||
{
|
||||
if (this.minecartContainerItems[index].stackSize <= count)
|
||||
{
|
||||
ItemStack itemstack1 = this.minecartContainerItems[index];
|
||||
this.minecartContainerItems[index] = null;
|
||||
return itemstack1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemStack itemstack = this.minecartContainerItems[index].splitStack(count);
|
||||
|
||||
if (this.minecartContainerItems[index].stackSize == 0)
|
||||
{
|
||||
this.minecartContainerItems[index] = null;
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a stack from the given slot and returns it.
|
||||
*/
|
||||
public ItemStack removeStackFromSlot(int index)
|
||||
{
|
||||
if (this.minecartContainerItems[index] != null)
|
||||
{
|
||||
ItemStack itemstack = this.minecartContainerItems[index];
|
||||
this.minecartContainerItems[index] = null;
|
||||
return itemstack;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
|
||||
*/
|
||||
public void setInventorySlotContents(int index, ItemStack stack)
|
||||
{
|
||||
this.minecartContainerItems[index] = stack;
|
||||
|
||||
if (stack != null && stack.stackSize > this.getInventoryStackLimit())
|
||||
{
|
||||
stack.stackSize = this.getInventoryStackLimit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For tile entities, ensures the chunk containing the tile entity is saved to disk later - the game won't think it
|
||||
* hasn't changed and skip it.
|
||||
*/
|
||||
public void markDirty()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not make give this method the name canInteractWith because it clashes with Container
|
||||
*/
|
||||
public boolean isUseableByPlayer(EntityNPC player)
|
||||
{
|
||||
return this.dead ? false : player.getDistanceSqToEntity(this) <= 64.0D;
|
||||
}
|
||||
|
||||
public void openInventory(EntityNPC player)
|
||||
{
|
||||
}
|
||||
|
||||
public void closeInventory(EntityNPC player)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot.
|
||||
*/
|
||||
public boolean isItemValidForSlot(int index, ItemStack stack)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the name of this object. For players this returns their username
|
||||
// */
|
||||
// public IChatComponent getTypeName()
|
||||
// {
|
||||
// return this.hasCustomName() ? new ChatComponentText(this.getCustomNameTag()) : new ChatComponentTranslation("container.minecart");
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
|
||||
*/
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
return ItemStack.MAX_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports the entity to another dimension. Params: Dimension number to teleport to
|
||||
*/
|
||||
public Entity travelToDimension(int dimensionId, BlockPos pos, float yaw, float pitch, PortalType portal)
|
||||
{
|
||||
this.dropContentsWhenDead = false;
|
||||
return super.travelToDimension(dimensionId, pos, yaw, pitch, portal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will get destroyed next tick.
|
||||
*/
|
||||
public void setDead()
|
||||
{
|
||||
if (this.dropContentsWhenDead)
|
||||
{
|
||||
InventoryHelper.dropInventoryItems(this.worldObj, this, this);
|
||||
}
|
||||
|
||||
super.setDead();
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
|
||||
for (int i = 0; i < this.minecartContainerItems.length; ++i)
|
||||
{
|
||||
if (this.minecartContainerItems[i] != null)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
nbttagcompound.setByte("Slot", (byte)i);
|
||||
this.minecartContainerItems[i].writeToNBT(nbttagcompound);
|
||||
nbttaglist.appendTag(nbttagcompound);
|
||||
}
|
||||
}
|
||||
|
||||
tagCompound.setTag("Items", nbttaglist);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
NBTTagList nbttaglist = tagCompund.getTagList("Items", 10);
|
||||
this.minecartContainerItems = new ItemStack[this.getSizeInventory()];
|
||||
|
||||
for (int i = 0; i < nbttaglist.tagCount(); ++i)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
|
||||
int j = nbttagcompound.getByte("Slot") & 255;
|
||||
|
||||
if (j >= 0 && j < this.minecartContainerItems.length)
|
||||
{
|
||||
this.minecartContainerItems[j] = ItemStack.loadItemStackFromNBT(nbttagcompound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* First layer of player interaction
|
||||
*/
|
||||
public boolean interactFirst(EntityNPC playerIn)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
playerIn.displayGUIChest(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void applyDrag()
|
||||
{
|
||||
int i = 15 - Container.calcRedstoneFromInventory(this);
|
||||
float f = 0.98F + (float)i * 0.001F;
|
||||
this.motionX *= (double)f;
|
||||
this.motionY *= 0.0D;
|
||||
this.motionZ *= (double)f;
|
||||
}
|
||||
|
||||
public int getField(int id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setField(int id, int value)
|
||||
{
|
||||
}
|
||||
|
||||
public int getFieldCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isLocked()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setLockCode(LockCode code)
|
||||
{
|
||||
}
|
||||
|
||||
public LockCode getLockCode()
|
||||
{
|
||||
return LockCode.EMPTY_CODE;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
for (int i = 0; i < this.minecartContainerItems.length; ++i)
|
||||
{
|
||||
this.minecartContainerItems[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
70
java/src/game/entity/item/EntityChestCart.java
Executable file
70
java/src/game/entity/item/EntityChestCart.java
Executable file
|
@ -0,0 +1,70 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.block.BlockChest;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.ItemRegistry;
|
||||
import game.inventory.Container;
|
||||
import game.inventory.ContainerChest;
|
||||
import game.inventory.InventoryPlayer;
|
||||
import game.world.Facing;
|
||||
import game.world.State;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityChestCart extends EntityCartContainer
|
||||
{
|
||||
public EntityChestCart(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityChestCart(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public void killMinecart(DamageSource source)
|
||||
{
|
||||
super.killMinecart(source);
|
||||
|
||||
if (Config.objectDrop)
|
||||
{
|
||||
this.dropItemWithOffset(ItemRegistry.getItemFromBlock(Blocks.chest), 1, 0.0F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of slots in the inventory.
|
||||
*/
|
||||
public int getSizeInventory()
|
||||
{
|
||||
return 27;
|
||||
}
|
||||
|
||||
public EntityCart.EnumMinecartType getMinecartType()
|
||||
{
|
||||
return EntityCart.EnumMinecartType.CHEST;
|
||||
}
|
||||
|
||||
public State getDefaultDisplayTile()
|
||||
{
|
||||
return Blocks.chest.getState().withProperty(BlockChest.FACING, Facing.NORTH);
|
||||
}
|
||||
|
||||
public int getDefaultDisplayTileOffset()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public String getGuiID()
|
||||
{
|
||||
return "chest";
|
||||
}
|
||||
|
||||
public Container createContainer(InventoryPlayer playerInventory, EntityNPC playerIn)
|
||||
{
|
||||
return new ContainerChest(playerInventory, this, playerIn);
|
||||
}
|
||||
}
|
125
java/src/game/entity/item/EntityCrystal.java
Executable file
125
java/src/game/entity/item/EntityCrystal.java
Executable file
|
@ -0,0 +1,125 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityCrystal extends Entity
|
||||
{
|
||||
public int innerRotation;
|
||||
// public int health;
|
||||
|
||||
public EntityCrystal(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.preventSpawning = true;
|
||||
this.setSize(2.0F, 2.0F);
|
||||
// this.health = 5;
|
||||
this.innerRotation = this.rand.zrange(100000);
|
||||
}
|
||||
|
||||
public EntityCrystal(World worldIn, double x, double y, double z)
|
||||
{
|
||||
this(worldIn);
|
||||
this.setPosition(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
// this.dataWatcher.addObject(8, Integer.valueOf(this.health));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
++this.innerRotation;
|
||||
// this.dataWatcher.updateObject(8, Integer.valueOf(this.health));
|
||||
// int i = MathHelper.floor_double(this.posX);
|
||||
// int j = MathHelper.floor_double(this.posY);
|
||||
// int k = MathHelper.floor_double(this.posZ);
|
||||
//
|
||||
// if (this.worldObj.dimension instanceof AreaEnd && this.worldObj.getBlockState(new BlockPos(i, j, k)).getBlock() != Blocks.fire)
|
||||
// {
|
||||
// this.worldObj.setBlockState(new BlockPos(i, j, k), Blocks.fire.getDefaultState());
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.dead && !this.worldObj.client)
|
||||
{
|
||||
// this.health = 0;
|
||||
//
|
||||
// if (this.health <= 0)
|
||||
// {
|
||||
this.setDead();
|
||||
|
||||
// if (!this.worldObj.client)
|
||||
// {
|
||||
this.worldObj.createExplosion(null, this.posX, this.posY, this.posZ, 6.0F, true);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 256;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
}
|
92
java/src/game/entity/item/EntityExplosion.java
Executable file
92
java/src/game/entity/item/EntityExplosion.java
Executable file
|
@ -0,0 +1,92 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.Entity;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.Explosion;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityExplosion extends Entity
|
||||
{
|
||||
private int progress;
|
||||
private int radius;
|
||||
|
||||
public EntityExplosion(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.preventSpawning = true;
|
||||
this.setSize(0.1F, 0.1F);
|
||||
// this.setInvisible(true);
|
||||
}
|
||||
|
||||
public EntityExplosion(World worldIn, double x, double y, double z)
|
||||
{
|
||||
this(worldIn, x, y, z, 70);
|
||||
}
|
||||
|
||||
public EntityExplosion(World worldIn, double x, double y, double z, int radius)
|
||||
{
|
||||
this(worldIn);
|
||||
this.setPosition(x, y, z);
|
||||
this.prevX = x;
|
||||
this.prevY = y;
|
||||
this.prevZ = z;
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onUpdate()
|
||||
{
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.motionX = this.motionY = this.motionZ = 0.0D;
|
||||
if(this.progress++ >= this.radius) {
|
||||
this.setDead();
|
||||
}
|
||||
else if(!this.worldObj.client) {
|
||||
this.explode(this.progress - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void explode(double min)
|
||||
{
|
||||
Explosion.doExplosionAlgo3(this.worldObj, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, this.rand, min + 6.0d, min);
|
||||
}
|
||||
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setInteger("Progress", this.progress);
|
||||
tagCompound.setInteger("Radius", this.radius);
|
||||
}
|
||||
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.progress = tagCompund.getInteger("Progress");
|
||||
this.radius = tagCompund.getInteger("Radius");
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
}
|
341
java/src/game/entity/item/EntityFalling.java
Executable file
341
java/src/game/entity/item/EntityFalling.java
Executable file
|
@ -0,0 +1,341 @@
|
|||
package game.entity.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.block.BlockAnvil;
|
||||
import game.block.BlockFalling;
|
||||
import game.block.ITileEntityProvider;
|
||||
import game.collect.Lists;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.init.BlockRegistry;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.item.ItemStack;
|
||||
import game.material.Material;
|
||||
import game.nbt.NBTBase;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.tileentity.TileEntity;
|
||||
import game.world.BlockPos;
|
||||
import game.world.Facing;
|
||||
import game.world.State;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityFalling extends Entity implements IObjectData
|
||||
{
|
||||
private State fallTile;
|
||||
public int fallTime;
|
||||
public boolean shouldDropItem = true;
|
||||
private boolean canSetAsBlock;
|
||||
private boolean hurtEntities;
|
||||
private int fallHurtMax = 40;
|
||||
private float fallHurtAmount = 2.0F;
|
||||
public NBTTagCompound tileEntityData;
|
||||
|
||||
public EntityFalling(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityFalling(World worldIn, double x, double y, double z, State fallingBlockState)
|
||||
{
|
||||
super(worldIn);
|
||||
this.fallTile = fallingBlockState;
|
||||
this.preventSpawning = true;
|
||||
this.setSize(0.98F, 0.98F);
|
||||
this.setPosition(x, y, z);
|
||||
this.motionX = 0.0D;
|
||||
this.motionY = 0.0D;
|
||||
this.motionZ = 0.0D;
|
||||
this.prevX = x;
|
||||
this.prevY = y;
|
||||
this.prevZ = z;
|
||||
}
|
||||
|
||||
public EntityFalling(World worldIn, double x, double y, double z, int data)
|
||||
{
|
||||
this(worldIn, x, y, z, BlockRegistry.getStateById(data & 65535));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return !this.dead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
Block block = this.fallTile.getBlock();
|
||||
|
||||
if (block.getMaterial() == Material.air)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
|
||||
if (this.fallTime++ == 0)
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this);
|
||||
|
||||
if (this.worldObj.getState(blockpos).getBlock() == block)
|
||||
{
|
||||
this.worldObj.setBlockToAir(blockpos);
|
||||
}
|
||||
else if (!this.worldObj.client)
|
||||
{
|
||||
this.setDead();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.motionY -= 0.03999999910593033D;
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.9800000190734863D;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= 0.9800000190734863D;
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
BlockPos blockpos1 = new BlockPos(this);
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
this.motionX *= 0.699999988079071D;
|
||||
this.motionZ *= 0.699999988079071D;
|
||||
this.motionY *= -0.5D;
|
||||
|
||||
if (this.worldObj.getState(blockpos1).getBlock() != Blocks.piston_extension)
|
||||
{
|
||||
this.setDead();
|
||||
|
||||
if (!this.canSetAsBlock)
|
||||
{
|
||||
if (this.worldObj.canBlockBePlaced(block, blockpos1, true, Facing.UP, (Entity)null, (ItemStack)null) && !BlockFalling.canFallInto(this.worldObj, blockpos1.down()) && this.worldObj.setState(blockpos1, this.fallTile, 3))
|
||||
{
|
||||
if (block instanceof BlockFalling)
|
||||
{
|
||||
((BlockFalling)block).onEndFalling(this.worldObj, blockpos1);
|
||||
}
|
||||
|
||||
if (this.tileEntityData != null && block instanceof ITileEntityProvider)
|
||||
{
|
||||
TileEntity tileentity = this.worldObj.getTileEntity(blockpos1);
|
||||
|
||||
if (tileentity != null)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
tileentity.writeToNBT(nbttagcompound);
|
||||
|
||||
for (String s : this.tileEntityData.getKeySet())
|
||||
{
|
||||
NBTBase nbtbase = this.tileEntityData.getTag(s);
|
||||
|
||||
if (!s.equals("x") && !s.equals("y") && !s.equals("z"))
|
||||
{
|
||||
nbttagcompound.setTag(s, nbtbase.copy());
|
||||
}
|
||||
}
|
||||
|
||||
tileentity.readFromNBT(nbttagcompound);
|
||||
tileentity.markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.shouldDropItem && Config.objectDrop)
|
||||
{
|
||||
this.entityDropItem(new ItemStack(block, 1, block.damageDropped(this.fallTile)), 0.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.fallTime > 100 && !this.worldObj.client && (blockpos1.getY() < 1 || blockpos1.getY() > 512) || this.fallTime > 600)
|
||||
{
|
||||
if (this.shouldDropItem && Config.objectDrop)
|
||||
{
|
||||
this.entityDropItem(new ItemStack(block, 1, block.damageDropped(this.fallTile)), 0.0F);
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
Block block = this.fallTile.getBlock();
|
||||
|
||||
if (this.hurtEntities)
|
||||
{
|
||||
int i = ExtMath.ceilf(distance - 1.0F);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
List<Entity> list = Lists.newArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox()));
|
||||
boolean flag = block == Blocks.anvil;
|
||||
DamageSource damagesource = flag ? DamageSource.anvil : DamageSource.fallingBlock;
|
||||
|
||||
if(this.worldObj.client || (flag ? Config.damageAcme : Config.damageSquish)) {
|
||||
for (Entity entity : list)
|
||||
{
|
||||
entity.attackEntityFrom(damagesource, Math.min(ExtMath.floorf((float)i * this.fallHurtAmount), this.fallHurtMax));
|
||||
}
|
||||
}
|
||||
|
||||
if (flag && (this.worldObj.client || Config.anvilFallDecay) && (double)this.rand.floatv() < 0.05000000074505806D + (double)i * 0.05D)
|
||||
{
|
||||
int j = ((Integer)this.fallTile.getValue(BlockAnvil.DAMAGE)).intValue();
|
||||
++j;
|
||||
|
||||
if (j > 2)
|
||||
{
|
||||
this.canSetAsBlock = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.fallTile = this.fallTile.withProperty(BlockAnvil.DAMAGE, Integer.valueOf(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
Block block = this.fallTile != null ? this.fallTile.getBlock() : Blocks.air;
|
||||
String resourcelocation = BlockRegistry.REGISTRY.getNameForObject(block);
|
||||
tagCompound.setString("Block", resourcelocation == null ? "" : resourcelocation.toString());
|
||||
tagCompound.setByte("Data", (byte)block.getMetaFromState(this.fallTile));
|
||||
tagCompound.setByte("Time", (byte)this.fallTime);
|
||||
tagCompound.setBoolean("DropItem", this.shouldDropItem);
|
||||
tagCompound.setBoolean("HurtEntities", this.hurtEntities);
|
||||
tagCompound.setFloat("FallHurtAmount", this.fallHurtAmount);
|
||||
tagCompound.setInteger("FallHurtMax", this.fallHurtMax);
|
||||
|
||||
if (this.tileEntityData != null)
|
||||
{
|
||||
tagCompound.setTag("TileEntityData", this.tileEntityData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
int i = tagCompund.getByte("Data") & 255;
|
||||
|
||||
if (tagCompund.hasKey("Block", 8))
|
||||
{
|
||||
this.fallTile = BlockRegistry.getByIdFallback(tagCompund.getString("Block")).getStateFromMeta(i);
|
||||
}
|
||||
else if (tagCompund.hasKey("TileID", 99))
|
||||
{
|
||||
this.fallTile = BlockRegistry.getBlockById(tagCompund.getInteger("TileID")).getStateFromMeta(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.fallTile = BlockRegistry.getBlockById(tagCompund.getByte("Tile") & 255).getStateFromMeta(i);
|
||||
}
|
||||
|
||||
this.fallTime = tagCompund.getByte("Time") & 255;
|
||||
Block block = this.fallTile.getBlock();
|
||||
|
||||
if (tagCompund.hasKey("HurtEntities", 99))
|
||||
{
|
||||
this.hurtEntities = tagCompund.getBoolean("HurtEntities");
|
||||
this.fallHurtAmount = tagCompund.getFloat("FallHurtAmount");
|
||||
this.fallHurtMax = tagCompund.getInteger("FallHurtMax");
|
||||
}
|
||||
else if (block == Blocks.anvil)
|
||||
{
|
||||
this.hurtEntities = true;
|
||||
}
|
||||
|
||||
if (tagCompund.hasKey("DropItem", 99))
|
||||
{
|
||||
this.shouldDropItem = tagCompund.getBoolean("DropItem");
|
||||
}
|
||||
|
||||
if (tagCompund.hasKey("TileEntityData", 10))
|
||||
{
|
||||
this.tileEntityData = tagCompund.getCompoundTag("TileEntityData");
|
||||
}
|
||||
|
||||
if (block == null || block.getMaterial() == Material.air)
|
||||
{
|
||||
this.fallTile = Blocks.sand.getState();
|
||||
}
|
||||
}
|
||||
|
||||
public World getWorldObj()
|
||||
{
|
||||
return this.worldObj;
|
||||
}
|
||||
|
||||
public void setHurtEntities(boolean p_145806_1_)
|
||||
{
|
||||
this.hurtEntities = p_145806_1_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this entity should be rendered as on fire.
|
||||
*/
|
||||
public boolean canRenderOnFire()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public State getBlock()
|
||||
{
|
||||
return this.fallTile;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 160;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return BlockRegistry.getStateId(this.fallTile);
|
||||
}
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
}
|
235
java/src/game/entity/item/EntityFireworks.java
Executable file
235
java/src/game/entity/item/EntityFireworks.java
Executable file
|
@ -0,0 +1,235 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.entity.Entity;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.World;
|
||||
import game.world.WorldClient;
|
||||
|
||||
public class EntityFireworks extends Entity
|
||||
{
|
||||
/** The age of the firework in ticks. */
|
||||
private int fireworkAge;
|
||||
|
||||
/**
|
||||
* The lifetime of the firework in ticks. When the age reaches the lifetime the firework explodes.
|
||||
*/
|
||||
private int lifetime;
|
||||
|
||||
public EntityFireworks(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.25F, 0.25F);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
this.dataWatcher.addObjectByDataType(8, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
|
||||
* length * 64 * renderDistanceWeight Args: distance
|
||||
*/
|
||||
public boolean isInRangeToRenderDist(double distance)
|
||||
{
|
||||
return distance < 4096.0D;
|
||||
}
|
||||
|
||||
public EntityFireworks(World worldIn, double x, double y, double z, ItemStack givenItem)
|
||||
{
|
||||
super(worldIn);
|
||||
this.fireworkAge = 0;
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.setPosition(x, y, z);
|
||||
int i = 1;
|
||||
|
||||
if (givenItem != null && givenItem.hasTagCompound())
|
||||
{
|
||||
this.dataWatcher.updateObject(8, givenItem);
|
||||
NBTTagCompound nbttagcompound = givenItem.getTagCompound();
|
||||
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("Fireworks");
|
||||
|
||||
if (nbttagcompound1 != null)
|
||||
{
|
||||
i += nbttagcompound1.getByte("Flight");
|
||||
}
|
||||
}
|
||||
|
||||
this.motionX = this.rand.gaussian() * 0.001D;
|
||||
this.motionZ = this.rand.gaussian() * 0.001D;
|
||||
this.motionY = 0.05D;
|
||||
this.lifetime = 10 * i + this.rand.zrange(6) + this.rand.zrange(7);
|
||||
}
|
||||
|
||||
public EntityFireworks(World worldIn, double x, double y, double z)
|
||||
{
|
||||
this(worldIn, x, y, z, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double x, double y, double z)
|
||||
{
|
||||
this.motionX = x;
|
||||
this.motionY = y;
|
||||
this.motionZ = z;
|
||||
|
||||
if (this.prevPitch == 0.0F && this.prevYaw == 0.0F)
|
||||
{
|
||||
float f = ExtMath.sqrtd(x * x + z * z);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(x, z) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(y, (double)f) * 180.0D / Math.PI);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
this.lastTickPosX = this.posX;
|
||||
this.lastTickPosY = this.posY;
|
||||
this.lastTickPosZ = this.posZ;
|
||||
super.onUpdate();
|
||||
this.motionX *= 1.15D;
|
||||
this.motionZ *= 1.15D;
|
||||
this.motionY += 0.04D;
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
float f = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotYaw = (float)(ExtMath.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
|
||||
for (this.rotPitch = (float)(ExtMath.atan2(this.motionY, (double)f) * 180.0D / Math.PI); this.rotPitch - this.prevPitch < -180.0F; this.prevPitch -= 360.0F)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
while (this.rotPitch - this.prevPitch >= 180.0F)
|
||||
{
|
||||
this.prevPitch += 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw < -180.0F)
|
||||
{
|
||||
this.prevYaw -= 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw >= 180.0F)
|
||||
{
|
||||
this.prevYaw += 360.0F;
|
||||
}
|
||||
|
||||
this.rotPitch = this.prevPitch + (this.rotPitch - this.prevPitch) * 0.2F;
|
||||
this.rotYaw = this.prevYaw + (this.rotYaw - this.prevYaw) * 0.2F;
|
||||
|
||||
if (this.fireworkAge == 0) // && !this.isSilent())
|
||||
{
|
||||
this.worldObj.playSoundAtEntity(this, SoundEvent.LAUNCH, 3.0F, 1.0F);
|
||||
}
|
||||
|
||||
++this.fireworkAge;
|
||||
|
||||
if (this.worldObj.client && this.fireworkAge % 2 < 2)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.FIREWORKS_SPARK, this.posX, this.posY - 0.3D, this.posZ, this.rand.gaussian() * 0.05D, -this.motionY * 0.5D, this.rand.gaussian() * 0.05D);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client && this.fireworkAge > this.lifetime)
|
||||
{
|
||||
this.worldObj.setEntityState(this, (byte)17);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
if (id == 17 && this.worldObj.client)
|
||||
{
|
||||
ItemStack itemstack = this.dataWatcher.getWatchableObjectItemStack(8);
|
||||
NBTTagCompound nbttagcompound = null;
|
||||
|
||||
if (itemstack != null && itemstack.hasTagCompound())
|
||||
{
|
||||
nbttagcompound = itemstack.getTagCompound().getCompoundTag("Fireworks");
|
||||
}
|
||||
|
||||
((WorldClient)this.worldObj).makeFireworks(this.posX, this.posY, this.posZ, this.motionX, this.motionY, this.motionZ, nbttagcompound);
|
||||
}
|
||||
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setInteger("Life", this.fireworkAge);
|
||||
tagCompound.setInteger("LifeTime", this.lifetime);
|
||||
ItemStack itemstack = this.dataWatcher.getWatchableObjectItemStack(8);
|
||||
|
||||
if (itemstack != null)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
itemstack.writeToNBT(nbttagcompound);
|
||||
tagCompound.setTag("FireworksItem", nbttagcompound);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.fireworkAge = tagCompund.getInteger("Life");
|
||||
this.lifetime = tagCompund.getInteger("LifeTime");
|
||||
NBTTagCompound nbttagcompound = tagCompund.getCompoundTag("FireworksItem");
|
||||
|
||||
if (nbttagcompound != null)
|
||||
{
|
||||
ItemStack itemstack = ItemStack.loadItemStackFromNBT(nbttagcompound);
|
||||
|
||||
if (itemstack != null)
|
||||
{
|
||||
this.dataWatcher.updateObject(8, itemstack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets how bright this entity is.
|
||||
*/
|
||||
public float getBrightness(float partialTicks)
|
||||
{
|
||||
return super.getBrightness(partialTicks);
|
||||
}
|
||||
|
||||
public int getBrightnessForRender(float partialTicks)
|
||||
{
|
||||
return super.getBrightnessForRender(partialTicks);
|
||||
}
|
||||
|
||||
/**
|
||||
* If returns false, the item will not inflict any damage against entities.
|
||||
*/
|
||||
public boolean canAttackWithItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
}
|
244
java/src/game/entity/item/EntityHopperCart.java
Executable file
244
java/src/game/entity/item/EntityHopperCart.java
Executable file
|
@ -0,0 +1,244 @@
|
|||
package game.entity.item;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.ItemRegistry;
|
||||
import game.inventory.Container;
|
||||
import game.inventory.ContainerHopper;
|
||||
import game.inventory.InventoryPlayer;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.tileentity.IHopper;
|
||||
import game.tileentity.TileEntityHopper;
|
||||
import game.world.BlockPos;
|
||||
import game.world.State;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityHopperCart extends EntityCartContainer implements IHopper
|
||||
{
|
||||
/** Whether this hopper minecart is being blocked by an activator rail. */
|
||||
private boolean isBlocked = true;
|
||||
private int transferTicker = -1;
|
||||
private BlockPos field_174900_c = BlockPos.ORIGIN;
|
||||
|
||||
public EntityHopperCart(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityHopperCart(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public EntityCart.EnumMinecartType getMinecartType()
|
||||
{
|
||||
return EntityCart.EnumMinecartType.HOPPER;
|
||||
}
|
||||
|
||||
public State getDefaultDisplayTile()
|
||||
{
|
||||
return Blocks.hopper.getState();
|
||||
}
|
||||
|
||||
public int getDefaultDisplayTileOffset()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of slots in the inventory.
|
||||
*/
|
||||
public int getSizeInventory()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* First layer of player interaction
|
||||
*/
|
||||
public boolean interactFirst(EntityNPC playerIn)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
playerIn.displayGUIChest(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick the minecart is on an activator rail. Args: x, y, z, is the rail receiving power
|
||||
*/
|
||||
public void onActivatorRailPass(int x, int y, int z, boolean receivingPower)
|
||||
{
|
||||
boolean flag = !receivingPower;
|
||||
|
||||
if (flag != this.getBlocked())
|
||||
{
|
||||
this.setBlocked(flag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this hopper minecart is being blocked by an activator rail.
|
||||
*/
|
||||
public boolean getBlocked()
|
||||
{
|
||||
return this.isBlocked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this hopper minecart is being blocked by an activator rail.
|
||||
*/
|
||||
public void setBlocked(boolean p_96110_1_)
|
||||
{
|
||||
this.isBlocked = p_96110_1_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the worldObj for this tileEntity.
|
||||
*/
|
||||
public World getWorld()
|
||||
{
|
||||
return this.worldObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world X position for this hopper entity.
|
||||
*/
|
||||
public double getXPos()
|
||||
{
|
||||
return this.posX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world Y position for this hopper entity.
|
||||
*/
|
||||
public double getYPos()
|
||||
{
|
||||
return this.posY + 0.5D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world Z position for this hopper entity.
|
||||
*/
|
||||
public double getZPos()
|
||||
{
|
||||
return this.posZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (!this.worldObj.client && this.isEntityAlive() && this.getBlocked())
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this);
|
||||
|
||||
if (blockpos.equals(this.field_174900_c))
|
||||
{
|
||||
--this.transferTicker;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setTransferTicker(0);
|
||||
}
|
||||
|
||||
if (!this.canTransfer())
|
||||
{
|
||||
this.setTransferTicker(0);
|
||||
|
||||
if (this.func_96112_aD())
|
||||
{
|
||||
this.setTransferTicker(Config.hopperCartDelay);
|
||||
this.markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean func_96112_aD()
|
||||
{
|
||||
if (TileEntityHopper.captureDroppedItems(this))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<EntityItem> list = this.worldObj.<EntityItem>getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.25D, 0.0D, 0.25D), new Predicate<EntityItem>() {
|
||||
public boolean test(EntityItem entity) {
|
||||
return entity.isEntityAlive();
|
||||
}
|
||||
});
|
||||
|
||||
if (list.size() > 0)
|
||||
{
|
||||
TileEntityHopper.putDropInInventoryAllSlots(this, (EntityItem)list.get(0));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void killMinecart(DamageSource source)
|
||||
{
|
||||
super.killMinecart(source);
|
||||
|
||||
if (Config.objectDrop)
|
||||
{
|
||||
this.dropItemWithOffset(ItemRegistry.getItemFromBlock(Blocks.hopper), 1, 0.0F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("TransferCooldown", this.transferTicker);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.transferTicker = tagCompund.getInteger("TransferCooldown");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transfer ticker, used to determine the delay between transfers.
|
||||
*/
|
||||
public void setTransferTicker(int p_98042_1_)
|
||||
{
|
||||
this.transferTicker = p_98042_1_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the hopper cart can currently transfer an item.
|
||||
*/
|
||||
public boolean canTransfer()
|
||||
{
|
||||
return this.transferTicker > 0;
|
||||
}
|
||||
|
||||
public String getGuiID()
|
||||
{
|
||||
return "hopper";
|
||||
}
|
||||
|
||||
public Container createContainer(InventoryPlayer playerInventory, EntityNPC playerIn)
|
||||
{
|
||||
return new ContainerHopper(playerInventory, this, playerIn);
|
||||
}
|
||||
}
|
621
java/src/game/entity/item/EntityItem.java
Executable file
621
java/src/game/entity/item/EntityItem.java
Executable file
|
@ -0,0 +1,621 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.Log;
|
||||
import game.color.TextColor;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.ItemRegistry;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemStack;
|
||||
import game.material.Material;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.PortalType;
|
||||
import game.world.World;
|
||||
import game.world.WorldServer;
|
||||
|
||||
public class EntityItem extends Entity
|
||||
{
|
||||
/**
|
||||
* The age of this EntityItem (used to animate it up and down as well as expire it)
|
||||
*/
|
||||
private int age;
|
||||
private int delayBeforeCanPickup;
|
||||
|
||||
/** The health of this EntityItem. (For example, damage for tools) */
|
||||
private int health;
|
||||
// private String thrower;
|
||||
// private String owner;
|
||||
|
||||
/** The EntityItem's random initial float height. */
|
||||
public float hoverStart;
|
||||
|
||||
public EntityItem(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn);
|
||||
this.health = 5;
|
||||
this.hoverStart = (float)(Math.random() * Math.PI * 2.0D);
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.setPosition(x, y, z);
|
||||
this.rotYaw = (float)(Math.random() * 360.0D);
|
||||
this.motionX = (double)((float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D));
|
||||
this.motionY = 0.20000000298023224D;
|
||||
this.motionZ = (double)((float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D));
|
||||
}
|
||||
|
||||
public EntityItem(World worldIn, double x, double y, double z, ItemStack stack)
|
||||
{
|
||||
this(worldIn, x, y, z);
|
||||
this.setEntityItemStack(stack);
|
||||
}
|
||||
|
||||
// public EntityItem(World worldIn, double x, double y, double z, int data)
|
||||
// {
|
||||
// this(worldIn, x, y, z);
|
||||
// }
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
if(!this.worldObj.client && Config.itemFallDamage && distance >= 1.0f && this.getEntityItem().getItem().isFragile()) {
|
||||
// for(int z = 0; z < 8; z++) {
|
||||
((WorldServer)this.worldObj).spawnParticle(ParticleType.ITEM_CRACK, this.posX, this.posY, this.posZ,
|
||||
8, this.rand.gaussian() * 0.15D, this.rand.doublev() * 0.2D, this.rand.gaussian() * 0.15D, 0.1f,
|
||||
ItemRegistry.getIdFromItem(this.getEntityItem().getItem()), this.getEntityItem().getMetadata());
|
||||
// }
|
||||
this.worldObj.playAuxSFX(1023, this.getPosition(), 0);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public EntityItem(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.health = 5;
|
||||
this.hoverStart = (float)(Math.random() * Math.PI * 2.0D);
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.setEntityItemStack(new ItemStack(Blocks.air, 0));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
this.getDataWatcher().addObjectByDataType(10, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
if (this.getEntityItem() == null)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.delayBeforeCanPickup > 0 && this.delayBeforeCanPickup != 32767)
|
||||
{
|
||||
--this.delayBeforeCanPickup;
|
||||
}
|
||||
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.motionY -= 0.03999999910593033D;
|
||||
this.noClip = this.pushOutOfBlocks(this.posX, (this.getEntityBoundingBox().minY + this.getEntityBoundingBox().maxY) / 2.0D, this.posZ);
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
boolean flag = (int)this.prevX != (int)this.posX || (int)this.prevY != (int)this.posY || (int)this.prevZ != (int)this.posZ;
|
||||
|
||||
if (flag || this.ticksExisted % 25 == 0)
|
||||
{
|
||||
if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() == Material.lava)
|
||||
{
|
||||
this.motionY = 0.20000000298023224D;
|
||||
this.motionX = (double)((this.rand.floatv() - this.rand.floatv()) * 0.2F);
|
||||
this.motionZ = (double)((this.rand.floatv() - this.rand.floatv()) * 0.2F);
|
||||
this.playSound(SoundEvent.FIZZ, 0.4F, 2.0F + this.rand.floatv() * 0.4F);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.searchForOtherItemsNearby();
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.worldObj.client && this.ticksExisted % 5 == 0) {
|
||||
ItemStack stack = this.getEntityItem();
|
||||
float rad = stack.getItem().getRadiation(stack);
|
||||
if(rad > 0.0f)
|
||||
this.affectEntities(rad * 0.25f);
|
||||
}
|
||||
|
||||
float f = 0.98F;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
f = this.worldObj.getState(new BlockPos(ExtMath.floord(this.posX), ExtMath.floord(this.getEntityBoundingBox().minY) - 1, ExtMath.floord(this.posZ))).getBlock().slipperiness * 0.98F;
|
||||
}
|
||||
|
||||
this.motionX *= (double)f;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= (double)f;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
this.motionY *= -0.5D;
|
||||
}
|
||||
|
||||
if (this.age != -32768)
|
||||
{
|
||||
++this.age;
|
||||
}
|
||||
|
||||
this.handleWaterMovement();
|
||||
|
||||
if (!this.worldObj.client && this.age >= 6000)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for other itemstacks nearby and tries to stack them together
|
||||
*/
|
||||
private void searchForOtherItemsNearby()
|
||||
{
|
||||
for (EntityItem entityitem : this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.getEntityBoundingBox().expand(0.5D, 0.0D, 0.5D)))
|
||||
{
|
||||
this.combineItems(entityitem);
|
||||
}
|
||||
}
|
||||
|
||||
private void affectEntities(float rad)
|
||||
{
|
||||
float r = ExtMath.clampf(rad * 2.0f, 0.0f, 25.0f);
|
||||
for (EntityLiving entity : this.worldObj.getEntitiesWithinAABB(EntityLiving.class, this.getEntityBoundingBox().expand(r, r, r)))
|
||||
{
|
||||
float effect = rad * 2.0f * (r - (float)this.getDistanceToEntity(entity)) / r;
|
||||
if(effect > 0.0f)
|
||||
entity.addRadiation(effect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to merge this item with the item passed as the parameter. Returns true if successful. Either this item or
|
||||
* the other item will be removed from the world.
|
||||
*/
|
||||
private boolean combineItems(EntityItem other)
|
||||
{
|
||||
if (other == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (other.isEntityAlive() && this.isEntityAlive())
|
||||
{
|
||||
ItemStack itemstack = this.getEntityItem();
|
||||
ItemStack itemstack1 = other.getEntityItem();
|
||||
|
||||
if (this.delayBeforeCanPickup != 32767 && other.delayBeforeCanPickup != 32767)
|
||||
{
|
||||
if (this.age != -32768 && other.age != -32768)
|
||||
{
|
||||
if (itemstack1.getItem() != itemstack.getItem())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (itemstack1.hasTagCompound() ^ itemstack.hasTagCompound())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (itemstack1.hasTagCompound() && !itemstack1.getTagCompound().equals(itemstack.getTagCompound()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (itemstack1.getItem() == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (itemstack1.getItem().getHasSubtypes() && itemstack1.getMetadata() != itemstack.getMetadata())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (itemstack1.stackSize < itemstack.stackSize)
|
||||
{
|
||||
return other.combineItems(this);
|
||||
}
|
||||
else if (itemstack1.stackSize + itemstack.stackSize > itemstack1.getMaxStackSize())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemstack1.stackSize += itemstack.stackSize;
|
||||
other.delayBeforeCanPickup = Math.max(other.delayBeforeCanPickup, this.delayBeforeCanPickup);
|
||||
other.age = Math.min(other.age, this.age);
|
||||
other.setEntityItemStack(itemstack1);
|
||||
this.setDead();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * sets the age of the item so that it'll despawn one minute after it has been dropped (instead of five). Used when
|
||||
// * items are dropped from players in creative mode
|
||||
// */
|
||||
// public void setAgeToCreativeDespawnTime()
|
||||
// {
|
||||
// this.age = 4800;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns if this entity is in water and will end up adding the waters velocity to the entity
|
||||
*/
|
||||
public boolean handleWaterMovement()
|
||||
{
|
||||
if (this.worldObj.handleLiquidAcceleration(this.getEntityBoundingBox(), this))
|
||||
{
|
||||
if (!this.inLiquid && !this.firstUpdate)
|
||||
{
|
||||
this.onEnterLiquid();
|
||||
}
|
||||
|
||||
this.inLiquid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inLiquid = false;
|
||||
}
|
||||
|
||||
return this.inLiquid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will deal the specified amount of damage to the entity if the entity isn't immune to fire damage. Args:
|
||||
* amountDamage
|
||||
*/
|
||||
protected void dealFireDamage(int amount)
|
||||
{
|
||||
if(Config.itemBurn)
|
||||
this.attackEntityFrom(DamageSource.inFire, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// else if (this.getEntityItem() != null && this.getEntityItem().getItem() == Items.nether_star && source.isExplosion())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
else
|
||||
{
|
||||
this.setBeenAttacked();
|
||||
this.health = this.health - (int)amount;
|
||||
|
||||
if (this.health <= 0)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setShort("Health", (short)((byte)this.health));
|
||||
tagCompound.setShort("Age", (short)this.age);
|
||||
tagCompound.setShort("PickupDelay", (short)this.delayBeforeCanPickup);
|
||||
|
||||
// if (this.getThrower() != null)
|
||||
// {
|
||||
// tagCompound.setString("Thrower", this.thrower);
|
||||
// }
|
||||
//
|
||||
// if (this.getOwner() != null)
|
||||
// {
|
||||
// tagCompound.setString("Owner", this.owner);
|
||||
// }
|
||||
|
||||
if (this.getEntityItem() != null)
|
||||
{
|
||||
tagCompound.setTag("Item", this.getEntityItem().writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.health = tagCompund.getShort("Health") & 255;
|
||||
this.age = tagCompund.getShort("Age");
|
||||
|
||||
if (tagCompund.hasKey("PickupDelay"))
|
||||
{
|
||||
this.delayBeforeCanPickup = tagCompund.getShort("PickupDelay");
|
||||
}
|
||||
|
||||
// if (tagCompund.hasKey("Owner"))
|
||||
// {
|
||||
// this.owner = tagCompund.getString("Owner");
|
||||
// }
|
||||
//
|
||||
// if (tagCompund.hasKey("Thrower"))
|
||||
// {
|
||||
// this.thrower = tagCompund.getString("Thrower");
|
||||
// }
|
||||
|
||||
NBTTagCompound nbttagcompound = tagCompund.getCompoundTag("Item");
|
||||
this.setEntityItemStack(ItemStack.loadItemStackFromNBT(nbttagcompound));
|
||||
|
||||
if (this.getEntityItem() == null)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by a player entity when they collide with an entity
|
||||
*/
|
||||
public void onCollideWithPlayer(EntityNPC entityIn)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
ItemStack itemstack = this.getEntityItem();
|
||||
int i = itemstack.stackSize;
|
||||
|
||||
if (this.delayBeforeCanPickup == 0 // && (this.owner == null || 6000 - this.age <= 200 || this.owner.equals(entityIn.getUser()))
|
||||
&& entityIn.inventory.addItemStackToInventory(itemstack))
|
||||
{
|
||||
// if (itemstack.getItem() == ItemRegistry.getItemFromBlock(Blocks.log))
|
||||
// {
|
||||
// entityIn.triggerAchievement(AchievementList.mineWood);
|
||||
// }
|
||||
//
|
||||
// if (itemstack.getItem() == ItemRegistry.getItemFromBlock(Blocks.log2))
|
||||
// {
|
||||
// entityIn.triggerAchievement(AchievementList.mineWood);
|
||||
// }
|
||||
//
|
||||
// if (itemstack.getItem() == Items.leather)
|
||||
// {
|
||||
// entityIn.triggerAchievement(AchievementList.killCow);
|
||||
// }
|
||||
//
|
||||
// if (itemstack.getItem() == Items.diamond)
|
||||
// {
|
||||
// entityIn.triggerAchievement(AchievementList.diamonds);
|
||||
// }
|
||||
//
|
||||
// if (itemstack.getItem() == Items.blaze_rod)
|
||||
// {
|
||||
// entityIn.triggerAchievement(AchievementList.blazeRod);
|
||||
// }
|
||||
//
|
||||
// if (itemstack.getItem() == Items.diamond && this.getThrower() != null)
|
||||
// {
|
||||
// EntityNPC entityplayer = this.worldObj.getPlayer(this.getThrower());
|
||||
//
|
||||
// if (entityplayer != null && entityplayer != entityIn)
|
||||
// {
|
||||
// entityplayer.triggerAchievement(AchievementList.diamondsToYou);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!this.isSilent())
|
||||
// {
|
||||
this.worldObj.playSoundAtEntity(entityIn, SoundEvent.POP, 0.2F, ((this.rand.floatv() - this.rand.floatv()) * 0.7F + 1.0F) * 2.0F);
|
||||
// }
|
||||
|
||||
entityIn.onItemPickup(this, i);
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this object. For players this returns their username
|
||||
*/
|
||||
public String getTypeName()
|
||||
{
|
||||
if(this.hasCustomName())
|
||||
return this.getCustomNameTag();
|
||||
String comp = super.getTypeName();
|
||||
comp += " (" + this.getEntityItem().stackSize + " * " +
|
||||
ItemRegistry.REGISTRY.getNameForObject(this.getEntityItem().getItem()) + ":" + this.getEntityItem().getMetadata() + ")";
|
||||
return comp;
|
||||
}
|
||||
|
||||
/**
|
||||
* If returns false, the item will not inflict any damage against entities.
|
||||
*/
|
||||
public boolean canAttackWithItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports the entity to another dimension. Params: Dimension number to teleport to
|
||||
*/
|
||||
public Entity travelToDimension(int dimensionId, BlockPos pos, float yaw, float pitch, PortalType portal)
|
||||
{
|
||||
Entity entity = super.travelToDimension(dimensionId, pos, yaw, pitch, portal);
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.searchForOtherItemsNearby();
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ItemStack corresponding to the Entity (Note: if no item exists, will log an error but still return an
|
||||
* ItemStack containing Block.stone)
|
||||
*/
|
||||
public ItemStack getEntityItem()
|
||||
{
|
||||
ItemStack itemstack = this.getDataWatcher().getWatchableObjectItemStack(10);
|
||||
|
||||
if (itemstack == null)
|
||||
{
|
||||
if (this.worldObj != null)
|
||||
{
|
||||
Log.JNI.warn("Gegenstand-Objekt " + this.getId() + " hat kein Item?!");
|
||||
}
|
||||
|
||||
return new ItemStack(Blocks.stone);
|
||||
}
|
||||
else
|
||||
{
|
||||
return itemstack;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ItemStack for this entity
|
||||
*/
|
||||
public void setEntityItemStack(ItemStack stack)
|
||||
{
|
||||
this.getDataWatcher().updateObject(10, stack);
|
||||
this.getDataWatcher().setObjectWatched(10);
|
||||
}
|
||||
|
||||
// public String getOwner()
|
||||
// {
|
||||
// return this.owner;
|
||||
// }
|
||||
//
|
||||
// public void setOwner(String owner)
|
||||
// {
|
||||
// this.owner = owner;
|
||||
// }
|
||||
|
||||
// public String getThrower()
|
||||
// {
|
||||
// return this.thrower;
|
||||
// }
|
||||
//
|
||||
// public void setThrower(String thrower)
|
||||
// {
|
||||
// this.thrower = thrower;
|
||||
// }
|
||||
|
||||
public int getAge()
|
||||
{
|
||||
return this.age;
|
||||
}
|
||||
|
||||
public void setDefaultPickupDelay()
|
||||
{
|
||||
this.delayBeforeCanPickup = 10;
|
||||
}
|
||||
|
||||
// public void setNoPickupDelay()
|
||||
// {
|
||||
// this.delayBeforeCanPickup = 0;
|
||||
// }
|
||||
|
||||
// public void setInfinitePickupDelay()
|
||||
// {
|
||||
// this.delayBeforeCanPickup = 32767;
|
||||
// }
|
||||
|
||||
public void setPickupDelay(int ticks)
|
||||
{
|
||||
this.delayBeforeCanPickup = ticks;
|
||||
}
|
||||
|
||||
public boolean cannotPickup()
|
||||
{
|
||||
return this.delayBeforeCanPickup > 0;
|
||||
}
|
||||
|
||||
public void setNoDespawn()
|
||||
{
|
||||
this.age = -6000;
|
||||
}
|
||||
|
||||
// public void setNoPickup()
|
||||
// {
|
||||
// this.setInfinitePickupDelay();
|
||||
// this.age = 5999;
|
||||
// }
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public int getPacketData() {
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
public boolean hasSpawnVelocity() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return this.getEntityItem().getItem().isMagnetic();
|
||||
}
|
||||
|
||||
public String getDisplayName()
|
||||
{
|
||||
ItemStack stack = this.getEntityItem();
|
||||
if(stack.stackSize <= 1)
|
||||
return null;
|
||||
return TextColor.DGREEN + "" + stack.stackSize;
|
||||
}
|
||||
}
|
467
java/src/game/entity/item/EntityLeashKnot.java
Executable file
467
java/src/game/entity/item/EntityLeashKnot.java
Executable file
|
@ -0,0 +1,467 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.BlockFence;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Items;
|
||||
import game.item.Item;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityLeashKnot extends Entity
|
||||
{
|
||||
private int checkTimer;
|
||||
private BlockPos fencePos;
|
||||
|
||||
// /** The direction the entity is facing */
|
||||
// public Facing facingDirection;
|
||||
|
||||
public EntityLeashKnot(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.5F, 0.5F);
|
||||
}
|
||||
|
||||
public EntityLeashKnot(World worldIn, BlockPos fence)
|
||||
{
|
||||
super(worldIn);
|
||||
this.fencePos = fence;
|
||||
this.setPosition((double)fence.getX() + 0.5D, (double)fence.getY() + 0.5D, (double)fence.getZ() + 0.5D);
|
||||
float f = 0.125F;
|
||||
float f1 = 0.1875F;
|
||||
float f2 = 0.25F;
|
||||
this.setEntityBoundingBox(new BoundingBox(this.posX - 0.1875D, this.posY - 0.25D + 0.125D, this.posZ - 0.1875D, this.posX + 0.1875D, this.posY + 0.25D + 0.125D, this.posZ + 0.1875D));
|
||||
}
|
||||
|
||||
public EntityLeashKnot(World worldIn, double x, double y, double z)
|
||||
{
|
||||
this(worldIn, new BlockPos(ExtMath.floord(x), ExtMath.floord(y), ExtMath.floord(z)));
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Updates facing and bounding box based on it
|
||||
// */
|
||||
// protected void updateFacingWithBoundingBox(Facing facingDirectionIn)
|
||||
// {
|
||||
// if (facingDirectionIn == null) {
|
||||
// throw new NullPointerException("Facing is null");
|
||||
// }
|
||||
// if (!facingDirectionIn.getAxis().isHorizontal()) {
|
||||
// throw new IllegalArgumentException("Invalid facing");
|
||||
// }
|
||||
// this.facingDirection = facingDirectionIn;
|
||||
// this.prevYaw = this.rotYaw = (float)(this.facingDirection.getHorizontalIndex() * 90);
|
||||
// this.updateBoundingBox();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Updates the entity bounding box based on current facing
|
||||
// */
|
||||
// private void updateBoundingBox()
|
||||
// {
|
||||
// if (this.facingDirection != null)
|
||||
// {
|
||||
// double d0 = (double)this.hangingPosition.getX() + 0.5D;
|
||||
// double d1 = (double)this.hangingPosition.getY() + 0.5D;
|
||||
// double d2 = (double)this.hangingPosition.getZ() + 0.5D;
|
||||
// double d3 = 0.46875D;
|
||||
// double d4 = 0.0; // this.func_174858_a(this.getWidthPixels());
|
||||
// double d5 = 0.0; // this.func_174858_a(this.getHeightPixels());
|
||||
// d0 = d0 - (double)this.facingDirection.getFrontOffsetX() * 0.46875D;
|
||||
// d2 = d2 - (double)this.facingDirection.getFrontOffsetZ() * 0.46875D;
|
||||
// d1 = d1 + d5;
|
||||
// Facing enumfacing = this.facingDirection.rotateYCCW();
|
||||
// d0 = d0 + d4 * (double)enumfacing.getFrontOffsetX();
|
||||
// d2 = d2 + d4 * (double)enumfacing.getFrontOffsetZ();
|
||||
// this.posX = d0;
|
||||
// this.posY = d1;
|
||||
// this.posZ = d2;
|
||||
// double d6 = 9.0; // (double)this.getWidthPixels();
|
||||
// double d7 = 9.0; // (double)this.getHeightPixels();
|
||||
// double d8 = 9.0; // (double)this.getWidthPixels();
|
||||
//
|
||||
// if (this.facingDirection.getAxis() == Facing.Axis.Z)
|
||||
// {
|
||||
// d8 = 1.0D;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// d6 = 1.0D;
|
||||
// }
|
||||
//
|
||||
// d6 = d6 / 32.0D;
|
||||
// d7 = d7 / 32.0D;
|
||||
// d8 = d8 / 32.0D;
|
||||
// this.setEntityBoundingBox(new BoundingBox(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8));
|
||||
// }
|
||||
// }
|
||||
|
||||
// private double func_174858_a(int s)
|
||||
// {
|
||||
// return s % 32 == 0 ? 0.5D : 0.0D;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
|
||||
if (this.checkTimer++ == 100 && !this.worldObj.client)
|
||||
{
|
||||
this.checkTimer = 0;
|
||||
|
||||
if (!this.dead && !(this.worldObj.getState(this.fencePos).getBlock() instanceof BlockFence))
|
||||
{
|
||||
this.setDead();
|
||||
// this.onBroken((Entity)null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * checks to make sure painting can be placed there
|
||||
// */
|
||||
// public boolean onValidSurface()
|
||||
// {
|
||||
// if (!this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// int i = Math.max(1, this.getWidthPixels() / 16);
|
||||
// int j = Math.max(1, this.getHeightPixels() / 16);
|
||||
// BlockPos blockpos = this.hangingPosition.offset(this.facingDirection.getOpposite());
|
||||
// Facing enumfacing = this.facingDirection.rotateYCCW();
|
||||
//
|
||||
// for (int k = 0; k < i; ++k)
|
||||
// {
|
||||
// for (int l = 0; l < j; ++l)
|
||||
// {
|
||||
// BlockPos blockpos1 = blockpos.offset(enumfacing, k).up(l);
|
||||
// Block block = this.worldObj.getState(blockpos1).getBlock();
|
||||
//
|
||||
// if (!block.getMaterial().isSolid() && !BlockRedstoneDiode.isRedstoneRepeaterBlockID(block))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (Entity entity : this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox()))
|
||||
// {
|
||||
// if (entity instanceof EntityLeashKnot)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player attacks an entity. If this returns true the attack will not happen.
|
||||
*/
|
||||
public boolean hitByEntity(Entity entityIn)
|
||||
{
|
||||
return entityIn instanceof EntityNPC ? this.attackEntityFrom(DamageSource.causeMobDamage((EntityNPC)entityIn), 0) : false;
|
||||
}
|
||||
|
||||
// public Facing getHorizontalFacing()
|
||||
// {
|
||||
// return this.facingDirection;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.dead && !this.worldObj.client)
|
||||
{
|
||||
this.setDead();
|
||||
this.setBeenAttacked();
|
||||
// this.onBroken(source.getEntity());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to moves the entity by the passed in displacement. Args: x, y, z
|
||||
*/
|
||||
public void moveEntity(double x, double y, double z)
|
||||
{
|
||||
if (!this.worldObj.client && !this.dead && x * x + y * y + z * z > 0.0D)
|
||||
{
|
||||
this.setDead();
|
||||
// this.onBroken((Entity)null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the current velocity of the entity. Args: x, y, z
|
||||
*/
|
||||
public void addVelocity(double x, double y, double z)
|
||||
{
|
||||
if (!this.worldObj.client && !this.dead && x * x + y * y + z * z > 0.0D)
|
||||
{
|
||||
this.setDead();
|
||||
// this.onBroken((Entity)null);
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
// */
|
||||
// public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
// {
|
||||
// tagCompound.setByte("Facing", (byte)this.facingDirection.getHorizontalIndex());
|
||||
// tagCompound.setInteger("TileX", this.getHangingPosition().getX());
|
||||
// tagCompound.setInteger("TileY", this.getHangingPosition().getY());
|
||||
// tagCompound.setInteger("TileZ", this.getHangingPosition().getZ());
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
// */
|
||||
// public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
// {
|
||||
// this.hangingPosition = new BlockPos(tagCompund.getInteger("TileX"), tagCompund.getInteger("TileY"), tagCompund.getInteger("TileZ"));
|
||||
// Facing enumfacing;
|
||||
//
|
||||
// if (tagCompund.hasKey("Direction", 99))
|
||||
// {
|
||||
// enumfacing = Facing.getHorizontal(tagCompund.getByte("Direction"));
|
||||
// this.hangingPosition = this.hangingPosition.offset(enumfacing);
|
||||
// }
|
||||
// else if (tagCompund.hasKey("Facing", 99))
|
||||
// {
|
||||
// enumfacing = Facing.getHorizontal(tagCompund.getByte("Facing"));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// enumfacing = Facing.getHorizontal(tagCompund.getByte("Dir"));
|
||||
// }
|
||||
//
|
||||
// this.updateFacingWithBoundingBox(enumfacing);
|
||||
// }
|
||||
|
||||
// public abstract int getWidthPixels();
|
||||
//
|
||||
// public abstract int getHeightPixels();
|
||||
|
||||
// /**
|
||||
// * Called when this entity is broken. Entity parameter may be null.
|
||||
// */
|
||||
// public abstract void onBroken(Entity brokenEntity);
|
||||
|
||||
protected boolean shouldSetPosAfterLoading()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the x,y,z of the entity from the given parameters. Also seems to set up a bounding box.
|
||||
*/
|
||||
public void setPosition(double x, double y, double z)
|
||||
{
|
||||
this.posX = x;
|
||||
this.posY = y;
|
||||
this.posZ = z;
|
||||
BlockPos blockpos = this.fencePos;
|
||||
this.fencePos = new BlockPos(x, y, z);
|
||||
|
||||
if (!this.fencePos.equals(blockpos))
|
||||
{
|
||||
// this.updateBoundingBox();
|
||||
this.isAirBorne = true;
|
||||
}
|
||||
}
|
||||
|
||||
public BlockPos getHangingPosition()
|
||||
{
|
||||
return this.fencePos;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 160;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// protected void entityInit()
|
||||
// {
|
||||
// super.entityInit();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Updates facing and bounding box based on it
|
||||
// */
|
||||
// public void updateFacingWithBoundingBox(Facing facingDirectionIn)
|
||||
// {
|
||||
// }
|
||||
|
||||
// public int getWidthPixels()
|
||||
// {
|
||||
// return 9;
|
||||
// }
|
||||
//
|
||||
// public int getHeightPixels()
|
||||
// {
|
||||
// return 9;
|
||||
// }
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return -0.0625F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
|
||||
* length * 64 * renderDistanceWeight Args: distance
|
||||
*/
|
||||
public boolean isInRangeToRenderDist(double distance)
|
||||
{
|
||||
return distance < 1024.0D;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Called when this entity is broken. Entity parameter may be null.
|
||||
// */
|
||||
// public void onBroken(Entity brokenEntity)
|
||||
// {
|
||||
// }
|
||||
|
||||
/**
|
||||
* Either write this entity to the NBT tag given and return true, or return false without doing anything. If this
|
||||
* returns false the entity is not saved on disk. Ridden entities return false here as they are saved with their
|
||||
* rider.
|
||||
*/
|
||||
public boolean writeToNBTOptional(NBTTagCompound tagCompund)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* First layer of player interaction
|
||||
*/
|
||||
public boolean interactFirst(EntityNPC playerIn)
|
||||
{
|
||||
ItemStack itemstack = playerIn.getHeldItem();
|
||||
boolean flag = false;
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == Items.lead && !this.worldObj.client)
|
||||
{
|
||||
double d0 = 7.0D;
|
||||
|
||||
for (EntityLiving entityliving : this.worldObj.getEntitiesWithinAABB(EntityLiving.class, new BoundingBox(this.posX - d0, this.posY - d0, this.posZ - d0, this.posX + d0, this.posY + d0, this.posZ + d0)))
|
||||
{
|
||||
if (entityliving.getLeashed() && entityliving.getLeashedTo() == playerIn)
|
||||
{
|
||||
entityliving.setLeashedTo(this, true);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.worldObj.client && !flag)
|
||||
{
|
||||
this.setDead();
|
||||
|
||||
// if (playerIn.creative)
|
||||
// {
|
||||
// double d1 = 7.0D;
|
||||
//
|
||||
// for (EntityLiving entityliving1 : this.worldObj.getEntitiesWithinAABB(EntityLiving.class, new BoundingBox(this.posX - d1, this.posY - d1, this.posZ - d1, this.posX + d1, this.posY + d1, this.posZ + d1)))
|
||||
// {
|
||||
// if (entityliving1.getLeashed() && entityliving1.getLeashedTo() == this)
|
||||
// {
|
||||
// entityliving1.clearLeashed(true, false);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return Items.lead;
|
||||
}
|
||||
|
||||
public static EntityLeashKnot createKnot(World worldIn, BlockPos fence)
|
||||
{
|
||||
EntityLeashKnot entityleashknot = new EntityLeashKnot(worldIn, fence);
|
||||
entityleashknot.forceSpawn = true;
|
||||
worldIn.spawnEntityInWorld(entityleashknot);
|
||||
return entityleashknot;
|
||||
}
|
||||
|
||||
public static EntityLeashKnot getKnotForPosition(World worldIn, BlockPos pos)
|
||||
{
|
||||
int i = pos.getX();
|
||||
int j = pos.getY();
|
||||
int k = pos.getZ();
|
||||
|
||||
for (EntityLeashKnot entityleashknot : worldIn.getEntitiesWithinAABB(EntityLeashKnot.class, new BoundingBox((double)i - 1.0D, (double)j - 1.0D, (double)k - 1.0D, (double)i + 1.0D, (double)j + 1.0D, (double)k + 1.0D)))
|
||||
{
|
||||
if (entityleashknot.getHangingPosition().equals(pos))
|
||||
{
|
||||
return entityleashknot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
70
java/src/game/entity/item/EntityMinecart.java
Executable file
70
java/src/game/entity/item/EntityMinecart.java
Executable file
|
@ -0,0 +1,70 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityMinecart extends EntityCart
|
||||
{
|
||||
public EntityMinecart(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityMinecart(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* First layer of player interaction
|
||||
*/
|
||||
public boolean interactFirst(EntityNPC playerIn)
|
||||
{
|
||||
// if (this.passenger != null && this.passenger.isPlayer() && this.passenger != playerIn)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// else
|
||||
if (this.passenger != null && this.passenger != playerIn)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
playerIn.mountEntity(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick the minecart is on an activator rail. Args: x, y, z, is the rail receiving power
|
||||
*/
|
||||
public void onActivatorRailPass(int x, int y, int z, boolean receivingPower)
|
||||
{
|
||||
if (receivingPower)
|
||||
{
|
||||
if (this.passenger != null)
|
||||
{
|
||||
this.passenger.mountEntity((Entity)null);
|
||||
}
|
||||
|
||||
if (this.getRollingAmplitude() == 0)
|
||||
{
|
||||
this.setRollingDirection(-this.getRollingDirection());
|
||||
this.setRollingAmplitude(10);
|
||||
this.setDamage(50);
|
||||
this.setBeenAttacked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public EntityCart.EnumMinecartType getMinecartType()
|
||||
{
|
||||
return EntityCart.EnumMinecartType.RIDEABLE;
|
||||
}
|
||||
}
|
121
java/src/game/entity/item/EntityNuke.java
Executable file
121
java/src/game/entity/item/EntityNuke.java
Executable file
|
@ -0,0 +1,121 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.Entity;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityNuke extends Entity
|
||||
{
|
||||
public int fuse;
|
||||
|
||||
public EntityNuke(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.preventSpawning = true;
|
||||
this.setSize(0.98F, 0.98F);
|
||||
}
|
||||
|
||||
public EntityNuke(World worldIn, double x, double y, double z)
|
||||
{
|
||||
this(worldIn);
|
||||
this.setPosition(x, y, z);
|
||||
float f = (float)(Math.random() * Math.PI * 2.0D);
|
||||
this.motionX = (double)(-((float)Math.sin((double)f)) * 0.005F);
|
||||
this.motionY = 0.1D;
|
||||
this.motionZ = (double)(-((float)Math.cos((double)f)) * 0.005F);
|
||||
this.fuse = 300;
|
||||
this.prevX = x;
|
||||
this.prevY = y;
|
||||
this.prevZ = z;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return !this.dead;
|
||||
}
|
||||
|
||||
public void onUpdate()
|
||||
{
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.motionY -= 0.03999999910593033D;
|
||||
if(this.fuse <= 0) {
|
||||
this.motionX = this.motionY = this.motionZ = 0.0D;
|
||||
}
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.9800000190734863D;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= 0.9800000190734863D;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
this.motionX *= 0.699999988079071D;
|
||||
this.motionZ *= 0.699999988079071D;
|
||||
this.motionY *= -0.5D;
|
||||
}
|
||||
|
||||
if(this.fuse-- <= 0)
|
||||
{
|
||||
// if(this.fuse < -70) {
|
||||
this.setDead();
|
||||
if(!this.worldObj.client)
|
||||
this.worldObj.newExplosion(this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 70);
|
||||
// }
|
||||
// else if(!this.worldObj.client) {
|
||||
// this.setInvisible(true);
|
||||
// this.explode(this.fuse + 1);
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
this.handleWaterMovement();
|
||||
// if(!this.isInvisible()) {
|
||||
this.worldObj.spawnParticle(ParticleType.FLAME, this.posX, this.posY + 1.1D, this.posZ, 0.0D, 0.0D, 0.0D);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// private void explode(int fuse)
|
||||
// {
|
||||
// double min = ((double)((int)((fuse+1) / 1))) * -1.0d;
|
||||
// Explosion.doExplosionAlgo3(this.worldObj, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, this.rand, min + 6.0d, min);
|
||||
// }
|
||||
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setInteger("Fuse", this.fuse);
|
||||
}
|
||||
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.fuse = tagCompund.getInteger("Fuse");
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
}
|
139
java/src/game/entity/item/EntityOrb.java
Executable file
139
java/src/game/entity/item/EntityOrb.java
Executable file
|
@ -0,0 +1,139 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityThrowable;
|
||||
import game.init.Config;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityOrb extends EntityThrowable
|
||||
{
|
||||
private EntityLiving thrower;
|
||||
|
||||
public EntityOrb(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityOrb(World worldIn, EntityLiving thrower)
|
||||
{
|
||||
super(worldIn, thrower);
|
||||
this.thrower = thrower;
|
||||
}
|
||||
|
||||
public EntityOrb(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
protected float getVelocity()
|
||||
{
|
||||
return 3.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityThrowable hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition pos)
|
||||
{
|
||||
EntityLiving entitylivingbase = this.getThrower();
|
||||
double x = this.posX;
|
||||
double y = this.posY;
|
||||
double z = this.posZ;
|
||||
|
||||
if (pos.entity != null)
|
||||
{
|
||||
// if (pos.entity == this.thrower && !(this.thrower.isPlayer()))
|
||||
// {
|
||||
// this.setDead();
|
||||
// return;
|
||||
// }
|
||||
|
||||
if(Config.telefrag) {
|
||||
x = pos.entity.posX;
|
||||
y = pos.entity.posY;
|
||||
z = pos.entity.posZ;
|
||||
}
|
||||
// else if(Config.smackingOrb) {
|
||||
// pos.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, entitylivingbase), Config.orbThorns);
|
||||
// }
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.PORTAL, this.posX, this.posY + this.rand.doublev() * 2.0D, this.posZ, this.rand.gaussian(), 0.0D, this.rand.gaussian());
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
// if(entitylivingbase != null)
|
||||
if (entitylivingbase != null) // && entitylivingbase.isPlayer())
|
||||
{
|
||||
this.worldObj.playAuxSFX(1013, entitylivingbase.getPosition(), 0);
|
||||
// EntityNPCMP entityplayermp = (EntityNPCMP)entitylivingbase;
|
||||
|
||||
if (/* entityplayermp.netHandler.connection.isChannelOpen() && */ entitylivingbase.worldObj == this.worldObj) // && !entityplayermp.isPlayerSleeping())
|
||||
{
|
||||
// if (this.rand.floatv() < 0.05F && Config.mobSpawning && Config.spawnEndermites)
|
||||
// {
|
||||
// EntityEndermite entityendermite = new EntityEndermite(this.worldObj);
|
||||
// entityendermite.setSpawnedByPlayer(true);
|
||||
// entityendermite.setLocationAndAngles(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, entitylivingbase.rotYaw, entitylivingbase.rotPitch);
|
||||
// this.worldObj.spawnEntityInWorld(entityendermite);
|
||||
// }
|
||||
|
||||
if (entitylivingbase.isRiding())
|
||||
{
|
||||
entitylivingbase.mountEntity((Entity)null);
|
||||
}
|
||||
|
||||
entitylivingbase.setPositionAndUpdate(x, y, z);
|
||||
entitylivingbase.fallDistance = 0.0F;
|
||||
if(Config.orbDamageSelf > 0)
|
||||
entitylivingbase.attackEntityFrom(DamageSource.fall, Config.orbDamageSelf);
|
||||
}
|
||||
}
|
||||
// else if (entitylivingbase != null)
|
||||
// {
|
||||
// entitylivingbase.setPositionAndUpdate(x, y, z);
|
||||
// entitylivingbase.fallDistance = 0.0F;
|
||||
// }
|
||||
|
||||
this.setDead();
|
||||
if(entitylivingbase != null)
|
||||
this.worldObj.playAuxSFX(1005, entitylivingbase.getPosition(), 0);
|
||||
}
|
||||
|
||||
if (pos.entity != null)
|
||||
{
|
||||
if(Config.telefrag) {
|
||||
pos.entity.attackEntityFrom(DamageSource.causeTeleFragDamage(this, entitylivingbase), 10000);
|
||||
if(!this.worldObj.client)
|
||||
this.worldObj.playAuxSFX(1017, pos.entity.getPosition(), 0);
|
||||
}
|
||||
else if(Config.knockOrb) {
|
||||
pos.entity.attackEntityFrom(DamageSource.causeThrownDamage(this, entitylivingbase), Config.orbDamageOther);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.getThrower();
|
||||
|
||||
if (entitylivingbase != null && /* entitylivingbase.isPlayer() && */ !entitylivingbase.isEntityAlive())
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onUpdate();
|
||||
}
|
||||
}
|
||||
}
|
158
java/src/game/entity/item/EntityTnt.java
Executable file
158
java/src/game/entity/item/EntityTnt.java
Executable file
|
@ -0,0 +1,158 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityTnt extends Entity implements IObjectData
|
||||
{
|
||||
public int fuse;
|
||||
public int explosionSize;
|
||||
private EntityLiving tntPlacedBy;
|
||||
|
||||
public EntityTnt(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.preventSpawning = true;
|
||||
this.setSize(0.98F, 0.98F);
|
||||
}
|
||||
|
||||
public EntityTnt(World worldIn, double x, double y, double z, EntityLiving igniter, int power)
|
||||
{
|
||||
this(worldIn);
|
||||
this.setPosition(x, y, z);
|
||||
float f = (float)(Math.random() * Math.PI * 2.0D);
|
||||
this.motionX = (double)(-((float)Math.sin((double)f)) * 0.02F);
|
||||
this.motionY = 0.20000000298023224D;
|
||||
this.motionZ = (double)(-((float)Math.cos((double)f)) * 0.02F);
|
||||
this.fuse = 80;
|
||||
this.explosionSize = power & 7;
|
||||
this.prevX = x;
|
||||
this.prevY = y;
|
||||
this.prevZ = z;
|
||||
this.tntPlacedBy = igniter;
|
||||
}
|
||||
|
||||
public EntityTnt(World worldIn, double x, double y, double z, int data)
|
||||
{
|
||||
this(worldIn, x, y, z, null, data);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return !this.dead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.motionY -= 0.03999999910593033D;
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.9800000190734863D;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= 0.9800000190734863D;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
this.motionX *= 0.699999988079071D;
|
||||
this.motionZ *= 0.699999988079071D;
|
||||
this.motionY *= -0.5D;
|
||||
}
|
||||
|
||||
if (this.fuse-- <= 0)
|
||||
{
|
||||
this.setDead();
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.explode();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.handleWaterMovement();
|
||||
this.worldObj.spawnParticle(ParticleType.SMOKE_NORMAL, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
|
||||
private void explode()
|
||||
{
|
||||
float f = 4.0F * (((float)this.explosionSize)+1.0f);
|
||||
this.worldObj.createExplosion(this, this.posX, this.posY + (double)(this.height / 16.0F), this.posZ, f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setByte("Fuse", (byte)this.fuse);
|
||||
tagCompound.setByte("Power", (byte)this.explosionSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.fuse = tagCompund.getByte("Fuse");
|
||||
this.explosionSize = ((int)tagCompund.getByte("Power")) & 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns null or the entityliving it was placed or ignited by
|
||||
*/
|
||||
public EntityLiving getTntPlacedBy()
|
||||
{
|
||||
return this.tntPlacedBy;
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 160;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.explosionSize;
|
||||
}
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
}
|
227
java/src/game/entity/item/EntityTntCart.java
Executable file
227
java/src/game/entity/item/EntityTntCart.java
Executable file
|
@ -0,0 +1,227 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.block.BlockRailBase;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.projectile.EntityArrow;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.Explosion;
|
||||
import game.world.State;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityTntCart extends EntityCart
|
||||
{
|
||||
private int minecartTNTFuse = -1;
|
||||
|
||||
public EntityTntCart(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityTntCart(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public EntityCart.EnumMinecartType getMinecartType()
|
||||
{
|
||||
return EntityCart.EnumMinecartType.TNT;
|
||||
}
|
||||
|
||||
public State getDefaultDisplayTile()
|
||||
{
|
||||
return Blocks.tnt.getState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.minecartTNTFuse > 0)
|
||||
{
|
||||
--this.minecartTNTFuse;
|
||||
this.worldObj.spawnParticle(ParticleType.SMOKE_NORMAL, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
else if (this.minecartTNTFuse == 0)
|
||||
{
|
||||
this.explodeCart(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
}
|
||||
|
||||
if (this.collidedHorizontally)
|
||||
{
|
||||
double d0 = this.motionX * this.motionX + this.motionZ * this.motionZ;
|
||||
|
||||
if (d0 >= 0.009999999776482582D)
|
||||
{
|
||||
this.explodeCart(d0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
Entity entity = source.getSourceOfDamage();
|
||||
|
||||
if (entity instanceof EntityArrow)
|
||||
{
|
||||
EntityArrow entityarrow = (EntityArrow)entity;
|
||||
|
||||
if (entityarrow.isBurning())
|
||||
{
|
||||
this.explodeCart(entityarrow.motionX * entityarrow.motionX + entityarrow.motionY * entityarrow.motionY + entityarrow.motionZ * entityarrow.motionZ);
|
||||
}
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
|
||||
public void killMinecart(DamageSource source)
|
||||
{
|
||||
super.killMinecart(source);
|
||||
double d0 = this.motionX * this.motionX + this.motionZ * this.motionZ;
|
||||
|
||||
if (!source.isExplosion() && Config.objectDrop)
|
||||
{
|
||||
this.entityDropItem(new ItemStack(Blocks.tnt, 1), 0.0F);
|
||||
}
|
||||
|
||||
if (source.isFireDamage() || source.isExplosion() || d0 >= 0.009999999776482582D)
|
||||
{
|
||||
this.explodeCart(d0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the minecart explode.
|
||||
*/
|
||||
protected void explodeCart(double p_94103_1_)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
double d0 = Math.sqrt(p_94103_1_);
|
||||
|
||||
if (d0 > 5.0D)
|
||||
{
|
||||
d0 = 5.0D;
|
||||
}
|
||||
|
||||
this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(4.0D + this.rand.doublev() * 1.5D * d0), true);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
if (distance >= 3.0F)
|
||||
{
|
||||
float f = distance / 10.0F;
|
||||
this.explodeCart((double)(f * f));
|
||||
}
|
||||
|
||||
super.fall(distance, damageMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick the minecart is on an activator rail. Args: x, y, z, is the rail receiving power
|
||||
*/
|
||||
public void onActivatorRailPass(int x, int y, int z, boolean receivingPower)
|
||||
{
|
||||
if (receivingPower && this.minecartTNTFuse < 0)
|
||||
{
|
||||
this.ignite();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
if (id == 10)
|
||||
{
|
||||
this.ignite();
|
||||
}
|
||||
else
|
||||
{
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignites this TNT cart.
|
||||
*/
|
||||
public void ignite()
|
||||
{
|
||||
this.minecartTNTFuse = 80;
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.worldObj.setEntityState(this, (byte)10);
|
||||
|
||||
// if (!this.isSilent())
|
||||
// {
|
||||
this.worldObj.playSoundAtEntity(this, SoundEvent.FUSE, 1.0F, 1.0F);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remaining fuse time in ticks.
|
||||
*/
|
||||
public int getFuseTicks()
|
||||
{
|
||||
return this.minecartTNTFuse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the TNT minecart is ignited.
|
||||
*/
|
||||
public boolean isIgnited()
|
||||
{
|
||||
return this.minecartTNTFuse > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explosion resistance of a block relative to this entity
|
||||
*/
|
||||
public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, State blockStateIn)
|
||||
{
|
||||
return !this.isIgnited() || !BlockRailBase.isRailBlock(blockStateIn) && !BlockRailBase.isRailBlock(worldIn, pos.up()) ? super.getExplosionResistance(explosionIn, worldIn, pos, blockStateIn) : 0.0F;
|
||||
}
|
||||
|
||||
public boolean verifyExplosion(Explosion explosionIn, World worldIn, BlockPos pos, State blockStateIn, float p_174816_5_)
|
||||
{
|
||||
return !this.isIgnited() || !BlockRailBase.isRailBlock(blockStateIn) && !BlockRailBase.isRailBlock(worldIn, pos.up()) ? super.verifyExplosion(explosionIn, worldIn, pos, blockStateIn, p_174816_5_) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
protected void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
|
||||
if (tagCompund.hasKey("TNTFuse", 99))
|
||||
{
|
||||
this.minecartTNTFuse = tagCompund.getInteger("TNTFuse");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
protected void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("TNTFuse", this.minecartTNTFuse);
|
||||
}
|
||||
}
|
407
java/src/game/entity/item/EntityXp.java
Executable file
407
java/src/game/entity/item/EntityXp.java
Executable file
|
@ -0,0 +1,407 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.color.TextColor;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.init.Config;
|
||||
import game.init.SoundEvent;
|
||||
import game.material.Material;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.PortalType;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityXp extends Entity implements IObjectData
|
||||
{
|
||||
/**
|
||||
* A constantly increasing value that RenderXPOrb uses to control the colour shifting (Green / yellow)
|
||||
*/
|
||||
public int xpColor;
|
||||
|
||||
/** The age of the XP orb in ticks. */
|
||||
public int xpOrbAge;
|
||||
public int delayBeforeCanPickup;
|
||||
|
||||
/** The health of this XP orb. */
|
||||
private int xpOrbHealth = 5;
|
||||
|
||||
/** This is how much XP this orb has. */
|
||||
private int xpValue;
|
||||
//
|
||||
// /** The closest pulling Entity to this orb. */
|
||||
// private Entity closestPlayer;
|
||||
//
|
||||
// /** Threshold color for tracking players */
|
||||
// private int xpTargetColor;
|
||||
|
||||
public EntityXp(World worldIn, double x, double y, double z, int expValue)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setPosition(x, y, z);
|
||||
this.rotYaw = (float)(Math.random() * 360.0D);
|
||||
this.motionX = (double)((float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F);
|
||||
this.motionY = (double)((float)(Math.random() * 0.2D) * 2.0F);
|
||||
this.motionZ = (double)((float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F);
|
||||
this.xpValue = expValue;
|
||||
if(!worldIn.client)
|
||||
this.setCustomNameTag("" + this.xpValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public EntityXp(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.25F, 0.25F);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
public int getBrightnessForRender(float partialTicks)
|
||||
{
|
||||
float f = 0.5F;
|
||||
f = ExtMath.clampf(f, 0.0F, 1.0F);
|
||||
int i = super.getBrightnessForRender(partialTicks);
|
||||
int j = i & 255;
|
||||
int k = i >> 16 & 255;
|
||||
j = j + (int)(f * 15.0F * 16.0F);
|
||||
|
||||
if (j > 240)
|
||||
{
|
||||
j = 240;
|
||||
}
|
||||
|
||||
return j | k << 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.delayBeforeCanPickup > 0)
|
||||
{
|
||||
--this.delayBeforeCanPickup;
|
||||
}
|
||||
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.motionY -= 0.029999999329447746D;
|
||||
|
||||
if (this.worldObj.getState(new BlockPos(this)).getBlock().getMaterial() == Material.lava)
|
||||
{
|
||||
this.motionY = 0.20000000298023224D;
|
||||
this.motionX = (double)((this.rand.floatv() - this.rand.floatv()) * 0.2F);
|
||||
this.motionZ = (double)((this.rand.floatv() - this.rand.floatv()) * 0.2F);
|
||||
this.playSound(SoundEvent.FIZZ, 0.4F, 2.0F + this.rand.floatv() * 0.4F);
|
||||
}
|
||||
|
||||
this.pushOutOfBlocks(this.posX, (this.getEntityBoundingBox().minY + this.getEntityBoundingBox().maxY) / 2.0D, this.posZ);
|
||||
double d0 = 8.0D;
|
||||
|
||||
// if (!this.worldObj.client && this.xpTargetColor < this.xpColor - 20 + this.getId() % 100)
|
||||
// {
|
||||
// if (this.closestPlayer == null || this.closestPlayer.getDistanceSqToEntity(this) > d0 * d0)
|
||||
// {
|
||||
// List<EntityXp> list = this.worldObj.getEntitiesWithinAABB(EntityXp.class,
|
||||
// this.getEntityBoundingBox().expand(1.5D, 1.0D, 1.5D), new Predicate<EntityXp>() {
|
||||
// public boolean apply(EntityXp entity) {
|
||||
// return entity != EntityXp.this && entity.isEntityAlive() && EntityXp.this.xpValue + entity.xpValue <= 2477;
|
||||
// }
|
||||
// });
|
||||
// this.closestPlayer = list.isEmpty() ? this.worldObj.getClosestPlayerToEntity(this, d0) : list.get(0);
|
||||
// }
|
||||
//
|
||||
// this.xpTargetColor = this.xpColor;
|
||||
// }
|
||||
|
||||
// if (this.closestPlayer != null && this.closestPlayer.isSpectator())
|
||||
// {
|
||||
// this.closestPlayer = null;
|
||||
// }
|
||||
|
||||
// if (this.ticksExisted % 25 == 0)
|
||||
// {
|
||||
// if (!this.worldObj.client)
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
// if (this.closestPlayer != null)
|
||||
// {
|
||||
// double d1 = (this.closestPlayer.posX - this.posX) / d0;
|
||||
// double d2 = (this.closestPlayer.posY + (double)this.closestPlayer.getEyeHeight() - this.posY) / d0;
|
||||
// double d3 = (this.closestPlayer.posZ - this.posZ) / d0;
|
||||
// double d4 = Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3);
|
||||
// double d5 = 1.0D - d4;
|
||||
//
|
||||
// if (d5 > 0.0D)
|
||||
// {
|
||||
// d5 = d5 * d5;
|
||||
// this.motionX += d1 / d4 * d5 * 0.1D;
|
||||
// this.motionY += d2 / d4 * d5 * 0.1D;
|
||||
// this.motionZ += d3 / d4 * d5 * 0.1D;
|
||||
// }
|
||||
// }
|
||||
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
boolean flag = (int)this.prevX != (int)this.posX || (int)this.prevY != (int)this.posY || (int)this.prevZ != (int)this.posZ;
|
||||
|
||||
if (flag || this.ticksExisted % 25 == 0)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.searchForOtherXpNearby();
|
||||
}
|
||||
}
|
||||
float f = 0.98F;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
f = this.worldObj.getState(new BlockPos(ExtMath.floord(this.posX), ExtMath.floord(this.getEntityBoundingBox().minY) - 1, ExtMath.floord(this.posZ))).getBlock().slipperiness * 0.98F;
|
||||
}
|
||||
|
||||
this.motionX *= (double)f;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= (double)f;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
this.motionY *= -0.8999999761581421D;
|
||||
}
|
||||
|
||||
++this.xpColor;
|
||||
++this.xpOrbAge;
|
||||
|
||||
if (!this.worldObj.client && this.xpOrbAge >= 6000)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public Entity travelToDimension(int dimensionId, BlockPos pos, float yaw, float pitch, PortalType portal)
|
||||
{
|
||||
Entity entity = super.travelToDimension(dimensionId, pos, yaw, pitch, portal);
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.searchForOtherXpNearby();
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void searchForOtherXpNearby()
|
||||
{
|
||||
for (EntityXp entityitem : this.worldObj.getEntitiesWithinAABB(EntityXp.class, this.getEntityBoundingBox().expand(3.0D, 3.0D, 3.0D)))
|
||||
{
|
||||
this.combineXp(entityitem);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean combineXp(EntityXp other)
|
||||
{
|
||||
if (other == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (other.isEntityAlive() && this.isEntityAlive())
|
||||
{
|
||||
if (other.xpValue < this.xpValue)
|
||||
{
|
||||
return other.combineXp(this);
|
||||
}
|
||||
else if (this.xpValue + other.xpValue > 2477)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
other.xpValue += this.xpValue;
|
||||
other.delayBeforeCanPickup = Math.max(other.delayBeforeCanPickup, this.delayBeforeCanPickup);
|
||||
other.xpOrbAge = Math.min(other.xpOrbAge, this.xpOrbAge);
|
||||
other.worldObj.setEntityState(other, (byte)other.getTextureByXP());
|
||||
other.setCustomNameTag("" + other.xpValue);
|
||||
this.setDead();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if this entity is in water and will end up adding the waters velocity to the entity
|
||||
*/
|
||||
public boolean handleWaterMovement()
|
||||
{
|
||||
return this.worldObj.handleLiquidAcceleration(this.getEntityBoundingBox(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will deal the specified amount of damage to the entity if the entity isn't immune to fire damage. Args:
|
||||
* amountDamage
|
||||
*/
|
||||
protected void dealFireDamage(int amount)
|
||||
{
|
||||
if(Config.xpOrbBurn)
|
||||
this.attackEntityFrom(DamageSource.inFire, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBeenAttacked();
|
||||
this.xpOrbHealth = this.xpOrbHealth - (int)amount;
|
||||
|
||||
if (this.xpOrbHealth <= 0)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setShort("Health", (short)((byte)this.xpOrbHealth));
|
||||
tagCompound.setShort("Age", (short)this.xpOrbAge);
|
||||
tagCompound.setShort("Value", (short)this.xpValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.xpOrbHealth = tagCompund.getShort("Health") & 255;
|
||||
this.xpOrbAge = tagCompund.getShort("Age");
|
||||
this.xpValue = tagCompund.getShort("Value");
|
||||
this.setCustomNameTag("" + this.xpValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by a player entity when they collide with an entity
|
||||
*/
|
||||
public void onCollideWithPlayer(EntityNPC entityIn)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
if (this.delayBeforeCanPickup == 0 && entityIn.xpCooldown == 0)
|
||||
{
|
||||
entityIn.xpCooldown = Config.xpDelay;
|
||||
this.worldObj.playSoundAtEntity(entityIn, SoundEvent.ORB, 0.1F, 0.5F * ((this.rand.floatv() - this.rand.floatv()) * 0.7F + 1.8F));
|
||||
entityIn.onItemPickup(this, this.xpValue);
|
||||
entityIn.addExperience(this.xpValue);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XP value of this XP orb.
|
||||
*/
|
||||
public int getXpValue()
|
||||
{
|
||||
return this.xpValue;
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
this.xpValue = id;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
double d0 = this.rand.gaussian() * 0.02D;
|
||||
double d1 = this.rand.gaussian() * 0.02D;
|
||||
double d2 = this.rand.gaussian() * 0.02D;
|
||||
this.worldObj.spawnParticle(ParticleType.GROW,
|
||||
this.posX + (double)(this.rand.floatv() * this.width) - (double)this.width * 0.5,
|
||||
this.posY + (double)(this.rand.floatv() * this.height),
|
||||
this.posZ + (double)(this.rand.floatv() * this.width) - (double)this.width * 0.5,
|
||||
d0, d1, d2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a number from 1 to 10 based on how much XP this orb is worth. This is used by RenderXPOrb to determine
|
||||
* what texture to use.
|
||||
*/
|
||||
public int getTextureByXP()
|
||||
{
|
||||
return this.xpValue >= 2477 ? 10 : (this.xpValue >= 1237 ? 9 : (this.xpValue >= 617 ? 8 : (this.xpValue >= 307 ? 7 : (this.xpValue >= 149 ? 6 : (this.xpValue >= 73 ? 5 : (this.xpValue >= 37 ? 4 : (this.xpValue >= 17 ? 3 : (this.xpValue >= 7 ? 2 : (this.xpValue >= 3 ? 1 : 0)))))))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a fragment of the maximum experience points value for the supplied value of experience points value.
|
||||
*/
|
||||
public static int getXPSplit(int expValue)
|
||||
{
|
||||
return expValue >= 2477 ? 2477 : expValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* If returns false, the item will not inflict any damage against entities.
|
||||
*/
|
||||
public boolean canAttackWithItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 160;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.getTextureByXP();
|
||||
}
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public String getDisplayName()
|
||||
{
|
||||
// if(!this.hasCustomName()) {
|
||||
// return super.getDisplayName();
|
||||
// }
|
||||
return this.hasCustomName() ? TextColor.GREEN + this.getCustomNameTag() : null;
|
||||
}
|
||||
}
|
64
java/src/game/entity/item/EntityXpBottle.java
Executable file
64
java/src/game/entity/item/EntityXpBottle.java
Executable file
|
@ -0,0 +1,64 @@
|
|||
package game.entity.item;
|
||||
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityThrowable;
|
||||
import game.world.BlockPos;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityXpBottle extends EntityThrowable
|
||||
{
|
||||
public EntityXpBottle(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityXpBottle(World worldIn, EntityLiving p_i1786_2_)
|
||||
{
|
||||
super(worldIn, p_i1786_2_);
|
||||
}
|
||||
|
||||
public EntityXpBottle(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of gravity to apply to the thrown entity with each tick.
|
||||
*/
|
||||
protected float getGravityVelocity()
|
||||
{
|
||||
return 0.07F;
|
||||
}
|
||||
|
||||
protected float getVelocity()
|
||||
{
|
||||
return 0.7F;
|
||||
}
|
||||
|
||||
protected float getInaccuracy()
|
||||
{
|
||||
return -20.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityThrowable hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition p_70184_1_)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.worldObj.playAuxSFX(2002, new BlockPos(this), 0);
|
||||
int i = this.worldObj.rand.rangeBonus(3, 7, 4);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
54
java/src/game/entity/npc/Alignment.java
Executable file
54
java/src/game/entity/npc/Alignment.java
Executable file
|
@ -0,0 +1,54 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import game.collect.Maps;
|
||||
import game.color.TextColor;
|
||||
|
||||
public enum Alignment {
|
||||
LAWFUL_GOOD("lgood", "Rechtsch. gut", 1, 1, TextColor.NEON),
|
||||
GOOD("good", "Gut", 0, 1, TextColor.BLUE),
|
||||
CHAOTIC_GOOD("cgood", "Chaotisch gut", -1, 1, TextColor.CYAN),
|
||||
LAWFUL("lawful", "Rechtschaffen", 1, 0, TextColor.WHITE),
|
||||
NEUTRAL("neutral", "Neutral", 0, 0, TextColor.LGRAY),
|
||||
CHAOTIC("chaotic", "Chaotisch", -1, 0, TextColor.GRAY),
|
||||
LAWFUL_EVIL("levil", "Rechtsch. böse", 1, -1, TextColor.ORANGE),
|
||||
EVIL("evil", "Böse", 0, -1, TextColor.RED),
|
||||
CHAOTIC_EVIL("cevil", "Chaotisch böse", -1, -1, TextColor.DRED);
|
||||
|
||||
private static final Map<String, Alignment> LOOKUP = Maps.newHashMap();
|
||||
|
||||
public final boolean lawful;
|
||||
public final boolean chaotic;
|
||||
public final boolean good;
|
||||
public final boolean evil;
|
||||
public final TextColor color;
|
||||
public final String name;
|
||||
public final String prefix;
|
||||
public final String display;
|
||||
|
||||
private Alignment(String name, String display, int temper, int morale, TextColor color) {
|
||||
this.lawful = temper == 1;
|
||||
this.chaotic = temper == -1;
|
||||
this.good = morale == 1;
|
||||
this.evil = morale == -1;
|
||||
this.color = color;
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
this.prefix = TextColor.GRAY + "[" + (temper == 0 && morale == 0 ? TextColor.LGRAY + "~" : "") +
|
||||
(this.good ? TextColor.BLUE + "*" : (this.evil ? TextColor.RED + "!" : "")) +
|
||||
(this.lawful ? TextColor.GREEN + "+" : (this.chaotic ? TextColor.DMAGENTA + "-" : "")) +
|
||||
TextColor.GRAY + "]";
|
||||
}
|
||||
|
||||
public static Alignment getByName(String name) {
|
||||
Alignment type = LOOKUP.get(name.toLowerCase());
|
||||
return type == null ? NEUTRAL : type;
|
||||
}
|
||||
|
||||
static {
|
||||
for(Alignment type : values()) {
|
||||
LOOKUP.put(type.name, type);
|
||||
}
|
||||
}
|
||||
}
|
62
java/src/game/entity/npc/CharacterInfo.java
Executable file
62
java/src/game/entity/npc/CharacterInfo.java
Executable file
|
@ -0,0 +1,62 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.init.SpeciesRegistry;
|
||||
import game.item.ItemStack;
|
||||
import game.item.RngLoot;
|
||||
import game.rng.Random;
|
||||
import game.rng.WeightedList;
|
||||
|
||||
public class CharacterInfo {
|
||||
public final boolean spawner;
|
||||
public final SpeciesInfo species;
|
||||
public final ClassInfo spclass;
|
||||
public final String name;
|
||||
public final String skin;
|
||||
public final String cape;
|
||||
public final int color1;
|
||||
public final int color2;
|
||||
private final WeightedList<RngLoot>[] items;
|
||||
|
||||
public CharacterInfo(SpeciesInfo species, ClassInfo spclass, String name, String skin, String cape, int color1, int color2, boolean spawner) {
|
||||
this.spawner = spawner; // ? SpeciesRegistry.CHARACTERS.size() : -1;
|
||||
this.species = species;
|
||||
this.spclass = spclass;
|
||||
this.name = name;
|
||||
this.skin = skin;
|
||||
this.cape = cape;
|
||||
this.color1 = color1;
|
||||
this.color2 = color2;
|
||||
this.items = new WeightedList[6];
|
||||
for(int z = 0; z < this.items.length; z++) {
|
||||
this.items[z] = new WeightedList();
|
||||
}
|
||||
SpeciesRegistry.SKINS.put(skin, species.renderer);
|
||||
if(!cape.isEmpty()) {
|
||||
SpeciesRegistry.CAPES.add(cape);
|
||||
}
|
||||
if(spclass != null)
|
||||
spclass.chars.add(this);
|
||||
// if(spawner)
|
||||
// SpeciesRegistry.CHARACTERS.add(this);
|
||||
}
|
||||
|
||||
public WeightedList<RngLoot>[] getItems() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public ItemStack pickItem(int slot, Random rand) {
|
||||
WeightedList<RngLoot> list = this.items[slot];
|
||||
if(list.isEmpty()) {
|
||||
if(this.spclass != null) {
|
||||
list = this.spclass.getItems()[slot];
|
||||
}
|
||||
if(this.spclass == null || list.isEmpty()) {
|
||||
list = this.species.getItems()[slot];
|
||||
if(list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.pick(rand).getItem(rand);
|
||||
}
|
||||
}
|
30
java/src/game/entity/npc/ClassInfo.java
Executable file
30
java/src/game/entity/npc/ClassInfo.java
Executable file
|
@ -0,0 +1,30 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.collect.Lists;
|
||||
import game.item.RngLoot;
|
||||
import game.rng.WeightedList;
|
||||
|
||||
public class ClassInfo {
|
||||
public final SpeciesInfo species;
|
||||
public final Enum type;
|
||||
public final List<CharacterInfo> chars;
|
||||
private final WeightedList<RngLoot>[] items;
|
||||
|
||||
public ClassInfo(SpeciesInfo species, Enum type) {
|
||||
this.species = species;
|
||||
this.type = type;
|
||||
this.items = new WeightedList[6];
|
||||
for(int z = 0; z < this.items.length; z++) {
|
||||
this.items[z] = new WeightedList();
|
||||
}
|
||||
this.chars = Lists.newArrayList();
|
||||
// SpeciesRegistry.SPCLASSES.add(this);
|
||||
this.species.classmap.put(this.type, this);
|
||||
}
|
||||
|
||||
public WeightedList<RngLoot>[] getItems() {
|
||||
return this.items;
|
||||
}
|
||||
}
|
31
java/src/game/entity/npc/Energy.java
Executable file
31
java/src/game/entity/npc/Energy.java
Executable file
|
@ -0,0 +1,31 @@
|
|||
package game.entity.npc;
|
||||
|
||||
public enum Energy {
|
||||
SPIRITUAL(-100, 'S', "spiritual", "SPR", 0x00ff00, 0x00ffff), // angelic
|
||||
NATURAL(-10, 'N', "natural", "NAT", 0x00bf00, 0x00bfbf),
|
||||
HADIC(-1, 'H', "hadic", "HDC", 0x005f00, 0x005f5f), // humanic
|
||||
|
||||
// +DEF
|
||||
//
|
||||
// +ATK
|
||||
|
||||
CEDIC(1, 'C', "cedic", "CDC", 0x5f0000, 0x5f005f), // combatic
|
||||
ARCANE(10, 'A', "arcane", "ARC", 0xbf0000, 0xbf00bf), // arcanic
|
||||
DEMONIC(100, 'D', "demonic", "DEM", 0xff0000, 0xff00ff);
|
||||
|
||||
public final int dir;
|
||||
public final char id;
|
||||
public final String name;
|
||||
public final String display;
|
||||
public final int color;
|
||||
public final int effect;
|
||||
|
||||
private Energy(int dir, char id, String name, String display, int color, int effect) {
|
||||
this.dir = dir;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
this.color = color;
|
||||
this.effect = effect;
|
||||
}
|
||||
}
|
263
java/src/game/entity/npc/EntityArachnoid.java
Executable file
263
java/src/game/entity/npc/EntityArachnoid.java
Executable file
|
@ -0,0 +1,263 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.EntityAIAttackOnCollide;
|
||||
import game.ai.EntityAILeapAtTarget;
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.pathfinding.PathNavigate;
|
||||
import game.pathfinding.PathNavigateClimber;
|
||||
import game.potion.Potion;
|
||||
import game.potion.PotionEffect;
|
||||
import game.rng.Random;
|
||||
import game.world.BlockPos;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityArachnoid extends EntityNPC
|
||||
{
|
||||
public EntityArachnoid(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
// this.setSize(1.4F, 1.6F);
|
||||
this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
|
||||
// this.tasks.addTask(4, new AISpiderAttack(this, EntityNPC.class));
|
||||
this.tasks.addTask(4, new AISpiderAttack(this, EntityNPC.class));
|
||||
// this.targets.addTask(2, new EntitySpider.AISpiderTarget(this, EntityNPC.class));
|
||||
// this.targets.addTask(3, new EntitySpider.AISpiderTarget(this, EntityNPC.class));
|
||||
}
|
||||
|
||||
// public double getMountedYOffset()
|
||||
// {
|
||||
// return (double)(this.height * 0.5F);
|
||||
// }
|
||||
|
||||
// public float getRenderScale()
|
||||
// {
|
||||
// return 0.9375f * this.height / 1.6f;
|
||||
// }
|
||||
|
||||
protected PathNavigate getNewNavigator(World worldIn)
|
||||
{
|
||||
return new PathNavigateClimber(this, worldIn);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(23, (byte)0);
|
||||
}
|
||||
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.setBesideClimbableBlock(this.collidedHorizontally);
|
||||
}
|
||||
}
|
||||
|
||||
// protected void applyEntityAttributes()
|
||||
// {
|
||||
// super.applyEntityAttributes();
|
||||
// this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
|
||||
// }
|
||||
|
||||
// protected String getLivingSound()
|
||||
// {
|
||||
// return "mob.spider.say";
|
||||
// }
|
||||
|
||||
public boolean isOnLadder()
|
||||
{
|
||||
return super.isOnLadder() || (this.sendQueue != null ? this.collidedHorizontally && !this.noclip : this.isBesideClimbableBlock());
|
||||
}
|
||||
|
||||
public void setInWeb()
|
||||
{
|
||||
}
|
||||
|
||||
public boolean isBesideClimbableBlock()
|
||||
{
|
||||
return (!this.isPlayer() || !this.noclip) && this.dataWatcher.getWatchableObjectByte(23) != 0;
|
||||
}
|
||||
|
||||
public void setBesideClimbableBlock(boolean climb)
|
||||
{
|
||||
this.dataWatcher.updateObject(23, (byte)(climb ? 1 : 0));
|
||||
}
|
||||
|
||||
public Object onInitialSpawn(Object livingdata)
|
||||
{
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
// if(!this.isChild()) {
|
||||
// if (this.worldObj.rand.chance(100))
|
||||
// {
|
||||
// EntityUndead entityskeleton = new EntityUndead(this.worldObj);
|
||||
// entityskeleton.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, 0.0F);
|
||||
// entityskeleton.onInitialSpawn(difficulty, (IEntityLivingData)null);
|
||||
// this.worldObj.spawnEntityInWorld(entityskeleton);
|
||||
// entityskeleton.mountEntity(this);
|
||||
// }
|
||||
|
||||
if (livingdata == null && !this.isPlayer())
|
||||
{
|
||||
livingdata = new EntityArachnoid.GroupData(this.worldObj.rand.chance(40));
|
||||
|
||||
if (/* this.worldObj.getDifficulty() == Difficulty.HARD && */ this.worldObj.rand.chance())
|
||||
{
|
||||
((EntityArachnoid.GroupData)livingdata).pickEffect(this.worldObj.rand);
|
||||
}
|
||||
}
|
||||
|
||||
if (livingdata instanceof EntityArachnoid.GroupData)
|
||||
{
|
||||
int i = ((EntityArachnoid.GroupData)livingdata).potionEffectId;
|
||||
|
||||
if (i > 0 && Potion.POTION_TYPES[i] != null)
|
||||
{
|
||||
this.addEffect(new PotionEffect(i, Integer.MAX_VALUE));
|
||||
}
|
||||
|
||||
if(((EntityArachnoid.GroupData)livingdata).isChild)
|
||||
this.setGrowingAge(-24000);
|
||||
}
|
||||
// }
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
// public float getEyeHeight()
|
||||
// {
|
||||
// return super.getEyeHeight() * 0.85f;
|
||||
// }
|
||||
|
||||
public boolean isSneakingVisually() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xc63ba0;
|
||||
}
|
||||
|
||||
static class AISpiderAttack extends EntityAIAttackOnCollide
|
||||
{
|
||||
public AISpiderAttack(EntityArachnoid spider, Class <? extends Entity > targetClass)
|
||||
{
|
||||
super(spider, targetClass, 1.0D, true);
|
||||
}
|
||||
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
float f = this.attacker.getBrightness(1.0F);
|
||||
|
||||
if (f >= 0.5F && this.attacker.getRNG().chance(100))
|
||||
{
|
||||
this.attacker.setAttackTarget((EntityLiving)null);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.continueExecuting();
|
||||
}
|
||||
}
|
||||
|
||||
protected double getAttackRange(EntityLiving attackTarget)
|
||||
{
|
||||
return (double)(4.0F + attackTarget.width);
|
||||
}
|
||||
}
|
||||
|
||||
// static class AISpiderTarget<T extends EntityLivingBase> extends EntityAINearestAttackableTarget
|
||||
// {
|
||||
// public AISpiderTarget(EntitySpider spider, Class<T> classTarget)
|
||||
// {
|
||||
// super(spider, classTarget, true);
|
||||
// }
|
||||
//
|
||||
// public boolean shouldExecute()
|
||||
// {
|
||||
// float f = this.taskOwner.getBrightness(1.0F);
|
||||
// return f >= 0.5F ? false : super.shouldExecute();
|
||||
// }
|
||||
// }
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return this.getBrightness(1.0f) < 0.5f;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(16, 24);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(0.0f, 0.25f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.LAWFUL_EVIL, Alignment.EVIL, Alignment.LAWFUL, Alignment.NEUTRAL);
|
||||
}
|
||||
|
||||
public boolean attackEntityAsMob(Entity entityIn)
|
||||
{
|
||||
if(super.attackEntityAsMob(entityIn)) {
|
||||
if(entityIn instanceof EntityLiving && this.rand.chance(50))
|
||||
((EntityLiving)entityIn).addEffect(new PotionEffect(Potion.poison.id, this.rand.range(14, 35) * 20, 0));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean getCanSpawnHere() {
|
||||
return this.worldObj.getLightFromNeighbors(new BlockPos(this)) <= this.rand.zrange(8);
|
||||
}
|
||||
|
||||
public boolean canAmbush(EntityLiving entity) {
|
||||
return (float)this.getHealth() >= ((float)this.getMaxHealth() / 4.0f);
|
||||
}
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class GroupData
|
||||
{
|
||||
public int potionEffectId;
|
||||
public boolean isChild;
|
||||
|
||||
public GroupData(boolean isChild) {
|
||||
this.isChild = isChild;
|
||||
}
|
||||
|
||||
public void pickEffect(Random rand)
|
||||
{
|
||||
this.potionEffectId = rand.pick(Potion.moveSpeed.id, Potion.moveSpeed.id, Potion.damageBoost.id, Potion.regeneration.id);
|
||||
}
|
||||
}
|
||||
}
|
61
java/src/game/entity/npc/EntityBloodElf.java
Executable file
61
java/src/game/entity/npc/EntityBloodElf.java
Executable file
|
@ -0,0 +1,61 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.init.NameRegistry;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityBloodElf extends EntityNPC {
|
||||
public EntityBloodElf(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return this.alignment.evil && !this.alignment.lawful;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return (this.alignment.evil && !this.alignment.lawful) || clazz == EntityCultivator.class;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return !this.alignment.evil && clazz == EntityWoodElf.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return this.alignment.chaotic;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return rand.range(12, 28);
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(24, 26);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.1f, 0.3f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.chance(50) ?
|
||||
(rand.chance(8) ? (rand.chance(5) ? Alignment.CHAOTIC : Alignment.LAWFUL) : Alignment.NEUTRAL) :
|
||||
(rand.chance(5) ? Alignment.EVIL : Alignment.LAWFUL_EVIL);
|
||||
}
|
||||
|
||||
public NameRegistry getNameType() {
|
||||
return NameRegistry.ELVEN;
|
||||
}
|
||||
}
|
117
java/src/game/entity/npc/EntityChaosMarine.java
Executable file
117
java/src/game/entity/npc/EntityChaosMarine.java
Executable file
|
@ -0,0 +1,117 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.collect.Lists;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.init.SpeciesRegistry;
|
||||
import game.properties.IStringSerializable;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityChaosMarine extends EntityNPC {
|
||||
public static enum Legion implements IStringSerializable {
|
||||
OTHER("other", "???", 0x000000, 0x000000, 2.15f, 200),
|
||||
EMPERORS_CHILDREN("emperorchild", "Emperors Children", 0xa224cc, 0xccb963, 2.43f, 300, "emperors_child");
|
||||
|
||||
public static final Object[] MARINES;
|
||||
|
||||
private final String name;
|
||||
private final String display;
|
||||
public final int color1;
|
||||
public final int color2;
|
||||
public final float size;
|
||||
public final int health;
|
||||
public final String[] classes;
|
||||
|
||||
static {
|
||||
List<Object> marines = Lists.newArrayList();
|
||||
for(Legion legion : values()) {
|
||||
if(legion.classes.length > 0)
|
||||
marines.add(legion);
|
||||
for(String type : legion.classes) {
|
||||
marines.add(":marine_" + type);
|
||||
marines.add(legion.color1);
|
||||
marines.add(legion.color2);
|
||||
}
|
||||
}
|
||||
MARINES = marines.toArray(new Object[marines.size()]);
|
||||
marines.clear();
|
||||
}
|
||||
|
||||
private Legion(String name, String display, int color1, int color2, float size, int health, String ... classes) {
|
||||
this.name = name;
|
||||
this.display = display + " Einheit";
|
||||
this.color1 = color1;
|
||||
this.color2 = color2;
|
||||
this.size = size;
|
||||
this.health = health;
|
||||
this.classes = classes;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.display;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityChaosMarine(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public Legion getLegion() {
|
||||
Enum legion = this.getNpcClass();
|
||||
return legion == null ? Legion.OTHER : (Legion)legion;
|
||||
}
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return "terra".equals(SpeciesRegistry.CLASSES.get(clazz).origin);
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return this.getLegion().health;
|
||||
}
|
||||
|
||||
public float getBaseSize(Random rand) {
|
||||
return this.getLegion().size / this.species.size;
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.chance(Alignment.CHAOTIC_EVIL, Alignment.EVIL, 6);
|
||||
}
|
||||
|
||||
public Object onInitialSpawn(Object livingdata) {
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
this.setMaxHealth(this.getLegion().health);
|
||||
this.setHealth(this.getMaxHealth());
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isSneakingVisually() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getTotalArmorValue() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
protected int getAttackSpeed() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(12.0D);
|
||||
}
|
||||
}
|
60
java/src/game/entity/npc/EntityCpu.java
Executable file
60
java/src/game/entity/npc/EntityCpu.java
Executable file
|
@ -0,0 +1,60 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.init.Items;
|
||||
import game.item.ItemStack;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityCpu extends EntityNPC {
|
||||
public EntityCpu(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return Integer.MAX_VALUE;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return 1024;
|
||||
}
|
||||
|
||||
// public float getHeightDeviation(Random rand) {
|
||||
// return 0.0f;
|
||||
// }
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return Alignment.NEUTRAL;
|
||||
}
|
||||
|
||||
public boolean isBreedingItem(ItemStack stack) {
|
||||
return stack.getItem() == Items.nieh_fragment;
|
||||
}
|
||||
}
|
115
java/src/game/entity/npc/EntityCultivator.java
Executable file
115
java/src/game/entity/npc/EntityCultivator.java
Executable file
|
@ -0,0 +1,115 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.EntityAITakePlace;
|
||||
import game.ai.EntityAITempt;
|
||||
import game.ai.EntityAIWatchClosest2;
|
||||
import game.entity.effect.EntityLightning;
|
||||
import game.init.Items;
|
||||
import game.item.ItemStack;
|
||||
import game.rng.Random;
|
||||
import game.world.BlockPos;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityCultivator extends EntityNPC {
|
||||
public EntityCultivator(World worldIn) {
|
||||
super(worldIn);
|
||||
this.tasks.addTask(2, new EntityAITempt(this, 1.0D, null, 10.0, 32.0, false) {
|
||||
public boolean shouldExecute() {
|
||||
return EntityCultivator.this.canTakePhotos() && super.shouldExecute();
|
||||
}
|
||||
});
|
||||
this.tasks.addTask(5, new EntityAIWatchClosest2(this, null, 32.0F, 1.0F) {
|
||||
public boolean shouldExecute() {
|
||||
return EntityCultivator.this.canTakePhotos() && super.shouldExecute();
|
||||
}
|
||||
|
||||
public boolean continueExecuting() {
|
||||
return EntityCultivator.this.canTakePhotos() && super.continueExecuting();
|
||||
}
|
||||
|
||||
public void updateTask() {
|
||||
super.updateTask();
|
||||
if(EntityCultivator.this.rand.chance(100) && EntityCultivator.this.getHeldItem() != null
|
||||
&& EntityCultivator.this.getHeldItem().getItem() == Items.camera) {
|
||||
EntityCultivator.this.swingItem();
|
||||
EntityCultivator.this.worldObj.playAuxSFX(1024, new BlockPos(EntityCultivator.this.posX,
|
||||
EntityCultivator.this.posY + EntityCultivator.this.getEyeHeight(), EntityCultivator.this.posZ), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void startExecuting() {
|
||||
super.startExecuting();
|
||||
EntityCultivator.this.setItemNoUpdate(0, new ItemStack(Items.camera));
|
||||
}
|
||||
|
||||
public void resetTask() {
|
||||
super.resetTask();
|
||||
EntityCultivator.this.setItemNoUpdate(0, null);
|
||||
}
|
||||
});
|
||||
this.tasks.addTask(10, new EntityAITakePlace(this));
|
||||
}
|
||||
|
||||
private boolean canTakePhotos() {
|
||||
return "Grell".equalsIgnoreCase(this.getCustomNameTag()) || "Grelle".equalsIgnoreCase(this.getCustomNameTag());
|
||||
}
|
||||
|
||||
public boolean canPlay() {
|
||||
return super.canPlay() && !this.canTakePhotos();
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return this.alignment.evil && !this.alignment.lawful;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return this.alignment.good;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityElf.class || clazz == EntityBloodElf.class || (this.alignment.evil && (this.alignment.chaotic || clazz == EntityWoodElf.class));
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return this.alignment.good && !this.alignment.chaotic;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return this.alignment == Alignment.CHAOTIC_EVIL;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return rand.range(12, 26);
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(25, 40);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.values());
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public void onStruckByLightning(EntityLightning lightningBolt) {
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x6f0099;
|
||||
}
|
||||
}
|
91
java/src/game/entity/npc/EntityDarkMage.java
Executable file
91
java/src/game/entity/npc/EntityDarkMage.java
Executable file
|
@ -0,0 +1,91 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.AISmallFireballAttack;
|
||||
import game.init.SoundEvent;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
import game.world.WorldClient;
|
||||
|
||||
public class EntityDarkMage extends EntityHoveringNPC {
|
||||
public EntityDarkMage(World worldIn) {
|
||||
super(worldIn);
|
||||
this.tasks.addTask(7, new AISmallFireballAttack(this));
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityFireDemon.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(34, 66);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return Alignment.CHAOTIC_EVIL;
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xeec800;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public boolean isBurning() {
|
||||
return super.isBurning() || this.isAttacking();
|
||||
}
|
||||
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
if(this.worldObj.client && this.isAttacking()) {
|
||||
if(this.rand.chance(24)) { // && !this.isSilent()) {
|
||||
((WorldClient)this.worldObj).playSound(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, SoundEvent.FIRE,
|
||||
1.0F + this.rand.floatv(), this.rand.floatv() * 0.7F + 0.3F);
|
||||
}
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
this.worldObj.spawnParticle(ParticleType.SMOKE_LARGE, this.posX + (this.rand.doublev() - 0.5D) * (double)this.width,
|
||||
this.posY + this.rand.doublev() * (double)this.height,
|
||||
this.posZ + (this.rand.doublev() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
}
|
63
java/src/game/entity/npc/EntityDwarf.java
Executable file
63
java/src/game/entity/npc/EntityDwarf.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityDwarf extends EntityNPC {
|
||||
public EntityDwarf(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(16, 18);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.1f, 0.1f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.GOOD, Alignment.LAWFUL_GOOD, Alignment.NEUTRAL, Alignment.LAWFUL);
|
||||
}
|
||||
|
||||
public boolean canTrade() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canAmbush(EntityLiving entity) {
|
||||
return (float)this.getHealth() >= ((float)this.getMaxHealth() / 2.85f) && entity.getHealth() < this.getHealth();
|
||||
}
|
||||
}
|
66
java/src/game/entity/npc/EntityElf.java
Executable file
66
java/src/game/entity/npc/EntityElf.java
Executable file
|
@ -0,0 +1,66 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.NameRegistry;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityElf extends EntityNPC {
|
||||
public EntityElf(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return this.alignment == Alignment.CHAOTIC_EVIL;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return this.alignment == Alignment.CHAOTIC_EVIL || clazz == EntityCultivator.class;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return !this.alignment.evil && clazz == EntityWoodElf.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return this.alignment.evil;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return rand.range(10, 30);
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(20, 24);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.4f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.chance(50) ?
|
||||
(rand.chance(8) ? (rand.chance(5) ? Alignment.CHAOTIC_EVIL : Alignment.EVIL) : Alignment.LAWFUL_EVIL) :
|
||||
(rand.chance(5) ? Alignment.NEUTRAL : Alignment.LAWFUL);
|
||||
}
|
||||
|
||||
public NameRegistry getNameType() {
|
||||
return NameRegistry.ELVEN;
|
||||
}
|
||||
|
||||
public boolean canAmbush(EntityLiving entity) {
|
||||
return (float)this.getHealth() >= ((float)this.getMaxHealth() / 5.0f);
|
||||
}
|
||||
}
|
84
java/src/game/entity/npc/EntityFireDemon.java
Executable file
84
java/src/game/entity/npc/EntityFireDemon.java
Executable file
|
@ -0,0 +1,84 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.AIFireballAttack;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.effect.EntityLightning;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityFireDemon extends EntityFlyingNPC {
|
||||
public EntityFireDemon(World worldIn) {
|
||||
super(worldIn);
|
||||
// this.setSize(2.55f);
|
||||
this.tasks.addTask(7, new AIFireballAttack(this, 3, 7, 64.0, 2.0));
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityHuman.class;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityDarkMage.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(56, 140);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.15f, 0.35f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return Alignment.CHAOTIC_EVIL;
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xa2371b;
|
||||
}
|
||||
|
||||
public boolean hasPowerRods() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, int amount) {
|
||||
if(source.isExplosion())
|
||||
return false;
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
|
||||
public void onStruckByLightning(EntityLightning lightningBolt) {
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true; // this.getHealth() >= this.getMaxHealth() / 8;
|
||||
// }
|
||||
}
|
245
java/src/game/entity/npc/EntityFlyingNPC.java
Executable file
245
java/src/game/entity/npc/EntityFlyingNPC.java
Executable file
|
@ -0,0 +1,245 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIBase;
|
||||
import game.ai.EntityMoveHelper;
|
||||
import game.block.Block;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.rng.Random;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityFlyingNPC extends EntityNPC
|
||||
{
|
||||
public EntityFlyingNPC(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.moveHelper = new FlyMoveHelper(this);
|
||||
this.tasks.addTask(5, new AIRandomFly(this));
|
||||
this.tasks.addTask(7, new AILookAround(this));
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.FOLLOW_RANGE).setBaseValue(48.0D);
|
||||
}
|
||||
|
||||
public float getArmRotation() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
public float getLegRotation() {
|
||||
return 0.2f;
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
}
|
||||
|
||||
protected void updateFallState(double y, boolean onGroundIn, Block blockIn, BlockPos pos)
|
||||
{
|
||||
}
|
||||
|
||||
public void moveEntityWithHeading(float strafe, float forward)
|
||||
{
|
||||
if (this.isInLiquid())
|
||||
{
|
||||
this.moveFlying(strafe, forward, 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.isInMolten())
|
||||
{
|
||||
this.moveFlying(strafe, forward, 0.02F);
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.5D;
|
||||
this.motionY *= 0.5D;
|
||||
this.motionZ *= 0.5D;
|
||||
}
|
||||
else
|
||||
{
|
||||
float f = 0.91F;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
f = this.worldObj.getState(new BlockPos(ExtMath.floord(this.posX), ExtMath.floord(this.getEntityBoundingBox().minY) - 1, ExtMath.floord(this.posZ))).getBlock().slipperiness * 0.91F;
|
||||
}
|
||||
|
||||
float f1 = 0.16277136F / (f * f * f);
|
||||
this.moveFlying(strafe, forward, this.onGround ? 0.1F * f1 : 0.02F);
|
||||
f = 0.91F;
|
||||
|
||||
if (this.onGround)
|
||||
{
|
||||
f = this.worldObj.getState(new BlockPos(ExtMath.floord(this.posX), ExtMath.floord(this.getEntityBoundingBox().minY) - 1, ExtMath.floord(this.posZ))).getBlock().slipperiness * 0.91F;
|
||||
}
|
||||
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= (double)f;
|
||||
this.motionY *= (double)f;
|
||||
this.motionZ *= (double)f;
|
||||
}
|
||||
|
||||
this.prevLswingAmount = this.lswingAmount;
|
||||
double d1 = this.posX - this.prevX;
|
||||
double d0 = this.posZ - this.prevZ;
|
||||
float f2 = ExtMath.sqrtd(d1 * d1 + d0 * d0) * 4.0F;
|
||||
|
||||
if (f2 > 1.0F)
|
||||
{
|
||||
f2 = 1.0F;
|
||||
}
|
||||
|
||||
this.lswingAmount += (f2 - this.lswingAmount) * 0.4F;
|
||||
this.limbSwing += this.lswingAmount;
|
||||
}
|
||||
|
||||
public boolean isOnLadder()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static class AILookAround extends EntityAIBase
|
||||
{
|
||||
private EntityFlyingNPC parentEntity;
|
||||
|
||||
public AILookAround(EntityFlyingNPC entity)
|
||||
{
|
||||
this.parentEntity = entity;
|
||||
this.setMutexBits(2);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.parentEntity.getAttackTarget() == null)
|
||||
{
|
||||
this.parentEntity.yawOffset = this.parentEntity.rotYaw = -((float)ExtMath.atan2(this.parentEntity.motionX, this.parentEntity.motionZ)) * 180.0F / (float)Math.PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntityLiving entitylivingbase = this.parentEntity.getAttackTarget();
|
||||
double d0 = 64.0D;
|
||||
|
||||
if (entitylivingbase.getDistanceSqToEntity(this.parentEntity) < d0 * d0)
|
||||
{
|
||||
double d1 = entitylivingbase.posX - this.parentEntity.posX;
|
||||
double d2 = entitylivingbase.posZ - this.parentEntity.posZ;
|
||||
this.parentEntity.yawOffset = this.parentEntity.rotYaw = -((float)ExtMath.atan2(d1, d2)) * 180.0F / (float)Math.PI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class AIRandomFly extends EntityAIBase
|
||||
{
|
||||
private EntityFlyingNPC parentEntity;
|
||||
|
||||
public AIRandomFly(EntityFlyingNPC entity)
|
||||
{
|
||||
this.parentEntity = entity;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityMoveHelper entitymovehelper = this.parentEntity.getMoveHelper();
|
||||
|
||||
if (!entitymovehelper.isUpdating())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
double d0 = entitymovehelper.getX() - this.parentEntity.posX;
|
||||
double d1 = entitymovehelper.getY() - this.parentEntity.posY;
|
||||
double d2 = entitymovehelper.getZ() - this.parentEntity.posZ;
|
||||
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
|
||||
return d3 < 1.0D || d3 > 3600.0D;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
Random random = this.parentEntity.getRNG();
|
||||
double d0 = this.parentEntity.posX + (double)((random.floatv() * 2.0F - 1.0F) * 16.0F);
|
||||
double d1 = this.parentEntity.posY + (double)((random.floatv() * 2.0F - 1.0F) * 16.0F);
|
||||
double d2 = this.parentEntity.posZ + (double)((random.floatv() * 2.0F - 1.0F) * 16.0F);
|
||||
this.parentEntity.getMoveHelper().setMoveTo(d0, d1, d2, 1.0D);
|
||||
}
|
||||
}
|
||||
|
||||
static class FlyMoveHelper extends EntityMoveHelper
|
||||
{
|
||||
private EntityFlyingNPC parentEntity;
|
||||
private int courseChangeCooldown;
|
||||
|
||||
public FlyMoveHelper(EntityFlyingNPC entity)
|
||||
{
|
||||
super(entity);
|
||||
this.parentEntity = entity;
|
||||
}
|
||||
|
||||
public void onUpdateMoveHelper()
|
||||
{
|
||||
if (this.update)
|
||||
{
|
||||
double d0 = this.posX - this.parentEntity.posX;
|
||||
double d1 = this.posY - this.parentEntity.posY;
|
||||
double d2 = this.posZ - this.parentEntity.posZ;
|
||||
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
|
||||
|
||||
if (this.courseChangeCooldown-- <= 0)
|
||||
{
|
||||
this.courseChangeCooldown += this.parentEntity.getRNG().range(2, 6);
|
||||
d3 = (double)ExtMath.sqrtd(d3);
|
||||
|
||||
if (this.isNotColliding(this.posX, this.posY, this.posZ, d3))
|
||||
{
|
||||
this.parentEntity.motionX += d0 / d3 * 0.1D;
|
||||
this.parentEntity.motionY += d1 / d3 * 0.1D;
|
||||
this.parentEntity.motionZ += d2 / d3 * 0.1D;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.update = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNotColliding(double x, double y, double z, double p_179926_7_)
|
||||
{
|
||||
double d0 = (x - this.parentEntity.posX) / p_179926_7_;
|
||||
double d1 = (y - this.parentEntity.posY) / p_179926_7_;
|
||||
double d2 = (z - this.parentEntity.posZ) / p_179926_7_;
|
||||
BoundingBox axisalignedbb = this.parentEntity.getEntityBoundingBox();
|
||||
|
||||
for (int i = 1; (double)i < p_179926_7_; ++i)
|
||||
{
|
||||
axisalignedbb = axisalignedbb.offset(d0, d1, d2);
|
||||
|
||||
if (!this.parentEntity.worldObj.getCollidingBoundingBoxes(this.parentEntity, axisalignedbb).isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
240
java/src/game/entity/npc/EntityGargoyle.java
Executable file
240
java/src/game/entity/npc/EntityGargoyle.java
Executable file
|
@ -0,0 +1,240 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.AIFlyingBoxAttack;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.init.Config;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityGargoyle extends EntityFlyingNPC
|
||||
{
|
||||
public EntityGargoyle(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
// this.setSize(2.2f);
|
||||
this.tasks.addTask(7, new AIFlyingBoxAttack(this));
|
||||
this.noPickup = true;
|
||||
}
|
||||
|
||||
public boolean isBoss() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(23, 0);
|
||||
}
|
||||
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("Invul", this.getInvulTime());
|
||||
}
|
||||
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setInvulTime(tagCompund.getInteger("Invul"));
|
||||
}
|
||||
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
// this.motionY *= 0.6000000238418579D;
|
||||
|
||||
// if (!this.worldObj.client)
|
||||
// {
|
||||
// EntityLivingBase entity = this.getAttackTarget();
|
||||
//
|
||||
// if (entity != null)
|
||||
// {
|
||||
// if (this.posY < entity.posY || /* !this.isArmored() && */ this.posY < entity.posY + 5.0D)
|
||||
// {
|
||||
// if (this.motionY < 0.0D)
|
||||
// {
|
||||
// this.motionY = 0.0D;
|
||||
// }
|
||||
//
|
||||
// this.motionY += (0.5D - this.motionY) * 0.6000000238418579D;
|
||||
// }
|
||||
//
|
||||
// double d0 = entity.posX - this.posX;
|
||||
// double d1 = entity.posZ - this.posZ;
|
||||
// double d3 = d0 * d0 + d1 * d1;
|
||||
//
|
||||
// if (d3 > 9.0D)
|
||||
// {
|
||||
// double d5 = (double)MathHelper.sqrt_double(d3);
|
||||
// this.motionX += (d0 / d5 * 0.5D - this.motionX) * 0.6000000238418579D;
|
||||
// this.motionZ += (d1 / d5 * 0.5D - this.motionZ) * 0.6000000238418579D;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (this.motionX * this.motionX + this.motionZ * this.motionZ > 0.05000000074505806D)
|
||||
// {
|
||||
// this.rotYaw = (float)MathHelper.atan2(this.motionZ, this.motionX) * (180F / (float)Math.PI) - 90.0F;
|
||||
// }
|
||||
|
||||
super.onLivingUpdate();
|
||||
|
||||
for (int l = 0; l < 5; ++l)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.SMOKE_NORMAL, this.posX + this.rand.gaussian() * 0.30000001192092896D, this.posY + this.height + this.rand.gaussian() * 0.30000001192092896D, this.posZ + this.rand.gaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
|
||||
if (this.getInvulTime() > 0)
|
||||
{
|
||||
for (int i1 = 0; i1 < 3; ++i1)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.SPELL_MOB, this.posX + this.rand.gaussian() * 1.0D, this.posY + (double)(this.rand.floatv() * 3.3F), this.posZ + this.rand.gaussian() * 1.0D, 0.699999988079071D, 0.699999988079071D, 0.8999999761581421D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateAITasks()
|
||||
{
|
||||
super.updateAITasks();
|
||||
|
||||
if (this.getInvulTime() > 0)
|
||||
{
|
||||
int j1 = this.getInvulTime() - 1;
|
||||
|
||||
if (j1 <= 0)
|
||||
{
|
||||
this.worldObj.newExplosion(this, this.posX, this.posY + (double)this.getEyeHeight(), this.posZ, 7.0F, false,
|
||||
Config.mobGrief, false);
|
||||
// this.worldObj.broadcastSound(1013, new BlockPos(this), 0);
|
||||
}
|
||||
|
||||
this.setInvulTime(j1);
|
||||
|
||||
if (this.ticksExisted % 10 == 0)
|
||||
{
|
||||
this.heal(10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.ticksExisted % 20 == 0)
|
||||
{
|
||||
this.heal(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setInWeb()
|
||||
{
|
||||
}
|
||||
|
||||
// public void attackEntityWithRangedAttack(EntityLivingBase target, float p_82196_2_)
|
||||
// {
|
||||
// this.launchBoxToEntity(target);
|
||||
// }
|
||||
|
||||
public boolean isRangedWeapon(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.getInvulTime() > 0 && source != DamageSource.outOfWorld)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.6000000238418579D);
|
||||
this.getEntityAttribute(Attributes.FOLLOW_RANGE).setBaseValue(40.0D);
|
||||
}
|
||||
|
||||
public int getInvulTime()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectInt(23);
|
||||
}
|
||||
|
||||
public void setInvulTime(int time)
|
||||
{
|
||||
this.dataWatcher.updateObject(23, Integer.valueOf(time));
|
||||
}
|
||||
|
||||
// public boolean isPotionApplicable(PotionEffect potioneffectIn) {
|
||||
// return potioneffectIn.getPotionID() != Potion.moveSlowdown.id;
|
||||
// }
|
||||
|
||||
public boolean isCharged() {
|
||||
return this.getInvulTime() > 0;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xc13633;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(300, 400);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(0.0f, 0.05f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return Alignment.CHAOTIC_EVIL;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
}
|
45
java/src/game/entity/npc/EntityGoblin.java
Executable file
45
java/src/game/entity/npc/EntityGoblin.java
Executable file
|
@ -0,0 +1,45 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityGoblin extends EntityNPC {
|
||||
public EntityGoblin(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityHuman.class || clazz == EntityElf.class || clazz == EntityWoodElf.class || clazz == EntityBloodElf.class;
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(8, 12);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.1f, 0.1f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.CHAOTIC_EVIL, Alignment.EVIL, Alignment.LAWFUL_EVIL);
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x309430;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(1.0D);
|
||||
}
|
||||
|
||||
public boolean canAmbush(EntityLiving entity) {
|
||||
return (float)this.getHealth() >= ((float)this.getMaxHealth() / 3.25f);
|
||||
}
|
||||
}
|
359
java/src/game/entity/npc/EntityHaunter.java
Executable file
359
java/src/game/entity/npc/EntityHaunter.java
Executable file
|
@ -0,0 +1,359 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.EntityAIExplode;
|
||||
import game.entity.Entity;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.effect.EntityLightning;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Config;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
import game.world.WorldServer;
|
||||
|
||||
public class EntityHaunter extends EntityNPC {
|
||||
// private int lastActiveTime;
|
||||
private int timeSinceIgnited;
|
||||
private int fuseTime = 30;
|
||||
|
||||
public EntityHaunter(World worldIn) {
|
||||
super(worldIn);
|
||||
this.tasks.addTask(2, new EntityAIExplode(this));
|
||||
// this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityOcelot.class, 6.0F, 1.0D, 1.2D));
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.25D);
|
||||
}
|
||||
|
||||
public int getMaxFallHeight()
|
||||
{
|
||||
return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1);
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
super.fall(distance, damageMultiplier);
|
||||
this.timeSinceIgnited = (int)((float)this.timeSinceIgnited + distance * 1.5F);
|
||||
|
||||
if (this.timeSinceIgnited > this.fuseTime - 5)
|
||||
{
|
||||
this.timeSinceIgnited = this.fuseTime - 5;
|
||||
}
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(23, Byte.valueOf((byte) - 1));
|
||||
// this.dataWatcher.addObject(24, Byte.valueOf((byte)0));
|
||||
this.dataWatcher.addObject(24, Byte.valueOf((byte)0));
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
|
||||
if (this.isCharged())
|
||||
{
|
||||
tagCompound.setBoolean("Charge", true);
|
||||
}
|
||||
|
||||
tagCompound.setShort("Fuse", (short)this.fuseTime);
|
||||
tagCompound.setBoolean("ignited", this.hasIgnited());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setCharged(tagCompund.getBoolean("Charge"));
|
||||
|
||||
if (tagCompund.hasKey("Fuse", 99))
|
||||
{
|
||||
this.fuseTime = tagCompund.getShort("Fuse");
|
||||
}
|
||||
|
||||
if (tagCompund.getBoolean("ignited"))
|
||||
{
|
||||
this.ignite();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
if (this.isEntityAlive())
|
||||
{
|
||||
// this.lastActiveTime = this.timeSinceIgnited;
|
||||
|
||||
if (this.hasIgnited())
|
||||
{
|
||||
this.setExplodeState(1);
|
||||
}
|
||||
|
||||
int i = this.getExplodeState();
|
||||
|
||||
if (i > 0 && this.timeSinceIgnited == 0)
|
||||
{
|
||||
this.playSound(SoundEvent.FUSE, 1.0F, 0.5F);
|
||||
}
|
||||
|
||||
this.timeSinceIgnited += i;
|
||||
|
||||
if (this.timeSinceIgnited < 0)
|
||||
{
|
||||
this.timeSinceIgnited = 0;
|
||||
}
|
||||
|
||||
if (this.timeSinceIgnited >= this.fuseTime)
|
||||
{
|
||||
this.timeSinceIgnited = this.fuseTime;
|
||||
this.explode();
|
||||
}
|
||||
|
||||
if(!this.worldObj.client && i <= 0 && this.rand.chance(20)) {
|
||||
EntityLiving target = this.getAttackTarget();
|
||||
if(target != null && this.getDistanceSqToEntity(target) >= 100.0)
|
||||
this.teleportToEntity(target);
|
||||
}
|
||||
}
|
||||
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
public boolean isGlowing() {
|
||||
return this.getExplodeState() > 0 && (this.ticksExisted & 7) < 4;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns the sound this mob makes when it is hurt.
|
||||
// */
|
||||
// protected String getHurtSound()
|
||||
// {
|
||||
// return "mob.creeper.say";
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the sound this mob makes on death.
|
||||
// */
|
||||
// protected String getDeathSound()
|
||||
// {
|
||||
// return "mob.creeper.death";
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Called when the mob's health reaches 0.
|
||||
// */
|
||||
// public void onDeath(DamageSource cause)
|
||||
// {
|
||||
// super.onDeath(cause);
|
||||
//
|
||||
//// if (cause.getEntity() instanceof EntitySkeleton)
|
||||
//// {
|
||||
////// int i = ItemRegistry.getIdFromItem(Items.record_13);
|
||||
////// int j = ItemRegistry.getIdFromItem(Items.record_wait);
|
||||
////// int k = i + this.rand.nextInt(j - i + 1);
|
||||
////// this.dropItem(ItemRegistry.getItemById(k), 1);
|
||||
//// this.dropItem(Items.dynamite, 1);
|
||||
//// }
|
||||
//// else
|
||||
// if (cause.getEntity() instanceof EntityCreeper && cause.getEntity() != this && ((EntityCreeper)cause.getEntity()).isPowered() && ((EntityCreeper)cause.getEntity()).isAIEnabled())
|
||||
// {
|
||||
// ((EntityCreeper)cause.getEntity()).func_175493_co();
|
||||
// this.entityDropItem(new ItemStack(Items.skull, 1, 4), 0.0F);
|
||||
// }
|
||||
// }
|
||||
|
||||
public boolean attackEntityAsMob(Entity entityIn)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns true if the creeper is powered by a lightning bolt.
|
||||
// */
|
||||
// public boolean isPowered()
|
||||
// {
|
||||
// return this.dataWatcher.getWatchableObjectByte(24) != 0;
|
||||
// }
|
||||
|
||||
// public float getFlashIntensity(float p_70831_1_)
|
||||
// {
|
||||
// return ((float)this.lastActiveTime + (float)(this.timeSinceIgnited - this.lastActiveTime) * p_70831_1_) / (float)(this.fuseTime - 2);
|
||||
// }
|
||||
|
||||
// protected Item getDropItem()
|
||||
// {
|
||||
// return Items.gunpowder;
|
||||
// }
|
||||
|
||||
public int getExplodeState()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(23);
|
||||
}
|
||||
|
||||
public void setExplodeState(int state)
|
||||
{
|
||||
this.dataWatcher.updateObject(23, Byte.valueOf((byte)state));
|
||||
}
|
||||
|
||||
public boolean isCharged()
|
||||
{
|
||||
return this.getFlag(6);
|
||||
}
|
||||
|
||||
public void setCharged(boolean power)
|
||||
{
|
||||
this.setFlag(6, power);
|
||||
}
|
||||
|
||||
// public int getPower() {
|
||||
// return (int)(this.dataWatcher.getWatchableObjectByte(24) & 255);
|
||||
// }
|
||||
|
||||
public void onStruckByLightning(EntityLightning lightningBolt)
|
||||
{
|
||||
// super.onStruckByLightning(lightningBolt);
|
||||
if(!this.worldObj.client && Config.chargeHaunter) {
|
||||
// int power = this.getPower();
|
||||
// if(++power < 256)
|
||||
// this.dataWatcher.updateObject(24, (byte)power);
|
||||
this.setCharged(true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean interact(EntityNPC player)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == Items.flint_and_steel)
|
||||
{
|
||||
this.worldObj.playSound(SoundEvent.IGNITE, this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, 1.0F, this.rand.floatv() * 0.4F + 0.8F);
|
||||
player.swingItem();
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.ignite();
|
||||
itemstack.damageItem(1, player);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.interact(player);
|
||||
}
|
||||
|
||||
private void explode()
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
boolean flag = Config.mobGrief;
|
||||
float f = 1.0F + (float)(this.isCharged() ? this.rand.range(3, 5) : 0) / 8.0f;
|
||||
this.worldObj.createAltExplosion(this, this.posX, this.posY, this.posZ, (float)this.rand.range(3, 5) * f, flag);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasIgnited()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(24) != 0;
|
||||
}
|
||||
|
||||
public void ignite()
|
||||
{
|
||||
this.dataWatcher.updateObject(24, Byte.valueOf((byte)1));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns true if the newer Entity AI code should be run
|
||||
// */
|
||||
// public boolean isAIEnabled()
|
||||
// {
|
||||
// return this.field_175494_bm < 1 && Config.dropLoot;
|
||||
// }
|
||||
|
||||
// public void func_175493_co()
|
||||
// {
|
||||
// ++this.field_175494_bm;
|
||||
// }
|
||||
|
||||
public int getColor() {
|
||||
return 0x00ff00;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityHuman.class;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityUndead.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return rand.range(1, 2);
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(8, 14);
|
||||
}
|
||||
|
||||
// public float getHeightDeviation(Random rand) {
|
||||
// return 0.0f;
|
||||
// }
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.EVIL, Alignment.CHAOTIC_EVIL);
|
||||
}
|
||||
|
||||
public boolean isGhost() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean getCanSpawnHere() {
|
||||
return !((WorldServer)this.worldObj).isDaytime();
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public float getArmRotation() {
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
public float getLegRotation() {
|
||||
return 0.2f;
|
||||
}
|
||||
}
|
192
java/src/game/entity/npc/EntityHoveringNPC.java
Executable file
192
java/src/game/entity/npc/EntityHoveringNPC.java
Executable file
|
@ -0,0 +1,192 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityHoveringNPC extends EntityNPC
|
||||
{
|
||||
private float heightOffset = 0.5F;
|
||||
private int heightOffsetUpdateTime;
|
||||
|
||||
public EntityHoveringNPC(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
// this.xpValue = 10;
|
||||
// this.tasks.addTask(4, new AISmallFireballAttack(this));
|
||||
// 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, EntityNPC.class, 8.0F));
|
||||
// this.tasks.addTask(8, new EntityAILookIdle(this));
|
||||
// this.targets.addTask(1, new EntityAIHurtByTarget(this, true));
|
||||
// this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityNPC.class, true));
|
||||
// this.targets.addTask(3, new EntityAINearestAttackableTarget(this, EntityNPC.class, true));
|
||||
}
|
||||
|
||||
// public boolean isImmuneToFire()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.FOLLOW_RANGE).setBaseValue(32.0D);
|
||||
}
|
||||
|
||||
// protected void entityInit()
|
||||
// {
|
||||
// super.entityInit();
|
||||
// this.dataWatcher.addObject(16, new Byte((byte)0));
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 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";
|
||||
// }
|
||||
//
|
||||
// public int getBrightnessForRender(float partialTicks)
|
||||
// {
|
||||
// return 15728880;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gets how bright this entity is.
|
||||
// */
|
||||
// public float getBrightness(float partialTicks)
|
||||
// {
|
||||
// return 1.0F;
|
||||
// }
|
||||
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
if (!this.onGround && this.motionY < 0.0D)
|
||||
{
|
||||
this.motionY *= 0.6D;
|
||||
}
|
||||
|
||||
// if (this.worldObj.client)
|
||||
// {
|
||||
// if (this.rand.chance(24) && !this.isSilent())
|
||||
// {
|
||||
// ((WorldClient)this.worldObj).playSound(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "random.fire", 1.0F + this.rand.floatv(), this.rand.floatv() * 0.7F + 0.3F);
|
||||
// }
|
||||
//
|
||||
// for (int i = 0; i < 2; ++i)
|
||||
// {
|
||||
// this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + (this.rand.doublev() - 0.5D) * (double)this.width, this.posY + this.rand.doublev() * (double)this.height, this.posZ + (this.rand.doublev() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D);
|
||||
// }
|
||||
// }
|
||||
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
protected void updateAITasks()
|
||||
{
|
||||
// if (Config.blazeWaterDamage && this.isWet())
|
||||
// {
|
||||
// this.attackEntityFrom(DamageSource.drown, 1);
|
||||
// }
|
||||
|
||||
--this.heightOffsetUpdateTime;
|
||||
|
||||
if (this.heightOffsetUpdateTime <= 0)
|
||||
{
|
||||
this.heightOffsetUpdateTime = 100;
|
||||
this.heightOffset = 0.5F + (float)this.rand.gaussian() * 3.0F;
|
||||
}
|
||||
|
||||
EntityLiving entitylivingbase = this.getAttackTarget();
|
||||
|
||||
if (entitylivingbase != null && entitylivingbase.posY + (double)entitylivingbase.getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset)
|
||||
{
|
||||
this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D;
|
||||
this.isAirBorne = true;
|
||||
}
|
||||
|
||||
super.updateAITasks();
|
||||
}
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
}
|
||||
|
||||
// protected Item getDropItem()
|
||||
// {
|
||||
// return Items.blaze_rod;
|
||||
// }
|
||||
|
||||
// public boolean isBurning()
|
||||
// {
|
||||
// return this.func_70845_n();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 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)
|
||||
// {
|
||||
// if (wasRecentlyHit)
|
||||
// {
|
||||
// int i = this.rand.zrange(2 + lootingModifier);
|
||||
//
|
||||
// for (int j = 0; j < i; ++j)
|
||||
// {
|
||||
// this.dropItem(Items.blaze_rod, 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// public boolean func_70845_n()
|
||||
// {
|
||||
// return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
|
||||
// }
|
||||
//
|
||||
// public void setOnFire(boolean onFire)
|
||||
// {
|
||||
// byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
//
|
||||
// if (onFire)
|
||||
// {
|
||||
// b0 = (byte)(b0 | 1);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// b0 = (byte)(b0 & -2);
|
||||
// }
|
||||
//
|
||||
// this.dataWatcher.updateObject(16, Byte.valueOf(b0));
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Checks to make sure the light is not too bright where the mob is spawning
|
||||
// */
|
||||
// protected boolean isValidLightLevel()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
}
|
129
java/src/game/entity/npc/EntityHuman.java
Executable file
129
java/src/game/entity/npc/EntityHuman.java
Executable file
|
@ -0,0 +1,129 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Items;
|
||||
import game.item.ItemStack;
|
||||
import game.properties.IStringSerializable;
|
||||
import game.rng.Random;
|
||||
import game.village.Village;
|
||||
import game.world.BlockPos;
|
||||
import game.world.World;
|
||||
import game.world.WorldServer;
|
||||
|
||||
public class EntityHuman extends EntityNPC {
|
||||
public static enum ClassType implements IStringSerializable {
|
||||
NONE("none", "???"),
|
||||
KNIGHT("knight", "Krieger"),
|
||||
PEASANT("peasant", "Bauer"),
|
||||
MAGE("mage", "Magier"),
|
||||
SORCERER("sorcerer", "Hexer"),
|
||||
HEALER("healer", "Heiler"),
|
||||
BARD("bard", "Barde"),
|
||||
LEADER("leader", "Anführer"),
|
||||
CAPTAIN("captain", "Kapitän"),
|
||||
HUNTER("hunter", "Jäger");
|
||||
|
||||
private final String name;
|
||||
private final String display;
|
||||
|
||||
private ClassType(String name, String display) {
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.display;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Alignment[] ALIGNMENTS = new Alignment[] {
|
||||
Alignment.LAWFUL_GOOD, Alignment.GOOD, Alignment.CHAOTIC_GOOD, Alignment.LAWFUL, Alignment.CHAOTIC, Alignment.LAWFUL_EVIL,
|
||||
Alignment.EVIL, Alignment.CHAOTIC_EVIL
|
||||
};
|
||||
|
||||
private Village village;
|
||||
private int checkTimer;
|
||||
|
||||
public EntityHuman(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return this.alignment.evil && !this.alignment.lawful;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return this.alignment.good && !this.alignment.chaotic;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return this.alignment.evil && !this.alignment.lawful;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return this.alignment == Alignment.LAWFUL_GOOD;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return this.alignment != Alignment.LAWFUL_GOOD;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return this.alignment == Alignment.CHAOTIC_EVIL;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return rand.range(0, 1);
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(18, 20);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(ALIGNMENTS);
|
||||
}
|
||||
|
||||
public boolean isBreedingItem(ItemStack stack) {
|
||||
return stack.getItem() == Items.golden_apple && stack.getMetadata() == 0;
|
||||
}
|
||||
|
||||
protected void updateAITasks() {
|
||||
if(--this.checkTimer <= 0) {
|
||||
BlockPos blockpos = new BlockPos(this);
|
||||
// if(((WorldServer)this.worldObj).isPrimary())
|
||||
((WorldServer)this.worldObj).addToVillagerPositionList(blockpos);
|
||||
this.checkTimer = this.rand.excl(70, 120);
|
||||
this.village = ((WorldServer)this.worldObj).getNearestVillage(blockpos, 32);
|
||||
|
||||
if(this.village == null) {
|
||||
this.detachHome();
|
||||
}
|
||||
else {
|
||||
BlockPos blockpos1 = this.village.getCenter();
|
||||
this.setHomePosAndDistance(blockpos1, (int)((float)this.village.getRadius() * 1.0F));
|
||||
}
|
||||
}
|
||||
super.updateAITasks();
|
||||
}
|
||||
|
||||
public boolean canTrade() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canAmbush(EntityLiving entity) {
|
||||
return (float)this.getHealth() >= ((float)this.getMaxHealth() / 2.5f);
|
||||
}
|
||||
}
|
162
java/src/game/entity/npc/EntityMage.java
Executable file
162
java/src/game/entity/npc/EntityMage.java
Executable file
|
@ -0,0 +1,162 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.entity.attributes.AttributeInstance;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.effect.EntityLightning;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Items;
|
||||
import game.item.ItemStack;
|
||||
import game.potion.Potion;
|
||||
import game.potion.PotionEffect;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityMage extends EntityNPC
|
||||
{
|
||||
private int attackTimer;
|
||||
private boolean drinking;
|
||||
|
||||
public EntityMage(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isRangedWeapon(ItemStack stack) {
|
||||
// return stack != null && stack.getItem() == Items.potion;
|
||||
// }
|
||||
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
if (this.drinking)
|
||||
{
|
||||
if (this.attackTimer-- <= 0)
|
||||
{
|
||||
this.drinking = false;
|
||||
ItemStack itemstack = this.getHeldItem();
|
||||
this.setItem(0, null);
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == Items.potion)
|
||||
{
|
||||
List<PotionEffect> list = Items.potion.getEffects(itemstack);
|
||||
|
||||
if (list != null)
|
||||
{
|
||||
for (PotionEffect potioneffect : list)
|
||||
{
|
||||
this.addEffect(new PotionEffect(potioneffect));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).removeModifier(Attributes.MAGE_POTSPEED_MOD);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
// if (this.rand.floatv() < 0.15F && this.isInsideOfLiquid() && !this.hasEffect(Potion.waterBreathing))
|
||||
// {
|
||||
// i = 8237;
|
||||
// }
|
||||
// else
|
||||
if (this.rand.floatv() < 0.15F && this.isBurning() && !this.hasEffect(Potion.fireResistance))
|
||||
{
|
||||
i = 16307;
|
||||
}
|
||||
else if (this.rand.floatv() < 0.05F && this.getHealth() < this.getMaxHealth())
|
||||
{
|
||||
i = 16341;
|
||||
}
|
||||
else if (this.rand.floatv() < 0.25F && this.getAttackTarget() != null && !this.hasEffect(Potion.moveSpeed) && this.getAttackTarget().getDistanceSqToEntity(this) > 121.0D)
|
||||
{
|
||||
i = 16274;
|
||||
}
|
||||
else if (this.rand.floatv() < 0.25F && this.getAttackTarget() != null && !this.hasEffect(Potion.moveSpeed) && this.getAttackTarget().getDistanceSqToEntity(this) > 121.0D)
|
||||
{
|
||||
i = 16274;
|
||||
}
|
||||
|
||||
if (i > -1)
|
||||
{
|
||||
this.setItem(0, new ItemStack(Items.potion, 1, i));
|
||||
this.attackTimer = this.getHeldItem().getMaxItemUseDuration();
|
||||
this.drinking = true;
|
||||
AttributeInstance iattributeinstance = this.getEntityAttribute(Attributes.MOVEMENT_SPEED);
|
||||
iattributeinstance.removeModifier(Attributes.MAGE_POTSPEED_MOD);
|
||||
iattributeinstance.applyModifier(Attributes.MAGE_POTSPEED_MOD);
|
||||
}
|
||||
else if(this.rand.chance(80)) {
|
||||
boolean far = this.getAttackTarget() != null && this.getAttackTarget().getDistanceSqToEntity(this) >= 256.0;
|
||||
this.setItem(0, far || this.rand.chance() ? new ItemStack(Items.potion, 1, 16384) : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
public void attackEntityWithRangedAttack(EntityLiving target, float range) {
|
||||
if(!this.drinking)
|
||||
super.attackEntityWithRangedAttack(target, range);
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x9b58c8;
|
||||
}
|
||||
|
||||
public void onStruckByLightning(EntityLightning lightningBolt) {
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityElf.class;
|
||||
}
|
||||
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(26, 66);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.EVIL, Alignment.CHAOTIC_EVIL);
|
||||
}
|
||||
}
|
175
java/src/game/entity/npc/EntityMagma.java
Executable file
175
java/src/game/entity/npc/EntityMagma.java
Executable file
|
@ -0,0 +1,175 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityMagma extends EntitySlime
|
||||
{
|
||||
public EntityMagma(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
// this.fireImmune = true;
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// protected void applyEntityAttributes()
|
||||
// {
|
||||
// super.applyEntityAttributes();
|
||||
// this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.20000000298023224D);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Checks if the entity's current position is a valid location to spawn this entity.
|
||||
*/
|
||||
public boolean getCanSpawnHere()
|
||||
{
|
||||
return true; // this.worldObj.getDifficulty() != Difficulty.PEACEFUL;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Checks that the entity is not colliding with any blocks / liquids
|
||||
// */
|
||||
// public boolean isNotColliding()
|
||||
// {
|
||||
// return this.worldObj.checkNoEntityCollision(this.getEntityBoundingBox(), this) && this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty() && !this.worldObj.isAnyLiquid(this.getEntityBoundingBox());
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
|
||||
// */
|
||||
// public int getTotalArmorValue()
|
||||
// {
|
||||
// return this.getSlimeSize() * 3;
|
||||
// }
|
||||
|
||||
// public int getBrightnessForRender(float partialTicks)
|
||||
// {
|
||||
// return 15728880;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gets how bright this entity is.
|
||||
// */
|
||||
// public float getBrightness(float partialTicks)
|
||||
// {
|
||||
// return 1.0F;
|
||||
// }
|
||||
|
||||
protected ParticleType getParticleType()
|
||||
{
|
||||
return ParticleType.FLAME;
|
||||
}
|
||||
|
||||
protected EntitySlime createInstance()
|
||||
{
|
||||
return new EntityMagma(this.worldObj);
|
||||
}
|
||||
|
||||
// protected Item getDropItem()
|
||||
// {
|
||||
// return Items.magma_cream;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 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)
|
||||
// {
|
||||
// Item item = this.getDropItem();
|
||||
//
|
||||
// if (item != null && this.getSlimeSize() > 1)
|
||||
// {
|
||||
// int i = this.rand.range(-2, 1);
|
||||
//
|
||||
// if (lootingModifier > 0)
|
||||
// {
|
||||
// i += this.rand.zrange(lootingModifier + 1);
|
||||
// }
|
||||
//
|
||||
// for (int j = 0; j < i; ++j)
|
||||
// {
|
||||
// this.dropItem(item, 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
|
||||
// */
|
||||
// public boolean isBurning()
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Gets the amount of time the slime needs to wait between jumps.
|
||||
// */
|
||||
// protected int getJumpDelay()
|
||||
// {
|
||||
// return super.getJumpDelay() * 4;
|
||||
// }
|
||||
|
||||
// protected void alterSquishAmount()
|
||||
// {
|
||||
// this.squishAmount *= 0.9F;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Causes this entity to do an upwards motion (jumping).
|
||||
// */
|
||||
// protected void jump()
|
||||
// {
|
||||
// this.motionY = 0.67;
|
||||
// this.isAirBorne = true;
|
||||
// }
|
||||
|
||||
protected void handleJumpLava()
|
||||
{
|
||||
this.motionY = 0.345;
|
||||
this.isAirBorne = true;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Indicates weather the slime is able to damage the player (based upon the slime's size)
|
||||
// */
|
||||
// public boolean canDamagePlayer()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Gets the amount of damage dealt to the player when "attacked" by the slime.
|
||||
// */
|
||||
// protected int getAttackStrength()
|
||||
// {
|
||||
// return super.getAttackStrength() + 2;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns the name of the sound played when the slime jumps.
|
||||
// */
|
||||
// protected String getJumpSound()
|
||||
// {
|
||||
// return this.getSlimeSize() > 1 ? "mob.magmacube.big" : "mob.magmacube.small";
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns true if the slime makes a sound when it lands after a jump (based upon the slime's size)
|
||||
// */
|
||||
// protected boolean makesSoundOnLand()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public int getColor() {
|
||||
return 0xee9300;
|
||||
}
|
||||
}
|
65
java/src/game/entity/npc/EntityMetalhead.java
Executable file
65
java/src/game/entity/npc/EntityMetalhead.java
Executable file
|
@ -0,0 +1,65 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.item.ItemMetal;
|
||||
import game.item.ItemStack;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityMetalhead extends EntityNPC {
|
||||
public EntityMetalhead(World worldIn) {
|
||||
super(worldIn);
|
||||
// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.gunpowder, false));
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(20, 24);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.values());
|
||||
}
|
||||
|
||||
public boolean isBreedingItem(ItemStack stack) {
|
||||
return stack.getItem() instanceof ItemMetal;
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return true;
|
||||
}
|
||||
}
|
317
java/src/game/entity/npc/EntityMobNPC.java
Executable file
317
java/src/game/entity/npc/EntityMobNPC.java
Executable file
|
@ -0,0 +1,317 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.EntityAIHurtByTarget;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.attributes.AttributeInstance;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityMobNPC extends EntityNPC
|
||||
{
|
||||
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.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.becomeAngryAt(entity);
|
||||
}
|
||||
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 apply(EntityLiving entity) {
|
||||
// return entity.isPlayer(); // || entity instanceof EntityNPC;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// public boolean shouldExecute()
|
||||
// {
|
||||
// return ((EntityMobNPC)this.taskOwner).isAngry() && super.shouldExecute();
|
||||
// }
|
||||
// }
|
||||
}
|
4636
java/src/game/entity/npc/EntityNPC.java
Executable file
4636
java/src/game/entity/npc/EntityNPC.java
Executable file
File diff suppressed because it is too large
Load diff
69
java/src/game/entity/npc/EntityOrc.java
Executable file
69
java/src/game/entity/npc/EntityOrc.java
Executable file
|
@ -0,0 +1,69 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityOrc extends EntityNPC {
|
||||
public EntityOrc(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityHuman.class || clazz == EntityElf.class || clazz == EntityWoodElf.class || clazz == EntityBloodElf.class
|
||||
|| clazz == EntityCultivator.class || clazz == EntityMage.class;
|
||||
}
|
||||
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(22, 48);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.1f, 0.3f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.CHAOTIC_EVIL, Alignment.EVIL);
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x009400;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(4.0D);
|
||||
}
|
||||
}
|
175
java/src/game/entity/npc/EntityPrimarch.java
Executable file
175
java/src/game/entity/npc/EntityPrimarch.java
Executable file
|
@ -0,0 +1,175 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.collect.Lists;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.properties.IStringSerializable;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityPrimarch extends EntityMobNPC {
|
||||
public static enum Founding implements IStringSerializable {
|
||||
OTHER("other", 0, 0x000000, 0x000000),
|
||||
DARK_ANGELS("darkangel", "Dark Angels", 1, 0xaf0000, 0x400000, "Lion El'Jonson:lion_el_jonson", 2.65f, 850, Alignment.GOOD),
|
||||
UNKNOWN_A("unkna", 2, 0xaf0000, 0x400000),
|
||||
EMPERORS_CHILDREN("emperorchild", "Emperors Children", 3, 0xaf0000, 0x400000, "Fulgrim", 2.65f, 1250, Alignment.NEUTRAL),
|
||||
IRON_WARRIORS("ironwarrior", "Iron Warriors", 4, 0xaf0000, 0x400000, "Perturabo", 2.65f, 450, Alignment.NEUTRAL),
|
||||
WHITE_SCARS("whitescar", "White Scars", 5, 0xaf0000, 0x400000, "Jaghatai Khan", 2.65f, 850, Alignment.NEUTRAL),
|
||||
SPACE_WOLVES("spacewolf", "Space Wolves", 6, 0xaf0000, 0x400000, "Leman Russ", 2.65f, 850, Alignment.NEUTRAL),
|
||||
IMPERIAL_FISTS("imperialfist", "Imperial Fists", 7, 0xaf0000, 0x400000, "Rogal Dorn", 2.65f, 850, Alignment.NEUTRAL),
|
||||
NIGHT_LORDS("nightlord", "Night Lords", 8, 0xaf0000, 0x400000, "Konrad Curze", 2.65f, 850, Alignment.NEUTRAL),
|
||||
BLOOD_ANGELS("bloodangel", "Blood Angels", 9, 0xaf0000, 0x400000, "Sanguinius", 2.65f, 850, Alignment.CHAOTIC_GOOD),
|
||||
IRON_HANDS("ironhand", "Iron Hands", 10, 0xaf0000, 0x400000, "Ferrus Manus", 2.65f, 850, Alignment.NEUTRAL),
|
||||
UNKNOWN_B("unknb", 11, 0xaf0000, 0x400000),
|
||||
WORLD_EATERS("worldeater", "World Eaters", 12, 0xaf0000, 0x400000, "Angron", 2.65f, 850, Alignment.NEUTRAL),
|
||||
ULTRAMARINES("ultramarine", "Ultramarines", 13, 0xaf0000, 0x400000, "Roboute Guilliman", 2.65f, 850, Alignment.NEUTRAL),
|
||||
DEATH_GUARD("deathguard", "Death Guard", 14, 0xaf0000, 0x400000, "Mortarion", 2.65f, 850, Alignment.NEUTRAL),
|
||||
THOUSAND_SONS("thousandson", "Thousand Sons", 15, 0xaf0000, 0x400000, "Magnus the Red", 2.65f, 850, Alignment.NEUTRAL),
|
||||
LUNA_WOLVES("lunawolf", "Luna Wolves", 16, 0xaf0000, 0x400000, "Horus Lupercal", 2.65f, 850, Alignment.NEUTRAL),
|
||||
WORD_BEARERS("wordbearer", "Word Bearers", 17, 0xaf0000, 0x400000, "Lorgar Aurelian", 2.65f, 850, Alignment.NEUTRAL),
|
||||
SALAMANDERS("salamander", "Salamanders", 18, 0xaf0000, 0x400000, "Vulkan", 2.65f, 850, Alignment.NEUTRAL),
|
||||
RAVEN_GUARD("ravenguard", "Raven Guard", 19, 0xaf0000, 0x400000, "Corvus Corax", 2.65f, 850, Alignment.NEUTRAL),
|
||||
ALPHA_LEGION("alphalegion", "Alpha Legion", 20, 0xaf0000, 0x400000, "Alpharius Omegon", 2.65f, 850, Alignment.NEUTRAL);
|
||||
|
||||
public static final Object[] PRIMARCHS;
|
||||
|
||||
private final String name;
|
||||
private final String display;
|
||||
public final int numeral;
|
||||
public final int color1;
|
||||
public final int color2;
|
||||
public final float size;
|
||||
public final int health;
|
||||
public final Alignment align;
|
||||
public final String primarch;
|
||||
|
||||
static {
|
||||
List<Object> primarchs = Lists.newArrayList();
|
||||
for(Founding founding : values()) {
|
||||
if(founding.primarch != null) {
|
||||
primarchs.add(founding);
|
||||
primarchs.add(founding.primarch);
|
||||
primarchs.add(founding.color1);
|
||||
primarchs.add(founding.color2);
|
||||
}
|
||||
}
|
||||
PRIMARCHS = primarchs.toArray(new Object[primarchs.size()]);
|
||||
primarchs.clear();
|
||||
}
|
||||
|
||||
private Founding(String name, int num, int color1, int color2) {
|
||||
this(name, "???", num, color1, color2, null, 2.65f, 850, Alignment.NEUTRAL);
|
||||
}
|
||||
|
||||
private Founding(String name, String display, int num, int color1, int color2, String primarch, float psize, int phealth,
|
||||
Alignment palign) {
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
this.numeral = num;
|
||||
this.color1 = color1;
|
||||
this.color2 = color2;
|
||||
this.primarch = primarch;
|
||||
this.size = psize;
|
||||
this.health = phealth;
|
||||
this.align = palign;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.display;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityPrimarch(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return this.getFounding().health; // rand.range(450, 1250);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getBaseSize(Random rand) {
|
||||
return this.getFounding().size / this.species.size;
|
||||
}
|
||||
|
||||
// public float getHeightDeviation(Random rand) {
|
||||
// return 0.0f; // rand.frange(0.0f, 0.5f);
|
||||
// }
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return this.getFounding().align;
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xff9494;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(20.0D);
|
||||
}
|
||||
|
||||
// public TextComponent getPrefix() {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public Founding getFounding() {
|
||||
Enum legion = this.getNpcClass();
|
||||
return legion == null ? Founding.OTHER : (Founding)legion;
|
||||
}
|
||||
|
||||
public Object onInitialSpawn(Object livingdata) {
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
this.setMaxHealth(this.getFounding().health);
|
||||
this.setHealth(this.getMaxHealth());
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return true;
|
||||
}
|
||||
}
|
681
java/src/game/entity/npc/EntitySlime.java
Executable file
681
java/src/game/entity/npc/EntitySlime.java
Executable file
|
@ -0,0 +1,681 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIBase;
|
||||
import game.ai.EntityMoveHelper;
|
||||
import game.biome.Biome;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Config;
|
||||
import game.init.SoundEvent;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.pathfinding.PathNavigateGround;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.rng.Random;
|
||||
import game.world.BlockPos;
|
||||
import game.world.Chunk;
|
||||
import game.world.World;
|
||||
import game.world.WorldServer;
|
||||
|
||||
public class EntitySlime extends EntityNPC
|
||||
{
|
||||
public float squishAmount;
|
||||
public float squishFactor;
|
||||
public float prevSquishFactor;
|
||||
private boolean wasOnGround;
|
||||
private double jumpHeight;
|
||||
|
||||
public EntitySlime(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
// this.setSize(1.0f, 1.0f);
|
||||
this.moveHelper = new EntitySlime.SlimeMoveHelper(this);
|
||||
this.tasks.addTask(1, new EntitySlime.AISlimeFloat(this));
|
||||
this.tasks.addTask(2, new EntitySlime.AISlimeAttack(this));
|
||||
this.tasks.addTask(3, new EntitySlime.AISlimeFaceRandom(this));
|
||||
this.tasks.addTask(5, new EntitySlime.AISlimeHop(this));
|
||||
// this.targets.addTask(1, new EntityAIFindEntityNearestPlayer(this));
|
||||
//// this.targets.addTask(3, new EntityAIFindEntityNearest(this, EntityIronGolem.class));
|
||||
// this.targets.addTask(3, new EntityAIFindEntityNearest(this, EntityNPC.class));
|
||||
this.noPickup = true;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(6, 7);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.7f, 3.0f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.LAWFUL_EVIL, Alignment.EVIL);
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// protected void entityInit()
|
||||
// {
|
||||
// super.entityInit();
|
||||
// this.dataWatcher.addObject(16, Byte.valueOf((byte)1));
|
||||
// }
|
||||
|
||||
// protected void setSlimeSize(int size)
|
||||
// {
|
||||
// this.dataWatcher.updateObject(16, Byte.valueOf((byte)size));
|
||||
// this.setSize(0.51000005F * (float)size, 0.51000005F * (float)size);
|
||||
// this.setPosition(this.posX, this.posY, this.posZ);
|
||||
// this.setMaxHealth(size * size);
|
||||
// this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue((double)(0.2F + 0.1F * (float)size));
|
||||
// this.setHealth(this.getMaxHealth());
|
||||
// this.xpValue = size;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns the size of the slime.
|
||||
// */
|
||||
// public int getSlimeSize()
|
||||
// {
|
||||
// return this.dataWatcher.getWatchableObjectByte(16);
|
||||
// }
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
// tagCompound.setInteger("Size", this.getSlimeSize() - 1);
|
||||
tagCompound.setBoolean("wasOnGround", this.wasOnGround);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
// int i = tagCompund.getInteger("Size");
|
||||
//
|
||||
// if (i < 0)
|
||||
// {
|
||||
// i = 0;
|
||||
// }
|
||||
//
|
||||
// this.setSlimeSize(i + 1);
|
||||
this.wasOnGround = tagCompund.getBoolean("wasOnGround");
|
||||
}
|
||||
|
||||
protected ParticleType getParticleType()
|
||||
{
|
||||
return ParticleType.SLIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
// if (!this.worldObj.client && this.worldObj.getDifficulty() == Difficulty.PEACEFUL && this.getSlimeSize() > 0)
|
||||
// {
|
||||
// this.dead = true;
|
||||
// }
|
||||
|
||||
this.squishFactor += (this.squishAmount - this.squishFactor) * 0.5F;
|
||||
this.prevSquishFactor = this.squishFactor;
|
||||
super.onUpdate();
|
||||
|
||||
if (this.onGround && !this.wasOnGround)
|
||||
{
|
||||
int i = (int)(this.width * 16.0f);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
float f = this.rand.floatv() * (float)Math.PI * 2.0F;
|
||||
float f1 = this.rand.floatv() * 0.5F + 0.5F;
|
||||
float f2 = ExtMath.sin(f) * this.width * f1;
|
||||
float f3 = ExtMath.cos(f) * this.width * f1;
|
||||
World world = this.worldObj;
|
||||
ParticleType enumparticletypes = this.getParticleType();
|
||||
double d0 = this.posX + (double)f2;
|
||||
double d1 = this.posZ + (double)f3;
|
||||
world.spawnParticle(enumparticletypes, d0, this.getEntityBoundingBox().minY, d1, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
|
||||
// if (!this.isChild())
|
||||
// {
|
||||
this.playSound(this.jumpHeight < 0.5 ? SoundEvent.SLIME_SMALL : SoundEvent.SLIME_BIG, this.getSoundVolume(), ((this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F) / 0.8F);
|
||||
// }
|
||||
this.jumpHeight = 0.0;
|
||||
|
||||
this.squishAmount = -0.5F;
|
||||
}
|
||||
else if (!this.onGround && this.wasOnGround)
|
||||
{
|
||||
this.squishAmount = 1.0F;
|
||||
}
|
||||
|
||||
this.wasOnGround = this.onGround;
|
||||
this.squishAmount *= 0.6F;
|
||||
}
|
||||
|
||||
// protected void alterSquishAmount()
|
||||
// {
|
||||
// this.squishAmount *= 0.6F;
|
||||
// }
|
||||
|
||||
public void fall(float distance, float damageMultiplier)
|
||||
{
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Gets the amount of time the slime needs to wait between jumps.
|
||||
// */
|
||||
// protected int getJumpDelay()
|
||||
// {
|
||||
// return this.rand.excl(10, 30);
|
||||
// }
|
||||
|
||||
protected EntitySlime createInstance()
|
||||
{
|
||||
return new EntitySlime(this.worldObj);
|
||||
}
|
||||
|
||||
// public void onDataWatcherUpdate(int dataID)
|
||||
// {
|
||||
// if (dataID == 16)
|
||||
// {
|
||||
// int i = this.getSlimeSize();
|
||||
// this.setSize(0.51000005F * (float)i, 0.51000005F * (float)i);
|
||||
// this.rotYaw = this.headYaw;
|
||||
// this.yawOffset = this.headYaw;
|
||||
//
|
||||
// if (this.isInLiquid() && this.rand.chance(20))
|
||||
// {
|
||||
// this.onEnterLiquid();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// super.onDataWatcherUpdate(dataID);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Will get destroyed next tick.
|
||||
*/
|
||||
public void setDead()
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
if (!this.worldObj.client && this.getHeight() >= 0.5f && this.getHealth() <= 0 && Config.mobs && Config.spawnSplitSlime)
|
||||
{
|
||||
int j = this.rand.range(2, 4);
|
||||
float size = this.getHeight() / 2.0f;
|
||||
|
||||
for (int k = 0; k < j; ++k)
|
||||
{
|
||||
float f = ((float)(k % 2) - 0.5F) * (float)i / 4.0F;
|
||||
float f1 = ((float)(k / 2) - 0.5F) * (float)i / 4.0F;
|
||||
EntitySlime entityslime = this.createInstance();
|
||||
|
||||
if (this.hasCustomName())
|
||||
{
|
||||
entityslime.setCustomNameTag(this.getCustomNameTag());
|
||||
}
|
||||
|
||||
// if (this.isNotDespawning())
|
||||
// {
|
||||
// entityslime.disableDespawn();
|
||||
// }
|
||||
|
||||
entityslime.setLocationAndAngles(this.posX + (double)f, this.posY + 0.5D, this.posZ + (double)f1, this.rand.floatv() * 360.0F, 0.0F);
|
||||
entityslime.onInitialSpawn(null);
|
||||
entityslime.setHeight(this.rand.frange(size * 0.8f, size * 1.2f));
|
||||
entityslime.setMaxHealth(Math.max(1, (int)((float)this.getMaxHealth() / this.getHeight() * entityslime.getHeight())));
|
||||
entityslime.setHealth(entityslime.getMaxHealth());
|
||||
entityslime.setGrowingAge(this.getGrowingAge());
|
||||
this.worldObj.spawnEntityInWorld(entityslime);
|
||||
}
|
||||
}
|
||||
|
||||
super.setDead();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a velocity to each of the entities pushing them away from each other. Args: entity
|
||||
*/
|
||||
public void applyEntityCollision(Entity entityIn)
|
||||
{
|
||||
super.applyEntityCollision(entityIn);
|
||||
|
||||
if (entityIn instanceof EntityNPC && !(entityIn.isPlayer())) // && this.canDamagePlayer())
|
||||
{
|
||||
this.damageEntity((EntityLiving)entityIn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by a player entity when they collide with an entity
|
||||
*/
|
||||
public void onCollideWithPlayer(EntityNPC entityIn)
|
||||
{
|
||||
// if (this.canDamagePlayer())
|
||||
// {
|
||||
this.damageEntity(entityIn);
|
||||
// }
|
||||
}
|
||||
|
||||
protected void damageEntity(EntityLiving p_175451_1_)
|
||||
{
|
||||
double i = this.width * 2.0f;
|
||||
|
||||
if ((this.worldObj.client || Config.damageMobs) && this.canEntityBeSeen(p_175451_1_)
|
||||
&& this.getDistanceSqToEntity(p_175451_1_) < 0.6D * i * 0.6D * i
|
||||
&& this.canAttack(p_175451_1_) && p_175451_1_.attackEntityFrom(DamageSource.causeMobDamage(this), this.rand.range(1, 3)))
|
||||
{
|
||||
this.playSound(SoundEvent.SLIME_ATTACK, 1.0F, (this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F);
|
||||
this.applyEnchantments(this, p_175451_1_);
|
||||
}
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return 0.625F * this.height;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Indicates weather the slime is able to damage the player (based upon the slime's size)
|
||||
// */
|
||||
// public boolean canDamagePlayer()
|
||||
// {
|
||||
// return this.getSlimeSize() > 1;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Gets the amount of damage dealt to the player when "attacked" by the slime.
|
||||
// */
|
||||
// protected int getAttackStrength()
|
||||
// {
|
||||
// return this.getSlimeSize();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns the sound this mob makes when it is hurt.
|
||||
// */
|
||||
// protected String getHurtSound()
|
||||
// {
|
||||
// return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the sound this mob makes on death.
|
||||
// */
|
||||
// protected String getDeathSound()
|
||||
// {
|
||||
// return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small");
|
||||
// }
|
||||
//
|
||||
// protected Item getDropItem()
|
||||
// {
|
||||
// return this.getSlimeSize() == 1 ? Items.slime_ball : null;
|
||||
// }
|
||||
|
||||
|
||||
public static Random getRandomWithSeed(WorldServer world, int xPosition, int zPosition, long seed)
|
||||
{
|
||||
return new Random(world.getSeed() +
|
||||
(long)(xPosition * xPosition * 4987142) + (long)(xPosition * 5947611) +
|
||||
(long)(zPosition * zPosition) * 4392871L + (long)(zPosition * 389711) ^ seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity's current position is a valid location to spawn this entity.
|
||||
*/
|
||||
public boolean getCanSpawnHere()
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(ExtMath.floord(this.posX), 0, ExtMath.floord(this.posZ));
|
||||
Chunk chunk = this.worldObj.getChunk(blockpos);
|
||||
|
||||
// if (this.worldObj.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (this.worldObj.getDifficulty() != Difficulty.PEACEFUL)
|
||||
// {
|
||||
Biome biomegenbase = this.worldObj.getBiomeGenForCoords(blockpos);
|
||||
|
||||
if (biomegenbase == Biome.swampland && this.posY > 50.0D && this.posY < 70.0D && this.rand.floatv() < 0.5F && this.rand.floatv() < this.worldObj.getCurrentMoonPhaseFactor() && this.worldObj.getLightFromNeighbors(new BlockPos(this)) <= this.rand.zrange(8))
|
||||
{
|
||||
return super.getCanSpawnHere();
|
||||
}
|
||||
|
||||
if (this.rand.zrange(10) == 0 && getRandomWithSeed((WorldServer)this.worldObj, chunk.xPos, chunk.zPos, 987234911L).zrange(10) == 0 && this.posY < 40.0D)
|
||||
{
|
||||
return super.getCanSpawnHere();
|
||||
}
|
||||
// }
|
||||
|
||||
return false;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume for the sounds this mob makes.
|
||||
*/
|
||||
protected float getSoundVolume()
|
||||
{
|
||||
return 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 0;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns true if the slime makes a sound when it jumps (based upon the slime's size)
|
||||
// */
|
||||
// protected boolean makesSoundOnJump()
|
||||
// {
|
||||
// return this.getSlimeSize() > 0;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns true if the slime makes a sound when it lands after a jump (based upon the slime's size)
|
||||
// */
|
||||
// protected boolean makesSoundOnLand()
|
||||
// {
|
||||
// return this.getSlimeSize() > 2;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Causes this entity to do an upwards motion (jumping).
|
||||
*/
|
||||
public void jump()
|
||||
{
|
||||
if(this.jumpHeight == 0.0)
|
||||
this.motionY = this.jumpHeight = this.getJumpMovement();
|
||||
else
|
||||
this.motionY = this.jumpHeight;
|
||||
this.isAirBorne = true;
|
||||
}
|
||||
|
||||
protected double getJumpMovement() {
|
||||
return ExtMath.clampd(this.rand.drange(0.3, 0.8) * this.height, 0.2, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Object onInitialSpawn(Object livingdata)
|
||||
{
|
||||
// if(this.rand.chance(5))
|
||||
// this.setGrowingAge(-24000);
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
this.setMaxHealth(Math.max(1, (int)((float)this.getMaxHealth() * this.getHeight())));
|
||||
this.setHealth(this.getMaxHealth());
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
// public int getTrackingRange() {
|
||||
// return 80;
|
||||
// }
|
||||
//
|
||||
// public int getUpdateFrequency() {
|
||||
// return 3;
|
||||
// }
|
||||
//
|
||||
// public boolean isSendingVeloUpdates() {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public boolean isSneakingVisually() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// public float getRenderScale()
|
||||
// {
|
||||
// return 2.0f * this.height;
|
||||
// }
|
||||
|
||||
public int getColor() {
|
||||
return 0x6dbf40;
|
||||
}
|
||||
|
||||
public boolean canPlay() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// public boolean allowLeashing() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
static class AISlimeAttack extends EntityAIBase
|
||||
{
|
||||
private EntitySlime slime;
|
||||
private int attackTimer;
|
||||
|
||||
public AISlimeAttack(EntitySlime slimeIn)
|
||||
{
|
||||
this.slime = slimeIn;
|
||||
this.setMutexBits(2);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.slime.getAttackTarget();
|
||||
return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : Config.mobAttacks);
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
this.attackTimer = 300;
|
||||
super.startExecuting();
|
||||
}
|
||||
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.slime.getAttackTarget();
|
||||
return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!Config.mobAttacks ? false : --this.attackTimer > 0));
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
this.slime.faceEntity(this.slime.getAttackTarget(), 10.0F, 10.0F);
|
||||
((EntitySlime.SlimeMoveHelper)this.slime.getMoveHelper()).setYawAccel(this.slime.rotYaw, true); // this.slime.canDamagePlayer());
|
||||
}
|
||||
}
|
||||
|
||||
static class AISlimeFaceRandom extends EntityAIBase
|
||||
{
|
||||
private EntitySlime slime;
|
||||
private float destYaw;
|
||||
private int faceTimer;
|
||||
|
||||
public AISlimeFaceRandom(EntitySlime slimeIn)
|
||||
{
|
||||
this.slime = slimeIn;
|
||||
this.setMutexBits(2);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.slime.getAttackTarget() == null && (this.slime.onGround || this.slime.isInLiquid() || this.slime.isInMolten());
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
if (--this.faceTimer <= 0)
|
||||
{
|
||||
this.faceTimer = this.slime.getRNG().excl(40, 100);
|
||||
this.destYaw = (float)this.slime.getRNG().zrange(360);
|
||||
}
|
||||
|
||||
((EntitySlime.SlimeMoveHelper)this.slime.getMoveHelper()).setYawAccel(this.destYaw, false);
|
||||
}
|
||||
}
|
||||
|
||||
static class AISlimeFloat extends EntityAIBase
|
||||
{
|
||||
private EntitySlime slime;
|
||||
|
||||
public AISlimeFloat(EntitySlime slimeIn)
|
||||
{
|
||||
this.slime = slimeIn;
|
||||
this.setMutexBits(5);
|
||||
((PathNavigateGround)slimeIn.getNavigator()).setCanSwim(true);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.slime.isInLiquid() || this.slime.isInMolten();
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.slime.getRNG().floatv() < 0.8F)
|
||||
{
|
||||
this.slime.getJumpHelper().setJumping();
|
||||
}
|
||||
|
||||
((EntitySlime.SlimeMoveHelper)this.slime.getMoveHelper()).setSpeed(1.2D);
|
||||
}
|
||||
}
|
||||
|
||||
static class AISlimeHop extends EntityAIBase
|
||||
{
|
||||
private EntitySlime slime;
|
||||
|
||||
public AISlimeHop(EntitySlime slimeIn)
|
||||
{
|
||||
this.slime = slimeIn;
|
||||
this.setMutexBits(5);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
((EntitySlime.SlimeMoveHelper)this.slime.getMoveHelper()).setSpeed(1.0D);
|
||||
}
|
||||
}
|
||||
|
||||
static class SlimeMoveHelper extends EntityMoveHelper
|
||||
{
|
||||
private float currentYaw;
|
||||
private int jumpDelay;
|
||||
private EntitySlime slime;
|
||||
private boolean accelerate;
|
||||
|
||||
public SlimeMoveHelper(EntitySlime slimeIn)
|
||||
{
|
||||
super(slimeIn);
|
||||
this.slime = slimeIn;
|
||||
}
|
||||
|
||||
public void setYawAccel(float yaw, boolean accel)
|
||||
{
|
||||
this.currentYaw = yaw;
|
||||
this.accelerate = accel;
|
||||
}
|
||||
|
||||
public void setSpeed(double speedIn)
|
||||
{
|
||||
this.speed = speedIn;
|
||||
this.update = true;
|
||||
}
|
||||
|
||||
public void onUpdateMoveHelper()
|
||||
{
|
||||
this.entity.rotYaw = this.limitAngle(this.entity.rotYaw, this.currentYaw, 30.0F);
|
||||
this.entity.headYaw = this.entity.rotYaw;
|
||||
this.entity.yawOffset = this.entity.rotYaw;
|
||||
|
||||
if (!this.update)
|
||||
{
|
||||
this.entity.setMoveForward(0.0F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.update = false;
|
||||
|
||||
if (this.entity.onGround)
|
||||
{
|
||||
this.entity.setAIMoveSpeed((float)(this.speed * this.entity.getEntityAttribute(Attributes.MOVEMENT_SPEED).getAttributeValue()));
|
||||
|
||||
if (this.jumpDelay-- <= 0)
|
||||
{
|
||||
this.jumpDelay = this.slime.rand.excl(10, 30);
|
||||
|
||||
if (this.accelerate)
|
||||
{
|
||||
this.jumpDelay /= 3;
|
||||
}
|
||||
|
||||
this.slime.getJumpHelper().setJumping();
|
||||
this.slime.jumpHeight = this.slime.getJumpMovement();
|
||||
|
||||
// if (!this.slime.isChild())
|
||||
// {
|
||||
this.slime.playSound(this.slime.jumpHeight < 0.5 ? SoundEvent.SLIME_SMALL : SoundEvent.SLIME_BIG, this.slime.getSoundVolume(), ((this.slime.getRNG().floatv() - this.slime.getRNG().floatv()) * 0.2F + 1.0F) * 0.8F);
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
this.slime.moveStrafe = this.slime.moveForward = 0.0F;
|
||||
this.entity.setAIMoveSpeed(0.0F);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entity.setAIMoveSpeed((float)(this.speed * this.entity.getEntityAttribute(Attributes.MOVEMENT_SPEED).getAttributeValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
java/src/game/entity/npc/EntitySpaceMarine.java
Executable file
117
java/src/game/entity/npc/EntitySpaceMarine.java
Executable file
|
@ -0,0 +1,117 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.collect.Lists;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.init.SpeciesRegistry;
|
||||
import game.properties.IStringSerializable;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntitySpaceMarine extends EntityNPC {
|
||||
public static enum Legion implements IStringSerializable {
|
||||
OTHER("other", "???", 0x000000, 0x000000, 2.15f, 200),
|
||||
BLACK_TEMPLARS("blacktemplar", "Black Templars", 0x101010, 0xc0c0c0, 2.43f, 300, "black_templar");
|
||||
|
||||
public static final Object[] MARINES;
|
||||
|
||||
private final String name;
|
||||
private final String display;
|
||||
public final int color1;
|
||||
public final int color2;
|
||||
public final float size;
|
||||
public final int health;
|
||||
public final String[] classes;
|
||||
|
||||
static {
|
||||
List<Object> marines = Lists.newArrayList();
|
||||
for(Legion legion : values()) {
|
||||
if(legion.classes.length > 0)
|
||||
marines.add(legion);
|
||||
for(String type : legion.classes) {
|
||||
marines.add(":marine_" + type);
|
||||
marines.add(legion.color1);
|
||||
marines.add(legion.color2);
|
||||
}
|
||||
}
|
||||
MARINES = marines.toArray(new Object[marines.size()]);
|
||||
marines.clear();
|
||||
}
|
||||
|
||||
private Legion(String name, String display, int color1, int color2, float size, int health, String ... classes) {
|
||||
this.name = name;
|
||||
this.display = display + " Einheit";
|
||||
this.color1 = color1;
|
||||
this.color2 = color2;
|
||||
this.size = size;
|
||||
this.health = health;
|
||||
this.classes = classes;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.display;
|
||||
}
|
||||
}
|
||||
|
||||
public EntitySpaceMarine(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public Legion getLegion() {
|
||||
Enum legion = this.getNpcClass();
|
||||
return legion == null ? Legion.OTHER : (Legion)legion;
|
||||
}
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return !"terra".equals(SpeciesRegistry.CLASSES.get(clazz).origin);
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return this.getLegion().health;
|
||||
}
|
||||
|
||||
public float getBaseSize(Random rand) {
|
||||
return this.getLegion().size / this.species.size;
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return Alignment.NEUTRAL;
|
||||
}
|
||||
|
||||
public Object onInitialSpawn(Object livingdata) {
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
this.setMaxHealth(this.getLegion().health);
|
||||
this.setHealth(this.getMaxHealth());
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isSneakingVisually() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getTotalArmorValue() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
protected int getAttackSpeed() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(12.0D);
|
||||
}
|
||||
}
|
83
java/src/game/entity/npc/EntitySpirit.java
Executable file
83
java/src/game/entity/npc/EntitySpirit.java
Executable file
|
@ -0,0 +1,83 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntitySpirit extends EntityNPC {
|
||||
public EntitySpirit(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityHaunter.class;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return clazz != EntityHaunter.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return rand.range(1, 2);
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(8, 14);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(0.0f, 0.1f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.LAWFUL_GOOD, Alignment.GOOD);
|
||||
}
|
||||
|
||||
public boolean isGhost() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xffffff;
|
||||
}
|
||||
|
||||
// public void attackEntityWithRangedAttack(EntityLiving target, float p_82196_2_)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
|
||||
// public boolean isRangedWeapon(ItemStack stack) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public float getArmRotation() {
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
public float getLegRotation() {
|
||||
return 0.2f;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
}
|
77
java/src/game/entity/npc/EntityTiefling.java
Executable file
77
java/src/game/entity/npc/EntityTiefling.java
Executable file
|
@ -0,0 +1,77 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityTiefling extends EntityMobNPC {
|
||||
public EntityTiefling(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(16, 28);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.1f, 0.4f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.CHAOTIC_EVIL, Alignment.EVIL, Alignment.LAWFUL_EVIL,
|
||||
Alignment.NEUTRAL, Alignment.LAWFUL, Alignment.CHAOTIC);
|
||||
}
|
||||
|
||||
public boolean isImmuneToFire() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xff9494;
|
||||
}
|
||||
|
||||
public boolean canSpawnInLiquid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(3.0D);
|
||||
}
|
||||
}
|
110
java/src/game/entity/npc/EntityUndead.java
Executable file
110
java/src/game/entity/npc/EntityUndead.java
Executable file
|
@ -0,0 +1,110 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.ai.EntityAIAvoidEntity;
|
||||
import game.entity.animal.EntityWolf;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
import game.world.WorldServer;
|
||||
|
||||
public class EntityUndead extends EntityNPC
|
||||
{
|
||||
public EntityUndead(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityWolf.class, 6.0F, 1.0D, 1.2D));
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.25D);
|
||||
}
|
||||
|
||||
// protected String getLivingSound()
|
||||
// {
|
||||
// return "mob.skeleton.say";
|
||||
// }
|
||||
|
||||
// protected String getHurtSound()
|
||||
// {
|
||||
// return "mob.skeleton.hurt";
|
||||
// }
|
||||
//
|
||||
// protected String getDeathSound()
|
||||
// {
|
||||
// return "mob.skeleton.death";
|
||||
// }
|
||||
|
||||
public void updateRidden()
|
||||
{
|
||||
super.updateRidden();
|
||||
|
||||
if (this.vehicle instanceof EntityLiving)
|
||||
{
|
||||
EntityLiving entitycreature = (EntityLiving)this.vehicle;
|
||||
this.yawOffset = entitycreature.yawOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xff6a00;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityElf.class || clazz == EntityHuman.class || clazz == EntityWoodElf.class;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityCultivator.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(12, 26);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return Alignment.EVIL;
|
||||
}
|
||||
|
||||
public boolean getCanSpawnHere() {
|
||||
return !((WorldServer)this.worldObj).isDaytime();
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public boolean arePotionsInverted() {
|
||||
return true;
|
||||
}
|
||||
}
|
72
java/src/game/entity/npc/EntityVampire.java
Executable file
72
java/src/game/entity/npc/EntityVampire.java
Executable file
|
@ -0,0 +1,72 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.effect.EntityLightning;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityVampire extends EntityNPC {
|
||||
public EntityVampire(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0x840000;
|
||||
}
|
||||
|
||||
public void onStruckByLightning(EntityLightning lightningBolt) {
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return !this.alignment.good;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityHuman.class || clazz == EntityElf.class;
|
||||
}
|
||||
|
||||
// public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(36, 82);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.EVIL, Alignment.CHAOTIC_EVIL, Alignment.CHAOTIC, Alignment.NEUTRAL, Alignment.CHAOTIC_GOOD);
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes() {
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(5.0D);
|
||||
}
|
||||
}
|
64
java/src/game/entity/npc/EntityWoodElf.java
Executable file
64
java/src/game/entity/npc/EntityWoodElf.java
Executable file
|
@ -0,0 +1,64 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.NameRegistry;
|
||||
import game.rng.Random;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityWoodElf extends EntityNPC {
|
||||
public EntityWoodElf(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityElf.class || clazz == EntityBloodElf.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean canUseMagic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return rand.range(2, 4);
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(20, 22);
|
||||
}
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.1f, 0.25f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.chance(5) ? (rand.chance(5) ? Alignment.CHAOTIC : Alignment.NEUTRAL) : Alignment.LAWFUL;
|
||||
}
|
||||
|
||||
public NameRegistry getNameType() {
|
||||
return NameRegistry.ELVEN;
|
||||
}
|
||||
|
||||
public boolean canAmbush(EntityLiving entity) {
|
||||
return (float)this.getHealth() >= ((float)this.getMaxHealth() / 3.0f);
|
||||
}
|
||||
}
|
344
java/src/game/entity/npc/EntityZombie.java
Executable file
344
java/src/game/entity/npc/EntityZombie.java
Executable file
|
@ -0,0 +1,344 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.ai.EntityAIMoveThroughVillage;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.animal.EntityChicken;
|
||||
import game.entity.attributes.AttributeModifier;
|
||||
import game.entity.attributes.Attributes;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Config;
|
||||
import game.rng.Random;
|
||||
import game.world.BlockPos;
|
||||
import game.world.World;
|
||||
import game.world.WorldServer;
|
||||
|
||||
public class EntityZombie extends EntityNPC
|
||||
{
|
||||
public EntityZombie(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.tasks.addTask(6, new EntityAIMoveThroughVillage(this, 1.0D, false));
|
||||
}
|
||||
|
||||
protected void applyEntityAttributes()
|
||||
{
|
||||
super.applyEntityAttributes();
|
||||
this.getEntityAttribute(Attributes.FOLLOW_RANGE).setBaseValue(28.0D);
|
||||
this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D);
|
||||
this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(3.0D);
|
||||
this.getAttributeMap().registerAttribute(Attributes.REINFORCEMENT_CHANCE).setBaseValue(this.rand.doublev() * 0.10000000149011612D);
|
||||
}
|
||||
|
||||
public void onLivingUpdate()
|
||||
{
|
||||
if(this.isRiding() && this.getAttackTarget() != null && this.vehicle instanceof EntityChicken)
|
||||
((EntityLiving)this.vehicle).getNavigator().setPath(this.getNavigator().getPath(), 1.5D);
|
||||
if(!this.worldObj.client)
|
||||
this.setAttacking(this.getAttackTarget() != null);
|
||||
super.onLivingUpdate();
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (super.attackEntityFrom(source, amount))
|
||||
{
|
||||
EntityLiving entitylivingbase = this.getAttackTarget();
|
||||
|
||||
if (entitylivingbase == null && source.getEntity() instanceof EntityLiving)
|
||||
{
|
||||
entitylivingbase = (EntityLiving)source.getEntity();
|
||||
}
|
||||
|
||||
if (entitylivingbase != null && /* this.worldObj.getDifficulty() == Difficulty.HARD && */ (double)this.rand.floatv() < this.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).getAttributeValue() && Config.mobs && Config.spawnMoreZombie)
|
||||
{
|
||||
int i = ExtMath.floord(this.posX);
|
||||
int j = ExtMath.floord(this.posY);
|
||||
int k = ExtMath.floord(this.posZ);
|
||||
EntityZombie entityzombie = new EntityZombie(this.worldObj);
|
||||
|
||||
for (int l = 0; l < 50; ++l)
|
||||
{
|
||||
int i1 = i + this.rand.range(7, 40) * this.rand.range(-1, 1);
|
||||
int j1 = j + this.rand.range(7, 40) * this.rand.range(-1, 1);
|
||||
int k1 = k + this.rand.range(7, 40) * this.rand.range(-1, 1);
|
||||
|
||||
if (this.worldObj.isBlockSolid(new BlockPos(i1, j1 - 1, k1)) && this.worldObj.getLightFromNeighbors(new BlockPos(i1, j1, k1)) < 10)
|
||||
{
|
||||
entityzombie.setPosition((double)i1, (double)j1, (double)k1);
|
||||
|
||||
if (!this.worldObj.isAnyPlayerWithinRangeAt((double)i1, (double)j1, (double)k1, 7.0D) && this.worldObj.checkNoEntityCollision(entityzombie.getEntityBoundingBox(), entityzombie) && this.worldObj.getCollidingBoundingBoxes(entityzombie, entityzombie.getEntityBoundingBox()).isEmpty() && !this.worldObj.isAnyLiquid(entityzombie.getEntityBoundingBox()))
|
||||
{
|
||||
this.worldObj.spawnEntityInWorld(entityzombie);
|
||||
entityzombie.setAttackTarget(entitylivingbase);
|
||||
entityzombie.onInitialSpawn(null);
|
||||
this.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).applyModifier(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, false));
|
||||
entityzombie.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).applyModifier(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// public boolean attackEntityAsMob(Entity entityIn)
|
||||
// {
|
||||
// boolean flag = super.attackEntityAsMob(entityIn);
|
||||
//
|
||||
// if (flag)
|
||||
// {
|
||||
// int i = this.worldObj.getDifficulty().getId();
|
||||
//
|
||||
// if (this.getHeldItem() == null && this.isBurning() && this.rand.floatv() < (float)i * 0.3F)
|
||||
// {
|
||||
// entityIn.setFire(2 * i);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return flag;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns the sound this mob makes while it's alive.
|
||||
// */
|
||||
// protected String getLivingSound()
|
||||
// {
|
||||
// return "mob.zombie.say";
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the sound this mob makes when it is hurt.
|
||||
// */
|
||||
// protected String getHurtSound()
|
||||
// {
|
||||
// return "mob.zombie.hurt";
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the sound this mob makes on death.
|
||||
// */
|
||||
// protected String getDeathSound()
|
||||
// {
|
||||
// return "mob.zombie.death";
|
||||
// }
|
||||
//
|
||||
// protected void playStepSound(BlockPos pos, Block blockIn)
|
||||
// {
|
||||
// this.playSound("mob.zombie.step", 0.15F, 1.0F);
|
||||
// }
|
||||
|
||||
public void onKillEntity(EntityLiving entityLivingIn)
|
||||
{
|
||||
super.onKillEntity(entityLivingIn);
|
||||
|
||||
if (/* (this.worldObj.getDifficulty() == Difficulty.NORMAL || this.worldObj.getDifficulty() == Difficulty.HARD) && */ entityLivingIn instanceof EntityNPC && !(entityLivingIn.isPlayer()) && Config.convertZombie)
|
||||
{
|
||||
// if (this.worldObj.getDifficulty() != Difficulty.HARD && this.rand.chance())
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
EntityNPC entityliving = (EntityNPC)entityLivingIn;
|
||||
EntityZombie entityzombie = new EntityZombie(this.worldObj);
|
||||
entityzombie.copyLocationAndAnglesFrom(entityLivingIn);
|
||||
this.worldObj.removeEntity(entityLivingIn);
|
||||
entityzombie.onInitialSpawn(null);
|
||||
// entityzombie.setVillager(true);
|
||||
|
||||
// if(entityLivingIn instanceof EntityNPC) {
|
||||
entityzombie.setGrowingAge(entityliving.getGrowingAge());
|
||||
// }
|
||||
// else if (entityLivingIn.isChild()) {
|
||||
// entityzombie.setGrowingAge(-24000);
|
||||
// }
|
||||
|
||||
// entityzombie.setNoAI(entityliving.isAIDisabled());
|
||||
|
||||
if (entityliving.hasCustomName())
|
||||
{
|
||||
entityzombie.setCustomNameTag(entityliving.getCustomNameTag());
|
||||
// entityzombie.setAlwaysRenderNameTag(entityliving.getAlwaysRenderNameTag());
|
||||
}
|
||||
|
||||
this.worldObj.spawnEntityInWorld(entityzombie);
|
||||
this.worldObj.playAuxSFX(1016, new BlockPos((int)this.posX, (int)this.posY, (int)this.posZ), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// protected boolean canPickUpItem(ItemStack stack)
|
||||
// {
|
||||
// return stack.getItem() == Items.egg && this.isRiding() ? false : super.canPickUpItem(stack);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 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 Object onInitialSpawn(Object livingdata)
|
||||
{
|
||||
livingdata = super.onInitialSpawn(livingdata);
|
||||
// float f = difficulty.getDifficulty();
|
||||
// this.setCanPickUpLoot(this.rand.floatv() < 0.55F * f);
|
||||
|
||||
if (livingdata == null)
|
||||
{
|
||||
livingdata = new EntityZombie.GroupData(this.worldObj.rand.floatv() < 0.05F); //, this.worldObj.rand.floatv() < 0.05F);
|
||||
}
|
||||
|
||||
if (livingdata instanceof EntityZombie.GroupData)
|
||||
{
|
||||
EntityZombie.GroupData entityzombie$groupdata = (EntityZombie.GroupData)livingdata;
|
||||
|
||||
// if (entityzombie$groupdata.isVillager)
|
||||
// {
|
||||
// this.setVillager(true);
|
||||
// }
|
||||
|
||||
if (entityzombie$groupdata.isChild)
|
||||
{
|
||||
this.setGrowingAge(-24000);
|
||||
|
||||
if ((double)this.worldObj.rand.floatv() < 0.05D)
|
||||
{
|
||||
List<EntityChicken> list = this.worldObj.<EntityChicken>getEntitiesWithinAABB(EntityChicken.class, this.getEntityBoundingBox().expand(5.0D, 3.0D, 5.0D), new Predicate<EntityChicken>() {
|
||||
public boolean test(EntityChicken entity) {
|
||||
return entity.isEntityAlive() && entity.passenger == null && entity.vehicle == null;
|
||||
}
|
||||
});
|
||||
|
||||
if (!list.isEmpty())
|
||||
{
|
||||
EntityChicken entitychicken = (EntityChicken)list.get(0);
|
||||
entitychicken.setChickenJockey(true);
|
||||
this.mountEntity(entitychicken);
|
||||
}
|
||||
}
|
||||
else if ((double)this.worldObj.rand.floatv() < 0.05D)
|
||||
{
|
||||
EntityChicken entitychicken1 = new EntityChicken(this.worldObj);
|
||||
entitychicken1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, 0.0F);
|
||||
entitychicken1.onInitialSpawn(null);
|
||||
entitychicken1.setChickenJockey(true);
|
||||
this.worldObj.spawnEntityInWorld(entitychicken1);
|
||||
this.mountEntity(entitychicken1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this.setBreakDoorsAItask(this.rand.floatv() < f * 0.1F);
|
||||
// this.setEquipmentBasedOnDifficulty(difficulty);
|
||||
// this.setEnchantmentBasedOnDifficulty(difficulty);
|
||||
|
||||
// if (Config.useHalloween && this.getItem(4) == null)
|
||||
// {
|
||||
// Calendar calendar = World.getCurrentDate();
|
||||
//
|
||||
// if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.rand.floatv() < 0.25F)
|
||||
// {
|
||||
// this.setItem(4, new ItemStack(this.rand.floatv() < 0.1F ? Blocks.lit_pumpkin : Blocks.pumpkin));
|
||||
// this.dropChances[4] = 0.0F;
|
||||
// }
|
||||
// }
|
||||
|
||||
this.getEntityAttribute(Attributes.KNOCKBACK_RESISTANCE).applyModifier(new AttributeModifier("Random spawn bonus", this.rand.doublev() * 0.05000000074505806D, false));
|
||||
double d0 = this.rand.doublev() * 15.0;
|
||||
|
||||
if (d0 > 1.0D)
|
||||
{
|
||||
this.getEntityAttribute(Attributes.FOLLOW_RANGE).applyModifier(new AttributeModifier("Random zombie-spawn bonus", d0, false));
|
||||
}
|
||||
|
||||
if (this.rand.chance(30))
|
||||
{
|
||||
this.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).applyModifier(new AttributeModifier("Leader zombie bonus", this.rand.doublev() * 0.25D + 0.5D, false));
|
||||
this.getEntityAttribute(Attributes.MAX_HEALTH).applyModifier(new AttributeModifier("Leader zombie bonus", this.rand.roll(4), true));
|
||||
// this.setBreakDoorsAItask(true);
|
||||
}
|
||||
|
||||
return livingdata;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return 0xff0000;
|
||||
}
|
||||
|
||||
// public boolean isAggressive() {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public boolean isPeaceful() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityHuman.class || clazz == EntityElf.class;
|
||||
}
|
||||
|
||||
public boolean isPeaceful(Class<? extends EntityNPC> clazz) {
|
||||
return clazz == EntityCultivator.class;
|
||||
}
|
||||
|
||||
// public boolean canInfight(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// public boolean canMurder(Alignment align) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// public boolean canUseMagic() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public int getBaseHealth(Random rand) {
|
||||
return rand.range(16, 36);
|
||||
}
|
||||
|
||||
// public int getBaseEnergy(Random rand) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
public float getHeightDeviation(Random rand) {
|
||||
return rand.frange(-0.2f, 0.2f);
|
||||
}
|
||||
|
||||
public Alignment getNaturalAlign(Random rand) {
|
||||
return rand.pick(Alignment.CHAOTIC_EVIL, Alignment.EVIL);
|
||||
}
|
||||
|
||||
public boolean getCanSpawnHere() {
|
||||
return !((WorldServer)this.worldObj).isDaytime();
|
||||
}
|
||||
|
||||
// public boolean canAmbush(EntityLiving entity) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public boolean arePotionsInverted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasArmsRaised() {
|
||||
return this.isAttacking();
|
||||
}
|
||||
|
||||
class GroupData
|
||||
{
|
||||
public boolean isChild;
|
||||
|
||||
private GroupData(boolean isBaby)
|
||||
{
|
||||
this.isChild = isBaby;
|
||||
}
|
||||
}
|
||||
}
|
224
java/src/game/entity/npc/SpeciesInfo.java
Executable file
224
java/src/game/entity/npc/SpeciesInfo.java
Executable file
|
@ -0,0 +1,224 @@
|
|||
package game.entity.npc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import game.block.Block;
|
||||
import game.collect.BiMap;
|
||||
import game.collect.HashBiMap;
|
||||
import game.collect.Lists;
|
||||
import game.collect.Maps;
|
||||
import game.init.SpeciesRegistry;
|
||||
import game.init.SpeciesRegistry.ModelType;
|
||||
import game.item.Item;
|
||||
import game.item.ItemArmor;
|
||||
import game.item.ItemBow;
|
||||
import game.item.ItemGunBase;
|
||||
import game.item.ItemHoe;
|
||||
import game.item.ItemShears;
|
||||
import game.item.ItemStack;
|
||||
import game.item.ItemSword;
|
||||
import game.item.ItemTool;
|
||||
import game.item.RngLoot;
|
||||
import game.properties.IStringSerializable;
|
||||
import game.rng.Random;
|
||||
import game.rng.WeightedList;
|
||||
|
||||
public class SpeciesInfo {
|
||||
public final Map<Enum, ClassInfo> classmap;
|
||||
public final BiMap<String, Enum> classnames;
|
||||
public final Class<? extends EntityNPC> clazz;
|
||||
public final Class<? extends Enum> classEnum;
|
||||
public final ModelType renderer;
|
||||
public final float size;
|
||||
public final boolean prefix;
|
||||
public final String id;
|
||||
public final String origin;
|
||||
public final String name;
|
||||
public final int color1;
|
||||
public final int color2;
|
||||
public final CharacterInfo[] chars;
|
||||
public final ClassInfo[] classes;
|
||||
private final WeightedList<RngLoot>[] items;
|
||||
private final int[] alignment = new int[Alignment.values().length];
|
||||
private final int[] energies = new int[Energy.values().length];
|
||||
private final int[] baseEnergy = new int[Energy.values().length];
|
||||
|
||||
public SpeciesInfo(String id, Class<? extends EntityNPC> clazz, Class<? extends Enum> classEnum, boolean prefix, String origin, String name, ModelType renderer, float size, int color1, int color2,
|
||||
Object ... names) {
|
||||
this.classmap = classEnum == null ? null : Maps.newEnumMap(classEnum);
|
||||
this.classnames = classEnum == null ? null : HashBiMap.create();
|
||||
this.clazz = clazz; // name.toLowerCase().replace(' ', '_');
|
||||
this.classEnum = classEnum;
|
||||
this.renderer = renderer;
|
||||
this.size = size;
|
||||
this.prefix = prefix;
|
||||
this.id = id; // clazz.getSimpleName().substring(6);
|
||||
this.origin = origin;
|
||||
this.name = name;
|
||||
this.color1 = color1;
|
||||
this.color2 = color2;
|
||||
List<CharacterInfo> chars = Lists.<CharacterInfo>newArrayList();
|
||||
List<ClassInfo> classes = Lists.<ClassInfo>newArrayList();
|
||||
ClassInfo spclass = null;
|
||||
for(int z = 0; z < names.length; z++) {
|
||||
if(names[z] == null) {
|
||||
spclass = null;
|
||||
continue;
|
||||
}
|
||||
if(names[z] instanceof Enum) {
|
||||
classes.add(spclass = new ClassInfo(this, (Enum)names[z]));
|
||||
continue;
|
||||
}
|
||||
// String id = ((String)names[z]);
|
||||
// if(id.startsWith("$")) {
|
||||
// id = id.substring(1);
|
||||
// spclass = id.isEmpty() ? null : new ClassInfo(this, Enum.valueOf(this.classEnum, id.toUpperCase()));
|
||||
// if(spclass != null)
|
||||
// classes.add(spclass);
|
||||
// continue;
|
||||
// }
|
||||
String[] tok = ((String)names[z]).split(":", 3);
|
||||
int scolor1 = color1;
|
||||
int scolor2 = color2;
|
||||
if(z < names.length - 1 && names[z+1].getClass() == Integer.class)
|
||||
scolor2 = ((Integer)names[++z]).intValue();
|
||||
if(z < names.length - 1 && names[z+1].getClass() == Integer.class) {
|
||||
scolor1 = scolor2;
|
||||
scolor2 = ((Integer)names[++z]).intValue();
|
||||
}
|
||||
chars.add(new CharacterInfo(this, spclass, tok[0], tok.length > 1 && !tok[1].isEmpty() ? tok[1] : (tok[0].isEmpty() ? this.id : tok[0]).toLowerCase().replace(' ', '_'),
|
||||
tok.length > 2 ? tok[2] : "", scolor1, scolor2, names.length > 1));
|
||||
}
|
||||
this.chars = chars.toArray(new CharacterInfo[chars.size()]);
|
||||
this.classes = classes.toArray(new ClassInfo[classes.size()]);
|
||||
this.items = new WeightedList[6];
|
||||
for(int z = 0; z < this.items.length; z++) {
|
||||
this.items[z] = new WeightedList();
|
||||
}
|
||||
// SpeciesRegistry.SPECIES.put(this.id, this);
|
||||
SpeciesRegistry.CLASSES.put(this.clazz, this);
|
||||
if(this.classEnum != null) {
|
||||
for(Enum type : this.classEnum.getEnumConstants()) {
|
||||
this.classnames.put(((IStringSerializable)type).getName(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CharacterInfo pickCharacter(Random rand) {
|
||||
return rand.pick(this.chars);
|
||||
}
|
||||
|
||||
public WeightedList<RngLoot>[] getItems() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public void addItems(Object[] items) {
|
||||
WeightedList<RngLoot>[] lists = this.items;
|
||||
int curSlot = -1;
|
||||
ItemStack item;
|
||||
int chance = 1;
|
||||
int min = 1;
|
||||
int max = 1;
|
||||
for(int z = 0; z < items.length; z++) {
|
||||
Object stack = items[z];
|
||||
if(stack == null) {
|
||||
item = null;
|
||||
}
|
||||
else if(stack instanceof String) {
|
||||
String name = (String)stack;
|
||||
if(name.isEmpty()) {
|
||||
lists = this.items;
|
||||
continue;
|
||||
}
|
||||
if(name.startsWith("$")) {
|
||||
name = name.substring(1);
|
||||
Enum type = this.classnames.get(name);
|
||||
if(type == null) {
|
||||
throw new IllegalArgumentException("Item [" + z + "/" + name + "] is not a known class");
|
||||
}
|
||||
ClassInfo ci = this.classmap.get(type);
|
||||
// for(int c = 0; c < this.classes.length; c++) {
|
||||
// if(this.classnames.get(this.classes[c].type).equalsIgnoreCase(name)) {
|
||||
// ci = this.classes[c];
|
||||
// }
|
||||
// }
|
||||
lists = ci.getItems();
|
||||
continue;
|
||||
}
|
||||
CharacterInfo ch = null;
|
||||
for(int c = 0; c < this.chars.length; c++) {
|
||||
if(!this.chars[c].name.isEmpty() && this.chars[c].name.equals(name)) {
|
||||
ch = this.chars[c];
|
||||
}
|
||||
}
|
||||
if(ch == null) {
|
||||
throw new IllegalArgumentException("Item [" + z + "/" + name + "] is not a known character");
|
||||
}
|
||||
lists = ch.getItems();
|
||||
continue;
|
||||
}
|
||||
else if(stack instanceof Integer) {
|
||||
int n = (Integer)stack;
|
||||
if(n <= 0)
|
||||
curSlot = -n;
|
||||
else
|
||||
chance = n;
|
||||
continue;
|
||||
}
|
||||
else if(stack instanceof ItemStack) {
|
||||
item = (ItemStack)stack;
|
||||
max = item.stackSize;
|
||||
item.stackSize = 1;
|
||||
}
|
||||
else if(stack instanceof Item) {
|
||||
item = new ItemStack((Item)stack);
|
||||
}
|
||||
else if(stack instanceof Block) {
|
||||
item = new ItemStack((Block)stack);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Item [" + z + "] has to be a stack, item, block or null");
|
||||
}
|
||||
int slot = curSlot;
|
||||
if(slot == -1 && item == null) {
|
||||
slot = 0;
|
||||
}
|
||||
else if(slot == -1) {
|
||||
slot = ItemArmor.getArmorPosition(item);
|
||||
if(slot == 0 && !(item.getItem() instanceof ItemTool || item.getItem() instanceof ItemSword || item.getItem() instanceof ItemBow ||
|
||||
item.getItem() instanceof ItemHoe || item.getItem() instanceof ItemShears || item.getItem() instanceof ItemGunBase)) {
|
||||
slot = 5;
|
||||
}
|
||||
}
|
||||
lists[slot].add(new RngLoot(item, min, max, chance));
|
||||
curSlot = -1;
|
||||
chance = 1;
|
||||
min = 1;
|
||||
max = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public SpeciesInfo setEnergy(Energy type, int affinity, int base) {
|
||||
this.energies[type.ordinal()] = affinity;
|
||||
this.baseEnergy[type.ordinal()] = base;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getEnergyAffinity(Energy type) {
|
||||
return this.energies[type.ordinal()];
|
||||
}
|
||||
|
||||
public int getEnergyBase(Energy type) {
|
||||
return this.baseEnergy[type.ordinal()];
|
||||
}
|
||||
|
||||
public SpeciesInfo setAlignAffinity(Alignment type, int value) {
|
||||
this.alignment[type.ordinal()] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getAlignAffinity(Alignment type) {
|
||||
return this.alignment[type.ordinal()];
|
||||
}
|
||||
}
|
634
java/src/game/entity/projectile/EntityArrow.java
Executable file
634
java/src/game/entity/projectile/EntityArrow.java
Executable file
|
@ -0,0 +1,634 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.enchantment.EnchantmentHelper;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.entity.types.IProjectile;
|
||||
import game.init.BlockRegistry;
|
||||
import game.init.Config;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemStack;
|
||||
import game.material.Material;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.HitPosition;
|
||||
import game.world.State;
|
||||
import game.world.Vec3;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityArrow extends Entity implements IProjectile, IObjectData
|
||||
{
|
||||
private int xTile = -1;
|
||||
private int yTile = -1;
|
||||
private int zTile = -1;
|
||||
private Block inTile;
|
||||
private int inData;
|
||||
private boolean inGround;
|
||||
|
||||
/** 1 if the player can pick up the arrow */
|
||||
public int canBePickedUp;
|
||||
|
||||
/** Seems to be some sort of timer for animating an arrow. */
|
||||
public int arrowShake;
|
||||
|
||||
/** The owner of this arrow. */
|
||||
public Entity shootingEntity;
|
||||
private int ticksInGround;
|
||||
private int ticksInAir;
|
||||
private double damage = 2.0D;
|
||||
|
||||
/** The amount of knockback an arrow applies when it hits a mob. */
|
||||
private int knockbackStrength;
|
||||
|
||||
public EntityArrow(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
}
|
||||
|
||||
public EntityArrow(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setPosition(x, y, z);
|
||||
}
|
||||
|
||||
public EntityArrow(World worldIn, double x, double y, double z, int data)
|
||||
{
|
||||
this(worldIn, x, y, z);
|
||||
Entity entity2 = worldIn.getEntityByID(data);
|
||||
if(entity2 instanceof EntityLiving) {
|
||||
this.shootingEntity = entity2;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityArrow(World worldIn, EntityLiving shooter, EntityLiving target, float velocity, float innacuracy)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.shootingEntity = shooter;
|
||||
|
||||
if (shooter.isPlayer())
|
||||
{
|
||||
this.canBePickedUp = 1;
|
||||
}
|
||||
|
||||
this.posY = shooter.posY + (double)shooter.getEyeHeight() - 0.10000000149011612D;
|
||||
double d0 = target.posX - shooter.posX;
|
||||
double d1 = target.getEntityBoundingBox().minY + (double)(target.height / 3.0F) - this.posY;
|
||||
double d2 = target.posZ - shooter.posZ;
|
||||
double d3 = (double)ExtMath.sqrtd(d0 * d0 + d2 * d2);
|
||||
|
||||
if (d3 >= 1.0E-7D)
|
||||
{
|
||||
float f = (float)(ExtMath.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
|
||||
float f1 = (float)(-(ExtMath.atan2(d1, d3) * 180.0D / Math.PI));
|
||||
double d4 = d0 / d3;
|
||||
double d5 = d2 / d3;
|
||||
this.setLocationAndAngles(shooter.posX + d4, this.posY, shooter.posZ + d5, f, f1);
|
||||
float f2 = (float)(d3 * 0.20000000298023224D);
|
||||
this.setThrowableHeading(d0, d1 + (double)f2, d2, velocity, innacuracy);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityArrow(World worldIn, EntityLiving shooter, float velocity)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.shootingEntity = shooter;
|
||||
|
||||
if (shooter.isPlayer())
|
||||
{
|
||||
this.canBePickedUp = 1;
|
||||
}
|
||||
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setLocationAndAngles(shooter.posX, shooter.posY + (double)shooter.getEyeHeight(), shooter.posZ, shooter.rotYaw, shooter.rotPitch);
|
||||
this.posX -= (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.posY -= 0.10000000149011612D;
|
||||
this.posZ -= (double)(ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
this.motionX = (double)(-ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI));
|
||||
this.motionZ = (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI));
|
||||
this.motionY = (double)(-ExtMath.sin(this.rotPitch / 180.0F * (float)Math.PI));
|
||||
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, velocity * 1.5F, 1.0F);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to setArrowHeading, it's point the throwable entity to a x, y, z direction.
|
||||
*/
|
||||
public void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy)
|
||||
{
|
||||
float f = ExtMath.sqrtd(x * x + y * y + z * z);
|
||||
x = x / (double)f;
|
||||
y = y / (double)f;
|
||||
z = z / (double)f;
|
||||
x = x + this.rand.gaussian() * (double)(this.rand.chance() ? -1 : 1) * 0.007499999832361937D * (double)inaccuracy;
|
||||
y = y + this.rand.gaussian() * (double)(this.rand.chance() ? -1 : 1) * 0.007499999832361937D * (double)inaccuracy;
|
||||
z = z + this.rand.gaussian() * (double)(this.rand.chance() ? -1 : 1) * 0.007499999832361937D * (double)inaccuracy;
|
||||
x = x * (double)velocity;
|
||||
y = y * (double)velocity;
|
||||
z = z * (double)velocity;
|
||||
this.motionX = x;
|
||||
this.motionY = y;
|
||||
this.motionZ = z;
|
||||
float f1 = ExtMath.sqrtd(x * x + z * z);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(x, z) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(y, (double)f1) * 180.0D / Math.PI);
|
||||
this.ticksInGround = 0;
|
||||
}
|
||||
|
||||
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_)
|
||||
{
|
||||
this.setPosition(x, y, z);
|
||||
this.setRotation(yaw, pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double x, double y, double z)
|
||||
{
|
||||
this.motionX = x;
|
||||
this.motionY = y;
|
||||
this.motionZ = z;
|
||||
|
||||
if (this.prevPitch == 0.0F && this.prevYaw == 0.0F)
|
||||
{
|
||||
float f = ExtMath.sqrtd(x * x + z * z);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(x, z) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(y, (double)f) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch;
|
||||
this.prevYaw = this.rotYaw;
|
||||
this.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, this.rotPitch);
|
||||
this.ticksInGround = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.prevPitch == 0.0F && this.prevYaw == 0.0F)
|
||||
{
|
||||
float f = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(this.motionY, (double)f) * 180.0D / Math.PI);
|
||||
}
|
||||
|
||||
BlockPos blockpos = new BlockPos(this.xTile, this.yTile, this.zTile);
|
||||
State iblockstate = this.worldObj.getState(blockpos);
|
||||
Block block = iblockstate.getBlock();
|
||||
|
||||
if (block.getMaterial() != Material.air)
|
||||
{
|
||||
block.setBlockBoundsBasedOnState(this.worldObj, blockpos);
|
||||
BoundingBox axisalignedbb = block.getCollisionBoundingBox(this.worldObj, blockpos, iblockstate);
|
||||
|
||||
if (axisalignedbb != null && axisalignedbb.isVecInside(new Vec3(this.posX, this.posY, this.posZ)))
|
||||
{
|
||||
this.inGround = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.arrowShake > 0)
|
||||
{
|
||||
--this.arrowShake;
|
||||
}
|
||||
|
||||
if (this.inGround)
|
||||
{
|
||||
int j = block.getMetaFromState(iblockstate);
|
||||
|
||||
if (block == this.inTile && j == this.inData)
|
||||
{
|
||||
++this.ticksInGround;
|
||||
|
||||
if (this.ticksInGround >= 1200)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inGround = false;
|
||||
this.motionX *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionY *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionZ *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.ticksInGround = 0;
|
||||
this.ticksInAir = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++this.ticksInAir;
|
||||
Vec3 vec31 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
Vec3 vec3 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
HitPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec31, vec3, false, true, false);
|
||||
vec31 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
vec3 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
vec3 = new Vec3(movingobjectposition.vec.xCoord, movingobjectposition.vec.yCoord, movingobjectposition.vec.zCoord);
|
||||
}
|
||||
|
||||
Entity entity = null;
|
||||
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
double d0 = 0.0D;
|
||||
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
Entity entity1 = (Entity)list.get(i);
|
||||
|
||||
if (entity1.canBeCollidedWith() && (entity1 != this.shootingEntity || this.ticksInAir >= 5))
|
||||
{
|
||||
float f1 = 0.3F;
|
||||
BoundingBox axisalignedbb1 = entity1.getEntityBoundingBox().expand((double)f1, (double)f1, (double)f1);
|
||||
HitPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(vec31, vec3);
|
||||
|
||||
if (movingobjectposition1 != null)
|
||||
{
|
||||
double d1 = vec31.squareDistanceTo(movingobjectposition1.vec);
|
||||
|
||||
if (d1 < d0 || d0 == 0.0D)
|
||||
{
|
||||
entity = entity1;
|
||||
d0 = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
movingobjectposition = new HitPosition(entity);
|
||||
}
|
||||
|
||||
// if (movingobjectposition != null && movingobjectposition.entity != null && movingobjectposition.entity.isPlayer())
|
||||
// {
|
||||
// EntityNPC entityplayer = (EntityNPC)movingobjectposition.entity;
|
||||
//
|
||||
// if (entityplayer.creative || this.shootingEntity.isPlayer() && !((EntityNPC)this.shootingEntity).canAttackPlayer(entityplayer))
|
||||
// {
|
||||
// movingobjectposition = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
if (movingobjectposition.entity != null)
|
||||
{
|
||||
float f2 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
|
||||
int l = ExtMath.ceild((double)f2 * this.damage);
|
||||
|
||||
if (this.getIsCritical())
|
||||
{
|
||||
l += this.rand.zrange(l / 2 + 2);
|
||||
}
|
||||
|
||||
DamageSource damagesource;
|
||||
|
||||
if (this.shootingEntity == null)
|
||||
{
|
||||
damagesource = DamageSource.causeShotDamage(this, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
damagesource = DamageSource.causeShotDamage(this, this.shootingEntity);
|
||||
}
|
||||
|
||||
if (this.isBurning()) // && !(movingobjectposition.entityHit instanceof EntityAITakePlace))
|
||||
{
|
||||
movingobjectposition.entity.setFire(5);
|
||||
}
|
||||
|
||||
if ((this.worldObj.client || Config.damageArrow) && movingobjectposition.entity.attackEntityFrom(damagesource, l))
|
||||
{
|
||||
if (movingobjectposition.entity instanceof EntityLiving)
|
||||
{
|
||||
EntityLiving entitylivingbase = (EntityLiving)movingobjectposition.entity;
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
entitylivingbase.setArrowCountInEntity(entitylivingbase.getArrowCountInEntity() + 1);
|
||||
}
|
||||
|
||||
if (this.knockbackStrength > 0)
|
||||
{
|
||||
float f7 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
|
||||
if (f7 > 0.0F)
|
||||
{
|
||||
movingobjectposition.entity.addKnockback(this.motionX * (double)this.knockbackStrength * 0.6000000238418579D / (double)f7, 0.1D, this.motionZ * (double)this.knockbackStrength * 0.6000000238418579D / (double)f7);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.shootingEntity instanceof EntityLiving)
|
||||
{
|
||||
EnchantmentHelper.applyThornEnchantments(entitylivingbase, this.shootingEntity);
|
||||
EnchantmentHelper.applyArthropodEnchantments((EntityLiving)this.shootingEntity, entitylivingbase);
|
||||
}
|
||||
|
||||
// if (this.shootingEntity != null && movingobjectposition.entityHit != this.shootingEntity && movingobjectposition.entityHit.isPlayer() && this.shootingEntity.isPlayer())
|
||||
// {
|
||||
// ((EntityNPCMP)this.shootingEntity).netHandler.sendPacket(new S29PacketSoundEffect(
|
||||
// "random.successful_hit", shootingEntity.posX,
|
||||
// shootingEntity.posY + (double)shootingEntity.getEyeHeight(), shootingEntity.posZ, 0.18F, 0.45F));
|
||||
// }
|
||||
}
|
||||
|
||||
this.playSound(SoundEvent.BOWHIT, 1.0F, 1.2F / (this.rand.floatv() * 0.2F + 0.9F));
|
||||
|
||||
// if (!(movingobjectposition.entityHit instanceof EntityAITakePlace))
|
||||
// {
|
||||
this.setDead();
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
this.motionX *= -0.10000000149011612D;
|
||||
this.motionY *= -0.10000000149011612D;
|
||||
this.motionZ *= -0.10000000149011612D;
|
||||
this.rotYaw += 180.0F;
|
||||
this.prevYaw += 180.0F;
|
||||
this.ticksInAir = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos1 = movingobjectposition.block;
|
||||
this.xTile = blockpos1.getX();
|
||||
this.yTile = blockpos1.getY();
|
||||
this.zTile = blockpos1.getZ();
|
||||
State iblockstate1 = this.worldObj.getState(blockpos1);
|
||||
this.inTile = iblockstate1.getBlock();
|
||||
this.inData = this.inTile.getMetaFromState(iblockstate1);
|
||||
this.motionX = (double)((float)(movingobjectposition.vec.xCoord - this.posX));
|
||||
this.motionY = (double)((float)(movingobjectposition.vec.yCoord - this.posY));
|
||||
this.motionZ = (double)((float)(movingobjectposition.vec.zCoord - this.posZ));
|
||||
float f5 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
|
||||
this.posX -= this.motionX / (double)f5 * 0.05000000074505806D;
|
||||
this.posY -= this.motionY / (double)f5 * 0.05000000074505806D;
|
||||
this.posZ -= this.motionZ / (double)f5 * 0.05000000074505806D;
|
||||
this.playSound(SoundEvent.BOWHIT, 1.0F, 1.2F / (this.rand.floatv() * 0.2F + 0.9F));
|
||||
this.inGround = true;
|
||||
this.arrowShake = 7;
|
||||
this.setIsCritical(false);
|
||||
|
||||
if (this.inTile.getMaterial() != Material.air)
|
||||
{
|
||||
this.inTile.onEntityCollidedWithBlock(this.worldObj, blockpos1, iblockstate1, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getIsCritical())
|
||||
{
|
||||
for (int k = 0; k < 4; ++k)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.CRIT, this.posX + this.motionX * (double)k / 4.0D, this.posY + this.motionY * (double)k / 4.0D, this.posZ + this.motionZ * (double)k / 4.0D, -this.motionX, -this.motionY + 0.2D, -this.motionZ);
|
||||
}
|
||||
}
|
||||
|
||||
this.posX += this.motionX;
|
||||
this.posY += this.motionY;
|
||||
this.posZ += this.motionZ;
|
||||
float f3 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotYaw = (float)(ExtMath.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
|
||||
for (this.rotPitch = (float)(ExtMath.atan2(this.motionY, (double)f3) * 180.0D / Math.PI); this.rotPitch - this.prevPitch < -180.0F; this.prevPitch -= 360.0F)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
while (this.rotPitch - this.prevPitch >= 180.0F)
|
||||
{
|
||||
this.prevPitch += 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw < -180.0F)
|
||||
{
|
||||
this.prevYaw -= 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw >= 180.0F)
|
||||
{
|
||||
this.prevYaw += 360.0F;
|
||||
}
|
||||
|
||||
this.rotPitch = this.prevPitch + (this.rotPitch - this.prevPitch) * 0.2F;
|
||||
this.rotYaw = this.prevYaw + (this.rotYaw - this.prevYaw) * 0.2F;
|
||||
float f4 = 0.99F;
|
||||
float f6 = 0.05F;
|
||||
|
||||
if (this.isInLiquid())
|
||||
{
|
||||
for (int i1 = 0; i1 < 4; ++i1)
|
||||
{
|
||||
float f8 = 0.25F;
|
||||
this.worldObj.spawnParticle(ParticleType.WATER_BUBBLE, this.posX - this.motionX * (double)f8, this.posY - this.motionY * (double)f8, this.posZ - this.motionZ * (double)f8, this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
|
||||
f4 = 0.6F;
|
||||
}
|
||||
|
||||
if (this.isWet())
|
||||
{
|
||||
this.extinguish();
|
||||
}
|
||||
|
||||
this.motionX *= (double)f4;
|
||||
this.motionY *= (double)f4;
|
||||
this.motionZ *= (double)f4;
|
||||
this.motionY -= (double)f6;
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
this.doBlockCollisions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setShort("xTile", (short)this.xTile);
|
||||
tagCompound.setShort("yTile", (short)this.yTile);
|
||||
tagCompound.setShort("zTile", (short)this.zTile);
|
||||
tagCompound.setShort("life", (short)this.ticksInGround);
|
||||
String resourcelocation = BlockRegistry.REGISTRY.getNameForObject(this.inTile);
|
||||
tagCompound.setString("inTile", resourcelocation == null ? "" : resourcelocation.toString());
|
||||
tagCompound.setByte("inData", (byte)this.inData);
|
||||
tagCompound.setByte("shake", (byte)this.arrowShake);
|
||||
tagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0));
|
||||
tagCompound.setByte("pickup", (byte)this.canBePickedUp);
|
||||
tagCompound.setDouble("damage", this.damage);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.xTile = tagCompund.getShort("xTile");
|
||||
this.yTile = tagCompund.getShort("yTile");
|
||||
this.zTile = tagCompund.getShort("zTile");
|
||||
this.ticksInGround = tagCompund.getShort("life");
|
||||
|
||||
if (tagCompund.hasKey("inTile", 8))
|
||||
{
|
||||
this.inTile = BlockRegistry.getByIdFallback(tagCompund.getString("inTile"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inTile = BlockRegistry.getBlockById(tagCompund.getByte("inTile") & 255);
|
||||
}
|
||||
|
||||
this.inData = tagCompund.getByte("inData") & 255;
|
||||
this.arrowShake = tagCompund.getByte("shake") & 255;
|
||||
this.inGround = tagCompund.getByte("inGround") == 1;
|
||||
|
||||
if (tagCompund.hasKey("damage", 99))
|
||||
{
|
||||
this.damage = tagCompund.getDouble("damage");
|
||||
}
|
||||
|
||||
if (tagCompund.hasKey("pickup", 99))
|
||||
{
|
||||
this.canBePickedUp = tagCompund.getByte("pickup");
|
||||
}
|
||||
else if (tagCompund.hasKey("player", 99))
|
||||
{
|
||||
this.canBePickedUp = tagCompund.getBoolean("player") ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by a player entity when they collide with an entity
|
||||
*/
|
||||
public void onCollideWithPlayer(EntityNPC entityIn)
|
||||
{
|
||||
if (!this.worldObj.client && this.inGround && this.arrowShake <= 0)
|
||||
{
|
||||
boolean flag = this.canBePickedUp == 1; // || this.canBePickedUp == 2 && entityIn.creative;
|
||||
|
||||
if (this.canBePickedUp == 1 && !entityIn.inventory.addItemStackToInventory(new ItemStack(Items.arrow, 1)))
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
this.playSound(SoundEvent.POP, 0.2F, ((this.rand.floatv() - this.rand.floatv()) * 0.7F + 1.0F) * 2.0F);
|
||||
entityIn.onItemPickup(this, 1);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setDamage(double damageIn)
|
||||
{
|
||||
this.damage = damageIn;
|
||||
}
|
||||
|
||||
public double getDamage()
|
||||
{
|
||||
return this.damage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of knockback the arrow applies when it hits a mob.
|
||||
*/
|
||||
public void setKnockbackStrength(int knockbackStrengthIn)
|
||||
{
|
||||
this.knockbackStrength = knockbackStrengthIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* If returns false, the item will not inflict any damage against entities.
|
||||
*/
|
||||
public boolean canAttackWithItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the arrow has a stream of critical hit particles flying behind it.
|
||||
*/
|
||||
public void setIsCritical(boolean critical)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (critical)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -2)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the arrow has a stream of critical hit particles flying behind it.
|
||||
*/
|
||||
public boolean getIsCritical()
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
return (b0 & 1) != 0;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.shootingEntity != null ? this.shootingEntity.getId() : this.getId();
|
||||
}
|
||||
|
||||
public boolean hasSpawnVelocity() {
|
||||
return true;
|
||||
}
|
||||
}
|
169
java/src/game/entity/projectile/EntityBox.java
Executable file
169
java/src/game/entity/projectile/EntityBox.java
Executable file
|
@ -0,0 +1,169 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.npc.EntityGargoyle;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Config;
|
||||
import game.potion.Potion;
|
||||
import game.potion.PotionEffect;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityBox extends EntityProjectile
|
||||
{
|
||||
public EntityBox(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.3125F, 0.3125F);
|
||||
}
|
||||
|
||||
public EntityBox(World worldIn, EntityLiving shooter, double accelX, double accelY, double accelZ, boolean invul)
|
||||
{
|
||||
super(worldIn, shooter, accelX, accelY, accelZ, 0.2f, 2.0f);
|
||||
this.setSize(0.3125F, 0.3125F);
|
||||
this.setInvulnerable(invul);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the motion factor for this projectile. The factor is multiplied by the original motion.
|
||||
*/
|
||||
protected float getMotionFactor()
|
||||
{
|
||||
return this.isInvulnerable() ? 0.98F : super.getMotionFactor();
|
||||
}
|
||||
|
||||
public EntityBox(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
this.setSize(0.3125F, 0.3125F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the entity is on fire. Used by render to add the fire effect on rendering.
|
||||
*/
|
||||
public boolean isBurning()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Explosion resistance of a block relative to this entity
|
||||
// */
|
||||
// public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, IBlockState blockStateIn)
|
||||
// {
|
||||
// float f = super.getExplosionResistance(explosionIn, worldIn, pos, blockStateIn);
|
||||
// Block block = blockStateIn.getBlock();
|
||||
//
|
||||
// if (this.isInvulnerable() && EntityWither.canDestroyBlock(block))
|
||||
// {
|
||||
// f = Math.min(0.8F, f);
|
||||
// }
|
||||
//
|
||||
// return f;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Called when this EntityFireball hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition movingObject)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
if (movingObject.entity != null)
|
||||
{
|
||||
if(Config.damageFlyingBox) {
|
||||
if (this.shootingEntity != null)
|
||||
{
|
||||
if (movingObject.entity.attackEntityFrom(DamageSource.causeMobDamage(this.shootingEntity),
|
||||
this.isInvulnerable() ? this.rand.range(10, 14) : this.rand.range(8, 10)))
|
||||
{
|
||||
if (!movingObject.entity.isEntityAlive())
|
||||
{
|
||||
this.shootingEntity.heal(this.rand.range(5, this.isInvulnerable() ? 10 : 7));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.applyEnchantments(this.shootingEntity, movingObject.entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
movingObject.entity.attackEntityFrom(DamageSource.magic, 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (movingObject.entity instanceof EntityLiving && !(movingObject.entity instanceof EntityGargoyle))
|
||||
{
|
||||
// int i = 0;
|
||||
//
|
||||
// if (this.worldObj.getDifficulty() == Difficulty.NORMAL)
|
||||
// {
|
||||
// i = 10;
|
||||
// }
|
||||
// else if (this.worldObj.getDifficulty() == Difficulty.HARD)
|
||||
// {
|
||||
// i = 40;
|
||||
// }
|
||||
//
|
||||
// if (i > 0)
|
||||
// {
|
||||
((EntityLiving)movingObject.entity).addEffect(new PotionEffect(Potion.moveSlowdown.id, 20 * this.rand.range(35, 55), this.rand.chance(1, 2, 5)));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, this.rand.frange(1.0f, 3.0f), false, false, false);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
// public void onUpdate() {
|
||||
// super.onUpdate();
|
||||
// if(!this.worldObj.client && this.age++ >= 200)
|
||||
// this.setDead();
|
||||
// }
|
||||
|
||||
// public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
// {
|
||||
// super.writeEntityToNBT(tagCompound);
|
||||
// tagCompound.setInteger("Age", this.age);
|
||||
// }
|
||||
//
|
||||
// public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
// {
|
||||
// super.readEntityFromNBT(tagCompund);
|
||||
// this.age = tagCompund.getInteger("Age");
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
this.dataWatcher.addObject(10, Byte.valueOf((byte)0));
|
||||
}
|
||||
|
||||
public boolean isInvulnerable()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectByte(10) == 1;
|
||||
}
|
||||
|
||||
public void setInvulnerable(boolean invulnerable)
|
||||
{
|
||||
this.dataWatcher.updateObject(10, Byte.valueOf((byte)(invulnerable ? 1 : 0)));
|
||||
}
|
||||
}
|
406
java/src/game/entity/projectile/EntityBullet.java
Executable file
406
java/src/game/entity/projectile/EntityBullet.java
Executable file
|
@ -0,0 +1,406 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.enchantment.EnchantmentHelper;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.entity.types.IProjectile;
|
||||
import game.init.Config;
|
||||
import game.init.SoundEvent;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.HitPosition;
|
||||
import game.world.Vec3;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityBullet extends Entity implements IProjectile, IObjectData
|
||||
{
|
||||
public Entity shootingEntity;
|
||||
private int ticksInAir;
|
||||
private int age;
|
||||
private int damage = 5;
|
||||
|
||||
public EntityBullet(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
}
|
||||
|
||||
public EntityBullet(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setPosition(x, y, z);
|
||||
}
|
||||
|
||||
public EntityBullet(World worldIn, double x, double y, double z, int data)
|
||||
{
|
||||
this(worldIn, x, y, z);
|
||||
Entity entity2 = worldIn.getEntityByID(data);
|
||||
if(entity2 instanceof EntityLiving) {
|
||||
this.shootingEntity = entity2;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityBullet(World worldIn, EntityLiving shooter, EntityLiving target, float velocity, float innacuracy)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.shootingEntity = shooter;
|
||||
|
||||
this.posY = shooter.posY + (double)shooter.getEyeHeight() - 0.10000000149011612D;
|
||||
double d0 = target.posX - shooter.posX;
|
||||
double d1 = target.getEntityBoundingBox().minY + (double)(target.height * 0.7f) - this.posY;
|
||||
double d2 = target.posZ - shooter.posZ;
|
||||
double d3 = (double)ExtMath.sqrtd(d0 * d0 + d2 * d2);
|
||||
|
||||
if (d3 >= 1.0E-7D)
|
||||
{
|
||||
float f = (float)(ExtMath.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
|
||||
float f1 = (float)(-(ExtMath.atan2(d1, d3) * 180.0D / Math.PI));
|
||||
double d4 = d0 / d3;
|
||||
double d5 = d2 / d3;
|
||||
this.setLocationAndAngles(shooter.posX + d4, this.posY, shooter.posZ + d5, f, f1);
|
||||
// float f2 = (float)(d3 * 0.20000000298023224D);
|
||||
this.setThrowableHeading(d0, d1 /* + (double)f2 */ , d2, velocity, innacuracy);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityBullet(World worldIn, EntityLiving shooter, float velocity)
|
||||
{
|
||||
super(worldIn);
|
||||
this.renderDistWeight = 10.0D;
|
||||
this.shootingEntity = shooter;
|
||||
|
||||
this.setSize(0.5F, 0.5F);
|
||||
this.setLocationAndAngles(shooter.posX, shooter.posY + (double)shooter.getEyeHeight(), shooter.posZ, shooter.rotYaw, shooter.rotPitch);
|
||||
this.posX -= (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.posY -= 0.10000000149011612D;
|
||||
this.posZ -= (double)(ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
this.motionX = (double)(-ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI));
|
||||
this.motionZ = (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI));
|
||||
this.motionY = (double)(-ExtMath.sin(this.rotPitch / 180.0F * (float)Math.PI));
|
||||
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, velocity, 0.5F);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to setArrowHeading, it's point the throwable entity to a x, y, z direction.
|
||||
*/
|
||||
public void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy)
|
||||
{
|
||||
float f = ExtMath.sqrtd(x * x + y * y + z * z);
|
||||
x = x / (double)f;
|
||||
y = y / (double)f;
|
||||
z = z / (double)f;
|
||||
x = x + this.rand.gaussian() * (double)(this.rand.chance() ? -1 : 1) * 0.007499999832361937D * (double)inaccuracy;
|
||||
y = y + this.rand.gaussian() * (double)(this.rand.chance() ? -1 : 1) * 0.007499999832361937D * (double)inaccuracy;
|
||||
z = z + this.rand.gaussian() * (double)(this.rand.chance() ? -1 : 1) * 0.007499999832361937D * (double)inaccuracy;
|
||||
x = x * (double)velocity;
|
||||
y = y * (double)velocity;
|
||||
z = z * (double)velocity;
|
||||
this.motionX = x;
|
||||
this.motionY = y;
|
||||
this.motionZ = z;
|
||||
float f1 = ExtMath.sqrtd(x * x + z * z);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(x, z) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(y, (double)f1) * 180.0D / Math.PI);
|
||||
}
|
||||
|
||||
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_)
|
||||
{
|
||||
this.setPosition(x, y, z);
|
||||
this.setRotation(yaw, pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double x, double y, double z)
|
||||
{
|
||||
this.motionX = x;
|
||||
this.motionY = y;
|
||||
this.motionZ = z;
|
||||
|
||||
if (this.prevPitch == 0.0F && this.prevYaw == 0.0F)
|
||||
{
|
||||
float f = ExtMath.sqrtd(x * x + z * z);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(x, z) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(y, (double)f) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch;
|
||||
this.prevYaw = this.rotYaw;
|
||||
this.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, this.rotPitch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
|
||||
if (this.prevPitch == 0.0F && this.prevYaw == 0.0F)
|
||||
{
|
||||
float f = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(this.motionY, (double)f) * 180.0D / Math.PI);
|
||||
}
|
||||
|
||||
if(!this.worldObj.client && ++this.age >= 200) {
|
||||
this.setDead();
|
||||
return;
|
||||
}
|
||||
++this.ticksInAir;
|
||||
Vec3 vec31 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
Vec3 vec3 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
HitPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec31, vec3, false, true, false);
|
||||
vec31 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
vec3 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
vec3 = new Vec3(movingobjectposition.vec.xCoord, movingobjectposition.vec.yCoord, movingobjectposition.vec.zCoord);
|
||||
}
|
||||
|
||||
Entity entity = null;
|
||||
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
double d0 = 0.0D;
|
||||
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
Entity entity1 = (Entity)list.get(i);
|
||||
|
||||
if (entity1.canBeCollidedWith() && (entity1 != this.shootingEntity || this.ticksInAir >= 5))
|
||||
{
|
||||
float f1 = 0.3F;
|
||||
BoundingBox axisalignedbb1 = entity1.getEntityBoundingBox().expand((double)f1, (double)f1, (double)f1);
|
||||
HitPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(vec31, vec3);
|
||||
|
||||
if (movingobjectposition1 != null)
|
||||
{
|
||||
double d1 = vec31.squareDistanceTo(movingobjectposition1.vec);
|
||||
|
||||
if (d1 < d0 || d0 == 0.0D)
|
||||
{
|
||||
entity = entity1;
|
||||
d0 = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
movingobjectposition = new HitPosition(entity);
|
||||
}
|
||||
|
||||
// if (movingobjectposition != null && movingobjectposition.entity != null && movingobjectposition.entity.isPlayer())
|
||||
// {
|
||||
// EntityNPC entityplayer = (EntityNPC)movingobjectposition.entity;
|
||||
//
|
||||
// if (entityplayer.creative || this.shootingEntity.isPlayer() && !((EntityNPC)this.shootingEntity).canAttackPlayer(entityplayer))
|
||||
// {
|
||||
// movingobjectposition = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
if (movingobjectposition.entity != null)
|
||||
{
|
||||
float f2 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
|
||||
int l = ExtMath.ceild((double)f2 * (double)this.damage);
|
||||
|
||||
DamageSource damagesource;
|
||||
|
||||
if (this.shootingEntity == null)
|
||||
{
|
||||
damagesource = DamageSource.causeShotDamage(this, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
damagesource = DamageSource.causeShotDamage(this, this.shootingEntity);
|
||||
}
|
||||
|
||||
if ((this.worldObj.client || Config.damageBullet) && movingobjectposition.entity.attackEntityFrom(damagesource, l))
|
||||
{
|
||||
if (movingobjectposition.entity instanceof EntityLiving)
|
||||
{
|
||||
EntityLiving entitylivingbase = (EntityLiving)movingobjectposition.entity;
|
||||
|
||||
// if (!this.worldObj.client)
|
||||
// {
|
||||
// entitylivingbase.setArrowCountInEntity(entitylivingbase.getArrowCountInEntity() + 1);
|
||||
// }
|
||||
|
||||
// if (this.knockbackStrength > 0)
|
||||
// {
|
||||
// float f7 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
//
|
||||
// if (f7 > 0.0F)
|
||||
// {
|
||||
// movingobjectposition.entityHit.addKnockback(this.motionX * (double)this.knockbackStrength * 0.6000000238418579D / (double)f7, 0.1D, this.motionZ * (double)this.knockbackStrength * 0.6000000238418579D / (double)f7);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (this.shootingEntity instanceof EntityLiving)
|
||||
{
|
||||
EnchantmentHelper.applyThornEnchantments(entitylivingbase, this.shootingEntity);
|
||||
EnchantmentHelper.applyArthropodEnchantments((EntityLiving)this.shootingEntity, entitylivingbase);
|
||||
}
|
||||
|
||||
// if (this.shootingEntity != null && movingobjectposition.entityHit != this.shootingEntity && movingobjectposition.entityHit.isPlayer() && this.shootingEntity.isPlayer())
|
||||
// {
|
||||
// ((EntityNPCMP)this.shootingEntity).netHandler.sendPacket(new S29PacketSoundEffect(
|
||||
// "random.successful_hit", shootingEntity.posX,
|
||||
// shootingEntity.posY + (double)shootingEntity.getEyeHeight(), shootingEntity.posZ, 0.18F, 0.45F));
|
||||
// }
|
||||
}
|
||||
|
||||
this.playSound(SoundEvent.METALHIT, 0.2F, this.rand.floatv() * 0.2F + 1.5F);
|
||||
|
||||
// this.setDead();
|
||||
}
|
||||
// else
|
||||
// {
|
||||
this.setDead();
|
||||
// this.motionX *= -0.10000000149011612D;
|
||||
// this.motionY *= -0.10000000149011612D;
|
||||
// this.motionZ *= -0.10000000149011612D;
|
||||
// this.rotYaw += 180.0F;
|
||||
// this.prevYaw += 180.0F;
|
||||
// this.ticksInAir = 0;
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
this.playSound(SoundEvent.METALHIT, 0.5F, this.rand.floatv() * 0.2F + 1.5F);
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
this.posX += this.motionX;
|
||||
this.posY += this.motionY;
|
||||
this.posZ += this.motionZ;
|
||||
float f3 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotYaw = (float)(ExtMath.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
|
||||
for (this.rotPitch = (float)(ExtMath.atan2(this.motionY, (double)f3) * 180.0D / Math.PI); this.rotPitch - this.prevPitch < -180.0F; this.prevPitch -= 360.0F)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
while (this.rotPitch - this.prevPitch >= 180.0F)
|
||||
{
|
||||
this.prevPitch += 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw < -180.0F)
|
||||
{
|
||||
this.prevYaw -= 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw >= 180.0F)
|
||||
{
|
||||
this.prevYaw += 360.0F;
|
||||
}
|
||||
|
||||
this.rotPitch = this.prevPitch + (this.rotPitch - this.prevPitch) * 0.2F;
|
||||
this.rotYaw = this.prevYaw + (this.rotYaw - this.prevYaw) * 0.2F;
|
||||
// float f4 = 0.99F;
|
||||
// float f6 = 0.001F;
|
||||
|
||||
// if (this.isInLiquid())
|
||||
// {
|
||||
// for (int i1 = 0; i1 < 4; ++i1)
|
||||
// {
|
||||
// float f8 = 0.25F;
|
||||
// this.worldObj.spawnParticle(ParticleType.WATER_BUBBLE, this.posX - this.motionX * (double)f8, this.posY - this.motionY * (double)f8, this.posZ - this.motionZ * (double)f8, this.motionX, this.motionY, this.motionZ);
|
||||
// }
|
||||
//
|
||||
// f4 = 0.85F;
|
||||
// }
|
||||
|
||||
// if (this.isWet())
|
||||
// {
|
||||
// this.extinguish();
|
||||
// }
|
||||
|
||||
// this.motionX *= (double)f4;
|
||||
// this.motionY *= (double)f4;
|
||||
// this.motionZ *= (double)f4;
|
||||
// this.motionY -= (double)f6;
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
// this.doBlockCollisions();
|
||||
}
|
||||
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setInteger("damage", this.damage);
|
||||
tagCompound.setInteger("age", this.age);
|
||||
}
|
||||
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
if(tagCompund.hasKey("damage", 99))
|
||||
this.damage = tagCompund.getInteger("damage");
|
||||
this.age = tagCompund.getInteger("age");
|
||||
}
|
||||
|
||||
protected boolean canTriggerWalking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setDamage(int damageIn)
|
||||
{
|
||||
this.damage = damageIn;
|
||||
}
|
||||
|
||||
public int getDamage()
|
||||
{
|
||||
return this.damage;
|
||||
}
|
||||
|
||||
public boolean canAttackWithItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public float getEyeHeight()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 96;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.shootingEntity != null ? this.shootingEntity.getId() : this.getId();
|
||||
}
|
||||
|
||||
public boolean hasSpawnVelocity() {
|
||||
return true;
|
||||
}
|
||||
}
|
165
java/src/game/entity/projectile/EntityDie.java
Executable file
165
java/src/game/entity/projectile/EntityDie.java
Executable file
|
@ -0,0 +1,165 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityThrowable;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemDie;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityDie extends EntityThrowable implements IObjectData
|
||||
{
|
||||
public int sides;
|
||||
private boolean noPickup;
|
||||
|
||||
public EntityDie(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.1f, 0.1f);
|
||||
}
|
||||
|
||||
public EntityDie(World worldIn, EntityLiving throwerIn, int sides, boolean noPickup)
|
||||
{
|
||||
super(worldIn, throwerIn);
|
||||
this.setSize(0.1f, 0.1f);
|
||||
this.sides = sides;
|
||||
this.noPickup = noPickup;
|
||||
}
|
||||
|
||||
public EntityDie(World worldIn, double x, double y, double z, int sides)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
this.setSize(0.1f, 0.1f);
|
||||
this.sides = sides;
|
||||
}
|
||||
|
||||
protected void onImpact(HitPosition pos)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.setValue(this.rand.roll(this.sides <= 0 ? 6 : this.sides));
|
||||
this.motionX = this.motionY = this.motionZ = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(16, 0);
|
||||
}
|
||||
|
||||
public void setValue(int value)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, value);
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return this.dataWatcher.getWatchableObjectInt(16);
|
||||
}
|
||||
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("Sides", this.sides);
|
||||
tagCompound.setInteger("Value", this.getValue());
|
||||
tagCompound.setBoolean("NoPickup", this.noPickup);
|
||||
}
|
||||
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.sides = tagCompund.getInteger("Sides");
|
||||
this.setValue(tagCompund.getInteger("Value"));
|
||||
this.noPickup = tagCompund.getBoolean("NoPickup");
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.sides;
|
||||
}
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public void onUpdate()
|
||||
{
|
||||
if (this.getValue() != 0)
|
||||
{
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.motionY -= 0.03999999910593033D;
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.9800000190734863D;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= 0.9800000190734863D;
|
||||
}
|
||||
else {
|
||||
super.onUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected float getVelocity()
|
||||
{
|
||||
return 0.3F;
|
||||
}
|
||||
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return this.getValue() != 0;
|
||||
}
|
||||
|
||||
public int getStackMeta() {
|
||||
int meta = 1;
|
||||
for(int z = 0; z < ItemDie.DIE_SIDES.length; z++) {
|
||||
if(this.sides == ItemDie.DIE_SIDES[z])
|
||||
meta = z;
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
public ItemStack getStack() {
|
||||
return new ItemStack(Items.die, 1, this.getStackMeta());
|
||||
}
|
||||
|
||||
public boolean interactFirst(EntityNPC player)
|
||||
{
|
||||
if(!this.worldObj.client)
|
||||
{
|
||||
if(this.noPickup)
|
||||
this.setDead();
|
||||
else if(player.inventory.addItemStackToInventory(this.getStack())) {
|
||||
this.setDead();
|
||||
player.worldObj.playSoundAtEntity(player, SoundEvent.POP, 0.2F, ((player.getRNG().floatv() - player.getRNG().floatv()) * 0.7F + 1.0F) * 2.0F);
|
||||
player.inventoryContainer.detectAndSendChanges();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if(this.isEntityInvulnerable(source))
|
||||
return false;
|
||||
if(!this.worldObj.client && !this.dead) {
|
||||
if(!this.noPickup)
|
||||
this.entityDropItem(this.getStack(), 0.0f);
|
||||
this.setDead();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getDisplayName()
|
||||
{
|
||||
if(this.getValue() == 0)
|
||||
return null;
|
||||
return ItemDie.DIE_COLORS[this.getStackMeta()] + "" + this.getValue();
|
||||
}
|
||||
}
|
80
java/src/game/entity/projectile/EntityDynamite.java
Executable file
80
java/src/game/entity/projectile/EntityDynamite.java
Executable file
|
@ -0,0 +1,80 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityThrowable;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.init.Config;
|
||||
import game.init.ItemRegistry;
|
||||
import game.init.Items;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityDynamite extends EntityThrowable implements IObjectData
|
||||
{
|
||||
public int explosionSize;
|
||||
|
||||
public EntityDynamite(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityDynamite(World worldIn, EntityLiving throwerIn, int power)
|
||||
{
|
||||
super(worldIn, throwerIn);
|
||||
this.explosionSize = power & 7;
|
||||
}
|
||||
|
||||
public EntityDynamite(World worldIn, double x, double y, double z, int power)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
this.explosionSize = power & 7;
|
||||
}
|
||||
|
||||
protected void onImpact(HitPosition pos)
|
||||
{
|
||||
if (pos.entity != null && Config.knockDynamite)
|
||||
{
|
||||
pos.entity.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
float f = 4.0F * (((float)this.explosionSize)+1.0f);
|
||||
EntityLiving thrower = this.getThrower();
|
||||
this.worldObj.createAltExplosion(thrower == null ? this : thrower, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, f, true);
|
||||
}
|
||||
|
||||
for (int k = 0; k < 8; ++k)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.ITEM_CRACK, this.posX, this.posY, this.posZ, ((double)this.rand.floatv() - 0.5D) * 0.08D, ((double)this.rand.floatv() - 0.5D) * 0.08D, ((double)this.rand.floatv() - 0.5D) * 0.08D, ItemRegistry.getIdFromItem(Items.dynamite), this.explosionSize);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setByte("Power", (byte)this.explosionSize);
|
||||
}
|
||||
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.explosionSize = ((int)tagCompund.getByte("Power")) & 7;
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.explosionSize;
|
||||
}
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
}
|
71
java/src/game/entity/projectile/EntityEgg.java
Executable file
71
java/src/game/entity/projectile/EntityEgg.java
Executable file
|
@ -0,0 +1,71 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.animal.EntityChicken;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityThrowable;
|
||||
import game.init.Config;
|
||||
import game.init.ItemRegistry;
|
||||
import game.init.Items;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityEgg extends EntityThrowable
|
||||
{
|
||||
public EntityEgg(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityEgg(World worldIn, EntityLiving throwerIn)
|
||||
{
|
||||
super(worldIn, throwerIn);
|
||||
}
|
||||
|
||||
public EntityEgg(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityThrowable hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition p_70184_1_)
|
||||
{
|
||||
if (p_70184_1_.entity != null && Config.knockEgg)
|
||||
{
|
||||
p_70184_1_.entity.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client && this.rand.chance(8) && Config.mobs && Config.spawnEggChicken)
|
||||
{
|
||||
int i = this.rand.chance(1, 4, 32);
|
||||
|
||||
// if (this.rand.chance(32))
|
||||
// {
|
||||
// i = 4;
|
||||
// }
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
EntityChicken entitychicken = new EntityChicken(this.worldObj);
|
||||
entitychicken.setGrowingAge(-24000);
|
||||
entitychicken.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, 0.0F);
|
||||
this.worldObj.spawnEntityInWorld(entitychicken);
|
||||
}
|
||||
}
|
||||
|
||||
double d0 = 0.08D;
|
||||
|
||||
for (int k = 0; k < 8; ++k)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.ITEM_CRACK, this.posX, this.posY, this.posZ, ((double)this.rand.floatv() - 0.5D) * 0.08D, ((double)this.rand.floatv() - 0.5D) * 0.08D, ((double)this.rand.floatv() - 0.5D) * 0.08D, ItemRegistry.getIdFromItem(Items.egg));
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
98
java/src/game/entity/projectile/EntityFireCharge.java
Executable file
98
java/src/game/entity/projectile/EntityFireCharge.java
Executable file
|
@ -0,0 +1,98 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.world.BlockPos;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityFireCharge extends EntityProjectile
|
||||
{
|
||||
public EntityFireCharge(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.3125F, 0.3125F);
|
||||
}
|
||||
|
||||
public EntityFireCharge(World worldIn, EntityLiving shooter, double accelX, double accelY, double accelZ)
|
||||
{
|
||||
super(worldIn, shooter, accelX, accelY, accelZ, 0.35f, 1.0f);
|
||||
this.setSize(0.3125F, 0.3125F);
|
||||
}
|
||||
|
||||
public EntityFireCharge(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
this.setSize(0.3125F, 0.3125F);
|
||||
}
|
||||
|
||||
public EntityFireCharge(World worldIn, double x, double y, double z, double accelX, double accelY, double accelZ)
|
||||
{
|
||||
this(worldIn, x, y, z);
|
||||
this.setAcceleration(accelX, accelY, accelZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityFireball hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition movingObject)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
if (movingObject.entity != null)
|
||||
{
|
||||
boolean flag = Config.damageFireball &&
|
||||
movingObject.entity.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 6);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
this.applyEnchantments(this.shootingEntity, movingObject.entity);
|
||||
|
||||
// if (!movingObject.entityHit.isImmuneToFire())
|
||||
// {
|
||||
movingObject.entity.setOnFireFromObject(5);
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean flag1 = true;
|
||||
|
||||
if (this.shootingEntity != null && this.shootingEntity instanceof EntityLiving) // && !(this.shootingEntity.isPlayer()))
|
||||
{
|
||||
flag1 = Config.mobGrief;
|
||||
}
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
BlockPos blockpos = movingObject.block.offset(movingObject.side);
|
||||
|
||||
if (this.worldObj.isAirBlock(blockpos))
|
||||
{
|
||||
this.worldObj.setState(blockpos, Blocks.fire.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
77
java/src/game/entity/projectile/EntityFireball.java
Executable file
77
java/src/game/entity/projectile/EntityFireball.java
Executable file
|
@ -0,0 +1,77 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.Config;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityFireball extends EntityProjectile
|
||||
{
|
||||
public int explosionPower = 1;
|
||||
|
||||
public EntityFireball(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.45F, 0.45F);
|
||||
}
|
||||
|
||||
public EntityFireball(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
this.setSize(0.45F, 0.45F);
|
||||
}
|
||||
|
||||
public EntityFireball(World worldIn, EntityLiving shooter, double accelX, double accelY, double accelZ, double velocity)
|
||||
{
|
||||
super(worldIn, shooter, accelX, accelY, accelZ, 0.1, velocity);
|
||||
this.setSize(0.45F, 0.45F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityFireball hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition movingObject)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
if (Config.damageFireball && movingObject.entity != null)
|
||||
{
|
||||
movingObject.entity.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 8);
|
||||
this.applyEnchantments(this.shootingEntity, movingObject.entity);
|
||||
}
|
||||
|
||||
boolean flag = Config.mobGrief;
|
||||
this.worldObj.newExplosion(this.shootingEntity, this.posX, this.posY, this.posZ, (float)this.explosionPower, flag, false, true);
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("ExplosionPower", this.explosionPower);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
|
||||
if (tagCompund.hasKey("ExplosionPower", 99))
|
||||
{
|
||||
this.explosionPower = tagCompund.getInteger("ExplosionPower");
|
||||
}
|
||||
}
|
||||
}
|
668
java/src/game/entity/projectile/EntityHook.java
Executable file
668
java/src/game/entity/projectile/EntityHook.java
Executable file
|
@ -0,0 +1,668 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.enchantment.EnchantmentHelper;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.item.EntityItem;
|
||||
import game.entity.item.EntityXp;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.init.BlockRegistry;
|
||||
import game.init.Blocks;
|
||||
import game.init.Config;
|
||||
import game.init.Items;
|
||||
import game.init.SoundEvent;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.HitPosition;
|
||||
import game.world.Vec3;
|
||||
import game.world.World;
|
||||
import game.world.WorldServer;
|
||||
import game.worldgen.LootConstants;
|
||||
|
||||
public class EntityHook extends Entity implements IObjectData
|
||||
{
|
||||
private int xTile;
|
||||
private int yTile;
|
||||
private int zTile;
|
||||
private Block inTile;
|
||||
private boolean inGround;
|
||||
public int shake;
|
||||
public EntityNPC angler;
|
||||
private int ticksInGround;
|
||||
private int ticksInAir;
|
||||
private int ticksCatchable;
|
||||
private int ticksCaughtDelay;
|
||||
private int ticksCatchableDelay;
|
||||
private float fishApproachAngle;
|
||||
public Entity caughtEntity;
|
||||
private int fishPosRotationIncrements;
|
||||
private double fishX;
|
||||
private double fishY;
|
||||
private double fishZ;
|
||||
private double fishYaw;
|
||||
private double fishPitch;
|
||||
private double clientMotionX;
|
||||
private double clientMotionY;
|
||||
private double clientMotionZ;
|
||||
|
||||
public EntityHook(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.xTile = -1;
|
||||
this.yTile = -1;
|
||||
this.zTile = -1;
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.noFrustumCheck = true;
|
||||
}
|
||||
|
||||
public EntityHook(World worldIn, double x, double y, double z, int data) //, EntityNPC anglerIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.xTile = -1;
|
||||
this.yTile = -1;
|
||||
this.zTile = -1;
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.noFrustumCheck = true;
|
||||
// this(worldIn);
|
||||
this.setPosition(x, y, z);
|
||||
// this.noFrustumCheck = true;
|
||||
// this.angler = anglerIn;
|
||||
// if(anglerIn != null) {
|
||||
// anglerIn.fishEntity = this;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public EntityFishHook(World worldIn, double x, double y, double z, int data)
|
||||
// {
|
||||
// this(worldIn, x, y, z, null);
|
||||
Entity entity1 = worldIn.getEntityByID(data);
|
||||
|
||||
if (entity1 != null && entity1.isPlayer())
|
||||
{
|
||||
this.angler = (EntityNPC)entity1;
|
||||
this.angler.fishEntity = this;
|
||||
}
|
||||
else {
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
public EntityHook(World worldIn, EntityNPC fishingPlayer)
|
||||
{
|
||||
super(worldIn);
|
||||
this.xTile = -1;
|
||||
this.yTile = -1;
|
||||
this.zTile = -1;
|
||||
this.noFrustumCheck = true;
|
||||
this.angler = fishingPlayer;
|
||||
this.angler.fishEntity = this;
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.setLocationAndAngles(fishingPlayer.posX, fishingPlayer.posY + (double)fishingPlayer.getEyeHeight(), fishingPlayer.posZ, fishingPlayer.rotYaw, fishingPlayer.rotPitch);
|
||||
this.posX -= (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.posY -= 0.10000000149011612D;
|
||||
this.posZ -= (double)(ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
float f = 0.4F;
|
||||
this.motionX = (double)(-ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI) * f);
|
||||
this.motionZ = (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI) * f);
|
||||
this.motionY = (double)(-ExtMath.sin(this.rotPitch / 180.0F * (float)Math.PI) * f);
|
||||
this.handleHookCasting(this.motionX, this.motionY, this.motionZ, 1.5F, 1.0F);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
public boolean writeToNBTOptional(NBTTagCompound tagCompund)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
|
||||
* length * 64 * renderDistanceWeight Args: distance
|
||||
*/
|
||||
public boolean isInRangeToRenderDist(double distance)
|
||||
{
|
||||
double d0 = this.getEntityBoundingBox().getAverageEdgeLength() * 4.0D;
|
||||
|
||||
if (Double.isNaN(d0))
|
||||
{
|
||||
d0 = 4.0D;
|
||||
}
|
||||
|
||||
d0 = d0 * 64.0D;
|
||||
return distance < d0 * d0;
|
||||
}
|
||||
|
||||
public void handleHookCasting(double p_146035_1_, double p_146035_3_, double p_146035_5_, float p_146035_7_, float p_146035_8_)
|
||||
{
|
||||
float f = ExtMath.sqrtd(p_146035_1_ * p_146035_1_ + p_146035_3_ * p_146035_3_ + p_146035_5_ * p_146035_5_);
|
||||
p_146035_1_ = p_146035_1_ / (double)f;
|
||||
p_146035_3_ = p_146035_3_ / (double)f;
|
||||
p_146035_5_ = p_146035_5_ / (double)f;
|
||||
p_146035_1_ = p_146035_1_ + this.rand.gaussian() * 0.007499999832361937D * (double)p_146035_8_;
|
||||
p_146035_3_ = p_146035_3_ + this.rand.gaussian() * 0.007499999832361937D * (double)p_146035_8_;
|
||||
p_146035_5_ = p_146035_5_ + this.rand.gaussian() * 0.007499999832361937D * (double)p_146035_8_;
|
||||
p_146035_1_ = p_146035_1_ * (double)p_146035_7_;
|
||||
p_146035_3_ = p_146035_3_ * (double)p_146035_7_;
|
||||
p_146035_5_ = p_146035_5_ * (double)p_146035_7_;
|
||||
this.motionX = p_146035_1_;
|
||||
this.motionY = p_146035_3_;
|
||||
this.motionZ = p_146035_5_;
|
||||
float f1 = ExtMath.sqrtd(p_146035_1_ * p_146035_1_ + p_146035_5_ * p_146035_5_);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(p_146035_1_, p_146035_5_) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(p_146035_3_, (double)f1) * 180.0D / Math.PI);
|
||||
this.ticksInGround = 0;
|
||||
}
|
||||
|
||||
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean p_180426_10_)
|
||||
{
|
||||
this.fishX = x;
|
||||
this.fishY = y;
|
||||
this.fishZ = z;
|
||||
this.fishYaw = (double)yaw;
|
||||
this.fishPitch = (double)pitch;
|
||||
this.fishPosRotationIncrements = posRotationIncrements;
|
||||
this.motionX = this.clientMotionX;
|
||||
this.motionY = this.clientMotionY;
|
||||
this.motionZ = this.clientMotionZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double x, double y, double z)
|
||||
{
|
||||
this.clientMotionX = this.motionX = x;
|
||||
this.clientMotionY = this.motionY = y;
|
||||
this.clientMotionZ = this.motionZ = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
super.onUpdate();
|
||||
if(this.angler == null) {
|
||||
this.setDead();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.fishPosRotationIncrements > 0)
|
||||
{
|
||||
double d7 = this.posX + (this.fishX - this.posX) / (double)this.fishPosRotationIncrements;
|
||||
double d8 = this.posY + (this.fishY - this.posY) / (double)this.fishPosRotationIncrements;
|
||||
double d9 = this.posZ + (this.fishZ - this.posZ) / (double)this.fishPosRotationIncrements;
|
||||
double d1 = ExtMath.wrapd(this.fishYaw - (double)this.rotYaw);
|
||||
this.rotYaw = (float)((double)this.rotYaw + d1 / (double)this.fishPosRotationIncrements);
|
||||
this.rotPitch = (float)((double)this.rotPitch + (this.fishPitch - (double)this.rotPitch) / (double)this.fishPosRotationIncrements);
|
||||
--this.fishPosRotationIncrements;
|
||||
this.setPosition(d7, d8, d9);
|
||||
this.setRotation(this.rotYaw, this.rotPitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
ItemStack itemstack = this.angler.getCurrentEquippedItem();
|
||||
|
||||
if (this.angler.dead || !this.angler.isEntityAlive() || itemstack == null || itemstack.getItem() != Items.fishing_rod || this.getDistanceSqToEntity(this.angler) > 1024.0D)
|
||||
{
|
||||
this.setDead();
|
||||
this.angler.fishEntity = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.caughtEntity != null)
|
||||
{
|
||||
if (!this.caughtEntity.dead)
|
||||
{
|
||||
this.posX = this.caughtEntity.posX;
|
||||
double d17 = (double)this.caughtEntity.height;
|
||||
this.posY = this.caughtEntity.getEntityBoundingBox().minY + d17 * 0.8D;
|
||||
this.posZ = this.caughtEntity.posZ;
|
||||
return;
|
||||
}
|
||||
|
||||
this.caughtEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.shake > 0)
|
||||
{
|
||||
--this.shake;
|
||||
}
|
||||
|
||||
if (this.inGround)
|
||||
{
|
||||
if (this.worldObj.getState(new BlockPos(this.xTile, this.yTile, this.zTile)).getBlock() == this.inTile)
|
||||
{
|
||||
++this.ticksInGround;
|
||||
|
||||
if (this.ticksInGround == 1200)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.inGround = false;
|
||||
this.motionX *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionY *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionZ *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.ticksInGround = 0;
|
||||
this.ticksInAir = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++this.ticksInAir;
|
||||
}
|
||||
|
||||
Vec3 vec31 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
Vec3 vec3 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
HitPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec31, vec3);
|
||||
vec31 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
vec3 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
vec3 = new Vec3(movingobjectposition.vec.xCoord, movingobjectposition.vec.yCoord, movingobjectposition.vec.zCoord);
|
||||
}
|
||||
|
||||
Entity entity = null;
|
||||
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
double d0 = 0.0D;
|
||||
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
Entity entity1 = (Entity)list.get(i);
|
||||
|
||||
if (entity1.canBeCollidedWith() && (entity1 != this.angler || this.ticksInAir >= 5))
|
||||
{
|
||||
float f = 0.3F;
|
||||
BoundingBox axisalignedbb = entity1.getEntityBoundingBox().expand((double)f, (double)f, (double)f);
|
||||
HitPosition movingobjectposition1 = axisalignedbb.calculateIntercept(vec31, vec3);
|
||||
|
||||
if (movingobjectposition1 != null)
|
||||
{
|
||||
double d2 = vec31.squareDistanceTo(movingobjectposition1.vec);
|
||||
|
||||
if (d2 < d0 || d0 == 0.0D)
|
||||
{
|
||||
entity = entity1;
|
||||
d0 = d2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
movingobjectposition = new HitPosition(entity);
|
||||
}
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
if (movingobjectposition.entity != null)
|
||||
{
|
||||
if (this.worldObj.client || !Config.knockHook || movingobjectposition.entity.attackEntityFrom(
|
||||
DamageSource.causeThrownDamage(this, this.angler), 0) || !Config.hookCheckDamage)
|
||||
{
|
||||
if(this.worldObj.client || Config.hookEntity) // && (!(movingobjectposition.entity.isPlayer())
|
||||
// || !((EntityNPC)movingobjectposition.entity).creative)))
|
||||
this.caughtEntity = movingobjectposition.entity;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inGround = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.inGround)
|
||||
{
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
float f5 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotYaw = (float)(ExtMath.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
|
||||
for (this.rotPitch = (float)(ExtMath.atan2(this.motionY, (double)f5) * 180.0D / Math.PI); this.rotPitch - this.prevPitch < -180.0F; this.prevPitch -= 360.0F)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
while (this.rotPitch - this.prevPitch >= 180.0F)
|
||||
{
|
||||
this.prevPitch += 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw < -180.0F)
|
||||
{
|
||||
this.prevYaw -= 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw >= 180.0F)
|
||||
{
|
||||
this.prevYaw += 360.0F;
|
||||
}
|
||||
|
||||
this.rotPitch = this.prevPitch + (this.rotPitch - this.prevPitch) * 0.2F;
|
||||
this.rotYaw = this.prevYaw + (this.rotYaw - this.prevYaw) * 0.2F;
|
||||
float f6 = 0.92F;
|
||||
|
||||
if (this.onGround || this.collidedHorizontally)
|
||||
{
|
||||
f6 = 0.5F;
|
||||
}
|
||||
|
||||
int j = 5;
|
||||
double d10 = 0.0D;
|
||||
|
||||
for (int k = 0; k < j; ++k)
|
||||
{
|
||||
BoundingBox axisalignedbb1 = this.getEntityBoundingBox();
|
||||
double d3 = axisalignedbb1.maxY - axisalignedbb1.minY;
|
||||
double d4 = axisalignedbb1.minY + d3 * (double)k / (double)j;
|
||||
double d5 = axisalignedbb1.minY + d3 * (double)(k + 1) / (double)j;
|
||||
BoundingBox axisalignedbb2 = new BoundingBox(axisalignedbb1.minX, d4, axisalignedbb1.minZ, axisalignedbb1.maxX, d5, axisalignedbb1.maxZ);
|
||||
|
||||
if (this.worldObj.isAABBInLiquid(axisalignedbb2))
|
||||
{
|
||||
d10 += 1.0D / (double)j;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.worldObj.client && d10 > 0.0D)
|
||||
{
|
||||
WorldServer worldserver = (WorldServer)this.worldObj;
|
||||
int l = 1;
|
||||
BlockPos blockpos = (new BlockPos(this)).up();
|
||||
|
||||
if (this.rand.floatv() < 0.25F && this.worldObj.isRainingAt(blockpos, true))
|
||||
{
|
||||
l = 2;
|
||||
}
|
||||
|
||||
if (this.rand.floatv() < 0.5F && !this.worldObj.canSeeSky(blockpos))
|
||||
{
|
||||
--l;
|
||||
}
|
||||
|
||||
if (this.ticksCatchable > 0)
|
||||
{
|
||||
--this.ticksCatchable;
|
||||
|
||||
if (this.ticksCatchable <= 0)
|
||||
{
|
||||
this.ticksCaughtDelay = 0;
|
||||
this.ticksCatchableDelay = 0;
|
||||
}
|
||||
}
|
||||
else if (this.ticksCatchableDelay > 0)
|
||||
{
|
||||
this.ticksCatchableDelay -= l;
|
||||
|
||||
if (this.ticksCatchableDelay <= 0)
|
||||
{
|
||||
this.motionY -= 0.20000000298023224D;
|
||||
this.playSound(SoundEvent.SPLASH, 0.25F, 1.0F + (this.rand.floatv() - this.rand.floatv()) * 0.4F);
|
||||
float f8 = (float)ExtMath.floord(this.getEntityBoundingBox().minY);
|
||||
worldserver.spawnParticle(ParticleType.WATER_BUBBLE, this.posX, (double)(f8 + 1.0F), this.posZ, (int)(1.0F + this.width * 20.0F), (double)this.width, 0.0D, (double)this.width, 0.20000000298023224D);
|
||||
worldserver.spawnParticle(ParticleType.WATER_WAKE, this.posX, (double)(f8 + 1.0F), this.posZ, (int)(1.0F + this.width * 20.0F), (double)this.width, 0.0D, (double)this.width, 0.20000000298023224D);
|
||||
this.ticksCatchable = this.rand.range(10, 30);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.fishApproachAngle = (float)((double)this.fishApproachAngle + this.rand.gaussian() * 4.0D);
|
||||
float f7 = this.fishApproachAngle * 0.017453292F;
|
||||
float f10 = ExtMath.sin(f7);
|
||||
float f11 = ExtMath.cos(f7);
|
||||
double d13 = this.posX + (double)(f10 * (float)this.ticksCatchableDelay * 0.1F);
|
||||
double d15 = (double)((float)ExtMath.floord(this.getEntityBoundingBox().minY) + 1.0F);
|
||||
double d16 = this.posZ + (double)(f11 * (float)this.ticksCatchableDelay * 0.1F);
|
||||
Block block1 = worldserver.getState(new BlockPos((int)d13, (int)d15 - 1, (int)d16)).getBlock();
|
||||
|
||||
if (block1 == Blocks.water || block1 == Blocks.flowing_water)
|
||||
{
|
||||
if (this.rand.floatv() < 0.15F)
|
||||
{
|
||||
worldserver.spawnParticle(ParticleType.WATER_BUBBLE, d13, d15 - 0.10000000149011612D, d16, 1, (double)f10, 0.1D, (double)f11, 0.0D);
|
||||
}
|
||||
|
||||
float f3 = f10 * 0.04F;
|
||||
float f4 = f11 * 0.04F;
|
||||
worldserver.spawnParticle(ParticleType.WATER_WAKE, d13, d15, d16, 0, (double)f4, 0.01D, (double)(-f3), 1.0D);
|
||||
worldserver.spawnParticle(ParticleType.WATER_WAKE, d13, d15, d16, 0, (double)(-f4), 0.01D, (double)f3, 1.0D);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.ticksCaughtDelay > 0)
|
||||
{
|
||||
this.ticksCaughtDelay -= l;
|
||||
float f1 = 0.15F;
|
||||
|
||||
if (this.ticksCaughtDelay < 20)
|
||||
{
|
||||
f1 = (float)((double)f1 + (double)(20 - this.ticksCaughtDelay) * 0.05D);
|
||||
}
|
||||
else if (this.ticksCaughtDelay < 40)
|
||||
{
|
||||
f1 = (float)((double)f1 + (double)(40 - this.ticksCaughtDelay) * 0.02D);
|
||||
}
|
||||
else if (this.ticksCaughtDelay < 60)
|
||||
{
|
||||
f1 = (float)((double)f1 + (double)(60 - this.ticksCaughtDelay) * 0.01D);
|
||||
}
|
||||
|
||||
if (this.rand.floatv() < f1)
|
||||
{
|
||||
float f9 = this.rand.frange(0.0F, 360.0F) * 0.017453292F;
|
||||
float f2 = this.rand.frange(25.0F, 60.0F);
|
||||
double d12 = this.posX + (double)(ExtMath.sin(f9) * f2 * 0.1F);
|
||||
double d14 = (double)((float)ExtMath.floord(this.getEntityBoundingBox().minY) + 1.0F);
|
||||
double d6 = this.posZ + (double)(ExtMath.cos(f9) * f2 * 0.1F);
|
||||
Block block = worldserver.getState(new BlockPos((int)d12, (int)d14 - 1, (int)d6)).getBlock();
|
||||
|
||||
if (block == Blocks.water || block == Blocks.flowing_water)
|
||||
{
|
||||
worldserver.spawnParticle(ParticleType.WATER_SPLASH, d12, d14, d6, this.rand.range(2, 3), 0.10000000149011612D, 0.0D, 0.10000000149011612D, 0.0D);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.ticksCaughtDelay <= 0)
|
||||
{
|
||||
this.fishApproachAngle = this.rand.frange(0.0F, 360.0F);
|
||||
this.ticksCatchableDelay = this.rand.range(20, 80);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ticksCaughtDelay = this.rand.range(100, 900);
|
||||
this.ticksCaughtDelay -= EnchantmentHelper.getLureModifier(this.angler) * 20 * 5;
|
||||
}
|
||||
|
||||
if (this.ticksCatchable > 0)
|
||||
{
|
||||
this.motionY -= (double)(this.rand.floatv() * this.rand.floatv() * this.rand.floatv()) * 0.2D;
|
||||
}
|
||||
}
|
||||
|
||||
double d11 = d10 * 2.0D - 1.0D;
|
||||
this.motionY += 0.03999999910593033D * d11;
|
||||
|
||||
if (d10 > 0.0D)
|
||||
{
|
||||
f6 = (float)((double)f6 * 0.9D);
|
||||
this.motionY *= 0.8D;
|
||||
}
|
||||
|
||||
this.motionX *= (double)f6;
|
||||
this.motionY *= (double)f6;
|
||||
this.motionZ *= (double)f6;
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setShort("xTile", (short)this.xTile);
|
||||
tagCompound.setShort("yTile", (short)this.yTile);
|
||||
tagCompound.setShort("zTile", (short)this.zTile);
|
||||
String resourcelocation = BlockRegistry.REGISTRY.getNameForObject(this.inTile);
|
||||
tagCompound.setString("inTile", resourcelocation == null ? "" : resourcelocation.toString());
|
||||
tagCompound.setByte("shake", (byte)this.shake);
|
||||
tagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.xTile = tagCompund.getShort("xTile");
|
||||
this.yTile = tagCompund.getShort("yTile");
|
||||
this.zTile = tagCompund.getShort("zTile");
|
||||
|
||||
if (tagCompund.hasKey("inTile", 8))
|
||||
{
|
||||
this.inTile = BlockRegistry.getByIdFallback(tagCompund.getString("inTile"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inTile = BlockRegistry.getBlockById(tagCompund.getByte("inTile") & 255);
|
||||
}
|
||||
|
||||
this.shake = tagCompund.getByte("shake") & 255;
|
||||
this.inGround = tagCompund.getByte("inGround") == 1;
|
||||
}
|
||||
|
||||
public int handleHookRetraction()
|
||||
{
|
||||
if (this.worldObj.client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (this.caughtEntity != null)
|
||||
{
|
||||
double d0 = this.angler.posX - this.posX;
|
||||
double d2 = this.angler.posY - this.posY;
|
||||
double d4 = this.angler.posZ - this.posZ;
|
||||
double d6 = (double)ExtMath.sqrtd(d0 * d0 + d2 * d2 + d4 * d4);
|
||||
double d8 = 0.1D;
|
||||
this.caughtEntity.motionX += d0 * d8;
|
||||
this.caughtEntity.motionY += d2 * d8 + (double)ExtMath.sqrtd(d6) * 0.08D;
|
||||
this.caughtEntity.motionZ += d4 * d8;
|
||||
i = 3;
|
||||
}
|
||||
else if (this.ticksCatchable > 0)
|
||||
{
|
||||
EntityItem entityitem = new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, this.getFishingResult());
|
||||
double d1 = this.angler.posX - this.posX;
|
||||
double d3 = this.angler.posY - this.posY;
|
||||
double d5 = this.angler.posZ - this.posZ;
|
||||
double d7 = (double)ExtMath.sqrtd(d1 * d1 + d3 * d3 + d5 * d5);
|
||||
double d9 = 0.1D;
|
||||
entityitem.motionX = d1 * d9;
|
||||
entityitem.motionY = d3 * d9 + (double)ExtMath.sqrtd(d7) * 0.08D;
|
||||
entityitem.motionZ = d5 * d9;
|
||||
this.worldObj.spawnEntityInWorld(entityitem);
|
||||
if(Config.fishingXP)
|
||||
this.angler.worldObj.spawnEntityInWorld(new EntityXp(this.angler.worldObj, this.angler.posX, this.angler.posY + 0.5D, this.angler.posZ + 0.5D, this.rand.roll(6)));
|
||||
i = 1;
|
||||
}
|
||||
|
||||
if (this.inGround)
|
||||
{
|
||||
i = 2;
|
||||
}
|
||||
|
||||
this.setDead();
|
||||
this.angler.fishEntity = null;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack getFishingResult()
|
||||
{
|
||||
float f = this.worldObj.rand.floatv();
|
||||
int i = EnchantmentHelper.getLuckOfSeaModifier(this.angler);
|
||||
int j = EnchantmentHelper.getLureModifier(this.angler);
|
||||
float f1 = 0.1F - (float)i * 0.025F - (float)j * 0.01F;
|
||||
float f2 = 0.05F + (float)i * 0.01F - (float)j * 0.01F;
|
||||
f1 = ExtMath.clampf(f1, 0.0F, 1.0F);
|
||||
f2 = ExtMath.clampf(f2, 0.0F, 1.0F);
|
||||
|
||||
if (f < f1)
|
||||
{
|
||||
// this.angler.triggerAchievement(StatRegistry.junkFishedStat);
|
||||
return ((RngFishable)LootConstants.FISHING_JUNK.pick(this.rand)).getItemStack(this.rand);
|
||||
}
|
||||
else
|
||||
{
|
||||
f = f - f1;
|
||||
|
||||
if (f < f2)
|
||||
{
|
||||
// this.angler.triggerAchievement(StatRegistry.treasureFishedStat);
|
||||
return ((RngFishable)LootConstants.FISHING_TREASURE.pick(this.rand)).getItemStack(this.rand);
|
||||
}
|
||||
else
|
||||
{
|
||||
float f3 = f - f2;
|
||||
// this.angler.triggerAchievement(StatRegistry.fishCaughtStat);
|
||||
return ((RngFishable)LootConstants.FISH_TYPES.pick(this.rand)).getItemStack(this.rand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will get destroyed next tick.
|
||||
*/
|
||||
public void setDead()
|
||||
{
|
||||
super.setDead();
|
||||
|
||||
if (this.angler != null)
|
||||
{
|
||||
this.angler.fishEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.angler != null ? this.angler.getId() : this.getId();
|
||||
}
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
}
|
198
java/src/game/entity/projectile/EntityPotion.java
Executable file
198
java/src/game/entity/projectile/EntityPotion.java
Executable file
|
@ -0,0 +1,198 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityThrowable;
|
||||
import game.entity.types.IObjectData;
|
||||
import game.init.Items;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.potion.Potion;
|
||||
import game.potion.PotionEffect;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntityPotion extends EntityThrowable implements IObjectData
|
||||
{
|
||||
/**
|
||||
* The damage value of the thrown potion that this EntityPotion represents.
|
||||
*/
|
||||
private ItemStack potionDamage;
|
||||
|
||||
public EntityPotion(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityPotion(World worldIn, EntityLiving throwerIn, int meta)
|
||||
{
|
||||
this(worldIn, throwerIn, new ItemStack(Items.potion, 1, meta));
|
||||
}
|
||||
|
||||
public EntityPotion(World worldIn, EntityLiving throwerIn, ItemStack potionDamageIn)
|
||||
{
|
||||
super(worldIn, throwerIn);
|
||||
this.potionDamage = potionDamageIn;
|
||||
}
|
||||
|
||||
public EntityPotion(World worldIn, double x, double y, double z, int data)
|
||||
{
|
||||
this(worldIn, x, y, z, new ItemStack(Items.potion, 1, data));
|
||||
}
|
||||
|
||||
public EntityPotion(World worldIn, double x, double y, double z, ItemStack potionDamageIn)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
this.potionDamage = potionDamageIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of gravity to apply to the thrown entity with each tick.
|
||||
*/
|
||||
protected float getGravityVelocity()
|
||||
{
|
||||
return 0.05F;
|
||||
}
|
||||
|
||||
protected float getVelocity()
|
||||
{
|
||||
return 0.5F;
|
||||
}
|
||||
|
||||
protected float getInaccuracy()
|
||||
{
|
||||
return -20.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the PotionEffect by the given id of the potion effect.
|
||||
*/
|
||||
public void setPotionDamage(int potionId)
|
||||
{
|
||||
if (this.potionDamage == null)
|
||||
{
|
||||
this.potionDamage = new ItemStack(Items.potion, 1, 0);
|
||||
}
|
||||
|
||||
this.potionDamage.setItemDamage(potionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the damage value of the thrown potion that this EntityPotion represents.
|
||||
*/
|
||||
public int getPotionDamage()
|
||||
{
|
||||
if (this.potionDamage == null)
|
||||
{
|
||||
this.potionDamage = new ItemStack(Items.potion, 1, 0);
|
||||
}
|
||||
|
||||
return this.potionDamage.getMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityThrowable hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition p_70184_1_)
|
||||
{
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
List<PotionEffect> list = Items.potion.getEffects(this.potionDamage);
|
||||
|
||||
BoundingBox axisalignedbb = this.getEntityBoundingBox().expand(4.0D, 2.0D, 4.0D);
|
||||
List<EntityLiving> list1 = this.worldObj.<EntityLiving>getEntitiesWithinAABB(EntityLiving.class, axisalignedbb);
|
||||
|
||||
if (!list1.isEmpty())
|
||||
{
|
||||
for (EntityLiving entitylivingbase : list1)
|
||||
{
|
||||
double d0 = this.getDistanceSqToEntity(entitylivingbase);
|
||||
|
||||
if (d0 < 16.0D)
|
||||
{
|
||||
if (list != null && !list.isEmpty())
|
||||
{
|
||||
double d1 = 1.0D - Math.sqrt(d0) / 4.0D;
|
||||
|
||||
if (entitylivingbase == p_70184_1_.entity)
|
||||
{
|
||||
d1 = 1.0D;
|
||||
}
|
||||
|
||||
for (PotionEffect potioneffect : list)
|
||||
{
|
||||
int i = potioneffect.getPotionID();
|
||||
|
||||
if (Potion.POTION_TYPES[i].isInstant())
|
||||
{
|
||||
Potion.POTION_TYPES[i].affectEntity(this, this.getThrower(), entitylivingbase, potioneffect.getAmplifier(), d1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int j = (int)(d1 * (double)potioneffect.getDuration() + 0.5D);
|
||||
|
||||
if (j > 20)
|
||||
{
|
||||
entitylivingbase.addEffect(new PotionEffect(i, j, potioneffect.getAmplifier()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
entitylivingbase.extinguish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.worldObj.playAuxSFX(2002, new BlockPos(this), this.getPotionDamage());
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
|
||||
if (tagCompund.hasKey("Potion", 10))
|
||||
{
|
||||
this.potionDamage = ItemStack.loadItemStackFromNBT(tagCompund.getCompoundTag("Potion"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setPotionDamage(tagCompund.getInteger("potionValue"));
|
||||
}
|
||||
|
||||
if (this.potionDamage == null)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
|
||||
if (this.potionDamage != null)
|
||||
{
|
||||
tagCompound.setTag("Potion", this.potionDamage.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
}
|
||||
|
||||
public int getPacketData() {
|
||||
return this.getPotionDamage();
|
||||
}
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
}
|
388
java/src/game/entity/projectile/EntityProjectile.java
Executable file
388
java/src/game/entity/projectile/EntityProjectile.java
Executable file
|
@ -0,0 +1,388 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.Entity;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.init.BlockRegistry;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.nbt.NBTTagList;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.HitPosition;
|
||||
import game.world.Vec3;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityProjectile extends Entity
|
||||
{
|
||||
private int xTile = -1;
|
||||
private int yTile = -1;
|
||||
private int zTile = -1;
|
||||
private Block inTile;
|
||||
private boolean inGround;
|
||||
public EntityLiving shootingEntity;
|
||||
private int ticksAlive;
|
||||
private int ticksInAir;
|
||||
public double accelerationX;
|
||||
public double accelerationY;
|
||||
public double accelerationZ;
|
||||
private int age;
|
||||
|
||||
public EntityProjectile(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(1.0F, 1.0F);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
|
||||
* length * 64 * renderDistanceWeight Args: distance
|
||||
*/
|
||||
public boolean isInRangeToRenderDist(double distance)
|
||||
{
|
||||
double d0 = this.getEntityBoundingBox().getAverageEdgeLength() * 4.0D;
|
||||
|
||||
if (Double.isNaN(d0))
|
||||
{
|
||||
d0 = 4.0D;
|
||||
}
|
||||
|
||||
d0 = d0 * 64.0D;
|
||||
return distance < d0 * d0;
|
||||
}
|
||||
|
||||
public EntityProjectile(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(1.0F, 1.0F);
|
||||
this.setLocationAndAngles(x, y, z, this.rotYaw, this.rotPitch);
|
||||
this.setPosition(x, y, z);
|
||||
}
|
||||
|
||||
public EntityProjectile(World worldIn, EntityLiving shooter, double accelX, double accelY, double accelZ, double random, double velo)
|
||||
{
|
||||
super(worldIn);
|
||||
this.shootingEntity = shooter;
|
||||
this.setSize(1.0F, 1.0F);
|
||||
this.setLocationAndAngles(shooter.posX, shooter.posY, shooter.posZ, shooter.rotYaw, shooter.rotPitch);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
this.motionX = this.motionY = this.motionZ = 0.0D;
|
||||
accelX = accelX + this.rand.gaussian() * random;
|
||||
accelY = accelY + this.rand.gaussian() * random;
|
||||
accelZ = accelZ + this.rand.gaussian() * random;
|
||||
double d0 = (double)ExtMath.sqrtd(accelX * accelX + accelY * accelY + accelZ * accelZ);
|
||||
this.accelerationX = (accelX / d0 * 0.1D) * velo;
|
||||
this.accelerationY = (accelY / d0 * 0.1D) * velo;
|
||||
this.accelerationZ = (accelZ / d0 * 0.1D) * velo;
|
||||
}
|
||||
|
||||
public void setAcceleration(double accelX, double accelY, double accelZ) {
|
||||
double d0 = (double)ExtMath.sqrtd(accelX * accelX + accelY * accelY + accelZ * accelZ);
|
||||
this.accelerationX = accelX / d0 * 0.1D;
|
||||
this.accelerationY = accelY / d0 * 0.1D;
|
||||
this.accelerationZ = accelZ / d0 * 0.1D;
|
||||
}
|
||||
|
||||
public Vec3 getAcceleration() {
|
||||
return new Vec3(this.accelerationX, this.accelerationY, this.accelerationZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
if (this.worldObj.client || (this.shootingEntity == null || !this.shootingEntity.dead) && this.worldObj.isBlockLoaded(new BlockPos(this)))
|
||||
{
|
||||
super.onUpdate();
|
||||
this.setFire(1);
|
||||
|
||||
if (this.inGround)
|
||||
{
|
||||
if (this.worldObj.getState(new BlockPos(this.xTile, this.yTile, this.zTile)).getBlock() == this.inTile)
|
||||
{
|
||||
++this.ticksAlive;
|
||||
|
||||
if (this.ticksAlive == 600)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.inGround = false;
|
||||
this.motionX *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionY *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionZ *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.ticksAlive = 0;
|
||||
this.ticksInAir = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++this.ticksInAir;
|
||||
}
|
||||
|
||||
Vec3 vec3 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
Vec3 vec31 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
HitPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec3, vec31);
|
||||
vec3 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
vec31 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
vec31 = new Vec3(movingobjectposition.vec.xCoord, movingobjectposition.vec.yCoord, movingobjectposition.vec.zCoord);
|
||||
}
|
||||
|
||||
Entity entity = null;
|
||||
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
double d0 = 0.0D;
|
||||
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
Entity entity1 = (Entity)list.get(i);
|
||||
|
||||
if (entity1.canBeCollidedWith() && (!entity1.isEntityEqual(this.shootingEntity) || this.ticksInAir >= 25))
|
||||
{
|
||||
float f = 0.3F;
|
||||
BoundingBox axisalignedbb = entity1.getEntityBoundingBox().expand((double)f, (double)f, (double)f);
|
||||
HitPosition movingobjectposition1 = axisalignedbb.calculateIntercept(vec3, vec31);
|
||||
|
||||
if (movingobjectposition1 != null)
|
||||
{
|
||||
double d1 = vec3.squareDistanceTo(movingobjectposition1.vec);
|
||||
|
||||
if (d1 < d0 || d0 == 0.0D)
|
||||
{
|
||||
entity = entity1;
|
||||
d0 = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
movingobjectposition = new HitPosition(entity);
|
||||
}
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
this.onImpact(movingobjectposition);
|
||||
}
|
||||
|
||||
this.posX += this.motionX;
|
||||
this.posY += this.motionY;
|
||||
this.posZ += this.motionZ;
|
||||
float f1 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotYaw = (float)(ExtMath.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) + 90.0F;
|
||||
|
||||
for (this.rotPitch = (float)(ExtMath.atan2((double)f1, this.motionY) * 180.0D / Math.PI) - 90.0F; this.rotPitch - this.prevPitch < -180.0F; this.prevPitch -= 360.0F)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
while (this.rotPitch - this.prevPitch >= 180.0F)
|
||||
{
|
||||
this.prevPitch += 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw < -180.0F)
|
||||
{
|
||||
this.prevYaw -= 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw >= 180.0F)
|
||||
{
|
||||
this.prevYaw += 360.0F;
|
||||
}
|
||||
|
||||
this.rotPitch = this.prevPitch + (this.rotPitch - this.prevPitch) * 0.2F;
|
||||
this.rotYaw = this.prevYaw + (this.rotYaw - this.prevYaw) * 0.2F;
|
||||
float f2 = this.getMotionFactor();
|
||||
|
||||
if (this.isInLiquid())
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
float f3 = 0.25F;
|
||||
this.worldObj.spawnParticle(ParticleType.WATER_BUBBLE, this.posX - this.motionX * (double)f3, this.posY - this.motionY * (double)f3, this.posZ - this.motionZ * (double)f3, this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
|
||||
f2 = 0.8F;
|
||||
}
|
||||
|
||||
this.motionX += this.accelerationX;
|
||||
this.motionY += this.accelerationY;
|
||||
this.motionZ += this.accelerationZ;
|
||||
this.motionX *= (double)f2;
|
||||
this.motionY *= (double)f2;
|
||||
this.motionZ *= (double)f2;
|
||||
this.worldObj.spawnParticle(ParticleType.SMOKE_NORMAL, this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
if(!this.worldObj.client && this.age++ >= 200)
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the motion factor for this projectile. The factor is multiplied by the original motion.
|
||||
*/
|
||||
protected float getMotionFactor()
|
||||
{
|
||||
return 0.95F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityFireball hits a block or entity.
|
||||
*/
|
||||
protected abstract void onImpact(HitPosition movingObject);
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setShort("xTile", (short)this.xTile);
|
||||
tagCompound.setShort("yTile", (short)this.yTile);
|
||||
tagCompound.setShort("zTile", (short)this.zTile);
|
||||
String resourcelocation = BlockRegistry.REGISTRY.getNameForObject(this.inTile);
|
||||
tagCompound.setString("inTile", resourcelocation == null ? "" : resourcelocation.toString());
|
||||
tagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0));
|
||||
tagCompound.setTag("direction", this.newDoubleNBTList(this.motionX, this.motionY, this.motionZ));
|
||||
tagCompound.setInteger("Age", this.age);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.xTile = tagCompund.getShort("xTile");
|
||||
this.yTile = tagCompund.getShort("yTile");
|
||||
this.zTile = tagCompund.getShort("zTile");
|
||||
|
||||
if (tagCompund.hasKey("inTile", 8))
|
||||
{
|
||||
this.inTile = BlockRegistry.getByIdFallback(tagCompund.getString("inTile"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inTile = BlockRegistry.getBlockById(tagCompund.getByte("inTile") & 255);
|
||||
}
|
||||
|
||||
this.inGround = tagCompund.getByte("inGround") == 1;
|
||||
|
||||
if (tagCompund.hasKey("direction", 9))
|
||||
{
|
||||
NBTTagList nbttaglist = tagCompund.getTagList("direction", 6);
|
||||
this.motionX = nbttaglist.getDoubleAt(0);
|
||||
this.motionY = nbttaglist.getDoubleAt(1);
|
||||
this.motionZ = nbttaglist.getDoubleAt(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
this.age = tagCompund.getInteger("Age");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public float getCollisionBorderSize()
|
||||
{
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBeenAttacked();
|
||||
|
||||
if (source.getEntity() != null)
|
||||
{
|
||||
Vec3 vec3 = source.getEntity().getLookVec();
|
||||
|
||||
if (vec3 != null)
|
||||
{
|
||||
this.motionX = vec3.xCoord;
|
||||
this.motionY = vec3.yCoord;
|
||||
this.motionZ = vec3.zCoord;
|
||||
this.accelerationX = this.motionX * 0.1D;
|
||||
this.accelerationY = this.motionY * 0.1D;
|
||||
this.accelerationZ = this.motionZ * 0.1D;
|
||||
}
|
||||
|
||||
if (source.getEntity() instanceof EntityLiving)
|
||||
{
|
||||
this.shootingEntity = (EntityLiving)source.getEntity();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets how bright this entity is.
|
||||
*/
|
||||
public float getBrightness(float partialTicks)
|
||||
{
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
public int getBrightnessForRender(float partialTicks)
|
||||
{
|
||||
return 15728880;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 1; // 10
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// public int getPacketData() {
|
||||
// return this.shootingEntity != null ? this.shootingEntity.getId() : 0;
|
||||
// }
|
||||
|
||||
// public boolean hasSpawnVelocity() {
|
||||
// return false;
|
||||
// }
|
||||
}
|
56
java/src/game/entity/projectile/EntitySnowball.java
Executable file
56
java/src/game/entity/projectile/EntitySnowball.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.types.EntityLiving;
|
||||
import game.entity.types.EntityThrowable;
|
||||
import game.init.Config;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.HitPosition;
|
||||
import game.world.World;
|
||||
|
||||
public class EntitySnowball extends EntityThrowable
|
||||
{
|
||||
public EntitySnowball(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntitySnowball(World worldIn, EntityLiving throwerIn)
|
||||
{
|
||||
super(worldIn, throwerIn);
|
||||
}
|
||||
|
||||
public EntitySnowball(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityThrowable hits a block or entity.
|
||||
*/
|
||||
protected void onImpact(HitPosition p_70184_1_)
|
||||
{
|
||||
if (p_70184_1_.entity != null)
|
||||
{
|
||||
// int i = 0;
|
||||
|
||||
// if (p_70184_1_.entityHit instanceof EntityBlaze && Config.blazeSnowballDamage)
|
||||
// {
|
||||
// i = 3;
|
||||
// }
|
||||
|
||||
if(Config.knockSnowball)
|
||||
p_70184_1_.entity.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0);
|
||||
}
|
||||
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
this.worldObj.spawnParticle(ParticleType.SNOWBALL, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
}
|
61
java/src/game/entity/projectile/RngFishable.java
Executable file
61
java/src/game/entity/projectile/RngFishable.java
Executable file
|
@ -0,0 +1,61 @@
|
|||
package game.entity.projectile;
|
||||
|
||||
import game.enchantment.EnchantmentHelper;
|
||||
import game.item.ItemStack;
|
||||
import game.rng.Random;
|
||||
import game.rng.RngItem;
|
||||
|
||||
public class RngFishable extends RngItem
|
||||
{
|
||||
private final ItemStack returnStack;
|
||||
private float maxDamagePercent;
|
||||
private boolean enchantable;
|
||||
|
||||
public RngFishable(ItemStack returnStackIn, int itemWeightIn)
|
||||
{
|
||||
super(itemWeightIn);
|
||||
this.returnStack = returnStackIn;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack(Random random)
|
||||
{
|
||||
ItemStack itemstack = this.returnStack.copy();
|
||||
|
||||
if (this.maxDamagePercent > 0.0F)
|
||||
{
|
||||
int i = (int)(this.maxDamagePercent * (float)this.returnStack.getMaxDamage());
|
||||
int j = itemstack.getMaxDamage() - random.zrange(random.zrange(i) + 1);
|
||||
|
||||
if (j > i)
|
||||
{
|
||||
j = i;
|
||||
}
|
||||
|
||||
if (j < 1)
|
||||
{
|
||||
j = 1;
|
||||
}
|
||||
|
||||
itemstack.setItemDamage(j);
|
||||
}
|
||||
|
||||
if (this.enchantable)
|
||||
{
|
||||
EnchantmentHelper.addRandomEnchantment(random, itemstack, 30);
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
public RngFishable setMaxDamagePercent(float maxDamagePercentIn)
|
||||
{
|
||||
this.maxDamagePercent = maxDamagePercentIn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RngFishable setEnchantable()
|
||||
{
|
||||
this.enchantable = true;
|
||||
return this;
|
||||
}
|
||||
}
|
33
java/src/game/entity/types/CombatEntry.java
Executable file
33
java/src/game/entity/types/CombatEntry.java
Executable file
|
@ -0,0 +1,33 @@
|
|||
package game.entity.types;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
|
||||
public class CombatEntry {
|
||||
private final DamageSource source;
|
||||
private final int damage;
|
||||
private final String blockType;
|
||||
private final float fallDistance;
|
||||
|
||||
public CombatEntry(DamageSource source, int damage, String blockType, float fallDistance) {
|
||||
this.source = source;
|
||||
this.damage = damage;
|
||||
this.blockType = blockType;
|
||||
this.fallDistance = fallDistance;
|
||||
}
|
||||
|
||||
public DamageSource getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public int getDamage() {
|
||||
return this.damage;
|
||||
}
|
||||
|
||||
public String getBlockType() {
|
||||
return this.blockType;
|
||||
}
|
||||
|
||||
public float getFallDistance() {
|
||||
return this.source == DamageSource.outOfWorld ? Float.MAX_VALUE : this.fallDistance;
|
||||
}
|
||||
}
|
317
java/src/game/entity/types/EntityAnimal.java
Executable file
317
java/src/game/entity/types/EntityAnimal.java
Executable file
|
@ -0,0 +1,317 @@
|
|||
package game.entity.types;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.collect.Sets;
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.npc.Alignment;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.init.Blocks;
|
||||
import game.init.Items;
|
||||
import game.item.ItemStack;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityAnimal extends EntityLiving
|
||||
{
|
||||
protected final Set<Block> spawnableBlocks = Sets.newHashSet(Blocks.grass, Blocks.tian_soil);
|
||||
|
||||
private int inLove;
|
||||
private EntityNPC playerInLove;
|
||||
|
||||
public EntityAnimal(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
protected void entityInit() {
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(30, Byte.valueOf((byte)0));
|
||||
}
|
||||
|
||||
protected void updateAITasks()
|
||||
{
|
||||
if (this.getGrowingAge() != 0)
|
||||
{
|
||||
this.resetInLove();
|
||||
}
|
||||
|
||||
super.updateAITasks();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (this.getGrowingAge() != 0)
|
||||
{
|
||||
this.resetInLove();
|
||||
}
|
||||
|
||||
if (this.isInLove())
|
||||
{
|
||||
if(!this.worldObj.client) {
|
||||
this.setInLove(this.inLove - 1, false);
|
||||
}
|
||||
else {
|
||||
this.inLove += 1;
|
||||
if (this.inLove == 10)
|
||||
{
|
||||
this.inLove = 0;
|
||||
double d0 = this.rand.gaussian() * 0.02D;
|
||||
double d1 = this.rand.gaussian() * 0.02D;
|
||||
double d2 = this.rand.gaussian() * 0.02D;
|
||||
this.worldObj.spawnParticle(ParticleType.HEART, this.posX + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.floatv() * this.height), this.posZ + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, d0, d1, d2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||
{
|
||||
if (this.isEntityInvulnerable(source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.resetInLove();
|
||||
return super.attackEntityFrom(source, amount);
|
||||
}
|
||||
}
|
||||
|
||||
public float getBlockPathWeight(BlockPos pos)
|
||||
{
|
||||
return this.worldObj.getState(pos.down()).getBlock() == Blocks.grass ? 10.0F : this.worldObj.getLightBrightness(pos) - 0.5F;
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
tagCompound.setInteger("InLove", this.inLove);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
this.setInLove(tagCompund.getInteger("InLove"), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity's current position is a valid location to spawn this entity.
|
||||
*/
|
||||
public boolean getCanSpawnHere()
|
||||
{
|
||||
int i = ExtMath.floord(this.posX);
|
||||
int j = ExtMath.floord(this.getEntityBoundingBox().minY);
|
||||
int k = ExtMath.floord(this.posZ);
|
||||
BlockPos blockpos = new BlockPos(i, j, k);
|
||||
return this.spawnableBlocks.contains(this.worldObj.getState(blockpos.down()).getBlock()) && this.isValidLightLevel(this.worldObj.getLight(blockpos)) && super.getCanSpawnHere();
|
||||
}
|
||||
|
||||
protected boolean isValidLightLevel(int level)
|
||||
{
|
||||
return level > 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of ticks, at least during which the living entity will be silent.
|
||||
*/
|
||||
public int getTalkInterval()
|
||||
{
|
||||
return 120;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Determines if an entity can be despawned, used on idle far away entities
|
||||
// */
|
||||
// protected boolean canDespawn()
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the experience points the entity currently has.
|
||||
*/
|
||||
protected int getExperiencePoints(EntityNPC player)
|
||||
{
|
||||
return this.worldObj.rand.roll(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 stack)
|
||||
{
|
||||
return stack == null ? false : stack.getItem() == Items.wheats;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
|
||||
if (itemstack != null)
|
||||
{
|
||||
if (this.isBreedingItem(itemstack) && this.getGrowingAge() == 0 && !this.isInLove())
|
||||
{
|
||||
this.consumeItemFromStack(player, itemstack);
|
||||
this.setInLove(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.isChild() && this.isBreedingItem(itemstack))
|
||||
{
|
||||
this.consumeItemFromStack(player, itemstack);
|
||||
if(!this.worldObj.client)
|
||||
this.grow((int)((float)(-this.getGrowingAge() / 20) * 0.1F));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.interact(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decreases ItemStack size by one
|
||||
*/
|
||||
protected void consumeItemFromStack(EntityNPC player, ItemStack stack)
|
||||
{
|
||||
// if (!player.creative)
|
||||
// {
|
||||
--stack.stackSize;
|
||||
|
||||
if (stack.stackSize <= 0)
|
||||
{
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
public void setInLove(EntityNPC player)
|
||||
{
|
||||
if(!this.worldObj.client) {
|
||||
this.setInLove(600, true);
|
||||
this.playerInLove = player;
|
||||
this.worldObj.setEntityState(this, (byte)18);
|
||||
}
|
||||
}
|
||||
|
||||
public EntityNPC getPlayerInLove()
|
||||
{
|
||||
return this.playerInLove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the entity is currently in 'love mode'.
|
||||
*/
|
||||
public boolean isInLove()
|
||||
{
|
||||
return this.worldObj.client ? (this.dataWatcher.getWatchableObjectByte(30) != 0) : (this.inLove > 0);
|
||||
// return this.inLove > 0;
|
||||
}
|
||||
|
||||
public void resetInLove()
|
||||
{
|
||||
if(!this.worldObj.client) {
|
||||
this.inLove = 0;
|
||||
this.dataWatcher.updateObject(30, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setInLove(int loveTicks, boolean update)
|
||||
{
|
||||
boolean last = this.isInLove();
|
||||
this.inLove = loveTicks;
|
||||
if(update || (last != this.isInLove()))
|
||||
this.dataWatcher.updateObject(30, (byte)(this.isInLove() ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mob is currently able to mate with the specified mob.
|
||||
*/
|
||||
public boolean canMateWith(EntityAnimal otherAnimal)
|
||||
{
|
||||
return otherAnimal == this ? false : (otherAnimal.getClass() != this.getClass() ? false : this.isInLove() && otherAnimal.isInLove());
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
if (id == 18)
|
||||
{
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
double d0 = this.rand.gaussian() * 0.02D;
|
||||
double d1 = this.rand.gaussian() * 0.02D;
|
||||
double d2 = this.rand.gaussian() * 0.02D;
|
||||
this.worldObj.spawnParticle(ParticleType.HEART, this.posX + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.floatv() * this.height), this.posZ + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, d0, d1, d2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If Animal, checks if the age timer is negative
|
||||
*/
|
||||
public boolean isChild()
|
||||
{
|
||||
return this.getGrowingAge() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Sets the scale for an ageable entity according to the boolean parameter, which says if it's a child."
|
||||
*/
|
||||
public void setScaleForAge()
|
||||
{
|
||||
this.setScale(this.isChild() ? 0.5F : 1.0F);
|
||||
}
|
||||
|
||||
protected boolean canDropLoot()
|
||||
{
|
||||
return !this.isChild();
|
||||
}
|
||||
|
||||
protected float getSoundPitch()
|
||||
{
|
||||
return this.isChild() ? (this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.5F : super.getSoundPitch();
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Alignment getAlignment() {
|
||||
return Alignment.LAWFUL;
|
||||
}
|
||||
}
|
80
java/src/game/entity/types/EntityBodyHelper.java
Executable file
80
java/src/game/entity/types/EntityBodyHelper.java
Executable file
|
@ -0,0 +1,80 @@
|
|||
package game.entity.types;
|
||||
|
||||
import game.ExtMath;
|
||||
|
||||
public class EntityBodyHelper
|
||||
{
|
||||
/** Instance of EntityLiving. */
|
||||
private EntityLiving theLiving;
|
||||
|
||||
/**
|
||||
* Used to progressively ajust the rotation of the body to the rotation of the head
|
||||
*/
|
||||
private int rotationTickCounter;
|
||||
private float prevRenderYawHead;
|
||||
|
||||
public EntityBodyHelper(EntityLiving p_i1611_1_)
|
||||
{
|
||||
this.theLiving = p_i1611_1_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Head and Body rendenring angles
|
||||
*/
|
||||
public void updateRenderAngles()
|
||||
{
|
||||
double d0 = this.theLiving.posX - this.theLiving.prevX;
|
||||
double d1 = this.theLiving.posZ - this.theLiving.prevZ;
|
||||
|
||||
if (d0 * d0 + d1 * d1 > 2.500000277905201E-7D)
|
||||
{
|
||||
this.theLiving.yawOffset = this.theLiving.rotYaw;
|
||||
this.theLiving.headYaw = this.computeAngleWithBound(this.theLiving.yawOffset, this.theLiving.headYaw, 75.0F);
|
||||
this.prevRenderYawHead = this.theLiving.headYaw;
|
||||
this.rotationTickCounter = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float f = 75.0F;
|
||||
|
||||
if (Math.abs(this.theLiving.headYaw - this.prevRenderYawHead) > 15.0F)
|
||||
{
|
||||
this.rotationTickCounter = 0;
|
||||
this.prevRenderYawHead = this.theLiving.headYaw;
|
||||
}
|
||||
else
|
||||
{
|
||||
++this.rotationTickCounter;
|
||||
int i = 10;
|
||||
|
||||
if (this.rotationTickCounter > 10)
|
||||
{
|
||||
f = Math.max(1.0F - (float)(this.rotationTickCounter - 10) / 10.0F, 0.0F) * 75.0F;
|
||||
}
|
||||
}
|
||||
|
||||
this.theLiving.yawOffset = this.computeAngleWithBound(this.theLiving.headYaw, this.theLiving.yawOffset, f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the new angle2 such that the difference between angle1 and angle2 is lower than angleMax. Args : angle1,
|
||||
* angle2, angleMax
|
||||
*/
|
||||
private float computeAngleWithBound(float p_75665_1_, float p_75665_2_, float p_75665_3_)
|
||||
{
|
||||
float f = ExtMath.wrapf(p_75665_1_ - p_75665_2_);
|
||||
|
||||
if (f < -p_75665_3_)
|
||||
{
|
||||
f = -p_75665_3_;
|
||||
}
|
||||
|
||||
if (f >= p_75665_3_)
|
||||
{
|
||||
f = p_75665_3_;
|
||||
}
|
||||
|
||||
return p_75665_1_ - f;
|
||||
}
|
||||
}
|
3355
java/src/game/entity/types/EntityLiving.java
Executable file
3355
java/src/game/entity/types/EntityLiving.java
Executable file
File diff suppressed because it is too large
Load diff
232
java/src/game/entity/types/EntityTameable.java
Executable file
232
java/src/game/entity/types/EntityTameable.java
Executable file
|
@ -0,0 +1,232 @@
|
|||
package game.entity.types;
|
||||
|
||||
import game.ai.EntityAISit;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityTameable extends EntityAnimal implements IEntityOwnable
|
||||
{
|
||||
protected EntityAISit aiSit = new EntityAISit(this);
|
||||
|
||||
public EntityTameable(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setupTamedAI();
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
super.entityInit();
|
||||
this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
|
||||
// this.dataWatcher.addObject(17, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
super.writeEntityToNBT(tagCompound);
|
||||
|
||||
// if (this.getOwnerId() == null)
|
||||
// {
|
||||
// tagCompound.setString("Owner", "");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// tagCompound.setString("Owner", this.getOwnerId());
|
||||
// }
|
||||
|
||||
tagCompound.setBoolean("Tame", this.isTamed());
|
||||
tagCompound.setBoolean("Sitting", this.isSitting());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
super.readEntityFromNBT(tagCompund);
|
||||
// String s = "";
|
||||
//
|
||||
// if (tagCompund.hasKey("Owner", 8))
|
||||
// {
|
||||
// s = tagCompund.getString("Owner");
|
||||
// }
|
||||
//
|
||||
// if (s.length() > 0)
|
||||
// {
|
||||
// this.setOwnerId(s);
|
||||
// this.setTamed(true);
|
||||
// }
|
||||
|
||||
this.setTamed(tagCompund.getBoolean("Tame"));
|
||||
this.aiSit.setSitting(tagCompund.getBoolean("Sitting"));
|
||||
this.setSitting(tagCompund.getBoolean("Sitting"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the taming effect, will either be hearts or smoke depending on status
|
||||
*/
|
||||
protected void playTameEffect(boolean play)
|
||||
{
|
||||
ParticleType enumparticletypes = ParticleType.HEART;
|
||||
|
||||
if (!play)
|
||||
{
|
||||
enumparticletypes = ParticleType.SMOKE_NORMAL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
double d0 = this.rand.gaussian() * 0.02D;
|
||||
double d1 = this.rand.gaussian() * 0.02D;
|
||||
double d2 = this.rand.gaussian() * 0.02D;
|
||||
this.worldObj.spawnParticle(enumparticletypes, this.posX + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, this.posY + 0.5D + (double)(this.rand.floatv() * this.height), this.posZ + (double)(this.rand.floatv() * this.width * 2.0F) - (double)this.width, d0, d1, d2);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleStatusUpdate(byte id)
|
||||
{
|
||||
if (id == 7)
|
||||
{
|
||||
this.playTameEffect(true);
|
||||
}
|
||||
else if (id == 6)
|
||||
{
|
||||
this.playTameEffect(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.handleStatusUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTamed()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 4) != 0;
|
||||
}
|
||||
|
||||
public void setTamed(boolean tamed)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (tamed)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 4)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -5)));
|
||||
}
|
||||
|
||||
this.setupTamedAI();
|
||||
}
|
||||
|
||||
protected void setupTamedAI()
|
||||
{
|
||||
}
|
||||
|
||||
public boolean isSitting()
|
||||
{
|
||||
return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
|
||||
}
|
||||
|
||||
public void setSitting(boolean sitting)
|
||||
{
|
||||
byte b0 = this.dataWatcher.getWatchableObjectByte(16);
|
||||
|
||||
if (sitting)
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -2)));
|
||||
}
|
||||
}
|
||||
|
||||
// public String getOwnerId()
|
||||
// {
|
||||
// return this.dataWatcher.getWatchableObjectString(17);
|
||||
// }
|
||||
//
|
||||
// public void setOwnerId(String owner)
|
||||
// {
|
||||
// this.dataWatcher.updateObject(17, owner);
|
||||
// }
|
||||
|
||||
public EntityLiving getOwner()
|
||||
{
|
||||
if(!this.isTamed())
|
||||
return null;
|
||||
return this.worldObj.getClosestPlayerToEntity(this, 32.0);
|
||||
}
|
||||
|
||||
public boolean isOwner(EntityLiving entityIn)
|
||||
{
|
||||
return entityIn.isPlayer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the AITask responsible of the sit logic
|
||||
*/
|
||||
public EntityAISit getAISit()
|
||||
{
|
||||
return this.aiSit;
|
||||
}
|
||||
|
||||
public boolean shouldAttackEntity(EntityLiving p_142018_1_, EntityLiving p_142018_2_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// public Team getTeam()
|
||||
// {
|
||||
// if (this.isTamed())
|
||||
// {
|
||||
// EntityLivingBase entitylivingbase = this.getOwner();
|
||||
//
|
||||
// if (entitylivingbase != null)
|
||||
// {
|
||||
// return entitylivingbase.getTeam();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return super.getTeam();
|
||||
// }
|
||||
//
|
||||
// public boolean isOnSameTeam(EntityLivingBase otherEntity)
|
||||
// {
|
||||
// if (this.isTamed())
|
||||
// {
|
||||
// EntityLivingBase entitylivingbase = this.getOwner();
|
||||
//
|
||||
// if (otherEntity == entitylivingbase)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// if (entitylivingbase != null)
|
||||
// {
|
||||
// return entitylivingbase.isOnSameTeam(otherEntity);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return super.isOnSameTeam(otherEntity);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Called when the mob's health reaches 0.
|
||||
// */
|
||||
// public void onDeath(DamageSource cause)
|
||||
// {
|
||||
// if (!this.worldObj.client && Config.deadPetMessages && this.hasCustomName() && this.getOwner().isPlayer())
|
||||
// {
|
||||
// ((EntityNPCMP)this.getOwner()).addChatMessage(this.getDeathMessage());
|
||||
// }
|
||||
//
|
||||
// super.onDeath(cause);
|
||||
// }
|
||||
}
|
392
java/src/game/entity/types/EntityThrowable.java
Executable file
392
java/src/game/entity/types/EntityThrowable.java
Executable file
|
@ -0,0 +1,392 @@
|
|||
package game.entity.types;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.block.Block;
|
||||
import game.block.BlockPortal;
|
||||
import game.entity.Entity;
|
||||
import game.init.BlockRegistry;
|
||||
import game.init.Blocks;
|
||||
import game.nbt.NBTTagCompound;
|
||||
import game.renderer.particle.ParticleType;
|
||||
import game.world.BlockPos;
|
||||
import game.world.BoundingBox;
|
||||
import game.world.HitPosition;
|
||||
import game.world.State;
|
||||
import game.world.Vec3;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityThrowable extends Entity implements IProjectile
|
||||
{
|
||||
private int xTile = -1;
|
||||
private int yTile = -1;
|
||||
private int zTile = -1;
|
||||
private Block inTile;
|
||||
protected boolean inGround;
|
||||
public int throwableShake;
|
||||
private EntityLiving thrower;
|
||||
private int ticksInGround;
|
||||
private int ticksInAir;
|
||||
|
||||
public EntityThrowable(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.setSize(0.25F, 0.25F);
|
||||
}
|
||||
|
||||
protected void entityInit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
|
||||
* length * 64 * renderDistanceWeight Args: distance
|
||||
*/
|
||||
public boolean isInRangeToRenderDist(double distance)
|
||||
{
|
||||
double d0 = this.getEntityBoundingBox().getAverageEdgeLength() * 4.0D;
|
||||
|
||||
if (Double.isNaN(d0))
|
||||
{
|
||||
d0 = 4.0D;
|
||||
}
|
||||
|
||||
d0 = d0 * 64.0D;
|
||||
return distance < d0 * d0;
|
||||
}
|
||||
|
||||
public EntityThrowable(World worldIn, EntityLiving throwerIn)
|
||||
{
|
||||
super(worldIn);
|
||||
this.thrower = throwerIn;
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.setLocationAndAngles(throwerIn.posX, throwerIn.posY + (double)throwerIn.getEyeHeight(), throwerIn.posZ, throwerIn.rotYaw, throwerIn.rotPitch);
|
||||
this.posX -= (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.posY -= 0.10000000149011612D;
|
||||
this.posZ -= (double)(ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * 0.16F);
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
float f = 0.4F;
|
||||
this.motionX = (double)(-ExtMath.sin(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI) * f);
|
||||
this.motionZ = (double)(ExtMath.cos(this.rotYaw / 180.0F * (float)Math.PI) * ExtMath.cos(this.rotPitch / 180.0F * (float)Math.PI) * f);
|
||||
this.motionY = (double)(-ExtMath.sin((this.rotPitch + this.getInaccuracy()) / 180.0F * (float)Math.PI) * f);
|
||||
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, this.getVelocity(), 1.0F);
|
||||
}
|
||||
|
||||
public EntityThrowable(World worldIn, double x, double y, double z)
|
||||
{
|
||||
super(worldIn);
|
||||
this.ticksInGround = 0;
|
||||
this.setSize(0.25F, 0.25F);
|
||||
this.setPosition(x, y, z);
|
||||
}
|
||||
|
||||
protected float getVelocity()
|
||||
{
|
||||
return 1.5F;
|
||||
}
|
||||
|
||||
protected float getInaccuracy()
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to setArrowHeading, it's point the throwable entity to a x, y, z direction.
|
||||
*/
|
||||
public void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy)
|
||||
{
|
||||
float f = ExtMath.sqrtd(x * x + y * y + z * z);
|
||||
x = x / (double)f;
|
||||
y = y / (double)f;
|
||||
z = z / (double)f;
|
||||
x = x + this.rand.gaussian() * 0.007499999832361937D * (double)inaccuracy;
|
||||
y = y + this.rand.gaussian() * 0.007499999832361937D * (double)inaccuracy;
|
||||
z = z + this.rand.gaussian() * 0.007499999832361937D * (double)inaccuracy;
|
||||
x = x * (double)velocity;
|
||||
y = y * (double)velocity;
|
||||
z = z * (double)velocity;
|
||||
this.motionX = x;
|
||||
this.motionY = y;
|
||||
this.motionZ = z;
|
||||
float f1 = ExtMath.sqrtd(x * x + z * z);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(x, z) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(y, (double)f1) * 180.0D / Math.PI);
|
||||
this.ticksInGround = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
*/
|
||||
public void setVelocity(double x, double y, double z)
|
||||
{
|
||||
this.motionX = x;
|
||||
this.motionY = y;
|
||||
this.motionZ = z;
|
||||
|
||||
if (this.prevPitch == 0.0F && this.prevYaw == 0.0F)
|
||||
{
|
||||
float f = ExtMath.sqrtd(x * x + z * z);
|
||||
this.prevYaw = this.rotYaw = (float)(ExtMath.atan2(x, z) * 180.0D / Math.PI);
|
||||
this.prevPitch = this.rotPitch = (float)(ExtMath.atan2(y, (double)f) * 180.0D / Math.PI);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
this.lastTickPosX = this.posX;
|
||||
this.lastTickPosY = this.posY;
|
||||
this.lastTickPosZ = this.posZ;
|
||||
super.onUpdate();
|
||||
|
||||
if (this.throwableShake > 0)
|
||||
{
|
||||
--this.throwableShake;
|
||||
}
|
||||
|
||||
if (this.inGround)
|
||||
{
|
||||
if (this.worldObj.getState(new BlockPos(this.xTile, this.yTile, this.zTile)).getBlock() == this.inTile)
|
||||
{
|
||||
++this.ticksInGround;
|
||||
|
||||
if (this.ticksInGround == 1200)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.inGround = false;
|
||||
this.motionX *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionY *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.motionZ *= (double)(this.rand.floatv() * 0.2F);
|
||||
this.ticksInGround = 0;
|
||||
this.ticksInAir = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++this.ticksInAir;
|
||||
}
|
||||
|
||||
Vec3 vec3 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
Vec3 vec31 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
HitPosition movingobjectposition = this.worldObj.rayTraceBlocks(vec3, vec31);
|
||||
vec3 = new Vec3(this.posX, this.posY, this.posZ);
|
||||
vec31 = new Vec3(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
vec31 = new Vec3(movingobjectposition.vec.xCoord, movingobjectposition.vec.yCoord, movingobjectposition.vec.zCoord);
|
||||
}
|
||||
|
||||
if (!this.worldObj.client)
|
||||
{
|
||||
Entity entity = null;
|
||||
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
|
||||
double d0 = 0.0D;
|
||||
EntityLiving entitylivingbase = this.getThrower();
|
||||
|
||||
for (int j = 0; j < list.size(); ++j)
|
||||
{
|
||||
Entity entity1 = (Entity)list.get(j);
|
||||
|
||||
if (entity1.canBeCollidedWith() && (entity1 != entitylivingbase || this.ticksInAir >= 5))
|
||||
{
|
||||
float f = 0.3F;
|
||||
BoundingBox axisalignedbb = entity1.getEntityBoundingBox().expand((double)f, (double)f, (double)f);
|
||||
HitPosition movingobjectposition1 = axisalignedbb.calculateIntercept(vec3, vec31);
|
||||
|
||||
if (movingobjectposition1 != null)
|
||||
{
|
||||
double d1 = vec3.squareDistanceTo(movingobjectposition1.vec);
|
||||
|
||||
if (d1 < d0 || d0 == 0.0D)
|
||||
{
|
||||
entity = entity1;
|
||||
d0 = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
movingobjectposition = new HitPosition(entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
State state;
|
||||
if (movingobjectposition.type == HitPosition.ObjectType.BLOCK && (state = this.worldObj.getState(movingobjectposition.block)).getBlock() == Blocks.portal)
|
||||
{
|
||||
this.setPortal(state.getValue(BlockPortal.DIM));
|
||||
}
|
||||
else if (movingobjectposition.type == HitPosition.ObjectType.BLOCK && this.worldObj.getState(movingobjectposition.block).getBlock() == Blocks.floor_portal)
|
||||
{
|
||||
this.setFlatPortal();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.onImpact(movingobjectposition);
|
||||
}
|
||||
}
|
||||
|
||||
this.posX += this.motionX;
|
||||
this.posY += this.motionY;
|
||||
this.posZ += this.motionZ;
|
||||
float f1 = ExtMath.sqrtd(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotYaw = (float)(ExtMath.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
|
||||
|
||||
for (this.rotPitch = (float)(ExtMath.atan2(this.motionY, (double)f1) * 180.0D / Math.PI); this.rotPitch - this.prevPitch < -180.0F; this.prevPitch -= 360.0F)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
while (this.rotPitch - this.prevPitch >= 180.0F)
|
||||
{
|
||||
this.prevPitch += 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw < -180.0F)
|
||||
{
|
||||
this.prevYaw -= 360.0F;
|
||||
}
|
||||
|
||||
while (this.rotYaw - this.prevYaw >= 180.0F)
|
||||
{
|
||||
this.prevYaw += 360.0F;
|
||||
}
|
||||
|
||||
this.rotPitch = this.prevPitch + (this.rotPitch - this.prevPitch) * 0.2F;
|
||||
this.rotYaw = this.prevYaw + (this.rotYaw - this.prevYaw) * 0.2F;
|
||||
float f2 = 0.99F;
|
||||
float f3 = this.getGravityVelocity();
|
||||
|
||||
if (this.isInLiquid())
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
float f4 = 0.25F;
|
||||
this.worldObj.spawnParticle(ParticleType.WATER_BUBBLE, this.posX - this.motionX * (double)f4, this.posY - this.motionY * (double)f4, this.posZ - this.motionZ * (double)f4, this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
|
||||
f2 = 0.8F;
|
||||
}
|
||||
|
||||
this.motionX *= (double)f2;
|
||||
this.motionY *= (double)f2;
|
||||
this.motionZ *= (double)f2;
|
||||
this.motionY -= (double)f3;
|
||||
this.setPosition(this.posX, this.posY, this.posZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of gravity to apply to the thrown entity with each tick.
|
||||
*/
|
||||
protected float getGravityVelocity()
|
||||
{
|
||||
return 0.03F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this EntityThrowable hits a block or entity.
|
||||
*/
|
||||
protected abstract void onImpact(HitPosition p_70184_1_);
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
||||
*/
|
||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
||||
{
|
||||
tagCompound.setShort("xTile", (short)this.xTile);
|
||||
tagCompound.setShort("yTile", (short)this.yTile);
|
||||
tagCompound.setShort("zTile", (short)this.zTile);
|
||||
String resourcelocation = BlockRegistry.REGISTRY.getNameForObject(this.inTile);
|
||||
tagCompound.setString("inTile", resourcelocation == null ? "" : resourcelocation.toString());
|
||||
tagCompound.setByte("shake", (byte)this.throwableShake);
|
||||
tagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0));
|
||||
|
||||
// if ((this.throwerName == null || this.throwerName.length() == 0) && this.thrower.isPlayer())
|
||||
// {
|
||||
// this.throwerName = ((EntityNPC)this.thrower).getUser();
|
||||
// }
|
||||
//
|
||||
// tagCompound.setString("ownerName", this.throwerName == null ? "" : this.throwerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
||||
{
|
||||
this.xTile = tagCompund.getShort("xTile");
|
||||
this.yTile = tagCompund.getShort("yTile");
|
||||
this.zTile = tagCompund.getShort("zTile");
|
||||
|
||||
if (tagCompund.hasKey("inTile", 8))
|
||||
{
|
||||
this.inTile = BlockRegistry.getByIdFallback(tagCompund.getString("inTile"));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inTile = BlockRegistry.getBlockById(tagCompund.getByte("inTile") & 255);
|
||||
}
|
||||
|
||||
this.throwableShake = tagCompund.getByte("shake") & 255;
|
||||
this.inGround = tagCompund.getByte("inGround") == 1;
|
||||
// this.thrower = null;
|
||||
// this.throwerName = tagCompund.getString("ownerName");
|
||||
//
|
||||
// if (this.throwerName != null && this.throwerName.length() == 0)
|
||||
// {
|
||||
// this.throwerName = null;
|
||||
// }
|
||||
|
||||
// this.thrower = this.getThrower();
|
||||
}
|
||||
|
||||
public EntityLiving getThrower()
|
||||
{
|
||||
// if (this.thrower == null && this.throwerName != null && this.throwerName.length() > 0)
|
||||
// {
|
||||
// this.thrower = this.worldObj.getPlayer(this.throwerName);
|
||||
|
||||
// if (this.thrower == null && this.worldObj instanceof WorldServer)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// Entity entity = ((WorldServer)this.worldObj).getEntityFromUuid(UUID.fromString(this.throwerName));
|
||||
//
|
||||
// if (entity instanceof EntityLivingBase)
|
||||
// {
|
||||
// this.thrower = (EntityLivingBase)entity;
|
||||
// }
|
||||
// }
|
||||
// catch (Throwable var2)
|
||||
// {
|
||||
// this.thrower = null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return this.thrower;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
}
|
111
java/src/game/entity/types/EntityWaterMob.java
Executable file
111
java/src/game/entity/types/EntityWaterMob.java
Executable file
|
@ -0,0 +1,111 @@
|
|||
package game.entity.types;
|
||||
|
||||
import game.entity.DamageSource;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.init.Config;
|
||||
import game.world.World;
|
||||
|
||||
public abstract class EntityWaterMob extends EntityLiving
|
||||
{
|
||||
public EntityWaterMob(World worldIn)
|
||||
{
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
// public boolean canBreatheUnderwater()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Checks if the entity's current position is a valid location to spawn this entity.
|
||||
// */
|
||||
// public boolean getCanSpawnHere()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Checks that the entity is not colliding with any blocks / liquids
|
||||
// */
|
||||
// public boolean isNotColliding()
|
||||
// {
|
||||
// return this.worldObj.checkNoEntityCollision(this.getEntityBoundingBox(), this) &&
|
||||
// this.worldObj.getCollidingBoundingBoxes(this, this.getEntityBoundingBox()).isEmpty(); //TODO: check
|
||||
// }
|
||||
|
||||
public boolean canSpawnInLiquid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of ticks, at least during which the living entity will be silent.
|
||||
*/
|
||||
public int getTalkInterval()
|
||||
{
|
||||
return 120;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Determines if an entity can be despawned, used on idle far away entities
|
||||
// */
|
||||
// protected boolean canDespawn()
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the experience points the entity currently has.
|
||||
*/
|
||||
protected int getExperiencePoints(EntityNPC player)
|
||||
{
|
||||
return this.worldObj.rand.roll(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets called every tick from main Entity class
|
||||
*/
|
||||
public void onEntityUpdate()
|
||||
{
|
||||
// int i = this.getAir();
|
||||
super.onEntityUpdate();
|
||||
|
||||
if (this.isEntityAlive() && (this.worldObj.client || Config.waterMobDry) && !this.isInLiquid() && this.rand.chance(30))
|
||||
{
|
||||
// --i;
|
||||
// this.setAir(i);
|
||||
//
|
||||
// if (this.getAir() == -20)
|
||||
// {
|
||||
// this.setAir(0);
|
||||
this.attackEntityFrom(DamageSource.dry, 2);
|
||||
// }
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// this.setAir(300);
|
||||
// }
|
||||
}
|
||||
|
||||
public boolean isPushedByWater()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getTrackingRange() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public int getUpdateFrequency() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public boolean isSendingVeloUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean getCanSpawnHere()
|
||||
{
|
||||
return this.posY > 45.0D && this.posY < (double)this.worldObj.getSeaLevel();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue