Add wasp
This commit is contained in:
parent
81b5e3032e
commit
51337af9f9
|
@ -16,7 +16,6 @@ import net.minecraft.block.properties.IProperty;
|
||||||
import net.minecraft.block.properties.PropertyEnum;
|
import net.minecraft.block.properties.PropertyEnum;
|
||||||
import net.minecraft.block.state.BlockState;
|
import net.minecraft.block.state.BlockState;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.passive.EntityChicken;
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemBlock;
|
import net.minecraft.item.ItemBlock;
|
||||||
import net.minecraft.util.BlockPos;
|
import net.minecraft.util.BlockPos;
|
||||||
|
@ -24,6 +23,7 @@ import net.minecraft.util.IStringSerializable;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import biomesoplenty.api.block.IBOPBlock;
|
import biomesoplenty.api.block.IBOPBlock;
|
||||||
import biomesoplenty.api.item.BOPItems;
|
import biomesoplenty.api.item.BOPItems;
|
||||||
|
import biomesoplenty.common.entities.EntityWasp;
|
||||||
import biomesoplenty.common.item.ItemBOPBlock;
|
import biomesoplenty.common.item.ItemBOPBlock;
|
||||||
|
|
||||||
public class BlockHive extends Block implements IBOPBlock
|
public class BlockHive extends Block implements IBOPBlock
|
||||||
|
@ -145,8 +145,7 @@ public class BlockHive extends Block implements IBOPBlock
|
||||||
switch ((HiveType) state.getValue(VARIANT))
|
switch ((HiveType) state.getValue(VARIANT))
|
||||||
{
|
{
|
||||||
case EMPTY_HONEYCOMB:
|
case EMPTY_HONEYCOMB:
|
||||||
// TODO: EntityWasp wasp = new EntityWasp(worldIn);
|
EntityWasp wasp = new EntityWasp(worldIn);
|
||||||
EntityChicken wasp = new EntityChicken(worldIn);
|
|
||||||
wasp.setLocationAndAngles((double)pos.getX() + 0.6D, (double)pos.getY(), (double)pos.getZ() + 0.3D, 0.0F, 0.0F);
|
wasp.setLocationAndAngles((double)pos.getX() + 0.6D, (double)pos.getY(), (double)pos.getZ() + 0.3D, 0.0F, 0.0F);
|
||||||
worldIn.spawnEntityInWorld(wasp);
|
worldIn.spawnEntityInWorld(wasp);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,379 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2015, the Biomes O' Plenty Team
|
||||||
|
*
|
||||||
|
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
|
||||||
|
*
|
||||||
|
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
package biomesoplenty.common.entities;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityFlying;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.SharedMonsterAttributes;
|
||||||
|
import net.minecraft.entity.ai.EntityAIBase;
|
||||||
|
import net.minecraft.entity.ai.EntityAIFindEntityNearestPlayer;
|
||||||
|
import net.minecraft.entity.ai.EntityMoveHelper;
|
||||||
|
import net.minecraft.entity.monster.IMob;
|
||||||
|
import net.minecraft.util.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class EntityWasp extends EntityFlying implements IMob {
|
||||||
|
|
||||||
|
public EntityWasp(World worldIn) {
|
||||||
|
super(worldIn);
|
||||||
|
this.setSize(0.7F, 0.7F);
|
||||||
|
|
||||||
|
this.moveHelper = new EntityWasp.WaspMoveHelper();
|
||||||
|
this.tasks.addTask(3, new EntityWasp.AIWaspRandomFly());
|
||||||
|
this.tasks.addTask(4, new EntityWasp.AIWaspAttackTarget());
|
||||||
|
this.targetTasks.addTask(1, new EntityAIFindEntityNearestPlayer(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyEntityAttributes()
|
||||||
|
{
|
||||||
|
super.applyEntityAttributes();
|
||||||
|
this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(2.5D);
|
||||||
|
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D);
|
||||||
|
this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(10.0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attackEntityAsMob(Entity target)
|
||||||
|
{
|
||||||
|
float f = (float)this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue();
|
||||||
|
return target.attackEntityFrom(DamageSource.causeMobDamage(this), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: sounds don't work yet - need to register them somewhere first I think
|
||||||
|
@Override
|
||||||
|
protected String getLivingSound()
|
||||||
|
{
|
||||||
|
return "biomesoplenty:mob.wasp.say";
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected String getHurtSound()
|
||||||
|
{
|
||||||
|
return "biomesoplenty:mob.wasp.hurt";
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected String getDeathSound()
|
||||||
|
{
|
||||||
|
return "biomesoplenty:mob.wasp.hurt";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper class representing a point in space that the wasp is targeting for some reason
|
||||||
|
class WaspMoveTargetPos
|
||||||
|
{
|
||||||
|
private EntityWasp wasp = EntityWasp.this;
|
||||||
|
|
||||||
|
public double posX;
|
||||||
|
public double posY;
|
||||||
|
public double posZ;
|
||||||
|
public double distX;
|
||||||
|
public double distY;
|
||||||
|
public double distZ;
|
||||||
|
public double dist;
|
||||||
|
public double aimX;
|
||||||
|
public double aimY;
|
||||||
|
public double aimZ;
|
||||||
|
|
||||||
|
public WaspMoveTargetPos()
|
||||||
|
{
|
||||||
|
this(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WaspMoveTargetPos(double posX, double posY, double posZ)
|
||||||
|
{
|
||||||
|
this.setTarget(posX, posY, posZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(double posX, double posY, double posZ)
|
||||||
|
{
|
||||||
|
this.posX = posX;
|
||||||
|
this.posY = posY;
|
||||||
|
this.posZ = posZ;
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh()
|
||||||
|
{
|
||||||
|
this.distX = this.posX - this.wasp.posX;
|
||||||
|
this.distY = this.posY - this.wasp.posY;
|
||||||
|
this.distZ = this.posZ - this.wasp.posZ;
|
||||||
|
|
||||||
|
this.dist = (double)MathHelper.sqrt_double(this.distX * this.distX + this.distY * this.distY + this.distZ * this.distZ);
|
||||||
|
|
||||||
|
// (aimX,aimY,aimZ) is a unit vector in the direction we want to go
|
||||||
|
if (this.dist == 0.0D)
|
||||||
|
{
|
||||||
|
this.aimX = 0.0D;
|
||||||
|
this.aimY = 0.0D;
|
||||||
|
this.aimZ = 0.0D;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.aimX = this.distX / this.dist;
|
||||||
|
this.aimY = this.distY / this.dist;
|
||||||
|
this.aimZ = this.distZ / this.dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBoxBlocked(AxisAlignedBB box)
|
||||||
|
{
|
||||||
|
return !this.wasp.worldObj.getCollidingBoundingBoxes(this.wasp, box).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check nothing will collide with the wasp in the direction of aim, for howFar units (or until the destination - whichever is closer)
|
||||||
|
public boolean isPathClear(double howFar)
|
||||||
|
{
|
||||||
|
howFar = Math.min(howFar, this.dist);
|
||||||
|
AxisAlignedBB box = this.wasp.getEntityBoundingBox();
|
||||||
|
for (double i = 0.5D; i < howFar; ++i)
|
||||||
|
{
|
||||||
|
// check there's nothing in the way
|
||||||
|
if (this.isBoxBlocked(box.offset(this.aimX * i, this.aimY * i, this.aimZ * i)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.isBoxBlocked(box.offset(this.aimX * howFar, this.aimY * howFar, this.aimZ * howFar)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class WaspMoveHelper extends EntityMoveHelper
|
||||||
|
{
|
||||||
|
// EntityMoveHelper has the boolean 'update' which is set to true when the target is changed, and set to false when a bearing is set
|
||||||
|
// So it means 'the target has changed but we're not yet heading for it'
|
||||||
|
// We'll re-use it here with a slightly different interpretation
|
||||||
|
// Here it will mean 'has a target and not yet arrived'
|
||||||
|
|
||||||
|
private EntityWasp wasp = EntityWasp.this;
|
||||||
|
private int courseChangeCooldown = 0;
|
||||||
|
private double closeEnough = 0.3D;
|
||||||
|
private WaspMoveTargetPos targetPos = new WaspMoveTargetPos();
|
||||||
|
|
||||||
|
public WaspMoveHelper()
|
||||||
|
{
|
||||||
|
super(EntityWasp.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMoveTo(double x, double y, double z, double speedIn)
|
||||||
|
{
|
||||||
|
super.setMoveTo(x,y,z,speedIn);
|
||||||
|
this.targetPos.setTarget(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdateMoveHelper()
|
||||||
|
{
|
||||||
|
// if we have arrived at the previous target, or we have no target to aim for, do nothing
|
||||||
|
if (!this.update) {return;}
|
||||||
|
|
||||||
|
if (this.courseChangeCooldown-- > 0) {
|
||||||
|
// limit the rate at which we change course
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.courseChangeCooldown += this.wasp.getRNG().nextInt(5) + 2;
|
||||||
|
|
||||||
|
// update the target position
|
||||||
|
this.targetPos.refresh();
|
||||||
|
|
||||||
|
// accelerate the wasp towards the target
|
||||||
|
double acceleration = 0.1D;
|
||||||
|
this.wasp.motionX += this.targetPos.aimX * acceleration;
|
||||||
|
this.wasp.motionY += this.targetPos.aimY * acceleration;
|
||||||
|
this.wasp.motionZ += this.targetPos.aimZ * acceleration;
|
||||||
|
|
||||||
|
// rotate to point at target
|
||||||
|
this.wasp.renderYawOffset = this.wasp.rotationYaw = -((float)Math.atan2(this.targetPos.distX, this.targetPos.distZ)) * 180.0F / (float)Math.PI;
|
||||||
|
|
||||||
|
// occasionally jerk to the side - makes them more difficult to hit
|
||||||
|
if (this.wasp.getRNG().nextInt(5)==0)
|
||||||
|
{
|
||||||
|
float strafeAmount = (this.wasp.getRNG().nextFloat() * 0.4F) - 0.2F;
|
||||||
|
this.wasp.motionX += (double)(strafeAmount * MathHelper.cos(this.wasp.rotationYaw * (float)Math.PI / 180.0F));
|
||||||
|
this.wasp.motionZ += (double)(strafeAmount * MathHelper.sin(this.wasp.rotationYaw * (float)Math.PI / 180.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
// abandon this movement if we have reached the target or there is no longer a clear path to the target
|
||||||
|
if (!this.targetPos.isPathClear(5.0D))
|
||||||
|
{
|
||||||
|
//System.out.println("Abandoning move target - way is blocked" );
|
||||||
|
this.update = false;
|
||||||
|
} else if (this.targetPos.dist < this.closeEnough) {
|
||||||
|
//System.out.println("Arrived (close enough) dist:"+this.targetPos.dist);
|
||||||
|
this.update = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// AI class for implementing the random flying behaviour
|
||||||
|
class AIWaspRandomFly extends EntityAIBase
|
||||||
|
{
|
||||||
|
private EntityWasp wasp = EntityWasp.this;
|
||||||
|
private WaspMoveTargetPos targetPos = new WaspMoveTargetPos();
|
||||||
|
|
||||||
|
public AIWaspRandomFly()
|
||||||
|
{
|
||||||
|
this.setMutexBits(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should we choose a new random destination for the wasp to fly to?
|
||||||
|
// yes, if the wasp doesn't already have a destination
|
||||||
|
@Override
|
||||||
|
public boolean shouldExecute()
|
||||||
|
{
|
||||||
|
//System.out.println(this.wasp.getMoveHelper().isUpdating()?"has a move target":"no move target");
|
||||||
|
return !this.wasp.getMoveHelper().isUpdating();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean continueExecuting() {return false;}
|
||||||
|
|
||||||
|
// choose a a new random destination for the wasp to fly to
|
||||||
|
@Override
|
||||||
|
public void startExecuting()
|
||||||
|
{
|
||||||
|
Random rand = this.wasp.getRNG();
|
||||||
|
// pick a random nearby point and see if we can fly to it
|
||||||
|
if (this.tryGoingRandomDirection(rand, 6.0D)) {return;}
|
||||||
|
// pick a random closer point to fly to instead
|
||||||
|
if (this.tryGoingRandomDirection(rand, 2.0D)) {return;}
|
||||||
|
// try going straight along axes (try all 6 directions in random order)
|
||||||
|
List<EnumFacing> directions = Arrays.asList(EnumFacing.values());
|
||||||
|
Collections.shuffle(directions);
|
||||||
|
for (EnumFacing facing : directions)
|
||||||
|
{
|
||||||
|
if (this.tryGoingAlongAxis(rand, facing, 1.0D)) {return;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// note y direction has a slight downward bias to stop them flying too high
|
||||||
|
public boolean tryGoingRandomDirection(Random rand, double maxDistance)
|
||||||
|
{
|
||||||
|
double dirX = ((rand.nextDouble() * 2.0D - 1.0D) * maxDistance);
|
||||||
|
double dirY = ((rand.nextDouble() * 2.0D - 1.1D) * maxDistance);
|
||||||
|
double dirZ = ((rand.nextDouble() * 2.0D - 1.0D) * maxDistance);
|
||||||
|
return this.tryGoing(dirX, dirY, dirZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean tryGoingAlongAxis(Random rand, EnumFacing facing, double maxDistance)
|
||||||
|
{
|
||||||
|
double dirX = 0.0D;
|
||||||
|
double dirY = 0.0D;
|
||||||
|
double dirZ = 0.0D;
|
||||||
|
switch (facing.getAxis())
|
||||||
|
{
|
||||||
|
case X:
|
||||||
|
dirX = rand.nextDouble() * facing.getAxisDirection().getOffset() * maxDistance;
|
||||||
|
break;
|
||||||
|
case Y:
|
||||||
|
dirY = rand.nextDouble() * facing.getAxisDirection().getOffset() * maxDistance;
|
||||||
|
break;
|
||||||
|
case Z: default:
|
||||||
|
dirZ = rand.nextDouble() * facing.getAxisDirection().getOffset() * maxDistance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return this.tryGoing(dirX, dirY, dirZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean tryGoing(double dirX, double dirY, double dirZ)
|
||||||
|
{
|
||||||
|
//System.out.println("("+dirX+","+dirY+","+dirZ+")");
|
||||||
|
this.targetPos.setTarget(this.wasp.posX + dirX, this.wasp.posY + dirY, this.wasp.posZ + dirZ);
|
||||||
|
//System.out.println("Testing random move target distance:"+this.targetPos.dist+" direction:("+this.targetPos.aimX+","+this.targetPos.aimY+","+this.targetPos.aimZ+")");
|
||||||
|
boolean result = this.targetPos.isPathClear(5.0F);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
this.wasp.getMoveHelper().setMoveTo(this.targetPos.posX, this.targetPos.posY, this.targetPos.posZ, 1.0D);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// AI class for implementing the behaviour to target and attack players
|
||||||
|
class AIWaspAttackTarget extends EntityAIBase
|
||||||
|
{
|
||||||
|
private EntityWasp wasp = EntityWasp.this;
|
||||||
|
private int attackTick = 0;
|
||||||
|
private WaspMoveTargetPos targetPos = new WaspMoveTargetPos();
|
||||||
|
|
||||||
|
public AIWaspAttackTarget()
|
||||||
|
{
|
||||||
|
this.setMutexBits(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean attackTargetExists()
|
||||||
|
{
|
||||||
|
// see if there's actually a living attack target to aim for
|
||||||
|
EntityLivingBase attackTarget = this.wasp.getAttackTarget();
|
||||||
|
return (attackTarget != null && attackTarget.isEntityAlive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldExecute()
|
||||||
|
{
|
||||||
|
// decrement time since last attack
|
||||||
|
if (this.attackTick > 0) {--this.attackTick;}
|
||||||
|
|
||||||
|
return this.attackTargetExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean continueExecuting()
|
||||||
|
{
|
||||||
|
// decrement time since last attack
|
||||||
|
if (this.attackTick > 0) {--this.attackTick;}
|
||||||
|
|
||||||
|
if (!this.attackTargetExists()) {return false;}
|
||||||
|
|
||||||
|
// focus attack on target position
|
||||||
|
EntityLivingBase attackTarget = this.wasp.getAttackTarget();
|
||||||
|
this.targetPos.setTarget(attackTarget.posX, attackTarget.posY, attackTarget.posZ);
|
||||||
|
|
||||||
|
// give up if the target is too far away
|
||||||
|
// double followRange = this.wasp.getEntityAttribute(SharedMonsterAttributes.followRange).getAttributeValue();
|
||||||
|
|
||||||
|
// damage the target if it's in range, and it has been long enough since the last attack
|
||||||
|
double damageRange = (double)(this.wasp.width + attackTarget.width);
|
||||||
|
if (this.attackTick <= 0 && this.targetPos.dist < damageRange)
|
||||||
|
{
|
||||||
|
this.wasp.attackEntityAsMob(attackTarget);
|
||||||
|
this.attackTick = 16; // 16 ticks before next attack
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if there's a straight path to the target, if there is, aim for it
|
||||||
|
if (this.targetPos.isPathClear(5.0D))
|
||||||
|
{
|
||||||
|
//System.out.println("Setting attack target");
|
||||||
|
this.wasp.getMoveHelper().setMoveTo(attackTarget.posX, attackTarget.posY, attackTarget.posZ, 1.0D);
|
||||||
|
}
|
||||||
|
//System.out.println("dist:"+this.targetPos.dist+" damageRange:"+damageRange+" attackTick:"+attackTick);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2015, the Biomes O' Plenty Team
|
||||||
|
*
|
||||||
|
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
|
||||||
|
*
|
||||||
|
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
package biomesoplenty.common.entities;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.ModelBase;
|
||||||
|
import net.minecraft.client.model.ModelRenderer;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.MathHelper;
|
||||||
|
|
||||||
|
public class ModelWasp extends ModelBase
|
||||||
|
{
|
||||||
|
//fields
|
||||||
|
|
||||||
|
/*Head*/
|
||||||
|
ModelRenderer Head;
|
||||||
|
ModelRenderer Right_Antenna;
|
||||||
|
ModelRenderer Left_Antenna;
|
||||||
|
ModelRenderer Nose;
|
||||||
|
|
||||||
|
/*Wings*/
|
||||||
|
ModelRenderer Left_Wing;
|
||||||
|
ModelRenderer Right_Wing;
|
||||||
|
|
||||||
|
/*Body*/
|
||||||
|
ModelRenderer Thorax;
|
||||||
|
ModelRenderer Left_Leg_Back;
|
||||||
|
ModelRenderer Left_Leg_Middle;
|
||||||
|
ModelRenderer Left_Leg_Front;
|
||||||
|
ModelRenderer Right_Leg_Back;
|
||||||
|
ModelRenderer Right_Leg_Middle;
|
||||||
|
ModelRenderer Right_Leg_Front;
|
||||||
|
|
||||||
|
/*Stinger*/
|
||||||
|
ModelRenderer Abdomen;
|
||||||
|
ModelRenderer Stinger;
|
||||||
|
|
||||||
|
public ModelWasp()
|
||||||
|
{
|
||||||
|
textureWidth = 64;
|
||||||
|
textureHeight = 32;
|
||||||
|
|
||||||
|
/*Head*/
|
||||||
|
Head = new ModelRenderer(this, 46, 0);
|
||||||
|
Head.addBox(0F, 0F, 0F, 5, 5, 4);
|
||||||
|
Head.setRotationPoint(0F, -2F, 8F);
|
||||||
|
Head.setTextureSize(64, 32);
|
||||||
|
|
||||||
|
Right_Antenna = new ModelRenderer(this, 54, 27);
|
||||||
|
Right_Antenna.addBox(0F, 2F, -8F, 1, 1, 4);
|
||||||
|
Right_Antenna.setRotationPoint(3F, -3F, 10F);
|
||||||
|
Right_Antenna.setTextureSize(64, 32);
|
||||||
|
Right_Antenna.mirror = true;
|
||||||
|
Head.addChild(Right_Antenna);
|
||||||
|
|
||||||
|
Left_Antenna = new ModelRenderer(this, 54, 27);
|
||||||
|
Left_Antenna.addBox(0F, 2F, -8F, 1, 1, 4);
|
||||||
|
Left_Antenna.setRotationPoint(1F, -3F, 10F);
|
||||||
|
Left_Antenna.setTextureSize(64, 32);
|
||||||
|
Left_Antenna.mirror = true;
|
||||||
|
Head.addChild(Left_Antenna);
|
||||||
|
|
||||||
|
Nose = new ModelRenderer(this, 54, 9);
|
||||||
|
Nose.addBox(0F, 2F, -8F, 3, 4, 2);
|
||||||
|
Nose.setRotationPoint(1F, 0F, 11F);
|
||||||
|
Nose.setTextureSize(64, 32);
|
||||||
|
Nose.mirror = true;
|
||||||
|
Head.addChild(Nose);
|
||||||
|
|
||||||
|
/*Wings*/
|
||||||
|
Left_Wing = new ModelRenderer(this, 24, 26);
|
||||||
|
Left_Wing.addBox(-7F, 0F, 0F, 8, 1, 5);
|
||||||
|
Left_Wing.setRotationPoint(0F, -1F, 2F);
|
||||||
|
Left_Wing.setTextureSize(64, 32);
|
||||||
|
|
||||||
|
Right_Wing = new ModelRenderer(this, 24, 20);
|
||||||
|
Right_Wing.addBox(0F, 0F, 0F, 8, 1, 5);
|
||||||
|
Right_Wing.setRotationPoint(4F, -1F, 2F);
|
||||||
|
Right_Wing.setTextureSize(64, 32);
|
||||||
|
|
||||||
|
/*Body*/
|
||||||
|
Thorax = new ModelRenderer(this, 0, 0);
|
||||||
|
Thorax.addBox(0F, 0F, 0F, 5, 5, 8);
|
||||||
|
Thorax.setRotationPoint(0F, 0F, 0F);
|
||||||
|
Thorax.setTextureSize(64, 32);
|
||||||
|
|
||||||
|
Left_Leg_Back = new ModelRenderer(this, 13, 23);
|
||||||
|
Left_Leg_Back.addBox(0F, 0F, 0F, 1, 4, 1);
|
||||||
|
Left_Leg_Back.setRotationPoint(-1F, 4F, 1F);
|
||||||
|
Left_Leg_Back.setTextureSize(64, 32);
|
||||||
|
Thorax.addChild(Left_Leg_Back);
|
||||||
|
|
||||||
|
Left_Leg_Middle = new ModelRenderer(this, 13, 23);
|
||||||
|
Left_Leg_Middle.addBox(0F, 0F, 0F, 1, 3, 1);
|
||||||
|
Left_Leg_Middle.setRotationPoint(-1F, 4F, 4F);
|
||||||
|
Left_Leg_Middle.setTextureSize(64, 32);
|
||||||
|
Thorax.addChild(Left_Leg_Middle);
|
||||||
|
|
||||||
|
Left_Leg_Front = new ModelRenderer(this, 13, 23);
|
||||||
|
Left_Leg_Front.addBox(0F, 0F, 0F, 1, 4, 1);
|
||||||
|
Left_Leg_Front.setRotationPoint(-1F, 4F, 6F);
|
||||||
|
Left_Leg_Front.setTextureSize(64, 32);
|
||||||
|
Thorax.addChild(Left_Leg_Front);
|
||||||
|
|
||||||
|
Right_Leg_Back = new ModelRenderer(this, 13, 23);
|
||||||
|
Right_Leg_Back.addBox(0F, 0F, 0F, 1, 4, 1);
|
||||||
|
Right_Leg_Back.setRotationPoint(5F, 4F, 1F);
|
||||||
|
Right_Leg_Back.setTextureSize(64, 32);
|
||||||
|
Thorax.addChild(Right_Leg_Back);
|
||||||
|
|
||||||
|
Right_Leg_Middle = new ModelRenderer(this, 13, 23);
|
||||||
|
Right_Leg_Middle.addBox(0F, 0F, 0F, 1, 3, 1);
|
||||||
|
Right_Leg_Middle.setRotationPoint(5F, 4F, 4F);
|
||||||
|
Right_Leg_Middle.setTextureSize(64, 32);
|
||||||
|
Thorax.addChild(Right_Leg_Middle);
|
||||||
|
|
||||||
|
Right_Leg_Front = new ModelRenderer(this, 13, 23);
|
||||||
|
Right_Leg_Front.addBox(0F, 0F, 0F, 1, 4, 1);
|
||||||
|
Right_Leg_Front.setRotationPoint(5F, 4F, 6F);
|
||||||
|
Right_Leg_Front.setTextureSize(64, 32);
|
||||||
|
Thorax.addChild(Right_Leg_Front);
|
||||||
|
|
||||||
|
/*Stinger*/
|
||||||
|
Abdomen = new ModelRenderer(this, 0, 13);
|
||||||
|
Abdomen.addBox(0F, 0F, 0F, 3, 3, 2);
|
||||||
|
Abdomen.setRotationPoint(1F, 2F, -2F);
|
||||||
|
Abdomen.setTextureSize(64, 32);
|
||||||
|
|
||||||
|
Stinger = new ModelRenderer(this, 0, 18);
|
||||||
|
Stinger.addBox(-1F, -3F, 2F, 1, 1, 3);
|
||||||
|
Stinger.setRotationPoint(2F, 4F, -5F);
|
||||||
|
Stinger.setTextureSize(64, 32);
|
||||||
|
Abdomen.addChild(Stinger);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)
|
||||||
|
{
|
||||||
|
this.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
|
||||||
|
|
||||||
|
/*Head*/
|
||||||
|
Head.render(f5);
|
||||||
|
|
||||||
|
/*Wings*/
|
||||||
|
Left_Wing.render(f5);
|
||||||
|
Right_Wing.render(f5);
|
||||||
|
|
||||||
|
/*Body*/
|
||||||
|
Thorax.render(f5);
|
||||||
|
|
||||||
|
/*float nosespeed = 0.5F * (float)(entity.entityId % 10);
|
||||||
|
Nose.rotateAngleX = MathHelper.sin((float)entity.ticksExisted * nosespeed) * 2.5F * (float)Math.PI / 180.0F;
|
||||||
|
Nose.rotateAngleY = 0.0F;
|
||||||
|
Nose.rotateAngleZ = MathHelper.cos((float)entity.ticksExisted * nosespeed) * 1.5F * (float)Math.PI / 180.0F;*/
|
||||||
|
|
||||||
|
/*Stinger*/
|
||||||
|
Abdomen.render(f5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity)
|
||||||
|
{
|
||||||
|
super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
|
||||||
|
|
||||||
|
float headspeed = 0.1F * (float)(entity.ticksExisted % 10);
|
||||||
|
Head.rotateAngleX = MathHelper.sin(f2 * headspeed) * 2.5F * (float)Math.PI / 180.0F;
|
||||||
|
Head.rotateAngleZ = MathHelper.cos(f2 * headspeed) * 1.5F * (float)Math.PI / 180.0F;
|
||||||
|
|
||||||
|
float thoraxspeed = 0.075F * (float)(entity.ticksExisted % 10);
|
||||||
|
Thorax.rotateAngleX = MathHelper.sin(f2 * thoraxspeed) * 2.5F * (float)Math.PI / 180.0F;
|
||||||
|
Thorax.rotateAngleZ = MathHelper.cos(f2 * thoraxspeed) * 1.5F * (float)Math.PI / 180.0F;
|
||||||
|
|
||||||
|
Right_Wing.rotateAngleY = MathHelper.cos(f2 * 1.7F) * (float)Math.PI * 0.25F;
|
||||||
|
Left_Wing.rotateAngleY = -Right_Wing.rotateAngleY;
|
||||||
|
Right_Wing.rotateAngleZ = Right_Wing.rotateAngleY;
|
||||||
|
Left_Wing.rotateAngleZ = -Right_Wing.rotateAngleY;
|
||||||
|
|
||||||
|
float abdomenspeed = 0.6F * (float)(entity.ticksExisted % 10);
|
||||||
|
Abdomen.rotateAngleX = MathHelper.sin(f2 * abdomenspeed) * 2.5F * (float)Math.PI / 180.0F;
|
||||||
|
Abdomen.rotateAngleZ = MathHelper.cos(f2 * abdomenspeed) * 1.5F * (float)Math.PI / 180.0F;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2015, the Biomes O' Plenty Team
|
||||||
|
*
|
||||||
|
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
|
||||||
|
*
|
||||||
|
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
package biomesoplenty.common.entities;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public class RenderWasp extends RenderLiving
|
||||||
|
{
|
||||||
|
private static final ResourceLocation waspTextureLocation = new ResourceLocation("biomesoplenty:textures/entity/wasp.png");
|
||||||
|
|
||||||
|
public RenderWasp(RenderManager renderManager)
|
||||||
|
{
|
||||||
|
super(renderManager, new ModelWasp(), 0.5F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void preRenderCallback(EntityLivingBase entity, float partialTickTime)
|
||||||
|
{
|
||||||
|
GL11.glRotatef(180F, 0.0F, 1.0F, 0.0F);
|
||||||
|
GL11.glTranslatef(0.0F, 0.75F, 0.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ResourceLocation getEntityTexture(Entity entity)
|
||||||
|
{
|
||||||
|
return waspTextureLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
package biomesoplenty.common.init;
|
package biomesoplenty.common.init;
|
||||||
|
|
||||||
|
import biomesoplenty.common.entities.EntityWasp;
|
||||||
import biomesoplenty.common.entities.projectiles.EntityDart;
|
import biomesoplenty.common.entities.projectiles.EntityDart;
|
||||||
import biomesoplenty.core.BiomesOPlenty;
|
import biomesoplenty.core.BiomesOPlenty;
|
||||||
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
||||||
|
@ -21,6 +22,8 @@ public class ModEntities
|
||||||
// TODO: how to set id?
|
// TODO: how to set id?
|
||||||
EntityRegistry.registerModEntity(EntityDart.class, "dart", 26, BiomesOPlenty.instance, 80, 3, true);
|
EntityRegistry.registerModEntity(EntityDart.class, "dart", 26, BiomesOPlenty.instance, 80, 3, true);
|
||||||
|
|
||||||
|
EntityRegistry.registerModEntity(EntityWasp.class, "wasp", 27, BiomesOPlenty.instance, 80, 3, true);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,6 +22,8 @@ import net.minecraftforge.client.model.ModelLoader;
|
||||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||||
import biomesoplenty.api.block.IBOPBlock;
|
import biomesoplenty.api.block.IBOPBlock;
|
||||||
import biomesoplenty.common.config.MiscConfigurationHandler;
|
import biomesoplenty.common.config.MiscConfigurationHandler;
|
||||||
|
import biomesoplenty.common.entities.EntityWasp;
|
||||||
|
import biomesoplenty.common.entities.RenderWasp;
|
||||||
import biomesoplenty.common.entities.projectiles.EntityDart;
|
import biomesoplenty.common.entities.projectiles.EntityDart;
|
||||||
import biomesoplenty.common.entities.projectiles.RenderDart;
|
import biomesoplenty.common.entities.projectiles.RenderDart;
|
||||||
|
|
||||||
|
@ -40,6 +42,8 @@ public class ClientProxy extends CommonProxy
|
||||||
|
|
||||||
//Entity rendering and other stuff will go here in future
|
//Entity rendering and other stuff will go here in future
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityDart.class, new RenderDart(minecraft.getRenderManager()));
|
RenderingRegistry.registerEntityRenderingHandler(EntityDart.class, new RenderDart(minecraft.getRenderManager()));
|
||||||
|
RenderingRegistry.registerEntityRenderingHandler(EntityWasp.class, new RenderWasp(minecraft.getRenderManager()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in New Issue