add gradle
This commit is contained in:
parent
bb6ebb0be8
commit
4e51e18bdc
3033 changed files with 470 additions and 0 deletions
11
common/src/main/java/common/Version.java
Normal file
11
common/src/main/java/common/Version.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package common;
|
||||
|
||||
import common.util.ReleaseType;
|
||||
|
||||
public abstract class Version {
|
||||
public static final String NAME = "TCR";
|
||||
public static final ReleaseType RELEASE = ReleaseType.DEV;
|
||||
public static final int MAJOR = 2;
|
||||
public static final int MINOR = 3;
|
||||
public static final int PATCH = 0;
|
||||
}
|
96
common/src/main/java/common/ai/AIFireballAttack.java
Executable file
96
common/src/main/java/common/ai/AIFireballAttack.java
Executable file
|
@ -0,0 +1,96 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.projectile.EntityFireball;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Items;
|
||||
import common.item.ItemStack;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Vec3;
|
||||
import common.world.World;
|
||||
|
||||
public class AIFireballAttack extends EntityAIBase
|
||||
{
|
||||
public final int power;
|
||||
public final int delay;
|
||||
public final double distance;
|
||||
public final double velocity;
|
||||
private final EntityNPC parentEntity;
|
||||
public int attackTimer;
|
||||
|
||||
public AIFireballAttack(EntityNPC entity, int power, int delay, double distance, double velocity)
|
||||
{
|
||||
this.parentEntity = entity;
|
||||
this.power = power;
|
||||
this.delay = delay;
|
||||
this.distance = distance;
|
||||
this.velocity = velocity;
|
||||
// this.setMutexBits(3);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.parentEntity.getAttackTarget() != null;
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
this.attackTimer = 0;
|
||||
}
|
||||
|
||||
public void resetTask()
|
||||
{
|
||||
this.parentEntity.setItemNoUpdate(0, null);
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
EntityLiving target = this.parentEntity.getAttackTarget();
|
||||
// double d0 = 64.0D;
|
||||
|
||||
if (target.getDistanceSqToEntity(this.parentEntity) < this.distance * this.distance && this.parentEntity.canEntityBeSeen(target))
|
||||
{
|
||||
World world = this.parentEntity.worldObj;
|
||||
++this.attackTimer;
|
||||
|
||||
if (this.attackTimer == this.delay)
|
||||
{
|
||||
world.playAuxSFX(1007, new BlockPos(this.parentEntity), 0);
|
||||
this.parentEntity.setItemNoUpdate(0, new ItemStack(Items.orb));
|
||||
}
|
||||
|
||||
if (this.attackTimer == this.delay * 2)
|
||||
{
|
||||
this.parentEntity.swingItem();
|
||||
this.parentEntity.setItemNoUpdate(0, null);
|
||||
double d1 = 1.0D;
|
||||
Vec3 vec3 = this.parentEntity.getLook(1.0F);
|
||||
double d2 = target.posX - (this.parentEntity.posX + vec3.xCoord * d1);
|
||||
double d3 = target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - (this.parentEntity.posY + (double)this.parentEntity.getEyeHeight());
|
||||
double d4 = target.posZ - (this.parentEntity.posZ + vec3.zCoord * d1);
|
||||
world.playAuxSFX(1008, new BlockPos(this.parentEntity), 0);
|
||||
EntityFireball fireball = new EntityFireball(world, this.parentEntity, d2, d3, d4, this.velocity);
|
||||
// 0.0, 0.0, 0.0);
|
||||
// fireball.setAcceleration(d2 + this.parentEntity.getRNG().gaussian() * 0.1D,
|
||||
// d3 + this.parentEntity.getRNG().gaussian() * 0.1D,
|
||||
// d4 + this.parentEntity.getRNG().gaussian() * 0.1D);
|
||||
// fireball.accelerationX *= this.velocity;
|
||||
// fireball.accelerationY *= this.velocity;
|
||||
// fireball.accelerationZ *= this.velocity;
|
||||
fireball.explosionPower = this.power;
|
||||
fireball.posX = this.parentEntity.posX + vec3.xCoord * d1;
|
||||
fireball.posY = this.parentEntity.posY + (double)this.parentEntity.getEyeHeight();
|
||||
fireball.posZ = this.parentEntity.posZ + vec3.zCoord * d1;
|
||||
world.spawnEntityInWorld(fireball);
|
||||
this.attackTimer = -this.delay * this.parentEntity.getRNG().range(1, 4);
|
||||
}
|
||||
this.parentEntity.getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f);
|
||||
}
|
||||
else if (this.attackTimer > 0)
|
||||
{
|
||||
--this.attackTimer;
|
||||
}
|
||||
|
||||
this.parentEntity.setItemNoUpdate(0, this.attackTimer > this.delay ? new ItemStack(Items.orb) : null);
|
||||
}
|
||||
}
|
91
common/src/main/java/common/ai/AIFlyingBoxAttack.java
Executable file
91
common/src/main/java/common/ai/AIFlyingBoxAttack.java
Executable file
|
@ -0,0 +1,91 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.projectile.EntityBox;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.BlockPos;
|
||||
|
||||
public class AIFlyingBoxAttack extends EntityAIBase
|
||||
{
|
||||
private EntityNPC entity;
|
||||
private int delay;
|
||||
private int charge;
|
||||
|
||||
public AIFlyingBoxAttack(EntityNPC entity)
|
||||
{
|
||||
this.entity = entity;
|
||||
// this.setMutexBits(3);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityLiving tgt = this.entity.getAttackTarget();
|
||||
return tgt != null && tgt.isEntityAlive();
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
this.delay = 0;
|
||||
this.charge = 0;
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.delay <= 0)
|
||||
{
|
||||
this.delay = this.entity.getRNG().excl(10, 20);
|
||||
|
||||
int k3 = this.charge;
|
||||
++this.charge;
|
||||
|
||||
if (k3 > 15)
|
||||
{
|
||||
float f = 10.0F;
|
||||
float f1 = 5.0F;
|
||||
double d0 = this.entity.getRNG().drange(this.entity.posX - (double)f, this.entity.posX + (double)f);
|
||||
double d1 = this.entity.getRNG().drange(this.entity.posY - (double)f1, this.entity.posY + (double)f1);
|
||||
double d2 = this.entity.getRNG().drange(this.entity.posZ - (double)f, this.entity.posZ + (double)f);
|
||||
this.launchBoxToCoords(d0, d1, d2, true);
|
||||
this.charge = 0;
|
||||
}
|
||||
|
||||
EntityLiving entity = this.entity.getAttackTarget();
|
||||
|
||||
if (entity != null && entity.isEntityAlive() && this.entity.getDistanceSqToEntity(entity) <= 900.0D && this.entity.canEntityBeSeen(entity))
|
||||
{
|
||||
this.launchBoxToEntity(entity);
|
||||
this.delay = this.entity.getRNG().excl(5, 10);
|
||||
this.charge = 0;
|
||||
this.entity.getLookHelper().setLookPositionWithEntity(entity, 30.0F, 30.0F);
|
||||
}
|
||||
}
|
||||
else {
|
||||
--this.delay;
|
||||
}
|
||||
|
||||
super.updateTask();
|
||||
}
|
||||
|
||||
private void launchBoxToEntity(EntityLiving p_82216_2_)
|
||||
{
|
||||
this.launchBoxToCoords(p_82216_2_.posX, p_82216_2_.posY + (double)p_82216_2_.getEyeHeight() * 0.5D, p_82216_2_.posZ,
|
||||
this.entity.getRNG().chance(100));
|
||||
}
|
||||
|
||||
private void launchBoxToCoords(double x, double y, double z, boolean invulnerable)
|
||||
{
|
||||
this.entity.swingItem();
|
||||
this.entity.worldObj.playAuxSFX(1014, new BlockPos(this.entity), 0);
|
||||
double d0 = this.entity.posX;
|
||||
double d1 = this.entity.posY + this.entity.height + 0.8;
|
||||
double d2 = this.entity.posZ;
|
||||
double d3 = x - d0;
|
||||
double d4 = y - d1;
|
||||
double d5 = z - d2;
|
||||
EntityBox skull = new EntityBox(this.entity.worldObj, this.entity, d3, d4, d5, invulnerable);
|
||||
skull.posY = d1;
|
||||
skull.posX = d0;
|
||||
skull.posZ = d2;
|
||||
this.entity.worldObj.spawnEntityInWorld(skull);
|
||||
}
|
||||
}
|
122
common/src/main/java/common/ai/AIRangedAttack.java
Executable file
122
common/src/main/java/common/ai/AIRangedAttack.java
Executable file
|
@ -0,0 +1,122 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public class AIRangedAttack extends EntityAIBase
|
||||
{
|
||||
private final EntityNPC entity;
|
||||
private EntityLiving target;
|
||||
private int delay;
|
||||
private double speed;
|
||||
private int timeout;
|
||||
private int minDelay;
|
||||
private int maxDelay;
|
||||
private float distance;
|
||||
private float distanceSq;
|
||||
|
||||
public AIRangedAttack(EntityNPC attacker, double movespeed, int minDelay, int maxDelay, float maxAttackDistanceIn)
|
||||
{
|
||||
this.delay = -1;
|
||||
this.entity = attacker;
|
||||
this.speed = movespeed;
|
||||
this.minDelay = minDelay;
|
||||
this.maxDelay = maxDelay;
|
||||
this.distance = maxAttackDistanceIn;
|
||||
this.distanceSq = maxAttackDistanceIn * maxAttackDistanceIn;
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if(this.entity.isFleeing())
|
||||
return false;
|
||||
EntityLiving entitylivingbase = this.entity.getAttackTarget();
|
||||
|
||||
if (entitylivingbase == null || entitylivingbase.dead)
|
||||
{
|
||||
this.target = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.target = entitylivingbase;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.shouldExecute() || (!this.entity.isFleeing() && !this.entity.getNavigator().noPath() && this.target != null && !this.target.dead);
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
this.entity.setUsingItem(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.target = null;
|
||||
this.timeout = 0;
|
||||
this.delay = -1;
|
||||
this.entity.setUsingItem(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
double d0 = this.entity.getDistanceSq(this.target.posX, this.target.getEntityBoundingBox().minY, this.target.posZ);
|
||||
boolean flag = this.entity.getEntitySenses().canSee(this.target);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
++this.timeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.timeout = 0;
|
||||
}
|
||||
|
||||
if (d0 <= (double)this.distanceSq && this.timeout >= 20)
|
||||
{
|
||||
this.entity.getNavigator().clearPathEntity();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entity.getNavigator().tryMoveToEntityLiving(this.target, this.speed);
|
||||
}
|
||||
|
||||
this.entity.getLookHelper().setLookPositionWithEntity(this.target, 30.0F, 30.0F);
|
||||
|
||||
if (--this.delay == 0)
|
||||
{
|
||||
if (d0 > (double)this.distanceSq || !flag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float f = ExtMath.sqrtd(d0) / this.distance;
|
||||
float lvt_5_1_ = ExtMath.clampf(f, 0.1F, 1.0F);
|
||||
this.entity.attackEntityWithRangedAttack(this.target, lvt_5_1_);
|
||||
this.delay = ExtMath.floorf(f * (float)(this.maxDelay - this.minDelay) + (float)this.minDelay);
|
||||
}
|
||||
else if (this.delay < 0)
|
||||
{
|
||||
float f2 = ExtMath.sqrtd(d0) / this.distance;
|
||||
this.delay = ExtMath.floorf(f2 * (float)(this.maxDelay - this.minDelay) + (float)this.minDelay);
|
||||
}
|
||||
}
|
||||
}
|
105
common/src/main/java/common/ai/AISmallFireballAttack.java
Executable file
105
common/src/main/java/common/ai/AISmallFireballAttack.java
Executable file
|
@ -0,0 +1,105 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.projectile.EntityFireCharge;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.BlockPos;
|
||||
|
||||
public class AISmallFireballAttack extends EntityAIBase
|
||||
{
|
||||
private EntityNPC entity;
|
||||
private int timer;
|
||||
private int charge;
|
||||
private int amount;
|
||||
|
||||
public AISmallFireballAttack(EntityNPC entity)
|
||||
{
|
||||
this.entity = entity;
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityLiving tgt = this.entity.getAttackTarget();
|
||||
return tgt != null && tgt.isEntityAlive();
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
this.timer = 0;
|
||||
}
|
||||
|
||||
public void resetTask()
|
||||
{
|
||||
this.entity.setAttacking(false);
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
--this.charge;
|
||||
EntityLiving target = this.entity.getAttackTarget();
|
||||
double d0 = this.entity.getDistanceSqToEntity(target);
|
||||
|
||||
if (d0 < 4.0D)
|
||||
{
|
||||
if (this.charge <= 0)
|
||||
{
|
||||
this.charge = this.entity.getRNG().range(8, 20);
|
||||
this.entity.attackEntityAsMob(target);
|
||||
}
|
||||
|
||||
this.entity.getMoveHelper().setMoveTo(target.posX, target.posY, target.posZ, 1.0D);
|
||||
}
|
||||
else if (d0 < 256.0D)
|
||||
{
|
||||
double d1 = target.posX - this.entity.posX;
|
||||
double d2 = target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - (this.entity.posY + (double)(this.entity.height / 2.0F));
|
||||
double d3 = target.posZ - this.entity.posZ;
|
||||
|
||||
if (this.charge <= 0)
|
||||
{
|
||||
++this.timer;
|
||||
|
||||
if (this.timer == 1)
|
||||
{
|
||||
this.charge = this.entity.getRNG().range(10, 20); // 60
|
||||
this.entity.setAttacking(true);
|
||||
this.amount = this.entity.getRNG().range(5, 25);
|
||||
}
|
||||
else if (this.timer <= this.amount)
|
||||
{
|
||||
this.charge = this.entity.getRNG().range(2, 6); // 6
|
||||
}
|
||||
else
|
||||
{
|
||||
this.charge = this.entity.getRNG().range(2, 6); // 100
|
||||
this.timer = 0;
|
||||
this.entity.setAttacking(false);
|
||||
}
|
||||
|
||||
if (this.timer > 1)
|
||||
{
|
||||
this.entity.swingItem();
|
||||
// float f = MathHelper.sqrt_float(MathHelper.sqrt_double(d0)) * 0.5F;
|
||||
this.entity.worldObj.playAuxSFX(1009, new BlockPos((int)this.entity.posX, (int)this.entity.posY, (int)this.entity.posZ), 0);
|
||||
|
||||
for (int i = 0; i < 1; ++i)
|
||||
{
|
||||
EntityFireCharge entitysmallfireball = new EntityFireCharge(this.entity.worldObj, this.entity, d1 /* + this.entity.getRNG().gaussian() * (double)f */, d2, d3 /* + this.entity.getRNG().gaussian() * (double)f */);
|
||||
entitysmallfireball.posY = this.entity.posY + (double)(this.entity.height / 2.0F) + 0.5D;
|
||||
this.entity.worldObj.spawnEntityInWorld(entitysmallfireball);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.entity.getLookHelper().setLookPositionWithEntity(target, 30.0F, 30.0F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entity.getNavigator().clearPathEntity();
|
||||
this.entity.getMoveHelper().setMoveTo(target.posX, target.posY, target.posZ, 1.0D);
|
||||
}
|
||||
|
||||
super.updateTask();
|
||||
}
|
||||
}
|
167
common/src/main/java/common/ai/EntityAIAttackOnCollide.java
Executable file
167
common/src/main/java/common/ai/EntityAIAttackOnCollide.java
Executable file
|
@ -0,0 +1,167 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathEntity;
|
||||
import common.util.BlockPos;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIAttackOnCollide extends EntityAIBase
|
||||
{
|
||||
World worldObj;
|
||||
protected EntityLiving attacker;
|
||||
|
||||
/**
|
||||
* An amount of decrementing ticks that allows the entity to attack once the tick reaches 0.
|
||||
*/
|
||||
int attackTick;
|
||||
|
||||
/** The speed with which the mob will approach the target */
|
||||
double speedTowardsTarget;
|
||||
|
||||
/**
|
||||
* When true, the mob will continue chasing its target, even if it can't find a path to them right now.
|
||||
*/
|
||||
boolean longMemory;
|
||||
private final boolean swing;
|
||||
|
||||
/** The PathEntity of our entity. */
|
||||
PathEntity entityPathEntity;
|
||||
Class <? extends Entity > classTarget;
|
||||
private int delayCounter;
|
||||
private double targetX;
|
||||
private double targetY;
|
||||
private double targetZ;
|
||||
|
||||
public EntityAIAttackOnCollide(EntityLiving creature, Class <? extends Entity > targetClass, double speedIn, boolean useLongMemory, boolean swingItem)
|
||||
{
|
||||
this(creature, speedIn, useLongMemory, swingItem);
|
||||
this.classTarget = targetClass;
|
||||
}
|
||||
|
||||
public EntityAIAttackOnCollide(EntityLiving creature, double speedIn, boolean useLongMemory, boolean swingItem)
|
||||
{
|
||||
this.attacker = creature;
|
||||
this.worldObj = creature.worldObj;
|
||||
this.speedTowardsTarget = speedIn;
|
||||
this.longMemory = useLongMemory;
|
||||
this.swing = swingItem;
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
|
||||
public EntityAIAttackOnCollide(EntityLiving creature, Class <? extends Entity > targetClass, double speedIn, boolean useLongMemory)
|
||||
{
|
||||
this(creature, speedIn, useLongMemory);
|
||||
this.classTarget = targetClass;
|
||||
}
|
||||
|
||||
public EntityAIAttackOnCollide(EntityLiving creature, double speedIn, boolean useLongMemory)
|
||||
{
|
||||
this(creature, speedIn, useLongMemory, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.attacker.getAttackTarget();
|
||||
|
||||
if (entitylivingbase == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!entitylivingbase.isEntityAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.classTarget != null && !this.classTarget.isAssignableFrom(entitylivingbase.getClass()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entityPathEntity = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase);
|
||||
return this.entityPathEntity != null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.attacker.getAttackTarget();
|
||||
return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!this.longMemory ? !this.attacker.getNavigator().noPath() : this.attacker.isWithinHomeDistanceFromPosition(new BlockPos(entitylivingbase))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.attacker.getNavigator().setPath(this.entityPathEntity, this.speedTowardsTarget);
|
||||
this.delayCounter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.attacker.getNavigator().clearPathEntity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.attacker.getAttackTarget();
|
||||
this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F);
|
||||
double d0 = this.attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.getEntityBoundingBox().minY, entitylivingbase.posZ);
|
||||
double d1 = this.getAttackRange(entitylivingbase);
|
||||
--this.delayCounter;
|
||||
|
||||
if ((this.longMemory || this.attacker.getEntitySenses().canSee(entitylivingbase)) && this.delayCounter <= 0 && (this.targetX == 0.0D && this.targetY == 0.0D && this.targetZ == 0.0D || entitylivingbase.getDistanceSq(this.targetX, this.targetY, this.targetZ) >= 1.0D || this.attacker.getRNG().floatv() < 0.05F))
|
||||
{
|
||||
this.targetX = entitylivingbase.posX;
|
||||
this.targetY = entitylivingbase.getEntityBoundingBox().minY;
|
||||
this.targetZ = entitylivingbase.posZ;
|
||||
this.delayCounter = 4 + this.attacker.getRNG().zrange(7);
|
||||
|
||||
if (d0 > 1024.0D)
|
||||
{
|
||||
this.delayCounter += 10;
|
||||
}
|
||||
else if (d0 > 256.0D)
|
||||
{
|
||||
this.delayCounter += 5;
|
||||
}
|
||||
|
||||
if (!this.attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, this.speedTowardsTarget))
|
||||
{
|
||||
this.delayCounter += 15;
|
||||
}
|
||||
}
|
||||
|
||||
this.attackTick = Math.max(this.attackTick - 1, 0);
|
||||
|
||||
if (d0 <= d1 && this.attackTick <= 0)
|
||||
{
|
||||
this.attackTick = 20;
|
||||
|
||||
// if (this.attacker.getHeldItem() != null)
|
||||
// {
|
||||
this.attacker.swingItem();
|
||||
// }
|
||||
|
||||
this.attacker.attackEntityAsMob(entitylivingbase);
|
||||
}
|
||||
}
|
||||
|
||||
protected double getAttackRange(EntityLiving attackTarget)
|
||||
{
|
||||
return (double)(this.attacker.width * 2.0F * this.attacker.width * 2.0F + attackTarget.width);
|
||||
}
|
||||
}
|
126
common/src/main/java/common/ai/EntityAIAvoidEntity.java
Executable file
126
common/src/main/java/common/ai/EntityAIAvoidEntity.java
Executable file
|
@ -0,0 +1,126 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathEntity;
|
||||
import common.pathfinding.PathNavigate;
|
||||
import common.util.Predicates;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class EntityAIAvoidEntity<T extends Entity> extends EntityAIBase
|
||||
{
|
||||
private final Predicate<Entity> canBeSeenSelector;
|
||||
|
||||
/** The entity we are attached to */
|
||||
protected EntityLiving theEntity;
|
||||
private double farSpeed;
|
||||
private double nearSpeed;
|
||||
protected T closestLivingEntity;
|
||||
private float avoidDistance;
|
||||
|
||||
/** The PathEntity of our entity */
|
||||
private PathEntity entityPathEntity;
|
||||
|
||||
/** The PathNavigate of our entity */
|
||||
private PathNavigate entityPathNavigate;
|
||||
private Class<T> classToAvoid;
|
||||
private Predicate <? super T > avoidTargetSelector;
|
||||
|
||||
public EntityAIAvoidEntity(EntityLiving theEntityIn, Class<T> classToAvoidIn, float avoidDistanceIn, double farSpeedIn, double nearSpeedIn)
|
||||
{
|
||||
this(theEntityIn, classToAvoidIn, Predicates.<T>alwaysTrue(), avoidDistanceIn, farSpeedIn, nearSpeedIn);
|
||||
}
|
||||
|
||||
public EntityAIAvoidEntity(EntityLiving theEntityIn, Class<T> classToAvoidIn, Predicate <? super T > avoidTargetSelectorIn, float avoidDistanceIn, double farSpeedIn, double nearSpeedIn)
|
||||
{
|
||||
this.canBeSeenSelector = new Predicate<Entity>()
|
||||
{
|
||||
public boolean test(Entity p_apply_1_)
|
||||
{
|
||||
return p_apply_1_.isEntityAlive() && EntityAIAvoidEntity.this.theEntity.getEntitySenses().canSee(p_apply_1_);
|
||||
}
|
||||
};
|
||||
this.theEntity = theEntityIn;
|
||||
this.classToAvoid = classToAvoidIn;
|
||||
this.avoidTargetSelector = avoidTargetSelectorIn;
|
||||
this.avoidDistance = avoidDistanceIn;
|
||||
this.farSpeed = farSpeedIn;
|
||||
this.nearSpeed = nearSpeedIn;
|
||||
this.entityPathNavigate = theEntityIn.getNavigator();
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
List<T> list = this.theEntity.worldObj.<T>getEntitiesWithinAABB(this.classToAvoid, this.theEntity.getEntityBoundingBox().expand((double)this.avoidDistance, 3.0D, (double)this.avoidDistance), Predicates.and(new Predicate[] {this.canBeSeenSelector, this.avoidTargetSelector}));
|
||||
|
||||
if (list.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.closestLivingEntity = list.get(0);
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockAwayFrom(this.theEntity, 16, 7, new Vec3(this.closestLivingEntity.posX, this.closestLivingEntity.posY, this.closestLivingEntity.posZ));
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.closestLivingEntity.getDistanceSq(vec3.xCoord, vec3.yCoord, vec3.zCoord) < this.closestLivingEntity.getDistanceSqToEntity(this.theEntity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entityPathEntity = this.entityPathNavigate.getPathToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord);
|
||||
return this.entityPathEntity == null ? false : this.entityPathEntity.isDestinationSame(vec3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.entityPathNavigate.noPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.entityPathNavigate.setPath(this.entityPathEntity, this.farSpeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.closestLivingEntity = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.theEntity.getDistanceSqToEntity(this.closestLivingEntity) < 49.0D)
|
||||
{
|
||||
this.theEntity.getNavigator().setSpeed(this.nearSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.theEntity.getNavigator().setSpeed(this.farSpeed);
|
||||
}
|
||||
}
|
||||
}
|
71
common/src/main/java/common/ai/EntityAIBase.java
Executable file
71
common/src/main/java/common/ai/EntityAIBase.java
Executable file
|
@ -0,0 +1,71 @@
|
|||
package common.ai;
|
||||
|
||||
public abstract class EntityAIBase
|
||||
{
|
||||
/**
|
||||
* A bitmask telling which other tasks may not run concurrently. The test is a simple bitwise AND - if it yields
|
||||
* zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
|
||||
*/
|
||||
private int mutexBits;
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public abstract boolean shouldExecute();
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.shouldExecute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this AI Task is interruptible by a higher (= lower value) priority task. All vanilla AITask have
|
||||
* this value set to true.
|
||||
*/
|
||||
public boolean isInterruptible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a bitmask telling which other tasks may not run concurrently. The test is a simple bitwise AND - if it
|
||||
* yields zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
|
||||
*/
|
||||
public void setMutexBits(int mutexBitsIn)
|
||||
{
|
||||
this.mutexBits = mutexBitsIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a bitmask telling which other tasks may not run concurrently. The test is a simple bitwise AND - if it yields
|
||||
* zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
|
||||
*/
|
||||
public int getMutexBits()
|
||||
{
|
||||
return this.mutexBits;
|
||||
}
|
||||
}
|
77
common/src/main/java/common/ai/EntityAIBeg.java
Executable file
77
common/src/main/java/common/ai/EntityAIBeg.java
Executable file
|
@ -0,0 +1,77 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.animal.EntityWolf;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Items;
|
||||
import common.item.ItemStack;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIBeg extends EntityAIBase
|
||||
{
|
||||
private EntityWolf theWolf;
|
||||
private EntityNPC thePlayer;
|
||||
private World worldObject;
|
||||
private float minPlayerDistance;
|
||||
private int timeoutCounter;
|
||||
|
||||
public EntityAIBeg(EntityWolf wolf, float minDistance)
|
||||
{
|
||||
this.theWolf = wolf;
|
||||
this.worldObject = wolf.worldObj;
|
||||
this.minPlayerDistance = minDistance;
|
||||
this.setMutexBits(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
this.thePlayer = this.worldObject.getClosestPlayerToEntity(this.theWolf, (double)this.minPlayerDistance);
|
||||
return this.thePlayer == null ? false : this.hasPlayerGotBoneInHand(this.thePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.thePlayer.isEntityAlive() ? false : (this.theWolf.getDistanceSqToEntity(this.thePlayer) > (double)(this.minPlayerDistance * this.minPlayerDistance) ? false : this.timeoutCounter > 0 && this.hasPlayerGotBoneInHand(this.thePlayer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theWolf.setBegging(true);
|
||||
this.timeoutCounter = 40 + this.theWolf.getRNG().zrange(40);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.theWolf.setBegging(false);
|
||||
this.thePlayer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.theWolf.getLookHelper().setLookPosition(this.thePlayer.posX, this.thePlayer.posY + (double)this.thePlayer.getEyeHeight(), this.thePlayer.posZ, 10.0F, (float)this.theWolf.getVerticalFaceSpeed());
|
||||
--this.timeoutCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the Player has the Bone in the hand.
|
||||
*/
|
||||
private boolean hasPlayerGotBoneInHand(EntityNPC player)
|
||||
{
|
||||
ItemStack itemstack = player.inventory.getCurrentItem();
|
||||
return itemstack == null ? false : (!this.theWolf.isTamed() && itemstack.getItem() == Items.bone ? true : this.theWolf.isBreedingItem(itemstack));
|
||||
}
|
||||
}
|
226
common/src/main/java/common/ai/EntityAIControlledByPlayer.java
Executable file
226
common/src/main/java/common/ai/EntityAIControlledByPlayer.java
Executable file
|
@ -0,0 +1,226 @@
|
|||
package common.ai;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.artificial.BlockSlab;
|
||||
import common.block.artificial.BlockStairs;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Blocks;
|
||||
import common.init.Items;
|
||||
import common.item.ItemStack;
|
||||
import common.pathfinding.WalkNodeProcessor;
|
||||
import common.util.BlockPos;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public class EntityAIControlledByPlayer extends EntityAIBase
|
||||
{
|
||||
private final EntityLiving thisEntity;
|
||||
private final float maxSpeed;
|
||||
private float currentSpeed;
|
||||
|
||||
/** Whether the entity's speed is boosted. */
|
||||
private boolean speedBoosted;
|
||||
|
||||
/**
|
||||
* Counter for speed boosting, upon reaching maxSpeedBoostTime the speed boost will be disabled
|
||||
*/
|
||||
private int speedBoostTime;
|
||||
|
||||
/** Maximum time the entity's speed should be boosted for. */
|
||||
private int maxSpeedBoostTime;
|
||||
|
||||
public EntityAIControlledByPlayer(EntityLiving entitylivingIn, float maxspeed)
|
||||
{
|
||||
this.thisEntity = entitylivingIn;
|
||||
this.maxSpeed = maxspeed;
|
||||
this.setMutexBits(7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.currentSpeed = 0.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.speedBoosted = false;
|
||||
this.currentSpeed = 0.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.thisEntity.isEntityAlive() && this.thisEntity.passenger != null && this.thisEntity.passenger.isPlayer() && (this.speedBoosted || this.thisEntity.canBeSteered());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
EntityNPC entityplayer = (EntityNPC)this.thisEntity.passenger;
|
||||
EntityLiving entitycreature = (EntityLiving)this.thisEntity;
|
||||
float f = ExtMath.wrapf(entityplayer.rotYaw - this.thisEntity.rotYaw) * 0.5F;
|
||||
|
||||
if (f > 5.0F)
|
||||
{
|
||||
f = 5.0F;
|
||||
}
|
||||
|
||||
if (f < -5.0F)
|
||||
{
|
||||
f = -5.0F;
|
||||
}
|
||||
|
||||
this.thisEntity.rotYaw = ExtMath.wrapf(this.thisEntity.rotYaw + f);
|
||||
|
||||
if (this.currentSpeed < this.maxSpeed)
|
||||
{
|
||||
this.currentSpeed += (this.maxSpeed - this.currentSpeed) * 0.01F;
|
||||
}
|
||||
|
||||
if (this.currentSpeed > this.maxSpeed)
|
||||
{
|
||||
this.currentSpeed = this.maxSpeed;
|
||||
}
|
||||
|
||||
int i = ExtMath.floord(this.thisEntity.posX);
|
||||
int j = ExtMath.floord(this.thisEntity.posY);
|
||||
int k = ExtMath.floord(this.thisEntity.posZ);
|
||||
float f1 = this.currentSpeed;
|
||||
|
||||
if (this.speedBoosted)
|
||||
{
|
||||
if (this.speedBoostTime++ > this.maxSpeedBoostTime)
|
||||
{
|
||||
this.speedBoosted = false;
|
||||
}
|
||||
|
||||
f1 += f1 * 1.15F * ExtMath.sin((float)this.speedBoostTime / (float)this.maxSpeedBoostTime * (float)Math.PI);
|
||||
}
|
||||
|
||||
float f2 = 0.91F;
|
||||
|
||||
if (this.thisEntity.onGround)
|
||||
{
|
||||
f2 = this.thisEntity.worldObj.getState(new BlockPos(ExtMath.floorf((float)i), ExtMath.floorf((float)j) - 1, ExtMath.floorf((float)k))).getBlock().slipperiness * 0.91F;
|
||||
}
|
||||
|
||||
float f3 = 0.16277136F / (f2 * f2 * f2);
|
||||
float f4 = ExtMath.sin(entitycreature.rotYaw * (float)Math.PI / 180.0F);
|
||||
float f5 = ExtMath.cos(entitycreature.rotYaw * (float)Math.PI / 180.0F);
|
||||
float f6 = entitycreature.getAIMoveSpeed() * f3;
|
||||
float f7 = Math.max(f1, 1.0F);
|
||||
f7 = f6 / f7;
|
||||
float f8 = f1 * f7;
|
||||
float f9 = -(f8 * f4);
|
||||
float f10 = f8 * f5;
|
||||
|
||||
if (ExtMath.absf(f9) > ExtMath.absf(f10))
|
||||
{
|
||||
if (f9 < 0.0F)
|
||||
{
|
||||
f9 -= this.thisEntity.width / 2.0F;
|
||||
}
|
||||
|
||||
if (f9 > 0.0F)
|
||||
{
|
||||
f9 += this.thisEntity.width / 2.0F;
|
||||
}
|
||||
|
||||
f10 = 0.0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
f9 = 0.0F;
|
||||
|
||||
if (f10 < 0.0F)
|
||||
{
|
||||
f10 -= this.thisEntity.width / 2.0F;
|
||||
}
|
||||
|
||||
if (f10 > 0.0F)
|
||||
{
|
||||
f10 += this.thisEntity.width / 2.0F;
|
||||
}
|
||||
}
|
||||
|
||||
int l = ExtMath.floord(this.thisEntity.posX + (double)f9);
|
||||
int i1 = ExtMath.floord(this.thisEntity.posZ + (double)f10);
|
||||
int j1 = ExtMath.floorf(this.thisEntity.width + 1.0F);
|
||||
int k1 = ExtMath.floorf(this.thisEntity.height + entityplayer.height + 1.0F);
|
||||
int l1 = ExtMath.floorf(this.thisEntity.width + 1.0F);
|
||||
|
||||
if (i != l || k != i1)
|
||||
{
|
||||
Block block = this.thisEntity.worldObj.getState(new BlockPos(i, j, k)).getBlock();
|
||||
boolean flag = !this.isStairOrSlab(block) && (block != Blocks.air || !this.isStairOrSlab(this.thisEntity.worldObj.getState(new BlockPos(i, j - 1, k)).getBlock()));
|
||||
|
||||
if (flag && 0 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j, i1, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, i, j + 1, k, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j + 1, i1, j1, k1, l1, false, false, true))
|
||||
{
|
||||
entitycreature.getJumpHelper().setJumping();
|
||||
}
|
||||
}
|
||||
|
||||
if (/* !entityplayer.creative && */ this.currentSpeed >= this.maxSpeed * 0.5F && this.thisEntity.getRNG().floatv() < 0.006F && !this.speedBoosted)
|
||||
{
|
||||
ItemStack itemstack = entityplayer.getHeldItem();
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == Items.carrot_on_a_stick)
|
||||
{
|
||||
itemstack.damageItem(1, entityplayer);
|
||||
|
||||
if (itemstack.stackSize == 0)
|
||||
{
|
||||
ItemStack itemstack1 = new ItemStack(Items.fishing_rod);
|
||||
itemstack1.setTagCompound(itemstack.getTagCompound());
|
||||
entityplayer.inventory.mainInventory[entityplayer.inventory.currentItem] = itemstack1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.thisEntity.moveEntityWithHeading(0.0F, f1);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the block is a stair block or a slab block
|
||||
*/
|
||||
private boolean isStairOrSlab(Block blockIn)
|
||||
{
|
||||
return blockIn instanceof BlockStairs || blockIn instanceof BlockSlab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the entity's speed is boosted.
|
||||
*/
|
||||
public boolean isSpeedBoosted()
|
||||
{
|
||||
return this.speedBoosted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Boost the entity's movement speed.
|
||||
*/
|
||||
public void boostSpeed()
|
||||
{
|
||||
this.speedBoosted = true;
|
||||
this.speedBoostTime = 0;
|
||||
this.maxSpeedBoostTime = this.thisEntity.getRNG().zrange(841) + 140;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the entity is being controlled by a player.
|
||||
*/
|
||||
public boolean isControlledByPlayer()
|
||||
{
|
||||
return !this.isSpeedBoosted() && this.currentSpeed > this.maxSpeed * 0.3F;
|
||||
}
|
||||
}
|
118
common/src/main/java/common/ai/EntityAIDoorInteract.java
Executable file
118
common/src/main/java/common/ai/EntityAIDoorInteract.java
Executable file
|
@ -0,0 +1,118 @@
|
|||
package common.ai;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.block.artificial.BlockDoor;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathEntity;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.pathfinding.PathPoint;
|
||||
import common.util.BlockPos;
|
||||
|
||||
public abstract class EntityAIDoorInteract extends EntityAIBase
|
||||
{
|
||||
protected EntityLiving theEntity;
|
||||
protected BlockPos doorPosition = BlockPos.ORIGIN;
|
||||
|
||||
/** The wooden door block */
|
||||
protected BlockDoor doorBlock;
|
||||
|
||||
/**
|
||||
* If is true then the Entity has stopped Door Interaction and compoleted the task.
|
||||
*/
|
||||
boolean hasStoppedDoorInteraction;
|
||||
float entityPositionX;
|
||||
float entityPositionZ;
|
||||
|
||||
public EntityAIDoorInteract(EntityLiving entityIn)
|
||||
{
|
||||
this.theEntity = entityIn;
|
||||
|
||||
if (!(entityIn.getNavigator() instanceof PathNavigateGround))
|
||||
{
|
||||
throw new IllegalArgumentException("Unsupported mob type for DoorInteractGoal");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.theEntity.collidedHorizontally)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
PathNavigateGround pathnavigateground = (PathNavigateGround)this.theEntity.getNavigator();
|
||||
PathEntity pathentity = pathnavigateground.getPath();
|
||||
|
||||
if (pathentity != null && !pathentity.isFinished() && pathnavigateground.getEnterDoors())
|
||||
{
|
||||
for (int i = 0; i < Math.min(pathentity.getCurrentPathIndex() + 2, pathentity.getCurrentPathLength()); ++i)
|
||||
{
|
||||
PathPoint pathpoint = pathentity.getPathPointFromIndex(i);
|
||||
this.doorPosition = new BlockPos(pathpoint.xCoord, pathpoint.yCoord + 1, pathpoint.zCoord);
|
||||
|
||||
if (this.theEntity.getDistanceSq((double)this.doorPosition.getX(), this.theEntity.posY, (double)this.doorPosition.getZ()) <= 2.25D)
|
||||
{
|
||||
this.doorBlock = this.getBlockDoor(this.doorPosition);
|
||||
|
||||
if (this.doorBlock != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.doorPosition = (new BlockPos(this.theEntity)).up();
|
||||
this.doorBlock = this.getBlockDoor(this.doorPosition);
|
||||
return this.doorBlock != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.hasStoppedDoorInteraction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.hasStoppedDoorInteraction = false;
|
||||
this.entityPositionX = (float)((double)((float)this.doorPosition.getX() + 0.5F) - this.theEntity.posX);
|
||||
this.entityPositionZ = (float)((double)((float)this.doorPosition.getZ() + 0.5F) - this.theEntity.posZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
float f = (float)((double)((float)this.doorPosition.getX() + 0.5F) - this.theEntity.posX);
|
||||
float f1 = (float)((double)((float)this.doorPosition.getZ() + 0.5F) - this.theEntity.posZ);
|
||||
float f2 = this.entityPositionX * f + this.entityPositionZ * f1;
|
||||
|
||||
if (f2 < 0.0F)
|
||||
{
|
||||
this.hasStoppedDoorInteraction = true;
|
||||
}
|
||||
}
|
||||
|
||||
private BlockDoor getBlockDoor(BlockPos pos)
|
||||
{
|
||||
Block block = this.theEntity.worldObj.getState(pos).getBlock();
|
||||
return block instanceof BlockDoor && block.getMaterial() == Material.WOOD ? (BlockDoor)block : null;
|
||||
}
|
||||
}
|
115
common/src/main/java/common/ai/EntityAIEatGrass.java
Executable file
115
common/src/main/java/common/ai/EntityAIEatGrass.java
Executable file
|
@ -0,0 +1,115 @@
|
|||
package common.ai;
|
||||
|
||||
import common.block.foliage.BlockTallGrass;
|
||||
import common.entity.animal.EntitySheep;
|
||||
import common.init.BlockRegistry;
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.util.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIEatGrass extends EntityAIBase
|
||||
{
|
||||
private EntitySheep grassEaterEntity;
|
||||
private World entityWorld;
|
||||
int eatingGrassTimer;
|
||||
|
||||
public EntityAIEatGrass(EntitySheep grassEaterEntityIn)
|
||||
{
|
||||
this.grassEaterEntity = grassEaterEntityIn;
|
||||
this.entityWorld = grassEaterEntityIn.worldObj;
|
||||
this.setMutexBits(7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.grassEaterEntity.getRNG().zrange(this.grassEaterEntity.isChild() ? 50 : 1000) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this.grassEaterEntity.posX, this.grassEaterEntity.posY, this.grassEaterEntity.posZ);
|
||||
State state = this.entityWorld.getState(blockpos);
|
||||
return (state.getBlock() == Blocks.tallgrass && state.getValue(BlockTallGrass.TYPE) == BlockTallGrass.EnumType.GRASS) ||
|
||||
this.entityWorld.getState(blockpos.down()).getBlock() == Blocks.grass;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.eatingGrassTimer = 40;
|
||||
this.entityWorld.setEntityState(this.grassEaterEntity, (byte)10);
|
||||
this.grassEaterEntity.getNavigator().clearPathEntity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.eatingGrassTimer = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.eatingGrassTimer > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of ticks since the entity started to eat grass
|
||||
*/
|
||||
public int getEatingGrassTimer()
|
||||
{
|
||||
return this.eatingGrassTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.eatingGrassTimer = Math.max(0, this.eatingGrassTimer - 1);
|
||||
|
||||
if (this.eatingGrassTimer == 4)
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this.grassEaterEntity.posX, this.grassEaterEntity.posY, this.grassEaterEntity.posZ);
|
||||
|
||||
State state = this.entityWorld.getState(blockpos);
|
||||
if (state.getBlock() == Blocks.tallgrass && state.getValue(BlockTallGrass.TYPE) == BlockTallGrass.EnumType.GRASS)
|
||||
{
|
||||
if (Config.mobGrief)
|
||||
{
|
||||
this.entityWorld.destroyBlock(blockpos, false);
|
||||
}
|
||||
|
||||
this.grassEaterEntity.eatGrass();
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos1 = blockpos.down();
|
||||
|
||||
if (this.entityWorld.getState(blockpos1).getBlock() == Blocks.grass)
|
||||
{
|
||||
if (Config.mobGrief)
|
||||
{
|
||||
this.entityWorld.playAuxSFX(2001, blockpos1, BlockRegistry.getIdFromBlock(Blocks.grass));
|
||||
this.entityWorld.setState(blockpos1, Blocks.dirt.getState(), 2);
|
||||
}
|
||||
|
||||
this.grassEaterEntity.eatGrass();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
65
common/src/main/java/common/ai/EntityAIExplode.java
Executable file
65
common/src/main/java/common/ai/EntityAIExplode.java
Executable file
|
@ -0,0 +1,65 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityHaunter;
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntityAIExplode extends EntityAIBase
|
||||
{
|
||||
EntityHaunter entity;
|
||||
EntityLiving target;
|
||||
|
||||
public EntityAIExplode(EntityHaunter entity)
|
||||
{
|
||||
this.entity = entity;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.entity.getAttackTarget();
|
||||
return this.entity.getExplodeState() > 0 || entitylivingbase != null && this.entity.getDistanceSqToEntity(entitylivingbase) < 9.0D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.entity.getNavigator().clearPathEntity();
|
||||
this.target = this.entity.getAttackTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.target = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.target == null)
|
||||
{
|
||||
this.entity.setExplodeState(-1);
|
||||
}
|
||||
else if (this.entity.getDistanceSqToEntity(this.target) > 49.0D)
|
||||
{
|
||||
this.entity.setExplodeState(-1);
|
||||
}
|
||||
else if (!this.entity.getEntitySenses().canSee(this.target))
|
||||
{
|
||||
this.entity.setExplodeState(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entity.setExplodeState(1);
|
||||
}
|
||||
}
|
||||
}
|
111
common/src/main/java/common/ai/EntityAIFindEntityNearest.java
Executable file
111
common/src/main/java/common/ai/EntityAIFindEntityNearest.java
Executable file
|
@ -0,0 +1,111 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.attributes.AttributeInstance;
|
||||
import common.attributes.Attributes;
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntityAIFindEntityNearest extends EntityAIBase
|
||||
{
|
||||
private EntityLiving mob;
|
||||
private final Predicate<EntityLiving> field_179443_c;
|
||||
private final EntityAINearestAttackableTarget.Sorter field_179440_d;
|
||||
private EntityLiving target;
|
||||
private Class <? extends EntityLiving > field_179439_f;
|
||||
|
||||
public EntityAIFindEntityNearest(EntityLiving mobIn, Class <? extends EntityLiving > p_i45884_2_)
|
||||
{
|
||||
this.mob = mobIn;
|
||||
this.field_179439_f = p_i45884_2_;
|
||||
|
||||
// if (mobIn instanceof EntityCreature)
|
||||
// {
|
||||
// Log.CONFIG.warn("Nutze NearestAttackableTargetGoal.class für PathfinderMob-Mobs!");
|
||||
// }
|
||||
|
||||
this.field_179443_c = new Predicate<EntityLiving>()
|
||||
{
|
||||
public boolean test(EntityLiving p_apply_1_)
|
||||
{
|
||||
double d0 = EntityAIFindEntityNearest.this.getFollowRange();
|
||||
|
||||
if (p_apply_1_.isSneaking())
|
||||
{
|
||||
d0 *= 0.800000011920929D;
|
||||
}
|
||||
|
||||
return (double)p_apply_1_.getDistanceToEntity(EntityAIFindEntityNearest.this.mob) > d0 ? false : EntityAITarget.isSuitableTarget(EntityAIFindEntityNearest.this.mob, p_apply_1_, true);
|
||||
}
|
||||
};
|
||||
this.field_179440_d = new EntityAINearestAttackableTarget.Sorter(mobIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
double d0 = this.getFollowRange();
|
||||
List<EntityLiving> list = this.mob.worldObj.<EntityLiving>getEntitiesWithinAABB(this.field_179439_f, this.mob.getEntityBoundingBox().expand(d0, 4.0D, d0), this.field_179443_c);
|
||||
Collections.sort(list, this.field_179440_d);
|
||||
|
||||
if (list.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.target = (EntityLiving)list.get(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.mob.getAttackTarget();
|
||||
|
||||
if (entitylivingbase == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!entitylivingbase.isEntityAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
double d0 = this.getFollowRange();
|
||||
return this.mob.getDistanceSqToEntity(entitylivingbase) <= d0 * d0; // ? false : !(entitylivingbase.isPlayer()) || !((EntityNPCMP)entitylivingbase).creative;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.mob.setAttackTarget(this.target);
|
||||
super.startExecuting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.mob.setAttackTarget((EntityLiving)null);
|
||||
super.startExecuting();
|
||||
}
|
||||
|
||||
protected double getFollowRange()
|
||||
{
|
||||
AttributeInstance iattributeinstance = this.mob.getEntityAttribute(Attributes.FOLLOW_RANGE);
|
||||
return iattributeinstance == null ? 16.0D : iattributeinstance.getAttributeValue();
|
||||
}
|
||||
}
|
95
common/src/main/java/common/ai/EntityAIFleeSun.java
Executable file
95
common/src/main/java/common/ai/EntityAIFleeSun.java
Executable file
|
@ -0,0 +1,95 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Vec3;
|
||||
import common.world.World;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class EntityAIFleeSun extends EntityAIBase
|
||||
{
|
||||
private EntityLiving theCreature;
|
||||
private double shelterX;
|
||||
private double shelterY;
|
||||
private double shelterZ;
|
||||
private double movementSpeed;
|
||||
private World theWorld;
|
||||
|
||||
public EntityAIFleeSun(EntityLiving theCreatureIn, double movementSpeedIn)
|
||||
{
|
||||
this.theCreature = theCreatureIn;
|
||||
this.movementSpeed = movementSpeedIn;
|
||||
this.theWorld = theCreatureIn.worldObj;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!((AWorldServer)this.theWorld).isDaytime())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.theCreature.isBurning())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.theWorld.canSeeSky(new BlockPos(this.theCreature.posX, this.theCreature.getEntityBoundingBox().minY, this.theCreature.posZ)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 vec3 = this.findPossibleShelter();
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.shelterX = vec3.xCoord;
|
||||
this.shelterY = vec3.yCoord;
|
||||
this.shelterZ = vec3.zCoord;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.theCreature.getNavigator().noPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theCreature.getNavigator().tryMoveToXYZ(this.shelterX, this.shelterY, this.shelterZ, this.movementSpeed);
|
||||
}
|
||||
|
||||
private Vec3 findPossibleShelter()
|
||||
{
|
||||
Random random = this.theCreature.getRNG();
|
||||
BlockPos blockpos = new BlockPos(this.theCreature.posX, this.theCreature.getEntityBoundingBox().minY, this.theCreature.posZ);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
BlockPos blockpos1 = blockpos.add(random.zrange(20) - 10, random.zrange(6) - 3, random.zrange(20) - 10);
|
||||
|
||||
if (!this.theWorld.canSeeSky(blockpos1) && this.theCreature.getBlockPathWeight(blockpos1) < 0.0F)
|
||||
{
|
||||
return new Vec3((double)blockpos1.getX(), (double)blockpos1.getY(), (double)blockpos1.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
115
common/src/main/java/common/ai/EntityAIFollowOwner.java
Executable file
115
common/src/main/java/common/ai/EntityAIFollowOwner.java
Executable file
|
@ -0,0 +1,115 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.entity.types.EntityTameable;
|
||||
import common.pathfinding.PathNavigate;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIFollowOwner extends EntityAIBase
|
||||
{
|
||||
private EntityTameable thePet;
|
||||
private EntityLiving theOwner;
|
||||
World theWorld;
|
||||
private double followSpeed;
|
||||
private PathNavigate petPathfinder;
|
||||
private int field_75343_h;
|
||||
float maxDist;
|
||||
float minDist;
|
||||
private boolean field_75344_i;
|
||||
|
||||
public EntityAIFollowOwner(EntityTameable thePetIn, double followSpeedIn, float minDistIn, float maxDistIn)
|
||||
{
|
||||
this.thePet = thePetIn;
|
||||
this.theWorld = thePetIn.worldObj;
|
||||
this.followSpeed = followSpeedIn;
|
||||
this.petPathfinder = thePetIn.getNavigator();
|
||||
this.minDist = minDistIn;
|
||||
this.maxDist = maxDistIn;
|
||||
this.setMutexBits(3);
|
||||
|
||||
if (!(thePetIn.getNavigator() instanceof PathNavigateGround))
|
||||
{
|
||||
throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.thePet.getOwner();
|
||||
|
||||
if (entitylivingbase == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// else if (entitylivingbase.isPlayer() && ((EntityNPC)entitylivingbase).isSpectator())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
else if (this.thePet.isSitting())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.thePet.getDistanceSqToEntity(entitylivingbase) < (double)(this.minDist * this.minDist))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.theOwner = entitylivingbase;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.petPathfinder.noPath() && this.thePet.getDistanceSqToEntity(this.theOwner) > (double)(this.maxDist * this.maxDist) && !this.thePet.isSitting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.field_75343_h = 0;
|
||||
this.field_75344_i = ((PathNavigateGround)this.thePet.getNavigator()).getAvoidsWater();
|
||||
((PathNavigateGround)this.thePet.getNavigator()).setAvoidsWater(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.theOwner = null;
|
||||
this.petPathfinder.clearPathEntity();
|
||||
((PathNavigateGround)this.thePet.getNavigator()).setAvoidsWater(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.thePet.getLookHelper().setLookPositionWithEntity(this.theOwner, 10.0F, (float)this.thePet.getVerticalFaceSpeed());
|
||||
|
||||
if (!this.thePet.isSitting())
|
||||
{
|
||||
if (--this.field_75343_h <= 0)
|
||||
{
|
||||
this.field_75343_h = 10;
|
||||
|
||||
if (!this.petPathfinder.tryMoveToEntityLiving(this.theOwner, this.followSpeed))
|
||||
{
|
||||
this.petPathfinder.clearPathEntity();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
112
common/src/main/java/common/ai/EntityAIFollowParent.java
Executable file
112
common/src/main/java/common/ai/EntityAIFollowParent.java
Executable file
|
@ -0,0 +1,112 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.types.EntityAnimal;
|
||||
|
||||
public class EntityAIFollowParent extends EntityAIBase
|
||||
{
|
||||
private EntityAnimal childAnimal;
|
||||
private EntityAnimal parentAnimal;
|
||||
private double speed;
|
||||
private int delay;
|
||||
|
||||
public EntityAIFollowParent(EntityAnimal animal, double speed)
|
||||
{
|
||||
this.childAnimal = animal;
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.childAnimal.isChild())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<EntityAnimal> list = this.childAnimal.worldObj.<EntityAnimal>getEntitiesWithinAABB(this.childAnimal.getClass(), this.childAnimal.getEntityBoundingBox().expand(8.0D, 4.0D, 8.0D));
|
||||
EntityAnimal entityanimal = null;
|
||||
double d0 = Double.MAX_VALUE;
|
||||
|
||||
for (EntityAnimal entityanimal1 : list)
|
||||
{
|
||||
if (!entityanimal1.isChild())
|
||||
{
|
||||
double d1 = this.childAnimal.getDistanceSqToEntity(entityanimal1);
|
||||
|
||||
if (d1 <= d0)
|
||||
{
|
||||
d0 = d1;
|
||||
entityanimal = entityanimal1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entityanimal == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (d0 < 9.0D)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.parentAnimal = entityanimal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
if (!this.childAnimal.isChild())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.parentAnimal.isEntityAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
double d0 = this.childAnimal.getDistanceSqToEntity(this.parentAnimal);
|
||||
return d0 >= 9.0D && d0 <= 256.0D;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.delay = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.parentAnimal = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
if (--this.delay <= 0)
|
||||
{
|
||||
this.delay = 10;
|
||||
this.childAnimal.getNavigator().tryMoveToEntityLiving(this.parentAnimal, this.speed);
|
||||
}
|
||||
}
|
||||
}
|
159
common/src/main/java/common/ai/EntityAIHarvestFarmland.java
Executable file
159
common/src/main/java/common/ai/EntityAIHarvestFarmland.java
Executable file
|
@ -0,0 +1,159 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.BlockPos;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIHarvestFarmland extends EntityAIMoveToBlock
|
||||
{
|
||||
// /** Villager that is harvesting */
|
||||
// private final EntityVillager theVillager;
|
||||
// private boolean hasFarmItem;
|
||||
// private boolean field_179503_e;
|
||||
// private int field_179501_f;
|
||||
//
|
||||
public EntityAIHarvestFarmland(EntityLiving entity, double speedIn)
|
||||
{
|
||||
super(entity, speedIn, 16);
|
||||
// this.theVillager = theVillagerIn;
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * Returns whether the EntityAIBase should begin execution.
|
||||
// */
|
||||
// public boolean shouldExecute()
|
||||
// {
|
||||
// if (this.runDelay <= 0)
|
||||
// {
|
||||
// if (!Config.mobGriefing || this.theVillager.isChild())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// this.field_179501_f = -1;
|
||||
// this.hasFarmItem = this.theVillager.hasFarmItem();
|
||||
// this.field_179503_e = this.theVillager.needsMoreItems();
|
||||
// }
|
||||
//
|
||||
// return super.shouldExecute();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns whether an in-progress EntityAIBase should continue executing
|
||||
// */
|
||||
// public boolean continueExecuting()
|
||||
// {
|
||||
// return this.field_179501_f >= 0 && super.continueExecuting();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Execute a one shot task or start executing a continuous task
|
||||
// */
|
||||
// public void startExecuting()
|
||||
// {
|
||||
// super.startExecuting();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Resets the task
|
||||
// */
|
||||
// public void resetTask()
|
||||
// {
|
||||
// super.resetTask();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Updates the task
|
||||
// */
|
||||
// public void updateTask()
|
||||
// {
|
||||
// super.updateTask();
|
||||
// this.theVillager.getLookHelper().setLookPosition((double)this.destinationBlock.getX() + 0.5D, (double)(this.destinationBlock.getY() + 1), (double)this.destinationBlock.getZ() + 0.5D, 10.0F, (float)this.theVillager.getVerticalFaceSpeed());
|
||||
//
|
||||
// if (this.getIsAboveDestination())
|
||||
// {
|
||||
// World world = this.theVillager.worldObj;
|
||||
// BlockPos blockpos = this.destinationBlock.up();
|
||||
// IBlockState iblockstate = world.getBlockState(blockpos);
|
||||
// Block block = iblockstate.getBlock();
|
||||
//
|
||||
// if (this.field_179501_f == 0 && block instanceof BlockCrops && ((Integer)iblockstate.getValue(BlockCrops.AGE)).intValue() == 7)
|
||||
// {
|
||||
// world.destroyBlock(blockpos, true);
|
||||
// }
|
||||
// else if (this.field_179501_f == 1 && block == Blocks.air)
|
||||
// {
|
||||
// InventoryBasic inventorybasic = this.theVillager.getFarmInventory();
|
||||
//
|
||||
// for (int i = 0; i < inventorybasic.getSizeInventory(); ++i)
|
||||
// {
|
||||
// ItemStack itemstack = inventorybasic.getStackInSlot(i);
|
||||
// boolean flag = false;
|
||||
//
|
||||
// if (itemstack != null)
|
||||
// {
|
||||
// if (itemstack.getItem() == Items.wheat_seeds)
|
||||
// {
|
||||
// world.setBlockState(blockpos, Blocks.wheat.getDefaultState(), 3);
|
||||
// flag = true;
|
||||
// }
|
||||
// else if (itemstack.getItem() == Items.potato)
|
||||
// {
|
||||
// world.setBlockState(blockpos, Blocks.potatoes.getDefaultState(), 3);
|
||||
// flag = true;
|
||||
// }
|
||||
// else if (itemstack.getItem() == Items.carrot)
|
||||
// {
|
||||
// world.setBlockState(blockpos, Blocks.carrots.getDefaultState(), 3);
|
||||
// flag = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (flag)
|
||||
// {
|
||||
// --itemstack.stackSize;
|
||||
//
|
||||
// if (itemstack.stackSize <= 0)
|
||||
// {
|
||||
// inventorybasic.setInventorySlotContents(i, (ItemStack)null);
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// this.field_179501_f = -1;
|
||||
// this.runDelay = 10;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Return true to set given position as destination
|
||||
// */
|
||||
protected boolean shouldMoveTo(World worldIn, BlockPos pos)
|
||||
{
|
||||
// Block block = worldIn.getBlockState(pos).getBlock();
|
||||
//
|
||||
// if (block == Blocks.farmland)
|
||||
// {
|
||||
// pos = pos.up();
|
||||
// IBlockState iblockstate = worldIn.getBlockState(pos);
|
||||
// block = iblockstate.getBlock();
|
||||
//
|
||||
// if (block instanceof BlockCrops && ((Integer)iblockstate.getValue(BlockCrops.AGE)).intValue() == 7 && this.field_179503_e && (this.field_179501_f == 0 || this.field_179501_f < 0))
|
||||
// {
|
||||
// this.field_179501_f = 0;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// if (block == Blocks.air && this.hasFarmItem && (this.field_179501_f == 1 || this.field_179501_f < 0))
|
||||
// {
|
||||
// this.field_179501_f = 1;
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
73
common/src/main/java/common/ai/EntityAIHurtByTarget.java
Executable file
73
common/src/main/java/common/ai/EntityAIHurtByTarget.java
Executable file
|
@ -0,0 +1,73 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.BoundingBox;
|
||||
|
||||
public class EntityAIHurtByTarget extends EntityAITarget
|
||||
{
|
||||
private boolean entityCallsForHelp;
|
||||
|
||||
/** Store the previous revengeTimer value */
|
||||
private int revengeTimerOld;
|
||||
private final Class[] targetClasses;
|
||||
|
||||
public EntityAIHurtByTarget(EntityLiving creatureIn, boolean entityCallsForHelpIn, Class... targetClassesIn)
|
||||
{
|
||||
super(creatureIn, false);
|
||||
this.entityCallsForHelp = entityCallsForHelpIn;
|
||||
this.targetClasses = targetClassesIn;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
int i = this.taskOwner.getAttackedTime();
|
||||
return i != this.revengeTimerOld && this.isSuitableTarget(this.taskOwner.getAttackedBy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.taskOwner.setAttackTarget(this.taskOwner.getAttackedBy());
|
||||
this.revengeTimerOld = this.taskOwner.getAttackedTime();
|
||||
|
||||
if (this.entityCallsForHelp)
|
||||
{
|
||||
double d0 = this.getTargetDistance();
|
||||
|
||||
for (EntityLiving entitycreature : this.taskOwner.worldObj.getEntitiesWithinAABB(this.taskOwner.getClass(), (new BoundingBox(this.taskOwner.posX, this.taskOwner.posY, this.taskOwner.posZ, this.taskOwner.posX + 1.0D, this.taskOwner.posY + 1.0D, this.taskOwner.posZ + 1.0D)).expand(d0, 10.0D, d0)))
|
||||
{
|
||||
if (this.taskOwner != entitycreature && /* !(entitycreature.isPlayer()) && */ entitycreature.getAttackTarget() == null) // && !entitycreature.isOnSameTeam(this.taskOwner.getAITarget()))
|
||||
{
|
||||
boolean flag = false;
|
||||
|
||||
for (Class oclass : this.targetClasses)
|
||||
{
|
||||
if (entitycreature.getClass() == oclass)
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
this.setEntityAttackTarget(entitycreature, this.taskOwner.getAttackedBy());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.startExecuting();
|
||||
}
|
||||
|
||||
protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn)
|
||||
{
|
||||
creatureIn.setAttackTarget(entityLivingBaseIn);
|
||||
}
|
||||
}
|
62
common/src/main/java/common/ai/EntityAILeapAtTarget.java
Executable file
62
common/src/main/java/common/ai/EntityAILeapAtTarget.java
Executable file
|
@ -0,0 +1,62 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public class EntityAILeapAtTarget extends EntityAIBase
|
||||
{
|
||||
/** The entity that is leaping. */
|
||||
EntityLiving leaper;
|
||||
|
||||
/** The entity that the leaper is leaping towards. */
|
||||
EntityLiving leapTarget;
|
||||
|
||||
/** The entity's motionY after leaping. */
|
||||
float leapMotionY;
|
||||
|
||||
public EntityAILeapAtTarget(EntityLiving leapingEntity, float leapMotionYIn)
|
||||
{
|
||||
this.leaper = leapingEntity;
|
||||
this.leapMotionY = leapMotionYIn;
|
||||
this.setMutexBits(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
this.leapTarget = this.leaper.getAttackTarget();
|
||||
|
||||
if (this.leapTarget == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
double d0 = this.leaper.getDistanceSqToEntity(this.leapTarget);
|
||||
return d0 >= 4.0D && d0 <= 16.0D ? (!this.leaper.onGround ? false : this.leaper.getRNG().zrange(5) == 0) : false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.leaper.onGround;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
double d0 = this.leapTarget.posX - this.leaper.posX;
|
||||
double d1 = this.leapTarget.posZ - this.leaper.posZ;
|
||||
float f = ExtMath.sqrtd(d0 * d0 + d1 * d1);
|
||||
this.leaper.motionX += d0 / (double)f * 0.5D * 0.800000011920929D + this.leaper.motionX * 0.20000000298023224D;
|
||||
this.leaper.motionZ += d1 / (double)f * 0.5D * 0.800000011920929D + this.leaper.motionZ * 0.20000000298023224D;
|
||||
this.leaper.motionY = (double)this.leapMotionY;
|
||||
}
|
||||
}
|
27
common/src/main/java/common/ai/EntityAILookAtTalkingPlayer.java
Executable file
27
common/src/main/java/common/ai/EntityAILookAtTalkingPlayer.java
Executable file
|
@ -0,0 +1,27 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
|
||||
public class EntityAILookAtTalkingPlayer extends EntityAIWatchClosest
|
||||
{
|
||||
private final EntityNPC npc;
|
||||
|
||||
public EntityAILookAtTalkingPlayer(EntityNPC npc)
|
||||
{
|
||||
super(npc, null, 8.0F);
|
||||
this.npc = npc;
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.npc.isTalking() && this.npc.getAttackTarget() == null)
|
||||
{
|
||||
this.closestEntity = this.npc.getTalking();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
62
common/src/main/java/common/ai/EntityAILookIdle.java
Executable file
62
common/src/main/java/common/ai/EntityAILookIdle.java
Executable file
|
@ -0,0 +1,62 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntityAILookIdle extends EntityAIBase
|
||||
{
|
||||
/** The entity that is looking idle. */
|
||||
private EntityLiving idleEntity;
|
||||
|
||||
/** X offset to look at */
|
||||
private double lookX;
|
||||
|
||||
/** Z offset to look at */
|
||||
private double lookZ;
|
||||
|
||||
/**
|
||||
* A decrementing tick that stops the entity from being idle once it reaches 0.
|
||||
*/
|
||||
private int idleTime;
|
||||
|
||||
public EntityAILookIdle(EntityLiving entitylivingIn)
|
||||
{
|
||||
this.idleEntity = entitylivingIn;
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.idleEntity.getRNG().floatv() < 0.02F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.idleTime >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
double d0 = (Math.PI * 2D) * this.idleEntity.getRNG().doublev();
|
||||
this.lookX = Math.cos(d0);
|
||||
this.lookZ = Math.sin(d0);
|
||||
this.idleTime = 20 + this.idleEntity.getRNG().zrange(20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
--this.idleTime;
|
||||
this.idleEntity.getLookHelper().setLookPosition(this.idleEntity.posX + this.lookX, this.idleEntity.posY + (double)this.idleEntity.getEyeHeight(), this.idleEntity.posZ + this.lookZ, 10.0F, (float)this.idleEntity.getVerticalFaceSpeed());
|
||||
}
|
||||
}
|
167
common/src/main/java/common/ai/EntityAIMate.java
Executable file
167
common/src/main/java/common/ai/EntityAIMate.java
Executable file
|
@ -0,0 +1,167 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.item.EntityXp;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityAnimal;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Config;
|
||||
import common.model.ParticleType;
|
||||
import common.rng.Random;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIMate extends EntityAIBase
|
||||
{
|
||||
private EntityAnimal theAnimal;
|
||||
World theWorld;
|
||||
private EntityAnimal targetMate;
|
||||
|
||||
/**
|
||||
* Delay preventing a baby from spawning immediately when two mate-able animals find each other.
|
||||
*/
|
||||
int spawnBabyDelay;
|
||||
|
||||
/** The speed the creature moves at during mating behavior. */
|
||||
double moveSpeed;
|
||||
|
||||
public EntityAIMate(EntityAnimal animal, double speedIn)
|
||||
{
|
||||
this.theAnimal = animal;
|
||||
this.theWorld = animal.worldObj;
|
||||
this.moveSpeed = speedIn;
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.theAnimal.isInLove())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.targetMate = this.getNearbyMate();
|
||||
return this.targetMate != null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.targetMate.isEntityAlive() && this.targetMate.isInLove() && this.spawnBabyDelay < 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.targetMate = null;
|
||||
this.spawnBabyDelay = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.theAnimal.getLookHelper().setLookPositionWithEntity(this.targetMate, 10.0F, (float)this.theAnimal.getVerticalFaceSpeed());
|
||||
this.theAnimal.getNavigator().tryMoveToEntityLiving(this.targetMate, this.moveSpeed);
|
||||
++this.spawnBabyDelay;
|
||||
|
||||
if (this.spawnBabyDelay >= 60 && this.theAnimal.getDistanceSqToEntity(this.targetMate) < 9.0D)
|
||||
{
|
||||
this.spawnBaby();
|
||||
}
|
||||
}
|
||||
|
||||
protected int getGrowingAge() {
|
||||
return 24000;
|
||||
}
|
||||
|
||||
protected int getMatingCooldown() {
|
||||
return 6000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through nearby animals and finds another animal of the same type that can be mated with. Returns the first
|
||||
* valid mate found.
|
||||
*/
|
||||
private EntityAnimal getNearbyMate()
|
||||
{
|
||||
float f = 8.0F;
|
||||
List<EntityAnimal> list = this.theWorld.<EntityAnimal>getEntitiesWithinAABB(this.theAnimal.getClass(), this.theAnimal.getEntityBoundingBox().expand((double)f, (double)f, (double)f));
|
||||
double d0 = Double.MAX_VALUE;
|
||||
EntityAnimal entityanimal = null;
|
||||
|
||||
for (EntityAnimal entityanimal1 : list)
|
||||
{
|
||||
if (this.theAnimal.canMateWith(entityanimal1) && this.theAnimal.getDistanceSqToEntity(entityanimal1) < d0)
|
||||
{
|
||||
entityanimal = entityanimal1;
|
||||
d0 = this.theAnimal.getDistanceSqToEntity(entityanimal1);
|
||||
}
|
||||
}
|
||||
|
||||
return entityanimal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns a baby animal of the same type.
|
||||
*/
|
||||
private void spawnBaby()
|
||||
{
|
||||
EntityLiving entityageable = this.theAnimal.createChild(this.targetMate);
|
||||
|
||||
if (entityageable != null)
|
||||
{
|
||||
EntityNPC entityplayer = this.theAnimal.getPlayerInLove();
|
||||
|
||||
if (entityplayer == null && this.targetMate.getPlayerInLove() != null)
|
||||
{
|
||||
entityplayer = this.targetMate.getPlayerInLove();
|
||||
}
|
||||
|
||||
// if (entityplayer != null)
|
||||
// {
|
||||
// entityplayer.triggerAchievement(StatRegistry.animalsBredStat);
|
||||
//
|
||||
//// if (this.theAnimal instanceof EntityCow)
|
||||
//// {
|
||||
//// entityplayer.triggerAchievement(AchievementList.breedCow);
|
||||
//// }
|
||||
// }
|
||||
|
||||
this.theAnimal.setGrowingAge(this.getMatingCooldown());
|
||||
this.targetMate.setGrowingAge(this.getMatingCooldown());
|
||||
this.theAnimal.resetInLove();
|
||||
this.targetMate.resetInLove();
|
||||
entityageable.setGrowingAge(-this.getGrowingAge());
|
||||
entityageable.setLocationAndAngles(this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, 0.0F, 0.0F);
|
||||
this.theWorld.spawnEntityInWorld(entityageable);
|
||||
Random random = this.theAnimal.getRNG();
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
double d0 = random.gaussian() * 0.02D;
|
||||
double d1 = random.gaussian() * 0.02D;
|
||||
double d2 = random.gaussian() * 0.02D;
|
||||
double d3 = random.doublev() * (double)this.theAnimal.width * 2.0D - (double)this.theAnimal.width;
|
||||
double d4 = 0.5D + random.doublev() * (double)this.theAnimal.height;
|
||||
double d5 = random.doublev() * (double)this.theAnimal.width * 2.0D - (double)this.theAnimal.width;
|
||||
this.theWorld.spawnParticle(ParticleType.HEART, this.theAnimal.posX + d3, this.theAnimal.posY + d4, this.theAnimal.posZ + d5, d0, d1, d2);
|
||||
}
|
||||
|
||||
if (entityplayer != null && Config.breedingXP) // FIX xp
|
||||
{
|
||||
this.theWorld.spawnEntityInWorld(new EntityXp(this.theWorld, this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, random.zrange(7) + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
104
common/src/main/java/common/ai/EntityAIMoveIndoors.java
Executable file
104
common/src/main/java/common/ai/EntityAIMoveIndoors.java
Executable file
|
@ -0,0 +1,104 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Vec3;
|
||||
import common.village.Village;
|
||||
import common.village.VillageDoorInfo;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class EntityAIMoveIndoors extends EntityAIBase
|
||||
{
|
||||
private EntityLiving entityObj;
|
||||
private VillageDoorInfo doorInfo;
|
||||
private int insidePosX = -1;
|
||||
private int insidePosZ = -1;
|
||||
|
||||
public EntityAIMoveIndoors(EntityLiving entityObjIn)
|
||||
{
|
||||
this.entityObj = entityObjIn;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this.entityObj);
|
||||
|
||||
if ((!((AWorldServer)this.entityObj.worldObj).isDaytime() /* || this.entityObj.worldObj.isRaining() && !this.entityObj.worldObj.getBiomeGenForCoords(blockpos).canRain() */) && !this.entityObj.worldObj.dimension.hasNoLight())
|
||||
{
|
||||
if (this.entityObj.getRNG().zrange(50) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.insidePosX != -1 && this.entityObj.getDistanceSq((double)this.insidePosX, this.entityObj.posY, (double)this.insidePosZ) < 4.0D)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Village village = ((AWorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 14);
|
||||
|
||||
if (village == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.doorInfo = village.getDoorInfo(blockpos);
|
||||
return this.doorInfo != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.entityObj.getNavigator().noPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.insidePosX = -1;
|
||||
BlockPos blockpos = this.doorInfo.getInsideBlockPos();
|
||||
int i = blockpos.getX();
|
||||
int j = blockpos.getY();
|
||||
int k = blockpos.getZ();
|
||||
|
||||
if (this.entityObj.getDistanceSq(blockpos) > 256.0D)
|
||||
{
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.entityObj, 14, 3, new Vec3((double)i + 0.5D, (double)j, (double)k + 0.5D));
|
||||
|
||||
if (vec3 != null)
|
||||
{
|
||||
this.entityObj.getNavigator().tryMoveToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord, 1.0D);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entityObj.getNavigator().tryMoveToXYZ((double)i + 0.5D, (double)j, (double)k + 0.5D, 1.0D);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.insidePosX = this.doorInfo.getInsideBlockPos().getX();
|
||||
this.insidePosZ = this.doorInfo.getInsideBlockPos().getZ();
|
||||
this.doorInfo = null;
|
||||
}
|
||||
}
|
174
common/src/main/java/common/ai/EntityAIMoveThroughVillage.java
Executable file
174
common/src/main/java/common/ai/EntityAIMoveThroughVillage.java
Executable file
|
@ -0,0 +1,174 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathEntity;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.util.BlockPos;
|
||||
import common.util.ExtMath;
|
||||
import common.util.Vec3;
|
||||
import common.village.Village;
|
||||
import common.village.VillageDoorInfo;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class EntityAIMoveThroughVillage extends EntityAIBase
|
||||
{
|
||||
private EntityLiving theEntity;
|
||||
private double movementSpeed;
|
||||
|
||||
/** The PathNavigate of our entity. */
|
||||
private PathEntity entityPathNavigate;
|
||||
private VillageDoorInfo doorInfo;
|
||||
private boolean isNocturnal;
|
||||
private List<VillageDoorInfo> doorList = Lists.<VillageDoorInfo>newArrayList();
|
||||
|
||||
public EntityAIMoveThroughVillage(EntityLiving theEntityIn, double movementSpeedIn, boolean isNocturnalIn)
|
||||
{
|
||||
this.theEntity = theEntityIn;
|
||||
this.movementSpeed = movementSpeedIn;
|
||||
this.isNocturnal = isNocturnalIn;
|
||||
this.setMutexBits(1);
|
||||
|
||||
if (!(theEntityIn.getNavigator() instanceof PathNavigateGround))
|
||||
{
|
||||
throw new IllegalArgumentException("Unsupported mob for MoveThroughVillageGoal");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
this.resizeDoorList();
|
||||
|
||||
if (this.isNocturnal && ((AWorldServer)this.theEntity.worldObj).isDaytime())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Village village = ((AWorldServer)this.theEntity.worldObj).getNearestVillage(new BlockPos(this.theEntity), 0);
|
||||
|
||||
if (village == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.doorInfo = this.findNearestDoor(village);
|
||||
|
||||
if (this.doorInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
PathNavigateGround pathnavigateground = (PathNavigateGround)this.theEntity.getNavigator();
|
||||
boolean flag = pathnavigateground.getEnterDoors();
|
||||
pathnavigateground.setBreakDoors(false);
|
||||
this.entityPathNavigate = pathnavigateground.getPathToPos(this.doorInfo.getDoorBlockPos());
|
||||
pathnavigateground.setBreakDoors(flag);
|
||||
|
||||
if (this.entityPathNavigate != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 10, 7, new Vec3((double)this.doorInfo.getDoorBlockPos().getX(), (double)this.doorInfo.getDoorBlockPos().getY(), (double)this.doorInfo.getDoorBlockPos().getZ()));
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pathnavigateground.setBreakDoors(false);
|
||||
this.entityPathNavigate = this.theEntity.getNavigator().getPathToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord);
|
||||
pathnavigateground.setBreakDoors(flag);
|
||||
return this.entityPathNavigate != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
if (this.theEntity.getNavigator().noPath())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
float f = this.theEntity.width + 4.0F;
|
||||
return this.theEntity.getDistanceSq(this.doorInfo.getDoorBlockPos()) > (double)(f * f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theEntity.getNavigator().setPath(this.entityPathNavigate, this.movementSpeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
if (this.theEntity.getNavigator().noPath() || this.theEntity.getDistanceSq(this.doorInfo.getDoorBlockPos()) < 16.0D)
|
||||
{
|
||||
this.doorList.add(this.doorInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private VillageDoorInfo findNearestDoor(Village villageIn)
|
||||
{
|
||||
VillageDoorInfo villagedoorinfo = null;
|
||||
int i = Integer.MAX_VALUE;
|
||||
|
||||
for (VillageDoorInfo villagedoorinfo1 : villageIn.getDoorList())
|
||||
{
|
||||
int j = villagedoorinfo1.getDistanceSquared(ExtMath.floord(this.theEntity.posX), ExtMath.floord(this.theEntity.posY), ExtMath.floord(this.theEntity.posZ));
|
||||
|
||||
if (j < i && !this.doesDoorListContain(villagedoorinfo1))
|
||||
{
|
||||
villagedoorinfo = villagedoorinfo1;
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
return villagedoorinfo;
|
||||
}
|
||||
|
||||
private boolean doesDoorListContain(VillageDoorInfo doorInfoIn)
|
||||
{
|
||||
for (VillageDoorInfo villagedoorinfo : this.doorList)
|
||||
{
|
||||
if (doorInfoIn.getDoorBlockPos().equals(villagedoorinfo.getDoorBlockPos()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void resizeDoorList()
|
||||
{
|
||||
if (this.doorList.size() > 15)
|
||||
{
|
||||
this.doorList.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
137
common/src/main/java/common/ai/EntityAIMoveToBlock.java
Executable file
137
common/src/main/java/common/ai/EntityAIMoveToBlock.java
Executable file
|
@ -0,0 +1,137 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.BlockPos;
|
||||
import common.world.World;
|
||||
|
||||
public abstract class EntityAIMoveToBlock extends EntityAIBase
|
||||
{
|
||||
private final EntityLiving theEntity;
|
||||
private final double movementSpeed;
|
||||
|
||||
/** Controls task execution delay */
|
||||
protected int runDelay;
|
||||
private int timeoutCounter;
|
||||
private int field_179490_f;
|
||||
|
||||
/** Block to move to */
|
||||
protected BlockPos destinationBlock = BlockPos.ORIGIN;
|
||||
private boolean isAboveDestination;
|
||||
private int searchLength;
|
||||
|
||||
public EntityAIMoveToBlock(EntityLiving creature, double speedIn, int length)
|
||||
{
|
||||
this.theEntity = creature;
|
||||
this.movementSpeed = speedIn;
|
||||
this.searchLength = length;
|
||||
this.setMutexBits(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.runDelay > 0)
|
||||
{
|
||||
--this.runDelay;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.runDelay = 200 + this.theEntity.getRNG().zrange(200);
|
||||
return this.searchForDestination();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.timeoutCounter >= -this.field_179490_f && this.timeoutCounter <= 1200 && this.shouldMoveTo(this.theEntity.worldObj, this.destinationBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theEntity.getNavigator().tryMoveToXYZ((double)((float)this.destinationBlock.getX()) + 0.5D, (double)(this.destinationBlock.getY() + 1), (double)((float)this.destinationBlock.getZ()) + 0.5D, this.movementSpeed);
|
||||
this.timeoutCounter = 0;
|
||||
this.field_179490_f = this.theEntity.getRNG().zrange(this.theEntity.getRNG().zrange(1200) + 1200) + 1200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.theEntity.getDistanceSqToCenter(this.destinationBlock.up()) > 1.0D)
|
||||
{
|
||||
this.isAboveDestination = false;
|
||||
++this.timeoutCounter;
|
||||
|
||||
if (this.timeoutCounter % 40 == 0)
|
||||
{
|
||||
this.theEntity.getNavigator().tryMoveToXYZ((double)((float)this.destinationBlock.getX()) + 0.5D, (double)(this.destinationBlock.getY() + 1), (double)((float)this.destinationBlock.getZ()) + 0.5D, this.movementSpeed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isAboveDestination = true;
|
||||
--this.timeoutCounter;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean getIsAboveDestination()
|
||||
{
|
||||
return this.isAboveDestination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches and sets new destination block and returns true if a suitable block (specified in {@link
|
||||
* game.ai.EntityAIMoveToBlock#shouldMoveTo(World, BlockPos) EntityAIMoveToBlock#shouldMoveTo(World,
|
||||
* BlockPos)}) can be found.
|
||||
*/
|
||||
protected boolean searchForDestination()
|
||||
{
|
||||
int i = this.searchLength;
|
||||
int j = 1;
|
||||
BlockPos blockpos = new BlockPos(this.theEntity);
|
||||
|
||||
for (int k = 0; k <= 1; k = k > 0 ? -k : 1 - k)
|
||||
{
|
||||
for (int l = 0; l < i; ++l)
|
||||
{
|
||||
for (int i1 = 0; i1 <= l; i1 = i1 > 0 ? -i1 : 1 - i1)
|
||||
{
|
||||
for (int j1 = i1 < l && i1 > -l ? l : 0; j1 <= l; j1 = j1 > 0 ? -j1 : 1 - j1)
|
||||
{
|
||||
BlockPos blockpos1 = blockpos.add(i1, k - 1, j1);
|
||||
|
||||
if (this.theEntity.isWithinHomeDistanceFromPosition(blockpos1) && this.shouldMoveTo(this.theEntity.worldObj, blockpos1))
|
||||
{
|
||||
this.destinationBlock = blockpos1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true to set given position as destination
|
||||
*/
|
||||
protected abstract boolean shouldMoveTo(World worldIn, BlockPos pos);
|
||||
}
|
65
common/src/main/java/common/ai/EntityAIMoveTowardsRestriction.java
Executable file
65
common/src/main/java/common/ai/EntityAIMoveTowardsRestriction.java
Executable file
|
@ -0,0 +1,65 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class EntityAIMoveTowardsRestriction extends EntityAIBase
|
||||
{
|
||||
private EntityLiving theEntity;
|
||||
private double movePosX;
|
||||
private double movePosY;
|
||||
private double movePosZ;
|
||||
private double movementSpeed;
|
||||
|
||||
public EntityAIMoveTowardsRestriction(EntityLiving creatureIn, double speedIn)
|
||||
{
|
||||
this.theEntity = creatureIn;
|
||||
this.movementSpeed = speedIn;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.theEntity.isWithinHomeDistanceCurrentPosition())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos = this.theEntity.getHomePosition();
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 16, 7, new Vec3((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ()));
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.movePosX = vec3.xCoord;
|
||||
this.movePosY = vec3.yCoord;
|
||||
this.movePosZ = vec3.zCoord;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.theEntity.getNavigator().noPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theEntity.getNavigator().tryMoveToXYZ(this.movePosX, this.movePosY, this.movePosZ, this.movementSpeed);
|
||||
}
|
||||
}
|
84
common/src/main/java/common/ai/EntityAIMoveTowardsTarget.java
Executable file
84
common/src/main/java/common/ai/EntityAIMoveTowardsTarget.java
Executable file
|
@ -0,0 +1,84 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class EntityAIMoveTowardsTarget extends EntityAIBase
|
||||
{
|
||||
private EntityLiving theEntity;
|
||||
private EntityLiving targetEntity;
|
||||
private double movePosX;
|
||||
private double movePosY;
|
||||
private double movePosZ;
|
||||
private double speed;
|
||||
|
||||
/**
|
||||
* If the distance to the target entity is further than this, this AI task will not run.
|
||||
*/
|
||||
private float maxTargetDistance;
|
||||
|
||||
public EntityAIMoveTowardsTarget(EntityLiving creature, double speedIn, float targetMaxDistance)
|
||||
{
|
||||
this.theEntity = creature;
|
||||
this.speed = speedIn;
|
||||
this.maxTargetDistance = targetMaxDistance;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
this.targetEntity = this.theEntity.getAttackTarget();
|
||||
|
||||
if (this.targetEntity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.targetEntity.getDistanceSqToEntity(this.theEntity) > (double)(this.maxTargetDistance * this.maxTargetDistance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 16, 7, new Vec3(this.targetEntity.posX, this.targetEntity.posY, this.targetEntity.posZ));
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.movePosX = vec3.xCoord;
|
||||
this.movePosY = vec3.yCoord;
|
||||
this.movePosZ = vec3.zCoord;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.theEntity.getNavigator().noPath() && this.targetEntity.isEntityAlive() && this.targetEntity.getDistanceSqToEntity(this.theEntity) < (double)(this.maxTargetDistance * this.maxTargetDistance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.targetEntity = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theEntity.getNavigator().tryMoveToXYZ(this.movePosX, this.movePosY, this.movePosZ, this.speed);
|
||||
}
|
||||
}
|
50
common/src/main/java/common/ai/EntityAINagPlayer.java
Executable file
50
common/src/main/java/common/ai/EntityAINagPlayer.java
Executable file
|
@ -0,0 +1,50 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.inventory.ContainerMerchant;
|
||||
|
||||
public class EntityAINagPlayer extends EntityAIBase
|
||||
{
|
||||
private EntityNPC npc;
|
||||
|
||||
public EntityAINagPlayer(EntityNPC npc)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.setMutexBits(5);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.npc.isEntityAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.npc.isInLiquid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.npc.onGround)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.npc.veloChanged)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntityNPC entityplayer = this.npc.getTalking();
|
||||
return entityplayer == null ? false : (this.npc.getDistanceSqToEntity(entityplayer) > 16.0D ? false : entityplayer.openContainer instanceof ContainerMerchant);
|
||||
}
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
this.npc.getNavigator().clearPathEntity();
|
||||
}
|
||||
|
||||
public void resetTask()
|
||||
{
|
||||
this.npc.setTalking(null);
|
||||
}
|
||||
}
|
133
common/src/main/java/common/ai/EntityAINearestAttackableTarget.java
Executable file
133
common/src/main/java/common/ai/EntityAINearestAttackableTarget.java
Executable file
|
@ -0,0 +1,133 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntityAINearestAttackableTarget<T extends EntityLiving> extends EntityAITarget
|
||||
{
|
||||
protected final Class<T> targetClass;
|
||||
private final int targetChance;
|
||||
|
||||
/** Instance of EntityAINearestAttackableTargetSorter. */
|
||||
protected final EntityAINearestAttackableTarget.Sorter theNearestAttackableTargetSorter;
|
||||
protected Predicate <? super T > targetEntitySelector;
|
||||
protected EntityLiving targetEntity;
|
||||
|
||||
public EntityAINearestAttackableTarget(EntityLiving creature, Class<T> classTarget, boolean checkSight)
|
||||
{
|
||||
this(creature, classTarget, checkSight, false);
|
||||
}
|
||||
|
||||
public EntityAINearestAttackableTarget(EntityLiving creature, Class<T> classTarget, boolean checkSight, boolean onlyNearby)
|
||||
{
|
||||
this(creature, classTarget, 10, checkSight, onlyNearby, (Predicate <? super T >)null);
|
||||
}
|
||||
|
||||
public EntityAINearestAttackableTarget(EntityLiving creature, Class<T> classTarget, int chance, boolean checkSight, boolean onlyNearby, final Predicate <? super T > targetSelector)
|
||||
{
|
||||
super(creature, checkSight, onlyNearby);
|
||||
this.targetClass = classTarget;
|
||||
this.targetChance = chance;
|
||||
this.theNearestAttackableTargetSorter = new EntityAINearestAttackableTarget.Sorter(creature);
|
||||
this.setMutexBits(1);
|
||||
this.targetEntitySelector = new Predicate<T>()
|
||||
{
|
||||
public boolean test(T p_apply_1_)
|
||||
{
|
||||
if (targetSelector != null && !targetSelector.test(p_apply_1_))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p_apply_1_.isPlayer())
|
||||
{
|
||||
double d0 = EntityAINearestAttackableTarget.this.getTargetDistance();
|
||||
|
||||
if (p_apply_1_.isSneaking())
|
||||
{
|
||||
d0 *= 0.800000011920929D;
|
||||
}
|
||||
|
||||
// if (p_apply_1_.isInvisible())
|
||||
// {
|
||||
// float f = ((EntityNPC)p_apply_1_).getArmorVisibility();
|
||||
//
|
||||
// if (f < 0.1F)
|
||||
// {
|
||||
// f = 0.1F;
|
||||
// }
|
||||
//
|
||||
// d0 *= (double)(0.7F * f);
|
||||
// }
|
||||
|
||||
if ((double)p_apply_1_.getDistanceToEntity(EntityAINearestAttackableTarget.this.taskOwner) > d0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return EntityAINearestAttackableTarget.this.isSuitableTarget(p_apply_1_);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.targetChance > 0 && this.taskOwner.getRNG().zrange(this.targetChance) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
double d0 = this.getTargetDistance();
|
||||
List<T> list = this.taskOwner.worldObj.<T>getEntitiesWithinAABB(this.targetClass, this.taskOwner.getEntityBoundingBox().expand(d0, 4.0D, d0), this.targetEntitySelector);
|
||||
Collections.sort(list, this.theNearestAttackableTargetSorter);
|
||||
|
||||
if (list.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.targetEntity = (EntityLiving)list.get(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.taskOwner.setAttackTarget(this.targetEntity);
|
||||
super.startExecuting();
|
||||
}
|
||||
|
||||
public static class Sorter implements Comparator<Entity>
|
||||
{
|
||||
private final Entity theEntity;
|
||||
|
||||
public Sorter(Entity theEntityIn)
|
||||
{
|
||||
this.theEntity = theEntityIn;
|
||||
}
|
||||
|
||||
public int compare(Entity p_compare_1_, Entity p_compare_2_)
|
||||
{
|
||||
double d0 = this.theEntity.getDistanceSqToEntity(p_compare_1_);
|
||||
double d1 = this.theEntity.getDistanceSqToEntity(p_compare_2_);
|
||||
return d0 < d1 ? -1 : (d0 > d1 ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
56
common/src/main/java/common/ai/EntityAINpcInteract.java
Executable file
56
common/src/main/java/common/ai/EntityAINpcInteract.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
|
||||
public class EntityAINpcInteract extends EntityAIWatchClosest2
|
||||
{
|
||||
private int interactionDelay;
|
||||
private EntityNPC npc;
|
||||
|
||||
public EntityAINpcInteract(EntityNPC npc)
|
||||
{
|
||||
super(npc, EntityNPC.class, 3.0F, 0.02F);
|
||||
this.npc = npc;
|
||||
}
|
||||
|
||||
// public boolean shouldExecute()
|
||||
// {
|
||||
// if(super.shouldExecute()) {
|
||||
// if(this.closestEntity.isPlayer()) {
|
||||
// this.closestEntity = null;
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
super.startExecuting();
|
||||
|
||||
if (this.closestEntity instanceof EntityNPC)
|
||||
{
|
||||
this.interactionDelay = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.interactionDelay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
super.updateTask();
|
||||
|
||||
if (this.interactionDelay > 0)
|
||||
{
|
||||
--this.interactionDelay;
|
||||
|
||||
if (this.interactionDelay == 0)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
108
common/src/main/java/common/ai/EntityAINpcMate.java
Executable file
108
common/src/main/java/common/ai/EntityAINpcMate.java
Executable file
|
@ -0,0 +1,108 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.world.World;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class EntityAINpcMate extends EntityAIBase
|
||||
{
|
||||
private EntityNPC npc;
|
||||
private EntityNPC mate;
|
||||
private World worldObj;
|
||||
private int matingTimeout;
|
||||
|
||||
public EntityAINpcMate(EntityNPC npc)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.worldObj = npc.worldObj;
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.npc.getGrowingAge() != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.npc.getRNG().zrange(100) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.npc.getIsWillingToMate(true))
|
||||
{
|
||||
Entity entity = ((AWorldServer)this.worldObj).findNearestEntityWithinAABB(EntityNPC.class, this.npc.getEntityBoundingBox().expand(8.0D, 3.0D, 8.0D), this.npc);
|
||||
|
||||
if (entity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.mate = (EntityNPC)entity;
|
||||
return this.mate.getGrowingAge() == 0 && this.mate.getIsWillingToMate(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startExecuting()
|
||||
{
|
||||
this.matingTimeout = 250;
|
||||
this.npc.setMating(true);
|
||||
}
|
||||
|
||||
public void resetTask()
|
||||
{
|
||||
this.mate = null;
|
||||
this.npc.setMating(false);
|
||||
}
|
||||
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.matingTimeout >= 0 && this.npc.getGrowingAge() == 0 && this.npc.getIsWillingToMate(false);
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
--this.matingTimeout;
|
||||
this.npc.getLookHelper().setLookPositionWithEntity(this.mate, 10.0F, 30.0F);
|
||||
|
||||
if (this.npc.getDistanceSqToEntity(this.mate) > 2.25D)
|
||||
{
|
||||
this.npc.getNavigator().tryMoveToEntityLiving(this.mate, 0.25D);
|
||||
}
|
||||
else if (this.matingTimeout >= 6)
|
||||
{
|
||||
this.matingTimeout -= 5;
|
||||
}
|
||||
else if (this.matingTimeout == 0 && this.mate.isMating())
|
||||
{
|
||||
this.giveBirth();
|
||||
}
|
||||
|
||||
// if (this.npc.getRNG().nextInt(35) == 0)
|
||||
// {
|
||||
// this.worldObj.setEntityState(this.npc, (byte)12);
|
||||
// }
|
||||
}
|
||||
|
||||
private void giveBirth()
|
||||
{
|
||||
EntityNPC entity = this.npc.createChild(this.mate);
|
||||
this.mate.setGrowingAge(100);
|
||||
this.npc.setGrowingAge(100);
|
||||
this.mate.setIsWillingToMate(false);
|
||||
this.npc.setIsWillingToMate(false);
|
||||
entity.setGrowingAge(-24000);
|
||||
entity.setLocationAndAngles(this.npc.posX, this.npc.posY, this.npc.posZ, 0.0F, 0.0F);
|
||||
this.worldObj.spawnEntityInWorld(entity);
|
||||
this.worldObj.setEntityState(entity, (byte)12);
|
||||
}
|
||||
}
|
86
common/src/main/java/common/ai/EntityAIOcelotAttack.java
Executable file
86
common/src/main/java/common/ai/EntityAIOcelotAttack.java
Executable file
|
@ -0,0 +1,86 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIOcelotAttack extends EntityAIBase
|
||||
{
|
||||
World theWorld;
|
||||
EntityLiving theEntity;
|
||||
EntityLiving theVictim;
|
||||
int attackCountdown;
|
||||
|
||||
public EntityAIOcelotAttack(EntityLiving theEntityIn)
|
||||
{
|
||||
this.theEntity = theEntityIn;
|
||||
this.theWorld = theEntityIn.worldObj;
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.theEntity.getAttackTarget();
|
||||
|
||||
if (entitylivingbase == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.theVictim = entitylivingbase;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.theVictim.isEntityAlive() ? false : (this.theEntity.getDistanceSqToEntity(this.theVictim) > 225.0D ? false : !this.theEntity.getNavigator().noPath() || this.shouldExecute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.theVictim = null;
|
||||
this.theEntity.getNavigator().clearPathEntity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.theEntity.getLookHelper().setLookPositionWithEntity(this.theVictim, 30.0F, 30.0F);
|
||||
double d0 = (double)(this.theEntity.width * 2.0F * this.theEntity.width * 2.0F);
|
||||
double d1 = this.theEntity.getDistanceSq(this.theVictim.posX, this.theVictim.getEntityBoundingBox().minY, this.theVictim.posZ);
|
||||
double d2 = 0.8D;
|
||||
|
||||
if (d1 > d0 && d1 < 16.0D)
|
||||
{
|
||||
d2 = 1.33D;
|
||||
}
|
||||
else if (d1 < 225.0D)
|
||||
{
|
||||
d2 = 0.6D;
|
||||
}
|
||||
|
||||
this.theEntity.getNavigator().tryMoveToEntityLiving(this.theVictim, d2);
|
||||
this.attackCountdown = Math.max(this.attackCountdown - 1, 0);
|
||||
|
||||
if (d1 <= d0)
|
||||
{
|
||||
if (this.attackCountdown <= 0)
|
||||
{
|
||||
this.attackCountdown = 20;
|
||||
this.theEntity.attackEntityAsMob(this.theVictim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
114
common/src/main/java/common/ai/EntityAIOcelotSit.java
Executable file
114
common/src/main/java/common/ai/EntityAIOcelotSit.java
Executable file
|
@ -0,0 +1,114 @@
|
|||
package common.ai;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.artificial.BlockBed;
|
||||
import common.entity.animal.EntityOcelot;
|
||||
import common.init.Blocks;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.tileentity.TileEntityChest;
|
||||
import common.util.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIOcelotSit extends EntityAIMoveToBlock
|
||||
{
|
||||
private final EntityOcelot ocelot;
|
||||
|
||||
public EntityAIOcelotSit(EntityOcelot ocelotIn, double p_i45315_2_)
|
||||
{
|
||||
super(ocelotIn, p_i45315_2_, 8);
|
||||
this.ocelot = ocelotIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.ocelot.isTamed() && !this.ocelot.isSitting() && super.shouldExecute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return super.continueExecuting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
super.startExecuting();
|
||||
this.ocelot.getAISit().setSitting(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
super.resetTask();
|
||||
this.ocelot.setSitting(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
super.updateTask();
|
||||
this.ocelot.getAISit().setSitting(false);
|
||||
|
||||
if (!this.getIsAboveDestination())
|
||||
{
|
||||
this.ocelot.setSitting(false);
|
||||
}
|
||||
else if (!this.ocelot.isSitting())
|
||||
{
|
||||
this.ocelot.setSitting(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true to set given position as destination
|
||||
*/
|
||||
protected boolean shouldMoveTo(World worldIn, BlockPos pos)
|
||||
{
|
||||
if (!worldIn.isAirBlock(pos.up()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
Block block = iblockstate.getBlock();
|
||||
|
||||
if (block == Blocks.chest)
|
||||
{
|
||||
TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
|
||||
if (tileentity instanceof TileEntityChest && ((TileEntityChest)tileentity).numPlayersUsing < 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (block == Blocks.lit_furnace)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (block instanceof BlockBed && iblockstate.getValue(BlockBed.PART) != BlockBed.EnumPartType.HEAD)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
58
common/src/main/java/common/ai/EntityAIOpenDoor.java
Executable file
58
common/src/main/java/common/ai/EntityAIOpenDoor.java
Executable file
|
@ -0,0 +1,58 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntityAIOpenDoor extends EntityAIDoorInteract
|
||||
{
|
||||
/** If the entity close the door */
|
||||
boolean closeDoor;
|
||||
|
||||
/**
|
||||
* The temporisation before the entity close the door (in ticks, always 20 = 1 second)
|
||||
*/
|
||||
int closeDoorTemporisation;
|
||||
|
||||
public EntityAIOpenDoor(EntityLiving entitylivingIn, boolean shouldClose)
|
||||
{
|
||||
super(entitylivingIn);
|
||||
this.theEntity = entitylivingIn;
|
||||
this.closeDoor = shouldClose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return this.closeDoor && this.closeDoorTemporisation > 0 && super.continueExecuting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.closeDoorTemporisation = 20;
|
||||
this.doorBlock.toggleDoor(this.theEntity.worldObj, this.doorPosition, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
if (this.closeDoor)
|
||||
{
|
||||
this.doorBlock.toggleDoor(this.theEntity.worldObj, this.doorPosition, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
--this.closeDoorTemporisation;
|
||||
super.updateTask();
|
||||
}
|
||||
}
|
60
common/src/main/java/common/ai/EntityAIOwnerHurtByTarget.java
Executable file
60
common/src/main/java/common/ai/EntityAIOwnerHurtByTarget.java
Executable file
|
@ -0,0 +1,60 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.entity.types.EntityTameable;
|
||||
|
||||
public class EntityAIOwnerHurtByTarget extends EntityAITarget
|
||||
{
|
||||
EntityTameable theDefendingTameable;
|
||||
EntityLiving theOwnerAttacker;
|
||||
private int field_142051_e;
|
||||
|
||||
public EntityAIOwnerHurtByTarget(EntityTameable theDefendingTameableIn)
|
||||
{
|
||||
super(theDefendingTameableIn, false);
|
||||
this.theDefendingTameable = theDefendingTameableIn;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.theDefendingTameable.isTamed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntityLiving entitylivingbase = this.theDefendingTameable.getOwner();
|
||||
|
||||
if (entitylivingbase == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.theOwnerAttacker = entitylivingbase.getAttackedBy();
|
||||
int i = entitylivingbase.getAttackedTime();
|
||||
return i != this.field_142051_e && this.isSuitableTarget(this.theOwnerAttacker) && this.theDefendingTameable.shouldAttackEntity(this.theOwnerAttacker, entitylivingbase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.taskOwner.setAttackTarget(this.theOwnerAttacker);
|
||||
EntityLiving entitylivingbase = this.theDefendingTameable.getOwner();
|
||||
|
||||
if (entitylivingbase != null)
|
||||
{
|
||||
this.field_142051_e = entitylivingbase.getAttackedTime();
|
||||
}
|
||||
|
||||
super.startExecuting();
|
||||
}
|
||||
}
|
60
common/src/main/java/common/ai/EntityAIOwnerHurtTarget.java
Executable file
60
common/src/main/java/common/ai/EntityAIOwnerHurtTarget.java
Executable file
|
@ -0,0 +1,60 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.entity.types.EntityTameable;
|
||||
|
||||
public class EntityAIOwnerHurtTarget extends EntityAITarget
|
||||
{
|
||||
EntityTameable theEntityTameable;
|
||||
EntityLiving theTarget;
|
||||
private int field_142050_e;
|
||||
|
||||
public EntityAIOwnerHurtTarget(EntityTameable theEntityTameableIn)
|
||||
{
|
||||
super(theEntityTameableIn, false);
|
||||
this.theEntityTameable = theEntityTameableIn;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.theEntityTameable.isTamed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntityLiving entitylivingbase = this.theEntityTameable.getOwner();
|
||||
|
||||
if (entitylivingbase == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.theTarget = entitylivingbase.getLastAttack();
|
||||
int i = entitylivingbase.getLastAttackTime();
|
||||
return i != this.field_142050_e && this.isSuitableTarget(this.theTarget) && this.theEntityTameable.shouldAttackEntity(this.theTarget, entitylivingbase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.taskOwner.setAttackTarget(this.theTarget);
|
||||
EntityLiving entitylivingbase = this.theEntityTameable.getOwner();
|
||||
|
||||
if (entitylivingbase != null)
|
||||
{
|
||||
this.field_142050_e = entitylivingbase.getLastAttackTime();
|
||||
}
|
||||
|
||||
super.startExecuting();
|
||||
}
|
||||
}
|
63
common/src/main/java/common/ai/EntityAIPanic.java
Executable file
63
common/src/main/java/common/ai/EntityAIPanic.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class EntityAIPanic extends EntityAIBase
|
||||
{
|
||||
private EntityLiving theEntityCreature;
|
||||
protected double speed;
|
||||
private double randPosX;
|
||||
private double randPosY;
|
||||
private double randPosZ;
|
||||
|
||||
public EntityAIPanic(EntityLiving creature, double speedIn)
|
||||
{
|
||||
this.theEntityCreature = creature;
|
||||
this.speed = speedIn;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.theEntityCreature.getAttackedBy() == null && !this.theEntityCreature.isBurning())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.theEntityCreature, 5, 4);
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.randPosX = vec3.xCoord;
|
||||
this.randPosY = vec3.yCoord;
|
||||
this.randPosZ = vec3.zCoord;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theEntityCreature.getNavigator().tryMoveToXYZ(this.randPosX, this.randPosY, this.randPosZ, this.speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.theEntityCreature.getNavigator().noPath();
|
||||
}
|
||||
}
|
72
common/src/main/java/common/ai/EntityAIPlay.java
Executable file
72
common/src/main/java/common/ai/EntityAIPlay.java
Executable file
|
@ -0,0 +1,72 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class EntityAIPlay extends EntityAIBase {
|
||||
private EntityNPC entity;
|
||||
private EntityLiving target;
|
||||
private double speed;
|
||||
private int time;
|
||||
|
||||
public EntityAIPlay(EntityNPC entity, double speed) {
|
||||
this.entity = entity;
|
||||
this.speed = speed;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
public boolean shouldExecute() {
|
||||
if(!this.entity.canPlay() || this.entity.getRNG().zrange(400) != 0)
|
||||
return false;
|
||||
List<EntityNPC> list = this.entity.worldObj.<EntityNPC>getEntitiesWithinAABB(EntityNPC.class,
|
||||
this.entity.getEntityBoundingBox().expand(6.0D, 3.0D, 6.0D));
|
||||
double d0 = Double.MAX_VALUE;
|
||||
for(EntityNPC npc : list) {
|
||||
if(npc != this.entity && !npc.isPlaying() && npc.canPlay() && !this.entity.canAttack(npc) && !npc.canAttack(this.entity)) {
|
||||
double d1 = npc.getDistanceSqToEntity(this.entity);
|
||||
if(d1 <= d0) {
|
||||
d0 = d1;
|
||||
this.target = npc;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(this.target == null) {
|
||||
Vec3 vec = RandomPositionGenerator.findRandomTarget(this.entity, 16, 3);
|
||||
if(vec == null)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean continueExecuting() {
|
||||
return this.time > 0;
|
||||
}
|
||||
|
||||
public void startExecuting() {
|
||||
if(this.target != null)
|
||||
this.entity.setPlaying(true);
|
||||
this.time = 1000;
|
||||
}
|
||||
|
||||
public void resetTask() {
|
||||
this.entity.setPlaying(false);
|
||||
this.target = null;
|
||||
}
|
||||
|
||||
public void updateTask() {
|
||||
--this.time;
|
||||
if(this.target != null) {
|
||||
if(this.entity.getDistanceSqToEntity(this.target) > 4.0D)
|
||||
this.entity.getNavigator().tryMoveToEntityLiving(this.target, this.speed);
|
||||
}
|
||||
else if(this.entity.getNavigator().noPath()) {
|
||||
Vec3 vec = RandomPositionGenerator.findRandomTarget(this.entity, 16, 3);
|
||||
if(vec == null)
|
||||
return;
|
||||
this.entity.getNavigator().tryMoveToXYZ(vec.xCoord, vec.yCoord, vec.zCoord, this.speed);
|
||||
}
|
||||
}
|
||||
}
|
85
common/src/main/java/common/ai/EntityAIRestrictOpenDoor.java
Executable file
85
common/src/main/java/common/ai/EntityAIRestrictOpenDoor.java
Executable file
|
@ -0,0 +1,85 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.util.BlockPos;
|
||||
import common.village.Village;
|
||||
import common.village.VillageDoorInfo;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class EntityAIRestrictOpenDoor extends EntityAIBase
|
||||
{
|
||||
private EntityLiving entityObj;
|
||||
private VillageDoorInfo frontDoor;
|
||||
|
||||
public EntityAIRestrictOpenDoor(EntityLiving creatureIn)
|
||||
{
|
||||
this.entityObj = creatureIn;
|
||||
|
||||
if (!(creatureIn.getNavigator() instanceof PathNavigateGround))
|
||||
{
|
||||
throw new IllegalArgumentException("Unsupported mob type for RestrictOpenDoorGoal");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (((AWorldServer)this.entityObj.worldObj).isDaytime())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this.entityObj);
|
||||
Village village = ((AWorldServer)this.entityObj.worldObj).getNearestVillage(blockpos, 16);
|
||||
|
||||
if (village == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.frontDoor = village.getNearestDoor(blockpos);
|
||||
return this.frontDoor == null ? false : (double)this.frontDoor.getDistanceToInsideBlockSq(blockpos) < 2.25D;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return ((AWorldServer)this.entityObj.worldObj).isDaytime() ? false : !this.frontDoor.getIsDetachedFromVillageFlag() && this.frontDoor.isIndoorSide(new BlockPos(this.entityObj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
((PathNavigateGround)this.entityObj.getNavigator()).setBreakDoors(false);
|
||||
((PathNavigateGround)this.entityObj.getNavigator()).setEnterDoors(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
((PathNavigateGround)this.entityObj.getNavigator()).setBreakDoors(true);
|
||||
((PathNavigateGround)this.entityObj.getNavigator()).setEnterDoors(true);
|
||||
this.frontDoor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.frontDoor.incrementDoorOpeningRestrictionCounter();
|
||||
}
|
||||
}
|
39
common/src/main/java/common/ai/EntityAIRestrictSun.java
Executable file
39
common/src/main/java/common/ai/EntityAIRestrictSun.java
Executable file
|
@ -0,0 +1,39 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class EntityAIRestrictSun extends EntityAIBase
|
||||
{
|
||||
private EntityLiving theEntity;
|
||||
|
||||
public EntityAIRestrictSun(EntityLiving creature)
|
||||
{
|
||||
this.theEntity = creature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return ((AWorldServer)this.theEntity.worldObj).isDaytime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
((PathNavigateGround)this.theEntity.getNavigator()).setAvoidSun(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
((PathNavigateGround)this.theEntity.getNavigator()).setAvoidSun(false);
|
||||
}
|
||||
}
|
94
common/src/main/java/common/ai/EntityAIRunAroundLikeCrazy.java
Executable file
94
common/src/main/java/common/ai/EntityAIRunAroundLikeCrazy.java
Executable file
|
@ -0,0 +1,94 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.animal.EntityHorse;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class EntityAIRunAroundLikeCrazy extends EntityAIBase
|
||||
{
|
||||
private EntityHorse horseHost;
|
||||
private double speed;
|
||||
private double targetX;
|
||||
private double targetY;
|
||||
private double targetZ;
|
||||
|
||||
public EntityAIRunAroundLikeCrazy(EntityHorse horse, double speedIn)
|
||||
{
|
||||
this.horseHost = horse;
|
||||
this.speed = speedIn;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.horseHost.isTame() && this.horseHost.passenger != null)
|
||||
{
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.horseHost, 5, 4);
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.targetX = vec3.xCoord;
|
||||
this.targetY = vec3.yCoord;
|
||||
this.targetZ = vec3.zCoord;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.horseHost.getNavigator().tryMoveToXYZ(this.targetX, this.targetY, this.targetZ, this.speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.horseHost.getNavigator().noPath() && this.horseHost.passenger != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.horseHost.getRNG().zrange(50) == 0)
|
||||
{
|
||||
if (this.horseHost.passenger instanceof EntityNPC)
|
||||
{
|
||||
int i = this.horseHost.getTemper();
|
||||
int j = this.horseHost.getMaxTemper();
|
||||
|
||||
if (j > 0 && this.horseHost.getRNG().zrange(j) < i)
|
||||
{
|
||||
this.horseHost.setHorseTamed(true);
|
||||
this.horseHost.worldObj.setEntityState(this.horseHost, (byte)7);
|
||||
return;
|
||||
}
|
||||
|
||||
this.horseHost.increaseTemper(5);
|
||||
}
|
||||
|
||||
this.horseHost.passenger.mountEntity((Entity)null);
|
||||
this.horseHost.passenger = null;
|
||||
this.horseHost.makeHorseRearWithSound();
|
||||
this.horseHost.worldObj.setEntityState(this.horseHost, (byte)6);
|
||||
}
|
||||
}
|
||||
}
|
101
common/src/main/java/common/ai/EntityAIShareItems.java
Executable file
101
common/src/main/java/common/ai/EntityAIShareItems.java
Executable file
|
@ -0,0 +1,101 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.item.EntityItem;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Items;
|
||||
import common.inventory.InventoryBasic;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public class EntityAIShareItems extends EntityAIWatchClosest2
|
||||
{
|
||||
private int interactionDelay;
|
||||
private EntityNPC entity;
|
||||
|
||||
public EntityAIShareItems(EntityNPC npc)
|
||||
{
|
||||
super(npc, EntityNPC.class, 3.0F, 0.02F);
|
||||
this.entity = npc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
super.startExecuting();
|
||||
|
||||
// if (this.entity.canShareItems() && this.closestEntity instanceof EntityNPC && ((EntityNPC)this.closestEntity).needsMoreItems())
|
||||
// {
|
||||
// this.interactionDelay = 10;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.interactionDelay = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
super.updateTask();
|
||||
|
||||
if (this.interactionDelay > 0)
|
||||
{
|
||||
--this.interactionDelay;
|
||||
|
||||
if (this.interactionDelay == 0)
|
||||
{
|
||||
InventoryBasic inventorybasic = this.entity.getExtendedInventory();
|
||||
|
||||
for (int i = 0; i < inventorybasic.getSizeInventory(); ++i)
|
||||
{
|
||||
ItemStack itemstack = inventorybasic.getStackInSlot(i);
|
||||
ItemStack itemstack1 = null;
|
||||
|
||||
if (itemstack != null)
|
||||
{
|
||||
Item item = itemstack.getItem();
|
||||
|
||||
if ((item == Items.bread || item == Items.potato || item == Items.carrot) && itemstack.stackSize > 3)
|
||||
{
|
||||
int l = itemstack.stackSize / 2;
|
||||
itemstack.stackSize -= l;
|
||||
itemstack1 = new ItemStack(item, l, itemstack.getMetadata());
|
||||
}
|
||||
else if (item == Items.wheats && itemstack.stackSize > 5)
|
||||
{
|
||||
int j = itemstack.stackSize / 2 / 3 * 3;
|
||||
int k = j / 3;
|
||||
itemstack.stackSize -= j;
|
||||
itemstack1 = new ItemStack(Items.bread, k, 0);
|
||||
}
|
||||
|
||||
if (itemstack.stackSize <= 0)
|
||||
{
|
||||
inventorybasic.setInventorySlotContents(i, (ItemStack)null);
|
||||
}
|
||||
}
|
||||
|
||||
if (itemstack1 != null)
|
||||
{
|
||||
double d0 = this.entity.posY - 0.30000001192092896D + (double)this.entity.getEyeHeight();
|
||||
EntityItem entityitem = new EntityItem(this.entity.worldObj, this.entity.posX, d0, this.entity.posZ, itemstack1);
|
||||
float f = 0.3F;
|
||||
float f1 = this.entity.headYaw;
|
||||
float f2 = this.entity.rotPitch;
|
||||
entityitem.motionX = (double)(-ExtMath.sin(f1 / 180.0F * (float)Math.PI) * ExtMath.cos(f2 / 180.0F * (float)Math.PI) * f);
|
||||
entityitem.motionZ = (double)(ExtMath.cos(f1 / 180.0F * (float)Math.PI) * ExtMath.cos(f2 / 180.0F * (float)Math.PI) * f);
|
||||
entityitem.motionY = (double)(-ExtMath.sin(f2 / 180.0F * (float)Math.PI) * f + 0.1F);
|
||||
entityitem.setDefaultPickupDelay();
|
||||
this.entity.worldObj.spawnEntityInWorld(entityitem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
67
common/src/main/java/common/ai/EntityAISit.java
Executable file
67
common/src/main/java/common/ai/EntityAISit.java
Executable file
|
@ -0,0 +1,67 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.entity.types.EntityTameable;
|
||||
|
||||
public class EntityAISit extends EntityAIBase
|
||||
{
|
||||
private EntityTameable theEntity;
|
||||
|
||||
/** If the EntityTameable is sitting. */
|
||||
private boolean isSitting;
|
||||
|
||||
public EntityAISit(EntityTameable entityIn)
|
||||
{
|
||||
this.theEntity = entityIn;
|
||||
this.setMutexBits(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (!this.theEntity.isTamed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (this.theEntity.isInLiquid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.theEntity.onGround)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntityLiving entitylivingbase = this.theEntity.getOwner();
|
||||
return entitylivingbase == null ? true : (this.theEntity.getDistanceSqToEntity(entitylivingbase) < 144.0D && entitylivingbase.getAttackedBy() != null ? false : this.isSitting);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.theEntity.getNavigator().clearPathEntity();
|
||||
this.theEntity.setSitting(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.theEntity.setSitting(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sitting flag.
|
||||
*/
|
||||
public void setSitting(boolean sitting)
|
||||
{
|
||||
this.isSitting = sitting;
|
||||
}
|
||||
}
|
35
common/src/main/java/common/ai/EntityAISwimming.java
Executable file
35
common/src/main/java/common/ai/EntityAISwimming.java
Executable file
|
@ -0,0 +1,35 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
|
||||
public class EntityAISwimming extends EntityAIBase
|
||||
{
|
||||
private EntityLiving theEntity;
|
||||
|
||||
public EntityAISwimming(EntityLiving entitylivingIn)
|
||||
{
|
||||
this.theEntity = entitylivingIn;
|
||||
this.setMutexBits(4);
|
||||
((PathNavigateGround)entitylivingIn.getNavigator()).setCanSwim(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return this.theEntity.isInLiquid() || this.theEntity.isInMolten();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
if (this.theEntity.getRNG().floatv() < 0.8F)
|
||||
{
|
||||
this.theEntity.getJumpHelper().setJumping();
|
||||
}
|
||||
}
|
||||
}
|
161
common/src/main/java/common/ai/EntityAITakePlace.java
Executable file
161
common/src/main/java/common/ai/EntityAITakePlace.java
Executable file
|
@ -0,0 +1,161 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import common.block.Block;
|
||||
import common.collect.Maps;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.init.ItemRegistry;
|
||||
import common.item.ItemStack;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.ExtMath;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAITakePlace extends EntityAIBase
|
||||
{
|
||||
private static class StackKey {
|
||||
public String item;
|
||||
public int meta;
|
||||
|
||||
public StackKey(String str) {
|
||||
String[] tok = str.split(":", 2);
|
||||
this.item = tok[0];
|
||||
this.meta = tok.length > 1 ? Integer.parseInt(tok[1]) : -1;
|
||||
}
|
||||
|
||||
public StackKey(ItemStack stack) {
|
||||
this.item = ItemRegistry.REGISTRY.getNameForObject(stack.getItem()).toString();
|
||||
this.meta = stack.getItem().getMaxDamage() <= 0 ? stack.getMetadata() : -1;
|
||||
}
|
||||
|
||||
// public boolean isSame(ItemStack stack) {
|
||||
// return this.item.equals(ItemRegistry.REGISTRY.getNameForObject(stack.getItem()).toString()) &&
|
||||
// (stack.getItem().getMaxDamage() > 0 || stack.getMetadata() == this.meta);
|
||||
// }
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return other instanceof StackKey && ((StackKey)other).item.equals(this.item) && ((StackKey)other).meta == this.meta;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.item.hashCode() ^ (this.meta << 8);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.item + (this.meta == -1 ? "" : (":" + this.meta));
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<State, ItemStack> STEALABLE = Maps.newHashMap();
|
||||
private static final Map<StackKey, State> PLACEABLE = Maps.newHashMap();
|
||||
|
||||
private static void addPlaceable(State state, ItemStack stack) {
|
||||
STEALABLE.put(state, stack);
|
||||
PLACEABLE.put(new StackKey(stack), state);
|
||||
}
|
||||
|
||||
private static void addPlaceable(Block block) {
|
||||
addPlaceable(block.getState(), new ItemStack(block));
|
||||
}
|
||||
|
||||
static {
|
||||
addPlaceable(Blocks.flower);
|
||||
addPlaceable(Blocks.brown_mushroom);
|
||||
addPlaceable(Blocks.red_mushroom);
|
||||
addPlaceable(Blocks.blue_mushroom);
|
||||
}
|
||||
|
||||
private EntityNPC entity;
|
||||
private boolean place;
|
||||
|
||||
public EntityAITakePlace(EntityNPC placer)
|
||||
{
|
||||
this.entity = placer;
|
||||
}
|
||||
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if(!Config.mobGrief || this.entity.getAttackTarget() != null)
|
||||
return false;
|
||||
if(this.entity.getHeldItem() == null) {
|
||||
this.place = false;
|
||||
return this.entity.getRNG().chance(20);
|
||||
}
|
||||
else if(this.entity.getRNG().chance(200) && PLACEABLE.containsKey(new StackKey(this.entity.getHeldItem()))) {
|
||||
this.place = this.entity.getRNG().rarity(10);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void updateTask()
|
||||
{
|
||||
Random random = this.entity.getRNG();
|
||||
World world = this.entity.worldObj;
|
||||
int i = ExtMath.floord(this.entity.posX - (this.place ? 1.0 : 2.0) + random.doublev() * (this.place ? 2.0 : 4.0));
|
||||
int j = ExtMath.floord(this.entity.posY + random.doublev() * (this.place ? 2.0 : 3.0));
|
||||
int k = ExtMath.floord(this.entity.posZ - (this.place ? 1.0 : 2.0) + random.doublev() * (this.place ? 2.0 : 4.0));
|
||||
BlockPos blockpos = new BlockPos(i, j, k);
|
||||
if(this.place) {
|
||||
ItemStack stack = this.entity.getHeldItem();
|
||||
if(stack == null || !PLACEABLE.containsKey(new StackKey(this.entity.getHeldItem())))
|
||||
return;
|
||||
Block replace = world.getState(blockpos).getBlock();
|
||||
Block below = world.getState(blockpos.down()).getBlock();
|
||||
State state = PLACEABLE.get(new StackKey(this.entity.getHeldItem()));
|
||||
if (state.getBlock().canPlaceBlockAt(world, blockpos) && replace == Blocks.air &&
|
||||
below != Blocks.air && below.isFullCube())
|
||||
{
|
||||
this.entity.getLookHelper().setLookPosition((double)i + 0.5, (double)j + 0.5, (double)k + 0.5, 10.0F,
|
||||
(float)this.entity.getVerticalFaceSpeed());
|
||||
this.entity.swingItem();
|
||||
world.setState(blockpos, state, 3);
|
||||
--stack.stackSize;
|
||||
if(stack.stackSize <= 0)
|
||||
this.entity.setItemNoUpdate(0, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
State state = world.getState(blockpos);
|
||||
Block block = state.getBlock();
|
||||
|
||||
if (STEALABLE.containsKey(state) &&
|
||||
(this.entity.getHeldItem() == null || (ItemStack.areItemsEqual(STEALABLE.get(state),
|
||||
this.entity.getHeldItem()) && this.entity.getHeldItem().stackSize < this.entity.getHeldItem().getMaxStackSize())))
|
||||
{
|
||||
this.entity.getLookHelper().setLookPosition((double)i + 0.5, (double)j + 0.5, (double)k + 0.5, 10.0F,
|
||||
(float)this.entity.getVerticalFaceSpeed());
|
||||
this.entity.swingItem();
|
||||
world.setState(blockpos, Blocks.air.getState());
|
||||
if(this.entity.getHeldItem() != null)
|
||||
++this.entity.getHeldItem().stackSize;
|
||||
else
|
||||
this.entity.setItemNoUpdate(0, STEALABLE.get(state).copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//private boolean shouldAttackPlayer(EntityNPC player)
|
||||
//{
|
||||
// ItemStack itemstack = player.inventory.armorInventory[3];
|
||||
//
|
||||
// if (itemstack != null && itemstack.getItem() == ItemRegistry.getItemFromBlock(Blocks.pumpkin))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Vec3 vec3 = player.getLook(1.0F).normalize();
|
||||
// Vec3 vec31 = new Vec3(this.posX - player.posX, this.getEntityBoundingBox().minY + (double)(this.height / 2.0F) - (player.posY + (double)player.getEyeHeight()), this.posZ - player.posZ);
|
||||
// double d0 = vec31.lengthVector();
|
||||
// vec31 = vec31.normalize();
|
||||
// double d1 = vec3.dotProduct(vec31);
|
||||
// return d1 > 1.0D - 0.025D / d0 ? player.canEntityBeSeen(this) : false;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
}
|
255
common/src/main/java/common/ai/EntityAITarget.java
Executable file
255
common/src/main/java/common/ai/EntityAITarget.java
Executable file
|
@ -0,0 +1,255 @@
|
|||
package common.ai;
|
||||
|
||||
import common.attributes.AttributeInstance;
|
||||
import common.attributes.Attributes;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.entity.types.IEntityOwnable;
|
||||
import common.init.Config;
|
||||
import common.pathfinding.PathEntity;
|
||||
import common.pathfinding.PathPoint;
|
||||
import common.util.BlockPos;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public abstract class EntityAITarget extends EntityAIBase
|
||||
{
|
||||
/** The entity that this task belongs to */
|
||||
protected final EntityLiving taskOwner;
|
||||
|
||||
/**
|
||||
* If true, EntityAI targets must be able to be seen (cannot be blocked by walls) to be suitable targets.
|
||||
*/
|
||||
protected boolean shouldCheckSight;
|
||||
|
||||
/**
|
||||
* When true, only entities that can be reached with minimal effort will be targetted.
|
||||
*/
|
||||
private boolean nearbyOnly;
|
||||
|
||||
/**
|
||||
* When nearbyOnly is true: 0 -> No target, but OK to search; 1 -> Nearby target found; 2 -> Target too far.
|
||||
*/
|
||||
private int targetSearchStatus;
|
||||
|
||||
/**
|
||||
* When nearbyOnly is true, this throttles target searching to avoid excessive pathfinding.
|
||||
*/
|
||||
private int targetSearchDelay;
|
||||
|
||||
/**
|
||||
* If @shouldCheckSight is true, the number of ticks before the interuption of this AITastk when the entity does't
|
||||
* see the target
|
||||
*/
|
||||
private int targetUnseenTicks;
|
||||
|
||||
public EntityAITarget(EntityLiving creature, boolean checkSight)
|
||||
{
|
||||
this(creature, checkSight, false);
|
||||
}
|
||||
|
||||
public EntityAITarget(EntityLiving creature, boolean checkSight, boolean onlyNearby)
|
||||
{
|
||||
this.taskOwner = creature;
|
||||
this.shouldCheckSight = checkSight;
|
||||
this.nearbyOnly = onlyNearby;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
EntityLiving entitylivingbase = this.taskOwner.getAttackTarget();
|
||||
|
||||
if (entitylivingbase == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!entitylivingbase.isEntityAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Team team = this.taskOwner.getTeam();
|
||||
// Team team1 = entitylivingbase.getTeam();
|
||||
//
|
||||
// if (team != null && team1 == team)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
double d0 = this.getTargetDistance();
|
||||
|
||||
if (this.taskOwner.getDistanceSqToEntity(entitylivingbase) > d0 * d0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.shouldCheckSight)
|
||||
{
|
||||
if (this.taskOwner.getEntitySenses().canSee(entitylivingbase))
|
||||
{
|
||||
this.targetUnseenTicks = 0;
|
||||
}
|
||||
else if (++this.targetUnseenTicks > 60)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Config.mobAttacks;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
protected double getTargetDistance()
|
||||
{
|
||||
AttributeInstance iattributeinstance = this.taskOwner.getEntityAttribute(Attributes.FOLLOW_RANGE);
|
||||
return iattributeinstance == null ? 16.0D : iattributeinstance.getAttributeValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.targetSearchStatus = 0;
|
||||
this.targetSearchDelay = 0;
|
||||
this.targetUnseenTicks = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.taskOwner.setAttackTarget((EntityLiving)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* A static method used to see if an entity is a suitable target through a number of checks.
|
||||
*/
|
||||
public static boolean isSuitableTarget(EntityLiving attacker, EntityLiving target, boolean checkSight)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (target == attacker)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!target.isEntityAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!Config.infight && target.getClass() == attacker.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Team team = attacker.getTeam();
|
||||
// Team team1 = target.getTeam();
|
||||
//
|
||||
// if (team != null && team1 == team)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
if (attacker instanceof IEntityOwnable // ) // && ((IEntityOwnable)attacker).getOwnerId() != null && !((IEntityOwnable)attacker).getOwnerId().isEmpty())
|
||||
// {
|
||||
// if (target instanceof IEntityOwnable && ((IEntityOwnable)attacker).getOwnerId().equalsIgnoreCase(((IEntityOwnable)target).getOwnerId()))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// if (
|
||||
&& target == ((IEntityOwnable)attacker).getOwner())
|
||||
{
|
||||
return false;
|
||||
// }
|
||||
}
|
||||
else if (!Config.mobAttacks)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !checkSight || attacker.getEntitySenses().canSee(target);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A method used to see if an entity is a suitable target through a number of checks. Args : entity,
|
||||
* canTargetInvinciblePlayer
|
||||
*/
|
||||
protected boolean isSuitableTarget(EntityLiving target)
|
||||
{
|
||||
if (!isSuitableTarget(this.taskOwner, target, this.shouldCheckSight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!this.taskOwner.isWithinHomeDistanceFromPosition(new BlockPos(target)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.nearbyOnly)
|
||||
{
|
||||
if (--this.targetSearchDelay <= 0)
|
||||
{
|
||||
this.targetSearchStatus = 0;
|
||||
}
|
||||
|
||||
if (this.targetSearchStatus == 0)
|
||||
{
|
||||
this.targetSearchStatus = this.canEasilyReach(target) ? 1 : 2;
|
||||
}
|
||||
|
||||
if (this.targetSearchStatus == 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if this entity can find a short path to the given target.
|
||||
*
|
||||
* @param target the entity to find a path to
|
||||
*/
|
||||
private boolean canEasilyReach(EntityLiving target)
|
||||
{
|
||||
this.targetSearchDelay = 10 + this.taskOwner.getRNG().zrange(5);
|
||||
PathEntity pathentity = this.taskOwner.getNavigator().getPathToEntityLiving(target);
|
||||
|
||||
if (pathentity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
PathPoint pathpoint = pathentity.getFinalPathPoint();
|
||||
|
||||
if (pathpoint == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = pathpoint.xCoord - ExtMath.floord(target.posX);
|
||||
int j = pathpoint.zCoord - ExtMath.floord(target.posZ);
|
||||
return (double)(i * i + j * j) <= 2.25D;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
common/src/main/java/common/ai/EntityAITargetNonTamed.java
Executable file
25
common/src/main/java/common/ai/EntityAITargetNonTamed.java
Executable file
|
@ -0,0 +1,25 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.entity.types.EntityTameable;
|
||||
|
||||
public class EntityAITargetNonTamed<T extends EntityLiving> extends EntityAINearestAttackableTarget
|
||||
{
|
||||
private EntityTameable theTameable;
|
||||
|
||||
public EntityAITargetNonTamed(EntityTameable entityIn, Class<T> classTarget, boolean checkSight, Predicate <? super T > targetSelector)
|
||||
{
|
||||
super(entityIn, classTarget, 10, checkSight, false, targetSelector);
|
||||
this.theTameable = entityIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
return !this.theTameable.isTamed() && super.shouldExecute();
|
||||
}
|
||||
}
|
173
common/src/main/java/common/ai/EntityAITasks.java
Executable file
173
common/src/main/java/common/ai/EntityAITasks.java
Executable file
|
@ -0,0 +1,173 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
|
||||
public class EntityAITasks
|
||||
{
|
||||
private List<EntityAITasks.EntityAITaskEntry> taskEntries = Lists.<EntityAITasks.EntityAITaskEntry>newArrayList();
|
||||
private List<EntityAITasks.EntityAITaskEntry> executingTaskEntries = Lists.<EntityAITasks.EntityAITaskEntry>newArrayList();
|
||||
private int tickCount;
|
||||
private int tickRate = 3;
|
||||
|
||||
/**
|
||||
* Add a now AITask. Args : priority, task
|
||||
*/
|
||||
public void addTask(int priority, EntityAIBase task)
|
||||
{
|
||||
this.taskEntries.add(new EntityAITasks.EntityAITaskEntry(priority, task));
|
||||
}
|
||||
|
||||
/**
|
||||
* removes the indicated task from the entity's AI tasks.
|
||||
*/
|
||||
public void removeTask(EntityAIBase task)
|
||||
{
|
||||
Iterator<EntityAITasks.EntityAITaskEntry> iterator = this.taskEntries.iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry = (EntityAITasks.EntityAITaskEntry)iterator.next();
|
||||
EntityAIBase entityaibase = entityaitasks$entityaitaskentry.action;
|
||||
|
||||
if (entityaibase == task)
|
||||
{
|
||||
if (this.executingTaskEntries.contains(entityaitasks$entityaitaskentry))
|
||||
{
|
||||
entityaibase.resetTask();
|
||||
this.executingTaskEntries.remove(entityaitasks$entityaitaskentry);
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onUpdateTasks()
|
||||
{
|
||||
// this.theProfiler.start("goalSetup");
|
||||
|
||||
if (this.tickCount++ % this.tickRate == 0)
|
||||
{
|
||||
Iterator iterator = this.taskEntries.iterator();
|
||||
label38:
|
||||
|
||||
while (true)
|
||||
{
|
||||
EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!iterator.hasNext())
|
||||
{
|
||||
break label38;
|
||||
}
|
||||
|
||||
entityaitasks$entityaitaskentry = (EntityAITasks.EntityAITaskEntry)iterator.next();
|
||||
boolean flag = this.executingTaskEntries.contains(entityaitasks$entityaitaskentry);
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this.canUse(entityaitasks$entityaitaskentry) || !this.canContinue(entityaitasks$entityaitaskentry))
|
||||
{
|
||||
entityaitasks$entityaitaskentry.action.resetTask();
|
||||
this.executingTaskEntries.remove(entityaitasks$entityaitaskentry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.canUse(entityaitasks$entityaitaskentry) && entityaitasks$entityaitaskentry.action.shouldExecute())
|
||||
{
|
||||
entityaitasks$entityaitaskentry.action.startExecuting();
|
||||
this.executingTaskEntries.add(entityaitasks$entityaitaskentry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<EntityAITasks.EntityAITaskEntry> iterator1 = this.executingTaskEntries.iterator();
|
||||
|
||||
while (iterator1.hasNext())
|
||||
{
|
||||
EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry1 = (EntityAITasks.EntityAITaskEntry)iterator1.next();
|
||||
|
||||
if (!this.canContinue(entityaitasks$entityaitaskentry1))
|
||||
{
|
||||
entityaitasks$entityaitaskentry1.action.resetTask();
|
||||
iterator1.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this.theProfiler.end();
|
||||
// this.theProfiler.start("goalTick");
|
||||
|
||||
for (EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry2 : this.executingTaskEntries)
|
||||
{
|
||||
entityaitasks$entityaitaskentry2.action.updateTask();
|
||||
}
|
||||
|
||||
// this.theProfiler.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a specific AI Task should continue being executed.
|
||||
*/
|
||||
private boolean canContinue(EntityAITasks.EntityAITaskEntry taskEntry)
|
||||
{
|
||||
boolean flag = taskEntry.action.continueExecuting();
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a specific AI Task can be executed, which means that all running higher (= lower int value) priority
|
||||
* tasks are compatible with it or all lower priority tasks can be interrupted.
|
||||
*/
|
||||
private boolean canUse(EntityAITasks.EntityAITaskEntry taskEntry)
|
||||
{
|
||||
for (EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry : this.taskEntries)
|
||||
{
|
||||
if (entityaitasks$entityaitaskentry != taskEntry)
|
||||
{
|
||||
if (taskEntry.priority >= entityaitasks$entityaitaskentry.priority)
|
||||
{
|
||||
if (!this.areTasksCompatible(taskEntry, entityaitasks$entityaitaskentry) && this.executingTaskEntries.contains(entityaitasks$entityaitaskentry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!entityaitasks$entityaitaskentry.action.isInterruptible() && this.executingTaskEntries.contains(entityaitasks$entityaitaskentry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether two EntityAITaskEntries can be executed concurrently
|
||||
*/
|
||||
private boolean areTasksCompatible(EntityAITasks.EntityAITaskEntry taskEntry1, EntityAITasks.EntityAITaskEntry taskEntry2)
|
||||
{
|
||||
return (taskEntry1.action.getMutexBits() & taskEntry2.action.getMutexBits()) == 0;
|
||||
}
|
||||
|
||||
class EntityAITaskEntry
|
||||
{
|
||||
public EntityAIBase action;
|
||||
public int priority;
|
||||
|
||||
public EntityAITaskEntry(int priorityIn, EntityAIBase task)
|
||||
{
|
||||
this.priority = priorityIn;
|
||||
this.action = task;
|
||||
}
|
||||
}
|
||||
}
|
181
common/src/main/java/common/ai/EntityAITempt.java
Executable file
181
common/src/main/java/common/ai/EntityAITempt.java
Executable file
|
@ -0,0 +1,181 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
|
||||
public class EntityAITempt extends EntityAIBase
|
||||
{
|
||||
/** The entity using this AI that is tempted by the player. */
|
||||
private EntityLiving temptedEntity;
|
||||
private double speed;
|
||||
|
||||
/** X position of player tempting this mob */
|
||||
private double targetX;
|
||||
|
||||
/** Y position of player tempting this mob */
|
||||
private double targetY;
|
||||
|
||||
/** Z position of player tempting this mob */
|
||||
private double targetZ;
|
||||
|
||||
/** Tempting player's pitch */
|
||||
private double pitch;
|
||||
|
||||
/** Tempting player's yaw */
|
||||
private double yaw;
|
||||
|
||||
/** The player that is tempting the entity that is using this AI. */
|
||||
private EntityNPC temptingPlayer;
|
||||
|
||||
/**
|
||||
* A counter that is decremented each time the shouldExecute method is called. The shouldExecute method will always
|
||||
* return false if delayTemptCounter is greater than 0.
|
||||
*/
|
||||
private int delayTemptCounter;
|
||||
|
||||
/** True if this EntityAITempt task is running */
|
||||
private boolean isRunning;
|
||||
private Item temptItem;
|
||||
private double range;
|
||||
private double distance;
|
||||
|
||||
/**
|
||||
* Whether the entity using this AI will be scared by the tempter's sudden movement.
|
||||
*/
|
||||
private boolean scaredByPlayerMovement;
|
||||
private boolean avoidWater;
|
||||
|
||||
public EntityAITempt(EntityLiving temptedEntityIn, double speedIn, Item temptItemIn, boolean scaredByPlayerMovementIn) {
|
||||
this(temptedEntityIn, speedIn, temptItemIn, 2.5, 10.0, scaredByPlayerMovementIn);
|
||||
}
|
||||
|
||||
public EntityAITempt(EntityLiving temptedEntityIn, double speedIn, Item temptItemIn, double distance, double range, boolean scaredByPlayerMovementIn)
|
||||
{
|
||||
this.temptedEntity = temptedEntityIn;
|
||||
this.speed = speedIn;
|
||||
this.temptItem = temptItemIn;
|
||||
this.distance = distance * distance;
|
||||
this.range = range;
|
||||
this.scaredByPlayerMovement = scaredByPlayerMovementIn;
|
||||
this.setMutexBits(3);
|
||||
|
||||
if (!(temptedEntityIn.getNavigator() instanceof PathNavigateGround))
|
||||
{
|
||||
throw new IllegalArgumentException("Unsupported mob type for TemptGoal");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.delayTemptCounter > 0)
|
||||
{
|
||||
--this.delayTemptCounter;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.temptingPlayer = this.temptedEntity.worldObj.getClosestPlayerToEntity(this.temptedEntity, this.distance);
|
||||
|
||||
if (this.temptingPlayer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.temptItem == null)
|
||||
return this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) >= this.distance;
|
||||
ItemStack itemstack = this.temptingPlayer.getCurrentEquippedItem();
|
||||
return itemstack == null ? false : itemstack.getItem() == this.temptItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
if (this.scaredByPlayerMovement)
|
||||
{
|
||||
if (this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) < 36.0D)
|
||||
{
|
||||
if (this.temptingPlayer.getDistanceSq(this.targetX, this.targetY, this.targetZ) > 0.010000000000000002D)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Math.abs((double)this.temptingPlayer.rotPitch - this.pitch) > 5.0D || Math.abs((double)this.temptingPlayer.rotYaw - this.yaw) > 5.0D)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.targetX = this.temptingPlayer.posX;
|
||||
this.targetY = this.temptingPlayer.posY;
|
||||
this.targetZ = this.temptingPlayer.posZ;
|
||||
}
|
||||
|
||||
this.pitch = (double)this.temptingPlayer.rotPitch;
|
||||
this.yaw = (double)this.temptingPlayer.rotYaw;
|
||||
}
|
||||
|
||||
return this.shouldExecute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.targetX = this.temptingPlayer.posX;
|
||||
this.targetY = this.temptingPlayer.posY;
|
||||
this.targetZ = this.temptingPlayer.posZ;
|
||||
this.isRunning = true;
|
||||
this.avoidWater = ((PathNavigateGround)this.temptedEntity.getNavigator()).getAvoidsWater();
|
||||
((PathNavigateGround)this.temptedEntity.getNavigator()).setAvoidsWater(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.temptingPlayer = null;
|
||||
this.temptedEntity.getNavigator().clearPathEntity();
|
||||
this.delayTemptCounter = 5; // 100;
|
||||
this.isRunning = false;
|
||||
((PathNavigateGround)this.temptedEntity.getNavigator()).setAvoidsWater(this.avoidWater);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.temptedEntity.getLookHelper().setLookPositionWithEntity(this.temptingPlayer, 30.0F, (float)this.temptedEntity.getVerticalFaceSpeed());
|
||||
|
||||
if (this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) < this.distance)
|
||||
{
|
||||
this.temptedEntity.getNavigator().clearPathEntity();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.temptedEntity.getNavigator().tryMoveToEntityLiving(this.temptingPlayer, this.speed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #isRunning
|
||||
*/
|
||||
public boolean isRunning()
|
||||
{
|
||||
return this.isRunning;
|
||||
}
|
||||
}
|
94
common/src/main/java/common/ai/EntityAIWander.java
Executable file
94
common/src/main/java/common/ai/EntityAIWander.java
Executable file
|
@ -0,0 +1,94 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class EntityAIWander extends EntityAIBase
|
||||
{
|
||||
private EntityLiving entity;
|
||||
private double xPosition;
|
||||
private double yPosition;
|
||||
private double zPosition;
|
||||
private double speed;
|
||||
private int executionChance;
|
||||
// private boolean mustUpdate;
|
||||
|
||||
public EntityAIWander(EntityLiving creatureIn, double speedIn)
|
||||
{
|
||||
this(creatureIn, speedIn, 120);
|
||||
}
|
||||
|
||||
public EntityAIWander(EntityLiving creatureIn, double speedIn, int chance)
|
||||
{
|
||||
this.entity = creatureIn;
|
||||
this.speed = speedIn;
|
||||
this.executionChance = chance;
|
||||
this.setMutexBits(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
// if (!this.mustUpdate)
|
||||
// {
|
||||
// if (this.entity.getAge() >= 100)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (this.entity.getRNG().zrange(this.executionChance) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// }
|
||||
|
||||
Vec3 vec3 = RandomPositionGenerator.findRandomTarget(this.entity, 10, 7);
|
||||
|
||||
if (vec3 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.xPosition = vec3.xCoord;
|
||||
this.yPosition = vec3.yCoord;
|
||||
this.zPosition = vec3.zCoord;
|
||||
// this.mustUpdate = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.entity.getNavigator().noPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.entity.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Makes task to bypass chance
|
||||
// */
|
||||
// public void makeUpdate()
|
||||
// {
|
||||
// this.mustUpdate = true;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Changes task random possibility for execution
|
||||
// */
|
||||
// public void setExecutionChance(int newchance)
|
||||
// {
|
||||
// this.executionChance = newchance;
|
||||
// }
|
||||
}
|
99
common/src/main/java/common/ai/EntityAIWatchClosest.java
Executable file
99
common/src/main/java/common/ai/EntityAIWatchClosest.java
Executable file
|
@ -0,0 +1,99 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class EntityAIWatchClosest extends EntityAIBase
|
||||
{
|
||||
protected EntityLiving theWatcher;
|
||||
|
||||
/** The closest entity which is being watched by this one. */
|
||||
protected Entity closestEntity;
|
||||
|
||||
/** This is the Maximum distance that the AI will look for the Entity */
|
||||
protected float maxDistanceForPlayer;
|
||||
private int lookTime;
|
||||
private float chance;
|
||||
protected Class <? extends Entity > watchedClass;
|
||||
|
||||
public EntityAIWatchClosest(EntityLiving entitylivingIn, Class <? extends Entity > watchTargetClass, float maxDistance)
|
||||
{
|
||||
this.theWatcher = entitylivingIn;
|
||||
this.watchedClass = watchTargetClass;
|
||||
this.maxDistanceForPlayer = maxDistance;
|
||||
this.chance = 0.02F;
|
||||
this.setMutexBits(2);
|
||||
}
|
||||
|
||||
public EntityAIWatchClosest(EntityLiving entitylivingIn, Class <? extends Entity > watchTargetClass, float maxDistance, float chanceIn)
|
||||
{
|
||||
this.theWatcher = entitylivingIn;
|
||||
this.watchedClass = watchTargetClass;
|
||||
this.maxDistanceForPlayer = maxDistance;
|
||||
this.chance = chanceIn;
|
||||
this.setMutexBits(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the EntityAIBase should begin execution.
|
||||
*/
|
||||
public boolean shouldExecute()
|
||||
{
|
||||
if (this.theWatcher.getRNG().floatv() >= this.chance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.theWatcher.getAttackTarget() != null)
|
||||
{
|
||||
this.closestEntity = this.theWatcher.getAttackTarget();
|
||||
}
|
||||
|
||||
if (this.watchedClass == null)
|
||||
{
|
||||
this.closestEntity = this.theWatcher.worldObj.getClosestPlayerToEntity(this.theWatcher, (double)this.maxDistanceForPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.closestEntity = ((AWorldServer)this.theWatcher.worldObj).findNearestEntityWithinAABB(this.watchedClass, this.theWatcher.getEntityBoundingBox().expand((double)this.maxDistanceForPlayer, 3.0D, (double)this.maxDistanceForPlayer), this.theWatcher);
|
||||
}
|
||||
|
||||
return this.closestEntity != null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an in-progress EntityAIBase should continue executing
|
||||
*/
|
||||
public boolean continueExecuting()
|
||||
{
|
||||
return !this.closestEntity.isEntityAlive() ? false : (this.theWatcher.getDistanceSqToEntity(this.closestEntity) > (double)(this.maxDistanceForPlayer * this.maxDistanceForPlayer) ? false : this.lookTime > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a one shot task or start executing a continuous task
|
||||
*/
|
||||
public void startExecuting()
|
||||
{
|
||||
this.lookTime = 40 + this.theWatcher.getRNG().zrange(40);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the task
|
||||
*/
|
||||
public void resetTask()
|
||||
{
|
||||
this.closestEntity = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the task
|
||||
*/
|
||||
public void updateTask()
|
||||
{
|
||||
this.theWatcher.getLookHelper().setLookPosition(this.closestEntity.posX, this.closestEntity.posY + (double)this.closestEntity.getEyeHeight(), this.closestEntity.posZ, 10.0F, (float)this.theWatcher.getVerticalFaceSpeed());
|
||||
--this.lookTime;
|
||||
}
|
||||
}
|
13
common/src/main/java/common/ai/EntityAIWatchClosest2.java
Executable file
13
common/src/main/java/common/ai/EntityAIWatchClosest2.java
Executable file
|
@ -0,0 +1,13 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntityAIWatchClosest2 extends EntityAIWatchClosest
|
||||
{
|
||||
public EntityAIWatchClosest2(EntityLiving entitylivingIn, Class <? extends Entity > watchTargetClass, float maxDistance, float chanceIn)
|
||||
{
|
||||
super(entitylivingIn, watchTargetClass, maxDistance, chanceIn);
|
||||
this.setMutexBits(3);
|
||||
}
|
||||
}
|
28
common/src/main/java/common/ai/EntityJumpHelper.java
Executable file
28
common/src/main/java/common/ai/EntityJumpHelper.java
Executable file
|
@ -0,0 +1,28 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntityJumpHelper
|
||||
{
|
||||
private EntityLiving entity;
|
||||
protected boolean isJumping;
|
||||
|
||||
public EntityJumpHelper(EntityLiving entityIn)
|
||||
{
|
||||
this.entity = entityIn;
|
||||
}
|
||||
|
||||
public void setJumping()
|
||||
{
|
||||
this.isJumping = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to actually make the entity jump if isJumping is true.
|
||||
*/
|
||||
public void doJump()
|
||||
{
|
||||
this.entity.setJumping(this.isJumping);
|
||||
this.isJumping = false;
|
||||
}
|
||||
}
|
143
common/src/main/java/common/ai/EntityLookHelper.java
Executable file
143
common/src/main/java/common/ai/EntityLookHelper.java
Executable file
|
@ -0,0 +1,143 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public class EntityLookHelper
|
||||
{
|
||||
private EntityLiving entity;
|
||||
|
||||
/**
|
||||
* The amount of change that is made each update for an entity facing a direction.
|
||||
*/
|
||||
private float deltaLookYaw;
|
||||
|
||||
/**
|
||||
* The amount of change that is made each update for an entity facing a direction.
|
||||
*/
|
||||
private float deltaLookPitch;
|
||||
|
||||
/** Whether or not the entity is trying to look at something. */
|
||||
private boolean isLooking;
|
||||
private double posX;
|
||||
private double posY;
|
||||
private double posZ;
|
||||
|
||||
public EntityLookHelper(EntityLiving entitylivingIn)
|
||||
{
|
||||
this.entity = entitylivingIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets position to look at using entity
|
||||
*/
|
||||
public void setLookPositionWithEntity(Entity entityIn, float deltaYaw, float deltaPitch)
|
||||
{
|
||||
this.posX = entityIn.posX;
|
||||
|
||||
if (entityIn instanceof EntityLiving)
|
||||
{
|
||||
this.posY = entityIn.posY + (double)entityIn.getEyeHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.posY = (entityIn.getEntityBoundingBox().minY + entityIn.getEntityBoundingBox().maxY) / 2.0D;
|
||||
}
|
||||
|
||||
this.posZ = entityIn.posZ;
|
||||
this.deltaLookYaw = deltaYaw;
|
||||
this.deltaLookPitch = deltaPitch;
|
||||
this.isLooking = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets position to look at
|
||||
*/
|
||||
public void setLookPosition(double x, double y, double z, float deltaYaw, float deltaPitch)
|
||||
{
|
||||
this.posX = x;
|
||||
this.posY = y;
|
||||
this.posZ = z;
|
||||
this.deltaLookYaw = deltaYaw;
|
||||
this.deltaLookPitch = deltaPitch;
|
||||
this.isLooking = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates look
|
||||
*/
|
||||
public void onUpdateLook()
|
||||
{
|
||||
this.entity.rotPitch = 0.0F;
|
||||
|
||||
if (this.isLooking)
|
||||
{
|
||||
this.isLooking = false;
|
||||
double d0 = this.posX - this.entity.posX;
|
||||
double d1 = this.posY - (this.entity.posY + (double)this.entity.getEyeHeight());
|
||||
double d2 = this.posZ - this.entity.posZ;
|
||||
double d3 = (double)ExtMath.sqrtd(d0 * d0 + d2 * d2);
|
||||
float f = (float)(ExtMath.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F;
|
||||
float f1 = (float)(-(ExtMath.atan2(d1, d3) * 180.0D / Math.PI));
|
||||
this.entity.rotPitch = this.updateRotation(this.entity.rotPitch, f1, this.deltaLookPitch);
|
||||
this.entity.headYaw = this.updateRotation(this.entity.headYaw, f, this.deltaLookYaw);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.entity.headYaw = this.updateRotation(this.entity.headYaw, this.entity.yawOffset, 10.0F);
|
||||
}
|
||||
|
||||
float f2 = ExtMath.wrapf(this.entity.headYaw - this.entity.yawOffset);
|
||||
|
||||
if (!this.entity.getNavigator().noPath())
|
||||
{
|
||||
if (f2 < -75.0F)
|
||||
{
|
||||
this.entity.headYaw = this.entity.yawOffset - 75.0F;
|
||||
}
|
||||
|
||||
if (f2 > 75.0F)
|
||||
{
|
||||
this.entity.headYaw = this.entity.yawOffset + 75.0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float updateRotation(float p_75652_1_, float p_75652_2_, float p_75652_3_)
|
||||
{
|
||||
float f = ExtMath.wrapf(p_75652_2_ - p_75652_1_);
|
||||
|
||||
if (f > p_75652_3_)
|
||||
{
|
||||
f = p_75652_3_;
|
||||
}
|
||||
|
||||
if (f < -p_75652_3_)
|
||||
{
|
||||
f = -p_75652_3_;
|
||||
}
|
||||
|
||||
return p_75652_1_ + f;
|
||||
}
|
||||
|
||||
public boolean getIsLooking()
|
||||
{
|
||||
return this.isLooking;
|
||||
}
|
||||
|
||||
public double getLookPosX()
|
||||
{
|
||||
return this.posX;
|
||||
}
|
||||
|
||||
public double getLookPosY()
|
||||
{
|
||||
return this.posY;
|
||||
}
|
||||
|
||||
public double getLookPosZ()
|
||||
{
|
||||
return this.posZ;
|
||||
}
|
||||
}
|
121
common/src/main/java/common/ai/EntityMoveHelper.java
Executable file
121
common/src/main/java/common/ai/EntityMoveHelper.java
Executable file
|
@ -0,0 +1,121 @@
|
|||
package common.ai;
|
||||
|
||||
import common.attributes.Attributes;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public class EntityMoveHelper
|
||||
{
|
||||
/** The EntityLiving that is being moved */
|
||||
protected EntityLiving entity;
|
||||
protected double posX;
|
||||
protected double posY;
|
||||
protected double posZ;
|
||||
|
||||
/** The speed at which the entity should move */
|
||||
protected double speed;
|
||||
protected boolean update;
|
||||
|
||||
public EntityMoveHelper(EntityLiving entitylivingIn)
|
||||
{
|
||||
this.entity = entitylivingIn;
|
||||
this.posX = entitylivingIn.posX;
|
||||
this.posY = entitylivingIn.posY;
|
||||
this.posZ = entitylivingIn.posZ;
|
||||
}
|
||||
|
||||
public boolean isUpdating()
|
||||
{
|
||||
return this.update;
|
||||
}
|
||||
|
||||
public double getSpeed()
|
||||
{
|
||||
return this.speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the speed and location to move to
|
||||
*/
|
||||
public void setMoveTo(double x, double y, double z, double speedIn)
|
||||
{
|
||||
this.posX = x;
|
||||
this.posY = y;
|
||||
this.posZ = z;
|
||||
this.speed = speedIn;
|
||||
this.update = true;
|
||||
}
|
||||
|
||||
public void onUpdateMoveHelper()
|
||||
{
|
||||
this.entity.setMoveForward(0.0F);
|
||||
|
||||
if (this.update)
|
||||
{
|
||||
this.update = false;
|
||||
int i = ExtMath.floord(this.entity.getEntityBoundingBox().minY + 0.5D);
|
||||
double d0 = this.posX - this.entity.posX;
|
||||
double d1 = this.posZ - this.entity.posZ;
|
||||
double d2 = this.posY - (double)i;
|
||||
double d3 = d0 * d0 + d2 * d2 + d1 * d1;
|
||||
|
||||
if (d3 >= 2.500000277905201E-7D)
|
||||
{
|
||||
float f = (float)(ExtMath.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
|
||||
this.entity.rotYaw = this.limitAngle(this.entity.rotYaw, f, 30.0F);
|
||||
this.entity.setAIMoveSpeed((float)(this.speed * this.entity.getEntityAttribute(Attributes.MOVEMENT_SPEED).getAttributeValue()));
|
||||
|
||||
if (d2 > 0.0D && d0 * d0 + d1 * d1 < 1.0D)
|
||||
{
|
||||
this.entity.getJumpHelper().setJumping();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits the given angle to a upper and lower limit.
|
||||
*/
|
||||
protected float limitAngle(float p_75639_1_, float p_75639_2_, float p_75639_3_)
|
||||
{
|
||||
float f = ExtMath.wrapf(p_75639_2_ - p_75639_1_);
|
||||
|
||||
if (f > p_75639_3_)
|
||||
{
|
||||
f = p_75639_3_;
|
||||
}
|
||||
|
||||
if (f < -p_75639_3_)
|
||||
{
|
||||
f = -p_75639_3_;
|
||||
}
|
||||
|
||||
float f1 = p_75639_1_ + f;
|
||||
|
||||
if (f1 < 0.0F)
|
||||
{
|
||||
f1 += 360.0F;
|
||||
}
|
||||
else if (f1 > 360.0F)
|
||||
{
|
||||
f1 -= 360.0F;
|
||||
}
|
||||
|
||||
return f1;
|
||||
}
|
||||
|
||||
public double getX()
|
||||
{
|
||||
return this.posX;
|
||||
}
|
||||
|
||||
public double getY()
|
||||
{
|
||||
return this.posY;
|
||||
}
|
||||
|
||||
public double getZ()
|
||||
{
|
||||
return this.posZ;
|
||||
}
|
||||
}
|
60
common/src/main/java/common/ai/EntitySenses.java
Executable file
60
common/src/main/java/common/ai/EntitySenses.java
Executable file
|
@ -0,0 +1,60 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
|
||||
public class EntitySenses
|
||||
{
|
||||
EntityLiving entityObj;
|
||||
List<Entity> seenEntities = Lists.<Entity>newArrayList();
|
||||
List<Entity> unseenEntities = Lists.<Entity>newArrayList();
|
||||
|
||||
public EntitySenses(EntityLiving entityObjIn)
|
||||
{
|
||||
this.entityObj = entityObjIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears canSeeCachePositive and canSeeCacheNegative.
|
||||
*/
|
||||
public void clearSensingCache()
|
||||
{
|
||||
this.seenEntities.clear();
|
||||
this.unseenEntities.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, whether 'our' entity can see the entity given as argument (true) or not (false), caching the result.
|
||||
*/
|
||||
public boolean canSee(Entity entityIn)
|
||||
{
|
||||
if (this.seenEntities.contains(entityIn))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (this.unseenEntities.contains(entityIn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this.entityObj.worldObj.profiler.start("canSee");
|
||||
boolean flag = this.entityObj.canEntityBeSeen(entityIn);
|
||||
// this.entityObj.worldObj.profiler.end();
|
||||
|
||||
if (flag)
|
||||
{
|
||||
this.seenEntities.add(entityIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.unseenEntities.add(entityIn);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
}
|
129
common/src/main/java/common/ai/RandomPositionGenerator.java
Executable file
129
common/src/main/java/common/ai/RandomPositionGenerator.java
Executable file
|
@ -0,0 +1,129 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.ExtMath;
|
||||
import common.util.Vec3;
|
||||
|
||||
public class RandomPositionGenerator
|
||||
{
|
||||
/**
|
||||
* used to store a driection when the user passes a point to move towards or away from. WARNING: NEVER THREAD SAFE.
|
||||
* MULTIPLE findTowards and findAway calls, will share this var
|
||||
*/
|
||||
private static Vec3 staticVector = new Vec3(0.0D, 0.0D, 0.0D);
|
||||
|
||||
/**
|
||||
* finds a random target within par1(x,z) and par2 (y) blocks
|
||||
*/
|
||||
public static Vec3 findRandomTarget(EntityLiving entitycreatureIn, int xz, int y)
|
||||
{
|
||||
return findRandomTargetBlock(entitycreatureIn, xz, y, (Vec3)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* finds a random target within par1(x,z) and par2 (y) blocks in the direction of the point par3
|
||||
*/
|
||||
public static Vec3 findRandomTargetBlockTowards(EntityLiving entitycreatureIn, int xz, int y, Vec3 targetVec3)
|
||||
{
|
||||
staticVector = targetVec3.subtract(entitycreatureIn.posX, entitycreatureIn.posY, entitycreatureIn.posZ);
|
||||
return findRandomTargetBlock(entitycreatureIn, xz, y, staticVector);
|
||||
}
|
||||
|
||||
/**
|
||||
* finds a random target within par1(x,z) and par2 (y) blocks in the reverse direction of the point par3
|
||||
*/
|
||||
public static Vec3 findRandomTargetBlockAwayFrom(EntityLiving entitycreatureIn, int xz, int y, Vec3 targetVec3)
|
||||
{
|
||||
staticVector = (new Vec3(entitycreatureIn.posX, entitycreatureIn.posY, entitycreatureIn.posZ)).subtract(targetVec3);
|
||||
return findRandomTargetBlock(entitycreatureIn, xz, y, staticVector);
|
||||
}
|
||||
|
||||
/**
|
||||
* searches 10 blocks at random in a within par1(x,z) and par2 (y) distance, ignores those not in the direction of
|
||||
* par3Vec3, then points to the tile for which creature.getBlockPathWeight returns the highest number
|
||||
*/
|
||||
private static Vec3 findRandomTargetBlock(EntityLiving entitycreatureIn, int xz, int y, Vec3 targetVec3)
|
||||
{
|
||||
Random random = entitycreatureIn.getRNG();
|
||||
boolean flag = false;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
float f = -99999.0F;
|
||||
boolean flag1;
|
||||
|
||||
if (entitycreatureIn.hasHome())
|
||||
{
|
||||
double d0 = entitycreatureIn.getHomePosition().distanceSq((double)ExtMath.floord(entitycreatureIn.posX), (double)ExtMath.floord(entitycreatureIn.posY), (double)ExtMath.floord(entitycreatureIn.posZ)) + 4.0D;
|
||||
double d1 = (double)(entitycreatureIn.getMaximumHomeDistance() + (float)xz);
|
||||
flag1 = d0 < d1 * d1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag1 = false;
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < 10; ++j1)
|
||||
{
|
||||
int l = random.zrange(2 * xz + 1) - xz;
|
||||
int k1 = random.zrange(2 * y + 1) - y;
|
||||
int i1 = random.zrange(2 * xz + 1) - xz;
|
||||
|
||||
if (targetVec3 == null || (double)l * targetVec3.xCoord + (double)i1 * targetVec3.zCoord >= 0.0D)
|
||||
{
|
||||
if (entitycreatureIn.hasHome() && xz > 1)
|
||||
{
|
||||
BlockPos blockpos = entitycreatureIn.getHomePosition();
|
||||
|
||||
if (entitycreatureIn.posX > (double)blockpos.getX())
|
||||
{
|
||||
l -= random.zrange(xz / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
l += random.zrange(xz / 2);
|
||||
}
|
||||
|
||||
if (entitycreatureIn.posZ > (double)blockpos.getZ())
|
||||
{
|
||||
i1 -= random.zrange(xz / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
i1 += random.zrange(xz / 2);
|
||||
}
|
||||
}
|
||||
|
||||
l = l + ExtMath.floord(entitycreatureIn.posX);
|
||||
k1 = k1 + ExtMath.floord(entitycreatureIn.posY);
|
||||
i1 = i1 + ExtMath.floord(entitycreatureIn.posZ);
|
||||
BlockPos blockpos1 = new BlockPos(l, k1, i1);
|
||||
|
||||
if (!flag1 || entitycreatureIn.isWithinHomeDistanceFromPosition(blockpos1))
|
||||
{
|
||||
float f1 = entitycreatureIn.getBlockPathWeight(blockpos1);
|
||||
|
||||
if (f1 > f)
|
||||
{
|
||||
f = f1;
|
||||
i = l;
|
||||
j = k1;
|
||||
k = i1;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
return new Vec3((double)i, (double)j, (double)k);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
84
common/src/main/java/common/attributes/Attribute.java
Executable file
84
common/src/main/java/common/attributes/Attribute.java
Executable file
|
@ -0,0 +1,84 @@
|
|||
package common.attributes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import common.collect.Maps;
|
||||
import common.util.ExtMath;
|
||||
|
||||
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
common/src/main/java/common/attributes/AttributeInstance.java
Executable file
191
common/src/main/java/common/attributes/AttributeInstance.java
Executable file
|
@ -0,0 +1,191 @@
|
|||
package common.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
import common.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> getModifiers()
|
||||
{
|
||||
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.getModifiers();
|
||||
|
||||
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;
|
||||
// }
|
||||
}
|
163
common/src/main/java/common/attributes/AttributeMap.java
Executable file
163
common/src/main/java/common/attributes/AttributeMap.java
Executable file
|
@ -0,0 +1,163 @@
|
|||
package common.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import common.collect.Maps;
|
||||
import common.collect.Sets;
|
||||
import common.util.LowerStringMap;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
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
common/src/main/java/common/attributes/AttributeModifier.java
Executable file
134
common/src/main/java/common/attributes/AttributeModifier.java
Executable file
|
@ -0,0 +1,134 @@
|
|||
package common.attributes;
|
||||
|
||||
import common.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
common/src/main/java/common/attributes/Attributes.java
Executable file
161
common/src/main/java/common/attributes/Attributes.java
Executable file
|
@ -0,0 +1,161 @@
|
|||
package common.attributes;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import common.log.Log;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.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.getModifiers();
|
||||
|
||||
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.TICK.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.TICK.warn("Konnte Attribute nicht erstellen: " + exception.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
235
common/src/main/java/common/biome/Biome.java
Normal file
235
common/src/main/java/common/biome/Biome.java
Normal file
|
@ -0,0 +1,235 @@
|
|||
package common.biome;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
import common.color.Colorizer;
|
||||
import common.log.Log;
|
||||
import common.rng.PerlinGen;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.ExtMath;
|
||||
|
||||
public enum Biome {
|
||||
NONE(0, "none", "<Keins>", 0x000000),
|
||||
PLAINS(1, "plains", "Ebene", 0x8db360, 12.0f, 40.0f),
|
||||
DESERT(2, "desert", "Wüste", 0xfa9418, 60.0f, 0.0f),
|
||||
EXTREMEHILLS(3, "extremeHills", "Extremes Bergland", 0x606060, -12.0f, 30.0f),
|
||||
FOREST(4, "forest", "Wald", 0x056621, 8.0f, 80.0f),
|
||||
TAIGA(5, "taiga", "Taiga", 0x0b6659, -10.0f, 80.0f),
|
||||
SWAMPLAND(6, "swampland", "Sumpf", 0x07f9b2, 12.0f, 90.0f, 0xe0ffae, 0xffffffff, 6975545),
|
||||
RIVER(7, "river", "Fluss", 0x0000ff),
|
||||
EXTERMINATED(8, "exterminated", "Ausgelöscht", 0x000000, 150.0f, 0.0f, 0x202020, 0x303030, 0x303030, 0x101010, 0x303030, 0x000000),
|
||||
SPACE(9, "space", "Leere des Weltraums", 0x000000, 0.0f, 0.0f),
|
||||
FROZENSEA(10, "frozenSea", "Vereister See", 0x9090a0, -20.0f),
|
||||
FROZENRIVER(11, "frozenRiver", "Vereister Fluss", 0xa0a0ff, -20.0f),
|
||||
ICEPLAINS(12, "icePlains", "Eisebene", 0xffffff, -20.0f),
|
||||
ICEMOUNTAINS(13, "iceMountains", "Vereistes Bergland", 0xa0a0a0, -20.0f),
|
||||
MUSHROOMPLAINS(14, "mushroomPlains", "Pilzland", 0xff00ff, 16.0f, 100.0f),
|
||||
BLACKENED(15, "blackened", "Schwarz", 0x000000, 0.0f, 0.0f, 0x000000, 0x303030, 0x303030, 0x000000, 0x000000, 0x000000),
|
||||
BEACH(16, "beach", "Strand", 0xfade55, 12.0f, 40.0f),
|
||||
DESERTHILLS(17, "desertHills", "Wüsten-Bergland", 0xd25f12, 60.0f, 0.0f),
|
||||
FORESTHILLS(18, "forestHills", "Wald-Bergland", 0x22551c, 8.0f, 80.0f),
|
||||
TAIGAHILLS(19, "taigaHills", "Taiga-Bergland", 0x163933, -10.0f, 80.0f),
|
||||
EXTREMEHILLSEDGE(20, "extremeHillsEdge", "Extremes Bergland Gr.", 0x72789a, -12.0f, 30.0f),
|
||||
JUNGLE(21, "jungle", "Urwald", 0x537b09, 18.0f, 90.0f),
|
||||
JUNGLEHILLS(22, "jungleHills", "Urwald-Bergland", 0x2c4205, 18.0f, 90.0f),
|
||||
JUNGLEEDGE(23, "jungleEdge", "Urwald Gr.", 0x628b17, 18.0f, 80.0f),
|
||||
SEA(24, "sea", "See", 0x000070),
|
||||
STONEBEACH(25, "stoneBeach", "Steinstrand", 0xa2a284, -12.0f, 30.0f),
|
||||
COLDBEACH(26, "coldBeach", "Vereister Strand", 0xfaf0c0, -18.0f, 30.0f),
|
||||
BIRCHFOREST(27, "birchForest", "Birkenwald", 0x307444, 4.0f, 60.0f),
|
||||
BIRCHFORESTHILLS(28, "birchForestHills", "Birkenwald-Bergland", 0x1f5f32, 4.0f, 60.0f),
|
||||
ROOFEDFOREST(29, "roofedForest", "Dichter Wald", 0x40511a, 8.0f, 80.0f),
|
||||
COLDTAIGA(30, "coldTaiga", "Vereiste Taiga", 0x31554a, -40.0f, 40.0f),
|
||||
COLDTAIGAHILLS(31, "coldTaigaHills", "Vereistes Taiga-Bergland", 0x243f36, -40.0f, 40.0f),
|
||||
MEGATAIGA(32, "megaTaiga", "Hohe Taiga", 0x596651, -8.0f, 80.0f),
|
||||
MEGATAIGAHILLS(33, "megaTaigaHills", "Hohes Taiga-Bergland", 0x454f3e, -8.0f, 80.0f),
|
||||
EXTREMEHILLSPLUS(34, "extremeHillsPlus", "Extremes Bergland +", 0x507050, -12.0f, 30.0f),
|
||||
SAVANNA(35, "savanna", "Savanne", 0xbdb25f, 28.0f, 0.0f),
|
||||
SAVANNAPLATEAU(36, "savannaPlateau", "Savannen-Plateau", 0xa79d64, 20.0f, 0.0f),
|
||||
MESA(37, "mesa", "Mesa", 0xd94515, 0.0f, 0.0f, 0xffffff, 9470285, 10387789),
|
||||
MESAPLATEAUF(38, "mesaPlateauF", "Mesa-Waldplateau", 0xb09765, 0.0f, 0.0f, 0xffffff, 9470285, 10387789),
|
||||
MESAPLATEAU(39, "mesaPlateau", "Mesa-Plateau", 0xca8c65, 0.0f, 0.0f, 0xffffff, 9470285, 10387789),
|
||||
SNOWLAND(40, "snowLand", "Eisland", 0xffffff, 0.0f, 100.0f),
|
||||
TIAN(41, "tian", "Tian", 0x808080, 0.0f, 80.0f),
|
||||
ELVENFOREST(42, "elvenForest", "Elbenwald", 0x059821, 8.0f, 90.0f),
|
||||
UPPERHELL(43, "upperHell", "Übergang in die Hölle", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000),
|
||||
LOWERHELL(44, "lowerHell", "Abgrund der Hölle", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000),
|
||||
HELLHILLS(45, "hellHills", "Bergland der Hölle", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000),
|
||||
SOULPLAINS(46, "soulPlains", "Seelenland", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000),
|
||||
ASHLAND(47, "ashLand", "Verbrannt", 0xff0000, 0.0f, 0.0f, 0x000000, 0x000000, 0x000000),
|
||||
MOON(48, "moon", "Mondoberfläche", 0xa0a0a0, 0.0f, 0.0f),
|
||||
CHAOS(49, "chaos", "Chaos", 0xff00ff),
|
||||
|
||||
DESERTM(130, "desertM", "Wüste M", 0xfa9418, 60.0f, 0.0f),
|
||||
EXTREMEHILLSM(131, "extremeHillsM", "Extremes Bergland M", 0x606060, -12.0f, 30.0f),
|
||||
FLOWERFOREST(132, "flowerForest", "Blumenwald", 0x6a7425, 8.0f, 80.0f),
|
||||
TAIGAM(133, "taigaM", "Taiga M", 0x0b6659, -10.0f, 80.0f),
|
||||
SWAMPLANDM(134, "swamplandM", "Sumpf M", 0x07f9b2, 12.0f, 90.0f, 0xe0ffae, 0xffffffff, 6975545),
|
||||
ICEPLAINSSPIKES(140, "icePlainsSpikes", "Eisebene + Spitzen", 0xd2ffff, -20.0f),
|
||||
JUNGLEM(149, "jungleM", "Urwald M", 0x537b09, 18.0f, 90.0f),
|
||||
JUNGLEEDGEM(151, "jungleEdgeM", "Urwald Gr. M", 0x628b17, 18.0f, 80.0f),
|
||||
BIRCHFORESTM(155, "birchForestM", "Birkenwald M", 0x307444, 4.0f, 60.0f),
|
||||
BIRCHFORESTHILLSM(156, "birchForestHillsM", "Birkenwald-Bergland M", 0x1f5f32, 4.0f, 60.0f),
|
||||
ROOFEDFORESTM(157, "roofedForestM", "Dichter Wald M", 0x40511a, 8.0f, 80.0f),
|
||||
COLDTAIGAM(158, "coldTaigaM", "Vereiste Taiga M", 0x31554a, -40.0f, 40.0f),
|
||||
MEGASPRUCETAIGA(160, "megaSpruceTaiga", "Hohe Fichtentaiga", 0x596651, -10.0f, 80.0f),
|
||||
REDWOODTAIGAHILLSM(161, "redwoodTaigaHillsM", "Mammutbaumtaiga", 0x596651, -10.0f, 80.0f),
|
||||
EXTREMEHILLSPLUSM(162, "extremeHillsPlusM", "Extremes Bergland + M", 0x507050, -12.0f, 30.0f),
|
||||
SAVANNAM(163, "savannaM", "Savanne M", 0xbdb25f, 24.0f, 0.0f),
|
||||
SAVANNAPLATEAUM(164, "savannaPlateauM", "Savannen-Plateau M", 0xa79d64, 20.0f, 0.0f),
|
||||
MESABRYCE(165, "mesaBryce", "Mesa (Bryce)", 0xd94515, 0.0f, 0.0f, 0xffffff, 9470285, 10387789),
|
||||
MESAPLATEAUFM(166, "mesaPlateauFM", "Mesa-Waldplateau M", 0xb09765, 0.0f, 0.0f, 0xffffff, 9470285, 10387789),
|
||||
MESAPLATEAUM(167, "mesaPlateauM", "Mesa-Plateau M", 0xca8c65, 0.0f, 0.0f, 0xffffff, 9470285, 10387789);
|
||||
|
||||
public static final Biome DEF_BIOME = FOREST;
|
||||
private static final PerlinGen TEMP_NOISE = new PerlinGen(new Random(836430928262265276L), 1);
|
||||
private static final PerlinGen COLOR_NOISE = new PerlinGen(new Random(6549321755809421L), 1);
|
||||
private static final Biome[] BIOMES = new Biome[256];
|
||||
private static final Map<String, Biome> LOOKUP = Maps.newTreeMap();
|
||||
|
||||
public final int id;
|
||||
public final String name;
|
||||
public final String display;
|
||||
public final int color;
|
||||
public final float temperature;
|
||||
public final float humidity;
|
||||
public final int waterColor;
|
||||
public final int grassColor;
|
||||
public final int foliageColor;
|
||||
public final int skyColor;
|
||||
public final int fogColor;
|
||||
public final int cloudColor;
|
||||
|
||||
static {
|
||||
for(Biome biome : values()) {
|
||||
BIOMES[biome.id] = biome;
|
||||
if(LOOKUP.containsKey(biome.name.toLowerCase()))
|
||||
throw new IllegalStateException("Biom \"" + biome.name + "\" ist als ID " + LOOKUP.get(biome.name.toLowerCase()).id + " und " + biome.id + " definiert");
|
||||
LOOKUP.put(biome.name.toLowerCase(), biome);
|
||||
}
|
||||
}
|
||||
|
||||
public static Biome getBiome(int id)
|
||||
{
|
||||
if (id >= 0 && id < BIOMES.length)
|
||||
{
|
||||
return BIOMES[id];
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.TICK.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")");
|
||||
return DEF_BIOME;
|
||||
}
|
||||
}
|
||||
|
||||
public static Biome getBiomeDef(int id)
|
||||
{
|
||||
if (id >= 0 && id < BIOMES.length)
|
||||
{
|
||||
Biome biome = BIOMES[id];
|
||||
return biome == null ? DEF_BIOME : biome;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.TICK.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")");
|
||||
return DEF_BIOME;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getBiomeNames() {
|
||||
return Lists.newArrayList(LOOKUP.keySet());
|
||||
}
|
||||
|
||||
public static Biome findByName(String name) {
|
||||
Biome biome = LOOKUP.get(name.toLowerCase().replace(" ", "").replace("_", ""));
|
||||
if(biome == null) {
|
||||
int z;
|
||||
try {
|
||||
z = Integer.parseInt(name);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
return DEF_BIOME;
|
||||
}
|
||||
return z < 0 || z >= BIOMES.length || BIOMES[z] == null ? DEF_BIOME : BIOMES[z];
|
||||
}
|
||||
return biome;
|
||||
}
|
||||
|
||||
private Biome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor, int skyColor, int fogColor, int cloudColor) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
this.temperature = temperature;
|
||||
this.humidity = humidity;
|
||||
this.color = color;
|
||||
this.waterColor = waterColor;
|
||||
this.grassColor = grassColor;
|
||||
this.foliageColor = foliageColor;
|
||||
this.skyColor = skyColor;
|
||||
this.fogColor = fogColor;
|
||||
this.cloudColor = cloudColor;
|
||||
}
|
||||
|
||||
private Biome(int id, String name, String display, int color, float temperature, float humidity, int waterColor, int grassColor, int foliageColor) {
|
||||
this(id, name, display, color, temperature, humidity, waterColor, grassColor, foliageColor, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
|
||||
private Biome(int id, String name, String display, int color, float temperature, float humidity) {
|
||||
this(id, name, display, color, temperature, humidity, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
|
||||
private Biome(int id, String name, String display, int color, float temperature) {
|
||||
this(id, name, display, color, temperature, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
|
||||
private Biome(int id, String name, String display, int color) {
|
||||
this(id, name, display, color, 0.0f, 50.0f, 0xffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
|
||||
public final float getTemperature(BlockPos pos) {
|
||||
if(pos.getY() > 64) {
|
||||
float f = (float)(TEMP_NOISE.generate((double)pos.getX() * 1.0D / 8.0D, (double)pos.getZ() * 1.0D / 8.0D) * 4.0D);
|
||||
return this.temperature - (f + (float)pos.getY() - 64.0F) / 15.0f;
|
||||
}
|
||||
return this.temperature;
|
||||
}
|
||||
|
||||
public float getFactor() {
|
||||
float f = this.humidity * 0.01f * ((this.temperature + 14.0f) / 40.0f + 0.15f);
|
||||
return f > 1.0f ? 1.0f : f;
|
||||
}
|
||||
|
||||
public boolean isHighHumidity() {
|
||||
return this.humidity > 85.0f;
|
||||
}
|
||||
|
||||
// skycolor = ((temp + 14) / 40 + 0.15) / 3
|
||||
|
||||
public int getGrassColorAtPos(BlockPos pos) {
|
||||
if(this.grassColor != 0xffffffff)
|
||||
return this.grassColor;
|
||||
if(this == SWAMPLAND || this == SWAMPLANDM) {
|
||||
double d0 = COLOR_NOISE.generate((double)pos.getX() * 0.0225D, (double)pos.getZ() * 0.0225D);
|
||||
return d0 < -0.1D ? 5011004 : 6975545;
|
||||
}
|
||||
if(this == ELVENFOREST)
|
||||
return Colorizer.getGrassColor(1.0f, this.humidity * 0.01f);
|
||||
double d0 = (double)ExtMath.clampf((this.getTemperature(pos) + 14.0f) / 40.0f + 0.15f, 0.0F, 1.0F);
|
||||
double d1 = (double)ExtMath.clampf(this.humidity * 0.01f, 0.0F, 1.0F);
|
||||
return this == ROOFEDFOREST || this == ROOFEDFORESTM ? (Colorizer.getGrassColor(d0, d1) & 16711422) + 2634762 >> 1 : Colorizer.getGrassColor(d0, d1);
|
||||
}
|
||||
|
||||
public int getFoliageColorAtPos(BlockPos pos) {
|
||||
if(this.foliageColor != 0xffffffff)
|
||||
return this.foliageColor;
|
||||
if(this == ELVENFOREST)
|
||||
return Colorizer.getFoliageColor(1.0f, this.humidity * 0.01f);
|
||||
double d0 = (double)ExtMath.clampf((this.getTemperature(pos) + 14.0f) / 40.0f + 0.15f, 0.0F, 1.0F);
|
||||
double d1 = (double)ExtMath.clampf(this.humidity * 0.01f, 0.0F, 1.0F);
|
||||
return Colorizer.getFoliageColor(d0, d1);
|
||||
}
|
||||
}
|
47
common/src/main/java/common/biome/IBiome.java
Normal file
47
common/src/main/java/common/biome/IBiome.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.BlockRegistry;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.world.AWorldServer;
|
||||
import common.world.State;
|
||||
|
||||
public interface IBiome {
|
||||
public static abstract class BiomeProvider {
|
||||
private static BiomeProvider provider = new BiomeProvider() {
|
||||
public IBiome getBiome(Biome base) {
|
||||
return new IBiome() {
|
||||
public State getFiller() {
|
||||
return BlockRegistry.getRegisteredBlock("air").getState();
|
||||
}
|
||||
public State getTop() {
|
||||
return BlockRegistry.getRegisteredBlock("air").getState();
|
||||
}
|
||||
public void growGrass(AWorldServer worldIn, BlockPos pos, State state, Random rand) {
|
||||
}
|
||||
public boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand) {
|
||||
return false;
|
||||
}
|
||||
public void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand) {
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
public abstract IBiome getBiome(Biome base);
|
||||
}
|
||||
|
||||
public static void setProvider(BiomeProvider provider) {
|
||||
BiomeProvider.provider = provider;
|
||||
}
|
||||
|
||||
public static IBiome getBiome(Biome base) {
|
||||
return BiomeProvider.provider.getBiome(base);
|
||||
}
|
||||
|
||||
void growGrass(AWorldServer worldIn, BlockPos pos, State state, Random rand);
|
||||
boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand);
|
||||
void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand);
|
||||
State getFiller();
|
||||
State getTop();
|
||||
}
|
1011
common/src/main/java/common/block/Block.java
Executable file
1011
common/src/main/java/common/block/Block.java
Executable file
File diff suppressed because it is too large
Load diff
35
common/src/main/java/common/block/BlockAir.java
Executable file
35
common/src/main/java/common/block/BlockAir.java
Executable file
|
@ -0,0 +1,35 @@
|
|||
package common.block;
|
||||
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public final class BlockAir extends Block {
|
||||
public BlockAir() {
|
||||
super(Material.NONE);
|
||||
}
|
||||
|
||||
public int getRenderType() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World world, BlockPos pos, State state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canCollideCheck(State state, boolean liquid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dropBlockAsItemWithChance(World world, BlockPos pos, State state, float chance, int fortune) {
|
||||
}
|
||||
|
||||
public boolean isReplaceable(World world, BlockPos pos) {
|
||||
return true;
|
||||
}
|
||||
}
|
49
common/src/main/java/common/block/BlockColored.java
Executable file
49
common/src/main/java/common/block/BlockColored.java
Executable file
|
@ -0,0 +1,49 @@
|
|||
package common.block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.color.DyeColor;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockColored extends Block {
|
||||
public static final PropertyEnum<DyeColor> COLOR = PropertyEnum.<DyeColor>create("color", DyeColor.class);
|
||||
|
||||
public BlockColored(Material material) {
|
||||
super(material);
|
||||
this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE));
|
||||
this.setTab(CheatTab.BLOCKS);
|
||||
}
|
||||
|
||||
public int damageDropped(State state) {
|
||||
return state.getValue(COLOR).getMetadata();
|
||||
}
|
||||
|
||||
public void getSubBlocks(Item item, CheatTab tab, List<ItemStack> list) {
|
||||
for(DyeColor color : DyeColor.values()) {
|
||||
list.add(new ItemStack(item, 1, color.getMetadata()));
|
||||
}
|
||||
}
|
||||
|
||||
public State getStateFromMeta(int meta) {
|
||||
return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta));
|
||||
}
|
||||
|
||||
public int getMetaFromState(State state) {
|
||||
return state.getValue(COLOR).getMetadata();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties() {
|
||||
return new IProperty[] {COLOR};
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel(state.getValue(COLOR).getName() + "_" + name).add().all();
|
||||
}
|
||||
}
|
39
common/src/main/java/common/block/BlockContainer.java
Executable file
39
common/src/main/java/common/block/BlockContainer.java
Executable file
|
@ -0,0 +1,39 @@
|
|||
package common.block;
|
||||
|
||||
import common.tileentity.TileEntity;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public abstract class BlockContainer extends Block implements ITileEntityProvider {
|
||||
public BlockContainer(Material material) {
|
||||
super(material);
|
||||
this.hasTile = true;
|
||||
}
|
||||
|
||||
protected boolean isInvalidNeighbor(World world, BlockPos pos, Facing face) {
|
||||
return world.getState(pos.offset(face)).getBlock().getMaterial() == Material.BLOCKING;
|
||||
}
|
||||
|
||||
protected boolean hasInvalidNeighbor(World world, BlockPos pos) {
|
||||
return this.isInvalidNeighbor(world, pos, Facing.NORTH) || this.isInvalidNeighbor(world, pos, Facing.SOUTH)
|
||||
|| this.isInvalidNeighbor(world, pos, Facing.WEST) || this.isInvalidNeighbor(world, pos, Facing.EAST);
|
||||
}
|
||||
|
||||
public int getRenderType() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void onBlockRemoved(AWorldServer world, BlockPos pos, State state) {
|
||||
super.onBlockRemoved(world, pos, state);
|
||||
world.removeTileEntity(pos);
|
||||
}
|
||||
|
||||
public boolean onBlockEventReceived(World world, BlockPos pos, State state, int id, int param) {
|
||||
super.onBlockEventReceived(world, pos, state, id, param);
|
||||
TileEntity tile = world.getTileEntity(pos);
|
||||
return tile == null ? false : tile.receiveClientEvent(id, param);
|
||||
}
|
||||
}
|
12
common/src/main/java/common/block/BlockDirectional.java
Executable file
12
common/src/main/java/common/block/BlockDirectional.java
Executable file
|
@ -0,0 +1,12 @@
|
|||
package common.block;
|
||||
|
||||
import common.properties.PropertyDirection;
|
||||
import common.util.Facing;
|
||||
|
||||
public abstract class BlockDirectional extends Block {
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL);
|
||||
|
||||
public BlockDirectional(Material material) {
|
||||
super(material);
|
||||
}
|
||||
}
|
72
common/src/main/java/common/block/BlockFalling.java
Executable file
72
common/src/main/java/common/block/BlockFalling.java
Executable file
|
@ -0,0 +1,72 @@
|
|||
package common.block;
|
||||
|
||||
import common.block.natural.BlockFire;
|
||||
import common.entity.item.EntityFalling;
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class BlockFalling extends Block {
|
||||
public static boolean fallInstantly;
|
||||
|
||||
public static boolean canFallInto(World world, BlockPos pos) {
|
||||
Block block = world.getState(pos).getBlock();
|
||||
return block instanceof BlockFire || block == Blocks.air || block.getMaterial().isLiquid();
|
||||
}
|
||||
|
||||
public BlockFalling(Material material) {
|
||||
super(material);
|
||||
}
|
||||
|
||||
public void onBlockAdded(AWorldServer world, BlockPos pos, State state) {
|
||||
world.scheduleUpdate(pos, this, this.tickRate(world, pos));
|
||||
}
|
||||
|
||||
public void onNeighborBlockChange(World world, BlockPos pos, State state, Block neighbor) {
|
||||
world.scheduleUpdate(pos, this, this.tickRate(world, pos));
|
||||
}
|
||||
|
||||
public void updateTick(AWorldServer world, BlockPos pos, State state, Random rand) {
|
||||
if(Config.blockGravity)
|
||||
this.checkFallable(world, pos);
|
||||
}
|
||||
|
||||
private void checkFallable(World world, BlockPos pos) {
|
||||
if(canFallInto(world, pos.down()) && pos.getY() >= 0) {
|
||||
int range = 32;
|
||||
if(!fallInstantly && world.isAreaLoaded(pos.add(-range, -range, -range), pos.add(range, range, range))) {
|
||||
if(!world.client) {
|
||||
EntityFalling entity = new EntityFalling(world, (double)pos.getX() + 0.5D, (double)pos.getY(),
|
||||
(double)pos.getZ() + 0.5D, world.getState(pos));
|
||||
this.onStartFalling(entity);
|
||||
world.spawnEntityInWorld(entity);
|
||||
}
|
||||
}
|
||||
else {
|
||||
world.setBlockToAir(pos);
|
||||
BlockPos loc;
|
||||
int limit = 512;
|
||||
for(loc = pos.down(); canFallInto(world, loc) && loc.getY() > -World.MAX_SIZE_Y; loc = loc.down()) {
|
||||
if(--limit <= 0)
|
||||
return;
|
||||
}
|
||||
if(loc.getY() > -World.MAX_SIZE_Y)
|
||||
world.setState(loc.up(), this.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int tickRate(World world, BlockPos pos) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
protected void onStartFalling(EntityFalling entity) {
|
||||
}
|
||||
|
||||
public void onEndFalling(World world, BlockPos pos) {
|
||||
}
|
||||
}
|
32
common/src/main/java/common/block/BlockRotatedPillar.java
Executable file
32
common/src/main/java/common/block/BlockRotatedPillar.java
Executable file
|
@ -0,0 +1,32 @@
|
|||
package common.block;
|
||||
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.util.Facing;
|
||||
import common.world.State;
|
||||
|
||||
public abstract class BlockRotatedPillar extends Block {
|
||||
public static final PropertyEnum<Facing.Axis> AXIS = PropertyEnum.<Facing.Axis>create("axis", Facing.Axis.class);
|
||||
|
||||
public BlockRotatedPillar(Material material) {
|
||||
super(material);
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
switch(state.getValue(AXIS)) {
|
||||
case X:
|
||||
return provider.getModel(name + "_side").add().d().rot(180).u()
|
||||
.n(name + "_top").rot(180).s(name + "_top").w().rot(270)
|
||||
.e().rot(90).rotate(ModelRotation.X0_Y90);
|
||||
case Y:
|
||||
default:
|
||||
return provider.getModel(name + "_side").add().nswe().du(name + "_top");
|
||||
case Z:
|
||||
return provider.getModel(name + "_side").add().d().rot(180).u()
|
||||
.n(name + "_top").rot(180).s(name + "_top").w().rot(270)
|
||||
.e().rot(90);
|
||||
}
|
||||
}
|
||||
}
|
27
common/src/main/java/common/block/BlockTranslucent.java
Executable file
27
common/src/main/java/common/block/BlockTranslucent.java
Executable file
|
@ -0,0 +1,27 @@
|
|||
package common.block;
|
||||
|
||||
import common.model.BlockLayer;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockTranslucent extends Block {
|
||||
public BlockTranslucent(Material material) {
|
||||
super(material);
|
||||
}
|
||||
|
||||
public final boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final BlockLayer getBlockLayer() {
|
||||
return BlockLayer.TRANSLUCENT;
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess world, BlockPos pos, Facing side) {
|
||||
State state = world.getState(pos);
|
||||
Block block = state.getBlock();
|
||||
return block != this && super.shouldSideBeRendered(world, pos, side);
|
||||
}
|
||||
}
|
11
common/src/main/java/common/block/BlockTreasure.java
Executable file
11
common/src/main/java/common/block/BlockTreasure.java
Executable file
|
@ -0,0 +1,11 @@
|
|||
package common.block;
|
||||
|
||||
public class BlockTreasure extends Block {
|
||||
public BlockTreasure(Material material) {
|
||||
super(material);
|
||||
}
|
||||
|
||||
public boolean isXrayVisible() {
|
||||
return true;
|
||||
}
|
||||
}
|
8
common/src/main/java/common/block/ITileEntityProvider.java
Executable file
8
common/src/main/java/common/block/ITileEntityProvider.java
Executable file
|
@ -0,0 +1,8 @@
|
|||
package common.block;
|
||||
|
||||
import common.tileentity.TileEntity;
|
||||
import common.world.World;
|
||||
|
||||
public interface ITileEntityProvider {
|
||||
TileEntity createNewTileEntity(World world);
|
||||
}
|
192
common/src/main/java/common/block/Material.java
Executable file
192
common/src/main/java/common/block/Material.java
Executable file
|
@ -0,0 +1,192 @@
|
|||
package common.block;
|
||||
|
||||
public enum Material {
|
||||
NONE {{
|
||||
this.setNonSolid().setReplaceable();
|
||||
}},
|
||||
LOOSE {{
|
||||
;
|
||||
}},
|
||||
WOOD {{
|
||||
this.setBurning();
|
||||
}},
|
||||
SOLID {{
|
||||
this.setRequiresTool();
|
||||
}},
|
||||
DIGGABLE {{ // can harvest with shovel
|
||||
this.setRequiresTool();
|
||||
}},
|
||||
TRANSLUCENT {{
|
||||
this.setTranslucent();
|
||||
}},
|
||||
BURNABLE {{
|
||||
this.setBurning();
|
||||
}},
|
||||
SOFT {{ // can break faster with sword, can't connect to fences+walls
|
||||
this.setNoPushMobility();
|
||||
}},
|
||||
PISTON {{
|
||||
this.setImmovableMobility();
|
||||
}},
|
||||
HEAVY {{
|
||||
this.setRequiresTool().setImmovableMobility();
|
||||
}},
|
||||
PLANT {{ // can break faster with sword
|
||||
this.setNonSolid().setNoPushMobility();
|
||||
}},
|
||||
SMALL {{ // can be placed more easily
|
||||
this.setNonSolid().setNoPushMobility();
|
||||
}},
|
||||
FLEECE {{
|
||||
this.setNonSolid().setBurning();
|
||||
}},
|
||||
EXPLOSIVE {{
|
||||
this.setBurning().setTranslucent();
|
||||
}},
|
||||
BLOCKING {{ // can't be placed next to signs and banners
|
||||
this.setTranslucent().setNoPushMobility();
|
||||
}},
|
||||
PORTAL {{ // not floodable by liquids
|
||||
this.setNonSolid().setImmovableMobility();
|
||||
}},
|
||||
WATER {{
|
||||
this.setLiquid(false).setReplaceable().setNoPushMobility();
|
||||
}},
|
||||
COLD {{
|
||||
this.setLiquid(false).setReplaceable().setNoPushMobility();
|
||||
}},
|
||||
LAVA {{
|
||||
this.setLiquid(true).setReplaceable().setNoPushMobility();
|
||||
}},
|
||||
HOT {{
|
||||
this.setLiquid(true).setReplaceable().setNoPushMobility();
|
||||
}},
|
||||
LEAVES {{ // can break faster with sword, precipitation block, special treatment in some worldgen
|
||||
this.setBurning().setTranslucent().setNoPushMobility();
|
||||
}},
|
||||
BUSH {{ // can break faster with sword, can be replaced by small tree leaves
|
||||
this.setNonSolid().setBurning().setNoPushMobility().setReplaceable();
|
||||
}},
|
||||
FIRE {{
|
||||
this.setNonSolid().setReplaceable().setNoPushMobility();
|
||||
}},
|
||||
POWDER {{ // can harvest with shovel, precipitation block
|
||||
this.setNonSolid().setReplaceable().setRequiresTool().setNoPushMobility();
|
||||
}},
|
||||
FLUFF {{ // can harvest with shears
|
||||
this.setPassable().setRequiresTool().setNoPushMobility();
|
||||
}};
|
||||
|
||||
private boolean solid = true;
|
||||
private boolean lightOpaque = true;
|
||||
private boolean unpassable = true;
|
||||
private boolean opaque = true;
|
||||
private boolean liquid;
|
||||
private boolean cold;
|
||||
private boolean hot;
|
||||
private boolean burnable;
|
||||
private boolean replaceable;
|
||||
private boolean requiresTool;
|
||||
// 0 - normal; 1 - can't push other blocks; 2 - can't be pushed
|
||||
private int mobility;
|
||||
|
||||
protected Material setTranslucent() {
|
||||
this.opaque = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setNonSolid() {
|
||||
this.solid = false;
|
||||
this.lightOpaque = false;
|
||||
this.unpassable = false;
|
||||
this.opaque = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setPassable() {
|
||||
this.unpassable = false;
|
||||
this.opaque = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setLiquid(boolean hot) {
|
||||
this.solid = false;
|
||||
this.unpassable = false;
|
||||
this.opaque = false;
|
||||
this.liquid = true;
|
||||
if(hot)
|
||||
this.hot = true;
|
||||
else
|
||||
this.cold = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setRequiresTool() {
|
||||
this.requiresTool = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setBurning() {
|
||||
this.burnable = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setReplaceable() {
|
||||
this.replaceable = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setNoPushMobility() {
|
||||
this.mobility = 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Material setImmovableMobility() {
|
||||
this.mobility = 2;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isLiquid() {
|
||||
return this.liquid;
|
||||
}
|
||||
|
||||
public boolean isColdLiquid() {
|
||||
return this.cold;
|
||||
}
|
||||
|
||||
public boolean isHotLiquid() {
|
||||
return this.hot;
|
||||
}
|
||||
|
||||
public boolean isSolid() {
|
||||
return this.solid;
|
||||
}
|
||||
|
||||
public boolean blocksLight() {
|
||||
return this.lightOpaque;
|
||||
}
|
||||
|
||||
public boolean blocksMovement() {
|
||||
return this.unpassable;
|
||||
}
|
||||
|
||||
public boolean getCanBurn() {
|
||||
return this.burnable;
|
||||
}
|
||||
|
||||
public boolean isReplaceable() {
|
||||
return this.replaceable;
|
||||
}
|
||||
|
||||
public boolean isOpaque() {
|
||||
return this.opaque;
|
||||
}
|
||||
|
||||
public boolean isToolRequired() {
|
||||
return this.requiresTool;
|
||||
}
|
||||
|
||||
public int getMobility() {
|
||||
return this.mobility;
|
||||
}
|
||||
}
|
47
common/src/main/java/common/block/SoundType.java
Executable file
47
common/src/main/java/common/block/SoundType.java
Executable file
|
@ -0,0 +1,47 @@
|
|||
package common.block;
|
||||
|
||||
import common.init.SoundEvent;
|
||||
|
||||
public enum SoundType {
|
||||
STONE(SoundEvent.STONE),
|
||||
WOOD(SoundEvent.WOOD),
|
||||
GRAVEL(SoundEvent.GRAVEL),
|
||||
SAND(SoundEvent.SAND),
|
||||
GRASS(SoundEvent.GRASS),
|
||||
SNOW(SoundEvent.SNOW),
|
||||
CLOTH(SoundEvent.CLOTH),
|
||||
SLIME(SoundEvent.SLIME_BIG, SoundEvent.SLIME_SMALL),
|
||||
ANVIL(SoundEvent.STONE, SoundEvent.ANVIL_LAND, SoundEvent.STONE),
|
||||
LADDER(SoundEvent.WOOD, null),
|
||||
GLASS(SoundEvent.GLASS, SoundEvent.STONE, SoundEvent.STONE);
|
||||
|
||||
private final SoundEvent breakSound;
|
||||
private final SoundEvent placeSound;
|
||||
private final SoundEvent stepSound;
|
||||
|
||||
private SoundType(SoundEvent breakSound, SoundEvent placeSound, SoundEvent stepSound) {
|
||||
this.breakSound = breakSound;
|
||||
this.placeSound = placeSound;
|
||||
this.stepSound = stepSound;
|
||||
}
|
||||
|
||||
private SoundType(SoundEvent breakPlaceSound, SoundEvent stepSound) {
|
||||
this(breakPlaceSound, breakPlaceSound, stepSound);
|
||||
}
|
||||
|
||||
private SoundType(SoundEvent sound) {
|
||||
this(sound, sound, sound);
|
||||
}
|
||||
|
||||
public SoundEvent getBreakSound() {
|
||||
return this.breakSound;
|
||||
}
|
||||
|
||||
public SoundEvent getPlaceSound() {
|
||||
return this.placeSound;
|
||||
}
|
||||
|
||||
public SoundEvent getStepSound() {
|
||||
return this.stepSound;
|
||||
}
|
||||
}
|
209
common/src/main/java/common/block/artificial/BlockBed.java
Executable file
209
common/src/main/java/common/block/artificial/BlockBed.java
Executable file
|
@ -0,0 +1,209 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockDirectional;
|
||||
import common.block.Material;
|
||||
import common.color.DyeColor;
|
||||
import common.color.TextColor;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.ItemRegistry;
|
||||
import common.item.Item;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.util.Identifyable;
|
||||
import common.util.WorldPos;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockBed extends BlockDirectional {
|
||||
public static enum EnumPartType implements Identifyable {
|
||||
HEAD("head"), FOOT("foot");
|
||||
|
||||
private final String name;
|
||||
|
||||
private EnumPartType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
public static final PropertyEnum<BlockBed.EnumPartType> PART =
|
||||
PropertyEnum.<BlockBed.EnumPartType>create("part", BlockBed.EnumPartType.class);
|
||||
public static final DyeColor[] COLORS = new DyeColor[]
|
||||
{DyeColor.RED, DyeColor.WHITE, DyeColor.BLACK, DyeColor.PURPLE};
|
||||
|
||||
private final DyeColor color;
|
||||
|
||||
public BlockBed(DyeColor color) {
|
||||
super(Material.BURNABLE);
|
||||
this.color = color;
|
||||
this.setDefaultState(this.getBaseState().withProperty(PART, BlockBed.EnumPartType.FOOT));
|
||||
this.setBedBounds();
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World world, BlockPos pos, State state, EntityNPC player, Facing side,
|
||||
float hitX, float hitY, float hitZ) {
|
||||
if(world.client)
|
||||
return true;
|
||||
if(state.getValue(PART) != BlockBed.EnumPartType.HEAD) {
|
||||
pos = pos.offset((Facing)state.getValue(FACING));
|
||||
state = world.getState(pos);
|
||||
if(state.getBlock() != this) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(player.isEntityAlive() && Math.abs(player.posX - (double)pos.getX()) <= 3.0D
|
||||
&& Math.abs(player.posY - (double)pos.getY()) <= 2.0D && Math.abs(player.posZ - (double)pos.getZ()) <= 3.0D) {
|
||||
player.setSpawnPoint(new WorldPos(pos, player.worldObj.dimension.getDimensionId()));
|
||||
player.connection.addHotbar(TextColor.DGREEN + "Dein Einstiegspunkt wurde auf %s bei [%s, %s, %s] gesetzt",
|
||||
player.worldObj.dimension.getFormattedName(false), player.getSpawnPoint().getX(),
|
||||
player.getSpawnPoint().getY(), player.getSpawnPoint().getZ());
|
||||
}
|
||||
// else if(!Config.bedSpawn) {
|
||||
// world.destroyBlock(pos, true);
|
||||
// BlockPos blockpos = pos.offset(((Facing)state.getValue(FACING)).getOpposite());
|
||||
// if(world.getState(blockpos).getBlock() == this)
|
||||
// world.destroyBlock(blockpos, true);
|
||||
// world.newExplosion(null, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, 0.0F,
|
||||
// false, false, true);
|
||||
// ((EntityNPCMP)player).addFeed(TextColor.DARK_RED + "Der Einstiegspunkt kann nicht gesetzt werden");
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isFullCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos) {
|
||||
this.setBedBounds();
|
||||
}
|
||||
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock) {
|
||||
Facing enumfacing = (Facing)state.getValue(FACING);
|
||||
if(state.getValue(PART) == BlockBed.EnumPartType.HEAD) {
|
||||
if(worldIn.getState(pos.offset(enumfacing.getOpposite())).getBlock() != this)
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
else if(worldIn.getState(pos.offset(enumfacing)).getBlock() != this) {
|
||||
worldIn.setBlockToAir(pos);
|
||||
if(!worldIn.client)
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public Item getItemDropped(State state, Random rand, int fortune) {
|
||||
return state.getValue(PART) == BlockBed.EnumPartType.HEAD ? null : ItemRegistry.getRegisteredItem(this.color.getName() + "_bed");
|
||||
}
|
||||
|
||||
private void setBedBounds() {
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5625F, 1.0F);
|
||||
}
|
||||
|
||||
public static BlockPos getSafeExitLocation(World worldIn, BlockPos pos, int tries) {
|
||||
Facing enumfacing = (Facing)worldIn.getState(pos).getValue(FACING);
|
||||
int i = pos.getX();
|
||||
int j = pos.getY();
|
||||
int k = pos.getZ();
|
||||
|
||||
for(int l = 0; l <= 1; ++l) {
|
||||
int i1 = i - enumfacing.getFrontOffsetX() * l - 1;
|
||||
int j1 = k - enumfacing.getFrontOffsetZ() * l - 1;
|
||||
int k1 = i1 + 2;
|
||||
int l1 = j1 + 2;
|
||||
|
||||
for(int i2 = i1; i2 <= k1; ++i2) {
|
||||
for(int j2 = j1; j2 <= l1; ++j2) {
|
||||
BlockPos blockpos = new BlockPos(i2, j, j2);
|
||||
|
||||
if(hasRoomForPlayer(worldIn, blockpos)) {
|
||||
if(tries <= 0) {
|
||||
return blockpos;
|
||||
}
|
||||
|
||||
--tries;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static boolean hasRoomForPlayer(World worldIn, BlockPos pos) {
|
||||
return worldIn.isBlockSolid(pos.down()) && !worldIn.getState(pos).getBlock().getMaterial().isSolid()
|
||||
&& !worldIn.getState(pos.up()).getBlock().getMaterial().isSolid();
|
||||
}
|
||||
|
||||
public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune) {
|
||||
if(state.getValue(PART) == BlockBed.EnumPartType.FOOT)
|
||||
super.dropBlockAsItemWithChance(worldIn, pos, state, chance, 0);
|
||||
}
|
||||
|
||||
public int getMobilityFlag() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer() {
|
||||
return BlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
public Item getItem(World worldIn, BlockPos pos) {
|
||||
return ItemRegistry.getRegisteredItem(this.color.getName() + "_bed");
|
||||
}
|
||||
|
||||
// public void onBlockHarvested(World worldIn, BlockPos pos, State state, EntityNPC player) {
|
||||
// if(player.creative && state.getValue(PART) == BlockBed.EnumPartType.HEAD) {
|
||||
// BlockPos blockpos = pos.offset(((Facing)state.getValue(FACING)).getOpposite());
|
||||
// if(worldIn.getState(blockpos).getBlock() == this)
|
||||
// worldIn.setBlockToAir(blockpos);
|
||||
// }
|
||||
// }
|
||||
|
||||
public State getStateFromMeta(int meta) {
|
||||
return this.getState().withProperty(PART, (meta & 8) > 0 ? BlockBed.EnumPartType.HEAD : BlockBed.EnumPartType.FOOT)
|
||||
.withProperty(FACING, Facing.getHorizontal(meta));
|
||||
}
|
||||
|
||||
public int getMetaFromState(State state) {
|
||||
return ((Facing)state.getValue(FACING)).getHorizontalIndex() | (state.getValue(PART) == BlockBed.EnumPartType.HEAD ? 8 : 0);
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties() {
|
||||
return new IProperty[] {FACING, PART};
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
if(state.getValue(PART) == EnumPartType.HEAD)
|
||||
return provider.getModel(this.color + "_bed_head_top").add(0, 0, 0, 16, 9, 16)
|
||||
.u().rot(90).noCull().s(this.color + "_bed_head_end").noCull()
|
||||
.w(this.color + "_bed_head_side").uv(0, 7, 16, 16).noCull().e(this.color + "_bed_head_side").uv(16, 7, 0, 16).noCull()
|
||||
.add(0, 3, 0, 16, 3, 16)
|
||||
.d("oak_planks").noCull().rotate(ModelRotation.getNorthRot(state.getValue(FACING).getOpposite()));
|
||||
else
|
||||
return provider.getModel(this.color + "_bed_foot_top").add(0, 0, 0, 16, 9, 16)
|
||||
.u().rot(90).noCull().n(this.color + "_bed_foot_end").noCull()
|
||||
.w(this.color + "_bed_foot_side").uv(0, 7, 16, 16).noCull().e(this.color + "_bed_foot_side").uv(16, 7, 0, 16).noCull()
|
||||
.add(0, 3, 0, 16, 3, 16)
|
||||
.d("oak_planks").noCull().rotate(ModelRotation.getNorthRot(state.getValue(FACING).getOpposite()));
|
||||
}
|
||||
}
|
40
common/src/main/java/common/block/artificial/BlockBookshelf.java
Executable file
40
common/src/main/java/common/block/artificial/BlockBookshelf.java
Executable file
|
@ -0,0 +1,40 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.init.Items;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.rng.Random;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockBookshelf extends Block
|
||||
{
|
||||
public BlockBookshelf()
|
||||
{
|
||||
super(Material.WOOD);
|
||||
this.setTab(CheatTab.DECORATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quantity of items to drop on block destruction.
|
||||
*/
|
||||
public int quantityDropped(Random random)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Item that this Block should drop when harvested.
|
||||
*/
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return Items.book;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel("bookshelf").add().nswe().du("oak_planks");
|
||||
}
|
||||
}
|
249
common/src/main/java/common/block/artificial/BlockCake.java
Executable file
249
common/src/main/java/common/block/artificial/BlockCake.java
Executable file
|
@ -0,0 +1,249 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Items;
|
||||
import common.item.Item;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyInteger;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockCake extends Block
|
||||
{
|
||||
private static final Model cake_slice3 = ModelProvider.getModelProvider().getModel("cake_side")
|
||||
.add(7, 0, 1, 15, 8, 15)
|
||||
.d("cake_bottom").uv(7, 1, 15, 15)
|
||||
.u("cake_top").uv(7, 1, 15, 15).noCull()
|
||||
.n().uv(1, 8, 9, 16).noCull()
|
||||
.s().uv(1, 8, 9, 16).noCull()
|
||||
.w("cake_inner").uv(1, 8, 15, 16).noCull()
|
||||
.e().uv(1, 8, 15, 16).noCull()
|
||||
;
|
||||
private static final Model cake_slice1 = ModelProvider.getModelProvider().getModel("cake_side")
|
||||
.add(3, 0, 1, 15, 8, 15)
|
||||
.d("cake_bottom").uv(3, 1, 15, 15)
|
||||
.u("cake_top").uv(3, 1, 15, 15).noCull()
|
||||
.n().uv(1, 8, 13, 16).noCull()
|
||||
.s().uv(1, 8, 13, 16).noCull()
|
||||
.w("cake_inner").uv(1, 8, 15, 16).noCull()
|
||||
.e().uv(1, 8, 15, 16).noCull()
|
||||
;
|
||||
private static final Model cake_slice2 = ModelProvider.getModelProvider().getModel("cake_side")
|
||||
.add(5, 0, 1, 15, 8, 15)
|
||||
.d("cake_bottom").uv(5, 1, 15, 15)
|
||||
.u("cake_top").uv(5, 1, 15, 15).noCull()
|
||||
.n().uv(1, 8, 11, 16).noCull()
|
||||
.s().uv(1, 8, 11, 16).noCull()
|
||||
.w("cake_inner").uv(1, 8, 15, 16).noCull()
|
||||
.e().uv(1, 8, 15, 16).noCull()
|
||||
;
|
||||
private static final Model cake_slice5 = ModelProvider.getModelProvider().getModel("cake_side")
|
||||
.add(11, 0, 1, 15, 8, 15)
|
||||
.d("cake_bottom").uv(11, 1, 15, 15)
|
||||
.u("cake_top").uv(11, 1, 15, 15).noCull()
|
||||
.n().uv(1, 8, 5, 16).noCull()
|
||||
.s().uv(1, 8, 5, 16).noCull()
|
||||
.w("cake_inner").uv(1, 8, 15, 16).noCull()
|
||||
.e().uv(1, 8, 15, 16).noCull()
|
||||
;
|
||||
private static final Model cake_slice4 = ModelProvider.getModelProvider().getModel("cake_side")
|
||||
.add(9, 0, 1, 15, 8, 15)
|
||||
.d("cake_bottom").uv(9, 1, 15, 15)
|
||||
.u("cake_top").uv(9, 1, 15, 15).noCull()
|
||||
.n().uv(1, 8, 7, 16).noCull()
|
||||
.s().uv(1, 8, 7, 16).noCull()
|
||||
.w("cake_inner").uv(1, 8, 15, 16).noCull()
|
||||
.e().uv(1, 8, 15, 16).noCull()
|
||||
;
|
||||
private static final Model cake_uneaten = ModelProvider.getModelProvider().getModel("cake_side")
|
||||
.add(1, 0, 1, 15, 8, 15)
|
||||
.d("cake_bottom").uv(1, 1, 15, 15)
|
||||
.u("cake_top").uv(1, 1, 15, 15).noCull()
|
||||
.n().uv(1, 8, 15, 16).noCull()
|
||||
.s().uv(1, 8, 15, 16).noCull()
|
||||
.w().uv(1, 8, 15, 16).noCull()
|
||||
.e().uv(1, 8, 15, 16).noCull()
|
||||
;
|
||||
private static final Model cake_slice6 = ModelProvider.getModelProvider().getModel("cake_side")
|
||||
.add(13, 0, 1, 15, 8, 15)
|
||||
.d("cake_bottom").uv(13, 1, 15, 15)
|
||||
.u("cake_top").uv(13, 1, 15, 15).noCull()
|
||||
.n().uv(1, 8, 3, 16).noCull()
|
||||
.s().uv(1, 8, 3, 16).noCull()
|
||||
.w("cake_inner").uv(1, 8, 15, 16).noCull()
|
||||
.e().uv(1, 8, 15, 16).noCull()
|
||||
;
|
||||
private static final Model[] cake_slices =
|
||||
new Model[] {cake_uneaten, cake_slice1, cake_slice2, cake_slice3, cake_slice4, cake_slice5, cake_slice6};
|
||||
|
||||
public static final PropertyInteger BITES = PropertyInteger.create("bites", 0, 6);
|
||||
|
||||
public BlockCake()
|
||||
{
|
||||
super(Material.SOFT);
|
||||
this.setDefaultState(this.getBaseState().withProperty(BITES, Integer.valueOf(0)));
|
||||
// this.setTickRandomly(true);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
float f = 0.0625F;
|
||||
float f1 = (float)(1 + ((Integer)worldIn.getState(pos).getValue(BITES)).intValue() * 2) / 16.0F;
|
||||
float f2 = 0.5F;
|
||||
this.setBlockBounds(f1, 0.0F, f, 1.0F - f, f2, 1.0F - f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block's bounds for rendering it as an item
|
||||
*/
|
||||
public void setBlockBoundsForItemRender()
|
||||
{
|
||||
float f = 0.0625F;
|
||||
float f1 = 0.5F;
|
||||
this.setBlockBounds(f, 0.0F, f, 1.0F - f, f1, 1.0F - f);
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
float f = 0.0625F;
|
||||
float f1 = (float)(1 + ((Integer)state.getValue(BITES)).intValue() * 2) / 16.0F;
|
||||
float f2 = 0.5F;
|
||||
return new BoundingBox((double)((float)pos.getX() + f1), (double)pos.getY(), (double)((float)pos.getZ() + f), (double)((float)(pos.getX() + 1) - f), (double)((float)pos.getY() + f2), (double)((float)(pos.getZ() + 1) - f));
|
||||
}
|
||||
|
||||
public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos)
|
||||
{
|
||||
return this.getCollisionBoundingBox(worldIn, pos, worldIn.getState(pos));
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
this.eatCake(worldIn, pos, state, playerIn);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onBlockClicked(World worldIn, BlockPos pos, EntityNPC playerIn)
|
||||
{
|
||||
this.eatCake(worldIn, pos, worldIn.getState(pos), playerIn);
|
||||
}
|
||||
|
||||
private void eatCake(World worldIn, BlockPos pos, State state, EntityNPC player)
|
||||
{
|
||||
// player.triggerAchievement(StatRegistry.cakeEatenStat);
|
||||
int i = ((Integer)state.getValue(BITES)).intValue();
|
||||
|
||||
if (i < 6)
|
||||
{
|
||||
worldIn.setState(pos, state.withProperty(BITES, Integer.valueOf(i + 1)), 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return super.canPlaceBlockAt(worldIn, pos) ? this.canBlockStay(worldIn, pos) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
if (!this.canBlockStay(worldIn, pos))
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canBlockStay(World worldIn, BlockPos pos)
|
||||
{
|
||||
return worldIn.getState(pos.down()).getBlock().getMaterial().isSolid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quantity of items to drop on block destruction.
|
||||
*/
|
||||
public int quantityDropped(Random random)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Item that this Block should drop when harvested.
|
||||
*/
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Item getItem(World worldIn, BlockPos pos)
|
||||
{
|
||||
return Items.cake;
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return BlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(BITES, Integer.valueOf(meta > 6 ? 0 : meta));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((Integer)state.getValue(BITES)).intValue();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {BITES};
|
||||
}
|
||||
|
||||
public int getComparatorInputOverride(World worldIn, BlockPos pos)
|
||||
{
|
||||
return (7 - ((Integer)worldIn.getState(pos).getValue(BITES)).intValue()) * 2;
|
||||
}
|
||||
|
||||
public boolean hasComparatorInputOverride()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return cake_slices[state.getValue(BITES)];
|
||||
}
|
||||
}
|
162
common/src/main/java/common/block/artificial/BlockCarpet.java
Executable file
162
common/src/main/java/common/block/artificial/BlockCarpet.java
Executable file
|
@ -0,0 +1,162 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.color.DyeColor;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.Transforms;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockCarpet extends Block
|
||||
{
|
||||
public static final PropertyEnum<DyeColor> COLOR = PropertyEnum.<DyeColor>create("color", DyeColor.class);
|
||||
|
||||
public BlockCarpet()
|
||||
{
|
||||
super(Material.FLEECE);
|
||||
this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE));
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F);
|
||||
// this.setTickRandomly(true);
|
||||
this.setTab(CheatTab.DECORATION);
|
||||
this.setBlockBoundsFromMeta(0);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the MapColor for this Block and the given BlockState
|
||||
// */
|
||||
// public MapColor getMapColor(IBlockState state)
|
||||
// {
|
||||
// return ((EnumDyeColor)state.getValue(COLOR)).getMapColor();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block's bounds for rendering it as an item
|
||||
*/
|
||||
public void setBlockBoundsForItemRender()
|
||||
{
|
||||
this.setBlockBoundsFromMeta(0);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
this.setBlockBoundsFromMeta(0);
|
||||
}
|
||||
|
||||
protected void setBlockBoundsFromMeta(int meta)
|
||||
{
|
||||
int i = 0;
|
||||
float f = (float)(1 * (1 + i)) / 16.0F;
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F);
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return super.canPlaceBlockAt(worldIn, pos) && this.canBlockStay(worldIn, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
this.checkForDrop(worldIn, pos, state);
|
||||
}
|
||||
|
||||
private boolean checkForDrop(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
if (!this.canBlockStay(worldIn, pos))
|
||||
{
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
worldIn.setBlockToAir(pos);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canBlockStay(World worldIn, BlockPos pos)
|
||||
{
|
||||
return !worldIn.isAirBlock(pos.down());
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
return side == Facing.UP ? true : super.shouldSideBeRendered(worldIn, pos, side);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It
|
||||
* returns the metadata of the dropped item based on the old metadata of the block.
|
||||
*/
|
||||
public int damageDropped(State state)
|
||||
{
|
||||
return ((DyeColor)state.getValue(COLOR)).getMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
|
||||
*/
|
||||
public void getSubBlocks(Item itemIn, CheatTab tab, List<ItemStack> list)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
list.add(new ItemStack(itemIn, 1, i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((DyeColor)state.getValue(COLOR)).getMetadata();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {COLOR};
|
||||
}
|
||||
|
||||
public Transforms getTransform() {
|
||||
return Transforms.LAYER;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel(state.getValue(COLOR).getName() + "_wool").add(0, 0, 0, 16, 1, 16).nswe().uv(0, 15, 16, 16).d().u().noCull();
|
||||
}
|
||||
}
|
33
common/src/main/java/common/block/artificial/BlockCompressedPowered.java
Executable file
33
common/src/main/java/common/block/artificial/BlockCompressedPowered.java
Executable file
|
@ -0,0 +1,33 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockCompressedPowered extends Block
|
||||
{
|
||||
public BlockCompressedPowered(Material p_i46386_1_)
|
||||
{
|
||||
super(p_i46386_1_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this block provide power. Only wire currently seems to have this change based on its state.
|
||||
*/
|
||||
public boolean canProvidePower()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getWeakPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side)
|
||||
{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return true;
|
||||
}
|
||||
}
|
538
common/src/main/java/common/block/artificial/BlockDoor.java
Executable file
538
common/src/main/java/common/block/artificial/BlockDoor.java
Executable file
|
@ -0,0 +1,538 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.collect.Lists;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Blocks;
|
||||
import common.init.Items;
|
||||
import common.item.Item;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyBool;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.util.HitPosition;
|
||||
import common.util.Identifyable;
|
||||
import common.util.Vec3;
|
||||
import common.world.IBlockAccess;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockDoor extends Block
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL);
|
||||
public static final PropertyBool OPEN = PropertyBool.create("open");
|
||||
public static final PropertyEnum<BlockDoor.EnumHingePosition> HINGE = PropertyEnum.<BlockDoor.EnumHingePosition>create("hinge", BlockDoor.EnumHingePosition.class);
|
||||
public static final PropertyBool POWERED = PropertyBool.create("powered");
|
||||
public static final PropertyEnum<BlockDoor.EnumDoorHalf> HALF = PropertyEnum.<BlockDoor.EnumDoorHalf>create("half", BlockDoor.EnumDoorHalf.class);
|
||||
public static final List<BlockDoor> DOORS = Lists.newArrayList();
|
||||
|
||||
public BlockDoor(Material materialIn)
|
||||
{
|
||||
super(materialIn);
|
||||
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(OPEN, Boolean.valueOf(false)).withProperty(HINGE, BlockDoor.EnumHingePosition.LEFT).withProperty(POWERED, Boolean.valueOf(false)).withProperty(HALF, BlockDoor.EnumDoorHalf.LOWER));
|
||||
DOORS.add(this);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Gets the localized name of this block. Used for the statistics page.
|
||||
// */
|
||||
// public String getLocalizedName()
|
||||
// {
|
||||
// return Strs.get((this.getUnlocalizedName() + ".name").replaceAll("tile", "item"));
|
||||
// }
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPassable(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return isOpen(combineMetadata(worldIn, pos));
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState(worldIn, pos);
|
||||
return super.getSelectedBoundingBox(worldIn, pos);
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState(worldIn, pos);
|
||||
return super.getCollisionBoundingBox(worldIn, pos, state);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
this.setBoundBasedOnMeta(combineMetadata(worldIn, pos));
|
||||
}
|
||||
|
||||
private void setBoundBasedOnMeta(int combinedMeta)
|
||||
{
|
||||
float f = 0.1875F;
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 2.0F, 1.0F);
|
||||
Facing enumfacing = getFacing(combinedMeta);
|
||||
boolean flag = isOpen(combinedMeta);
|
||||
boolean flag1 = isHingeLeft(combinedMeta);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
if (enumfacing == Facing.EAST)
|
||||
{
|
||||
if (!flag1)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.SOUTH)
|
||||
{
|
||||
if (!flag1)
|
||||
{
|
||||
this.setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.WEST)
|
||||
{
|
||||
if (!flag1)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.NORTH)
|
||||
{
|
||||
if (!flag1)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.EAST)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
|
||||
}
|
||||
else if (enumfacing == Facing.SOUTH)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
|
||||
}
|
||||
else if (enumfacing == Facing.WEST)
|
||||
{
|
||||
this.setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
else if (enumfacing == Facing.NORTH)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
if (this.material == Material.SOLID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos = state.getValue(HALF) == BlockDoor.EnumDoorHalf.LOWER ? pos : pos.down();
|
||||
State iblockstate = pos.equals(blockpos) ? state : worldIn.getState(blockpos);
|
||||
|
||||
if (iblockstate.getBlock() != this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = iblockstate.cycleProperty(OPEN);
|
||||
worldIn.setState(blockpos, state, 2);
|
||||
worldIn.markBlockRangeForRenderUpdate(blockpos, pos);
|
||||
worldIn.playAuxSFX(playerIn, ((Boolean)state.getValue(OPEN)).booleanValue() ? 1003 : 1006, pos, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleDoor(World worldIn, BlockPos pos, boolean open)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
|
||||
if (iblockstate.getBlock() == this)
|
||||
{
|
||||
BlockPos blockpos = iblockstate.getValue(HALF) == BlockDoor.EnumDoorHalf.LOWER ? pos : pos.down();
|
||||
State iblockstate1 = pos == blockpos ? iblockstate : worldIn.getState(blockpos);
|
||||
|
||||
if (iblockstate1.getBlock() == this && ((Boolean)iblockstate1.getValue(OPEN)).booleanValue() != open)
|
||||
{
|
||||
worldIn.setState(blockpos, iblockstate1.withProperty(OPEN, Boolean.valueOf(open)), 2);
|
||||
worldIn.markBlockRangeForRenderUpdate(blockpos, pos);
|
||||
worldIn.playAuxSFX(open ? 1003 : 1006, pos, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
if (state.getValue(HALF) == BlockDoor.EnumDoorHalf.UPPER)
|
||||
{
|
||||
BlockPos blockpos = pos.down();
|
||||
State iblockstate = worldIn.getState(blockpos);
|
||||
|
||||
if (iblockstate.getBlock() != this)
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
else if (neighborBlock != this)
|
||||
{
|
||||
this.onNeighborBlockChange(worldIn, blockpos, iblockstate, neighborBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean flag1 = false;
|
||||
BlockPos blockpos1 = pos.up();
|
||||
State iblockstate1 = worldIn.getState(blockpos1);
|
||||
|
||||
if (iblockstate1.getBlock() != this)
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
flag1 = true;
|
||||
}
|
||||
|
||||
if (!worldIn.isBlockSolid(pos.down()))
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
flag1 = true;
|
||||
|
||||
if (iblockstate1.getBlock() == this)
|
||||
{
|
||||
worldIn.setBlockToAir(blockpos1);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
if (!worldIn.client)
|
||||
{
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean flag = worldIn.isBlockPowered(pos) || worldIn.isBlockPowered(blockpos1);
|
||||
|
||||
if ((flag || neighborBlock.canProvidePower()) && neighborBlock != this && flag != ((Boolean)iblockstate1.getValue(POWERED)).booleanValue())
|
||||
{
|
||||
worldIn.setState(blockpos1, iblockstate1.withProperty(POWERED, Boolean.valueOf(flag)), 2);
|
||||
|
||||
if (flag != ((Boolean)state.getValue(OPEN)).booleanValue())
|
||||
{
|
||||
worldIn.setState(pos, state.withProperty(OPEN, Boolean.valueOf(flag)), 2);
|
||||
worldIn.markBlockRangeForRenderUpdate(pos, pos);
|
||||
worldIn.playAuxSFX(flag ? 1003 : 1006, pos, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Item that this Block should drop when harvested.
|
||||
*/
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return state.getValue(HALF) == BlockDoor.EnumDoorHalf.UPPER ? null : this.getItem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ray traces through the blocks collision from start vector to end vector returning a ray trace hit.
|
||||
*/
|
||||
public HitPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState(worldIn, pos);
|
||||
return super.collisionRayTrace(worldIn, pos, start, end);
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return pos.getY() >= World.MAX_SIZE_Y - 1 ? false : worldIn.isBlockSolid(pos.down()) && super.canPlaceBlockAt(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos.up());
|
||||
}
|
||||
|
||||
public int getMobilityFlag()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int combineMetadata(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
int i = iblockstate.getBlock().getMetaFromState(iblockstate);
|
||||
boolean flag = isTop(i);
|
||||
State iblockstate1 = worldIn.getState(pos.down());
|
||||
int j = iblockstate1.getBlock().getMetaFromState(iblockstate1);
|
||||
int k = flag ? j : i;
|
||||
State iblockstate2 = worldIn.getState(pos.up());
|
||||
int l = iblockstate2.getBlock().getMetaFromState(iblockstate2);
|
||||
int i1 = flag ? i : l;
|
||||
boolean flag1 = (i1 & 1) != 0;
|
||||
boolean flag2 = (i1 & 2) != 0;
|
||||
return removeHalfBit(k) | (flag ? 8 : 0) | (flag1 ? 16 : 0) | (flag2 ? 32 : 0);
|
||||
}
|
||||
|
||||
public Item getItem(World worldIn, BlockPos pos)
|
||||
{
|
||||
return this.getItem();
|
||||
}
|
||||
|
||||
private Item getItem()
|
||||
{
|
||||
return this == Blocks.iron_door ? Items.iron_door : (this == Blocks.spruce_door ? Items.spruce_door : (this == Blocks.birch_door ? Items.birch_door : (this == Blocks.jungle_door ? Items.jungle_door : (this == Blocks.acacia_door ? Items.acacia_door : (this == Blocks.dark_oak_door ? Items.dark_oak_door : (this == Blocks.cherry_door ? Items.cherry_door : (this == Blocks.maple_door ? Items.maple_door : Items.oak_door)))))));
|
||||
}
|
||||
|
||||
// public void onBlockHarvested(World worldIn, BlockPos pos, State state, EntityNPC player)
|
||||
// {
|
||||
// BlockPos blockpos = pos.down();
|
||||
//
|
||||
// if (player.creative && state.getValue(HALF) == BlockDoor.EnumDoorHalf.UPPER && worldIn.getState(blockpos).getBlock() == this)
|
||||
// {
|
||||
// worldIn.setBlockToAir(blockpos);
|
||||
// }
|
||||
// }
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return BlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual Block state of this Block at the given position. This applies properties not visible in the
|
||||
* metadata, such as fence connections.
|
||||
*/
|
||||
public State getActualState(State state, IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
if (state.getValue(HALF) == BlockDoor.EnumDoorHalf.LOWER)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos.up());
|
||||
|
||||
if (iblockstate.getBlock() == this)
|
||||
{
|
||||
state = state.withProperty(HINGE, iblockstate.getValue(HINGE)).withProperty(POWERED, iblockstate.getValue(POWERED));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
State iblockstate1 = worldIn.getState(pos.down());
|
||||
|
||||
if (iblockstate1.getBlock() == this)
|
||||
{
|
||||
state = state.withProperty(FACING, iblockstate1.getValue(FACING)).withProperty(OPEN, iblockstate1.getValue(OPEN));
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return (meta & 8) > 0 ? this.getState().withProperty(HALF, BlockDoor.EnumDoorHalf.UPPER).withProperty(HINGE, (meta & 1) > 0 ? BlockDoor.EnumHingePosition.RIGHT : BlockDoor.EnumHingePosition.LEFT).withProperty(POWERED, Boolean.valueOf((meta & 2) > 0)) : this.getState().withProperty(HALF, BlockDoor.EnumDoorHalf.LOWER).withProperty(FACING, Facing.getHorizontal(meta & 3).rotateYCCW()).withProperty(OPEN, Boolean.valueOf((meta & 4) > 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (state.getValue(HALF) == BlockDoor.EnumDoorHalf.UPPER)
|
||||
{
|
||||
i = i | 8;
|
||||
|
||||
if (state.getValue(HINGE) == BlockDoor.EnumHingePosition.RIGHT)
|
||||
{
|
||||
i |= 1;
|
||||
}
|
||||
|
||||
if (((Boolean)state.getValue(POWERED)).booleanValue())
|
||||
{
|
||||
i |= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = i | ((Facing)state.getValue(FACING)).rotateY().getHorizontalIndex();
|
||||
|
||||
if (((Boolean)state.getValue(OPEN)).booleanValue())
|
||||
{
|
||||
i |= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
protected static int removeHalfBit(int meta)
|
||||
{
|
||||
return meta & 7;
|
||||
}
|
||||
|
||||
public static boolean isOpen(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return isOpen(combineMetadata(worldIn, pos));
|
||||
}
|
||||
|
||||
public static Facing getFacing(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return getFacing(combineMetadata(worldIn, pos));
|
||||
}
|
||||
|
||||
public static Facing getFacing(int combinedMeta)
|
||||
{
|
||||
return Facing.getHorizontal(combinedMeta & 3).rotateYCCW();
|
||||
}
|
||||
|
||||
protected static boolean isOpen(int combinedMeta)
|
||||
{
|
||||
return (combinedMeta & 4) != 0;
|
||||
}
|
||||
|
||||
protected static boolean isTop(int meta)
|
||||
{
|
||||
return (meta & 8) != 0;
|
||||
}
|
||||
|
||||
protected static boolean isHingeLeft(int combinedMeta)
|
||||
{
|
||||
return (combinedMeta & 16) != 0;
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {HALF, FACING, OPEN, HINGE, POWERED};
|
||||
}
|
||||
|
||||
private static ModelRotation getRotation(Facing rot, int offset) {
|
||||
return ModelRotation.getEastRot(Facing.getHorizontal(rot.getHorizontalIndex() + offset), false);
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
String bottom = name + "_bottom";
|
||||
String top = name + "_top";
|
||||
if(state.getValue(HALF) == EnumDoorHalf.LOWER) {
|
||||
if(state.getValue(HINGE) == EnumHingePosition.LEFT == state.getValue(OPEN))
|
||||
return provider.getModel(bottom).noOcclude()
|
||||
.add(0, 0, 0, 3, 16, 16)
|
||||
.d().uv(13, 0, 16, 16)
|
||||
.n().uv(3, 0, 0, 16)
|
||||
.s().uv(0, 0, 3, 16)
|
||||
.w().uv(16, 0, 0, 16)
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.rotate(getRotation(state.getValue(FACING), state.getValue(OPEN) ? 1 : 0));
|
||||
else
|
||||
return provider.getModel(bottom).noOcclude()
|
||||
.add(0, 0, 0, 3, 16, 16)
|
||||
.d().uv(13, 0, 16, 16)
|
||||
.n().uv(3, 0, 0, 16)
|
||||
.s().uv(0, 0, 3, 16)
|
||||
.w().uv(0, 0, 16, 16)
|
||||
.e().uv(16, 0, 0, 16).noCull()
|
||||
.rotate(getRotation(state.getValue(FACING), state.getValue(OPEN) ? 3 : 0));
|
||||
}
|
||||
else {
|
||||
if(state.getValue(HINGE) == EnumHingePosition.LEFT == state.getValue(OPEN))
|
||||
return provider.getModel(top).noOcclude()
|
||||
.add(0, 0, 0, 3, 16, 16)
|
||||
.u(bottom).uv(13, 0, 16, 16)
|
||||
.n().uv(3, 0, 0, 16)
|
||||
.s().uv(0, 0, 3, 16)
|
||||
.w().uv(16, 0, 0, 16)
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.rotate(getRotation(state.getValue(FACING), state.getValue(OPEN) ? 1 : 0));
|
||||
else
|
||||
return provider.getModel(top).noOcclude()
|
||||
.add(0, 0, 0, 3, 16, 16)
|
||||
.u(bottom).uv(13, 0, 16, 16)
|
||||
.n().uv(3, 0, 0, 16)
|
||||
.s().uv(0, 0, 3, 16)
|
||||
.w().uv(0, 0, 16, 16)
|
||||
.e().uv(16, 0, 0, 16).noCull()
|
||||
.rotate(getRotation(state.getValue(FACING), state.getValue(OPEN) ? 3 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
public IProperty<?>[] getIgnoredProperties() {
|
||||
return new IProperty[] {POWERED};
|
||||
}
|
||||
|
||||
public static enum EnumDoorHalf implements Identifyable
|
||||
{
|
||||
UPPER,
|
||||
LOWER;
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this == UPPER ? "upper" : "lower";
|
||||
}
|
||||
}
|
||||
|
||||
public static enum EnumHingePosition implements Identifyable
|
||||
{
|
||||
LEFT,
|
||||
RIGHT;
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this == LEFT ? "left" : "right";
|
||||
}
|
||||
}
|
||||
}
|
221
common/src/main/java/common/block/artificial/BlockDragonEgg.java
Executable file
221
common/src/main/java/common/block/artificial/BlockDragonEgg.java
Executable file
|
@ -0,0 +1,221 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockFalling;
|
||||
import common.block.Material;
|
||||
import common.entity.item.EntityFalling;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ParticleType;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class BlockDragonEgg extends Block
|
||||
{
|
||||
private static final Model dragon_egg = ModelProvider.getModelProvider().getModel("dragon_egg").noOcclude()
|
||||
.add(6, 15, 6, 10, 16, 10)
|
||||
.d().uv(6, 6, 10, 10).noCull()
|
||||
.u().uv(6, 6, 10, 10).noCull()
|
||||
.n().uv(6, 15, 10, 16).noCull()
|
||||
.s().uv(6, 15, 10, 16).noCull()
|
||||
.w().uv(6, 15, 10, 16).noCull()
|
||||
.e().uv(6, 15, 10, 16).noCull()
|
||||
.add(5, 14, 5, 11, 15, 11)
|
||||
.d().uv(5, 5, 11, 11).noCull()
|
||||
.u().uv(5, 5, 11, 11).noCull()
|
||||
.n().uv(5, 14, 11, 15).noCull()
|
||||
.s().uv(5, 14, 11, 15).noCull()
|
||||
.w().uv(5, 14, 11, 15).noCull()
|
||||
.e().uv(5, 14, 11, 15).noCull()
|
||||
.add(5, 13, 5, 11, 14, 11)
|
||||
.d().uv(4, 4, 12, 12).noCull()
|
||||
.u().uv(4, 4, 12, 12).noCull()
|
||||
.n().uv(4, 13, 12, 14).noCull()
|
||||
.s().uv(4, 13, 12, 14).noCull()
|
||||
.w().uv(4, 13, 12, 14).noCull()
|
||||
.e().uv(4, 13, 12, 14).noCull()
|
||||
.add(3, 11, 3, 13, 13, 13)
|
||||
.d().uv(3, 3, 13, 13).noCull()
|
||||
.u().uv(3, 3, 13, 13).noCull()
|
||||
.n().uv(3, 11, 13, 13).noCull()
|
||||
.s().uv(3, 11, 13, 13).noCull()
|
||||
.w().uv(3, 11, 13, 13).noCull()
|
||||
.e().uv(3, 11, 13, 13).noCull()
|
||||
.add(2, 8, 2, 14, 11, 14)
|
||||
.d().uv(2, 2, 14, 14).noCull()
|
||||
.u().uv(2, 2, 14, 14).noCull()
|
||||
.n().uv(2, 8, 14, 11).noCull()
|
||||
.s().uv(2, 8, 14, 11).noCull()
|
||||
.w().uv(2, 8, 14, 11).noCull()
|
||||
.e().uv(2, 8, 14, 11).noCull()
|
||||
.add(1, 3, 1, 15, 8, 15)
|
||||
.d().uv(1, 1, 15, 15).noCull()
|
||||
.u().uv(1, 1, 15, 15).noCull()
|
||||
.n().uv(1, 3, 15, 8).noCull()
|
||||
.s().uv(1, 3, 15, 8).noCull()
|
||||
.w().uv(1, 3, 15, 8).noCull()
|
||||
.e().uv(1, 3, 15, 8).noCull()
|
||||
.add(2, 1, 2, 14, 3, 14)
|
||||
.d().uv(2, 2, 14, 14).noCull()
|
||||
.u().uv(2, 2, 14, 14).noCull()
|
||||
.n().uv(2, 1, 14, 3).noCull()
|
||||
.s().uv(2, 1, 14, 3).noCull()
|
||||
.w().uv(2, 1, 14, 3).noCull()
|
||||
.e().uv(2, 1, 14, 3).noCull()
|
||||
.add(3, 0, 3, 13, 1, 13)
|
||||
.d().uv(3, 3, 13, 13).noCull()
|
||||
.u().uv(3, 3, 13, 13).noCull()
|
||||
.n().uv(3, 0, 13, 1).noCull()
|
||||
.s().uv(3, 0, 13, 1).noCull()
|
||||
.w().uv(3, 0, 13, 1).noCull()
|
||||
.e().uv(3, 0, 13, 1).noCull()
|
||||
;
|
||||
|
||||
public BlockDragonEgg()
|
||||
{
|
||||
super(Material.SOFT);
|
||||
this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F);
|
||||
}
|
||||
|
||||
public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state)
|
||||
{
|
||||
worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos));
|
||||
}
|
||||
|
||||
public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
if(Config.blockGravity)
|
||||
this.checkFall(worldIn, pos);
|
||||
}
|
||||
|
||||
private void checkFall(World worldIn, BlockPos pos)
|
||||
{
|
||||
if (BlockFalling.canFallInto(worldIn, pos.down()) && pos.getY() >= 0)
|
||||
{
|
||||
int i = 32;
|
||||
|
||||
if (!BlockFalling.fallInstantly && worldIn.isAreaLoaded(pos.add(-i, -i, -i), pos.add(i, i, i)))
|
||||
{
|
||||
worldIn.spawnEntityInWorld(new EntityFalling(worldIn, (double)((float)pos.getX() + 0.5F), (double)pos.getY(), (double)((float)pos.getZ() + 0.5F), this.getState()));
|
||||
}
|
||||
else
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
BlockPos blockpos;
|
||||
for(blockpos = pos; BlockFalling.canFallInto(worldIn, blockpos) && blockpos.getY() > 0; blockpos = blockpos.down()) {
|
||||
}
|
||||
if(blockpos != pos)
|
||||
blockpos = blockpos.up();
|
||||
if(blockpos.getY() > 0)
|
||||
worldIn.setState(blockpos, this.getState(), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
this.teleport(worldIn, pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onBlockClicked(World worldIn, BlockPos pos, EntityNPC playerIn)
|
||||
{
|
||||
this.teleport(worldIn, pos);
|
||||
}
|
||||
|
||||
private void teleport(World worldIn, BlockPos pos)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
|
||||
if (iblockstate.getBlock() == this)
|
||||
{
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
{
|
||||
BlockPos blockpos = pos.add(worldIn.rand.zrange(16) - worldIn.rand.zrange(16), worldIn.rand.zrange(8) - worldIn.rand.zrange(8), worldIn.rand.zrange(16) - worldIn.rand.zrange(16));
|
||||
|
||||
if (worldIn.getState(blockpos).getBlock() == Blocks.air)
|
||||
{
|
||||
if (worldIn.client)
|
||||
{
|
||||
for (int j = 0; j < 128; ++j)
|
||||
{
|
||||
double d0 = worldIn.rand.doublev();
|
||||
float f = (worldIn.rand.floatv() - 0.5F) * 0.2F;
|
||||
float f1 = (worldIn.rand.floatv() - 0.5F) * 0.2F;
|
||||
float f2 = (worldIn.rand.floatv() - 0.5F) * 0.2F;
|
||||
double d1 = (double)blockpos.getX() + (double)(pos.getX() - blockpos.getX()) * d0 + (worldIn.rand.doublev() - 0.5D) * 1.0D + 0.5D;
|
||||
double d2 = (double)blockpos.getY() + (double)(pos.getY() - blockpos.getY()) * d0 + worldIn.rand.doublev() * 1.0D - 0.5D;
|
||||
double d3 = (double)blockpos.getZ() + (double)(pos.getZ() - blockpos.getZ()) * d0 + (worldIn.rand.doublev() - 0.5D) * 1.0D + 0.5D;
|
||||
worldIn.spawnParticle(ParticleType.PORTAL, d1, d2, d3, (double)f, (double)f1, (double)f2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
if(!Config.blockGravity) {
|
||||
BlockPos blockpos2;
|
||||
for(blockpos2 = blockpos; BlockFalling.canFallInto(worldIn, blockpos2) && blockpos2.getY() > 0; blockpos2 = blockpos2.down()) {
|
||||
}
|
||||
if(blockpos2 != blockpos)
|
||||
blockpos = blockpos2.up();
|
||||
}
|
||||
worldIn.setState(blockpos, iblockstate, 2);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How many world ticks before ticking
|
||||
*/
|
||||
public int tickRate(World worldIn, BlockPos pos)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// public Item getItem(World worldIn, BlockPos pos)
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return dragon_egg;
|
||||
}
|
||||
}
|
382
common/src/main/java/common/block/artificial/BlockFence.java
Executable file
382
common/src/main/java/common/block/artificial/BlockFence.java
Executable file
|
@ -0,0 +1,382 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.collect.Lists;
|
||||
import common.entity.Entity;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.item.CheatTab;
|
||||
import common.item.ItemLead;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.model.Transforms;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyBool;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.world.IBlockAccess;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockFence extends Block
|
||||
{
|
||||
/** Whether this fence connects in the northern direction */
|
||||
public static final PropertyBool NORTH = PropertyBool.create("north");
|
||||
|
||||
/** Whether this fence connects in the eastern direction */
|
||||
public static final PropertyBool EAST = PropertyBool.create("east");
|
||||
|
||||
/** Whether this fence connects in the southern direction */
|
||||
public static final PropertyBool SOUTH = PropertyBool.create("south");
|
||||
|
||||
/** Whether this fence connects in the western direction */
|
||||
public static final PropertyBool WEST = PropertyBool.create("west");
|
||||
public static final List<BlockFence> FENCES = Lists.newArrayList();
|
||||
|
||||
private final String texture;
|
||||
|
||||
public BlockFence(Material p_i46395_1_, String texture)
|
||||
{
|
||||
super(p_i46395_1_);
|
||||
this.setDefaultState(this.getBaseState().withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)));
|
||||
this.setTab(p_i46395_1_ == Material.WOOD ? CheatTab.WOOD : CheatTab.BLOCKS);
|
||||
this.texture = texture;
|
||||
FENCES.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all collision boxes of this Block to the list that intersect with the given mask.
|
||||
*/
|
||||
public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
|
||||
{
|
||||
boolean flag = this.canConnectTo(worldIn, pos.north());
|
||||
boolean flag1 = this.canConnectTo(worldIn, pos.south());
|
||||
boolean flag2 = this.canConnectTo(worldIn, pos.west());
|
||||
boolean flag3 = this.canConnectTo(worldIn, pos.east());
|
||||
float f = 0.375F;
|
||||
float f1 = 0.625F;
|
||||
float f2 = 0.375F;
|
||||
float f3 = 0.625F;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
f2 = 0.0F;
|
||||
}
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
f3 = 1.0F;
|
||||
}
|
||||
|
||||
if (flag || flag1)
|
||||
{
|
||||
this.setBlockBounds(f, 0.0F, f2, f1, 1.5F, f3);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
|
||||
f2 = 0.375F;
|
||||
f3 = 0.625F;
|
||||
|
||||
if (flag2)
|
||||
{
|
||||
f = 0.0F;
|
||||
}
|
||||
|
||||
if (flag3)
|
||||
{
|
||||
f1 = 1.0F;
|
||||
}
|
||||
|
||||
if (flag2 || flag3 || !flag && !flag1)
|
||||
{
|
||||
this.setBlockBounds(f, 0.0F, f2, f1, 1.5F, f3);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
f2 = 0.0F;
|
||||
}
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
f3 = 1.0F;
|
||||
}
|
||||
|
||||
this.setBlockBounds(f, 0.0F, f2, f1, 1.0F, f3);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
boolean flag = this.canConnectTo(worldIn, pos.north());
|
||||
boolean flag1 = this.canConnectTo(worldIn, pos.south());
|
||||
boolean flag2 = this.canConnectTo(worldIn, pos.west());
|
||||
boolean flag3 = this.canConnectTo(worldIn, pos.east());
|
||||
float f = 0.375F;
|
||||
float f1 = 0.625F;
|
||||
float f2 = 0.375F;
|
||||
float f3 = 0.625F;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
f2 = 0.0F;
|
||||
}
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
f3 = 1.0F;
|
||||
}
|
||||
|
||||
if (flag2)
|
||||
{
|
||||
f = 0.0F;
|
||||
}
|
||||
|
||||
if (flag3)
|
||||
{
|
||||
f1 = 1.0F;
|
||||
}
|
||||
|
||||
this.setBlockBounds(f, 0.0F, f2, f1, 1.0F, f3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPassable(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canConnectTo(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
Block block = worldIn.getState(pos).getBlock();
|
||||
return ((!(block instanceof BlockFence) || block.getMaterial() != this.material) && !(block instanceof BlockFenceGate) ? (block.getMaterial().isOpaque() && block.isFullCube() ? block.getMaterial() != Material.SOFT : false) : true);
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
return worldIn.client ? true : ItemLead.attachToFence(playerIn, worldIn, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual Block state of this Block at the given position. This applies properties not visible in the
|
||||
* metadata, such as fence connections.
|
||||
*/
|
||||
public State getActualState(State state, IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return state.withProperty(NORTH, Boolean.valueOf(this.canConnectTo(worldIn, pos.north()))).withProperty(EAST, Boolean.valueOf(this.canConnectTo(worldIn, pos.east()))).withProperty(SOUTH, Boolean.valueOf(this.canConnectTo(worldIn, pos.south()))).withProperty(WEST, Boolean.valueOf(this.canConnectTo(worldIn, pos.west())));
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {NORTH, EAST, WEST, SOUTH};
|
||||
}
|
||||
|
||||
public Transforms getTransform() {
|
||||
return Transforms.FENCE;
|
||||
}
|
||||
|
||||
public String getTexture() {
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
boolean n = state.getValue(NORTH);
|
||||
boolean s = state.getValue(SOUTH);
|
||||
boolean w = state.getValue(WEST);
|
||||
boolean e = state.getValue(EAST);
|
||||
int sides = (n ? 1 : 0) + (s ? 1 : 0) + (w ? 1 : 0) + (e ? 1 : 0);
|
||||
if(sides == 0)
|
||||
return provider.getModel(this.texture)
|
||||
.add(6, 0, 6, 10, 16, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u().uv(6, 6, 10, 10)
|
||||
.n().uv(6, 0, 10, 16).noCull()
|
||||
.s().uv(6, 0, 10, 16).noCull()
|
||||
.w().uv(6, 0, 10, 16).noCull()
|
||||
.e().uv(6, 0, 10, 16).noCull();
|
||||
else if(sides == 4)
|
||||
return provider.getModel(this.texture).uvLock()
|
||||
.add(6, 0, 6, 10, 16, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u().uv(6, 6, 10, 10)
|
||||
.n().uv(6, 0, 10, 16).noCull()
|
||||
.s().uv(6, 0, 10, 16).noCull()
|
||||
.w().uv(6, 0, 10, 16).noCull()
|
||||
.e().uv(6, 0, 10, 16).noCull()
|
||||
.add(7, 12, 0, 9, 15, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(7, 0, 9, 16).noCull()
|
||||
.n().uv(7, 1, 9, 4)
|
||||
.s().uv(7, 1, 9, 4)
|
||||
.w().uv(0, 1, 16, 4).noCull()
|
||||
.e().uv(0, 1, 16, 4).noCull()
|
||||
.add(7, 6, 0, 9, 9, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(7, 0, 9, 16).noCull()
|
||||
.n().uv(7, 7, 9, 10)
|
||||
.s().uv(7, 7, 9, 10)
|
||||
.w().uv(0, 7, 16, 10).noCull()
|
||||
.e().uv(0, 7, 16, 10).noCull()
|
||||
.add(0, 12, 7, 16, 15, 9)
|
||||
.d().uv(0, 7, 16, 9).noCull()
|
||||
.u().uv(0, 7, 16, 9).noCull()
|
||||
.n().uv(0, 1, 16, 4).noCull()
|
||||
.s().uv(0, 1, 16, 4).noCull()
|
||||
.w().uv(7, 1, 9, 4)
|
||||
.e().uv(7, 1, 9, 4)
|
||||
.add(0, 6, 7, 16, 9, 9)
|
||||
.d().uv(0, 7, 16, 9).noCull()
|
||||
.u().uv(0, 7, 16, 9).noCull()
|
||||
.n().uv(0, 7, 16, 10).noCull()
|
||||
.s().uv(0, 7, 16, 10).noCull()
|
||||
.w().uv(7, 7, 9, 10)
|
||||
.e().uv(7, 7, 9, 10);
|
||||
else if(sides == 1)
|
||||
return provider.getModel(this.texture).uvLock()
|
||||
.add(6, 0, 6, 10, 16, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u().uv(6, 6, 10, 10)
|
||||
.n().uv(6, 0, 10, 16).noCull()
|
||||
.s().uv(6, 0, 10, 16).noCull()
|
||||
.w().uv(6, 0, 10, 16).noCull()
|
||||
.e().uv(6, 0, 10, 16).noCull()
|
||||
.add(7, 12, 0, 9, 15, 9)
|
||||
.d().uv(7, 0, 9, 9).noCull()
|
||||
.u().uv(7, 0, 9, 9).noCull()
|
||||
.n().uv(7, 1, 9, 4)
|
||||
.w().uv(0, 1, 9, 4).noCull()
|
||||
.e().uv(0, 1, 9, 4).noCull()
|
||||
.add(7, 6, 0, 9, 9, 9)
|
||||
.d().uv(7, 0, 9, 9).noCull()
|
||||
.u().uv(7, 0, 9, 9).noCull()
|
||||
.n().uv(7, 7, 9, 10)
|
||||
.w().uv(0, 7, 9, 10).noCull()
|
||||
.e().uv(0, 7, 9, 10).noCull()
|
||||
.rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90)));
|
||||
else if(sides == 2 && ((e != w) || (n != s)))
|
||||
return provider.getModel(this.texture).uvLock()
|
||||
.add(6, 0, 6, 10, 16, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u().uv(6, 6, 10, 10)
|
||||
.n().uv(6, 0, 10, 16).noCull()
|
||||
.s().uv(6, 0, 10, 16).noCull()
|
||||
.w().uv(6, 0, 10, 16).noCull()
|
||||
.e().uv(6, 0, 10, 16).noCull()
|
||||
.add(7, 12, 0, 9, 15, 9)
|
||||
.d().uv(7, 0, 9, 9).noCull()
|
||||
.u().uv(7, 0, 9, 9).noCull()
|
||||
.n().uv(7, 1, 9, 4)
|
||||
.w().uv(0, 1, 9, 4).noCull()
|
||||
.e().uv(0, 1, 9, 4).noCull()
|
||||
.add(7, 6, 0, 9, 9, 9)
|
||||
.d().uv(7, 0, 9, 9).noCull()
|
||||
.u().uv(7, 0, 9, 9).noCull()
|
||||
.n().uv(7, 7, 9, 10)
|
||||
.w().uv(0, 7, 9, 10).noCull()
|
||||
.e().uv(0, 7, 9, 10).noCull()
|
||||
.add(7, 12, 7, 16, 15, 9)
|
||||
.d().uv(7, 7, 16, 9).noCull()
|
||||
.u().uv(7, 7, 16, 9).noCull()
|
||||
.n().uv(7, 1, 16, 4).noCull()
|
||||
.s().uv(7, 1, 16, 4).noCull()
|
||||
.e().uv(7, 1, 9, 4)
|
||||
.add(7, 6, 7, 16, 9, 9)
|
||||
.d().uv(7, 7, 16, 9).noCull()
|
||||
.u().uv(7, 7, 16, 9).noCull()
|
||||
.n().uv(7, 7, 16, 10).noCull()
|
||||
.s().uv(7, 7, 16, 10).noCull()
|
||||
.e().uv(7, 7, 9, 10)
|
||||
.rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 :
|
||||
(n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90)));
|
||||
else if(sides == 2)
|
||||
return provider.getModel(this.texture).uvLock()
|
||||
.add(6, 0, 6, 10, 16, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u().uv(6, 6, 10, 10)
|
||||
.n().uv(6, 0, 10, 16).noCull()
|
||||
.s().uv(6, 0, 10, 16).noCull()
|
||||
.w().uv(6, 0, 10, 16).noCull()
|
||||
.e().uv(6, 0, 10, 16).noCull()
|
||||
.add(7, 12, 0, 9, 15, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(7, 0, 9, 16).noCull()
|
||||
.n().uv(7, 1, 9, 4)
|
||||
.s().uv(7, 1, 9, 4)
|
||||
.w().uv(0, 1, 16, 4).noCull()
|
||||
.e().uv(0, 1, 16, 4).noCull()
|
||||
.add(7, 6, 0, 9, 9, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(7, 0, 9, 16).noCull()
|
||||
.n().uv(7, 7, 9, 10)
|
||||
.s().uv(7, 7, 9, 10)
|
||||
.w().uv(0, 7, 16, 10).noCull()
|
||||
.e().uv(0, 7, 16, 10).noCull()
|
||||
.rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90);
|
||||
else
|
||||
return provider.getModel(this.texture).uvLock()
|
||||
.add(6, 0, 6, 10, 16, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u().uv(6, 6, 10, 10)
|
||||
.n().uv(6, 0, 10, 16).noCull()
|
||||
.s().uv(6, 0, 10, 16).noCull()
|
||||
.w().uv(6, 0, 10, 16).noCull()
|
||||
.e().uv(6, 0, 10, 16).noCull()
|
||||
.add(7, 12, 0, 9, 15, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(7, 0, 9, 16).noCull()
|
||||
.n().uv(7, 1, 9, 4)
|
||||
.s().uv(7, 1, 9, 4)
|
||||
.w().uv(0, 1, 16, 4).noCull()
|
||||
.e().uv(0, 1, 16, 4).noCull()
|
||||
.add(7, 6, 0, 9, 9, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(7, 0, 9, 16).noCull()
|
||||
.n().uv(7, 7, 9, 10)
|
||||
.s().uv(7, 7, 9, 10)
|
||||
.w().uv(0, 7, 16, 10).noCull()
|
||||
.e().uv(0, 7, 16, 10).noCull()
|
||||
.add(7, 12, 7, 16, 15, 9)
|
||||
.d().uv(7, 7, 16, 9).noCull()
|
||||
.u().uv(7, 7, 16, 9).noCull()
|
||||
.n().uv(7, 1, 16, 4).noCull()
|
||||
.s().uv(7, 1, 16, 4).noCull()
|
||||
.e().uv(7, 1, 9, 4)
|
||||
.add(7, 6, 7, 16, 9, 9)
|
||||
.d().uv(7, 7, 16, 9).noCull()
|
||||
.u().uv(7, 7, 16, 9).noCull()
|
||||
.n().uv(7, 7, 16, 10).noCull()
|
||||
.s().uv(7, 7, 16, 10).noCull()
|
||||
.e().uv(7, 7, 9, 10)
|
||||
.rotate(!w ? ModelRotation.X0_Y0 : (!e ? ModelRotation.X0_Y180 : (!s ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90)));
|
||||
}
|
||||
}
|
412
common/src/main/java/common/block/artificial/BlockFenceGate.java
Executable file
412
common/src/main/java/common/block/artificial/BlockFenceGate.java
Executable file
|
@ -0,0 +1,412 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockDirectional;
|
||||
import common.block.Material;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Blocks;
|
||||
import common.init.WoodType;
|
||||
import common.item.CheatTab;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.model.Transforms;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyBool;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.world.IBlockAccess;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockFenceGate extends BlockDirectional
|
||||
{
|
||||
public static final PropertyBool OPEN = PropertyBool.create("open");
|
||||
public static final PropertyBool POWERED = PropertyBool.create("powered");
|
||||
public static final PropertyBool IN_WALL = PropertyBool.create("in_wall");
|
||||
|
||||
private final String texture;
|
||||
|
||||
public BlockFenceGate(WoodType p_i46394_1_)
|
||||
{
|
||||
super(Material.WOOD); // , p_i46394_1_.getMapColor());
|
||||
this.setDefaultState(this.getBaseState().withProperty(OPEN, Boolean.valueOf(false)).withProperty(POWERED, Boolean.valueOf(false)).withProperty(IN_WALL, Boolean.valueOf(false)));
|
||||
this.setTab(CheatTab.WOOD);
|
||||
this.texture = p_i46394_1_.getName() + "_planks";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual Block state of this Block at the given position. This applies properties not visible in the
|
||||
* metadata, such as fence connections.
|
||||
*/
|
||||
public State getActualState(State state, IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
Facing.Axis enumfacing$axis = ((Facing)state.getValue(FACING)).getAxis();
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.Z && (worldIn.getState(pos.west()).getBlock() == Blocks.cobblestone_wall || worldIn.getState(pos.east()).getBlock() == Blocks.cobblestone_wall) || enumfacing$axis == Facing.Axis.X && (worldIn.getState(pos.north()).getBlock() == Blocks.cobblestone_wall || worldIn.getState(pos.south()).getBlock() == Blocks.cobblestone_wall))
|
||||
{
|
||||
state = state.withProperty(IN_WALL, Boolean.valueOf(true));
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return worldIn.getState(pos.down()).getBlock().getMaterial().isSolid() ? super.canPlaceBlockAt(worldIn, pos) : false;
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
if (((Boolean)state.getValue(OPEN)).booleanValue())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Facing.Axis enumfacing$axis = ((Facing)state.getValue(FACING)).getAxis();
|
||||
return enumfacing$axis == Facing.Axis.Z ? new BoundingBox((double)pos.getX(), (double)pos.getY(), (double)((float)pos.getZ() + 0.375F), (double)(pos.getX() + 1), (double)((float)pos.getY() + 1.5F), (double)((float)pos.getZ() + 0.625F)) : new BoundingBox((double)((float)pos.getX() + 0.375F), (double)pos.getY(), (double)pos.getZ(), (double)((float)pos.getX() + 0.625F), (double)((float)pos.getY() + 1.5F), (double)(pos.getZ() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
Facing.Axis enumfacing$axis = ((Facing)worldIn.getState(pos).getValue(FACING)).getAxis();
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.Z)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.375F, 1.0F, 1.0F, 0.625F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.375F, 0.0F, 0.0F, 0.625F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPassable(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return ((Boolean)worldIn.getState(pos).getValue(OPEN)).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
||||
* IBlockstate
|
||||
*/
|
||||
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
||||
{
|
||||
return this.getState().withProperty(FACING, placer.getHorizontalFacing()).withProperty(OPEN, Boolean.valueOf(false)).withProperty(POWERED, Boolean.valueOf(false)).withProperty(IN_WALL, Boolean.valueOf(false));
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
if (((Boolean)state.getValue(OPEN)).booleanValue())
|
||||
{
|
||||
state = state.withProperty(OPEN, Boolean.valueOf(false));
|
||||
worldIn.setState(pos, state, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Facing enumfacing = Facing.fromAngle((double)playerIn.rotYaw);
|
||||
|
||||
if (state.getValue(FACING) == enumfacing.getOpposite())
|
||||
{
|
||||
state = state.withProperty(FACING, enumfacing);
|
||||
}
|
||||
|
||||
state = state.withProperty(OPEN, Boolean.valueOf(true));
|
||||
worldIn.setState(pos, state, 2);
|
||||
}
|
||||
|
||||
worldIn.playAuxSFX(playerIn, ((Boolean)state.getValue(OPEN)).booleanValue() ? 1003 : 1006, pos, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
if (!worldIn.client)
|
||||
{
|
||||
boolean flag = worldIn.isBlockPowered(pos);
|
||||
|
||||
if (flag || neighborBlock.canProvidePower())
|
||||
{
|
||||
if (flag && !((Boolean)state.getValue(OPEN)).booleanValue() && !((Boolean)state.getValue(POWERED)).booleanValue())
|
||||
{
|
||||
worldIn.setState(pos, state.withProperty(OPEN, Boolean.valueOf(true)).withProperty(POWERED, Boolean.valueOf(true)), 2);
|
||||
worldIn.playAuxSFX(1003, pos, 0);
|
||||
}
|
||||
else if (!flag && ((Boolean)state.getValue(OPEN)).booleanValue() && ((Boolean)state.getValue(POWERED)).booleanValue())
|
||||
{
|
||||
worldIn.setState(pos, state.withProperty(OPEN, Boolean.valueOf(false)).withProperty(POWERED, Boolean.valueOf(false)), 2);
|
||||
worldIn.playAuxSFX(1006, pos, 0);
|
||||
}
|
||||
else if (flag != ((Boolean)state.getValue(POWERED)).booleanValue())
|
||||
{
|
||||
worldIn.setState(pos, state.withProperty(POWERED, Boolean.valueOf(flag)), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(FACING, Facing.getHorizontal(meta)).withProperty(OPEN, Boolean.valueOf((meta & 4) != 0)).withProperty(POWERED, Boolean.valueOf((meta & 8) != 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
int i = 0;
|
||||
i = i | ((Facing)state.getValue(FACING)).getHorizontalIndex();
|
||||
|
||||
if (((Boolean)state.getValue(POWERED)).booleanValue())
|
||||
{
|
||||
i |= 8;
|
||||
}
|
||||
|
||||
if (((Boolean)state.getValue(OPEN)).booleanValue())
|
||||
{
|
||||
i |= 4;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {FACING, OPEN, POWERED, IN_WALL};
|
||||
}
|
||||
|
||||
public Transforms getTransform() {
|
||||
return Transforms.GATE;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return (state.getValue(IN_WALL) ? (state.getValue(OPEN) ? provider.getModel(this.texture).noOcclude().uvLock()
|
||||
.add(0, 2, 7, 2, 13, 9)
|
||||
.d().uv(0, 7, 2, 9).noCull()
|
||||
.u().uv(0, 7, 2, 9).noCull()
|
||||
.n().uv(0, 0, 2, 11).noCull()
|
||||
.s().uv(0, 0, 2, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11)
|
||||
.e().uv(7, 0, 9, 11).noCull()
|
||||
.add(14, 2, 7, 16, 13, 9)
|
||||
.d().uv(14, 7, 16, 9).noCull()
|
||||
.u().uv(14, 7, 16, 9).noCull()
|
||||
.n().uv(14, 0, 16, 11).noCull()
|
||||
.s().uv(14, 0, 16, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11).noCull()
|
||||
.e().uv(7, 0, 9, 11)
|
||||
.add(0, 3, 13, 2, 12, 15)
|
||||
.d().uv(0, 13, 2, 15).noCull()
|
||||
.u().uv(0, 13, 2, 15).noCull()
|
||||
.n().uv(0, 1, 2, 10).noCull()
|
||||
.s().uv(0, 1, 2, 10).noCull()
|
||||
.w().uv(13, 1, 15, 10).noCull()
|
||||
.e().uv(13, 1, 15, 10).noCull()
|
||||
.add(14, 3, 13, 16, 12, 15)
|
||||
.d().uv(14, 13, 16, 15).noCull()
|
||||
.u().uv(14, 13, 16, 15).noCull()
|
||||
.n().uv(14, 1, 16, 10).noCull()
|
||||
.s().uv(14, 1, 16, 10).noCull()
|
||||
.w().uv(13, 1, 15, 10).noCull()
|
||||
.e().uv(13, 1, 15, 10).noCull()
|
||||
.add(0, 3, 9, 2, 6, 13)
|
||||
.d().uv(0, 9, 2, 13).noCull()
|
||||
.u().uv(0, 9, 2, 13).noCull()
|
||||
.w().uv(13, 7, 15, 10).noCull()
|
||||
.e().uv(13, 7, 15, 10).noCull()
|
||||
.add(0, 9, 9, 2, 12, 13)
|
||||
.d().uv(0, 9, 2, 13).noCull()
|
||||
.u().uv(0, 9, 2, 13).noCull()
|
||||
.w().uv(13, 1, 15, 4).noCull()
|
||||
.e().uv(13, 1, 15, 4).noCull()
|
||||
.add(14, 3, 9, 16, 6, 13)
|
||||
.d().uv(14, 9, 16, 13).noCull()
|
||||
.u().uv(14, 9, 16, 13).noCull()
|
||||
.w().uv(13, 7, 15, 10).noCull()
|
||||
.e().uv(13, 7, 15, 10).noCull()
|
||||
.add(14, 9, 9, 16, 12, 13)
|
||||
.d().uv(14, 9, 16, 13).noCull()
|
||||
.u().uv(14, 9, 16, 13).noCull()
|
||||
.w().uv(13, 1, 15, 4).noCull()
|
||||
.e().uv(13, 1, 15, 4).noCull() : provider.getModel(this.texture).noOcclude().uvLock()
|
||||
.add(0, 2, 7, 2, 13, 9)
|
||||
.d().uv(0, 7, 2, 9).noCull()
|
||||
.u().uv(0, 7, 2, 9).noCull()
|
||||
.n().uv(0, 0, 2, 11).noCull()
|
||||
.s().uv(0, 0, 2, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11)
|
||||
.e().uv(7, 0, 9, 11).noCull()
|
||||
.add(14, 2, 7, 16, 13, 9)
|
||||
.d().uv(14, 7, 16, 9).noCull()
|
||||
.u().uv(14, 7, 16, 9).noCull()
|
||||
.n().uv(14, 0, 16, 11).noCull()
|
||||
.s().uv(14, 0, 16, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11).noCull()
|
||||
.e().uv(7, 0, 9, 11)
|
||||
.add(6, 3, 7, 8, 12, 9)
|
||||
.d().uv(6, 7, 8, 9).noCull()
|
||||
.u().uv(6, 7, 8, 9).noCull()
|
||||
.n().uv(6, 1, 8, 10).noCull()
|
||||
.s().uv(6, 1, 8, 10).noCull()
|
||||
.w().uv(7, 1, 9, 10).noCull()
|
||||
.e().uv(7, 1, 9, 10).noCull()
|
||||
.add(8, 3, 7, 10, 12, 9)
|
||||
.d().uv(8, 7, 10, 9).noCull()
|
||||
.u().uv(8, 7, 10, 9).noCull()
|
||||
.n().uv(8, 1, 10, 10).noCull()
|
||||
.s().uv(8, 1, 10, 10).noCull()
|
||||
.w().uv(7, 1, 9, 10).noCull()
|
||||
.e().uv(7, 1, 9, 10).noCull()
|
||||
.add(2, 3, 7, 6, 6, 9)
|
||||
.d().uv(2, 7, 6, 9).noCull()
|
||||
.u().uv(2, 7, 6, 9).noCull()
|
||||
.n().uv(2, 7, 6, 10).noCull()
|
||||
.s().uv(2, 7, 6, 10).noCull()
|
||||
.add(2, 9, 7, 6, 12, 9)
|
||||
.d().uv(2, 7, 6, 9).noCull()
|
||||
.u().uv(2, 7, 6, 9).noCull()
|
||||
.n().uv(2, 1, 6, 4).noCull()
|
||||
.s().uv(2, 1, 6, 4).noCull()
|
||||
.add(10, 3, 7, 14, 6, 9)
|
||||
.d().uv(10, 7, 14, 9).noCull()
|
||||
.u().uv(10, 7, 14, 9).noCull()
|
||||
.n().uv(10, 7, 14, 10).noCull()
|
||||
.s().uv(10, 7, 14, 10).noCull()
|
||||
.add(10, 9, 7, 14, 12, 9)
|
||||
.d().uv(10, 7, 14, 9).noCull()
|
||||
.u().uv(10, 7, 14, 9).noCull()
|
||||
.n().uv(10, 1, 14, 4).noCull()
|
||||
.s().uv(10, 1, 14, 4).noCull()) : (state.getValue(OPEN) ? provider.getModel(this.texture).uvLock()
|
||||
.add(0, 5, 7, 2, 16, 9)
|
||||
.d().uv(0, 7, 2, 9).noCull()
|
||||
.u().uv(0, 7, 2, 9).noCull()
|
||||
.n().uv(0, 0, 2, 11).noCull()
|
||||
.s().uv(0, 0, 2, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11)
|
||||
.e().uv(7, 0, 9, 11).noCull()
|
||||
.add(14, 5, 7, 16, 16, 9)
|
||||
.d().uv(14, 7, 16, 9).noCull()
|
||||
.u().uv(14, 7, 16, 9).noCull()
|
||||
.n().uv(14, 0, 16, 11).noCull()
|
||||
.s().uv(14, 0, 16, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11).noCull()
|
||||
.e().uv(7, 0, 9, 11)
|
||||
.add(0, 6, 13, 2, 15, 15)
|
||||
.d().uv(0, 13, 2, 15).noCull()
|
||||
.u().uv(0, 13, 2, 15).noCull()
|
||||
.n().uv(0, 1, 2, 10).noCull()
|
||||
.s().uv(0, 1, 2, 10).noCull()
|
||||
.w().uv(13, 1, 15, 10).noCull()
|
||||
.e().uv(13, 1, 15, 10).noCull()
|
||||
.add(14, 6, 13, 16, 15, 15)
|
||||
.d().uv(14, 13, 16, 15).noCull()
|
||||
.u().uv(14, 13, 16, 15).noCull()
|
||||
.n().uv(14, 1, 16, 10).noCull()
|
||||
.s().uv(14, 1, 16, 10).noCull()
|
||||
.w().uv(13, 1, 15, 10).noCull()
|
||||
.e().uv(13, 1, 15, 10).noCull()
|
||||
.add(0, 6, 9, 2, 9, 13)
|
||||
.d().uv(0, 9, 2, 13).noCull()
|
||||
.u().uv(0, 9, 2, 13).noCull()
|
||||
.w().uv(13, 7, 15, 10).noCull()
|
||||
.e().uv(13, 7, 15, 10).noCull()
|
||||
.add(0, 12, 9, 2, 15, 13)
|
||||
.d().uv(0, 9, 2, 13).noCull()
|
||||
.u().uv(0, 9, 2, 13).noCull()
|
||||
.w().uv(13, 1, 15, 4).noCull()
|
||||
.e().uv(13, 1, 15, 4).noCull()
|
||||
.add(14, 6, 9, 16, 9, 13)
|
||||
.d().uv(14, 9, 16, 13).noCull()
|
||||
.u().uv(14, 9, 16, 13).noCull()
|
||||
.w().uv(13, 7, 15, 10).noCull()
|
||||
.e().uv(13, 7, 15, 10).noCull()
|
||||
.add(14, 12, 9, 16, 15, 13)
|
||||
.d().uv(14, 9, 16, 13).noCull()
|
||||
.u().uv(14, 9, 16, 13).noCull()
|
||||
.w().uv(13, 1, 15, 4).noCull()
|
||||
.e().uv(13, 1, 15, 4).noCull() : provider.getModel(this.texture).uvLock()
|
||||
.add(0, 5, 7, 2, 16, 9)
|
||||
.d().uv(0, 7, 2, 9).noCull()
|
||||
.u().uv(0, 7, 2, 9).noCull()
|
||||
.n().uv(0, 0, 2, 11).noCull()
|
||||
.s().uv(0, 0, 2, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11)
|
||||
.e().uv(7, 0, 9, 11).noCull()
|
||||
.add(14, 5, 7, 16, 16, 9)
|
||||
.d().uv(14, 7, 16, 9).noCull()
|
||||
.u().uv(14, 7, 16, 9).noCull()
|
||||
.n().uv(14, 0, 16, 11).noCull()
|
||||
.s().uv(14, 0, 16, 11).noCull()
|
||||
.w().uv(7, 0, 9, 11).noCull()
|
||||
.e().uv(7, 0, 9, 11)
|
||||
.add(6, 6, 7, 8, 15, 9)
|
||||
.d().uv(6, 7, 8, 9).noCull()
|
||||
.u().uv(6, 7, 8, 9).noCull()
|
||||
.n().uv(6, 1, 8, 10).noCull()
|
||||
.s().uv(6, 1, 8, 10).noCull()
|
||||
.w().uv(7, 1, 9, 10).noCull()
|
||||
.e().uv(7, 1, 9, 10).noCull()
|
||||
.add(8, 6, 7, 10, 15, 9)
|
||||
.d().uv(8, 7, 10, 9).noCull()
|
||||
.u().uv(8, 7, 10, 9).noCull()
|
||||
.n().uv(8, 1, 10, 10).noCull()
|
||||
.s().uv(8, 1, 10, 10).noCull()
|
||||
.w().uv(7, 1, 9, 10).noCull()
|
||||
.e().uv(7, 1, 9, 10).noCull()
|
||||
.add(2, 6, 7, 6, 9, 9)
|
||||
.d().uv(2, 7, 6, 9).noCull()
|
||||
.u().uv(2, 7, 6, 9).noCull()
|
||||
.n().uv(2, 7, 6, 10).noCull()
|
||||
.s().uv(2, 7, 6, 10).noCull()
|
||||
.add(2, 12, 7, 6, 15, 9)
|
||||
.d().uv(2, 7, 6, 9).noCull()
|
||||
.u().uv(2, 7, 6, 9).noCull()
|
||||
.n().uv(2, 1, 6, 4).noCull()
|
||||
.s().uv(2, 1, 6, 4).noCull()
|
||||
.add(10, 6, 7, 14, 9, 9)
|
||||
.d().uv(10, 7, 14, 9).noCull()
|
||||
.u().uv(10, 7, 14, 9).noCull()
|
||||
.n().uv(10, 7, 14, 10).noCull()
|
||||
.s().uv(10, 7, 14, 10).noCull()
|
||||
.add(10, 12, 7, 14, 15, 9)
|
||||
.d().uv(10, 7, 14, 9).noCull()
|
||||
.u().uv(10, 7, 14, 9).noCull()
|
||||
.n().uv(10, 1, 14, 4).noCull()
|
||||
.s().uv(10, 1, 14, 4).noCull()))
|
||||
.rotate(ModelRotation.getNorthRot(state.getValue(FACING).getOpposite()));
|
||||
}
|
||||
|
||||
public IProperty<?>[] getIgnoredProperties() {
|
||||
return new IProperty[] {POWERED};
|
||||
}
|
||||
}
|
157
common/src/main/java/common/block/artificial/BlockFloorPortal.java
Executable file
157
common/src/main/java/common/block/artificial/BlockFloorPortal.java
Executable file
|
@ -0,0 +1,157 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.collect.Sets;
|
||||
import common.entity.Entity;
|
||||
import common.item.Item;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ParticleType;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.AWorldClient;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockFloorPortal extends Block
|
||||
{
|
||||
private static final Model floor_portal = ModelProvider.getModelProvider().getModel("floor_portal")
|
||||
.add(0, 11, 0, 16, 12, 16).du().uv(0, 0, 16, 16).noCull().nswe().uv(0, 0, 16, 1);
|
||||
|
||||
public BlockFloorPortal(Material materialIn)
|
||||
{
|
||||
super(materialIn);
|
||||
this.setLightLevel(1.0F);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Returns a new instance of a block's tile entity class. Called on placing the block.
|
||||
// */
|
||||
// public TileEntity createNewTileEntity(World worldIn, int meta)
|
||||
// {
|
||||
// return new TileEntityPortal();
|
||||
// }
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.6875F, 0.0F, 1.0F, 0.75F, 1.0F);
|
||||
}
|
||||
|
||||
// public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
// {
|
||||
// return side == Facing.DOWN ? super.shouldSideBeRendered(worldIn, pos, side) : false;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Add all collision boxes of this Block to the list that intersect with the given mask.
|
||||
*/
|
||||
public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quantity of items to drop on block destruction.
|
||||
*/
|
||||
public int quantityDropped(Random random)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called When an Entity Collided with the Block
|
||||
*/
|
||||
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, State state, Entity entityIn)
|
||||
{
|
||||
// if (entityIn.ridingEntity == null && entityIn.riddenByEntity == null && !worldIn.client && GameServer.getServer().getAllowEnd())
|
||||
// {
|
||||
// entityIn.travelToDimension(entityIn.dimension == 1 ? 0 : 1, null, 0.0f, 0.0f);
|
||||
// }
|
||||
if(entityIn.getEntityBoundingBox().intersectsWith(this.getCollisionBoundingBox(worldIn, pos, state)))
|
||||
entityIn.setFlatPortal();
|
||||
}
|
||||
|
||||
public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
double d0 = (double)((float)pos.getX() + rand.floatv());
|
||||
double d1 = (double)((float)pos.getY() + 0.8F);
|
||||
double d2 = (double)((float)pos.getZ() + rand.floatv());
|
||||
double d3 = 0.0D;
|
||||
double d4 = 0.0D;
|
||||
double d5 = 0.0D;
|
||||
worldIn.spawnParticle(ParticleType.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
public Item getItem(World worldIn, BlockPos pos)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the MapColor for this Block and the given BlockState
|
||||
// */
|
||||
// public MapColor getMapColor(IBlockState state)
|
||||
// {
|
||||
// return MapColor.blackColor;
|
||||
// }
|
||||
|
||||
private void destroyRecursive(World world, Set<BlockPos> positions, BlockPos pos, int limit) {
|
||||
for(int n = 0; n < 4; n++) {
|
||||
BlockPos npos = pos.offset(Facing.getHorizontal(n));
|
||||
if(/* !positions.contains(npos) && */ world.getState(npos).getBlock() == this) {
|
||||
positions.add(npos);
|
||||
if(limit > 0)
|
||||
destroyRecursive(world, positions, npos, limit-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBlockDestroyedByPlayer(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
Set<BlockPos> positions = Sets.newHashSet();
|
||||
positions.add(pos);
|
||||
this.destroyRecursive(worldIn, positions, pos, 10);
|
||||
for(BlockPos bpos : positions)
|
||||
worldIn.setBlockToAir(bpos);
|
||||
// for(int x = -2; x <= 2; x++) {
|
||||
// for(int z = -2; z <= 2; z++) {
|
||||
// BlockPos bpos = pos.add(x, 0, z);
|
||||
// if((x != 0 || z != 0) && worldIn.getBlockState(bpos).getBlock() == this)
|
||||
// worldIn.setBlockToAir(bpos);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public boolean isXrayVisible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return floor_portal;
|
||||
}
|
||||
|
||||
public void getAnimatedTextures(Map<String, Object> map) {
|
||||
map.put("blocks/floor_portal", 5);
|
||||
}
|
||||
}
|
396
common/src/main/java/common/block/artificial/BlockFlowerPot.java
Executable file
396
common/src/main/java/common/block/artificial/BlockFlowerPot.java
Executable file
|
@ -0,0 +1,396 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.block.foliage.BlockFlower;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Blocks;
|
||||
import common.init.ItemRegistry;
|
||||
import common.init.Items;
|
||||
import common.item.Item;
|
||||
import common.item.ItemBlock;
|
||||
import common.item.ItemStack;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyInteger;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class BlockFlowerPot extends Block // Container
|
||||
{
|
||||
private static final Model flower_pot_cactus = ModelProvider.getModelProvider().getModel("flower_pot").noOcclude()
|
||||
.add(5, 0, 5, 6, 6, 11)
|
||||
.d().uv(5, 5, 6, 11)
|
||||
.u().uv(5, 5, 6, 11).noCull()
|
||||
.n().uv(10, 10, 11, 16).noCull()
|
||||
.s().uv(5, 10, 6, 16).noCull()
|
||||
.w().uv(5, 10, 11, 16).noCull()
|
||||
.e().uv(5, 10, 11, 16).noCull()
|
||||
.add(10, 0, 5, 11, 6, 11)
|
||||
.d().uv(10, 5, 11, 11)
|
||||
.u().uv(10, 5, 11, 11).noCull()
|
||||
.n().uv(5, 10, 6, 16).noCull()
|
||||
.s().uv(10, 10, 11, 16).noCull()
|
||||
.w().uv(5, 10, 11, 16).noCull()
|
||||
.e().uv(5, 10, 11, 16).noCull()
|
||||
.add(6, 0, 5, 10, 6, 6)
|
||||
.d().uv(6, 10, 10, 11)
|
||||
.u().uv(6, 5, 10, 6).noCull()
|
||||
.n().uv(6, 10, 10, 16).noCull()
|
||||
.s().uv(6, 10, 10, 16).noCull()
|
||||
.add(6, 0, 10, 10, 6, 11)
|
||||
.d().uv(6, 5, 10, 6)
|
||||
.u().uv(6, 10, 10, 11).noCull()
|
||||
.n().uv(6, 10, 10, 16).noCull()
|
||||
.s().uv(6, 10, 10, 16).noCull()
|
||||
.add(6, 0, 6, 10, 4, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u("dirt").uv(6, 6, 10, 10).noCull()
|
||||
.add(6, 4, 6, 10, 8, 10)
|
||||
.n("cactus_side").uv(6, 8, 10, 12).noCull()
|
||||
.s("cactus_side").uv(6, 8, 10, 12).noCull()
|
||||
.w("cactus_side").uv(6, 8, 10, 12).noCull()
|
||||
.e("cactus_side").uv(6, 8, 10, 12).noCull()
|
||||
.add(6, 8, 6, 10, 12, 10)
|
||||
.n("cactus_side").uv(6, 4, 10, 8).noCull()
|
||||
.s("cactus_side").uv(6, 4, 10, 8).noCull()
|
||||
.w("cactus_side").uv(6, 4, 10, 8).noCull()
|
||||
.e("cactus_side").uv(6, 4, 10, 8).noCull()
|
||||
.add(6, 12, 6, 10, 16, 10)
|
||||
.u("cactus_side").uv(6, 6, 10, 10).noCull()
|
||||
.n("cactus_side").uv(6, 0, 10, 4).noCull()
|
||||
.s("cactus_side").uv(6, 0, 10, 4).noCull()
|
||||
.w("cactus_side").uv(6, 0, 10, 4).noCull()
|
||||
.e("cactus_side").uv(6, 0, 10, 4).noCull()
|
||||
;
|
||||
private static final Model flower_pot = ModelProvider.getModelProvider().getModel("flower_pot").noOcclude()
|
||||
.add(5, 0, 5, 6, 6, 11)
|
||||
.d().uv(5, 5, 6, 11)
|
||||
.u().uv(5, 5, 6, 11).noCull()
|
||||
.n().uv(10, 10, 11, 16).noCull()
|
||||
.s().uv(5, 10, 6, 16).noCull()
|
||||
.w().uv(5, 10, 11, 16).noCull()
|
||||
.e().uv(5, 10, 11, 16).noCull()
|
||||
.add(10, 0, 5, 11, 6, 11)
|
||||
.d().uv(10, 5, 11, 11)
|
||||
.u().uv(10, 5, 11, 11).noCull()
|
||||
.n().uv(5, 10, 6, 16).noCull()
|
||||
.s().uv(10, 10, 11, 16).noCull()
|
||||
.w().uv(5, 10, 11, 16).noCull()
|
||||
.e().uv(5, 10, 11, 16).noCull()
|
||||
.add(6, 0, 5, 10, 6, 6)
|
||||
.d().uv(6, 10, 10, 11)
|
||||
.u().uv(6, 5, 10, 6).noCull()
|
||||
.n().uv(6, 10, 10, 16).noCull()
|
||||
.s().uv(6, 10, 10, 16).noCull()
|
||||
.add(6, 0, 10, 10, 6, 11)
|
||||
.d().uv(6, 5, 10, 6)
|
||||
.u().uv(6, 10, 10, 11).noCull()
|
||||
.n().uv(6, 10, 10, 16).noCull()
|
||||
.s().uv(6, 10, 10, 16).noCull()
|
||||
.add(6, 0, 6, 10, 4, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u("dirt").uv(6, 6, 10, 10).noCull()
|
||||
;
|
||||
|
||||
public static final PropertyInteger CONTENTS = PropertyInteger.create("contents", 0, 1 + BlockFlower.EnumFlowerType.values().length);
|
||||
|
||||
public BlockFlowerPot()
|
||||
{
|
||||
super(Material.SMALL);
|
||||
this.setDefaultState(this.getBaseState().withProperty(CONTENTS, 0)); // .withProperty(LEGACY_DATA, Integer.valueOf(0)));
|
||||
this.setBlockBoundsForItemRender();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Gets the localized name of this block. Used for the statistics page.
|
||||
// */
|
||||
// public String getLocalizedName()
|
||||
// {
|
||||
// return "Blumentopf";
|
||||
// }
|
||||
|
||||
/**
|
||||
* Sets the block's bounds for rendering it as an item
|
||||
*/
|
||||
public void setBlockBoundsForItemRender()
|
||||
{
|
||||
float f = 0.375F;
|
||||
float f1 = f / 2.0F;
|
||||
this.setBlockBounds(0.5F - f1, 0.0F, 0.5F - f1, 0.5F + f1, f, 0.5F + f1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * The type of render function called. 3 for standard block models, 2 for TESR's, 1 for liquids, -1 is no render
|
||||
// */
|
||||
// public int getRenderType()
|
||||
// {
|
||||
// return 3;
|
||||
// }
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// public int colorMultiplier(IWorldAccess worldIn, BlockPos pos, int renderPass)
|
||||
// {
|
||||
// TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
//
|
||||
// if (tileentity instanceof TileEntityFlowerPot)
|
||||
// {
|
||||
// Item item = ((TileEntityFlowerPot)tileentity).getFlowerPotItem();
|
||||
//
|
||||
// if (item instanceof ItemBlock)
|
||||
// {
|
||||
// return BlockRegistry.getBlockFromItem(item).colorMultiplier(worldIn, pos, renderPass);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return 16777215;
|
||||
// }
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
ItemStack itemstack = playerIn.inventory.getCurrentItem();
|
||||
|
||||
if (itemstack != null && itemstack.getItem() instanceof ItemBlock)
|
||||
{
|
||||
if (state.getValue(CONTENTS) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Block block = itemstack.getItem().getBlock();
|
||||
|
||||
if (block != Blocks.flower && block != Blocks.cactus)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
worldIn.setState(pos, state.withProperty(CONTENTS, block == Blocks.cactus ? 1 : (2 + (itemstack.getMetadata() >=
|
||||
BlockFlower.EnumFlowerType.values().length ? 0 : itemstack.getMetadata()))), 2);
|
||||
// tileentityflowerpot.setFlowerPotData(itemstack.getItem(), itemstack.getMetadata());
|
||||
// tileentityflowerpot.markDirty();
|
||||
// worldIn.markBlockForUpdate(pos);
|
||||
// playerIn.triggerAchievement(StatRegistry.flowerPottedStat);
|
||||
|
||||
if (/* !playerIn.creative && */ --itemstack.stackSize <= 0)
|
||||
{
|
||||
playerIn.inventory.setInventorySlotContents(playerIn.inventory.currentItem, (ItemStack)null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Item getItem(World worldIn, BlockPos pos)
|
||||
{
|
||||
State state = worldIn.getState(pos);
|
||||
return state.getBlock() == this ? (state.getValue(CONTENTS) == 1 ? ItemRegistry.getItemFromBlock(Blocks.cactus) :
|
||||
(state.getValue(CONTENTS) >= 2 ? ItemRegistry.getItemFromBlock(Blocks.flower) : Items.flower_pot)) : Items.flower_pot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the meta to use for the Pick Block ItemStack result
|
||||
*/
|
||||
public int getDamageValue(World worldIn, BlockPos pos)
|
||||
{
|
||||
State state = worldIn.getState(pos);
|
||||
return state.getBlock() == this && state.getValue(CONTENTS) >= 2 ? state.getValue(CONTENTS) - 2 : 0;
|
||||
}
|
||||
|
||||
public boolean isPickStrict()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return super.canPlaceBlockAt(worldIn, pos) && worldIn.isBlockSolid(pos.down());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
if (!worldIn.isBlockSolid(pos.down()))
|
||||
{
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state)
|
||||
{
|
||||
int type = state.getValue(CONTENTS);
|
||||
if(type > 0)
|
||||
spawnAsEntity(worldIn, pos, new ItemStack(type == 1 ? Blocks.cactus : Blocks.flower, 1, type == 1 ? 0 : (type - 2)));
|
||||
super.onBlockRemoved(worldIn, pos, state);
|
||||
}
|
||||
|
||||
// public void onBlockHarvested(World worldIn, BlockPos pos, IBlockState state, EntityNPC player)
|
||||
// {
|
||||
// super.onBlockHarvested(worldIn, pos, state, player);
|
||||
//
|
||||
// if (player.capabilities.isCreativeMode)
|
||||
// {
|
||||
// TileEntityFlowerPot tileentityflowerpot = this.getTileEntity(worldIn, pos);
|
||||
//
|
||||
// if (tileentityflowerpot != null)
|
||||
// {
|
||||
// tileentityflowerpot.setFlowerPotData((Item)null, 0);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the Item that this Block should drop when harvested.
|
||||
*/
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return Items.flower_pot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(CONTENTS, Math.min(meta, BlockFlower.EnumFlowerType.values().length + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return state.getValue(CONTENTS);
|
||||
}
|
||||
|
||||
// private TileEntityFlowerPot getTileEntity(World worldIn, BlockPos pos)
|
||||
// {
|
||||
// TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
// return tileentity instanceof TileEntityFlowerPot ? (TileEntityFlowerPot)tileentity : null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns a new instance of a block's tile entity class. Called on placing the block.
|
||||
// */
|
||||
// public TileEntity createNewTileEntity(World worldIn, int meta)
|
||||
// {
|
||||
// return new TileEntityFlowerPot(null, 0);
|
||||
// }
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {CONTENTS};
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the actual Block state of this Block at the given position. This applies properties not visible in the
|
||||
// * metadata, such as fence connections.
|
||||
// */
|
||||
// public IBlockState getActualState(IBlockState state, IWorldAccess worldIn, BlockPos pos)
|
||||
// {
|
||||
// int type = 0;
|
||||
// TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
//
|
||||
// if (tileentity instanceof TileEntityFlowerPot)
|
||||
// {
|
||||
// TileEntityFlowerPot tileentityflowerpot = (TileEntityFlowerPot)tileentity;
|
||||
// Item item = tileentityflowerpot.getFlowerPotItem();
|
||||
//
|
||||
// if (item instanceof ItemBlock)
|
||||
// {
|
||||
// int i = tileentityflowerpot.getFlowerPotData();
|
||||
// Block block = BlockRegistry.getBlockFromItem(item);
|
||||
// if (block == Blocks.flower)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// else if (block == Blocks.cactus)
|
||||
// {
|
||||
// type = 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return state.withProperty(CONTENTS, type);
|
||||
// }
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return BlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
switch(state.getValue(CONTENTS)) {
|
||||
case 0:
|
||||
return flower_pot;
|
||||
case 1:
|
||||
return flower_pot_cactus;
|
||||
// case FERN:
|
||||
// return flower_pot_fern;
|
||||
default:
|
||||
String plant = BlockFlower.EnumFlowerType.getType(BlockFlower.EnumFlowerColor.BASE, state.getValue(CONTENTS) - 2).getName().toLowerCase();
|
||||
return provider.getModel("flower_pot").noOcclude()
|
||||
.add(5, 0, 5, 6, 6, 11)
|
||||
.d().uv(5, 5, 6, 11)
|
||||
.u().uv(5, 5, 6, 11).noCull()
|
||||
.n().uv(10, 10, 11, 16).noCull()
|
||||
.s().uv(5, 10, 6, 16).noCull()
|
||||
.w().uv(5, 10, 11, 16).noCull()
|
||||
.e().uv(5, 10, 11, 16).noCull()
|
||||
.add(10, 0, 5, 11, 6, 11)
|
||||
.d().uv(10, 5, 11, 11)
|
||||
.u().uv(10, 5, 11, 11).noCull()
|
||||
.n().uv(5, 10, 6, 16).noCull()
|
||||
.s().uv(10, 10, 11, 16).noCull()
|
||||
.w().uv(5, 10, 11, 16).noCull()
|
||||
.e().uv(5, 10, 11, 16).noCull()
|
||||
.add(6, 0, 5, 10, 6, 6)
|
||||
.d().uv(6, 10, 10, 11)
|
||||
.u().uv(6, 5, 10, 6).noCull()
|
||||
.n().uv(6, 10, 10, 16).noCull()
|
||||
.s().uv(6, 10, 10, 16).noCull()
|
||||
.add(6, 0, 10, 10, 6, 11)
|
||||
.d().uv(6, 5, 10, 6)
|
||||
.u().uv(6, 10, 10, 11).noCull()
|
||||
.n().uv(6, 10, 10, 16).noCull()
|
||||
.s().uv(6, 10, 10, 16).noCull()
|
||||
.add(6, 0, 6, 10, 4, 10)
|
||||
.d().uv(6, 6, 10, 10)
|
||||
.u("dirt").uv(6, 6, 10, 10).noCull()
|
||||
.add(2.6f, 4, 8, 13.4f, 16, 8).rotate(8, 8, 8, Facing.Axis.Y, 45, true)
|
||||
.n(plant).uv(0, 0, 16, 16).noCull()
|
||||
.s(plant).uv(0, 0, 16, 16).noCull()
|
||||
.add(8, 4, 2.6f, 8, 16, 13.4f).rotate(8, 8, 8, Facing.Axis.Y, 45, true)
|
||||
.w(plant).uv(0, 0, 16, 16).noCull()
|
||||
.e(plant).uv(0, 0, 16, 16).noCull();
|
||||
}
|
||||
}
|
||||
}
|
44
common/src/main/java/common/block/artificial/BlockGlass.java
Executable file
44
common/src/main/java/common/block/artificial/BlockGlass.java
Executable file
|
@ -0,0 +1,44 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.item.CheatTab;
|
||||
import common.model.BlockLayer;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockGlass extends Block {
|
||||
public BlockGlass() {
|
||||
super(Material.TRANSLUCENT);
|
||||
this.setTab(CheatTab.BLOCKS);
|
||||
}
|
||||
|
||||
public int quantityDropped(Random rand) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer() {
|
||||
return BlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canSilkHarvest() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess world, BlockPos pos, Facing side) {
|
||||
State state = world.getState(pos);
|
||||
Block block = state.getBlock();
|
||||
return world.getState(pos.offset(side.getOpposite())) != state || (block != this && super.shouldSideBeRendered(world, pos, side));
|
||||
}
|
||||
}
|
82
common/src/main/java/common/block/artificial/BlockHay.java
Executable file
82
common/src/main/java/common/block/artificial/BlockHay.java
Executable file
|
@ -0,0 +1,82 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.BlockRotatedPillar;
|
||||
import common.block.Material;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.ItemRegistry;
|
||||
import common.item.CheatTab;
|
||||
import common.item.ItemStack;
|
||||
import common.properties.IProperty;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockHay extends BlockRotatedPillar
|
||||
{
|
||||
public BlockHay()
|
||||
{
|
||||
super(Material.LOOSE);
|
||||
this.setDefaultState(this.getBaseState().withProperty(AXIS, Facing.Axis.Y));
|
||||
this.setTab(CheatTab.BLOCKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
Facing.Axis enumfacing$axis = Facing.Axis.Y;
|
||||
int i = meta & 12;
|
||||
|
||||
if (i == 4)
|
||||
{
|
||||
enumfacing$axis = Facing.Axis.X;
|
||||
}
|
||||
else if (i == 8)
|
||||
{
|
||||
enumfacing$axis = Facing.Axis.Z;
|
||||
}
|
||||
|
||||
return this.getState().withProperty(AXIS, enumfacing$axis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
int i = 0;
|
||||
Facing.Axis enumfacing$axis = (Facing.Axis)state.getValue(AXIS);
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.X)
|
||||
{
|
||||
i |= 4;
|
||||
}
|
||||
else if (enumfacing$axis == Facing.Axis.Z)
|
||||
{
|
||||
i |= 8;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {AXIS};
|
||||
}
|
||||
|
||||
public ItemStack createStackedBlock(State state)
|
||||
{
|
||||
return new ItemStack(ItemRegistry.getItemFromBlock(this), 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
||||
* IBlockstate
|
||||
*/
|
||||
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
||||
{
|
||||
return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer).withProperty(AXIS, facing.getAxis());
|
||||
}
|
||||
}
|
176
common/src/main/java/common/block/artificial/BlockLadder.java
Executable file
176
common/src/main/java/common/block/artificial/BlockLadder.java
Executable file
|
@ -0,0 +1,176 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockDirectional;
|
||||
import common.block.Material;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.item.CheatTab;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockLadder extends Block
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL);
|
||||
|
||||
public BlockLadder()
|
||||
{
|
||||
super(Material.SMALL);
|
||||
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH));
|
||||
this.setTab(CheatTab.WOOD);
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState(worldIn, pos);
|
||||
return super.getCollisionBoundingBox(worldIn, pos, state);
|
||||
}
|
||||
|
||||
public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState(worldIn, pos);
|
||||
return super.getSelectedBoundingBox(worldIn, pos);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
|
||||
if (iblockstate.getBlock() == this)
|
||||
{
|
||||
float f = 0.125F;
|
||||
|
||||
switch ((Facing)iblockstate.getValue(FACING))
|
||||
{
|
||||
case NORTH:
|
||||
this.setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
this.setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
default:
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return worldIn.getState(pos.west()).getBlock().isNormalCube() ? true : (worldIn.getState(pos.east()).getBlock().isNormalCube() ? true : (worldIn.getState(pos.north()).getBlock().isNormalCube() ? true : worldIn.getState(pos.south()).getBlock().isNormalCube()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
||||
* IBlockstate
|
||||
*/
|
||||
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
||||
{
|
||||
if (facing.getAxis().isHorizontal() && this.canBlockStay(worldIn, pos, facing))
|
||||
{
|
||||
return this.getState().withProperty(FACING, facing);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Facing enumfacing : Facing.Plane.HORIZONTAL)
|
||||
{
|
||||
if (this.canBlockStay(worldIn, pos, enumfacing))
|
||||
{
|
||||
return this.getState().withProperty(FACING, enumfacing);
|
||||
}
|
||||
}
|
||||
|
||||
return this.getState();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
Facing enumfacing = (Facing)state.getValue(FACING);
|
||||
|
||||
if (!this.canBlockStay(worldIn, pos, enumfacing))
|
||||
{
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
|
||||
super.onNeighborBlockChange(worldIn, pos, state, neighborBlock);
|
||||
}
|
||||
|
||||
protected boolean canBlockStay(World worldIn, BlockPos pos, Facing facing)
|
||||
{
|
||||
return worldIn.getState(pos.offset(facing.getOpposite())).getBlock().isNormalCube();
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return BlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
Facing enumfacing = Facing.getFront(meta);
|
||||
|
||||
if (enumfacing.getAxis() == Facing.Axis.Y)
|
||||
{
|
||||
enumfacing = Facing.NORTH;
|
||||
}
|
||||
|
||||
return this.getState().withProperty(FACING, enumfacing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((Facing)state.getValue(FACING)).getIndex();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {FACING};
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel("ladder").noOcclude()
|
||||
.add(0, 0, 15.2f, 16, 16, 15.2f).noShade()
|
||||
.n().uv(0, 0, 16, 16).noCull()
|
||||
.s().uv(0, 0, 16, 16).noCull()
|
||||
.rotate(ModelRotation.getNorthRot(state.getValue(BlockDirectional.FACING)));
|
||||
}
|
||||
}
|
495
common/src/main/java/common/block/artificial/BlockPane.java
Executable file
495
common/src/main/java/common/block/artificial/BlockPane.java
Executable file
|
@ -0,0 +1,495 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.entity.Entity;
|
||||
import common.init.Blocks;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyBool;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockPane extends Block
|
||||
{
|
||||
public static final PropertyBool NORTH = PropertyBool.create("north");
|
||||
public static final PropertyBool EAST = PropertyBool.create("east");
|
||||
public static final PropertyBool SOUTH = PropertyBool.create("south");
|
||||
public static final PropertyBool WEST = PropertyBool.create("west");
|
||||
private final boolean canDrop;
|
||||
|
||||
public BlockPane(Material materialIn, boolean canDrop)
|
||||
{
|
||||
super(materialIn);
|
||||
this.setDefaultState(this.getBaseState().withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)));
|
||||
this.canDrop = canDrop;
|
||||
this.setTab(CheatTab.BLOCKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual Block state of this Block at the given position. This applies properties not visible in the
|
||||
* metadata, such as fence connections.
|
||||
*/
|
||||
public State getActualState(State state, IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return state.withProperty(NORTH, Boolean.valueOf(this.canPaneConnectToBlock(worldIn.getState(pos.north()).getBlock()))).withProperty(SOUTH, Boolean.valueOf(this.canPaneConnectToBlock(worldIn.getState(pos.south()).getBlock()))).withProperty(WEST, Boolean.valueOf(this.canPaneConnectToBlock(worldIn.getState(pos.west()).getBlock()))).withProperty(EAST, Boolean.valueOf(this.canPaneConnectToBlock(worldIn.getState(pos.east()).getBlock())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Item that this Block should drop when harvested.
|
||||
*/
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return !this.canDrop ? null : super.getItemDropped(state, rand, fortune);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
return worldIn.getState(pos).getBlock() == this ? false : super.shouldSideBeRendered(worldIn, pos, side);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all collision boxes of this Block to the list that intersect with the given mask.
|
||||
*/
|
||||
public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
|
||||
{
|
||||
boolean flag = this.canPaneConnectToBlock(worldIn.getState(pos.north()).getBlock());
|
||||
boolean flag1 = this.canPaneConnectToBlock(worldIn.getState(pos.south()).getBlock());
|
||||
boolean flag2 = this.canPaneConnectToBlock(worldIn.getState(pos.west()).getBlock());
|
||||
boolean flag3 = this.canPaneConnectToBlock(worldIn.getState(pos.east()).getBlock());
|
||||
|
||||
if ((!flag2 || !flag3) && (flag2 || flag3 || flag || flag1))
|
||||
{
|
||||
if (flag2)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.4375F, 0.5F, 1.0F, 0.5625F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
else if (flag3)
|
||||
{
|
||||
this.setBlockBounds(0.5F, 0.0F, 0.4375F, 1.0F, 1.0F, 0.5625F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.4375F, 1.0F, 1.0F, 0.5625F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
|
||||
if ((!flag || !flag1) && (flag2 || flag3 || flag || flag1))
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
this.setBlockBounds(0.4375F, 0.0F, 0.0F, 0.5625F, 1.0F, 0.5F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
else if (flag1)
|
||||
{
|
||||
this.setBlockBounds(0.4375F, 0.0F, 0.5F, 0.5625F, 1.0F, 1.0F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.4375F, 0.0F, 0.0F, 0.5625F, 1.0F, 1.0F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block's bounds for rendering it as an item
|
||||
*/
|
||||
public void setBlockBoundsForItemRender()
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
float f = 0.4375F;
|
||||
float f1 = 0.5625F;
|
||||
float f2 = 0.4375F;
|
||||
float f3 = 0.5625F;
|
||||
boolean flag = this.canPaneConnectToBlock(worldIn.getState(pos.north()).getBlock());
|
||||
boolean flag1 = this.canPaneConnectToBlock(worldIn.getState(pos.south()).getBlock());
|
||||
boolean flag2 = this.canPaneConnectToBlock(worldIn.getState(pos.west()).getBlock());
|
||||
boolean flag3 = this.canPaneConnectToBlock(worldIn.getState(pos.east()).getBlock());
|
||||
|
||||
if ((!flag2 || !flag3) && (flag2 || flag3 || flag || flag1))
|
||||
{
|
||||
if (flag2)
|
||||
{
|
||||
f = 0.0F;
|
||||
}
|
||||
else if (flag3)
|
||||
{
|
||||
f1 = 1.0F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
f = 0.0F;
|
||||
f1 = 1.0F;
|
||||
}
|
||||
|
||||
if ((!flag || !flag1) && (flag2 || flag3 || flag || flag1))
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
f2 = 0.0F;
|
||||
}
|
||||
else if (flag1)
|
||||
{
|
||||
f3 = 1.0F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
f2 = 0.0F;
|
||||
f3 = 1.0F;
|
||||
}
|
||||
|
||||
this.setBlockBounds(f, 0.0F, f2, f1, 1.0F, f3);
|
||||
}
|
||||
|
||||
public final boolean canPaneConnectToBlock(Block blockIn)
|
||||
{
|
||||
return blockIn.isFullBlock() || blockIn == this || blockIn == Blocks.glass || blockIn == Blocks.stained_glass || blockIn == Blocks.stained_glass_pane || blockIn instanceof BlockPane;
|
||||
}
|
||||
|
||||
public boolean canSilkHarvest()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return BlockLayer.CUTOUT_MIPPED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {NORTH, EAST, WEST, SOUTH};
|
||||
}
|
||||
|
||||
public boolean isMagnetic() {
|
||||
return this.material == Material.SOLID;
|
||||
}
|
||||
|
||||
protected String getPaneBase(State state) {
|
||||
return "glass";
|
||||
}
|
||||
|
||||
protected String getPaneEdge(State state) {
|
||||
return "glass_pane";
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
boolean n = state.getValue(NORTH);
|
||||
boolean s = state.getValue(SOUTH);
|
||||
boolean w = state.getValue(WEST);
|
||||
boolean e = state.getValue(EAST);
|
||||
int sides = (n ? 1 : 0) + (s ? 1 : 0) + (w ? 1 : 0) + (e ? 1 : 0);
|
||||
if(this.canDrop) {
|
||||
if(sides == 0 || sides == 4)
|
||||
return provider.getModel(name).noOcclude()
|
||||
.add(8, 0, 0, 8, 16, 16)
|
||||
.w().uv(0, 0, 16, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.add(7, 0, 0, 9, 16, 16)
|
||||
.n().uv(7, 0, 9, 16)
|
||||
.s().uv(7, 0, 9, 16)
|
||||
.add(7, 0.005f, 0, 9, 15.995f, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(9, 0, 7, 16).noCull()
|
||||
.add(0, 0, 8, 16, 16, 8)
|
||||
.n().uv(0, 0, 16, 16).noCull()
|
||||
.s().uv(0, 0, 16, 16).noCull()
|
||||
.add(0, 0, 7, 16, 16, 9)
|
||||
.w().uv(7, 0, 9, 16)
|
||||
.e().uv(7, 0, 9, 16)
|
||||
.add(0, 0.005f, 7, 7, 15.995f, 9)
|
||||
.d().uv(9, 9, 7, 16).rot(90).noCull()
|
||||
.u().uv(7, 9, 9, 16).rot(90).noCull()
|
||||
.add(9, 0.005f, 7, 16, 15.995f, 9)
|
||||
.d().uv(9, 0, 7, 7).rot(90).noCull()
|
||||
.u().uv(7, 0, 9, 7).rot(90).noCull();
|
||||
else if(sides == 1)
|
||||
return provider.getModel(name).noOcclude()
|
||||
.add(8, 0, 0, 8, 16, 8)
|
||||
.w().uv(8, 0, 16, 16).noCull()
|
||||
.e().uv(8, 0, 16, 16).noCull()
|
||||
.add(7, 0, 0, 9, 16, 9)
|
||||
.n().uv(7, 0, 9, 16)
|
||||
.s().uv(7, 0, 9, 16).noCull()
|
||||
.add(7, 0.005f, 0, 9, 15.995f, 9)
|
||||
.d().uv(9, 0, 7, 9).noCull()
|
||||
.u().uv(7, 0, 9, 9).noCull()
|
||||
.rotate(n ? ModelRotation.X0_Y0 : (s ? ModelRotation.X0_Y180 : (w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90)));
|
||||
else if(sides == 2 && ((e != w) || (n != s)))
|
||||
return provider.getModel(name).noOcclude()
|
||||
.add(8, 0, 0, 8, 16, 8)
|
||||
.w().uv(0, 0, 8, 16).noCull()
|
||||
.e().uv(8, 0, 16, 16).noCull()
|
||||
.add(7, 0, 0, 9, 16, 0)
|
||||
.n().uv(7, 0, 9, 16)
|
||||
.add(7, 0.005f, 0, 9, 15.995f, 9)
|
||||
.d().uv(9, 0, 7, 9).noCull()
|
||||
.u().uv(7, 0, 9, 9).noCull()
|
||||
.add(8, 0, 8, 16, 16, 8)
|
||||
.n().uv(0, 0, 8, 16).noCull()
|
||||
.s().uv(8, 0, 16, 16).noCull()
|
||||
.add(0, 0, 7, 16, 16, 9)
|
||||
.e().uv(7, 0, 9, 16)
|
||||
.add(9, 0.005f, 7, 16, 15.995f, 9)
|
||||
.d().uv(9, 0, 7, 7).rot(90).noCull()
|
||||
.u().uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.rotate(n && e ? ModelRotation.X0_Y0 : (s && w ? ModelRotation.X0_Y180 :
|
||||
(n && w ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90)));
|
||||
else if(sides == 2)
|
||||
return provider.getModel(name).noOcclude()
|
||||
.add(8, 0, 0, 8, 16, 16)
|
||||
.w().uv(0, 0, 16, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.add(7, 0, 0, 9, 16, 16)
|
||||
.n().uv(7, 0, 9, 16)
|
||||
.s().uv(7, 0, 9, 16)
|
||||
.add(7, 0.005f, 0, 9, 15.995f, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(9, 0, 7, 16).noCull()
|
||||
.rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90);
|
||||
else
|
||||
return provider.getModel(name).noOcclude()
|
||||
.add(8, 0, 0, 8, 16, 16)
|
||||
.w().uv(0, 0, 16, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.add(7, 0, 0, 9, 16, 16)
|
||||
.n().uv(7, 0, 9, 16)
|
||||
.s().uv(7, 0, 9, 16)
|
||||
.add(7, 0.005f, 0, 9, 15.995f, 16)
|
||||
.d().uv(7, 0, 9, 16).noCull()
|
||||
.u().uv(9, 0, 7, 16).noCull()
|
||||
.add(8, 0, 8, 16, 16, 8)
|
||||
.n().uv(0, 0, 8, 16).noCull()
|
||||
.s().uv(8, 0, 16, 16).noCull()
|
||||
.add(0, 0, 7, 16, 16, 9)
|
||||
.e().uv(7, 0, 9, 16)
|
||||
.add(9, 0.005f, 7, 16, 15.995f, 9)
|
||||
.d().uv(9, 0, 7, 7).rot(90).noCull()
|
||||
.u().uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.rotate(!w ? ModelRotation.X0_Y0 : (!e ? ModelRotation.X0_Y180 : (!s ? ModelRotation.X0_Y270 : ModelRotation.X0_Y90)));
|
||||
}
|
||||
else {
|
||||
String pane = this.getPaneBase(state);
|
||||
String edge = this.getPaneEdge(state);
|
||||
if(sides == 0 || sides == 4)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 0, 9, 16).noCull()
|
||||
.u(edge).uv(7, 0, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16)
|
||||
.w().uv(0, 0, 16, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.add(0, 0, 7, 16, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 16).rot(90).noCull()
|
||||
.u(edge).uv(7, 0, 9, 16).rot(90).noCull()
|
||||
.n().uv(0, 0, 16, 16).noCull()
|
||||
.s().uv(0, 0, 16, 16).noCull()
|
||||
.w(edge).uv(7, 0, 9, 16)
|
||||
.e(edge).uv(7, 0, 9, 16);
|
||||
else if(sides == 1 && (n || e))
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 9).noCull()
|
||||
.u(edge).uv(7, 0, 9, 9).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(16, 0, 7, 16).noCull()
|
||||
.e().uv(7, 0, 16, 16).noCull()
|
||||
.rotate(n ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90);
|
||||
else if(sides == 1)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 7, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 7, 9, 16).noCull()
|
||||
.u(edge).uv(7, 7, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(9, 0, 0, 16).noCull()
|
||||
.e().uv(0, 0, 9, 16).noCull()
|
||||
.rotate(s ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90);
|
||||
else if(e && n && !s && !w)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 9).noCull()
|
||||
.u(edge).uv(7, 0, 9, 9).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(16, 0, 7, 16).noCull()
|
||||
.e().uv(7, 0, 16, 16).noCull()
|
||||
.add(9, 0, 7, 16, 16, 9).noShade()
|
||||
.d(edge).uv(7, 9, 9, 16).rot(90).noCull()
|
||||
.u(edge).uv(7, 9, 9, 16).rot(90).noCull()
|
||||
.n().uv(16, 0, 9, 16).noCull()
|
||||
.s().uv(9, 0, 16, 16).noCull()
|
||||
.w().uv(7, 0, 9, 16).noCull()
|
||||
.e(edge).uv(7, 0, 9, 16);
|
||||
else if(e && !n && s && !w)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 7, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 7, 9, 16).noCull()
|
||||
.u(edge).uv(7, 7, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(9, 0, 0, 16).noCull()
|
||||
.e().uv(0, 0, 9, 16).noCull()
|
||||
.add(9, 0, 7, 16, 16, 9).noShade()
|
||||
.d(edge).uv(7, 9, 9, 16).rot(90).noCull()
|
||||
.u(edge).uv(7, 9, 9, 16).rot(90).noCull()
|
||||
.n().uv(16, 0, 9, 16).noCull()
|
||||
.s().uv(9, 0, 16, 16).noCull()
|
||||
.w().uv(7, 0, 9, 16).noCull()
|
||||
.e(edge).uv(7, 0, 9, 16);
|
||||
else if(!e && !n && s && w)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 7, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 7, 9, 16).noCull()
|
||||
.u(edge).uv(7, 7, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(9, 0, 0, 16).noCull()
|
||||
.e().uv(0, 0, 9, 16).noCull()
|
||||
.add(0, 0, 7, 7, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.u(edge).uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.n().uv(7, 0, 0, 16).noCull()
|
||||
.s().uv(0, 0, 7, 16).noCull()
|
||||
.w(edge).uv(7, 0, 9, 16)
|
||||
.e().uv(7, 0, 9, 16).noCull();
|
||||
else if(!e && n && !s && w)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 9).noCull()
|
||||
.u(edge).uv(7, 0, 9, 9).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(16, 0, 7, 16).noCull()
|
||||
.e().uv(7, 0, 16, 16).noCull()
|
||||
.add(0, 0, 7, 7, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.u(edge).uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.n().uv(7, 0, 0, 16).noCull()
|
||||
.s().uv(0, 0, 7, 16).noCull()
|
||||
.w(edge).uv(7, 0, 9, 16)
|
||||
.e().uv(7, 0, 9, 16).noCull();
|
||||
else if((!e && n && s && !w) || (e && !n && !s && w))
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 0, 9, 16).noCull()
|
||||
.u(edge).uv(7, 0, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16).noCull()
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(16, 0, 0, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.rotate(s ? ModelRotation.X0_Y0 : ModelRotation.X0_Y90);
|
||||
else if(!w)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 0, 9, 16).noCull()
|
||||
.u(edge).uv(7, 0, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16)
|
||||
.w().uv(16, 0, 0, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.add(9, 0, 7, 16, 16, 9).noShade()
|
||||
.d(edge).uv(7, 9, 9, 16).rot(90).noCull()
|
||||
.u(edge).uv(7, 9, 9, 16).rot(90).noCull()
|
||||
.n().uv(16, 0, 9, 16).noCull()
|
||||
.s().uv(9, 0, 16, 16).noCull()
|
||||
.w(edge).uv(7, 0, 9, 16).noCull()
|
||||
.e(edge).uv(7, 0, 9, 16);
|
||||
else if(!n)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 9, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 9, 9, 16).noCull()
|
||||
.u(edge).uv(7, 9, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16).noCull()
|
||||
.s(edge).uv(7, 0, 9, 16)
|
||||
.w().uv(7, 0, 0, 16).noCull()
|
||||
.e().uv(0, 0, 7, 16).noCull()
|
||||
.add(0, 0, 7, 16, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 16).rot(90).noCull()
|
||||
.u(edge).uv(7, 0, 9, 16).rot(90).noCull()
|
||||
.n().uv(16, 0, 0, 16).noCull()
|
||||
.s().uv(0, 0, 16, 16).noCull()
|
||||
.w(edge).uv(7, 0, 9, 16)
|
||||
.e(edge).uv(7, 0, 9, 16);
|
||||
else if(!e)
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 16).noShade()
|
||||
.d(edge).uv(7, 0, 9, 16).noCull()
|
||||
.u(edge).uv(7, 0, 9, 16).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16)
|
||||
.w().uv(16, 0, 0, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.add(0, 0, 7, 7, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.u(edge).uv(7, 0, 9, 7).rot(90).noCull()
|
||||
.n().uv(7, 0, 0, 16).noCull()
|
||||
.s().uv(0, 0, 7, 16).noCull()
|
||||
.w(edge).uv(7, 0, 9, 16).cull(Facing.EAST)
|
||||
.e(edge).uv(7, 0, 9, 16).noCull();
|
||||
else
|
||||
return provider.getModel(pane).noOcclude()
|
||||
.add(7, 0, 0, 9, 16, 7).noShade()
|
||||
.d(edge).uv(7, 0, 9, 7).noCull()
|
||||
.u(edge).uv(7, 0, 9, 7).noCull()
|
||||
.n(edge).uv(7, 0, 9, 16)
|
||||
.s(edge).uv(7, 0, 9, 16).noCull()
|
||||
.w().uv(16, 0, 9, 16).noCull()
|
||||
.e().uv(9, 0, 16, 16).noCull()
|
||||
.add(0, 0, 7, 16, 16, 9).noShade()
|
||||
.d(edge).uv(7, 0, 9, 16).rot(90).noCull()
|
||||
.u(edge).uv(7, 0, 9, 16).rot(90).noCull()
|
||||
.n().uv(16, 0, 0, 16).noCull()
|
||||
.s().uv(0, 0, 16, 16).noCull()
|
||||
.w(edge).uv(7, 0, 9, 16)
|
||||
.e(edge).uv(7, 0, 9, 16);
|
||||
}
|
||||
}
|
||||
}
|
524
common/src/main/java/common/block/artificial/BlockPortal.java
Executable file
524
common/src/main/java/common/block/artificial/BlockPortal.java
Executable file
|
@ -0,0 +1,524 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.block.natural.BlockFire;
|
||||
import common.entity.Entity;
|
||||
import common.init.Blocks;
|
||||
import common.item.Item;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ParticleType;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.properties.PropertyInteger;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.util.Facing.Axis;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.AWorldClient;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockPortal extends Block
|
||||
{
|
||||
public static final PropertyEnum<Facing.Axis> AXIS = PropertyEnum.<Facing.Axis>create("axis", Facing.Axis.class, Facing.Axis.X, Facing.Axis.Z);
|
||||
public static final PropertyInteger DIM = PropertyInteger.create("dim", 0, 7);
|
||||
|
||||
private static final int[] COLORS = new int[] {0x000000, 0xff0000, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0xff00ff, 0xffffff};
|
||||
|
||||
public BlockPortal()
|
||||
{
|
||||
super(Material.PORTAL);
|
||||
this.setDefaultState(this.getBaseState().withProperty(AXIS, Facing.Axis.X).withProperty(DIM, 0));
|
||||
// this.setTickRandomly();
|
||||
}
|
||||
|
||||
// public void updateTick(IWorldServer worldIn, BlockPos pos, IBlockState state, Random rand)
|
||||
// {
|
||||
//// super.updateTick(worldIn, pos, state, rand);
|
||||
//
|
||||
// if (/* worldIn.isPrimary() && */ Config.mobSpawning && Config.pigmanPortalChance > 0 && rand.zrange(Config.pigmanPortalChance) < worldIn.getDifficulty().getId())
|
||||
// {
|
||||
// int i = pos.getY();
|
||||
// BlockPos blockpos;
|
||||
//
|
||||
// for (blockpos = pos; !worldIn.isBlockSolid(blockpos) && blockpos.getY() > 0; blockpos = blockpos.down())
|
||||
// {
|
||||
// ;
|
||||
// }
|
||||
//
|
||||
// if (i > 0 && !worldIn.getBlockState(blockpos.up()).getBlock().isNormalCube())
|
||||
// {
|
||||
// Entity entity = ItemMonsterPlacer.spawnCreature(worldIn, 57, (double)blockpos.getX() + 0.5D, (double)blockpos.getY() + 1.1D, (double)blockpos.getZ() + 0.5D);
|
||||
//
|
||||
// if (entity != null)
|
||||
// {
|
||||
// entity.portalTimer = entity.getPortalCooldown();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
Facing.Axis enumfacing$axis = (Facing.Axis)worldIn.getState(pos).getValue(AXIS);
|
||||
float f = 0.125F;
|
||||
float f1 = 0.125F;
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.X)
|
||||
{
|
||||
f = 0.5F;
|
||||
}
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.Z)
|
||||
{
|
||||
f1 = 0.5F;
|
||||
}
|
||||
|
||||
this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, 1.0F, 0.5F + f1);
|
||||
}
|
||||
|
||||
public static int getMetaForAxis(Facing.Axis axis)
|
||||
{
|
||||
return axis == Facing.Axis.X ? 1 : (axis == Facing.Axis.Z ? 2 : 0);
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOpaqueCube() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer() {
|
||||
return BlockLayer.TRANSLUCENT;
|
||||
}
|
||||
|
||||
public boolean tryIgnitePortal(World worldIn, BlockPos pos, int dim)
|
||||
{
|
||||
BlockPortal.Size size = new BlockPortal.Size(worldIn, pos, Facing.Axis.X, dim);
|
||||
|
||||
if (size.func_150860_b() && size.field_150864_e == 0)
|
||||
{
|
||||
size.func_150859_c();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPortal.Size size2 = new BlockPortal.Size(worldIn, pos, Facing.Axis.Z, dim);
|
||||
|
||||
if (size2.func_150860_b() && size2.field_150864_e == 0)
|
||||
{
|
||||
size2.func_150859_c();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
Facing.Axis enumfacing$axis = (Facing.Axis)state.getValue(AXIS);
|
||||
int dim = state.getValue(DIM);
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.X)
|
||||
{
|
||||
BlockPortal.Size blockportal$size = new BlockPortal.Size(worldIn, pos, Facing.Axis.X, dim);
|
||||
|
||||
if (!blockportal$size.func_150860_b() || blockportal$size.field_150864_e < blockportal$size.field_150868_h * blockportal$size.height)
|
||||
{
|
||||
worldIn.setState(pos, Blocks.air.getState());
|
||||
}
|
||||
}
|
||||
else if (enumfacing$axis == Facing.Axis.Z)
|
||||
{
|
||||
BlockPortal.Size blockportal$size1 = new BlockPortal.Size(worldIn, pos, Facing.Axis.Z, dim);
|
||||
|
||||
if (!blockportal$size1.func_150860_b() || blockportal$size1.field_150864_e < blockportal$size1.field_150868_h * blockportal$size1.height)
|
||||
{
|
||||
worldIn.setState(pos, Blocks.air.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
Facing.Axis enumfacing$axis = null;
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
|
||||
if (worldIn.getState(pos).getBlock() == this)
|
||||
{
|
||||
enumfacing$axis = (Facing.Axis)iblockstate.getValue(AXIS);
|
||||
|
||||
if (enumfacing$axis == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.Z && side != Facing.EAST && side != Facing.WEST)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enumfacing$axis == Facing.Axis.X && side != Facing.SOUTH && side != Facing.NORTH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean flag = worldIn.getState(pos.west()).getBlock() == this && worldIn.getState(pos.west(2)).getBlock() != this;
|
||||
boolean flag1 = worldIn.getState(pos.east()).getBlock() == this && worldIn.getState(pos.east(2)).getBlock() != this;
|
||||
boolean flag2 = worldIn.getState(pos.north()).getBlock() == this && worldIn.getState(pos.north(2)).getBlock() != this;
|
||||
boolean flag3 = worldIn.getState(pos.south()).getBlock() == this && worldIn.getState(pos.south(2)).getBlock() != this;
|
||||
boolean flag4 = flag || flag1 || enumfacing$axis == Facing.Axis.X;
|
||||
boolean flag5 = flag2 || flag3 || enumfacing$axis == Facing.Axis.Z;
|
||||
return flag4 && side == Facing.WEST ? true : (flag4 && side == Facing.EAST ? true : (flag5 && side == Facing.NORTH ? true : flag5 && side == Facing.SOUTH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quantity of items to drop on block destruction.
|
||||
*/
|
||||
public int quantityDropped(Random random)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called When an Entity Collided with the Block
|
||||
*/
|
||||
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, State state, Entity entityIn)
|
||||
{
|
||||
if (entityIn.vehicle == null && entityIn.passenger == null)
|
||||
{
|
||||
entityIn.setPortal(state.getValue(DIM));
|
||||
}
|
||||
}
|
||||
|
||||
public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
// if (rand.chance(100))
|
||||
// {
|
||||
// worldIn.playSound((double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, "portal.portal", 0.5F, rand.floatv() * 0.4F + 0.8F);
|
||||
// }
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
double d0 = (double)((float)pos.getX() + rand.floatv());
|
||||
double d1 = (double)((float)pos.getY() + rand.floatv());
|
||||
double d2 = (double)((float)pos.getZ() + rand.floatv());
|
||||
double d3 = ((double)rand.floatv() - 0.5D) * 0.5D;
|
||||
double d4 = ((double)rand.floatv() - 0.5D) * 0.5D;
|
||||
double d5 = ((double)rand.floatv() - 0.5D) * 0.5D;
|
||||
int j = rand.zrange(2) * 2 - 1;
|
||||
|
||||
if (worldIn.getState(pos.west()).getBlock() != this && worldIn.getState(pos.east()).getBlock() != this)
|
||||
{
|
||||
d0 = (double)pos.getX() + 0.5D + 0.25D * (double)j;
|
||||
d3 = (double)(rand.floatv() * 2.0F * (float)j);
|
||||
}
|
||||
else
|
||||
{
|
||||
d2 = (double)pos.getZ() + 0.5D + 0.25D * (double)j;
|
||||
d5 = (double)(rand.floatv() * 2.0F * (float)j);
|
||||
}
|
||||
|
||||
worldIn.spawnParticle(ParticleType.PORTAL, d0, d1, d2, d3, d4, d5);
|
||||
}
|
||||
}
|
||||
|
||||
public Item getItem(World worldIn, BlockPos pos)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRenderColor(State state)
|
||||
{
|
||||
return COLORS[state.getValue(DIM)];
|
||||
}
|
||||
|
||||
public int colorMultiplier(IWorldAccess worldIn, BlockPos pos, int renderPass)
|
||||
{
|
||||
return this.getRenderColor(worldIn.getState(pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(AXIS, (meta & 8) == 8 ? Facing.Axis.Z : Facing.Axis.X)
|
||||
.withProperty(DIM, meta & 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return (state.getValue(AXIS) == Axis.Z ? 8 : 0) | state.getValue(DIM);
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {AXIS, DIM};
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return state.getValue(AXIS) == Facing.Axis.X ? provider.getModel(name)
|
||||
.add(0, 0, 6, 16, 16, 10)
|
||||
.n().uv(0, 0, 16, 16).noCull().tint()
|
||||
.s().uv(0, 0, 16, 16).noCull().tint() : provider.getModel(name)
|
||||
.add(6, 0, 0, 10, 16, 16)
|
||||
.w().uv(0, 0, 16, 16).noCull().tint()
|
||||
.e().uv(0, 0, 16, 16).noCull().tint();
|
||||
}
|
||||
|
||||
public void getAnimatedTextures(Map<String, Object> map) {
|
||||
map.put("blocks/portal", 1);
|
||||
}
|
||||
|
||||
// public BlockPattern.PatternHelper func_181089_f(World p_181089_1_, BlockPos p_181089_2_)
|
||||
// {
|
||||
// EnumFacing.Axis enumfacing$axis = EnumFacing.Axis.Z;
|
||||
// BlockPortal.Size blockportal$size = new BlockPortal.Size(p_181089_1_, p_181089_2_, EnumFacing.Axis.X);
|
||||
// LoadingCache<BlockPos, BlockWorldState> loadingcache = BlockPattern.createLoadingCache(p_181089_1_, true);
|
||||
//
|
||||
// if (!blockportal$size.func_150860_b())
|
||||
// {
|
||||
// enumfacing$axis = EnumFacing.Axis.X;
|
||||
// blockportal$size = new BlockPortal.Size(p_181089_1_, p_181089_2_, EnumFacing.Axis.Z);
|
||||
// }
|
||||
//
|
||||
// if (!blockportal$size.func_150860_b())
|
||||
// {
|
||||
// return new BlockPattern.PatternHelper(p_181089_2_, EnumFacing.NORTH, EnumFacing.UP, loadingcache, 1, 1, 1);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// int[] aint = new int[EnumFacing.AxisDirection.values().length];
|
||||
// EnumFacing enumfacing = blockportal$size.field_150866_c.rotateYCCW();
|
||||
// BlockPos blockpos = blockportal$size.field_150861_f.up(blockportal$size.func_181100_a() - 1);
|
||||
//
|
||||
// for (EnumFacing.AxisDirection enumfacing$axisdirection : EnumFacing.AxisDirection.values())
|
||||
// {
|
||||
// BlockPattern.PatternHelper blockpattern$patternhelper = new BlockPattern.PatternHelper(enumfacing.getAxisDirection() == enumfacing$axisdirection ? blockpos : blockpos.offset(blockportal$size.field_150866_c, blockportal$size.func_181101_b() - 1), EnumFacing.getFacingFromAxis(enumfacing$axisdirection, enumfacing$axis), EnumFacing.UP, loadingcache, blockportal$size.func_181101_b(), blockportal$size.func_181100_a(), 1);
|
||||
//
|
||||
// for (int i = 0; i < blockportal$size.func_181101_b(); ++i)
|
||||
// {
|
||||
// for (int j = 0; j < blockportal$size.func_181100_a(); ++j)
|
||||
// {
|
||||
// BlockWorldState blockworldstate = blockpattern$patternhelper.translateOffset(i, j, 1);
|
||||
//
|
||||
// if (blockworldstate.getBlockState() != null && blockworldstate.getBlockState().getBlock() != Blocks.air)
|
||||
// {
|
||||
// ++aint[enumfacing$axisdirection.ordinal()];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// EnumFacing.AxisDirection enumfacing$axisdirection1 = EnumFacing.AxisDirection.POSITIVE;
|
||||
//
|
||||
// for (EnumFacing.AxisDirection enumfacing$axisdirection2 : EnumFacing.AxisDirection.values())
|
||||
// {
|
||||
// if (aint[enumfacing$axisdirection2.ordinal()] < aint[enumfacing$axisdirection1.ordinal()])
|
||||
// {
|
||||
// enumfacing$axisdirection1 = enumfacing$axisdirection2;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return new BlockPattern.PatternHelper(enumfacing.getAxisDirection() == enumfacing$axisdirection1 ? blockpos : blockpos.offset(blockportal$size.field_150866_c, blockportal$size.func_181101_b() - 1), EnumFacing.getFacingFromAxis(enumfacing$axisdirection1, enumfacing$axis), EnumFacing.UP, loadingcache, blockportal$size.func_181101_b(), blockportal$size.func_181100_a(), 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static class Size
|
||||
{
|
||||
private final World world;
|
||||
private final Facing.Axis axis;
|
||||
private final Facing field_150866_c;
|
||||
private final Facing field_150863_d;
|
||||
private final int dim;
|
||||
private int field_150864_e = 0;
|
||||
private BlockPos field_150861_f;
|
||||
private int height;
|
||||
private int field_150868_h;
|
||||
|
||||
public Size(World worldIn, BlockPos p_i45694_2_, Facing.Axis p_i45694_3_, int dim)
|
||||
{
|
||||
this.world = worldIn;
|
||||
this.dim = dim;
|
||||
this.axis = p_i45694_3_;
|
||||
|
||||
if (p_i45694_3_ == Facing.Axis.X)
|
||||
{
|
||||
this.field_150863_d = Facing.EAST;
|
||||
this.field_150866_c = Facing.WEST;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.field_150863_d = Facing.NORTH;
|
||||
this.field_150866_c = Facing.SOUTH;
|
||||
}
|
||||
|
||||
for (BlockPos blockpos = p_i45694_2_; p_i45694_2_.getY() > blockpos.getY() - 21 && p_i45694_2_.getY() > 0 && this.func_150857_a(worldIn.getState(p_i45694_2_.down()).getBlock()); p_i45694_2_ = p_i45694_2_.down())
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
int i = this.func_180120_a(p_i45694_2_, this.field_150863_d) - 1;
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
this.field_150861_f = p_i45694_2_.offset(this.field_150863_d, i);
|
||||
this.field_150868_h = this.func_180120_a(this.field_150861_f, this.field_150866_c);
|
||||
|
||||
if (this.field_150868_h < 2 || this.field_150868_h > 21)
|
||||
{
|
||||
this.field_150861_f = null;
|
||||
this.field_150868_h = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.field_150861_f != null)
|
||||
{
|
||||
this.height = this.func_150858_a();
|
||||
}
|
||||
}
|
||||
|
||||
protected int func_180120_a(BlockPos p_180120_1_, Facing p_180120_2_)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 22; ++i)
|
||||
{
|
||||
BlockPos blockpos = p_180120_1_.offset(p_180120_2_, i);
|
||||
|
||||
if (!this.func_150857_a(this.world.getState(blockpos).getBlock()) || this.world.getState(blockpos.down()).getBlock() != Blocks.obsidian)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Block block = this.world.getState(p_180120_1_.offset(p_180120_2_, i)).getBlock();
|
||||
return block == Blocks.obsidian ? i : 0;
|
||||
}
|
||||
|
||||
public int func_181100_a()
|
||||
{
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int func_181101_b()
|
||||
{
|
||||
return this.field_150868_h;
|
||||
}
|
||||
|
||||
protected int func_150858_a()
|
||||
{
|
||||
label24:
|
||||
|
||||
for (this.height = 0; this.height < 21; ++this.height)
|
||||
{
|
||||
for (int i = 0; i < this.field_150868_h; ++i)
|
||||
{
|
||||
BlockPos blockpos = this.field_150861_f.offset(this.field_150866_c, i).up(this.height);
|
||||
Block block = this.world.getState(blockpos).getBlock();
|
||||
|
||||
if (!this.func_150857_a(block))
|
||||
{
|
||||
break label24;
|
||||
}
|
||||
|
||||
if (block == Blocks.portal)
|
||||
{
|
||||
++this.field_150864_e;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
block = this.world.getState(blockpos.offset(this.field_150863_d)).getBlock();
|
||||
|
||||
if (block != Blocks.obsidian)
|
||||
{
|
||||
break label24;
|
||||
}
|
||||
}
|
||||
else if (i == this.field_150868_h - 1)
|
||||
{
|
||||
block = this.world.getState(blockpos.offset(this.field_150866_c)).getBlock();
|
||||
|
||||
if (block != Blocks.obsidian)
|
||||
{
|
||||
break label24;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < this.field_150868_h; ++j)
|
||||
{
|
||||
if (this.world.getState(this.field_150861_f.offset(this.field_150866_c, j).up(this.height)).getBlock() != Blocks.obsidian)
|
||||
{
|
||||
this.height = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.height <= 21 && this.height >= 3)
|
||||
{
|
||||
return this.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.field_150861_f = null;
|
||||
this.field_150868_h = 0;
|
||||
this.height = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean func_150857_a(Block p_150857_1_)
|
||||
{
|
||||
return p_150857_1_ == Blocks.air || p_150857_1_ instanceof BlockFire || p_150857_1_ == Blocks.portal;
|
||||
}
|
||||
|
||||
public boolean func_150860_b()
|
||||
{
|
||||
return this.field_150861_f != null && this.field_150868_h >= 2 && this.field_150868_h <= 21 && this.height >= 3 && this.height <= 21;
|
||||
}
|
||||
|
||||
public void func_150859_c()
|
||||
{
|
||||
for (int i = 0; i < this.field_150868_h; ++i)
|
||||
{
|
||||
BlockPos blockpos = this.field_150861_f.offset(this.field_150866_c, i);
|
||||
State state = Blocks.portal.getState().withProperty(BlockPortal.AXIS, this.axis)
|
||||
.withProperty(DIM, this.dim);
|
||||
|
||||
for (int j = 0; j < this.height; ++j)
|
||||
{
|
||||
this.world.setState(blockpos.up(j), state, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
181
common/src/main/java/common/block/artificial/BlockPortalFrame.java
Executable file
181
common/src/main/java/common/block/artificial/BlockPortalFrame.java
Executable file
|
@ -0,0 +1,181 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.entity.Entity;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Blocks;
|
||||
import common.init.ItemRegistry;
|
||||
import common.init.Items;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyBool;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.rng.Random;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockPortalFrame extends Block
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL);
|
||||
public static final PropertyBool ORB = PropertyBool.create("orb");
|
||||
|
||||
public BlockPortalFrame()
|
||||
{
|
||||
super(Material.SOLID);
|
||||
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(ORB, Boolean.valueOf(false)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block's bounds for rendering it as an item
|
||||
*/
|
||||
public void setBlockBoundsForItemRender()
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.8125F, 1.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all collision boxes of this Block to the list that intersect with the given mask.
|
||||
*/
|
||||
public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.8125F, 1.0F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
|
||||
if (((Boolean)worldIn.getState(pos).getValue(ORB)).booleanValue())
|
||||
{
|
||||
this.setBlockBounds(0.3125F, 0.8125F, 0.3125F, 0.6875F, 1.0F, 0.6875F);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
|
||||
this.setBlockBoundsForItemRender();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Item that this Block should drop when harvested.
|
||||
*/
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return ItemRegistry.getItemFromBlock(Blocks.obsidian);
|
||||
}
|
||||
|
||||
public int quantityDropped(Random random)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
public void harvestBlock(World worldIn, EntityNPC player, BlockPos pos, State state, TileEntity te)
|
||||
{
|
||||
super.harvestBlock(worldIn, player, pos, state, te);
|
||||
if(state.getValue(ORB))
|
||||
spawnAsEntity(worldIn, pos, new ItemStack(Items.charged_orb));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
||||
* IBlockstate
|
||||
*/
|
||||
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
||||
{
|
||||
return this.getState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()).withProperty(ORB, Boolean.valueOf(false));
|
||||
}
|
||||
|
||||
public boolean hasComparatorInputOverride()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getComparatorInputOverride(World worldIn, BlockPos pos)
|
||||
{
|
||||
return ((Boolean)worldIn.getState(pos).getValue(ORB)).booleanValue() ? 15 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(ORB, Boolean.valueOf((meta & 4) != 0)).withProperty(FACING, Facing.getHorizontal(meta & 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
int i = 0;
|
||||
i = i | ((Facing)state.getValue(FACING)).getHorizontalIndex();
|
||||
|
||||
if (((Boolean)state.getValue(ORB)).booleanValue())
|
||||
{
|
||||
i |= 4;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {FACING, ORB};
|
||||
}
|
||||
|
||||
public void onBlockDestroyedByPlayer(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
for(int n = 0; n < 4; n++) {
|
||||
BlockPos ppos = pos.offset(Facing.getHorizontal(n));
|
||||
State pstate = worldIn.getState(ppos);
|
||||
if(pstate.getBlock() == Blocks.floor_portal)
|
||||
Blocks.floor_portal.onBlockDestroyedByPlayer(worldIn, ppos, pstate);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isXrayVisible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return (state.getValue(ORB) ? provider.getModel("portal_frame_side")
|
||||
.add(0, 0, 0, 16, 13, 16)
|
||||
.d("portal_frame_bottom").uv(0, 0, 16, 16).noCull()
|
||||
.u("portal_frame_top").uv(0, 0, 16, 16).noCull()
|
||||
.n().uv(0, 3, 16, 16).noCull()
|
||||
.s().uv(0, 3, 16, 16).noCull()
|
||||
.w().uv(0, 3, 16, 16).noCull()
|
||||
.e().uv(0, 3, 16, 16).noCull()
|
||||
.add(4, 13, 4, 12, 16, 12)
|
||||
.d("portal_frame_orb").uv(4, 4, 12, 12).noCull()
|
||||
.u("portal_frame_orb").uv(4, 4, 12, 12).noCull()
|
||||
.n("portal_frame_orb").uv(4, 0, 12, 3).noCull()
|
||||
.s("portal_frame_orb").uv(4, 0, 12, 3).noCull()
|
||||
.w("portal_frame_orb").uv(4, 0, 12, 3).noCull()
|
||||
.e("portal_frame_orb").uv(4, 0, 12, 3).noCull() : provider.getModel("portal_frame_side")
|
||||
.add(0, 0, 0, 16, 13, 16)
|
||||
.d("portal_frame_bottom").uv(0, 0, 16, 16).noCull()
|
||||
.u("portal_frame_top").uv(0, 0, 16, 16).noCull()
|
||||
.n().uv(0, 3, 16, 16).noCull()
|
||||
.s().uv(0, 3, 16, 16).noCull()
|
||||
.w().uv(0, 3, 16, 16).noCull()
|
||||
.e().uv(0, 3, 16, 16).noCull())
|
||||
.rotate(ModelRotation.getNorthRot(state.getValue(FACING)));
|
||||
}
|
||||
}
|
195
common/src/main/java/common/block/artificial/BlockQuartz.java
Executable file
195
common/src/main/java/common/block/artificial/BlockQuartz.java
Executable file
|
@ -0,0 +1,195 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.ItemRegistry;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.util.Identifyable;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockQuartz extends Block
|
||||
{
|
||||
public static final PropertyEnum<BlockQuartz.EnumType> VARIANT = PropertyEnum.<BlockQuartz.EnumType>create("variant", BlockQuartz.EnumType.class);
|
||||
|
||||
private final String prefix;
|
||||
|
||||
public BlockQuartz(String prefix)
|
||||
{
|
||||
super(Material.SOLID);
|
||||
this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockQuartz.EnumType.DEFAULT));
|
||||
this.setTab(CheatTab.BLOCKS);
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
||||
* IBlockstate
|
||||
*/
|
||||
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
||||
{
|
||||
if (meta == BlockQuartz.EnumType.LINES_Y.getMetadata())
|
||||
{
|
||||
switch (facing.getAxis())
|
||||
{
|
||||
case Z:
|
||||
return this.getState().withProperty(VARIANT, BlockQuartz.EnumType.LINES_Z);
|
||||
|
||||
case X:
|
||||
return this.getState().withProperty(VARIANT, BlockQuartz.EnumType.LINES_X);
|
||||
|
||||
case Y:
|
||||
default:
|
||||
return this.getState().withProperty(VARIANT, BlockQuartz.EnumType.LINES_Y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return meta == BlockQuartz.EnumType.CHISELED.getMetadata() ? this.getState().withProperty(VARIANT, BlockQuartz.EnumType.CHISELED) : this.getState().withProperty(VARIANT, BlockQuartz.EnumType.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It
|
||||
* returns the metadata of the dropped item based on the old metadata of the block.
|
||||
*/
|
||||
public int damageDropped(State state)
|
||||
{
|
||||
BlockQuartz.EnumType blockquartz$enumtype = (BlockQuartz.EnumType)state.getValue(VARIANT);
|
||||
return blockquartz$enumtype != BlockQuartz.EnumType.LINES_X && blockquartz$enumtype != BlockQuartz.EnumType.LINES_Z ? blockquartz$enumtype.getMetadata() : BlockQuartz.EnumType.LINES_Y.getMetadata();
|
||||
}
|
||||
|
||||
public ItemStack createStackedBlock(State state)
|
||||
{
|
||||
BlockQuartz.EnumType blockquartz$enumtype = (BlockQuartz.EnumType)state.getValue(VARIANT);
|
||||
return blockquartz$enumtype != BlockQuartz.EnumType.LINES_X && blockquartz$enumtype != BlockQuartz.EnumType.LINES_Z ? super.createStackedBlock(state) : new ItemStack(ItemRegistry.getItemFromBlock(this), 1, BlockQuartz.EnumType.LINES_Y.getMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
|
||||
*/
|
||||
public void getSubBlocks(Item itemIn, CheatTab tab, List<ItemStack> list)
|
||||
{
|
||||
list.add(new ItemStack(itemIn, 1, BlockQuartz.EnumType.DEFAULT.getMetadata()));
|
||||
list.add(new ItemStack(itemIn, 1, BlockQuartz.EnumType.CHISELED.getMetadata()));
|
||||
list.add(new ItemStack(itemIn, 1, BlockQuartz.EnumType.LINES_Y.getMetadata()));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the MapColor for this Block and the given BlockState
|
||||
// */
|
||||
// public MapColor getMapColor(IBlockState state)
|
||||
// {
|
||||
// return MapColor.quartzColor;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(VARIANT, BlockQuartz.EnumType.byMetadata(meta));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((BlockQuartz.EnumType)state.getValue(VARIANT)).getMetadata();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {VARIANT};
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
switch(state.getValue(VARIANT)) {
|
||||
case DEFAULT:
|
||||
default:
|
||||
return provider.getModel(this.prefix + "quartz_block_side").add().nswe().d(this.prefix + "quartz_block_bottom").u(this.prefix + "quartz_top");
|
||||
case CHISELED:
|
||||
return provider.getModel(this.prefix + "quartz_block_chiseled").add().nswe().du(this.prefix + "quartz_block_chiseled_top");
|
||||
case LINES_X:
|
||||
return provider.getModel(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top").rotate(ModelRotation.X90_Y90);
|
||||
case LINES_Y:
|
||||
return provider.getModel(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top");
|
||||
case LINES_Z:
|
||||
return provider.getModel(this.prefix + "quartz_block_lines").add().nswe().du(this.prefix + "quartz_block_lines_top").rotate(ModelRotation.X90_Y0);
|
||||
}
|
||||
}
|
||||
|
||||
public static enum EnumType implements Identifyable
|
||||
{
|
||||
DEFAULT(0, "default", "default", null),
|
||||
CHISELED(1, "chiseled", "chiseled", null),
|
||||
LINES_Y(2, "lines_y", "lines", Facing.Axis.Y),
|
||||
LINES_X(3, "lines_x", "lines", Facing.Axis.X),
|
||||
LINES_Z(4, "lines_z", "lines", Facing.Axis.Z);
|
||||
|
||||
private static final BlockQuartz.EnumType[] META_LOOKUP = new BlockQuartz.EnumType[values().length];
|
||||
private final int meta;
|
||||
private final String name;
|
||||
private final String unlocalizedName;
|
||||
private final Facing.Axis axis;
|
||||
|
||||
private EnumType(int meta, String name, String unlocalizedName, Facing.Axis axis)
|
||||
{
|
||||
this.meta = meta;
|
||||
this.name = name;
|
||||
this.unlocalizedName = unlocalizedName;
|
||||
this.axis = axis;
|
||||
}
|
||||
|
||||
public int getMetadata()
|
||||
{
|
||||
return this.meta;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.name;
|
||||
// return this.unlocalizedName;
|
||||
}
|
||||
|
||||
public static BlockQuartz.EnumType byMetadata(int meta)
|
||||
{
|
||||
if (meta < 0 || meta >= META_LOOKUP.length)
|
||||
{
|
||||
meta = 0;
|
||||
}
|
||||
|
||||
return META_LOOKUP[meta];
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Facing.Axis getAxis()
|
||||
{
|
||||
return this.axis;
|
||||
}
|
||||
|
||||
static {
|
||||
for (BlockQuartz.EnumType blockquartz$enumtype : values())
|
||||
{
|
||||
META_LOOKUP[blockquartz$enumtype.getMetadata()] = blockquartz$enumtype;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
362
common/src/main/java/common/block/artificial/BlockSlab.java
Executable file
362
common/src/main/java/common/block/artificial/BlockSlab.java
Executable file
|
@ -0,0 +1,362 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.collect.Lists;
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyBool;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.util.Facing.Axis;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockSlab extends Block
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing");
|
||||
public static final PropertyBool DOUBLE = PropertyBool.create("double");
|
||||
public static final PropertyBool SEAMLESS = PropertyBool.create("seamless");
|
||||
public static final List<BlockSlab> SLABS = Lists.newArrayList();
|
||||
|
||||
private final String textureTop;
|
||||
private final String textureBottom;
|
||||
private final String textureSide;
|
||||
|
||||
public BlockSlab(Material materialIn, String texture)
|
||||
{
|
||||
this(materialIn, texture, texture, texture);
|
||||
}
|
||||
|
||||
public BlockSlab(Material materialIn, String side, String bottom, String top)
|
||||
{
|
||||
super(materialIn);
|
||||
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.DOWN).withProperty(DOUBLE, false)
|
||||
.withProperty(SEAMLESS, false));
|
||||
this.setTab(materialIn == Material.WOOD ? CheatTab.WOOD : CheatTab.BLOCKS);
|
||||
|
||||
// this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F);
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
|
||||
|
||||
this.setLightOpacity(255);
|
||||
this.textureTop = top;
|
||||
this.textureBottom = bottom;
|
||||
this.textureSide = side;
|
||||
SLABS.add(this);
|
||||
}
|
||||
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
meta = meta & 7;
|
||||
return this.getState().withProperty(DOUBLE, meta >= 6).withProperty(SEAMLESS, meta == 7)
|
||||
.withProperty(FACING, (meta == 0 || meta >= 6) ? Facing.DOWN :
|
||||
(meta == 1 ? Facing.UP : Facing.getHorizontal(meta - 2)));
|
||||
}
|
||||
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
if(state.getValue(DOUBLE))
|
||||
return state.getValue(SEAMLESS) ? 7 : 6;
|
||||
Facing dir = state.getValue(FACING);
|
||||
return dir == Facing.DOWN ? 0 : (dir == Facing.UP ? 1 : (dir.getHorizontalIndex() + 2));
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {FACING, DOUBLE, SEAMLESS};
|
||||
}
|
||||
|
||||
public boolean canSilkHarvest()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune)
|
||||
{
|
||||
if (!worldIn.client)
|
||||
{
|
||||
int i = state.getBlock() == this && state.getValue(DOUBLE) ? 2 : 1;
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
if (worldIn.rand.floatv() <= chance)
|
||||
{
|
||||
Item item = this.getItemDropped(state, worldIn.rand, fortune);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
spawnAsEntity(worldIn, pos, new ItemStack(item, 1, this.damageDropped(state)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
||||
{
|
||||
State iblockstate = this.getState().withProperty(FACING, Facing.DOWN);
|
||||
return facing != Facing.DOWN && (facing == Facing.UP || (double)hitY <= 0.5D) ? iblockstate :
|
||||
iblockstate.withProperty(FACING, Facing.UP);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
// if (this.isDouble())
|
||||
// {
|
||||
// this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
|
||||
if (iblockstate.getBlock() == this)
|
||||
{
|
||||
if(iblockstate.getValue(DOUBLE)) {
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
return;
|
||||
}
|
||||
switch(iblockstate.getValue(FACING)) {
|
||||
case EAST:
|
||||
this.setBlockBounds(0.5F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
break;
|
||||
case WEST:
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.5F, 1.0F, 1.0F);
|
||||
break;
|
||||
case SOUTH:
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.5F, 1.0F, 1.0F, 1.0F);
|
||||
break;
|
||||
case NORTH:
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F);
|
||||
break;
|
||||
case UP:
|
||||
this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
break;
|
||||
case DOWN:
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
|
||||
break;
|
||||
}
|
||||
|
||||
// if (iblockstate.getValue(HALF) == BlockSlab.EnumBlockHalf.TOP)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
//
|
||||
// }
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
// {
|
||||
// IBlockState iblockstate = worldIn.getBlockState(pos);
|
||||
//
|
||||
// if (iblockstate.getBlock() == this)
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
|
||||
public void setBlockBoundsForItemRender()
|
||||
{
|
||||
// this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F);
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
|
||||
}
|
||||
|
||||
public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState(worldIn, pos);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
|
||||
// {
|
||||
// return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer).withProperty(FACING, placer.getHorizontalFacing() /* .getOpposite() */);
|
||||
// }
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static boolean isSlab(Block blockIn)
|
||||
{
|
||||
return blockIn instanceof BlockSlab;
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
if (iblockstate.getBlock() == this && iblockstate.getValue(DOUBLE))
|
||||
{
|
||||
return super.shouldSideBeRendered(worldIn, pos, side);
|
||||
}
|
||||
if(iblockstate.getBlock() == this && iblockstate.getValue(FACING).getAxis() == Axis.Y) {
|
||||
if (side != Facing.UP && side != Facing.DOWN && !super.shouldSideBeRendered(worldIn, pos, side))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos = pos.offset(side.getOpposite());
|
||||
// IBlockState iblockstate = worldIn.getBlockState(pos);
|
||||
State iblockstate1 = worldIn.getState(blockpos);
|
||||
if(isSlab(iblockstate1.getBlock()) && iblockstate.getValue(FACING).getAxis() == Axis.Y)
|
||||
return true;
|
||||
boolean flag = isSlab(iblockstate.getBlock()) && iblockstate.getValue(FACING) == Facing.UP;
|
||||
boolean flag1 = isSlab(iblockstate1.getBlock()) && iblockstate1.getValue(FACING) == Facing.UP;
|
||||
return flag1 ? (side == Facing.DOWN ? true : (side == Facing.UP && super.shouldSideBeRendered(worldIn, pos, side) ? true : !isSlab(iblockstate.getBlock()) || !flag)) : (side == Facing.UP ? true : (side == Facing.DOWN && super.shouldSideBeRendered(worldIn, pos, side) ? true : !isSlab(iblockstate.getBlock()) || flag));
|
||||
}
|
||||
}
|
||||
|
||||
if (side == Facing.UP || side == Facing.DOWN)
|
||||
{
|
||||
return super.shouldSideBeRendered(worldIn, pos, side);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (iblockstate.getBlock() == this && iblockstate.getValue(FACING) == side.getOpposite()) || super.shouldSideBeRendered(worldIn, pos, side);
|
||||
}
|
||||
}
|
||||
|
||||
// public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, EnumFacing side)
|
||||
// {
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
// public abstract String getUnlocalizedName(int meta);
|
||||
|
||||
// public int getDamageValue(World worldIn, BlockPos pos)
|
||||
// {
|
||||
// return super.getDamageValue(worldIn, pos) & 7;
|
||||
// }
|
||||
|
||||
// public abstract IProperty<?> getVariantProperty();
|
||||
//
|
||||
// public abstract Object getVariant(ItemStack stack);
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
if(state.getValue(DOUBLE)) {
|
||||
return provider.getModel(state.getValue(SEAMLESS) ? this.textureTop : this.textureSide)
|
||||
.add().nswe().d(state.getValue(SEAMLESS) ? this.textureTop : this.textureBottom).u(this.textureTop);
|
||||
}
|
||||
else {
|
||||
if(state.getValue(FACING).getAxis() != Axis.Y)
|
||||
return provider.getModel(this.textureSide).vslab(state.getValue(FACING), this.textureBottom, this.textureTop);
|
||||
else
|
||||
return provider.getModel(this.textureSide).slab(state.getValue(FACING) == Facing.UP, this.textureBottom,
|
||||
this.textureTop);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
if(state.getValue(VARIANT) == EnumType.STONE)
|
||||
return state.getValue(SEAMLESS) ? provider.getModel("double_stone_top").add().all() :
|
||||
provider.getModel("stone_slab_side").add().nswe().du("double_stone_top");
|
||||
else if(state.getValue(VARIANT) == EnumType.QUARTZ)
|
||||
return provider.getModel("quartz_block_side").add().nswe().d("quartz_block_bottom").u("quartz_top");
|
||||
else if(state.getValue(VARIANT) == EnumType.SAND)
|
||||
return provider.getModel("sandstone_normal").add().nswe().d("sandstone_bottom").u("sandstone_all");
|
||||
else
|
||||
return provider.getModel(getTexture(state.getValue(VARIANT))).add().all();
|
||||
}
|
||||
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
if(state.getValue(VARIANT) == EnumType.STONE)
|
||||
return provider.getModel("stone_slab_side").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "double_stone_top");
|
||||
else if(state.getValue(VARIANT) == EnumType.QUARTZ)
|
||||
return provider.getModel("quartz_block_side").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "quartz_block_bottom",
|
||||
"quartz_top");
|
||||
else if(state.getValue(VARIANT) == EnumType.SAND)
|
||||
return provider.getModel("sandstone_normal").slab(state.getValue(HALF) == EnumBlockHalf.TOP, "sandstone_bottom",
|
||||
"sandstone_all");
|
||||
else
|
||||
return provider.getModel(getTexture(state.getValue(VARIANT))).slab(state.getValue(HALF) == EnumBlockHalf.TOP);
|
||||
}
|
||||
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
return provider.getModel(state.getValue(VARIANT).getName() + "_planks").slab(state.getValue(HALF) == EnumBlockHalf.TOP);
|
||||
}
|
||||
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
return provider.getModel(state.getValue(VARIANT).getName() + "_planks").add().all();
|
||||
}
|
||||
|
||||
protected static String getTexture(BlockStoneSlab.EnumType type) {
|
||||
switch(type) {
|
||||
case BRICK:
|
||||
return "brick_block";
|
||||
case SMOOTHBRICK:
|
||||
return "stonebrick_default";
|
||||
case WOOD:
|
||||
return "oak_planks";
|
||||
default:
|
||||
return type.getName();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTexture(BlockVertStoneSlab.EnumType type) {
|
||||
switch(type) {
|
||||
case WOOD:
|
||||
return "oak_planks";
|
||||
default:
|
||||
return type.getName();
|
||||
}
|
||||
}
|
||||
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
if(state.getValue(VARIANT) == EnumType.STONE)
|
||||
return provider.getModel("stone_slab_side").vslab(state.getValue(FACING), "double_stone_top");
|
||||
else if(state.getValue(VARIANT) == EnumType.SAND)
|
||||
return provider.getModel("sandstone_normal").vslab(state.getValue(FACING), "sandstone_bottom",
|
||||
"sandstone_all");
|
||||
else
|
||||
return provider.getModel(getTexture(state.getValue(VARIANT))).vslab(state.getValue(FACING));
|
||||
}
|
||||
|
||||
private static String getTexture(BlockVertStoneSlab2.EnumType type) {
|
||||
switch(type) {
|
||||
case BRICK:
|
||||
return "brick_block";
|
||||
case SMOOTHBRICK:
|
||||
return "stonebrick_default";
|
||||
default:
|
||||
return type.getName();
|
||||
}
|
||||
}
|
||||
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
if(state.getValue(VARIANT) == EnumType.QUARTZ)
|
||||
return provider.getModel("quartz_block_side").vslab(state.getValue(FACING), "quartz_block_bottom",
|
||||
"quartz_top");
|
||||
else
|
||||
return provider.getModel(getTexture(state.getValue(VARIANT))).vslab(state.getValue(FACING));
|
||||
}
|
||||
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
return provider.getModel(state.getValue(VARIANT).getName() + "_planks").vslab(state.getValue(FACING));
|
||||
}
|
||||
|
||||
public Model getModel(String name, IBlockState state) {
|
||||
return provider.getModel(state.getValue(VARIANT).getName() + "_planks").vslab(state.getValue(FACING));
|
||||
}
|
||||
*/
|
||||
}
|
52
common/src/main/java/common/block/artificial/BlockStainedGlass.java
Executable file
52
common/src/main/java/common/block/artificial/BlockStainedGlass.java
Executable file
|
@ -0,0 +1,52 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.color.DyeColor;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockStainedGlass extends BlockGlass {
|
||||
public static final PropertyEnum<DyeColor> COLOR = PropertyEnum.<DyeColor>create("color", DyeColor.class);
|
||||
|
||||
public BlockStainedGlass() {
|
||||
this.setDefaultState(this.getBaseState().withProperty(COLOR, DyeColor.WHITE));
|
||||
}
|
||||
|
||||
public int damageDropped(State state) {
|
||||
return state.getValue(COLOR).getMetadata();
|
||||
}
|
||||
|
||||
public void getSubBlocks(Item item, CheatTab tab, List<ItemStack> list) {
|
||||
for(DyeColor color : DyeColor.values()) {
|
||||
list.add(new ItemStack(item, 1, color.getMetadata()));
|
||||
}
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer() {
|
||||
return BlockLayer.TRANSLUCENT;
|
||||
}
|
||||
|
||||
public State getStateFromMeta(int meta) {
|
||||
return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta));
|
||||
}
|
||||
|
||||
public int getMetaFromState(State state) {
|
||||
return state.getValue(COLOR).getMetadata();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties() {
|
||||
return new IProperty[] {COLOR};
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel(state.getValue(COLOR).getName() + "_glass").add().all();
|
||||
}
|
||||
}
|
103
common/src/main/java/common/block/artificial/BlockStainedGlassPane.java
Executable file
103
common/src/main/java/common/block/artificial/BlockStainedGlassPane.java
Executable file
|
@ -0,0 +1,103 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Material;
|
||||
import common.color.DyeColor;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.BlockLayer;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockStainedGlassPane extends BlockPane
|
||||
{
|
||||
public static final PropertyEnum<DyeColor> COLOR = PropertyEnum.<DyeColor>create("color", DyeColor.class);
|
||||
|
||||
public BlockStainedGlassPane()
|
||||
{
|
||||
super(Material.TRANSLUCENT, false);
|
||||
this.setDefaultState(this.getBaseState().withProperty(NORTH, Boolean.valueOf(false)).withProperty(EAST, Boolean.valueOf(false)).withProperty(SOUTH, Boolean.valueOf(false)).withProperty(WEST, Boolean.valueOf(false)).withProperty(COLOR, DyeColor.WHITE));
|
||||
this.setTab(CheatTab.BLOCKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It
|
||||
* returns the metadata of the dropped item based on the old metadata of the block.
|
||||
*/
|
||||
public int damageDropped(State state)
|
||||
{
|
||||
return ((DyeColor)state.getValue(COLOR)).getMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
|
||||
*/
|
||||
public void getSubBlocks(Item itemIn, CheatTab tab, List<ItemStack> list)
|
||||
{
|
||||
for (int i = 0; i < DyeColor.values().length; ++i)
|
||||
{
|
||||
list.add(new ItemStack(itemIn, 1, i));
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the MapColor for this Block and the given BlockState
|
||||
// */
|
||||
// public MapColor getMapColor(IBlockState state)
|
||||
// {
|
||||
// return ((EnumDyeColor)state.getValue(COLOR)).getMapColor();
|
||||
// }
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return BlockLayer.TRANSLUCENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(COLOR, DyeColor.byMetadata(meta));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((DyeColor)state.getValue(COLOR)).getMetadata();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {NORTH, EAST, WEST, SOUTH, COLOR};
|
||||
}
|
||||
|
||||
// public void onBlockAdded(IWorldServer worldIn, BlockPos pos, State state)
|
||||
// {
|
||||
// if (!worldIn.client)
|
||||
// {
|
||||
// BlockBeacon.updateColorAsync(worldIn, pos);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void onBlockRemoved(IWorldServer worldIn, BlockPos pos, State state)
|
||||
// {
|
||||
// if (!worldIn.client)
|
||||
// {
|
||||
// BlockBeacon.updateColorAsync(worldIn, pos);
|
||||
// }
|
||||
// }
|
||||
|
||||
protected String getPaneBase(State state) {
|
||||
return state.getValue(COLOR).getName() + "_glass";
|
||||
}
|
||||
|
||||
protected String getPaneEdge(State state) {
|
||||
return state.getValue(COLOR).getName() + "_glass_pane";
|
||||
}
|
||||
}
|
881
common/src/main/java/common/block/artificial/BlockStairs.java
Executable file
881
common/src/main/java/common/block/artificial/BlockStairs.java
Executable file
|
@ -0,0 +1,881 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.entity.Entity;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.BlockRegistry;
|
||||
import common.init.Blocks;
|
||||
import common.item.CheatTab;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.Transforms;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.BoundingBox;
|
||||
import common.util.Facing;
|
||||
import common.util.HitPosition;
|
||||
import common.util.Identifyable;
|
||||
import common.util.Vec3;
|
||||
import common.world.Explosion;
|
||||
import common.world.IBlockAccess;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.AWorldClient;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.AWorldServer;
|
||||
|
||||
public class BlockStairs extends Block
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL);
|
||||
public static final PropertyEnum<BlockStairs.EnumHalf> HALF = PropertyEnum.<BlockStairs.EnumHalf>create("half", BlockStairs.EnumHalf.class);
|
||||
public static final PropertyEnum<BlockStairs.EnumShape> SHAPE = PropertyEnum.<BlockStairs.EnumShape>create("shape", BlockStairs.EnumShape.class);
|
||||
private static final int[][] field_150150_a = new int[][] {{4, 5}, {5, 7}, {6, 7}, {4, 6}, {0, 1}, {1, 3}, {2, 3}, {0, 2}};
|
||||
private final Block modelBlock;
|
||||
private final State modelState;
|
||||
private final String downTex;
|
||||
private final String upTex;
|
||||
private boolean hasRaytraced;
|
||||
private int rayTracePass;
|
||||
|
||||
public BlockStairs(State modelState)
|
||||
{
|
||||
this(modelState, null, null);
|
||||
}
|
||||
|
||||
public BlockStairs(State modelState, String down, String up)
|
||||
{
|
||||
super(modelState.getBlock().getMaterial());
|
||||
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(HALF, BlockStairs.EnumHalf.BOTTOM).withProperty(SHAPE, BlockStairs.EnumShape.STRAIGHT));
|
||||
this.modelBlock = modelState.getBlock();
|
||||
this.modelState = modelState;
|
||||
this.setHardness(this.modelBlock.getRawHardness());
|
||||
this.setResistance(this.modelBlock.getRawResistance() / 3.0F);
|
||||
this.setStepSound(this.modelBlock.sound);
|
||||
this.setLightOpacity(255);
|
||||
this.setTab(modelState.getBlock().getMaterial() == Material.WOOD ? CheatTab.WOOD : CheatTab.BLOCKS);
|
||||
this.downTex = down;
|
||||
this.upTex = up;
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
if (this.hasRaytraced)
|
||||
{
|
||||
this.setBlockBounds(0.5F * (float)(this.rayTracePass % 2), 0.5F * (float)(this.rayTracePass / 4 % 2), 0.5F * (float)(this.rayTracePass / 2 % 2), 0.5F + 0.5F * (float)(this.rayTracePass % 2), 0.5F + 0.5F * (float)(this.rayTracePass / 4 % 2), 0.5F + 0.5F * (float)(this.rayTracePass / 2 % 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block bounds as the collision bounds for the stairs at the given position
|
||||
*/
|
||||
public void setBaseCollisionBounds(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
if (worldIn.getState(pos).getValue(HALF) == BlockStairs.EnumHalf.TOP)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a block is stairs
|
||||
*/
|
||||
public static boolean isBlockStairs(Block blockIn)
|
||||
{
|
||||
return blockIn instanceof BlockStairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is a stair block at the given position and it has the same properties as the given BlockState
|
||||
*/
|
||||
public static boolean isSameStair(IBlockAccess worldIn, BlockPos pos, State state)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
Block block = iblockstate.getBlock();
|
||||
return isBlockStairs(block) && iblockstate.getValue(HALF) == state.getValue(HALF) && iblockstate.getValue(FACING) == state.getValue(FACING);
|
||||
}
|
||||
|
||||
public int getOuterShape(IBlockAccess blockAccess, BlockPos pos)
|
||||
{
|
||||
State iblockstate = blockAccess.getState(pos);
|
||||
Facing enumfacing = (Facing)iblockstate.getValue(FACING);
|
||||
BlockStairs.EnumHalf blockstairs$enumhalf = (BlockStairs.EnumHalf)iblockstate.getValue(HALF);
|
||||
boolean flag = blockstairs$enumhalf == BlockStairs.EnumHalf.TOP;
|
||||
|
||||
if (enumfacing == Facing.EAST)
|
||||
{
|
||||
State iblockstate1 = blockAccess.getState(pos.east());
|
||||
Block block = iblockstate1.getBlock();
|
||||
|
||||
if (isBlockStairs(block) && blockstairs$enumhalf == iblockstate1.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing1 = (Facing)iblockstate1.getValue(FACING);
|
||||
|
||||
if (enumfacing1 == Facing.NORTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
|
||||
if (enumfacing1 == Facing.SOUTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.WEST)
|
||||
{
|
||||
State iblockstate2 = blockAccess.getState(pos.west());
|
||||
Block block1 = iblockstate2.getBlock();
|
||||
|
||||
if (isBlockStairs(block1) && blockstairs$enumhalf == iblockstate2.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing2 = (Facing)iblockstate2.getValue(FACING);
|
||||
|
||||
if (enumfacing2 == Facing.NORTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
|
||||
if (enumfacing2 == Facing.SOUTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.SOUTH)
|
||||
{
|
||||
State iblockstate3 = blockAccess.getState(pos.south());
|
||||
Block block2 = iblockstate3.getBlock();
|
||||
|
||||
if (isBlockStairs(block2) && blockstairs$enumhalf == iblockstate3.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing3 = (Facing)iblockstate3.getValue(FACING);
|
||||
|
||||
if (enumfacing3 == Facing.WEST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
|
||||
if (enumfacing3 == Facing.EAST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.NORTH)
|
||||
{
|
||||
State iblockstate4 = blockAccess.getState(pos.north());
|
||||
Block block3 = iblockstate4.getBlock();
|
||||
|
||||
if (isBlockStairs(block3) && blockstairs$enumhalf == iblockstate4.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing4 = (Facing)iblockstate4.getValue(FACING);
|
||||
|
||||
if (enumfacing4 == Facing.WEST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
|
||||
if (enumfacing4 == Facing.EAST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getInnerShape(IBlockAccess blockAccess, BlockPos pos)
|
||||
{
|
||||
State iblockstate = blockAccess.getState(pos);
|
||||
Facing enumfacing = (Facing)iblockstate.getValue(FACING);
|
||||
BlockStairs.EnumHalf blockstairs$enumhalf = (BlockStairs.EnumHalf)iblockstate.getValue(HALF);
|
||||
boolean flag = blockstairs$enumhalf == BlockStairs.EnumHalf.TOP;
|
||||
|
||||
if (enumfacing == Facing.EAST)
|
||||
{
|
||||
State iblockstate1 = blockAccess.getState(pos.west());
|
||||
Block block = iblockstate1.getBlock();
|
||||
|
||||
if (isBlockStairs(block) && blockstairs$enumhalf == iblockstate1.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing1 = (Facing)iblockstate1.getValue(FACING);
|
||||
|
||||
if (enumfacing1 == Facing.NORTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
|
||||
if (enumfacing1 == Facing.SOUTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.WEST)
|
||||
{
|
||||
State iblockstate2 = blockAccess.getState(pos.east());
|
||||
Block block1 = iblockstate2.getBlock();
|
||||
|
||||
if (isBlockStairs(block1) && blockstairs$enumhalf == iblockstate2.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing2 = (Facing)iblockstate2.getValue(FACING);
|
||||
|
||||
if (enumfacing2 == Facing.NORTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
|
||||
if (enumfacing2 == Facing.SOUTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.SOUTH)
|
||||
{
|
||||
State iblockstate3 = blockAccess.getState(pos.north());
|
||||
Block block2 = iblockstate3.getBlock();
|
||||
|
||||
if (isBlockStairs(block2) && blockstairs$enumhalf == iblockstate3.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing3 = (Facing)iblockstate3.getValue(FACING);
|
||||
|
||||
if (enumfacing3 == Facing.WEST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
|
||||
if (enumfacing3 == Facing.EAST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.NORTH)
|
||||
{
|
||||
State iblockstate4 = blockAccess.getState(pos.south());
|
||||
Block block3 = iblockstate4.getBlock();
|
||||
|
||||
if (isBlockStairs(block3) && blockstairs$enumhalf == iblockstate4.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing4 = (Facing)iblockstate4.getValue(FACING);
|
||||
|
||||
if (enumfacing4 == Facing.WEST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
return flag ? 1 : 2;
|
||||
}
|
||||
|
||||
if (enumfacing4 == Facing.EAST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
return flag ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean setBaseBlockBounds(IBlockAccess blockAccess, BlockPos pos)
|
||||
{
|
||||
State iblockstate = blockAccess.getState(pos);
|
||||
Facing enumfacing = (Facing)iblockstate.getValue(FACING);
|
||||
BlockStairs.EnumHalf blockstairs$enumhalf = (BlockStairs.EnumHalf)iblockstate.getValue(HALF);
|
||||
boolean flag = blockstairs$enumhalf == BlockStairs.EnumHalf.TOP;
|
||||
float f = 0.5F;
|
||||
float f1 = 1.0F;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
f = 0.0F;
|
||||
f1 = 0.5F;
|
||||
}
|
||||
|
||||
float f2 = 0.0F;
|
||||
float f3 = 1.0F;
|
||||
float f4 = 0.0F;
|
||||
float f5 = 0.5F;
|
||||
boolean flag1 = true;
|
||||
|
||||
if (enumfacing == Facing.EAST)
|
||||
{
|
||||
f2 = 0.5F;
|
||||
f5 = 1.0F;
|
||||
State iblockstate1 = blockAccess.getState(pos.east());
|
||||
Block block = iblockstate1.getBlock();
|
||||
|
||||
if (isBlockStairs(block) && blockstairs$enumhalf == iblockstate1.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing1 = (Facing)iblockstate1.getValue(FACING);
|
||||
|
||||
if (enumfacing1 == Facing.NORTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
f5 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
else if (enumfacing1 == Facing.SOUTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
f4 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.WEST)
|
||||
{
|
||||
f3 = 0.5F;
|
||||
f5 = 1.0F;
|
||||
State iblockstate2 = blockAccess.getState(pos.west());
|
||||
Block block1 = iblockstate2.getBlock();
|
||||
|
||||
if (isBlockStairs(block1) && blockstairs$enumhalf == iblockstate2.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing2 = (Facing)iblockstate2.getValue(FACING);
|
||||
|
||||
if (enumfacing2 == Facing.NORTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
f5 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
else if (enumfacing2 == Facing.SOUTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
f4 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.SOUTH)
|
||||
{
|
||||
f4 = 0.5F;
|
||||
f5 = 1.0F;
|
||||
State iblockstate3 = blockAccess.getState(pos.south());
|
||||
Block block2 = iblockstate3.getBlock();
|
||||
|
||||
if (isBlockStairs(block2) && blockstairs$enumhalf == iblockstate3.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing3 = (Facing)iblockstate3.getValue(FACING);
|
||||
|
||||
if (enumfacing3 == Facing.WEST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
f3 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
else if (enumfacing3 == Facing.EAST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
f2 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.NORTH)
|
||||
{
|
||||
State iblockstate4 = blockAccess.getState(pos.north());
|
||||
Block block3 = iblockstate4.getBlock();
|
||||
|
||||
if (isBlockStairs(block3) && blockstairs$enumhalf == iblockstate4.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing4 = (Facing)iblockstate4.getValue(FACING);
|
||||
|
||||
if (enumfacing4 == Facing.WEST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
f3 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
else if (enumfacing4 == Facing.EAST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
f2 = 0.5F;
|
||||
flag1 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setBlockBounds(f2, f, f4, f3, f1, f5);
|
||||
return flag1;
|
||||
}
|
||||
|
||||
public boolean setCollisionBlockBounds(IBlockAccess blockAccess, BlockPos pos)
|
||||
{
|
||||
State iblockstate = blockAccess.getState(pos);
|
||||
Facing enumfacing = (Facing)iblockstate.getValue(FACING);
|
||||
BlockStairs.EnumHalf blockstairs$enumhalf = (BlockStairs.EnumHalf)iblockstate.getValue(HALF);
|
||||
boolean flag = blockstairs$enumhalf == BlockStairs.EnumHalf.TOP;
|
||||
float f = 0.5F;
|
||||
float f1 = 1.0F;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
f = 0.0F;
|
||||
f1 = 0.5F;
|
||||
}
|
||||
|
||||
float f2 = 0.0F;
|
||||
float f3 = 0.5F;
|
||||
float f4 = 0.5F;
|
||||
float f5 = 1.0F;
|
||||
boolean flag1 = false;
|
||||
|
||||
if (enumfacing == Facing.EAST)
|
||||
{
|
||||
State iblockstate1 = blockAccess.getState(pos.west());
|
||||
Block block = iblockstate1.getBlock();
|
||||
|
||||
if (isBlockStairs(block) && blockstairs$enumhalf == iblockstate1.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing1 = (Facing)iblockstate1.getValue(FACING);
|
||||
|
||||
if (enumfacing1 == Facing.NORTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
f4 = 0.0F;
|
||||
f5 = 0.5F;
|
||||
flag1 = true;
|
||||
}
|
||||
else if (enumfacing1 == Facing.SOUTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
f4 = 0.5F;
|
||||
f5 = 1.0F;
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.WEST)
|
||||
{
|
||||
State iblockstate2 = blockAccess.getState(pos.east());
|
||||
Block block1 = iblockstate2.getBlock();
|
||||
|
||||
if (isBlockStairs(block1) && blockstairs$enumhalf == iblockstate2.getValue(HALF))
|
||||
{
|
||||
f2 = 0.5F;
|
||||
f3 = 1.0F;
|
||||
Facing enumfacing2 = (Facing)iblockstate2.getValue(FACING);
|
||||
|
||||
if (enumfacing2 == Facing.NORTH && !isSameStair(blockAccess, pos.north(), iblockstate))
|
||||
{
|
||||
f4 = 0.0F;
|
||||
f5 = 0.5F;
|
||||
flag1 = true;
|
||||
}
|
||||
else if (enumfacing2 == Facing.SOUTH && !isSameStair(blockAccess, pos.south(), iblockstate))
|
||||
{
|
||||
f4 = 0.5F;
|
||||
f5 = 1.0F;
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.SOUTH)
|
||||
{
|
||||
State iblockstate3 = blockAccess.getState(pos.north());
|
||||
Block block2 = iblockstate3.getBlock();
|
||||
|
||||
if (isBlockStairs(block2) && blockstairs$enumhalf == iblockstate3.getValue(HALF))
|
||||
{
|
||||
f4 = 0.0F;
|
||||
f5 = 0.5F;
|
||||
Facing enumfacing3 = (Facing)iblockstate3.getValue(FACING);
|
||||
|
||||
if (enumfacing3 == Facing.WEST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
flag1 = true;
|
||||
}
|
||||
else if (enumfacing3 == Facing.EAST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
f2 = 0.5F;
|
||||
f3 = 1.0F;
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enumfacing == Facing.NORTH)
|
||||
{
|
||||
State iblockstate4 = blockAccess.getState(pos.south());
|
||||
Block block3 = iblockstate4.getBlock();
|
||||
|
||||
if (isBlockStairs(block3) && blockstairs$enumhalf == iblockstate4.getValue(HALF))
|
||||
{
|
||||
Facing enumfacing4 = (Facing)iblockstate4.getValue(FACING);
|
||||
|
||||
if (enumfacing4 == Facing.WEST && !isSameStair(blockAccess, pos.west(), iblockstate))
|
||||
{
|
||||
flag1 = true;
|
||||
}
|
||||
else if (enumfacing4 == Facing.EAST && !isSameStair(blockAccess, pos.east(), iblockstate))
|
||||
{
|
||||
f2 = 0.5F;
|
||||
f3 = 1.0F;
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
this.setBlockBounds(f2, f, f4, f3, f1, f5);
|
||||
}
|
||||
|
||||
return flag1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all collision boxes of this Block to the list that intersect with the given mask.
|
||||
*/
|
||||
public void addCollisionBoxesToList(World worldIn, BlockPos pos, State state, BoundingBox mask, List<BoundingBox> list, Entity collidingEntity)
|
||||
{
|
||||
this.setBaseCollisionBounds(worldIn, pos);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
boolean flag = this.setBaseBlockBounds(worldIn, pos);
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
|
||||
if (flag && this.setCollisionBlockBounds(worldIn, pos))
|
||||
{
|
||||
super.addCollisionBoxesToList(worldIn, pos, state, mask, list, collidingEntity);
|
||||
}
|
||||
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
public void randomDisplayTick(AWorldClient worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
this.modelBlock.randomDisplayTick(worldIn, pos, state, rand);
|
||||
}
|
||||
|
||||
public void onBlockClicked(World worldIn, BlockPos pos, EntityNPC playerIn)
|
||||
{
|
||||
this.modelBlock.onBlockClicked(worldIn, pos, playerIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player destroys this Block
|
||||
*/
|
||||
public void onBlockDestroyedByPlayer(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
this.modelBlock.onBlockDestroyedByPlayer(worldIn, pos, state);
|
||||
}
|
||||
|
||||
public int getMixedBrightnessForBlock(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return this.modelBlock.getMixedBrightnessForBlock(worldIn, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how much this block can resist explosions from the passed in entity.
|
||||
*/
|
||||
public float getExplosionResistance(Entity exploder)
|
||||
{
|
||||
return this.modelBlock.getExplosionResistance(exploder);
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return this.modelBlock.getBlockLayer();
|
||||
}
|
||||
|
||||
/**
|
||||
* How many world ticks before ticking
|
||||
*/
|
||||
public int tickRate(World worldIn, BlockPos pos)
|
||||
{
|
||||
return this.modelBlock.tickRate(worldIn, pos);
|
||||
}
|
||||
|
||||
public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos)
|
||||
{
|
||||
return this.modelBlock.getSelectedBoundingBox(worldIn, pos);
|
||||
}
|
||||
|
||||
public Vec3 modifyAcceleration(World worldIn, BlockPos pos, Entity entityIn, Vec3 motion)
|
||||
{
|
||||
return this.modelBlock.modifyAcceleration(worldIn, pos, entityIn, motion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if this block is collidable (only used by Fire). Args: x, y, z
|
||||
*/
|
||||
public boolean isCollidable()
|
||||
{
|
||||
return this.modelBlock.isCollidable();
|
||||
}
|
||||
|
||||
public boolean canCollideCheck(State state, boolean liquid)
|
||||
{
|
||||
return this.modelBlock.canCollideCheck(state, liquid);
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return this.modelBlock.canPlaceBlockAt(worldIn, pos);
|
||||
}
|
||||
|
||||
public void onBlockAdded(AWorldServer worldIn, BlockPos pos, State state)
|
||||
{
|
||||
this.onNeighborBlockChange(worldIn, pos, this.modelState, Blocks.air);
|
||||
this.modelBlock.onBlockAdded(worldIn, pos, this.modelState);
|
||||
}
|
||||
|
||||
public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state)
|
||||
{
|
||||
this.modelBlock.onBlockRemoved(worldIn, pos, this.modelState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered whenever an entity collides with this block (enters into the block)
|
||||
*/
|
||||
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, Entity entityIn)
|
||||
{
|
||||
this.modelBlock.onEntityCollidedWithBlock(worldIn, pos, entityIn);
|
||||
}
|
||||
|
||||
public void updateTick(AWorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
this.modelBlock.updateTick(worldIn, pos, state, rand);
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
return this.modelBlock.onBlockActivated(worldIn, pos, this.modelState, playerIn, Facing.DOWN, 0.0F, 0.0F, 0.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this Block is destroyed by an Explosion
|
||||
*/
|
||||
public void onBlockDestroyedByExplosion(World worldIn, BlockPos pos, Explosion explosionIn, State prevState)
|
||||
{
|
||||
this.modelBlock.onBlockDestroyedByExplosion(worldIn, pos, explosionIn, prevState);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the MapColor for this Block and the given BlockState
|
||||
// */
|
||||
// public MapColor getMapColor(IBlockState state)
|
||||
// {
|
||||
// return this.modelBlock.getMapColor(this.modelState);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
|
||||
* IBlockstate
|
||||
*/
|
||||
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, int meta, EntityLiving placer)
|
||||
{
|
||||
State iblockstate = super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer);
|
||||
iblockstate = iblockstate.withProperty(FACING, placer.getHorizontalFacing()).withProperty(SHAPE, BlockStairs.EnumShape.STRAIGHT);
|
||||
return facing != Facing.DOWN && (facing == Facing.UP || (double)hitY <= 0.5D) ? iblockstate.withProperty(HALF, BlockStairs.EnumHalf.BOTTOM) : iblockstate.withProperty(HALF, BlockStairs.EnumHalf.TOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ray traces through the blocks collision from start vector to end vector returning a ray trace hit.
|
||||
*/
|
||||
public HitPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end)
|
||||
{
|
||||
HitPosition[] amovingobjectposition = new HitPosition[8];
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
int i = ((Facing)iblockstate.getValue(FACING)).getHorizontalIndex();
|
||||
boolean flag = iblockstate.getValue(HALF) == BlockStairs.EnumHalf.TOP;
|
||||
int[] aint = field_150150_a[i + (flag ? 4 : 0)];
|
||||
this.hasRaytraced = true;
|
||||
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
this.rayTracePass = j;
|
||||
|
||||
if (Arrays.binarySearch(aint, j) < 0)
|
||||
{
|
||||
amovingobjectposition[j] = super.collisionRayTrace(worldIn, pos, start, end);
|
||||
}
|
||||
}
|
||||
|
||||
for (int k : aint)
|
||||
{
|
||||
amovingobjectposition[k] = null;
|
||||
}
|
||||
|
||||
HitPosition movingobjectposition1 = null;
|
||||
double d1 = 0.0D;
|
||||
|
||||
for (HitPosition movingobjectposition : amovingobjectposition)
|
||||
{
|
||||
if (movingobjectposition != null)
|
||||
{
|
||||
double d0 = movingobjectposition.vec.squareDistanceTo(end);
|
||||
|
||||
if (d0 > d1)
|
||||
{
|
||||
movingobjectposition1 = movingobjectposition;
|
||||
d1 = d0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return movingobjectposition1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
State iblockstate = this.getState().withProperty(HALF, (meta & 4) > 0 ? BlockStairs.EnumHalf.TOP : BlockStairs.EnumHalf.BOTTOM);
|
||||
iblockstate = iblockstate.withProperty(FACING, Facing.getFront(5 - (meta & 3)));
|
||||
return iblockstate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (state.getValue(HALF) == BlockStairs.EnumHalf.TOP)
|
||||
{
|
||||
i |= 4;
|
||||
}
|
||||
|
||||
i = i | 5 - ((Facing)state.getValue(FACING)).getIndex();
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual Block state of this Block at the given position. This applies properties not visible in the
|
||||
* metadata, such as fence connections.
|
||||
*/
|
||||
public State getActualState(State state, IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
if (this.setBaseBlockBounds(worldIn, pos))
|
||||
{
|
||||
switch (this.getInnerShape(worldIn, pos))
|
||||
{
|
||||
case 0:
|
||||
state = state.withProperty(SHAPE, BlockStairs.EnumShape.STRAIGHT);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
state = state.withProperty(SHAPE, BlockStairs.EnumShape.INNER_RIGHT);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
state = state.withProperty(SHAPE, BlockStairs.EnumShape.INNER_LEFT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (this.getOuterShape(worldIn, pos))
|
||||
{
|
||||
case 0:
|
||||
state = state.withProperty(SHAPE, BlockStairs.EnumShape.STRAIGHT);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
state = state.withProperty(SHAPE, BlockStairs.EnumShape.OUTER_RIGHT);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
state = state.withProperty(SHAPE, BlockStairs.EnumShape.OUTER_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {FACING, HALF, SHAPE};
|
||||
}
|
||||
|
||||
public Transforms getTransform() {
|
||||
return Transforms.STAIRS;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
String primary = this.modelBlock.getModel(provider, BlockRegistry.REGISTRY.getNameForObject(this.modelBlock).toString(), this.modelState)
|
||||
.getPrimary();
|
||||
return provider.getModel(primary)
|
||||
.stairs(state.getValue(HALF) == EnumHalf.TOP, state.getValue(SHAPE) == EnumShape.INNER_RIGHT ||
|
||||
state.getValue(SHAPE) == EnumShape.INNER_LEFT, state.getValue(SHAPE) == EnumShape.OUTER_RIGHT ||
|
||||
state.getValue(SHAPE) == EnumShape.OUTER_LEFT, state.getValue(SHAPE) == EnumShape.INNER_LEFT ||
|
||||
state.getValue(SHAPE) == EnumShape.OUTER_LEFT, state.getValue(FACING),
|
||||
this.downTex != null ? this.downTex : primary, this.upTex != null ? this.upTex : primary
|
||||
// state.getBlock() == Blocks.quartz_stairs ? "quartz_block_bottom" :
|
||||
// (state.getBlock() == Blocks.sandstone_stairs ? "sandstone_bottom" : (state.getBlock() == Blocks.black_quartz_stairs ? "black_quartz_block_bottom" : primary)),
|
||||
// state.getBlock() == Blocks.quartz_stairs ? "quartz_top" :
|
||||
// (state.getBlock() == Blocks.sandstone_stairs ? "sandstone_all" : (state.getBlock() == Blocks.black_quartz_stairs ? "black_quartz_top" : primary))
|
||||
);
|
||||
}
|
||||
|
||||
public static enum EnumHalf implements Identifyable
|
||||
{
|
||||
TOP("top"),
|
||||
BOTTOM("bottom");
|
||||
|
||||
private final String name;
|
||||
|
||||
private EnumHalf(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum EnumShape implements Identifyable
|
||||
{
|
||||
STRAIGHT("straight"),
|
||||
INNER_LEFT("inner_left"),
|
||||
INNER_RIGHT("inner_right"),
|
||||
OUTER_LEFT("outer_left"),
|
||||
OUTER_RIGHT("outer_right");
|
||||
|
||||
private final String name;
|
||||
|
||||
private EnumShape(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
}
|
140
common/src/main/java/common/block/artificial/BlockStoneBrick.java
Executable file
140
common/src/main/java/common/block/artificial/BlockStoneBrick.java
Executable file
|
@ -0,0 +1,140 @@
|
|||
package common.block.artificial;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyEnum;
|
||||
import common.util.Identifyable;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockStoneBrick extends Block
|
||||
{
|
||||
public static final PropertyEnum<BlockStoneBrick.EnumType> VARIANT = PropertyEnum.<BlockStoneBrick.EnumType>create("variant", BlockStoneBrick.EnumType.class);
|
||||
public static final int DEFAULT_META = BlockStoneBrick.EnumType.DEFAULT.getMetadata();
|
||||
public static final int MOSSY_META = BlockStoneBrick.EnumType.MOSSY.getMetadata();
|
||||
public static final int CRACKED_META = BlockStoneBrick.EnumType.CRACKED.getMetadata();
|
||||
public static final int CHISELED_META = BlockStoneBrick.EnumType.CHISELED.getMetadata();
|
||||
|
||||
public BlockStoneBrick()
|
||||
{
|
||||
super(Material.SOLID);
|
||||
this.setDefaultState(this.getBaseState().withProperty(VARIANT, BlockStoneBrick.EnumType.DEFAULT));
|
||||
this.setTab(CheatTab.BLOCKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata of the item this Block can drop. This method is called when the block gets destroyed. It
|
||||
* returns the metadata of the dropped item based on the old metadata of the block.
|
||||
*/
|
||||
public int damageDropped(State state)
|
||||
{
|
||||
return ((BlockStoneBrick.EnumType)state.getValue(VARIANT)).getMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
|
||||
*/
|
||||
public void getSubBlocks(Item itemIn, CheatTab tab, List<ItemStack> list)
|
||||
{
|
||||
for (BlockStoneBrick.EnumType blockstonebrick$enumtype : BlockStoneBrick.EnumType.values())
|
||||
{
|
||||
list.add(new ItemStack(itemIn, 1, blockstonebrick$enumtype.getMetadata()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(VARIANT, BlockStoneBrick.EnumType.byMetadata(meta));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((BlockStoneBrick.EnumType)state.getValue(VARIANT)).getMetadata();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {VARIANT};
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel("stonebrick_" + state.getValue(VARIANT).getTexture()).add().all();
|
||||
}
|
||||
|
||||
public static enum EnumType implements Identifyable
|
||||
{
|
||||
DEFAULT("default", 0, "stonebrick", "Steinziegel"),
|
||||
MOSSY("mossy", 1, "mossy_stonebrick", "Bemooste Steinziegel"),
|
||||
CRACKED("cracked", 2, "cracked_stonebrick", "Rissige Steinziegel"),
|
||||
CHISELED("chiseled", 3, "chiseled_stonebrick", "Gemeißelte Steinziegel");
|
||||
|
||||
private static final BlockStoneBrick.EnumType[] META_LOOKUP = new BlockStoneBrick.EnumType[values().length];
|
||||
private final int meta;
|
||||
private final String texture;
|
||||
private final String name;
|
||||
private final String display;
|
||||
|
||||
private EnumType(String texture, int meta, String name, String display)
|
||||
{
|
||||
this.texture = texture;
|
||||
this.meta = meta;
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
public int getMetadata()
|
||||
{
|
||||
return this.meta;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static BlockStoneBrick.EnumType byMetadata(int meta)
|
||||
{
|
||||
if (meta < 0 || meta >= META_LOOKUP.length)
|
||||
{
|
||||
meta = 0;
|
||||
}
|
||||
|
||||
return META_LOOKUP[meta];
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getTexture()
|
||||
{
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
public String getDisplay()
|
||||
{
|
||||
return this.display;
|
||||
}
|
||||
|
||||
static {
|
||||
for (BlockStoneBrick.EnumType blockstonebrick$enumtype : values())
|
||||
{
|
||||
META_LOOKUP[blockstonebrick$enumtype.getMetadata()] = blockstonebrick$enumtype;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
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