change project names and libraries
This commit is contained in:
parent
278fd0b7e2
commit
6cab25e79f
967 changed files with 4 additions and 3 deletions
34
common/src/common/IClient.java
Normal file
34
common/src/common/IClient.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package common;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.IEntityFX;
|
||||
import common.model.ParticleType;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.sound.Sound;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
|
||||
public interface IClient {
|
||||
int getRenderDistance();
|
||||
float getGravity();
|
||||
int getTimeFactor();
|
||||
boolean hasDayCycle();
|
||||
void playSound(Sound sound);
|
||||
EntityNPC getPlayer();
|
||||
Entity getRenderViewEntity();
|
||||
void makeFireworks(double x, double y, double z, double motionX, double motionY, double motionZ, NBTTagCompound compund);
|
||||
IEntityFX spawnEffectParticle(int particleId, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int[] parameters);
|
||||
void addBlockDestroyEffects(BlockPos pos, State state);
|
||||
void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress);
|
||||
void markBlocksForUpdate(int x1, int y1, int z1, int x2, int y2, int z2);
|
||||
void updatePlayerMoveState();
|
||||
void emitParticleAtEntity(Entity entityIn, ParticleType particleTypes);
|
||||
boolean isJumping();
|
||||
boolean isSprinting();
|
||||
boolean isSneaking();
|
||||
float getMoveForward();
|
||||
float getMoveStrafe();
|
||||
void setMoveForward(float value);
|
||||
void setMoveStrafe(float value);
|
||||
}
|
25
common/src/common/IServer.java
Normal file
25
common/src/common/IServer.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package common;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.network.IPlayer;
|
||||
import common.network.Packet;
|
||||
import common.world.BlockPos;
|
||||
import common.world.PortalType;
|
||||
import common.world.Position;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public interface IServer {
|
||||
List<IPlayer> getIPlayers();
|
||||
void sendPacket(Packet packet);
|
||||
void sendPacket(Packet packet, int dimension);
|
||||
void sendNear(double x, double y, double z, double radius, int dimension, Packet packet);
|
||||
void sendNearExcept(EntityNPC except, double x, double y, double z, double radius, int dimension, Packet packet);
|
||||
Map<String, Position> getWarps();
|
||||
List<WorldServer> getWorlds();
|
||||
WorldServer getWorld(int dimension);
|
||||
void placeInDimension(Entity entity, WorldServer oldWorld, WorldServer world, BlockPos pos, PortalType portal);
|
||||
}
|
96
common/src/common/ai/AIFireballAttack.java
Executable file
96
common/src/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.world.BlockPos;
|
||||
import common.world.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/common/ai/AIFlyingBoxAttack.java
Executable file
91
common/src/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.world.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/common/ai/AIRangedAttack.java
Executable file
122
common/src/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/common/ai/AISmallFireballAttack.java
Executable file
105
common/src/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.world.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/common/ai/EntityAIAttackOnCollide.java
Executable file
167
common/src/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.world.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/common/ai/EntityAIAvoidEntity.java
Executable file
126
common/src/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.world.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/common/ai/EntityAIBase.java
Executable file
71
common/src/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/common/ai/EntityAIBeg.java
Executable file
77
common/src/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/common/ai/EntityAIControlledByPlayer.java
Executable file
226
common/src/common/ai/EntityAIControlledByPlayer.java
Executable file
|
@ -0,0 +1,226 @@
|
|||
package common.ai;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockSlab;
|
||||
import common.block.BlockStairs;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Items;
|
||||
import common.item.ItemStack;
|
||||
import common.material.Material;
|
||||
import common.pathfinding.WalkNodeProcessor;
|
||||
import common.util.ExtMath;
|
||||
import common.world.BlockPos;
|
||||
|
||||
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.getMaterial() != Material.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/common/ai/EntityAIDoorInteract.java
Executable file
118
common/src/common/ai/EntityAIDoorInteract.java
Executable file
|
@ -0,0 +1,118 @@
|
|||
package common.ai;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockDoor;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.material.Material;
|
||||
import common.pathfinding.PathEntity;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.pathfinding.PathPoint;
|
||||
import common.world.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;
|
||||
}
|
||||
}
|
118
common/src/common/ai/EntityAIEatGrass.java
Executable file
118
common/src/common/ai/EntityAIEatGrass.java
Executable file
|
@ -0,0 +1,118 @@
|
|||
package common.ai;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.block.BlockTallGrass;
|
||||
import common.entity.animal.EntitySheep;
|
||||
import common.init.BlockRegistry;
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.pattern.BlockStateHelper;
|
||||
import common.util.Predicates;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class EntityAIEatGrass extends EntityAIBase
|
||||
{
|
||||
private static final Predicate<State> field_179505_b = BlockStateHelper.forBlock(Blocks.tallgrass).where(BlockTallGrass.TYPE, Predicates.equalTo(BlockTallGrass.EnumType.GRASS));
|
||||
|
||||
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);
|
||||
return field_179505_b.test(this.entityWorld.getState(blockpos)) ? true : 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);
|
||||
|
||||
if (field_179505_b.test(this.entityWorld.getState(blockpos)))
|
||||
{
|
||||
if (Config.mobGrief)
|
||||
{
|
||||
this.entityWorld.destroyBlock(blockpos, false);
|
||||
}
|
||||
|
||||
this.grassEaterEntity.eatGrassBonus();
|
||||
}
|
||||
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.eatGrassBonus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
65
common/src/common/ai/EntityAIExplode.java
Executable file
65
common/src/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/common/ai/EntityAIFindEntityNearest.java
Executable file
111
common/src/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.entity.attributes.AttributeInstance;
|
||||
import common.entity.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/common/ai/EntityAIFleeSun.java
Executable file
95
common/src/common/ai/EntityAIFleeSun.java
Executable file
|
@ -0,0 +1,95 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.Vec3;
|
||||
import common.world.World;
|
||||
import common.world.WorldServer;
|
||||
|
||||
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 (!((WorldServer)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/common/ai/EntityAIFollowOwner.java
Executable file
115
common/src/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/common/ai/EntityAIFollowParent.java
Executable file
112
common/src/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/common/ai/EntityAIHarvestFarmland.java
Executable file
159
common/src/common/ai/EntityAIHarvestFarmland.java
Executable file
|
@ -0,0 +1,159 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.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/common/ai/EntityAIHurtByTarget.java
Executable file
73
common/src/common/ai/EntityAIHurtByTarget.java
Executable file
|
@ -0,0 +1,73 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.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/common/ai/EntityAILeapAtTarget.java
Executable file
62
common/src/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/common/ai/EntityAILookAtTalkingPlayer.java
Executable file
27
common/src/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/common/ai/EntityAILookIdle.java
Executable file
62
common/src/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/common/ai/EntityAIMate.java
Executable file
167
common/src/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/common/ai/EntityAIMoveIndoors.java
Executable file
104
common/src/common/ai/EntityAIMoveIndoors.java
Executable file
|
@ -0,0 +1,104 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.village.Village;
|
||||
import common.village.VillageDoorInfo;
|
||||
import common.world.BlockPos;
|
||||
import common.world.Vec3;
|
||||
import common.world.WorldServer;
|
||||
|
||||
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 ((!((WorldServer)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 = ((WorldServer)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/common/ai/EntityAIMoveThroughVillage.java
Executable file
174
common/src/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.ExtMath;
|
||||
import common.village.Village;
|
||||
import common.village.VillageDoorInfo;
|
||||
import common.world.BlockPos;
|
||||
import common.world.Vec3;
|
||||
import common.world.WorldServer;
|
||||
|
||||
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 && ((WorldServer)this.theEntity.worldObj).isDaytime())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Village village = ((WorldServer)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/common/ai/EntityAIMoveToBlock.java
Executable file
137
common/src/common/ai/EntityAIMoveToBlock.java
Executable file
|
@ -0,0 +1,137 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.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/common/ai/EntityAIMoveTowardsRestriction.java
Executable file
65
common/src/common/ai/EntityAIMoveTowardsRestriction.java
Executable file
|
@ -0,0 +1,65 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.BlockPos;
|
||||
import common.world.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/common/ai/EntityAIMoveTowardsTarget.java
Executable file
84
common/src/common/ai/EntityAIMoveTowardsTarget.java
Executable file
|
@ -0,0 +1,84 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.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/common/ai/EntityAINagPlayer.java
Executable file
50
common/src/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/common/ai/EntityAINearestAttackableTarget.java
Executable file
133
common/src/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/common/ai/EntityAINpcInteract.java
Executable file
56
common/src/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/common/ai/EntityAINpcMate.java
Executable file
108
common/src/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.WorldServer;
|
||||
|
||||
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 = ((WorldServer)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/common/ai/EntityAIOcelotAttack.java
Executable file
86
common/src/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/common/ai/EntityAIOcelotSit.java
Executable file
114
common/src/common/ai/EntityAIOcelotSit.java
Executable file
|
@ -0,0 +1,114 @@
|
|||
package common.ai;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockBed;
|
||||
import common.entity.animal.EntityOcelot;
|
||||
import common.init.Blocks;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.tileentity.TileEntityChest;
|
||||
import common.world.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/common/ai/EntityAIOpenDoor.java
Executable file
58
common/src/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/common/ai/EntityAIOwnerHurtByTarget.java
Executable file
60
common/src/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/common/ai/EntityAIOwnerHurtTarget.java
Executable file
60
common/src/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/common/ai/EntityAIPanic.java
Executable file
63
common/src/common/ai/EntityAIPanic.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.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/common/ai/EntityAIPlay.java
Executable file
72
common/src/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.world.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/common/ai/EntityAIRestrictOpenDoor.java
Executable file
85
common/src/common/ai/EntityAIRestrictOpenDoor.java
Executable file
|
@ -0,0 +1,85 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.pathfinding.PathNavigateGround;
|
||||
import common.village.Village;
|
||||
import common.village.VillageDoorInfo;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
|
||||
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 (((WorldServer)this.entityObj.worldObj).isDaytime())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockPos blockpos = new BlockPos(this.entityObj);
|
||||
Village village = ((WorldServer)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 ((WorldServer)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/common/ai/EntityAIRestrictSun.java
Executable file
39
common/src/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.WorldServer;
|
||||
|
||||
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 ((WorldServer)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/common/ai/EntityAIRunAroundLikeCrazy.java
Executable file
94
common/src/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.world.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/common/ai/EntityAIShareItems.java
Executable file
101
common/src/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/common/ai/EntityAISit.java
Executable file
67
common/src/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/common/ai/EntityAISwimming.java
Executable file
35
common/src/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();
|
||||
}
|
||||
}
|
||||
}
|
162
common/src/common/ai/EntityAITakePlace.java
Executable file
162
common/src/common/ai/EntityAITakePlace.java
Executable file
|
@ -0,0 +1,162 @@
|
|||
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.material.Material;
|
||||
import common.rng.Random;
|
||||
import common.util.ExtMath;
|
||||
import common.world.BlockPos;
|
||||
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.getMaterial() == Material.air &&
|
||||
below.getMaterial() != Material.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/common/ai/EntityAITarget.java
Executable file
255
common/src/common/ai/EntityAITarget.java
Executable file
|
@ -0,0 +1,255 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.attributes.AttributeInstance;
|
||||
import common.entity.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.ExtMath;
|
||||
import common.world.BlockPos;
|
||||
|
||||
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/common/ai/EntityAITargetNonTamed.java
Executable file
25
common/src/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/common/ai/EntityAITasks.java
Executable file
173
common/src/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/common/ai/EntityAITempt.java
Executable file
181
common/src/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/common/ai/EntityAIWander.java
Executable file
94
common/src/common/ai/EntityAIWander.java
Executable file
|
@ -0,0 +1,94 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.world.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/common/ai/EntityAIWatchClosest.java
Executable file
99
common/src/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.WorldServer;
|
||||
|
||||
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 = ((WorldServer)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/common/ai/EntityAIWatchClosest2.java
Executable file
13
common/src/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/common/ai/EntityJumpHelper.java
Executable file
28
common/src/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/common/ai/EntityLookHelper.java
Executable file
143
common/src/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/common/ai/EntityMoveHelper.java
Executable file
121
common/src/common/ai/EntityMoveHelper.java
Executable file
|
@ -0,0 +1,121 @@
|
|||
package common.ai;
|
||||
|
||||
import common.entity.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/common/ai/EntitySenses.java
Executable file
60
common/src/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/common/ai/RandomPositionGenerator.java
Executable file
129
common/src/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.ExtMath;
|
||||
import common.world.BlockPos;
|
||||
import common.world.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;
|
||||
}
|
||||
}
|
||||
}
|
770
common/src/common/biome/Biome.java
Executable file
770
common/src/common/biome/Biome.java
Executable file
|
@ -0,0 +1,770 @@
|
|||
package common.biome;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockColored;
|
||||
import common.block.BlockFlower;
|
||||
import common.block.BlockSand;
|
||||
import common.block.BlockTallGrass;
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
import common.color.Colorizer;
|
||||
import common.color.DyeColor;
|
||||
import common.entity.animal.EntityBat;
|
||||
import common.entity.animal.EntityChicken;
|
||||
import common.entity.animal.EntityCow;
|
||||
import common.entity.animal.EntityMouse;
|
||||
import common.entity.animal.EntityPig;
|
||||
import common.entity.animal.EntityRabbit;
|
||||
import common.entity.animal.EntitySheep;
|
||||
import common.entity.animal.EntitySquid;
|
||||
import common.entity.npc.EntityArachnoid;
|
||||
import common.entity.npc.EntityHaunter;
|
||||
import common.entity.npc.EntityMage;
|
||||
import common.entity.npc.EntitySlime;
|
||||
import common.entity.npc.EntityUndead;
|
||||
import common.entity.npc.EntityZombie;
|
||||
import common.init.Blocks;
|
||||
import common.log.Log;
|
||||
import common.material.Material;
|
||||
import common.rng.PerlinGen;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.ExtMath;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
import common.worldgen.FeatureGenerator;
|
||||
import common.worldgen.feature.WorldGenClay;
|
||||
import common.worldgen.feature.WorldGenClayExt;
|
||||
import common.worldgen.feature.WorldGenSand;
|
||||
import common.worldgen.foliage.FeatureDoublePlant;
|
||||
import common.worldgen.foliage.WorldGenBigMushroom;
|
||||
import common.worldgen.foliage.WorldGenCactus;
|
||||
import common.worldgen.foliage.WorldGenDeadBush;
|
||||
import common.worldgen.foliage.WorldGenFlowers;
|
||||
import common.worldgen.foliage.WorldGenMushroom;
|
||||
import common.worldgen.foliage.WorldGenPumpkin;
|
||||
import common.worldgen.foliage.WorldGenReed;
|
||||
import common.worldgen.foliage.WorldGenTallGrass;
|
||||
import common.worldgen.foliage.WorldGenWaterlily;
|
||||
import common.worldgen.tree.WorldGenBaseTree;
|
||||
import common.worldgen.tree.WorldGenBigTree;
|
||||
import common.worldgen.tree.WorldGenSwamp;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public abstract class Biome {
|
||||
private static final Biome[] BIOMES = new Biome[256];
|
||||
|
||||
public static final Biome none = (new BiomeNone(0)).setBiomeName("none", "<Keins>");
|
||||
|
||||
public static final Biome plains = (new BiomePlains(1)).setColor(9286496).setBiomeName("plains", "Ebene");
|
||||
public static final Biome desert = (new BiomeDesert(2)).setColor(16421912).setBiomeName("desert", "Wüste").setTemperature(60.0f).setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final Biome extremeHills = (new BiomeHills(3, false)).setColor(6316128).setBiomeName("extremeHills", "Extremes Bergland").setScaling(Scaling.HILLS_LARGE).setTemperature(-12.0f).setHumidity(30.0f);
|
||||
public static final Biome forest = (new BiomeForest(4, 0)).setColor(353825).setBiomeName("forest", "Wald");
|
||||
public static final Biome taiga = (new BiomeTaiga(5, 0)).setColor(747097).setBiomeName("taiga", "Taiga").setTemperature(-10.0f).setHumidity(80.0f).setScaling(Scaling.PLAINS_MEDIUM);
|
||||
public static final Biome swampland = (new BiomeSwamp(6)).setColor(522674).setBiomeName("swampland", "Sumpf").setScaling(Scaling.SEA_POND).setTemperature(12.0f).setHumidity(90.0f);
|
||||
public static final Biome river = (new BiomeWater(7, true)).setColor(255).setBiomeName("river", "Fluss").setScaling(Scaling.SEA_SHALLOW);
|
||||
|
||||
public static final Biome exterminated = (new BiomeExterminated(8)).setColor(0x000000).setBiomeName("exterminated", "Ausgelöscht").setHumidity(0.0f).setTemperature(150.0f);
|
||||
public static final Biome space = (new BiomeSpace(9)).setColor(0x000000).setBiomeName("space", "Leere des Weltraums").setHumidity(0.0f);
|
||||
|
||||
public static final Biome frozenSea = (new BiomeWater(10, false)).setColor(9474208).setBiomeName("frozenSea", "Vereister See").enableColdBeach().setScaling(Scaling.SEA_MEDIUM).setTemperature(-20.0f).setHumidity(50.0f);
|
||||
public static final Biome frozenRiver = (new BiomeWater(11, true)).setColor(10526975).setBiomeName("frozenRiver", "Vereister Fluss").enableColdBeach().setScaling(Scaling.SEA_SHALLOW).setTemperature(-20.0f).setHumidity(50.0f);
|
||||
public static final Biome icePlains = (new BiomeSnow(12, false)).setColor(16777215).setBiomeName("icePlains", "Eisebene").enableColdBeach().setTemperature(-20.0f).setHumidity(50.0f).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final Biome iceMountains = (new BiomeSnow(13, false)).setColor(10526880).setBiomeName("iceMountains", "Vereistes Bergland").enableColdBeach().setScaling(Scaling.HILLS_LOW).setTemperature(-20.0f).setHumidity(50.0f);
|
||||
public static final Biome mushroomPlains = (new BiomeMushroom(14)).setColor(16711935).setBiomeName("mushroomPlains", "Pilzland").setTemperature(16.0f).setHumidity(100.0f).setScaling(Scaling.PLAINS_VARYING);
|
||||
public static final Biome blackened = (new BiomeBlackened(15)).setColor(0x000000).setBiomeName("blackened", "Schwarz").setHumidity(0.0f);
|
||||
public static final Biome beach = (new BiomeBeach(16)).setColor(16440917).setBiomeName("beach", "Strand").setTemperature(12.0f).setHumidity(40.0f).setScaling(Scaling.SEA_SHORE);
|
||||
public static final Biome desertHills = (new BiomeDesert(17)).setColor(13786898).setBiomeName("desertHills", "Wüsten-Bergland").setTemperature(60.0f).setHumidity(0.0f).setScaling(Scaling.HILLS_LOW);
|
||||
public static final Biome forestHills = (new BiomeForest(18, 0)).setColor(2250012).setBiomeName("forestHills", "Wald-Bergland").setScaling(Scaling.HILLS_LOW);
|
||||
public static final Biome taigaHills = (new BiomeTaiga(19, 0)).setColor(1456435).setBiomeName("taigaHills", "Taiga-Bergland").setTemperature(-10.0f).setHumidity(80.0f).setScaling(Scaling.HILLS_LOW);
|
||||
public static final Biome extremeHillsEdge = (new BiomeHills(20, true)).setColor(7501978).setBiomeName("extremeHillsEdge", "Extremes Bergland Gr.").setScaling(Scaling.HILLS_MEDIUM).setTemperature(-12.0f).setHumidity(30.0f);
|
||||
public static final Biome jungle = (new BiomeJungle(21, false)).setColor(5470985).setBiomeName("jungle", "Urwald").setTemperature(18.0f).setHumidity(90.0f);
|
||||
public static final Biome jungleHills = (new BiomeJungle(22, false)).setColor(2900485).setBiomeName("jungleHills", "Urwald-Bergland").setTemperature(18.0f).setHumidity(90.0f).setScaling(Scaling.HILLS_LOW);
|
||||
public static final Biome jungleEdge = (new BiomeJungle(23, true)).setColor(6458135).setBiomeName("jungleEdge", "Urwald Gr.").setTemperature(18.0f).setHumidity(80.0f);
|
||||
public static final Biome sea = (new BiomeWater(24, false)).setColor(112).setBiomeName("sea", "See").setScaling(Scaling.SEA_MEDIUM);
|
||||
public static final Biome stoneBeach = (new BiomeStoneBeach(25)).setColor(10658436).setBiomeName("stoneBeach", "Steinstrand").setTemperature(-12.0f).setHumidity(30.0f).setScaling(Scaling.SEA_VARYING);
|
||||
public static final Biome coldBeach = (new BiomeBeach(26)).setColor(16445632).setBiomeName("coldBeach", "Vereister Strand").setTemperature(-18.0f).setHumidity(30.0f).setScaling(Scaling.SEA_SHORE).enableColdBeach();
|
||||
public static final Biome birchForest = (new BiomeForest(27, 2)).setBiomeName("birchForest", "Birkenwald").setColor(3175492);
|
||||
public static final Biome birchForestHills = (new BiomeForest(28, 2)).setBiomeName("birchForestHills", "Birkenwald-Bergland").setColor(2055986).setScaling(Scaling.HILLS_LOW);
|
||||
public static final Biome roofedForest = (new BiomeForest(29, 3)).setColor(4215066).setBiomeName("roofedForest", "Dichter Wald");
|
||||
public static final Biome coldTaiga = (new BiomeTaiga(30, 0)).setColor(3233098).setBiomeName("coldTaiga", "Vereiste Taiga").enableColdBeach().setTemperature(-40.0f).setHumidity(40.0f).setScaling(Scaling.PLAINS_MEDIUM);
|
||||
public static final Biome coldTaigaHills = (new BiomeTaiga(31, 0)).setColor(2375478).setBiomeName("coldTaigaHills", "Vereistes Taiga-Bergland").enableColdBeach().setTemperature(-40.0f).setHumidity(40.0f).setScaling(Scaling.HILLS_LOW);
|
||||
public static final Biome megaTaiga = (new BiomeTaiga(32, 1)).setColor(5858897).setBiomeName("megaTaiga", "Hohe Taiga").setTemperature(-8.0f).setHumidity(80.0f).setScaling(Scaling.PLAINS_MEDIUM);
|
||||
public static final Biome megaTaigaHills = (new BiomeTaiga(33, 1)).setColor(4542270).setBiomeName("megaTaigaHills", "Hohes Taiga-Bergland").setTemperature(-8.0f).setHumidity(80.0f).setScaling(Scaling.HILLS_LOW);
|
||||
public static final Biome extremeHillsPlus = (new BiomeHills(34, true)).setColor(5271632).setBiomeName("extremeHillsPlus", "Extremes Bergland +").setScaling(Scaling.HILLS_LARGE).setTemperature(-12.0f).setHumidity(30.0f);
|
||||
public static final Biome savanna = (new BiomeSavanna(35)).setColor(12431967).setBiomeName("savanna", "Savanne").setTemperature(28.0F).setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final Biome savannaPlateau = (new BiomeSavanna(36)).setColor(10984804).setBiomeName("savannaPlateau", "Savannen-Plateau").setTemperature(20.0F).setHumidity(0.0f).setScaling(Scaling.HILLS_PLATEAU);
|
||||
|
||||
public static final Biome mesa = (new BiomeMesa(37, false, false)).setColor(14238997).setBiomeName("mesa", "Mesa");
|
||||
public static final Biome mesaPlateau_F = (new BiomeMesa(38, false, true)).setColor(11573093).setBiomeName("mesaPlateauF", "Mesa-Waldplateau").setScaling(Scaling.HILLS_PLATEAU);
|
||||
public static final Biome mesaPlateau = (new BiomeMesa(39, false, false)).setColor(13274213).setBiomeName("mesaPlateau", "Mesa-Plateau").setScaling(Scaling.HILLS_PLATEAU);
|
||||
|
||||
public static final Biome snowLand = (new BiomeSnowLand(40)).setColor(0xffffff).setBiomeName("snowLand", "Eisland").enableColdBeach().setHumidity(100.0f);
|
||||
public static final Biome tian = (new BiomeTian(41)).setColor(0x808080).setBiomeName("tian", "Tian").setHumidity(80.0f).setScaling(Scaling.VARYING_MEDIUM);
|
||||
public static final Biome elvenForest = (new BiomeForest(42, 4)).setColor(0x059821).setBiomeName("elvenForest", "Elbenwald").setHumidity(90.0f);
|
||||
public static final Biome upperHell = (new BiomeHell(43, 0)).setColor(16711680).setBiomeName("upperHell", "Übergang in die Hölle").setHumidity(0.0f);
|
||||
public static final Biome lowerHell = (new BiomeHell(44, 1)).setColor(16711680).setBiomeName("lowerHell", "Abgrund der Hölle").setHumidity(0.0f);
|
||||
public static final Biome hellHills = (new BiomeHell(45, 1)).setColor(16711680).setBiomeName("hellHills", "Bergland der Hölle").setHumidity(0.0f).setScaling(Scaling.HILLS_LARGE);
|
||||
public static final Biome soulPlains = (new BiomeHell(46, 1)).setColor(16711680).setBiomeName("soulPlains", "Seelenland").setHumidity(0.0f).setScaling(Scaling.SEA_POND);
|
||||
public static final Biome ashLand = (new BiomeHell(47, 2)).setColor(16711680).setBiomeName("ashLand", "Verbrannt").setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final Biome moon = (new BiomeMoon(48)).setColor(0xa0a0a0).setBiomeName("moon", "Mondoberfläche").setHumidity(0.0f).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final Biome chaos = (new BiomeChaos(49)).setColor(0xff00ff).setBiomeName("chaos", "Chaos").setHumidity(50.0f).setScaling(Scaling.VARYING_CHAOTIC);
|
||||
|
||||
public static final Biome DEF_BIOME = forest;
|
||||
protected static final PerlinGen TEMP_NOISE;
|
||||
protected static final PerlinGen TREE_NOISE;
|
||||
protected static final PerlinGen GRASS_NOISE;
|
||||
protected static final FeatureDoublePlant DOUBLE_PLANT_GEN;
|
||||
private static final Map<String, Biome> LOOKUP = Maps.newTreeMap();
|
||||
private static final List<Biome> LIST = Lists.newArrayList();
|
||||
|
||||
public final int id;
|
||||
|
||||
protected final WeightedList<RngSpawn> mobs = new WeightedList<RngSpawn>();
|
||||
protected final WorldGenBaseTree worldGeneratorTrees = new WorldGenBaseTree(false);
|
||||
protected final WorldGenBigTree worldGeneratorBigTree = new WorldGenBigTree(false);
|
||||
protected final WorldGenSwamp worldGeneratorSwamp = new WorldGenSwamp();
|
||||
private final FeatureGenerator clayGen = new WorldGenClay(4);
|
||||
private final FeatureGenerator sandGen = new WorldGenSand(Blocks.sand, 7);
|
||||
private final FeatureGenerator gravelAsSandGen = new WorldGenSand(Blocks.gravel, 6);
|
||||
private final WorldGenFlowers yellowFlowerGen = new WorldGenFlowers(Blocks.flower, BlockFlower.EnumFlowerType.DANDELION);
|
||||
private final FeatureGenerator mushroomBrownGen = new WorldGenMushroom(Blocks.brown_mushroom);
|
||||
private final FeatureGenerator mushroomRedGen = new WorldGenMushroom(Blocks.red_mushroom);
|
||||
private final FeatureGenerator bigMushroomGen = new WorldGenBigMushroom();
|
||||
private final FeatureGenerator reedGen = new WorldGenReed();
|
||||
private final FeatureGenerator cactusGen = new WorldGenCactus();
|
||||
private final FeatureGenerator waterlilyGen = new WorldGenWaterlily();
|
||||
private final FeatureGenerator clayGenExt = new WorldGenClayExt(32);
|
||||
|
||||
public String name = null;
|
||||
public String display = "<?>";
|
||||
public int color = 0x000000;
|
||||
public State topBlock = Blocks.grass.getState();
|
||||
public State fillerBlock = Blocks.dirt.getState();
|
||||
public float depth = Scaling.VARYING_LOW.depth;
|
||||
public float scale = Scaling.VARYING_LOW.scale;
|
||||
protected float temperature = 0.0f;
|
||||
protected float humidity = 50.0f;
|
||||
public int waterColor = 0xffffff;
|
||||
public boolean generateLakes = true;
|
||||
public boolean generateLiquids = true;
|
||||
public boolean allowColdBeach = false;
|
||||
public boolean disallowBeach = false;
|
||||
|
||||
protected int waterlilyPerChunk = 0;
|
||||
protected int treesPerChunk = 0;
|
||||
protected int flowersPerChunk = 2;
|
||||
protected int grassPerChunk = 1;
|
||||
protected int deadBushPerChunk = 0;
|
||||
protected int mushroomsPerChunk = 0;
|
||||
protected int reedsPerChunk = 0;
|
||||
protected int cactiPerChunk = 0;
|
||||
protected int sandPerChunk = 1;
|
||||
protected int sandPerChunk2 = 3;
|
||||
protected int clayPerChunk = 1;
|
||||
protected int clayExtPerChunk = 0; // 10
|
||||
protected int bigMushroomsPerChunk = 0;
|
||||
|
||||
protected Biome(int id) {
|
||||
this.id = id;
|
||||
BIOMES[id] = this;
|
||||
this.addMobs(this.mobs);
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntitySheep.class, 12, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityRabbit.class, 10, 3, 10));
|
||||
mobs.add(new RngSpawn(EntityPig.class, 10, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityChicken.class, 10, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityCow.class, 8, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityArachnoid.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityZombie.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityUndead.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityHaunter.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntitySlime.class, 100, 4, 4));
|
||||
// mobs.add(new Biome.RngSpawn(EntityEnder....class, 10, 1, 4));
|
||||
mobs.add(new RngSpawn(EntityMage.class, 5, 1, 1));
|
||||
mobs.add(new RngSpawn(EntitySquid.class, 10, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityBat.class, 10, 8, 8));
|
||||
mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8));
|
||||
}
|
||||
|
||||
public int getSkyColor() {
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
public int getFogColor() {
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
public int getCloudColor() {
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
public float getFactor() {
|
||||
float f = this.humidity * 0.01f * ((this.temperature + 14.0f) / 40.0f + 0.15f);
|
||||
return f > 1.0f ? 1.0f : f;
|
||||
}
|
||||
|
||||
// skycolor = ((temp + 14) / 40 + 0.15) / 3
|
||||
protected Biome setTemperature(float temp)
|
||||
{
|
||||
this.temperature = temp;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Biome setHumidity(float humidity)
|
||||
{
|
||||
this.humidity = humidity;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected final Biome setScaling(Scaling scaling)
|
||||
{
|
||||
return this.setScaling(scaling.depth, scaling.scale);
|
||||
}
|
||||
|
||||
protected final Biome setScaling(float depth, float scale)
|
||||
{
|
||||
this.depth = depth;
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return rand.chance(10) ? this.worldGeneratorBigTree : this.worldGeneratorTrees;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeLegacy(Random rand, BlockPos pos)
|
||||
{
|
||||
int noise = (int)((TREE_NOISE.generate((double)pos.getX() * 0.5D, (double)pos.getZ() * 0.5D) / 8D + rand.doublev() * 4D + 4D) / 3D);
|
||||
return (noise > 0 && rand.chance(noise)) || (this.isHighHumidity() && rand.chance(3)) ? this.worldGeneratorBigTree :
|
||||
this.worldGeneratorTrees;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a WorldGen appropriate for this biome.
|
||||
*/
|
||||
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
|
||||
{
|
||||
return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
return rand.rarity(3) ? BlockFlower.EnumFlowerType.DANDELION : BlockFlower.EnumFlowerType.ROSE;
|
||||
}
|
||||
|
||||
protected Biome enableColdBeach()
|
||||
{
|
||||
this.allowColdBeach = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Biome disableBeach()
|
||||
{
|
||||
this.disallowBeach = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Biome setBiomeName(String name, String display)
|
||||
{
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Biome setColor(int colorIn)
|
||||
{
|
||||
this.color = colorIn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedList<RngSpawn> getMobs()
|
||||
{
|
||||
return this.mobs;
|
||||
}
|
||||
|
||||
public boolean isHighHumidity()
|
||||
{
|
||||
return this.humidity > 85.0f;
|
||||
}
|
||||
|
||||
public float getMobGenChance()
|
||||
{
|
||||
return 0.1F;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.temperature;
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(WorldServer world, Random rand, BlockPos pos)
|
||||
{
|
||||
for (int i = 0; i < this.sandPerChunk2; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
this.sandGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(j, 0, k)));
|
||||
}
|
||||
|
||||
for (int i1 = 0; i1 < this.clayPerChunk; ++i1)
|
||||
{
|
||||
int l1 = rand.chOffset();
|
||||
int i6 = rand.chOffset();
|
||||
this.clayGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(l1, 0, i6)));
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < this.sandPerChunk; ++j1)
|
||||
{
|
||||
int i2 = rand.chOffset();
|
||||
int j6 = rand.chOffset();
|
||||
this.gravelAsSandGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(i2, 0, j6)));
|
||||
}
|
||||
|
||||
for (int i1 = 0; i1 < this.clayExtPerChunk; ++i1)
|
||||
{
|
||||
int l1 = rand.chOffset();
|
||||
int i6 = rand.chOffset();
|
||||
this.clayGenExt.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(l1, 0, i6)));
|
||||
}
|
||||
|
||||
int k1 = this.treesPerChunk;
|
||||
|
||||
if (rand.chance(10))
|
||||
{
|
||||
++k1;
|
||||
}
|
||||
|
||||
for (int j2 = 0; j2 < k1; ++j2)
|
||||
{
|
||||
int k6 = rand.chOffset();
|
||||
int l = rand.chOffset();
|
||||
WorldGenTree treeGen = this.genBigTreeChance(rand);
|
||||
treeGen.prepare();
|
||||
BlockPos blockpos = world.getHeight(pos.add(k6, 0, l));
|
||||
|
||||
if (treeGen.generate(world, rand, blockpos))
|
||||
{
|
||||
treeGen.finish(world, rand, blockpos);
|
||||
}
|
||||
}
|
||||
|
||||
for (int k2 = 0; k2 < this.bigMushroomsPerChunk; ++k2)
|
||||
{
|
||||
int l6 = rand.chOffset();
|
||||
int k10 = rand.chOffset();
|
||||
this.bigMushroomGen.generate(world, rand, world.getHeight(pos.add(l6, 0, k10)));
|
||||
}
|
||||
|
||||
for (int l2 = 0; l2 < this.flowersPerChunk; ++l2)
|
||||
{
|
||||
int i7 = rand.chOffset();
|
||||
int l10 = rand.chOffset();
|
||||
int j14 = world.getHeight(pos.add(i7, 0, l10)).getY() + 32;
|
||||
|
||||
if (j14 > 0)
|
||||
{
|
||||
int k17 = rand.zrange(j14);
|
||||
BlockPos blockpos1 = pos.add(i7, k17, l10);
|
||||
BlockFlower.EnumFlowerType blockflower$enumflowertype = this.pickRandomFlower(rand, blockpos1);
|
||||
BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock();
|
||||
|
||||
if (blockflower.getMaterial() != Material.air)
|
||||
{
|
||||
this.yellowFlowerGen.setGeneratedBlock(blockflower, blockflower$enumflowertype);
|
||||
this.yellowFlowerGen.generate(world, rand, blockpos1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i3 = 0; i3 < this.grassPerChunk; ++i3)
|
||||
{
|
||||
int j7 = rand.chOffset();
|
||||
int i11 = rand.chOffset();
|
||||
int k14 = world.getHeight(pos.add(j7, 0, i11)).getY() * 2;
|
||||
|
||||
if (k14 > 0)
|
||||
{
|
||||
int l17 = rand.zrange(k14);
|
||||
this.getRandomWorldGenForGrass(rand).generate(world, rand, pos.add(j7, l17, i11));
|
||||
}
|
||||
}
|
||||
|
||||
for (int j3 = 0; j3 < this.deadBushPerChunk; ++j3)
|
||||
{
|
||||
int k7 = rand.chOffset();
|
||||
int j11 = rand.chOffset();
|
||||
int l14 = world.getHeight(pos.add(k7, 0, j11)).getY() * 2;
|
||||
|
||||
if (l14 > 0)
|
||||
{
|
||||
int i18 = rand.zrange(l14);
|
||||
(new WorldGenDeadBush()).generate(world, rand, pos.add(k7, i18, j11));
|
||||
}
|
||||
}
|
||||
|
||||
for (int k3 = 0; k3 < this.waterlilyPerChunk; ++k3)
|
||||
{
|
||||
int l7 = rand.chOffset();
|
||||
int k11 = rand.chOffset();
|
||||
int i15 = world.getHeight(pos.add(l7, 0, k11)).getY() * 2;
|
||||
|
||||
if (i15 > 0)
|
||||
{
|
||||
int j18 = rand.zrange(i15);
|
||||
BlockPos blockpos4;
|
||||
BlockPos blockpos7;
|
||||
|
||||
for (blockpos4 = pos.add(l7, j18, k11); blockpos4.getY() > 0; blockpos4 = blockpos7)
|
||||
{
|
||||
blockpos7 = blockpos4.down();
|
||||
|
||||
if (!world.isAirBlock(blockpos7))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.waterlilyGen.generate(world, rand, blockpos4);
|
||||
}
|
||||
}
|
||||
|
||||
for (int l3 = 0; l3 < this.mushroomsPerChunk; ++l3)
|
||||
{
|
||||
if (rand.chance(4))
|
||||
{
|
||||
int i8 = rand.chOffset();
|
||||
int l11 = rand.chOffset();
|
||||
BlockPos blockpos2 = world.getHeight(pos.add(i8, 0, l11));
|
||||
this.mushroomBrownGen.generate(world, rand, blockpos2);
|
||||
}
|
||||
|
||||
if (rand.chance(8))
|
||||
{
|
||||
int j8 = rand.chOffset();
|
||||
int i12 = rand.chOffset();
|
||||
int j15 = world.getHeight(pos.add(j8, 0, i12)).getY() * 2;
|
||||
|
||||
if (j15 > 0)
|
||||
{
|
||||
int k18 = rand.zrange(j15);
|
||||
BlockPos blockpos5 = pos.add(j8, k18, i12);
|
||||
this.mushroomRedGen.generate(world, rand, blockpos5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.mushroomsPerChunk != -1 && rand.chance(4))
|
||||
{
|
||||
int i4 = rand.chOffset();
|
||||
int k8 = rand.chOffset();
|
||||
int j12 = world.getHeight(pos.add(i4, 0, k8)).getY() * 2;
|
||||
|
||||
if (j12 > 0)
|
||||
{
|
||||
int k15 = rand.zrange(j12);
|
||||
this.mushroomBrownGen.generate(world, rand, pos.add(i4, k15, k8));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.mushroomsPerChunk != -1 && rand.chance(8))
|
||||
{
|
||||
int j4 = rand.chOffset();
|
||||
int l8 = rand.chOffset();
|
||||
int k12 = world.getHeight(pos.add(j4, 0, l8)).getY() * 2;
|
||||
|
||||
if (k12 > 0)
|
||||
{
|
||||
int l15 = rand.zrange(k12);
|
||||
this.mushroomRedGen.generate(world, rand, pos.add(j4, l15, l8));
|
||||
}
|
||||
}
|
||||
|
||||
for (int k4 = 0; k4 < this.reedsPerChunk; ++k4)
|
||||
{
|
||||
int i9 = rand.chOffset();
|
||||
int l12 = rand.chOffset();
|
||||
int i16 = world.getHeight(pos.add(i9, 0, l12)).getY() * 2;
|
||||
|
||||
if (i16 > 0)
|
||||
{
|
||||
int l18 = rand.zrange(i16);
|
||||
this.reedGen.generate(world, rand, pos.add(i9, l18, l12));
|
||||
}
|
||||
}
|
||||
|
||||
for (int l4 = 0; l4 < 10; ++l4)
|
||||
{
|
||||
int j9 = rand.chOffset();
|
||||
int i13 = rand.chOffset();
|
||||
int j16 = world.getHeight(pos.add(j9, 0, i13)).getY() * 2;
|
||||
|
||||
if (j16 > 0)
|
||||
{
|
||||
int i19 = rand.zrange(j16);
|
||||
this.reedGen.generate(world, rand, pos.add(j9, i19, i13));
|
||||
}
|
||||
}
|
||||
|
||||
if (rand.chance(32))
|
||||
{
|
||||
int i5 = rand.chOffset();
|
||||
int k9 = rand.chOffset();
|
||||
int j13 = world.getHeight(pos.add(i5, 0, k9)).getY() * 2;
|
||||
|
||||
if (j13 > 0)
|
||||
{
|
||||
int k16 = rand.zrange(j13);
|
||||
(new WorldGenPumpkin()).generate(world, rand, pos.add(i5, k16, k9));
|
||||
}
|
||||
}
|
||||
|
||||
for (int j5 = 0; j5 < this.cactiPerChunk; ++j5)
|
||||
{
|
||||
int l9 = rand.chOffset();
|
||||
int k13 = rand.chOffset();
|
||||
int l16 = world.getHeight(pos.add(l9, 0, k13)).getY() * 2;
|
||||
|
||||
if (l16 > 0)
|
||||
{
|
||||
int j19 = rand.zrange(l16);
|
||||
this.cactusGen.generate(world, rand, pos.add(l9, j19, k13));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getGrassColorAtPos(BlockPos pos)
|
||||
{
|
||||
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.getGrassColor(d0, d1);
|
||||
}
|
||||
|
||||
public int getFoliageColorAtPos(BlockPos pos)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given x, z coordinates, we count down all the y positions starting at height - 1 and working our way down. When we hit a
|
||||
* non-air block, we replace it with this.topBlock (default grass, descendants may set otherwise), and then a
|
||||
* relatively shallow layer of blocks of type this.fillerBlock (default dirt). A random set of blocks below y == 5
|
||||
* (but always including y == 0) is replaced with bedrock in Chunk(...).
|
||||
*
|
||||
* If we don't hit non-air until somewhat below sea level, we top with gravel and fill down with stone.
|
||||
*
|
||||
* If this.fillerBlock is red sand, we replace some of that with red sandstone.
|
||||
*/
|
||||
public final void generateBiomeTerrain(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
int i = worldIn.getSeaLevel();
|
||||
State worldState = worldIn.dimension.getFiller();
|
||||
Block worldBlock = worldState.getBlock();
|
||||
State worldAlt = worldIn.dimension.getAltFiller1();
|
||||
State liquid = worldIn.getSurfaceLiquid();
|
||||
boolean freeze = liquid.getBlock().getMaterial() == Material.water;
|
||||
State iblockstate = this.topBlock;
|
||||
State iblockstate1 = this.fillerBlock;
|
||||
int j = -1;
|
||||
int k = (int)(noiseVal / 3.0D + 3.0D + rand.doublev() * 0.25D);
|
||||
int l = x & 15;
|
||||
int i1 = z & 15;
|
||||
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (int j1 = chunkPrimerIn.height - 1; j1 >= 0; --j1)
|
||||
{
|
||||
State iblockstate2 = chunkPrimerIn.get(i1, j1, l);
|
||||
|
||||
if (iblockstate2.getBlock().getMaterial() == Material.air)
|
||||
{
|
||||
j = -1;
|
||||
}
|
||||
else if (iblockstate2.getBlock() == worldBlock)
|
||||
{
|
||||
if (j == -1)
|
||||
{
|
||||
if (k <= 0)
|
||||
{
|
||||
iblockstate = null;
|
||||
iblockstate1 = worldState;
|
||||
}
|
||||
else if (j1 >= i - 4 && j1 <= i + 1)
|
||||
{
|
||||
iblockstate = this.topBlock;
|
||||
iblockstate1 = this.fillerBlock;
|
||||
}
|
||||
|
||||
if (j1 < i && (iblockstate == null || iblockstate.getBlock().getMaterial() == Material.air))
|
||||
{
|
||||
if (freeze && World.ABSOLUTE_ZERO + worldIn.getTempOffset() + this.getTemperature(blockpos$mutableblockpos.set(x, j1, z)) <= 0.0F)
|
||||
{
|
||||
iblockstate = Blocks.ice.getState();
|
||||
}
|
||||
else
|
||||
{
|
||||
iblockstate = liquid;
|
||||
}
|
||||
}
|
||||
|
||||
j = k;
|
||||
|
||||
if (j1 >= i - 1)
|
||||
{
|
||||
chunkPrimerIn.set(i1, j1, l, iblockstate);
|
||||
}
|
||||
else if (j1 < i - 7 - k)
|
||||
{
|
||||
iblockstate = null;
|
||||
iblockstate1 = worldState;
|
||||
chunkPrimerIn.set(i1, j1, l, worldAlt);
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkPrimerIn.set(i1, j1, l, iblockstate1);
|
||||
}
|
||||
}
|
||||
else if (j > 0)
|
||||
{
|
||||
--j;
|
||||
chunkPrimerIn.set(i1, j1, l, iblockstate1);
|
||||
|
||||
if (j == 0 && iblockstate1.getBlock() == Blocks.sand)
|
||||
{
|
||||
j = rand.zrange(4) + Math.max(0, j1 - 63);
|
||||
iblockstate1 = iblockstate1.getValue(BlockSand.VARIANT) == BlockSand.EnumType.RED_SAND ? Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE) : Blocks.sandstone.getState(); //TODO: check!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Biome createMutation()
|
||||
{
|
||||
return this.createMutatedBiome(this.id + 128);
|
||||
}
|
||||
|
||||
protected Biome createMutatedBiome(int p_180277_1_)
|
||||
{
|
||||
return new BiomeMutated(p_180277_1_, this);
|
||||
}
|
||||
|
||||
public Class <? extends Biome > getBiomeClass()
|
||||
{
|
||||
return this.getClass();
|
||||
}
|
||||
|
||||
public boolean isEqualTo(Biome biome)
|
||||
{
|
||||
return biome == this ? true : (biome == null ? false : this.getBiomeClass() == biome.getBiomeClass());
|
||||
}
|
||||
|
||||
public Temperature getTempCategory()
|
||||
{
|
||||
return this.temperature < -12.0f ? Temperature.COLD : (this.temperature < 20.0f ? Temperature.MEDIUM : Temperature.WARM);
|
||||
}
|
||||
|
||||
public static Biome getBiome(int id)
|
||||
{
|
||||
return getBiome(id, null);
|
||||
}
|
||||
|
||||
public static Biome getBiome(int id, Biome def)
|
||||
{
|
||||
if (id >= 0 && id < BIOMES.length)
|
||||
{
|
||||
Biome biome = BIOMES[id];
|
||||
return biome == null ? def : biome;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.JNI.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + DEF_BIOME.id + " (" + DEF_BIOME.name + ")");
|
||||
return DEF_BIOME;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Biome> getBiomes() {
|
||||
return LIST;
|
||||
}
|
||||
|
||||
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 null;
|
||||
}
|
||||
return z < 0 || z >= BIOMES.length ? null : BIOMES[z];
|
||||
}
|
||||
return biome;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
// plains.createMutation();
|
||||
desert.createMutation();
|
||||
forest.createMutation();
|
||||
taiga.createMutation();
|
||||
swampland.createMutation();
|
||||
icePlains.createMutation();
|
||||
jungle.createMutation();
|
||||
jungleEdge.createMutation();
|
||||
coldTaiga.createMutation();
|
||||
savanna.createMutation();
|
||||
savannaPlateau.createMutation();
|
||||
mesa.createMutation();
|
||||
mesaPlateau_F.createMutation();
|
||||
mesaPlateau.createMutation();
|
||||
birchForest.createMutation();
|
||||
birchForestHills.createMutation();
|
||||
roofedForest.createMutation();
|
||||
megaTaiga.createMutation();
|
||||
extremeHills.createMutation();
|
||||
extremeHillsPlus.createMutation();
|
||||
megaTaiga.createMutatedBiome(megaTaigaHills.id + 128).setBiomeName("redwoodTaigaHillsM", "Mammutbaumtaiga");
|
||||
|
||||
TEMP_NOISE = new PerlinGen(new Random(1234L), 1);
|
||||
TREE_NOISE = new PerlinGen(new Random(667L), 8);
|
||||
GRASS_NOISE = new PerlinGen(new Random(2345L), 1);
|
||||
DOUBLE_PLANT_GEN = new FeatureDoublePlant();
|
||||
|
||||
for(Biome biome : BIOMES) {
|
||||
if(biome == null)
|
||||
continue;
|
||||
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);
|
||||
LIST.add(biome);
|
||||
}
|
||||
}
|
||||
}
|
21
common/src/common/biome/BiomeBeach.java
Executable file
21
common/src/common/biome/BiomeBeach.java
Executable file
|
@ -0,0 +1,21 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeBeach extends Biome
|
||||
{
|
||||
public BiomeBeach(int id)
|
||||
{
|
||||
super(id);
|
||||
this.topBlock = Blocks.sand.getState();
|
||||
this.fillerBlock = Blocks.sand.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 0;
|
||||
this.reedsPerChunk = 0;
|
||||
this.cactiPerChunk = 0;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
}
|
34
common/src/common/biome/BiomeBlackened.java
Normal file
34
common/src/common/biome/BiomeBlackened.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockFlower;
|
||||
import common.entity.npc.EntityMetalhead;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.worldgen.tree.WorldGenBaseTree;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeBlackened extends Biome {
|
||||
protected final WorldGenTree treeGen = new WorldGenBaseTree(false, Blocks.blackwood_log.getState(), Blocks.blackwood_leaves.getState());
|
||||
|
||||
public BiomeBlackened(int id) {
|
||||
super(id);
|
||||
this.topBlock = Blocks.blackened_soil.getState();
|
||||
this.fillerBlock = Blocks.blackened_dirt.getState();
|
||||
this.treesPerChunk = 3;
|
||||
this.generateLakes = false;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntityMetalhead.class, 50, 1, 1));
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos) {
|
||||
return BlockFlower.EnumFlowerType.BLACK_LOTUS;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand) {
|
||||
return this.treeGen;
|
||||
}
|
||||
}
|
44
common/src/common/biome/BiomeChaos.java
Executable file
44
common/src/common/biome/BiomeChaos.java
Executable file
|
@ -0,0 +1,44 @@
|
|||
package common.biome;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Blocks;
|
||||
import common.init.EntityRegistry;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.FeatureGenerator;
|
||||
import common.worldgen.foliage.WorldGenMushroom;
|
||||
|
||||
public class BiomeChaos extends Biome
|
||||
{
|
||||
protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom);
|
||||
|
||||
public BiomeChaos(int id)
|
||||
{
|
||||
super(id);
|
||||
this.topBlock = Blocks.obsidian.getState();
|
||||
this.fillerBlock = Blocks.obsidian.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
for(Class<? extends Entity> clazz : EntityRegistry.getAllClasses()) {
|
||||
if(EntityLiving.class.isAssignableFrom(clazz))
|
||||
mobs.add(new RngSpawn((Class<? extends EntityLiving>)clazz, 1, 1, 8));
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
|
||||
if (rand.chance(10))
|
||||
{
|
||||
int i8 = rand.chOffset();
|
||||
int l11 = rand.chOffset();
|
||||
BlockPos blockpos2 = worldIn.getHeight(pos.add(i8, 0, l11));
|
||||
this.mushroomBlueGen.generate(worldIn, rand, blockpos2);
|
||||
}
|
||||
}
|
||||
}
|
39
common/src/common/biome/BiomeDesert.java
Executable file
39
common/src/common/biome/BiomeDesert.java
Executable file
|
@ -0,0 +1,39 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.feature.WorldGenDesertWells;
|
||||
|
||||
public class BiomeDesert extends Biome
|
||||
{
|
||||
public BiomeDesert(int id)
|
||||
{
|
||||
super(id);
|
||||
this.topBlock = Blocks.sand.getState();
|
||||
this.fillerBlock = Blocks.sand.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 2;
|
||||
this.reedsPerChunk = 50;
|
||||
this.cactiPerChunk = 10;
|
||||
this.generateLakes = false;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
|
||||
if (rand.chance(1000))
|
||||
{
|
||||
int i = rand.chOffset();
|
||||
int j = rand.chOffset();
|
||||
BlockPos blockpos = worldIn.getHeight(pos.add(i, 0, j)).up();
|
||||
(new WorldGenDesertWells()).generate(worldIn, rand, blockpos);
|
||||
}
|
||||
}
|
||||
}
|
33
common/src/common/biome/BiomeExterminated.java
Executable file
33
common/src/common/biome/BiomeExterminated.java
Executable file
|
@ -0,0 +1,33 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public class BiomeExterminated extends Biome {
|
||||
public BiomeExterminated(int id) {
|
||||
super(id);
|
||||
this.topBlock = Blocks.air.getState();
|
||||
this.fillerBlock = Blocks.air.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
|
||||
}
|
||||
|
||||
public int getSkyColor() {
|
||||
return 0x101010;
|
||||
}
|
||||
|
||||
public int getFogColor() {
|
||||
return 0x303030;
|
||||
}
|
||||
|
||||
public int getCloudColor() {
|
||||
return 0x000000;
|
||||
}
|
||||
}
|
245
common/src/common/biome/BiomeForest.java
Executable file
245
common/src/common/biome/BiomeForest.java
Executable file
|
@ -0,0 +1,245 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockDoublePlant;
|
||||
import common.block.BlockFlower;
|
||||
import common.color.Colorizer;
|
||||
import common.entity.animal.EntityWolf;
|
||||
import common.entity.npc.EntityElf;
|
||||
import common.entity.npc.EntityWoodElf;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.util.ExtMath;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.foliage.WorldGenBigMushroom;
|
||||
import common.worldgen.tree.WorldGenBaseTree;
|
||||
import common.worldgen.tree.WorldGenBigTree;
|
||||
import common.worldgen.tree.WorldGenBirch;
|
||||
import common.worldgen.tree.WorldGenDarkOak;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeForest extends Biome
|
||||
{
|
||||
private static final BlockDoublePlant.EnumPlantType[] FLOWER_TYPES = new BlockDoublePlant.EnumPlantType[] {
|
||||
BlockDoublePlant.EnumPlantType.SYRINGA, BlockDoublePlant.EnumPlantType.ROSE, BlockDoublePlant.EnumPlantType.PAEONIA
|
||||
};
|
||||
protected static final WorldGenBirch tallBirch = new WorldGenBirch(false, true);
|
||||
protected static final WorldGenBirch normalBirch = new WorldGenBirch(false, false);
|
||||
protected static final WorldGenDarkOak darkOak = new WorldGenDarkOak(false);
|
||||
|
||||
private final int subType;
|
||||
// protected LeavesType leavesType = null;
|
||||
// protected WorldGenBaseTree cherry;
|
||||
// protected WorldGenBaseTree maple;
|
||||
// protected WorldGenBigTree cherryBig;
|
||||
// protected WorldGenBigTree mapleBig;
|
||||
protected WorldGenBaseTree cherry = new WorldGenBaseTree(false, Blocks.cherry_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
Blocks.cherry_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
protected WorldGenBaseTree maple = new WorldGenBaseTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
protected WorldGenBigTree cherryBig = new WorldGenBigTree(false, Blocks.cherry_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
Blocks.cherry_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
protected WorldGenBigTree mapleBig = new WorldGenBigTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
|
||||
public BiomeForest(int id, int type)
|
||||
{
|
||||
super(id);
|
||||
this.subType = type;
|
||||
this.treesPerChunk = 10;
|
||||
this.grassPerChunk = 2;
|
||||
|
||||
if (this.subType == 1)
|
||||
{
|
||||
this.treesPerChunk = 6;
|
||||
this.flowersPerChunk = 100;
|
||||
this.grassPerChunk = 1;
|
||||
}
|
||||
|
||||
if (this.subType == 4)
|
||||
{
|
||||
this.treesPerChunk = 20;
|
||||
this.flowersPerChunk = 20;
|
||||
this.grassPerChunk = 1;
|
||||
this.reedsPerChunk = 50;
|
||||
this.waterlilyPerChunk = 4;
|
||||
}
|
||||
|
||||
this.setTemperature(8.0f).setHumidity(80.0f);
|
||||
|
||||
if (this.subType == 2)
|
||||
{
|
||||
this.setColor(3175492);
|
||||
this.setTemperature(4.0f).setHumidity(60.0f);
|
||||
}
|
||||
|
||||
if (this.subType == 0)
|
||||
{
|
||||
this.mobs.add(new RngSpawn(EntityWolf.class, 5, 4, 4));
|
||||
}
|
||||
|
||||
if (this.subType == 3)
|
||||
{
|
||||
this.treesPerChunk = -999;
|
||||
}
|
||||
|
||||
if(this.subType != 4) {
|
||||
this.mobs.add(new RngSpawn(EntityWoodElf.class, 3, 2, 6));
|
||||
}
|
||||
else {
|
||||
this.mobs.add(new RngSpawn(EntityWoodElf.class, 100, 4, 16));
|
||||
this.mobs.add(new RngSpawn(EntityElf.class, 12, 4, 16));
|
||||
}
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)
|
||||
(this.subType == 3 && rand.rarity(3) ? darkOak :
|
||||
(this.subType != 2 && rand.rarity(5) ? (this.subType != 3 && this.subType != 4 && rand.chance(this.subType == 1 ? 2 : 30) ? (rand.chance(25) ? this.cherryBig : this.cherry) :
|
||||
this.subType == 4 && rand.chance(42) ? this.worldGeneratorBigTree : this.worldGeneratorTrees) :
|
||||
(this.subType == 4 || rand.chance(this.subType == 2 ? 30 : 2) ? (rand.chance(this.subType == 4 ? 32 : 5) ? this.mapleBig : this.maple) : normalBirch)));
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
if (this.subType == 1)
|
||||
{
|
||||
double d0 = ExtMath.clampd((1.0D + GRASS_NOISE.generate((double)pos.getX() / 48.0D, (double)pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D);
|
||||
BlockFlower.EnumFlowerType blockflower$enumflowertype = BlockFlower.EnumFlowerType.values()[(int)(d0 * (double)BlockFlower.EnumFlowerType.values().length)];
|
||||
return blockflower$enumflowertype == BlockFlower.EnumFlowerType.BLUE_ORCHID ? BlockFlower.EnumFlowerType.ROSE : blockflower$enumflowertype;
|
||||
}
|
||||
else if (this.subType == 4)
|
||||
{
|
||||
double d0 = ExtMath.clampd((1.0D + GRASS_NOISE.generate((double)pos.getX() / 48.0D, (double)pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D);
|
||||
return BlockFlower.EnumFlowerType.values()[(int)(d0 * (double)BlockFlower.EnumFlowerType.values().length)];
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.pickRandomFlower(rand, pos);
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
// if(worldIn.getLeavesGen() != this.leavesType) {
|
||||
// this.leavesType = worldIn.getLeavesGen();
|
||||
// this.cherry = new WorldGenBaseTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
// Blocks.cherry_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// this.maple = new WorldGenBaseTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
// Blocks.maple_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// this.cherryBig = new WorldGenBigTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
// Blocks.cherry_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// this.mapleBig = new WorldGenBigTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
// Blocks.maple_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// }
|
||||
|
||||
if (this.subType == 3)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
int k = i * 4 + rand.range(9, 11);
|
||||
int l = j * 4 + rand.range(9, 11);
|
||||
BlockPos blockpos = worldIn.getHeight(pos.add(k, 0, l));
|
||||
|
||||
if (rand.chance(20))
|
||||
{
|
||||
WorldGenBigMushroom worldgenbigmushroom = new WorldGenBigMushroom();
|
||||
worldgenbigmushroom.generate(worldIn, rand, blockpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldGenTree worldgenabstracttree = this.genBigTreeChance(rand);
|
||||
worldgenabstracttree.prepare();
|
||||
|
||||
if (worldgenabstracttree.generate(worldIn, rand, blockpos))
|
||||
{
|
||||
worldgenabstracttree.finish(worldIn, rand, blockpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int j1 = rand.range(-3, 1);
|
||||
|
||||
if (this.subType == 1)
|
||||
{
|
||||
j1 += 2;
|
||||
}
|
||||
|
||||
for (int k1 = 0; k1 < j1; ++k1)
|
||||
{
|
||||
// int l1 = rand.nextInt(3);
|
||||
|
||||
// if (l1 == 0)
|
||||
// {
|
||||
DOUBLE_PLANT_GEN.setPlantType(rand.pick(FLOWER_TYPES));
|
||||
// }
|
||||
// else if (l1 == 1)
|
||||
// {
|
||||
// DOUBLE_PLANT_GENERATOR.setPlantType();
|
||||
// }
|
||||
// else if (l1 == 2)
|
||||
// {
|
||||
// DOUBLE_PLANT_GENERATOR.setPlantType();
|
||||
// }
|
||||
|
||||
for (int i2 = 0; i2 < 5; ++i2)
|
||||
{
|
||||
int j2 = rand.chOffset();
|
||||
int k2 = rand.chOffset();
|
||||
int i1 = rand.zrange(worldIn.getHeight(pos.add(j2, 0, k2)).getY() + 32);
|
||||
|
||||
if (DOUBLE_PLANT_GEN.generate(worldIn, rand, new BlockPos(pos.getX() + j2, i1, pos.getZ() + k2)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public int getGrassColorAtPos(BlockPos pos)
|
||||
{
|
||||
return this.subType == 4 ? Colorizer.getGrassColor(1.0f, this.humidity * 0.01f) :
|
||||
(this.subType == 3 ? (super.getGrassColorAtPos(pos) & 16711422) + 2634762 >> 1 :
|
||||
super.getGrassColorAtPos(pos));
|
||||
}
|
||||
|
||||
public int getFoliageColorAtPos(BlockPos pos)
|
||||
{
|
||||
return this.subType == 4 ? Colorizer.getFoliageColor(1.0f, this.humidity * 0.01f) : super.getFoliageColorAtPos(pos);
|
||||
}
|
||||
|
||||
protected Biome createMutatedBiome(final int id)
|
||||
{
|
||||
if (this.id == Biome.forest.id)
|
||||
{
|
||||
BiomeForest biomegenforest = new BiomeForest(id, 1);
|
||||
biomegenforest.setScaling(this.depth, this.scale + 0.2F);
|
||||
biomegenforest.setBiomeName("flowerForest", "Blumenwald");
|
||||
biomegenforest.setColor(6976549);
|
||||
return biomegenforest;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.id != Biome.birchForest.id && this.id != Biome.birchForestHills.id ? new BiomeMutated(id, this)
|
||||
{
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
this.baseBiome.decorate(worldIn, rand, pos);
|
||||
}
|
||||
}: new BiomeMutated(id, this)
|
||||
{
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return rand.chance() ? BiomeForest.tallBirch : BiomeForest.normalBirch;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
138
common/src/common/biome/BiomeHell.java
Executable file
138
common/src/common/biome/BiomeHell.java
Executable file
|
@ -0,0 +1,138 @@
|
|||
package common.biome;
|
||||
|
||||
import common.entity.npc.EntityBloodElf;
|
||||
import common.entity.npc.EntityCultivator;
|
||||
import common.entity.npc.EntityFireDemon;
|
||||
import common.entity.npc.EntityMagma;
|
||||
import common.entity.npc.EntityMetalhead;
|
||||
import common.entity.npc.EntityTiefling;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.FeatureOres;
|
||||
import common.worldgen.feature.WorldGenFire;
|
||||
import common.worldgen.feature.WorldGenGlowStone;
|
||||
import common.worldgen.feature.WorldGenHellLava;
|
||||
import common.worldgen.foliage.WorldGenMushroom;
|
||||
|
||||
public class BiomeHell extends Biome
|
||||
{
|
||||
private final int subtype;
|
||||
private final WorldGenFire fireGen;
|
||||
private final WorldGenGlowStone glowStoneGen1;
|
||||
private final WorldGenGlowStone glowStoneGen2;
|
||||
private final FeatureOres quartzGen;
|
||||
private final WorldGenHellLava lavaGen1;
|
||||
private final WorldGenHellLava lavaGen2;
|
||||
private final WorldGenMushroom brownMushroomGen;
|
||||
private final WorldGenMushroom redMushroomGen;
|
||||
|
||||
public BiomeHell(int id, int subtype)
|
||||
{
|
||||
super(id);
|
||||
this.subtype = subtype;
|
||||
if(this.subtype == 0) {
|
||||
this.mobs.add(new RngSpawn(EntityBloodElf.class, 10, 1, 2));
|
||||
this.mobs.add(new RngSpawn(EntityMetalhead.class, 1, 1, 1));
|
||||
this.fireGen = new WorldGenFire();
|
||||
this.glowStoneGen1 = new WorldGenGlowStone();
|
||||
this.glowStoneGen2 = new WorldGenGlowStone();
|
||||
this.quartzGen = new FeatureOres(Blocks.quartz_ore.getState(), 16, 0, 14, 10, 118, false);
|
||||
this.lavaGen1 = new WorldGenHellLava(Blocks.flowing_lava, true);
|
||||
this.lavaGen2 = new WorldGenHellLava(Blocks.flowing_lava, false);
|
||||
this.brownMushroomGen = new WorldGenMushroom(Blocks.brown_mushroom);
|
||||
this.redMushroomGen = new WorldGenMushroom(Blocks.red_mushroom);
|
||||
}
|
||||
else {
|
||||
this.mobs.add(new RngSpawn(EntityBloodElf.class, 50, 2, 10));
|
||||
this.mobs.add(new RngSpawn(EntityCultivator.class, 10, 1, 1));
|
||||
this.fireGen = null;
|
||||
this.glowStoneGen1 = null;
|
||||
this.glowStoneGen2 = null;
|
||||
this.quartzGen = null;
|
||||
this.lavaGen1 = null;
|
||||
this.lavaGen2 = null;
|
||||
this.brownMushroomGen = null;
|
||||
this.redMushroomGen = null;
|
||||
}
|
||||
if(this.subtype == 2) {
|
||||
this.topBlock = Blocks.ash.getState();
|
||||
this.fillerBlock = Blocks.rock.getState();
|
||||
}
|
||||
else {
|
||||
this.topBlock = Blocks.hellrock.getState();
|
||||
this.fillerBlock = Blocks.hellrock.getState();
|
||||
}
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntityFireDemon.class, 50, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityTiefling.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityMagma.class, 1, 4, 4));
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if(this.subtype == 0) {
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
this.lavaGen2.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
for (int j = 0; j < rand.zrange(rand.zrange(10) + 1) + 1; ++j)
|
||||
{
|
||||
this.fireGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
for (int k = 0; k < rand.zrange(rand.zrange(10) + 1); ++k)
|
||||
{
|
||||
this.glowStoneGen1.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
for (int l = 0; l < 10; ++l)
|
||||
{
|
||||
this.glowStoneGen2.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
if (rand.chance())
|
||||
{
|
||||
this.brownMushroomGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
if (rand.chance())
|
||||
{
|
||||
this.redMushroomGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
// for (int i1 = 0; i1 < 16; ++i1)
|
||||
// {
|
||||
this.quartzGen.generate(worldIn, rand, pos); // .add(rand.nextInt(16), rand.nextInt(108) + 10, rand.nextInt(16)));
|
||||
// }
|
||||
|
||||
for (int j1 = 0; j1 < 16; ++j1)
|
||||
{
|
||||
this.lavaGen1.generate(worldIn, rand, pos.add(rand.zrange(16), rand.zrange(108) + 10, rand.zrange(16)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
}
|
||||
|
||||
// protected Decorator createBiomeDecorator()
|
||||
// {
|
||||
// return this.subtype == 0 ? new DecoratorHell() : super.createBiomeDecorator();
|
||||
// }
|
||||
|
||||
public int getGrassColorAtPos(BlockPos pos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getFoliageColorAtPos(BlockPos pos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
104
common/src/common/biome/BiomeHills.java
Executable file
104
common/src/common/biome/BiomeHills.java
Executable file
|
@ -0,0 +1,104 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
import common.worldgen.FeatureOres;
|
||||
import common.worldgen.tree.WorldGenTaiga2;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeHills extends Biome
|
||||
{
|
||||
// private FeatureGenerator theWorldGenerator = new FeatureOres(Blocks.monster_egg.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONE), false, 7, 9, 0, 64);
|
||||
private FeatureOres theEmeraldGenerator = new FeatureOres(Blocks.emerald_ore.getState(), 3, 5, 1, 4, 32, false);
|
||||
private WorldGenTaiga2 field_150634_aD = new WorldGenTaiga2(false);
|
||||
private int field_150635_aE = 0;
|
||||
private int field_150636_aF = 1;
|
||||
private int field_150637_aG = 2;
|
||||
private int field_150638_aH;
|
||||
|
||||
protected BiomeHills(int id, boolean p_i45373_2_)
|
||||
{
|
||||
super(id);
|
||||
this.field_150638_aH = this.field_150635_aE;
|
||||
|
||||
if (p_i45373_2_)
|
||||
{
|
||||
this.treesPerChunk = 3;
|
||||
this.field_150638_aH = this.field_150636_aF;
|
||||
}
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)(rand.rarity(3) ? this.field_150634_aD : super.genBigTreeChance(rand));
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
// int i = 3 + rand.nextInt(6);
|
||||
//
|
||||
// for (int j = 0; j < i; ++j)
|
||||
// {
|
||||
// int k = rand.nextInt(16);
|
||||
// int l = rand.nextInt(28) + 4;
|
||||
// int i1 = rand.nextInt(16);
|
||||
// BlockPos blockpos = pos.add(k, l, i1);
|
||||
//
|
||||
// if (worldIn.getBlockState(blockpos).getBlock() == Blocks.stone)
|
||||
// {
|
||||
// worldIn.setBlockState(blockpos, Blocks.emerald_ore.getDefaultState(), 2);
|
||||
// }
|
||||
// }
|
||||
this.theEmeraldGenerator.generate(worldIn, rand, pos);
|
||||
|
||||
// for (i = 0; i < 7; ++i)
|
||||
// {
|
||||
// int j1 = rand.nextInt(16);
|
||||
// int k1 = rand.nextInt(64);
|
||||
// int l1 = rand.nextInt(16);
|
||||
// this.theWorldGenerator.generate(worldIn, rand, pos); // .add(j1, k1, l1));
|
||||
// }
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.topBlock = Blocks.grass.getState();
|
||||
this.fillerBlock = Blocks.dirt.getState();
|
||||
|
||||
if ((noiseVal < -1.0D || noiseVal > 2.0D) && this.field_150638_aH == this.field_150637_aG)
|
||||
{
|
||||
this.topBlock = Blocks.gravel.getState();
|
||||
this.fillerBlock = Blocks.gravel.getState();
|
||||
}
|
||||
else if (noiseVal > 1.0D && this.field_150638_aH != this.field_150636_aF)
|
||||
{
|
||||
this.topBlock = Blocks.stone.getState();
|
||||
this.fillerBlock = Blocks.stone.getState();
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* this creates a mutation specific to Hills biomes
|
||||
*/
|
||||
private BiomeHills mutateHills(Biome p_150633_1_)
|
||||
{
|
||||
this.field_150638_aH = this.field_150637_aG;
|
||||
this.setColor(p_150633_1_.color);
|
||||
this.setBiomeName(p_150633_1_.name + "M", p_150633_1_.display + " M");
|
||||
this.setScaling(p_150633_1_.depth, p_150633_1_.scale);
|
||||
this.setTemperature(p_150633_1_.temperature);
|
||||
this.setHumidity(p_150633_1_.humidity);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Biome createMutatedBiome(int p_180277_1_)
|
||||
{
|
||||
return (new BiomeHills(p_180277_1_, false)).mutateHills(this);
|
||||
}
|
||||
}
|
83
common/src/common/biome/BiomeJungle.java
Executable file
83
common/src/common/biome/BiomeJungle.java
Executable file
|
@ -0,0 +1,83 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockTallGrass;
|
||||
import common.entity.animal.EntityChicken;
|
||||
import common.entity.animal.EntityOcelot;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.FeatureGenerator;
|
||||
import common.worldgen.foliage.WorldGenMelon;
|
||||
import common.worldgen.foliage.WorldGenShrub;
|
||||
import common.worldgen.foliage.WorldGenTallGrass;
|
||||
import common.worldgen.foliage.WorldGenVines;
|
||||
import common.worldgen.tree.WorldGenBaseTree;
|
||||
import common.worldgen.tree.WorldGenJungle;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeJungle extends Biome
|
||||
{
|
||||
private static final State LOG = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
|
||||
private static final State LEAVES = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
|
||||
private static final State BUSH = Blocks.oak_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
|
||||
|
||||
private final boolean edge;
|
||||
|
||||
public BiomeJungle(int id, boolean edge)
|
||||
{
|
||||
super(id);
|
||||
this.edge = edge;
|
||||
|
||||
if (edge)
|
||||
{
|
||||
this.treesPerChunk = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.treesPerChunk = 50;
|
||||
}
|
||||
|
||||
this.grassPerChunk = 25;
|
||||
this.flowersPerChunk = 4;
|
||||
|
||||
if (!edge)
|
||||
{
|
||||
this.mobs.add(new RngSpawn(EntityOcelot.class, 2, 1, 1));
|
||||
}
|
||||
|
||||
this.mobs.add(new RngSpawn(EntityChicken.class, 10, 4, 4));
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)(rand.chance(10) ? this.worldGeneratorBigTree : (rand.chance(2) ? new WorldGenShrub(LOG, BUSH) : (!this.edge && rand.chance(3) ? new WorldGenJungle(false, 10, 20, LOG, LEAVES) : new WorldGenBaseTree(false, rand.range(4, 10), LOG, LEAVES, true))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a WorldGen appropriate for this biome.
|
||||
*/
|
||||
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
|
||||
{
|
||||
return rand.chance(4) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
int i = rand.chOffset();
|
||||
int j = rand.chOffset();
|
||||
int k = rand.zrange(worldIn.getHeight(pos.add(i, 0, j)).getY() * 2);
|
||||
(new WorldGenMelon()).generate(worldIn, rand, pos.add(i, k, j));
|
||||
WorldGenVines worldgenvines = new WorldGenVines();
|
||||
|
||||
for (j = 0; j < 50; ++j)
|
||||
{
|
||||
k = rand.chOffset();
|
||||
int l = 128;
|
||||
int i1 = rand.chOffset();
|
||||
worldgenvines.generate(worldIn, rand, pos.add(k, 128, i1));
|
||||
}
|
||||
}
|
||||
}
|
348
common/src/common/biome/BiomeMesa.java
Executable file
348
common/src/common/biome/BiomeMesa.java
Executable file
|
@ -0,0 +1,348 @@
|
|||
package common.biome;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockColored;
|
||||
import common.block.BlockDirt;
|
||||
import common.block.BlockSand;
|
||||
import common.color.DyeColor;
|
||||
import common.init.Blocks;
|
||||
import common.material.Material;
|
||||
import common.rng.PerlinGen;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeMesa extends Biome
|
||||
{
|
||||
private final boolean bryce;
|
||||
private final boolean soil;
|
||||
|
||||
private State[] layers;
|
||||
private long layerSeed;
|
||||
private PerlinGen baseBryceGen;
|
||||
private PerlinGen highBryceGen;
|
||||
private PerlinGen clayColorGen;
|
||||
|
||||
public BiomeMesa(int id, boolean bryce, boolean soil)
|
||||
{
|
||||
super(id);
|
||||
this.bryce = bryce;
|
||||
this.soil = soil;
|
||||
// this.setDisableRain();
|
||||
// this.setTemperatureLegacy(2.0F).setHumidity(0.0F);
|
||||
this.setHumidity(0.0f);
|
||||
// this.mobs.clear();
|
||||
this.topBlock = Blocks.sand.getState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND);
|
||||
this.fillerBlock = Blocks.stained_hardened_clay.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 20;
|
||||
this.reedsPerChunk = 3;
|
||||
this.cactiPerChunk = 5;
|
||||
this.flowersPerChunk = 0;
|
||||
// this.mobs.clear();
|
||||
|
||||
if (soil)
|
||||
{
|
||||
this.treesPerChunk = 5;
|
||||
}
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return this.worldGeneratorTrees;
|
||||
}
|
||||
|
||||
public int getFoliageColorAtPos(BlockPos pos)
|
||||
{
|
||||
return 10387789;
|
||||
}
|
||||
|
||||
public int getGrassColorAtPos(BlockPos pos)
|
||||
{
|
||||
return 9470285;
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
if (this.layers == null || this.layerSeed != worldIn.getSeed())
|
||||
{
|
||||
this.setupLayers(worldIn.getSeed());
|
||||
}
|
||||
|
||||
if (this.baseBryceGen == null || this.highBryceGen == null || this.layerSeed != worldIn.getSeed())
|
||||
{
|
||||
Random random = new Random(this.layerSeed);
|
||||
this.baseBryceGen = new PerlinGen(random, 4);
|
||||
this.highBryceGen = new PerlinGen(random, 1);
|
||||
}
|
||||
|
||||
this.layerSeed = worldIn.getSeed();
|
||||
double d4 = 0.0D;
|
||||
|
||||
if (this.bryce)
|
||||
{
|
||||
int i = (x & -16) + (z & 15);
|
||||
int j = (z & -16) + (x & 15);
|
||||
double d0 = Math.min(Math.abs(noiseVal), this.baseBryceGen.generate((double)i * 0.25D, (double)j * 0.25D));
|
||||
|
||||
if (d0 > 0.0D)
|
||||
{
|
||||
double d1 = 0.001953125D;
|
||||
double d2 = Math.abs(this.highBryceGen.generate((double)i * d1, (double)j * d1));
|
||||
d4 = d0 * d0 * 2.5D;
|
||||
double d3 = Math.ceil(d2 * 50.0D) + 14.0D;
|
||||
|
||||
if (d4 > d3)
|
||||
{
|
||||
d4 = d3;
|
||||
}
|
||||
|
||||
d4 = d4 + 64.0D;
|
||||
}
|
||||
}
|
||||
|
||||
int j1 = x & 15;
|
||||
int k1 = z & 15;
|
||||
int l1 = worldIn.getSeaLevel();
|
||||
State iblockstate = Blocks.stained_hardened_clay.getState();
|
||||
State iblockstate3 = this.fillerBlock;
|
||||
int k = (int)(noiseVal / 3.0D + 3.0D + rand.doublev() * 0.25D);
|
||||
boolean flag = Math.cos(noiseVal / 3.0D * Math.PI) > 0.0D;
|
||||
int l = -1;
|
||||
boolean flag1 = false;
|
||||
State worldState = worldIn.dimension.getFiller();
|
||||
Block worldBlock = worldState.getBlock();
|
||||
State worldAlt = worldIn.dimension.getAltFiller1();
|
||||
State liquid = worldIn.getSurfaceLiquid();
|
||||
// IBlockState bottom = worldIn.dimension.hasBedrock() ? Blocks.bedrock.getDefaultState() : Blocks.air.getDefaultState();
|
||||
|
||||
for (int i1 = chunkPrimerIn.height - 1; i1 >= 0; --i1)
|
||||
{
|
||||
if (chunkPrimerIn.get(k1, i1, j1).getBlock().getMaterial() == Material.air && i1 < (int)d4)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, worldState);
|
||||
}
|
||||
|
||||
// if (i1 <= rand.zrange(5) && bedrock)
|
||||
// {
|
||||
// chunkPrimerIn.set(k1, i1, j1, bottom);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
State iblockstate1 = chunkPrimerIn.get(k1, i1, j1);
|
||||
|
||||
if (iblockstate1.getBlock().getMaterial() == Material.air)
|
||||
{
|
||||
l = -1;
|
||||
}
|
||||
else if (iblockstate1.getBlock() == worldBlock)
|
||||
{
|
||||
if (l == -1)
|
||||
{
|
||||
flag1 = false;
|
||||
|
||||
if (k <= 0)
|
||||
{
|
||||
iblockstate = null;
|
||||
iblockstate3 = worldState;
|
||||
}
|
||||
else if (i1 >= l1 - 4 && i1 <= l1 + 1)
|
||||
{
|
||||
iblockstate = Blocks.stained_hardened_clay.getState();
|
||||
iblockstate3 = this.fillerBlock;
|
||||
}
|
||||
|
||||
if (i1 < l1 && (iblockstate == null || iblockstate.getBlock().getMaterial() == Material.air))
|
||||
{
|
||||
iblockstate = liquid;
|
||||
}
|
||||
|
||||
l = k + Math.max(0, i1 - l1);
|
||||
|
||||
if (i1 < l1 - 1)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate3);
|
||||
|
||||
if (iblockstate3.getBlock() == Blocks.stained_hardened_clay)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate3.getBlock().getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE));
|
||||
}
|
||||
}
|
||||
else if (this.soil && i1 > 86 + k * 2)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT));
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, Blocks.grass.getState());
|
||||
}
|
||||
}
|
||||
else if (i1 <= l1 + 3 + k)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, this.topBlock);
|
||||
flag1 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
State iblockstate4;
|
||||
|
||||
if (i1 >= 64 && i1 <= 127)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
iblockstate4 = Blocks.hardened_clay.getState();
|
||||
}
|
||||
else
|
||||
{
|
||||
iblockstate4 = this.getBlockAt(x, i1, z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iblockstate4 = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE);
|
||||
}
|
||||
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate4);
|
||||
}
|
||||
}
|
||||
else if (l > 0)
|
||||
{
|
||||
--l;
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE));
|
||||
}
|
||||
else
|
||||
{
|
||||
State iblockstate2 = this.getBlockAt(x, i1, z);
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
private void setupLayers(long seed)
|
||||
{
|
||||
this.layers = new State[64];
|
||||
Arrays.fill(this.layers, Blocks.hardened_clay.getState());
|
||||
Random random = new Random(seed);
|
||||
this.clayColorGen = new PerlinGen(random, 1);
|
||||
|
||||
for (int l1 = 0; l1 < 64; ++l1)
|
||||
{
|
||||
l1 += random.roll(5);
|
||||
|
||||
if (l1 < 64)
|
||||
{
|
||||
this.layers[l1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE);
|
||||
}
|
||||
}
|
||||
|
||||
int i2 = random.range(2, 5);
|
||||
|
||||
for (int i = 0; i < i2; ++i)
|
||||
{
|
||||
int j = random.roll(3);
|
||||
int k = random.zrange(64);
|
||||
|
||||
for (int l = 0; k + l < 64 && l < j; ++l)
|
||||
{
|
||||
this.layers[k + l] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
int j2 = random.range(2, 5);
|
||||
|
||||
for (int k2 = 0; k2 < j2; ++k2)
|
||||
{
|
||||
int i3 = random.range(2, 4);
|
||||
int l3 = random.zrange(64);
|
||||
|
||||
for (int i1 = 0; l3 + i1 < 64 && i1 < i3; ++i1)
|
||||
{
|
||||
this.layers[l3 + i1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.BROWN);
|
||||
}
|
||||
}
|
||||
|
||||
int l2 = random.range(2, 5);
|
||||
|
||||
for (int j3 = 0; j3 < l2; ++j3)
|
||||
{
|
||||
int i4 = random.roll(3);
|
||||
int k4 = random.zrange(64);
|
||||
|
||||
for (int j1 = 0; k4 + j1 < 64 && j1 < i4; ++j1)
|
||||
{
|
||||
this.layers[k4 + j1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.RED);
|
||||
}
|
||||
}
|
||||
|
||||
int k3 = random.range(3, 5);
|
||||
int j4 = 0;
|
||||
|
||||
for (int l4 = 0; l4 < k3; ++l4)
|
||||
{
|
||||
int i5 = 1;
|
||||
j4 += random.range(4, 19);
|
||||
|
||||
for (int k1 = 0; j4 + k1 < 64 && k1 < i5; ++k1)
|
||||
{
|
||||
this.layers[j4 + k1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.WHITE);
|
||||
|
||||
if (j4 + k1 > 1 && random.chance())
|
||||
{
|
||||
this.layers[j4 + k1 - 1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.SILVER);
|
||||
}
|
||||
|
||||
if (j4 + k1 < 63 && random.chance())
|
||||
{
|
||||
this.layers[j4 + k1 + 1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.SILVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private State getBlockAt(int x, int y, int z)
|
||||
{
|
||||
int i = (int)Math.round(this.clayColorGen.generate((double)x * 1.0D / 512.0D, (double)x * 1.0D / 512.0D) * 2.0D);
|
||||
return this.layers[(y + i + 64) % 64];
|
||||
}
|
||||
|
||||
protected Biome createMutatedBiome(int id)
|
||||
{
|
||||
boolean bryce = this.id == Biome.mesa.id;
|
||||
BiomeMesa mesa = new BiomeMesa(id, bryce, this.soil);
|
||||
|
||||
if (!bryce)
|
||||
{
|
||||
mesa.setScaling(Scaling.HILLS_LOW);
|
||||
mesa.setBiomeName(this.name + "M", this.display + " M");
|
||||
}
|
||||
else
|
||||
{
|
||||
mesa.setBiomeName(this.name + "Bryce", this.display + " (Bryce)");
|
||||
}
|
||||
|
||||
mesa.setColor(this.color);
|
||||
return mesa;
|
||||
}
|
||||
}
|
25
common/src/common/biome/BiomeMoon.java
Executable file
25
common/src/common/biome/BiomeMoon.java
Executable file
|
@ -0,0 +1,25 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.FeatureOres;
|
||||
|
||||
public class BiomeMoon extends Biome {
|
||||
private FeatureOres cheeseGenerator = new FeatureOres(Blocks.moon_cheese.getState(), 8, 8, 12, 24, 52, false);
|
||||
|
||||
public BiomeMoon(int id) {
|
||||
super(id);
|
||||
this.topBlock = Blocks.moon_rock.getState();
|
||||
this.fillerBlock = Blocks.moon_rock.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
|
||||
this.cheeseGenerator.generate(worldIn, rand, pos);
|
||||
}
|
||||
}
|
23
common/src/common/biome/BiomeMushroom.java
Executable file
23
common/src/common/biome/BiomeMushroom.java
Executable file
|
@ -0,0 +1,23 @@
|
|||
package common.biome;
|
||||
|
||||
import common.entity.animal.EntityMooshroom;
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeMushroom extends Biome
|
||||
{
|
||||
public BiomeMushroom(int id)
|
||||
{
|
||||
super(id);
|
||||
this.treesPerChunk = -100;
|
||||
this.flowersPerChunk = -100;
|
||||
this.grassPerChunk = -100;
|
||||
this.mushroomsPerChunk = 1;
|
||||
this.bigMushroomsPerChunk = 1;
|
||||
this.topBlock = Blocks.mycelium.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntityMooshroom.class, 8, 4, 8));
|
||||
}
|
||||
}
|
98
common/src/common/biome/BiomeMutated.java
Executable file
98
common/src/common/biome/BiomeMutated.java
Executable file
|
@ -0,0 +1,98 @@
|
|||
package common.biome;
|
||||
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeMutated extends Biome
|
||||
{
|
||||
protected Biome baseBiome;
|
||||
|
||||
public BiomeMutated(int id, Biome biome)
|
||||
{
|
||||
super(id);
|
||||
this.baseBiome = biome;
|
||||
this.setColor(biome.color);
|
||||
this.name = biome.name + "M";
|
||||
this.display = biome.display + " M";
|
||||
this.topBlock = biome.topBlock;
|
||||
this.fillerBlock = biome.fillerBlock;
|
||||
// this.minHeight = biome.minHeight;
|
||||
// this.maxHeight = biome.maxHeight;
|
||||
this.temperature = biome.temperature;
|
||||
this.humidity = biome.humidity;
|
||||
this.waterColor = biome.waterColor;
|
||||
this.allowColdBeach = biome.allowColdBeach;
|
||||
// this.enableRain = biome.enableRain;
|
||||
// this.mobs.clear();
|
||||
this.mobs.addAll(biome.mobs);
|
||||
// this.mobs = new WeightedList(biome.mobs);
|
||||
// this.monsters = new WeightedList(biome.monsters);
|
||||
// this.caveMobs = new WeightedList(biome.caveMobs);
|
||||
// this.waterMobs = new WeightedList(biome.waterMobs);
|
||||
// this.npcs = new WeightedList(biome.npcs);
|
||||
// this.temperature = biome.temperature;
|
||||
// this.humidity = biome.humidity;
|
||||
this.depth = biome.depth + 0.1F;
|
||||
this.scale = biome.scale + 0.2F;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
this.baseBiome.decorate(worldIn, rand, pos); // TODO: check
|
||||
}
|
||||
|
||||
public void decorateNormal(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.baseBiome.genTerrainBlocks(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
public float getMobGenChance()
|
||||
{
|
||||
return this.baseBiome.getMobGenChance();
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return this.baseBiome.genBigTreeChance(rand);
|
||||
}
|
||||
|
||||
public int getFoliageColorAtPos(BlockPos pos)
|
||||
{
|
||||
return this.baseBiome.getFoliageColorAtPos(pos);
|
||||
}
|
||||
|
||||
public int getGrassColorAtPos(BlockPos pos)
|
||||
{
|
||||
return this.baseBiome.getGrassColorAtPos(pos);
|
||||
}
|
||||
|
||||
public Class <? extends Biome > getBiomeClass()
|
||||
{
|
||||
return this.baseBiome.getBiomeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the biome specified is equal to this biome
|
||||
*/
|
||||
public boolean isEqualTo(Biome biome)
|
||||
{
|
||||
return this.baseBiome.isEqualTo(biome);
|
||||
}
|
||||
|
||||
public Temperature getTempCategory()
|
||||
{
|
||||
return this.baseBiome.getTempCategory();
|
||||
}
|
||||
}
|
29
common/src/common/biome/BiomeNone.java
Executable file
29
common/src/common/biome/BiomeNone.java
Executable file
|
@ -0,0 +1,29 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
|
||||
public class BiomeNone extends Biome {
|
||||
public BiomeNone(int id) {
|
||||
super(id);
|
||||
this.topBlock = Blocks.air.getState();
|
||||
this.fillerBlock = Blocks.air.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
|
||||
}
|
||||
|
||||
public Temperature getTempCategory() {
|
||||
return Temperature.SEA;
|
||||
}
|
||||
}
|
120
common/src/common/biome/BiomePlains.java
Executable file
120
common/src/common/biome/BiomePlains.java
Executable file
|
@ -0,0 +1,120 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockDoublePlant;
|
||||
import common.block.BlockFlower;
|
||||
import common.entity.animal.EntityHorse;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public class BiomePlains extends Biome
|
||||
{
|
||||
private static final BlockFlower.EnumFlowerType[] TULIP_TYPES = new BlockFlower.EnumFlowerType[] {
|
||||
BlockFlower.EnumFlowerType.ORANGE_TULIP, BlockFlower.EnumFlowerType.RED_TULIP,
|
||||
BlockFlower.EnumFlowerType.PINK_TULIP, BlockFlower.EnumFlowerType.WHITE_TULIP
|
||||
};
|
||||
|
||||
private static final BlockFlower.EnumFlowerType[] FLOWER_TYPES = new BlockFlower.EnumFlowerType[] {
|
||||
BlockFlower.EnumFlowerType.POPPY, BlockFlower.EnumFlowerType.HOUSTONIA, BlockFlower.EnumFlowerType.OXEYE_DAISY
|
||||
};
|
||||
|
||||
// protected boolean field_150628_aC;
|
||||
|
||||
protected BiomePlains(int id)
|
||||
{
|
||||
super(id);
|
||||
this.setTemperature(12.0f).setHumidity(40.0f);
|
||||
this.setScaling(Scaling.PLAINS_LOW);
|
||||
this.mobs.add(new RngSpawn(EntityHorse.class, 5, 2, 6));
|
||||
this.treesPerChunk = -999;
|
||||
this.flowersPerChunk = 4;
|
||||
this.grassPerChunk = 10;
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
double d0 = GRASS_NOISE.generate((double)pos.getX() / 200.0D, (double)pos.getZ() / 200.0D);
|
||||
|
||||
if (d0 < -0.8D)
|
||||
{
|
||||
return rand.pick(TULIP_TYPES);
|
||||
// int j = rand.nextInt(4);
|
||||
//
|
||||
// switch (j)
|
||||
// {
|
||||
// case 0:
|
||||
// return BlockFlower.EnumFlowerType.ORANGE_TULIP;
|
||||
//
|
||||
// case 1:
|
||||
// return BlockFlower.EnumFlowerType.RED_TULIP;
|
||||
//
|
||||
// case 2:
|
||||
// return BlockFlower.EnumFlowerType.PINK_TULIP;
|
||||
//
|
||||
// case 3:
|
||||
// default:
|
||||
// return BlockFlower.EnumFlowerType.WHITE_TULIP;
|
||||
// }
|
||||
}
|
||||
else if (rand.rarity(3))
|
||||
{
|
||||
return rand.pick(FLOWER_TYPES);
|
||||
// int i = rand.nextInt(3);
|
||||
// return i == 0 ? BlockFlower.EnumFlowerType.POPPY : (i == 1 ? BlockFlower.EnumFlowerType.HOUSTONIA : BlockFlower.EnumFlowerType.OXEYE_DAISY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return BlockFlower.EnumFlowerType.DANDELION;
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
double d0 = GRASS_NOISE.generate((double)(pos.getX() + 8) / 200.0D, (double)(pos.getZ() + 8) / 200.0D);
|
||||
|
||||
if (d0 < -0.8D)
|
||||
{
|
||||
this.flowersPerChunk = 15;
|
||||
this.grassPerChunk = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.flowersPerChunk = 4;
|
||||
this.grassPerChunk = 10;
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
int l = rand.zrange(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j, l, k));
|
||||
}
|
||||
}
|
||||
|
||||
// int n = rand.range(0, 2);
|
||||
if (rand.chance())
|
||||
{
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.SUNFLOWER);
|
||||
|
||||
// for (int i1 = 0; i1 < 10; ++i1)
|
||||
// {
|
||||
int j1 = rand.chOffset();
|
||||
int k1 = rand.chOffset();
|
||||
int l1 = rand.zrange(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j1, l1, k1));
|
||||
// }
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
// protected Biome createMutatedBiome(int p_180277_1_)
|
||||
// {
|
||||
// BiomePlains biomegenplains = new BiomePlains(p_180277_1_);
|
||||
// biomegenplains.setBiomeName("sunflowerPlains");
|
||||
// biomegenplains.field_150628_aC = true;
|
||||
// biomegenplains.setColor(9286496);
|
||||
// return biomegenplains;
|
||||
// }
|
||||
}
|
89
common/src/common/biome/BiomeSavanna.java
Executable file
89
common/src/common/biome/BiomeSavanna.java
Executable file
|
@ -0,0 +1,89 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockDirt;
|
||||
import common.block.BlockDoublePlant;
|
||||
import common.entity.animal.EntityHorse;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
import common.worldgen.tree.WorldGenSavanna;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeSavanna extends Biome
|
||||
{
|
||||
private static final WorldGenSavanna field_150627_aC = new WorldGenSavanna(false);
|
||||
|
||||
protected BiomeSavanna(int id)
|
||||
{
|
||||
super(id);
|
||||
this.mobs.add(new RngSpawn(EntityHorse.class, 1, 2, 6));
|
||||
this.treesPerChunk = 1;
|
||||
this.flowersPerChunk = 4;
|
||||
this.grassPerChunk = 20;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)(rand.rarity(5) ? field_150627_aC : this.worldGeneratorTrees);
|
||||
}
|
||||
|
||||
protected Biome createMutatedBiome(int p_180277_1_)
|
||||
{
|
||||
Biome biomegenbase = new BiomeSavanna.Mutated(p_180277_1_, this);
|
||||
biomegenbase.temperature = this.temperature == 28.0f ? 24.0f : 20.0f;
|
||||
biomegenbase.depth = this.depth * 0.5F + 0.3F;
|
||||
biomegenbase.scale = this.scale * 0.5F + 1.2F;
|
||||
return biomegenbase;
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
int l = rand.zrange(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j, l, k));
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public static class Mutated extends BiomeMutated
|
||||
{
|
||||
public Mutated(int p_i45382_1_, Biome p_i45382_2_)
|
||||
{
|
||||
super(p_i45382_1_, p_i45382_2_);
|
||||
this.treesPerChunk = 2;
|
||||
this.flowersPerChunk = 2;
|
||||
this.grassPerChunk = 5;
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.topBlock = Blocks.grass.getState();
|
||||
this.fillerBlock = Blocks.dirt.getState();
|
||||
|
||||
if (noiseVal > 1.75D)
|
||||
{
|
||||
this.topBlock = Blocks.stone.getState();
|
||||
this.fillerBlock = Blocks.stone.getState();
|
||||
}
|
||||
else if (noiseVal > -0.5D)
|
||||
{
|
||||
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
this.decorateNormal(worldIn, rand, pos);
|
||||
}
|
||||
}
|
||||
}
|
64
common/src/common/biome/BiomeSnow.java
Executable file
64
common/src/common/biome/BiomeSnow.java
Executable file
|
@ -0,0 +1,64 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.feature.WorldGenIcePath;
|
||||
import common.worldgen.feature.WorldGenIceSpike;
|
||||
import common.worldgen.tree.WorldGenTaiga2;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeSnow extends Biome
|
||||
{
|
||||
private final WorldGenIceSpike spikeGen = new WorldGenIceSpike();
|
||||
private final WorldGenIcePath pathGen = new WorldGenIcePath(4);
|
||||
private final boolean spiky;
|
||||
|
||||
public BiomeSnow(int id, boolean spiky)
|
||||
{
|
||||
super(id);
|
||||
this.spiky = spiky;
|
||||
if(spiky)
|
||||
this.topBlock = Blocks.snow.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if (this.spiky)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
this.spikeGen.generate(worldIn, rand, worldIn.getHeight(pos.add(j, 0, k)));
|
||||
}
|
||||
|
||||
for (int l = 0; l < 2; ++l)
|
||||
{
|
||||
int i1 = rand.chOffset();
|
||||
int j1 = rand.chOffset();
|
||||
this.pathGen.generate(worldIn, rand, worldIn.getHeight(pos.add(i1, 0, j1)));
|
||||
}
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return new WorldGenTaiga2(false);
|
||||
}
|
||||
|
||||
protected Biome createMutatedBiome(int p_180277_1_)
|
||||
{
|
||||
Biome biomegenbase = (new BiomeSnow(p_180277_1_, true)).setColor(13828095).setBiomeName(this.name + "Spikes", this.display + " + Spitzen").enableColdBeach().setTemperature(-20.0f).setHumidity(50.0f).setScaling(this.depth + 0.1F, this.scale + 0.1F);
|
||||
biomegenbase.depth = this.depth + 0.3F;
|
||||
biomegenbase.scale = this.scale + 0.4F;
|
||||
return biomegenbase;
|
||||
}
|
||||
}
|
22
common/src/common/biome/BiomeSnowLand.java
Executable file
22
common/src/common/biome/BiomeSnowLand.java
Executable file
|
@ -0,0 +1,22 @@
|
|||
package common.biome;
|
||||
|
||||
import common.entity.animal.EntitySheep;
|
||||
import common.entity.npc.EntitySpirit;
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeSnowLand extends Biome
|
||||
{
|
||||
public BiomeSnowLand(int id)
|
||||
{
|
||||
super(id);
|
||||
this.topBlock = Blocks.snow.getState();
|
||||
this.fillerBlock = Blocks.snow.getState();
|
||||
this.mushroomsPerChunk = -1;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntitySheep.class, 50, 4, 4));
|
||||
mobs.add(new RngSpawn(EntitySpirit.class, 10, 1, 1));
|
||||
}
|
||||
}
|
38
common/src/common/biome/BiomeSpace.java
Executable file
38
common/src/common/biome/BiomeSpace.java
Executable file
|
@ -0,0 +1,38 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockDirt;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.FeatureGenerator;
|
||||
import common.worldgen.feature.WorldGenAsteroid;
|
||||
|
||||
public class BiomeSpace extends Biome
|
||||
{
|
||||
protected FeatureGenerator asteroidGen1 = new WorldGenAsteroid(Blocks.stone.getState(),
|
||||
Blocks.rock.getState());
|
||||
protected FeatureGenerator asteroidGen2 = new WorldGenAsteroid(Blocks.dirt.getState(),
|
||||
Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT));
|
||||
|
||||
public BiomeSpace(int id)
|
||||
{
|
||||
super(id);
|
||||
this.topBlock = Blocks.air.getState();
|
||||
this.fillerBlock = Blocks.air.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if(rand.chance(5)) {
|
||||
int x = rand.chOffset();
|
||||
int z = rand.chOffset();
|
||||
rand.chance(this.asteroidGen1, this.asteroidGen2, 100).generate(worldIn, rand,
|
||||
pos.add(x, rand.range(16, 495), z));
|
||||
}
|
||||
}
|
||||
}
|
22
common/src/common/biome/BiomeStoneBeach.java
Executable file
22
common/src/common/biome/BiomeStoneBeach.java
Executable file
|
@ -0,0 +1,22 @@
|
|||
package common.biome;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeStoneBeach extends Biome
|
||||
{
|
||||
public BiomeStoneBeach(int id)
|
||||
{
|
||||
super(id);
|
||||
// this.mobs.clear();
|
||||
this.topBlock = Blocks.stone.getState();
|
||||
this.fillerBlock = Blocks.stone.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 0;
|
||||
this.reedsPerChunk = 0;
|
||||
this.cactiPerChunk = 0;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
}
|
86
common/src/common/biome/BiomeSwamp.java
Executable file
86
common/src/common/biome/BiomeSwamp.java
Executable file
|
@ -0,0 +1,86 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockDirectional;
|
||||
import common.block.BlockFlower;
|
||||
import common.entity.npc.EntitySlime;
|
||||
import common.init.Blocks;
|
||||
import common.material.Material;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.Facing;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeSwamp extends Biome
|
||||
{
|
||||
protected BiomeSwamp(int id)
|
||||
{
|
||||
super(id);
|
||||
this.treesPerChunk = 2;
|
||||
this.flowersPerChunk = 1;
|
||||
this.deadBushPerChunk = 1;
|
||||
this.mushroomsPerChunk = 8;
|
||||
this.reedsPerChunk = 10;
|
||||
this.clayPerChunk = 1;
|
||||
this.waterlilyPerChunk = 4;
|
||||
this.sandPerChunk2 = 0;
|
||||
this.sandPerChunk = 0;
|
||||
this.grassPerChunk = 5;
|
||||
this.waterColor = 0xe0ffae;
|
||||
this.mobs.add(new RngSpawn(EntitySlime.class, 1, 1, 1));
|
||||
this.disableBeach();
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return this.worldGeneratorSwamp;
|
||||
}
|
||||
|
||||
public int getGrassColorAtPos(BlockPos pos)
|
||||
{
|
||||
double d0 = GRASS_NOISE.generate((double)pos.getX() * 0.0225D, (double)pos.getZ() * 0.0225D);
|
||||
return d0 < -0.1D ? 5011004 : 6975545;
|
||||
}
|
||||
|
||||
public int getFoliageColorAtPos(BlockPos pos)
|
||||
{
|
||||
return 6975545;
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
return BlockFlower.EnumFlowerType.BLUE_ORCHID;
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
double d0 = GRASS_NOISE.generate((double)x * 0.25D, (double)z * 0.25D);
|
||||
|
||||
if (d0 > 0.0D)
|
||||
{
|
||||
int i = x & 15;
|
||||
int j = z & 15;
|
||||
|
||||
for (int k = chunkPrimerIn.height - 1; k >= 0; --k)
|
||||
{
|
||||
if (chunkPrimerIn.get(j, k, i).getBlock().getMaterial() != Material.air)
|
||||
{
|
||||
if (k == 62 && chunkPrimerIn.get(j, k, i).getBlock() != Blocks.water)
|
||||
{
|
||||
chunkPrimerIn.set(j, k, i, Blocks.water.getState());
|
||||
|
||||
if (d0 < 0.12D)
|
||||
{
|
||||
chunkPrimerIn.set(j, k + 1, i, Blocks.waterlily.getState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(rand)));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
}
|
114
common/src/common/biome/BiomeTaiga.java
Executable file
114
common/src/common/biome/BiomeTaiga.java
Executable file
|
@ -0,0 +1,114 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockDirt;
|
||||
import common.block.BlockDoublePlant;
|
||||
import common.block.BlockTallGrass;
|
||||
import common.entity.animal.EntityWolf;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.ChunkPrimer;
|
||||
import common.worldgen.FeatureGenerator;
|
||||
import common.worldgen.feature.WorldGenBlockBlob;
|
||||
import common.worldgen.foliage.WorldGenTallGrass;
|
||||
import common.worldgen.tree.WorldGenPine;
|
||||
import common.worldgen.tree.WorldGenTaiga1;
|
||||
import common.worldgen.tree.WorldGenTaiga2;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeTaiga extends Biome
|
||||
{
|
||||
private static final WorldGenTaiga1 field_150639_aC = new WorldGenTaiga1();
|
||||
private static final WorldGenTaiga2 field_150640_aD = new WorldGenTaiga2(false);
|
||||
private static final WorldGenPine field_150641_aE = new WorldGenPine(false, false);
|
||||
private static final WorldGenPine field_150642_aF = new WorldGenPine(false, true);
|
||||
private static final WorldGenBlockBlob field_150643_aG = new WorldGenBlockBlob(Blocks.mossy_cobblestone, 0);
|
||||
private int field_150644_aH;
|
||||
|
||||
public BiomeTaiga(int id, int p_i45385_2_)
|
||||
{
|
||||
super(id);
|
||||
this.field_150644_aH = p_i45385_2_;
|
||||
this.mobs.add(new RngSpawn(EntityWolf.class, 8, 4, 4));
|
||||
this.treesPerChunk = 10;
|
||||
|
||||
if (p_i45385_2_ != 1 && p_i45385_2_ != 2)
|
||||
{
|
||||
this.grassPerChunk = 1;
|
||||
this.mushroomsPerChunk = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.grassPerChunk = 7;
|
||||
this.deadBushPerChunk = 1;
|
||||
this.mushroomsPerChunk = 3;
|
||||
}
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)((this.field_150644_aH == 1 || this.field_150644_aH == 2) && rand.chance(3) ? (this.field_150644_aH != 2 && rand.rarity(13) ? field_150641_aE : field_150642_aF) : (rand.chance(3) ? field_150639_aC : field_150640_aD));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a WorldGen appropriate for this biome.
|
||||
*/
|
||||
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
|
||||
{
|
||||
return rand.rarity(5) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if (this.field_150644_aH == 1 || this.field_150644_aH == 2)
|
||||
{
|
||||
int i = rand.zrange(3);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
int k = rand.chOffset();
|
||||
int l = rand.chOffset();
|
||||
BlockPos blockpos = worldIn.getHeight(pos.add(k, 0, l));
|
||||
field_150643_aG.generate(worldIn, rand, blockpos);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.FERN);
|
||||
|
||||
for (int i1 = 0; i1 < 7; ++i1)
|
||||
{
|
||||
int j1 = rand.chOffset();
|
||||
int k1 = rand.chOffset();
|
||||
int l1 = rand.zrange(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j1, l1, k1));
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
if (this.field_150644_aH == 1 || this.field_150644_aH == 2)
|
||||
{
|
||||
this.topBlock = Blocks.grass.getState();
|
||||
this.fillerBlock = Blocks.dirt.getState();
|
||||
|
||||
if (noiseVal > 1.75D)
|
||||
{
|
||||
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
|
||||
}
|
||||
else if (noiseVal > -0.95D)
|
||||
{
|
||||
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.PODZOL);
|
||||
}
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
protected Biome createMutatedBiome(int p_180277_1_)
|
||||
{
|
||||
return this.id == Biome.megaTaiga.id ? (new BiomeTaiga(p_180277_1_, 2)).setColor(5858897).setBiomeName("megaSpruceTaiga", "Hohe Fichtentaiga").setTemperature(-10.0f).setHumidity(80.0f).setScaling(this.depth, this.scale) : super.createMutatedBiome(p_180277_1_);
|
||||
}
|
||||
}
|
82
common/src/common/biome/BiomeTian.java
Executable file
82
common/src/common/biome/BiomeTian.java
Executable file
|
@ -0,0 +1,82 @@
|
|||
package common.biome;
|
||||
|
||||
import common.block.BlockFlower;
|
||||
import common.entity.animal.EntityBat;
|
||||
import common.entity.animal.EntityMouse;
|
||||
import common.entity.animal.EntityRabbit;
|
||||
import common.entity.npc.EntityCultivator;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.world.BlockPos;
|
||||
import common.world.WorldServer;
|
||||
import common.worldgen.FeatureGenerator;
|
||||
import common.worldgen.feature.WorldGenSpikes;
|
||||
import common.worldgen.foliage.WorldGenMushroom;
|
||||
import common.worldgen.tree.WorldGenBaseTree;
|
||||
import common.worldgen.tree.WorldGenBigTree;
|
||||
import common.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeTian extends Biome
|
||||
{
|
||||
protected FeatureGenerator spikeGen = new WorldGenSpikes(Blocks.tian_soil, 128, 2, 3, Blocks.obsidian.getState(), true);
|
||||
protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom);
|
||||
protected WorldGenTree treeGen1 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
|
||||
.setHeightLimit(6, 8);
|
||||
protected WorldGenTree treeGen2 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
|
||||
.setHeightLimit(14, 20);
|
||||
protected WorldGenTree treeGen3 = new WorldGenBaseTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState());
|
||||
protected WorldGenTree treeGen4 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
|
||||
.setHeightLimit(12, 15);
|
||||
|
||||
public BiomeTian(int id)
|
||||
{
|
||||
super(id);
|
||||
this.topBlock = Blocks.tian_soil.getState();
|
||||
this.fillerBlock = Blocks.tian.getState();
|
||||
this.mushroomsPerChunk = -1;
|
||||
this.grassPerChunk = 0;
|
||||
this.treesPerChunk = 1;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
// mobs.add(new Biome.RngSpawn(EntityHaunter.class, 50, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityCultivator.class, 50, 1, 1));
|
||||
mobs.add(new RngSpawn(EntityRabbit.class, 10, 3, 10));
|
||||
mobs.add(new RngSpawn(EntityBat.class, 10, 8, 8));
|
||||
mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8));
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
return BlockFlower.EnumFlowerType.BLACK_LOTUS;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return rand.pick(rand.chance(this.treeGen2, this.treeGen1, 4), rand.chance(this.treeGen3, this.treeGen4, 15));
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
|
||||
for (int l3 = 0; l3 < 2; ++l3)
|
||||
{
|
||||
if (rand.chance(4))
|
||||
{
|
||||
int i8 = rand.chOffset();
|
||||
int l11 = rand.chOffset();
|
||||
BlockPos blockpos2 = worldIn.getHeight(pos.add(i8, 0, l11));
|
||||
this.mushroomBlueGen.generate(worldIn, rand, blockpos2);
|
||||
}
|
||||
}
|
||||
|
||||
if (rand.chance(4))
|
||||
{
|
||||
int i = rand.chOffset();
|
||||
int j = rand.chOffset();
|
||||
this.spikeGen.generate(worldIn, rand, worldIn.getTopSolidOrLiquidBlock(pos.add(i, 0, j)));
|
||||
}
|
||||
}
|
||||
}
|
22
common/src/common/biome/BiomeWater.java
Executable file
22
common/src/common/biome/BiomeWater.java
Executable file
|
@ -0,0 +1,22 @@
|
|||
package common.biome;
|
||||
|
||||
import common.entity.animal.EntitySquid;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeWater extends Biome {
|
||||
private final boolean river;
|
||||
|
||||
public BiomeWater(int id, boolean river) {
|
||||
super(id);
|
||||
this.river = river;
|
||||
this.disableBeach();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntitySquid.class, 10, 4, 4));
|
||||
}
|
||||
|
||||
public Temperature getTempCategory() {
|
||||
return this.river ? super.getTempCategory() : Temperature.SEA;
|
||||
}
|
||||
}
|
17
common/src/common/biome/RngSpawn.java
Normal file
17
common/src/common/biome/RngSpawn.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package common.biome;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.rng.RngItem;
|
||||
|
||||
public class RngSpawn extends RngItem {
|
||||
public final Class<? extends EntityLiving> type;
|
||||
public final int min;
|
||||
public final int max;
|
||||
|
||||
public RngSpawn(Class<? extends EntityLiving> type, int weight, int min, int max) {
|
||||
super(weight);
|
||||
this.type = type;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
}
|
28
common/src/common/biome/Scaling.java
Normal file
28
common/src/common/biome/Scaling.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package common.biome;
|
||||
|
||||
public enum Scaling {
|
||||
VARYING_LOW(0.1F, 0.2F),
|
||||
VARYING_MEDIUM(0.1F, 1.0F),
|
||||
VARYING_CHAOTIC(1.0F, 2.0F),
|
||||
SEA_VARYING(0.1F, 0.8F),
|
||||
SEA_SHORE(0.0F, 0.025F),
|
||||
SEA_POND(-0.2F, 0.1F),
|
||||
SEA_SHALLOW(-0.5F, 0.0F),
|
||||
SEA_MEDIUM(-1.0F, 0.1F),
|
||||
SEA_DEEP(-1.8F, 0.1F),
|
||||
PLAINS_LOW(0.125F, 0.05F),
|
||||
PLAINS_MEDIUM(0.2F, 0.2F),
|
||||
PLAINS_VARYING(0.2F, 0.3F),
|
||||
HILLS_LOW(0.45F, 0.3F),
|
||||
HILLS_MEDIUM(0.8F, 0.3F),
|
||||
HILLS_LARGE(1.0F, 0.5F),
|
||||
HILLS_PLATEAU(1.5F, 0.025F);
|
||||
|
||||
public final float depth;
|
||||
public final float scale;
|
||||
|
||||
private Scaling(float depth, float scale) {
|
||||
this.depth = depth;
|
||||
this.scale = scale;
|
||||
}
|
||||
}
|
5
common/src/common/biome/Temperature.java
Normal file
5
common/src/common/biome/Temperature.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
package common.biome;
|
||||
|
||||
public enum Temperature {
|
||||
SEA, COLD, MEDIUM, WARM;
|
||||
}
|
1446
common/src/common/block/Block.java
Executable file
1446
common/src/common/block/Block.java
Executable file
File diff suppressed because it is too large
Load diff
56
common/src/common/block/BlockAir.java
Executable file
56
common/src/common/block/BlockAir.java
Executable file
|
@ -0,0 +1,56 @@
|
|||
package common.block;
|
||||
|
||||
import common.material.Material;
|
||||
import common.world.BlockPos;
|
||||
import common.world.BoundingBox;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockAir extends Block
|
||||
{
|
||||
public BlockAir()
|
||||
{
|
||||
super(Material.air);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 -1;
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canCollideCheck(State state, boolean hitIfLiquid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns this Block's drops into the World as EntityItems.
|
||||
*/
|
||||
public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this Block can be replaced directly by other blocks (true for e.g. tall grass)
|
||||
*/
|
||||
public boolean isReplaceable(World worldIn, BlockPos pos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
209
common/src/common/block/BlockAnvil.java
Executable file
209
common/src/common/block/BlockAnvil.java
Executable file
|
@ -0,0 +1,209 @@
|
|||
package common.block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.item.EntityFalling;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.inventory.Container;
|
||||
import common.inventory.ContainerRepair;
|
||||
import common.inventory.InventoryPlayer;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.material.Material;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.model.ModelRotation;
|
||||
import common.model.Transforms;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.properties.PropertyInteger;
|
||||
import common.tileentity.IInteractionObject;
|
||||
import common.world.BlockPos;
|
||||
import common.world.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockAnvil extends BlockFalling
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL);
|
||||
public static final PropertyInteger DAMAGE = PropertyInteger.create("damage", 0, 2);
|
||||
|
||||
public BlockAnvil()
|
||||
{
|
||||
super(Material.anvil);
|
||||
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(DAMAGE, Integer.valueOf(0)));
|
||||
this.setLightOpacity(0);
|
||||
this.setTab(CheatTab.tabTech);
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
Facing enumfacing = placer.getHorizontalFacing().rotateY();
|
||||
return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer).withProperty(FACING, enumfacing).withProperty(DAMAGE, Integer.valueOf(meta >> 2));
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
if (!worldIn.client)
|
||||
{
|
||||
playerIn.displayGui(new BlockAnvil.Anvil(worldIn, pos));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ((Integer)state.getValue(DAMAGE)).intValue();
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
Facing enumfacing = (Facing)worldIn.getState(pos).getValue(FACING);
|
||||
|
||||
if (enumfacing.getAxis() == Facing.Axis.X)
|
||||
{
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.125F, 1.0F, 1.0F, 0.875F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, 0));
|
||||
list.add(new ItemStack(itemIn, 1, 1));
|
||||
list.add(new ItemStack(itemIn, 1, 2));
|
||||
}
|
||||
|
||||
protected void onStartFalling(EntityFalling fallingEntity)
|
||||
{
|
||||
fallingEntity.setHurtEntities(true);
|
||||
}
|
||||
|
||||
public void onEndFalling(World worldIn, BlockPos pos)
|
||||
{
|
||||
worldIn.playAuxSFX(1022, pos, 0);
|
||||
}
|
||||
|
||||
public boolean shouldSideBeRendered(IWorldAccess worldIn, BlockPos pos, Facing side)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Possibly modify the given BlockState before rendering it on an Entity (Minecarts, Endermen, ...)
|
||||
*/
|
||||
public State getStateForEntityRender(State state)
|
||||
{
|
||||
return this.getState().withProperty(FACING, Facing.SOUTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given metadata into a BlockState for this Block
|
||||
*/
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(FACING, Facing.getHorizontal(meta & 3)).withProperty(DAMAGE, Integer.valueOf((meta & 12) == 12 ? 0 : ((meta & 12) >> 2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the BlockState into the correct metadata value
|
||||
*/
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
int i = 0;
|
||||
i = i | ((Facing)state.getValue(FACING)).getHorizontalIndex();
|
||||
i = i | ((Integer)state.getValue(DAMAGE)).intValue() << 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {FACING, DAMAGE};
|
||||
}
|
||||
|
||||
public Transforms getTransform() {
|
||||
return Transforms.ANVIL;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel("anvil_base")
|
||||
.add(2, 0, 2, 14, 4, 14).d().uv(2, 2, 14, 14).rot(180).u().uv(2, 2, 14, 14).rot(180).noCull()
|
||||
.ns().uv(2, 12, 14, 16).noCull().w().uv(0, 2, 4, 14).rot(90).noCull().e().uv(4, 2, 0, 14).rot(270).noCull()
|
||||
.add(4, 4, 3, 12, 5, 13).du().uv(4, 3, 12, 13).rot(180).noCull()
|
||||
.ns().uv(4, 11, 12, 12).noCull().w().uv(4, 3, 5, 13).rot(90).noCull().e().uv(5, 3, 4, 13).rot(270).noCull()
|
||||
.add(6, 5, 4, 10, 10, 12).du().uv(10, 12, 6, 4).rot(180).noCull()
|
||||
.ns().uv(6, 6, 10, 11).noCull().w().uv(5, 4, 10, 12).rot(90).noCull().e().uv(10, 4, 5, 12).rot(270).noCull()
|
||||
.add(3, 10, 0, 13, 16, 16).d().uv(3, 0, 13, 16).rot(180).noCull().u("anvil_top_" + state.getValue(DAMAGE))
|
||||
.uv(3, 0, 13, 16).rot(180).noCull()
|
||||
.ns().uv(3, 0, 13, 6).noCull().w().uv(10, 0, 16, 16).rot(90).noCull().e().uv(16, 0, 10, 16).rot(270).noCull()
|
||||
.rotate(ModelRotation.getNorthRot(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
public static class Anvil implements IInteractionObject
|
||||
{
|
||||
private final World world;
|
||||
private final BlockPos position;
|
||||
|
||||
public Anvil(World worldIn, BlockPos pos)
|
||||
{
|
||||
this.world = worldIn;
|
||||
this.position = pos;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "anvil";
|
||||
}
|
||||
|
||||
public boolean hasCustomName()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getCommandName()
|
||||
{
|
||||
return "Amboss";
|
||||
}
|
||||
|
||||
public Container createContainer(InventoryPlayer playerInventory, EntityNPC playerIn)
|
||||
{
|
||||
return new ContainerRepair(playerInventory, this.world, this.position, playerIn);
|
||||
}
|
||||
|
||||
public String getGuiID()
|
||||
{
|
||||
return "anvil";
|
||||
}
|
||||
}
|
||||
}
|
273
common/src/common/block/BlockBanner.java
Executable file
273
common/src/common/block/BlockBanner.java
Executable file
|
@ -0,0 +1,273 @@
|
|||
package common.block;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.Items;
|
||||
import common.item.Item;
|
||||
import common.item.ItemStack;
|
||||
import common.material.Material;
|
||||
import common.model.Transforms;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.properties.PropertyInteger;
|
||||
import common.rng.Random;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.tileentity.TileEntityBanner;
|
||||
import common.world.BlockPos;
|
||||
import common.world.BoundingBox;
|
||||
import common.world.Facing;
|
||||
import common.world.IBlockAccess;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockBanner extends BlockContainer
|
||||
{
|
||||
public static final PropertyDirection FACING = PropertyDirection.create("facing", Facing.Plane.HORIZONTAL);
|
||||
public static final PropertyInteger ROTATION = PropertyInteger.create("rotation", 0, 15);
|
||||
|
||||
public BlockBanner()
|
||||
{
|
||||
super(Material.wood);
|
||||
float f = 0.25F;
|
||||
float f1 = 1.0F;
|
||||
this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Gets the localized name of this block. Used for the statistics page.
|
||||
// */
|
||||
// public String getLocalizedName()
|
||||
// {
|
||||
// return "Banner";
|
||||
// }
|
||||
|
||||
public boolean isPickStrict()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public BoundingBox getSelectedBoundingBox(World worldIn, BlockPos pos)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState(worldIn, pos);
|
||||
return super.getSelectedBoundingBox(worldIn, pos);
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPassable(IBlockAccess worldIn, BlockPos pos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if an entity can be spawned inside the block (used to get the player's bed spawn location)
|
||||
*/
|
||||
public boolean canSpawnInBlock()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 TileEntityBanner();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Item that this Block should drop when harvested.
|
||||
*/
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return Items.banner;
|
||||
}
|
||||
|
||||
public Item getItem(World worldIn, BlockPos pos)
|
||||
{
|
||||
return Items.banner;
|
||||
}
|
||||
|
||||
public int getDamageValue(World worldIn, BlockPos pos)
|
||||
{
|
||||
TileEntity te = worldIn.getTileEntity(pos);
|
||||
if(te instanceof TileEntityBanner)
|
||||
return ((TileEntityBanner)te).getBaseColor();
|
||||
return super.getDamageValue(worldIn, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns this Block's drops into the World as EntityItems.
|
||||
*/
|
||||
public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, State state, float chance, int fortune)
|
||||
{
|
||||
TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
|
||||
if (tileentity instanceof TileEntityBanner)
|
||||
{
|
||||
ItemStack itemstack = new ItemStack(Items.banner, 1, ((TileEntityBanner)tileentity).getBaseColor());
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
tileentity.writeToNBT(nbttagcompound);
|
||||
nbttagcompound.removeTag("x");
|
||||
nbttagcompound.removeTag("y");
|
||||
nbttagcompound.removeTag("z");
|
||||
nbttagcompound.removeTag("id");
|
||||
itemstack.setTagInfo("BlockEntityTag", nbttagcompound);
|
||||
spawnAsEntity(worldIn, pos, itemstack);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.dropBlockAsItemWithChance(worldIn, pos, state, chance, fortune);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return !this.hasInvalidNeighbor(worldIn, pos) && super.canPlaceBlockAt(worldIn, pos);
|
||||
}
|
||||
|
||||
public void harvestBlock(World worldIn, EntityNPC player, BlockPos pos, State state, TileEntity te)
|
||||
{
|
||||
if (te instanceof TileEntityBanner)
|
||||
{
|
||||
TileEntityBanner tileentitybanner = (TileEntityBanner)te;
|
||||
ItemStack itemstack = new ItemStack(Items.banner, 1, ((TileEntityBanner)te).getBaseColor());
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
TileEntityBanner.setBaseColorAndPatterns(nbttagcompound, tileentitybanner.getBaseColor(), tileentitybanner.getPatterns());
|
||||
itemstack.setTagInfo("BlockEntityTag", nbttagcompound);
|
||||
spawnAsEntity(worldIn, pos, itemstack);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.harvestBlock(worldIn, player, pos, state, (TileEntity)null);
|
||||
}
|
||||
}
|
||||
|
||||
public Transforms getTransform() {
|
||||
return Transforms.BANNER;
|
||||
}
|
||||
|
||||
public static class BlockBannerHanging extends BlockBanner
|
||||
{
|
||||
public BlockBannerHanging()
|
||||
{
|
||||
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH));
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
Facing enumfacing = (Facing)worldIn.getState(pos).getValue(FACING);
|
||||
float f = 0.0F;
|
||||
float f1 = 0.78125F;
|
||||
float f2 = 0.0F;
|
||||
float f3 = 1.0F;
|
||||
float f4 = 0.125F;
|
||||
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
switch (enumfacing)
|
||||
{
|
||||
case NORTH:
|
||||
default:
|
||||
this.setBlockBounds(f2, f, 1.0F - f4, f3, f1, 1.0F);
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
this.setBlockBounds(f2, f, 0.0F, f3, f1, f4);
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
this.setBlockBounds(1.0F - f4, f, f2, 1.0F, f1, f3);
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
this.setBlockBounds(0.0F, f, f2, f4, f1, f3);
|
||||
}
|
||||
}
|
||||
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
Facing enumfacing = (Facing)state.getValue(FACING);
|
||||
|
||||
if (!worldIn.getState(pos.offset(enumfacing.getOpposite())).getBlock().getMaterial().isSolid())
|
||||
{
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
|
||||
super.onNeighborBlockChange(worldIn, pos, state, neighborBlock);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((Facing)state.getValue(FACING)).getIndex();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {FACING};
|
||||
}
|
||||
}
|
||||
|
||||
public static class BlockBannerStanding extends BlockBanner
|
||||
{
|
||||
public BlockBannerStanding()
|
||||
{
|
||||
this.setDefaultState(this.getBaseState().withProperty(ROTATION, Integer.valueOf(0)));
|
||||
}
|
||||
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
if (!worldIn.getState(pos.down()).getBlock().getMaterial().isSolid())
|
||||
{
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
|
||||
super.onNeighborBlockChange(worldIn, pos, state, neighborBlock);
|
||||
}
|
||||
|
||||
public State getStateFromMeta(int meta)
|
||||
{
|
||||
return this.getState().withProperty(ROTATION, Integer.valueOf(meta));
|
||||
}
|
||||
|
||||
public int getMetaFromState(State state)
|
||||
{
|
||||
return ((Integer)state.getValue(ROTATION)).intValue();
|
||||
}
|
||||
|
||||
protected IProperty[] getProperties()
|
||||
{
|
||||
return new IProperty[] {ROTATION};
|
||||
}
|
||||
}
|
||||
}
|
9
common/src/common/block/BlockBaseFlower.java
Executable file
9
common/src/common/block/BlockBaseFlower.java
Executable file
|
@ -0,0 +1,9 @@
|
|||
package common.block;
|
||||
|
||||
public class BlockBaseFlower extends BlockFlower
|
||||
{
|
||||
public BlockFlower.EnumFlowerColor getBlockType()
|
||||
{
|
||||
return BlockFlower.EnumFlowerColor.BASE;
|
||||
}
|
||||
}
|
267
common/src/common/block/BlockBasePressurePlate.java
Executable file
267
common/src/common/block/BlockBasePressurePlate.java
Executable file
|
@ -0,0 +1,267 @@
|
|||
package common.block;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.init.SoundEvent;
|
||||
import common.item.CheatTab;
|
||||
import common.material.Material;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.BoundingBox;
|
||||
import common.world.Facing;
|
||||
import common.world.IBlockAccess;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public abstract class BlockBasePressurePlate extends Block
|
||||
{
|
||||
public BlockBasePressurePlate(Material p_i46401_1_)
|
||||
{
|
||||
super(p_i46401_1_);
|
||||
this.setTab(CheatTab.tabTech);
|
||||
// this.setTickRandomly(true);
|
||||
}
|
||||
|
||||
public void setBlockBoundsBasedOnState(IWorldAccess worldIn, BlockPos pos)
|
||||
{
|
||||
this.setBlockBoundsBasedOnState0(worldIn.getState(pos));
|
||||
}
|
||||
|
||||
protected void setBlockBoundsBasedOnState0(State state)
|
||||
{
|
||||
boolean flag = this.getRedstoneStrength(state) > 0;
|
||||
float f = 0.0625F;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.03125F, 0.9375F);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.0625F, 0.9375F);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How many world ticks before ticking
|
||||
*/
|
||||
public int tickRate(World worldIn, BlockPos pos)
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
public BoundingBox getCollisionBoundingBox(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if an entity can be spawned inside the block (used to get the player's bed spawn location)
|
||||
*/
|
||||
public boolean canSpawnInBlock()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return this.canBePlacedOn(worldIn, pos.down());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
if (!this.canBePlacedOn(worldIn, pos.down()))
|
||||
{
|
||||
this.dropBlockAsItem(worldIn, pos, state, 0);
|
||||
worldIn.setBlockToAir(pos);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canBePlacedOn(World worldIn, BlockPos pos)
|
||||
{
|
||||
return worldIn.isBlockSolid(pos) || worldIn.getState(pos).getBlock() instanceof BlockFence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called randomly when setTickRandomly is set to true (used by e.g. crops to grow, etc.)
|
||||
*/
|
||||
public void randomTick(WorldServer worldIn, BlockPos pos, State state, Random random)
|
||||
{
|
||||
}
|
||||
|
||||
public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
// if (!worldIn.client)
|
||||
// {
|
||||
int i = this.getRedstoneStrength(state);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
this.updateState(worldIn, pos, state, i);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Called When an Entity Collided with the Block
|
||||
*/
|
||||
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, State state, Entity entityIn)
|
||||
{
|
||||
if (!worldIn.client)
|
||||
{
|
||||
int i = this.getRedstoneStrength(state);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
this.updateState(worldIn, pos, state, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the pressure plate when stepped on
|
||||
*/
|
||||
protected void updateState(World worldIn, BlockPos pos, State state, int oldRedstoneStrength)
|
||||
{
|
||||
int i = this.computeRedstoneStrength(worldIn, pos);
|
||||
boolean flag = oldRedstoneStrength > 0;
|
||||
boolean flag1 = i > 0;
|
||||
|
||||
if (oldRedstoneStrength != i)
|
||||
{
|
||||
state = this.setRedstoneStrength(state, i);
|
||||
worldIn.setState(pos, state, 2);
|
||||
this.updateNeighbors(worldIn, pos);
|
||||
worldIn.markBlockRangeForRenderUpdate(pos, pos);
|
||||
}
|
||||
|
||||
if (!flag1 && flag)
|
||||
{
|
||||
worldIn.playSound(SoundEvent.CLICK, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D, 0.3F);
|
||||
}
|
||||
else if (flag1 && !flag)
|
||||
{
|
||||
worldIn.playSound(SoundEvent.CLICK, (double)pos.getX() + 0.5D, (double)pos.getY() + 0.1D, (double)pos.getZ() + 0.5D, 0.3F);
|
||||
}
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn, pos));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cubic AABB inset by 1/8 on all sides
|
||||
*/
|
||||
protected BoundingBox getSensitiveAABB(BlockPos pos)
|
||||
{
|
||||
float f = 0.125F;
|
||||
return new BoundingBox((double)((float)pos.getX() + 0.125F), (double)pos.getY(), (double)((float)pos.getZ() + 0.125F), (double)((float)(pos.getX() + 1) - 0.125F), (double)pos.getY() + 0.25D, (double)((float)(pos.getZ() + 1) - 0.125F));
|
||||
}
|
||||
|
||||
public void onBlockRemoved(WorldServer worldIn, BlockPos pos, State state)
|
||||
{
|
||||
if (this.getRedstoneStrength(state) > 0)
|
||||
{
|
||||
this.updateNeighbors(worldIn, pos);
|
||||
}
|
||||
|
||||
super.onBlockRemoved(worldIn, pos, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify block and block below of changes
|
||||
*/
|
||||
protected void updateNeighbors(World worldIn, BlockPos pos)
|
||||
{
|
||||
worldIn.notifyNeighborsOfStateChange(pos, this);
|
||||
worldIn.notifyNeighborsOfStateChange(pos.down(), this);
|
||||
}
|
||||
|
||||
public int getWeakPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side)
|
||||
{
|
||||
return this.getRedstoneStrength(state);
|
||||
}
|
||||
|
||||
public int getStrongPower(IWorldAccess worldIn, BlockPos pos, State state, Facing side)
|
||||
{
|
||||
return side == Facing.UP ? this.getRedstoneStrength(state) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this block provide power. Only wire currently seems to have this change based on its state.
|
||||
*/
|
||||
public boolean canProvidePower()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block's bounds for rendering it as an item
|
||||
*/
|
||||
public void setBlockBoundsForItemRender()
|
||||
{
|
||||
float f = 0.5F;
|
||||
float f1 = 0.125F;
|
||||
float f2 = 0.5F;
|
||||
this.setBlockBounds(0.0F, 0.375F, 0.0F, 1.0F, 0.625F, 1.0F);
|
||||
}
|
||||
|
||||
public int getMobilityFlag()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
if(this.getRedstoneStrength(state) > 0)
|
||||
return provider.getModel(this.getTexture())
|
||||
.add(1, 0, 1, 15, 0.5f, 15)
|
||||
.d().uv(1, 1, 15, 15)
|
||||
.u().uv(1, 1, 15, 15).noCull()
|
||||
.n().uv(1, 15.5f, 15, 16).noCull()
|
||||
.s().uv(1, 15.5f, 15, 16).noCull()
|
||||
.w().uv(1, 15.5f, 15, 16).noCull()
|
||||
.e().uv(1, 15.5f, 15, 16).noCull();
|
||||
else
|
||||
return provider.getModel(this.getTexture())
|
||||
.add(1, 0, 1, 15, 1, 15)
|
||||
.d().uv(1, 1, 15, 15)
|
||||
.u().uv(1, 1, 15, 15).noCull()
|
||||
.n().uv(1, 15, 15, 16).noCull()
|
||||
.s().uv(1, 15, 15, 16).noCull()
|
||||
.w().uv(1, 15, 15, 16).noCull()
|
||||
.e().uv(1, 15, 15, 16).noCull();
|
||||
}
|
||||
|
||||
public abstract String getTexture();
|
||||
|
||||
protected abstract int computeRedstoneStrength(World worldIn, BlockPos pos);
|
||||
|
||||
protected abstract int getRedstoneStrength(State state);
|
||||
|
||||
protected abstract State setRedstoneStrength(State state, int strength);
|
||||
}
|
138
common/src/common/block/BlockBeacon.java
Executable file
138
common/src/common/block/BlockBeacon.java
Executable file
|
@ -0,0 +1,138 @@
|
|||
package common.block;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.item.CheatTab;
|
||||
import common.material.Material;
|
||||
import common.model.BlockLayer;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.tileentity.TileEntityBeacon;
|
||||
import common.world.BlockPos;
|
||||
import common.world.Facing;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
|
||||
public class BlockBeacon extends BlockContainer
|
||||
{
|
||||
private static final Model beacon = ModelProvider.getModelProvider().getModel("glass").noOcclude()
|
||||
.add(0, 0, 0, 16, 16, 16)
|
||||
.d().uv(0, 0, 16, 16).noCull()
|
||||
.u().uv(0, 0, 16, 16).noCull()
|
||||
.n().uv(0, 0, 16, 16).noCull()
|
||||
.s().uv(0, 0, 16, 16).noCull()
|
||||
.w().uv(0, 0, 16, 16).noCull()
|
||||
.e().uv(0, 0, 16, 16).noCull()
|
||||
.add(2, 0.1f, 2, 14, 3, 14)
|
||||
.d("obsidian").uv(2, 2, 14, 14).noCull()
|
||||
.u("obsidian").uv(2, 2, 14, 14).noCull()
|
||||
.n("obsidian").uv(2, 13, 14, 16).noCull()
|
||||
.s("obsidian").uv(2, 13, 14, 16).noCull()
|
||||
.w("obsidian").uv(2, 13, 14, 16).noCull()
|
||||
.e("obsidian").uv(2, 13, 14, 16).noCull()
|
||||
.add(3, 3, 3, 13, 14, 13)
|
||||
.d("beacon").uv(3, 3, 13, 13).noCull()
|
||||
.u("beacon").uv(3, 3, 13, 13).noCull()
|
||||
.n("beacon").uv(3, 2, 13, 13).noCull()
|
||||
.s("beacon").uv(3, 2, 13, 13).noCull()
|
||||
.w("beacon").uv(3, 2, 13, 13).noCull()
|
||||
.e("beacon").uv(3, 2, 13, 13).noCull()
|
||||
;
|
||||
|
||||
public BlockBeacon()
|
||||
{
|
||||
super(Material.glass);
|
||||
this.setHardness(3.0F);
|
||||
this.setTab(CheatTab.tabTech);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 TileEntityBeacon();
|
||||
}
|
||||
|
||||
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
if (worldIn.client)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
//
|
||||
// if (tileentity instanceof TileEntityBeacon)
|
||||
// {
|
||||
// playerIn.displayGUIChest((TileEntityBeacon)tileentity);
|
||||
//// playerIn.triggerAchievement(StatRegistry.beaconStat);
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine ambient occlusion and culling when rebuilding chunks for render
|
||||
*/
|
||||
public boolean isOpaqueCube()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFullCube()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by ItemBlocks after a block is set in the world, to allow post-place logic
|
||||
*/
|
||||
// public void onBlockPlacedBy(World worldIn, BlockPos pos, State state, EntityLiving placer, ItemStack stack)
|
||||
// {
|
||||
// super.onBlockPlacedBy(worldIn, pos, state, placer, stack);
|
||||
//
|
||||
// if (stack.hasDisplayName())
|
||||
// {
|
||||
// TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
//
|
||||
// if (tileentity instanceof TileEntityBeacon)
|
||||
// {
|
||||
// ((TileEntityBeacon)tileentity).setName(stack.getDisplayName());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Called when a neighboring block changes.
|
||||
*/
|
||||
public void onNeighborBlockChange(World worldIn, BlockPos pos, State state, Block neighborBlock)
|
||||
{
|
||||
TileEntity tileentity = worldIn.getTileEntity(pos);
|
||||
|
||||
if (tileentity instanceof TileEntityBeacon)
|
||||
{
|
||||
((TileEntityBeacon)tileentity).updateBeacon();
|
||||
// worldIn.addBlockEvent(pos, this, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockLayer getBlockLayer()
|
||||
{
|
||||
return BlockLayer.CUTOUT;
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return beacon;
|
||||
}
|
||||
}
|
207
common/src/common/block/BlockBed.java
Executable file
207
common/src/common/block/BlockBed.java
Executable file
|
@ -0,0 +1,207 @@
|
|||
package common.block;
|
||||
|
||||
import common.color.DyeColor;
|
||||
import common.color.TextColor;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.init.ItemRegistry;
|
||||
import common.item.Item;
|
||||
import common.material.Material;
|
||||
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.Identifyable;
|
||||
import common.world.BlockPos;
|
||||
import common.world.Facing;
|
||||
import common.world.IWorldAccess;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.WorldPos;
|
||||
|
||||
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.cloth);
|
||||
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()));
|
||||
}
|
||||
}
|
22
common/src/common/block/BlockBedrock.java
Executable file
22
common/src/common/block/BlockBedrock.java
Executable file
|
@ -0,0 +1,22 @@
|
|||
package common.block;
|
||||
|
||||
import common.material.Material;
|
||||
import common.model.ParticleType;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.WorldClient;
|
||||
|
||||
public class BlockBedrock extends Block {
|
||||
public BlockBedrock() {
|
||||
super(Material.rock);
|
||||
}
|
||||
|
||||
public void randomDisplayTick(WorldClient worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
if(/* worldIn.canShowVoidParticles() && */ pos.getY() <= 5 && rand.chance(8)) {
|
||||
worldIn.spawnParticle(ParticleType.SUSPENDED_DEPTH, (double)pos.getX() + rand.floatv(), (double)(pos.getY()+1) + (rand.floatv() * 0.5f),
|
||||
(double)pos.getZ() + rand.floatv(), 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
}
|
46
common/src/common/block/BlockBlackenedDirt.java
Normal file
46
common/src/common/block/BlockBlackenedDirt.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package common.block;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.item.CheatTab;
|
||||
import common.material.Material;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public class BlockBlackenedDirt extends Block
|
||||
{
|
||||
public BlockBlackenedDirt()
|
||||
{
|
||||
super(Material.ground);
|
||||
this.setTickRandomly();
|
||||
this.setTab(CheatTab.tabNature);
|
||||
}
|
||||
|
||||
public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
if (Config.darkDirtSpread)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
BlockPos blockpos = pos.add(rand.zrange(3) - 1, rand.zrange(5) - 3, rand.zrange(3) - 1);
|
||||
Block block = worldIn.getState(blockpos.up()).getBlock();
|
||||
State iblockstate = worldIn.getState(blockpos);
|
||||
|
||||
if (iblockstate.getBlock() == Blocks.dirt)
|
||||
{
|
||||
worldIn.setState(blockpos, Blocks.blackened_dirt.getState());
|
||||
}
|
||||
else if (iblockstate.getBlock() == Blocks.grass && worldIn.getLightFromNeighbors(blockpos.up()) >= 2 && block.getLightOpacity() <= 6)
|
||||
{
|
||||
worldIn.setState(blockpos, Blocks.blackened_soil.getState());
|
||||
}
|
||||
else if (iblockstate.getBlock() == Blocks.stone && rand.chance(25))
|
||||
{
|
||||
worldIn.setState(blockpos, Blocks.blackened_stone.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
common/src/common/block/BlockBlackenedSoil.java
Normal file
55
common/src/common/block/BlockBlackenedSoil.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package common.block;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.material.Material;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public class BlockBlackenedSoil extends Block
|
||||
{
|
||||
public BlockBlackenedSoil()
|
||||
{
|
||||
super(Material.grass);
|
||||
this.setTickRandomly();
|
||||
this.setTab(CheatTab.tabNature);
|
||||
}
|
||||
|
||||
public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
if (worldIn.getLightFromNeighbors(pos.up()) < 2 && worldIn.getState(pos.up()).getBlock().getLightOpacity() > 6)
|
||||
{
|
||||
if(Config.darkSoilDecay)
|
||||
worldIn.setState(pos, Blocks.blackened_dirt.getState());
|
||||
}
|
||||
else if (Config.darkSoilSpread && worldIn.getLightFromNeighbors(pos.up()) >= 1)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
BlockPos blockpos = pos.add(rand.zrange(3) - 1, rand.zrange(5) - 3, rand.zrange(3) - 1);
|
||||
Block block = worldIn.getState(blockpos.up()).getBlock();
|
||||
State iblockstate = worldIn.getState(blockpos);
|
||||
|
||||
if ((iblockstate.getBlock() == Blocks.dirt || iblockstate.getBlock() == Blocks.grass || iblockstate.getBlock() == Blocks.blackened_dirt) && worldIn.getLightFromNeighbors(blockpos.up()) >= 2 && block.getLightOpacity() <= 6)
|
||||
{
|
||||
worldIn.setState(blockpos, Blocks.blackened_soil.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Item getItemDropped(State state, Random rand, int fortune)
|
||||
{
|
||||
return Blocks.blackened_dirt.getItemDropped(Blocks.blackened_dirt.getState(), rand, fortune);
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel("blackened_dirt").add().d().u("blackened_soil_top").nswe("blackened_soil_side");
|
||||
}
|
||||
}
|
20
common/src/common/block/BlockBlackenedStone.java
Normal file
20
common/src/common/block/BlockBlackenedStone.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package common.block;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.init.ItemRegistry;
|
||||
import common.item.CheatTab;
|
||||
import common.item.Item;
|
||||
import common.material.Material;
|
||||
import common.rng.Random;
|
||||
import common.world.State;
|
||||
|
||||
public class BlockBlackenedStone extends Block {
|
||||
public BlockBlackenedStone() {
|
||||
super(Material.rock);
|
||||
this.setTab(CheatTab.tabNature);
|
||||
}
|
||||
|
||||
public Item getItemDropped(State state, Random rand, int fortune) {
|
||||
return ItemRegistry.getItemFromBlock(Blocks.blackened_cobble);
|
||||
}
|
||||
}
|
87
common/src/common/block/BlockBlueShroom.java
Executable file
87
common/src/common/block/BlockBlueShroom.java
Executable file
|
@ -0,0 +1,87 @@
|
|||
package common.block;
|
||||
|
||||
import common.init.Blocks;
|
||||
import common.init.Config;
|
||||
import common.model.Model;
|
||||
import common.model.ModelProvider;
|
||||
import common.rng.Random;
|
||||
import common.world.BlockPos;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import common.world.WorldServer;
|
||||
|
||||
public class BlockBlueShroom extends BlockBush
|
||||
{
|
||||
public BlockBlueShroom()
|
||||
{
|
||||
float f = 0.2F;
|
||||
this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f);
|
||||
this.setTickRandomly();
|
||||
}
|
||||
|
||||
public void updateTick(WorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
if (Config.blueShroomGrowth > 0 && rand.chance(Config.blueShroomGrowth))
|
||||
{
|
||||
int i = 5;
|
||||
int j = 4;
|
||||
|
||||
for (BlockPos blockpos : BlockPos.getAllInBoxMutable(pos.add(-4, -1, -4), pos.add(4, 1, 4)))
|
||||
{
|
||||
if (worldIn.getState(blockpos).getBlock() == this)
|
||||
{
|
||||
--i;
|
||||
|
||||
if (i <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BlockPos blockpos1 = pos.add(rand.zrange(3) - 1, rand.zrange(2) - rand.zrange(2), rand.zrange(3) - 1);
|
||||
|
||||
for (int k = 0; k < 4; ++k)
|
||||
{
|
||||
if (worldIn.isAirBlock(blockpos1) && this.canBlockStay(worldIn, blockpos1, this.getState()))
|
||||
{
|
||||
pos = blockpos1;
|
||||
}
|
||||
|
||||
blockpos1 = pos.add(rand.zrange(3) - 1, rand.zrange(2) - rand.zrange(2), rand.zrange(3) - 1);
|
||||
}
|
||||
|
||||
if (worldIn.isAirBlock(blockpos1) && this.canBlockStay(worldIn, blockpos1, this.getState()))
|
||||
{
|
||||
worldIn.setState(blockpos1, this.getState(), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
|
||||
{
|
||||
return super.canPlaceBlockAt(worldIn, pos) && this.canBlockStay(worldIn, pos, this.getState());
|
||||
}
|
||||
|
||||
protected boolean canPlaceBlockOn(Block ground)
|
||||
{
|
||||
return ground.isFullBlock();
|
||||
}
|
||||
|
||||
public boolean canBlockStay(World worldIn, BlockPos pos, State state)
|
||||
{
|
||||
if (pos.getY() >= 0 && pos.getY() < 512)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos.down());
|
||||
return (iblockstate.getBlock() == Blocks.tian_soil || iblockstate.getBlock() == Blocks.obsidian) ? true : (worldIn.getLight(pos) < 13 && this.canPlaceBlockOn(iblockstate.getBlock()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Model getModel(ModelProvider provider, String name, State state) {
|
||||
return provider.getModel("blue_mushroom").cross();
|
||||
}
|
||||
}
|
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