package mhfc.net.common.ai.entity.boss.nargacuga;
import mhfc.net.common.ai.IExecutableAction;
import mhfc.net.common.ai.general.AIUtils;
import mhfc.net.common.ai.general.AIUtils.IDamageCalculator;
import mhfc.net.common.ai.general.actions.AIGeneralJumpAttack;
import mhfc.net.common.ai.general.actions.IJumpTimingProvider;
import mhfc.net.common.ai.general.provider.simple.IJumpParamterProvider;
import mhfc.net.common.ai.general.provider.simple.IJumpParamterProvider.ConstantAirTimeAdapter.ITargetResolver;
import mhfc.net.common.ai.general.provider.simple.ISelectionPredicate;
import mhfc.net.common.entity.monster.EntityNargacuga;
import mhfc.net.common.entity.projectile.EntityProjectileBlock;
import net.minecraft.entity.Entity;
import net.minecraft.util.Vec3;
public class TailSlam extends AIGeneralJumpAttack<EntityNargacuga> {
private static final String ANIMATION = "mhfc:models/Nargacuga/TailSlam.mcanm";
private static final int ANIM_LENGTH = 100;
private static final int MAX_ANGLE = 20;
private static final float MAX_DISTANCE = 8;
private static final float WEIGHT = 20;
private static final int JUMP_FRAME = 19;
private static final int JUMP_TIME = 12;
private static final int SPIKE_FRAME = 50;
private static final float SPEED = 1.4f;
private static final ISelectionPredicate<EntityNargacuga> select;
private static final IDamageCalculator damageCalculator;
private static final IJumpTimingProvider<EntityNargacuga> timing;
private static final IJumpParamterProvider<EntityNargacuga> jumpParams;
static {
select = new ISelectionPredicate.SelectionAdapter<>(-MAX_ANGLE, MAX_ANGLE, 0, MAX_DISTANCE);
damageCalculator = AIUtils.defaultDamageCalc(280, 500, 888880);
jumpParams = new IJumpParamterProvider.ConstantAirTimeAdapter<>(
JUMP_TIME,
new ITargetResolver<EntityNargacuga>() {
@Override
public Vec3 getJumpTarget(EntityNargacuga entity) {
return entity.getLookVec().addVector(entity.posX, entity.posY, entity.posZ);
}
});
timing = new IJumpTimingProvider.JumpTimingAdapter<EntityNargacuga>(JUMP_FRAME, 0, 0);
}
public TailSlam() {}
@Override
protected void finishExecution() {
super.finishExecution();
EntityNargacuga nargacuga = getEntity();
nargacuga.rotationYaw = AIUtils.normalizeAngle(nargacuga.rotationYaw + 180);
nargacuga.addVelocity(10e-4, 0, 10e-4);
}
@Override
public void update() {
EntityNargacuga nargacuga = getEntity();
if(this.getCurrentFrame() == 10){
nargacuga.playSound("mhfc:narga.tailjump", 2.0F, 1.0F);
}
if (nargacuga.worldObj.isRemote)
return;
if (getCurrentFrame() == SPIKE_FRAME) {
Vec3 up = Vec3.createVectorHelper(0, 1, 0);
Vec3 look = nargacuga.getLookVec();
Vec3 left = look.crossProduct(up).normalize();
Vec3 relUp = left.crossProduct(look);
final int spikeClusters = 7;
final int spikesPerCluster = 9;
final float offsetScaleBack = 9;
for (int i = 0; i < spikeClusters * spikesPerCluster; i++) {
int cluster = i / spikesPerCluster;
int spike = i % spikesPerCluster;
// FIXME replace with narga spikes once they are done
EntityProjectileBlock spikeEntity = new EntityProjectileBlock(nargacuga.worldObj, nargacuga);
spikeEntity.moveEntity(
offsetScaleBack * look.xCoord,
offsetScaleBack * look.yCoord - 2.5,
offsetScaleBack * look.zCoord);
float weightRelUp = (float) Math.sin(Math.PI / (spikesPerCluster - 1) * spike);
float weightLeft = (float) Math.cos(Math.PI / (spikesPerCluster - 1) * spike);
float weightLook = (float) Math.cos(Math.PI / spikeClusters * cluster) * 0.6f;
spikeEntity.setThrowableHeading(
weightLeft * left.xCoord + weightRelUp * relUp.xCoord + weightLook * look.xCoord,
weightLeft * left.yCoord + weightRelUp * relUp.yCoord + weightLook * look.yCoord,
weightLeft * left.zCoord + weightRelUp * relUp.zCoord + weightLook * look.zCoord,
SPEED,
0);
nargacuga.worldObj.spawnEntityInWorld(spikeEntity);
}
}
AIUtils.damageCollidingEntities(getEntity(), damageCalculator);
}
@Override
public String getAnimationLocation() {
return ANIMATION;
}
@Override
public int getAnimationLength() {
return ANIM_LENGTH;
}
@Override
public boolean shouldSelectAttack(
IExecutableAction<? super EntityNargacuga> attack,
EntityNargacuga actor,
Entity target) {
return select.shouldSelectAttack(attack, actor, target);
}
@Override
public float getWeight(EntityNargacuga entity, Entity target) {
return WEIGHT;
}
@Override
public IDamageCalculator getDamageCalculator() {
return damageCalculator;
}
@Override
public float getInitialUpVelocity(EntityNargacuga entity) {
return jumpParams.getInitialUpVelocity(entity);
}
@Override
public float getForwardVelocity(EntityNargacuga entity) {
return jumpParams.getForwardVelocity(entity);
}
@Override
public boolean isJumpFrame(EntityNargacuga entity, int frame) {
return timing.isJumpFrame(entity, frame);
}
@Override
public boolean isDamageFrame(EntityNargacuga entity, int frame) {
return timing.isDamageFrame(entity, frame);
}
@Override
public float getTurnRate(EntityNargacuga entity, int frame) {
return timing.getTurnRate(entity, frame);
}
}