package matteroverdrive.data.biostats; import com.google.common.collect.Multimap; import matteroverdrive.MatterOverdrive; import matteroverdrive.Reference; import matteroverdrive.api.events.bionicStats.MOEventBionicStat; import matteroverdrive.entity.player.AndroidPlayer; import matteroverdrive.network.packet.client.PacketSpawnParticle; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.*; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent; import java.util.EnumSet; import java.util.List; /** * Created by Simeon on 1/1/2016. */ public class BioticStatShockwave extends AbstractBioticStat { public static final int DELAY = 20*12; public BioticStatShockwave(String name, int xp) { super(name, xp); this.showOnHud = true; this.showOnWheel = true; } @Override public String getDetails(int level) { return String.format(super.getDetails(level), EnumChatFormatting.YELLOW + Integer.toString(10) + EnumChatFormatting.GRAY); } @Override public void onAndroidUpdate(AndroidPlayer android, int level) { if (!android.getPlayer().onGround && android.getPlayer().motionY < 0 && android.getPlayer().isSneaking()) { Vec3 motion = Vec3.createVectorHelper(android.getPlayer().motionX,android.getPlayer().motionY,android.getPlayer().motionZ).subtract(Vec3.createVectorHelper(0,1,0)).normalize(); android.getPlayer().addVelocity(-motion.xCoord*0.2,-motion.yCoord*0.2,-motion.zCoord*0.2); } } @Override public void onActionKeyPress(AndroidPlayer androidPlayer, int level, boolean server) { if (androidPlayer.getActiveStat() == this && server) { createShockwave(androidPlayer,androidPlayer.getPlayer(),5); } } @Override public void onKeyPress(AndroidPlayer androidPlayer, int level, int keycode, boolean down) { } @Override public void onLivingEvent(AndroidPlayer androidPlayer, int level, LivingEvent event) { if ((event instanceof LivingFallEvent || event instanceof PlayerFlyableFallEvent) && event.entityLiving.isSneaking()) { if (event instanceof LivingFallEvent) { createShockwave(androidPlayer,event.entityLiving,((LivingFallEvent) event).distance); }else if (event instanceof PlayerFlyableFallEvent) { createShockwave(androidPlayer,event.entityLiving,((PlayerFlyableFallEvent) event).distance); } } } private void createShockwave(AndroidPlayer androidPlayer,EntityLivingBase entityPlayer, float distance) { if (getLastShockwaveTime(androidPlayer) < androidPlayer.getPlayer().worldObj.getTotalWorldTime()) { if (!MinecraftForge.EVENT_BUS.post(new MOEventBionicStat(this,androidPlayer.getUnlockedLevel(this),androidPlayer))) { if (!entityPlayer.worldObj.isRemote) { float range = MathHelper.clamp_float(distance, 5, 10); float power = MathHelper.clamp_float(distance, 1, 3) * 0.8f; AxisAlignedBB area = AxisAlignedBB.getBoundingBox(entityPlayer.posX - range, entityPlayer.posY - range, entityPlayer.posZ - range, entityPlayer.posX + range, entityPlayer.posY + range, entityPlayer.posZ + range); List<EntityLivingBase> entities = entityPlayer.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, area); for (EntityLivingBase entityLivingBase : entities) { if (entityLivingBase != entityPlayer) { Vec3 dir = Vec3.createVectorHelper(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ).subtract(Vec3.createVectorHelper(entityLivingBase.posX, entityLivingBase.posY, entityLivingBase.posZ)); double localDistance = dir.lengthVector(); double distanceMultiply = range / Math.max(1, localDistance); dir = dir.normalize(); entityLivingBase.addVelocity(dir.xCoord * power * distanceMultiply, power * 0.2f, dir.zCoord * power * distanceMultiply); entityLivingBase.velocityChanged = true; ShockwaveDamage damageSource = new ShockwaveDamage("android_shockwave", entityPlayer); entityLivingBase.attackEntityFrom(damageSource, power * 3); } } setLastShockwaveTime(androidPlayer, androidPlayer.getPlayer().worldObj.getTotalWorldTime() + DELAY); androidPlayer.sync(EnumSet.of(AndroidPlayer.DataType.EFFECTS)); entityPlayer.worldObj.playSoundAtEntity(entityPlayer, Reference.MOD_ID + ":" + "shockwave", 1, 0.9f + entityPlayer.getRNG().nextFloat() * 0.1f); for (int i = 0; i < 20; ++i) { double d0 = entityPlayer.getRNG().nextGaussian() * 0.02D; double d1 = entityPlayer.getRNG().nextGaussian() * 0.02D; double d2 = entityPlayer.getRNG().nextGaussian() * 0.02D; double d3 = 10.0D; entityPlayer.worldObj.spawnParticle("explode", entityPlayer.posX + (double) (entityPlayer.getRNG().nextFloat() * entityPlayer.width * 2.0F) - (double) entityPlayer.width - d0 * d3, entityPlayer.posY + (double) (entityPlayer.getRNG().nextFloat() * entityPlayer.height) - d1 * d3, entityPlayer.posZ + (double) (entityPlayer.getRNG().nextFloat() * entityPlayer.width * 2.0F) - (double) entityPlayer.width - d2 * d3, d0, d1, d2); } MatterOverdrive.packetPipeline.sendToAllAround(new PacketSpawnParticle("shockwave", androidPlayer.getPlayer().posX, androidPlayer.getPlayer().posY + androidPlayer.getPlayer().getEyeHeight() / 2, androidPlayer.getPlayer().posZ, 1, 0, 10), androidPlayer.getPlayer(), 64); } else { } } } } @Override public void changeAndroidStats(AndroidPlayer androidPlayer, int level, boolean enabled) { } @Override public Multimap attributes(AndroidPlayer androidPlayer, int level) { return null; } @Override public boolean isActive(AndroidPlayer androidPlayer, int level) { return false; } @Override public boolean isEnabled(AndroidPlayer android, int level) { return super.isEnabled(android,level) && getDelay(android,level) <= 0; } @Override public int getDelay(AndroidPlayer androidPlayer, int level) { long shockwaveTime = getLastShockwaveTime(androidPlayer) - androidPlayer.getPlayer().worldObj.getTotalWorldTime(); if (shockwaveTime > 0) { return (int)shockwaveTime; } return 0; } public class ShockwaveDamage extends DamageSource { EntityLivingBase source; public ShockwaveDamage(String p_i1566_1_,EntityLivingBase source) { super(p_i1566_1_); this.source = source; setExplosion(); setDamageBypassesArmor(); } @Override public Entity getEntity() { return source; } } public long getLastShockwaveTime(AndroidPlayer androidPlayer) { return androidPlayer.getEffects().getLong("SHOCK_LAST_USE"); } public void setLastShockwaveTime(AndroidPlayer androidPlayer,long time) { androidPlayer.getEffects().setLong("SHOCK_LAST_USE",time); } }