That's one heck of a commit you've got there...
I may have got a bit behind with version control. A lot behind, in fact. Maybe I'll go back and split this sometime - then again, I probably won't. But hey, at least it's here!
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.EntityLevitatingBlock;
|
||||
import electroblob.wizardry.item.ItemArtefact;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityTNTPrimed;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class GreaterTelekinesis extends SpellRay {
|
||||
|
||||
public static final String HOLD_RANGE = "hold_range";
|
||||
public static final String THROW_VELOCITY = "throw_velocity";
|
||||
|
||||
/** Makes things a bit smoother-looking / 'realistic'. */
|
||||
private static final float UNDERSHOOT = 0.2f;
|
||||
|
||||
public GreaterTelekinesis(){
|
||||
super("greater_telekinesis", true, EnumAction.NONE);
|
||||
this.aimAssist(0.4f);
|
||||
this.particleSpacing(1);
|
||||
this.particleJitter(0.05);
|
||||
this.particleVelocity(0.3);
|
||||
addProperties(HOLD_RANGE, THROW_VELOCITY, DAMAGE);
|
||||
this.soundValues(0.8f, 1, 0.2f);
|
||||
}
|
||||
|
||||
@Override public boolean canBeCastByNPCs() { return false; }
|
||||
@Override public boolean canBeCastByDispensers() { return false; }
|
||||
|
||||
@Override
|
||||
protected SoundEvent[] createSounds(){
|
||||
return this.createContinuousSpellSounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, EntityLivingBase entity, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
this.playSoundLoop(world, entity, ticksInUse);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, double x, double y, double z, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
this.playSoundLoop(world, x, y, z, ticksInUse, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
// Can't be cast by dispensers so we know caster isn't null, but just in case...
|
||||
if(caster != null && (target instanceof EntityLivingBase || target instanceof EntityLevitatingBlock || target instanceof EntityTNTPrimed)){
|
||||
|
||||
if(target instanceof EntityPlayer && ((caster instanceof EntityPlayer && !Wizardry.settings.playersMoveEachOther)
|
||||
|| ItemArtefact.isArtefactActive((EntityPlayer)target, WizardryItems.amulet_anchoring))){
|
||||
|
||||
if(!world.isRemote && caster instanceof EntityPlayer) ((EntityPlayer)caster).sendStatusMessage(
|
||||
new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted()), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(target instanceof EntityLevitatingBlock){
|
||||
((EntityLevitatingBlock)target).suspend();
|
||||
((EntityLevitatingBlock)target).setCaster(caster); // Yep, you can steal other players' blocks in mid-air!
|
||||
}
|
||||
|
||||
Vec3d targetPos = target.getPositionVector().add(0, target.height/2, 0);
|
||||
|
||||
if(caster.isSneaking()){
|
||||
|
||||
Vec3d look = caster.getLookVec().scale(getProperty(THROW_VELOCITY).floatValue() * modifiers.get(WizardryItems.range_upgrade));
|
||||
target.addVelocity(look.x, look.y, look.z);
|
||||
if(caster instanceof EntityPlayer) caster.swingArm(caster.getActiveHand());
|
||||
|
||||
}else{
|
||||
|
||||
WizardryUtilities.undoGravity(target);
|
||||
|
||||
// The following code extrapolates the entity's current velocity to determine whether it will pass the
|
||||
// target position in the next tick, and adds or subtracts velocity accordingly.
|
||||
|
||||
Vec3d vec = origin.add(caster.getLookVec().scale(getProperty(HOLD_RANGE).floatValue()));
|
||||
|
||||
Vec3d velocity = vec.subtract(targetPos).subtract(target.motionX, target.motionY, target.motionZ)
|
||||
.scale(1 - UNDERSHOOT);
|
||||
|
||||
target.addVelocity(velocity.x, velocity.y, velocity.z);
|
||||
}
|
||||
|
||||
// Player motion is handled on that player's client so needs packets
|
||||
if(target instanceof EntityPlayerMP){
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
}
|
||||
|
||||
if(world.isRemote){
|
||||
|
||||
ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f + 0.3f * world.rand.nextFloat(), 1)
|
||||
.pos(origin.subtract(caster.getPositionVector())).target(target).time(0)
|
||||
.scale(MathHelper.sin(ticksInUse * 0.3f) * 0.1f + 0.9f).spawn(world);
|
||||
|
||||
if(ticksInUse % 18 == 1) ParticleBuilder.create(Type.FLASH).entity(target).pos(0, target.height/2, 0)
|
||||
.scale(2.5f).time(30).clr(0.2f, 0.8f, 1).fade(1f, 1f, 1f).spawn(world);
|
||||
|
||||
ParticleBuilder.create(Type.SPARKLE, target).vel(0, 0.05, 0).time(15).scale(0.6f).clr(0.2f, 0.6f, 1)
|
||||
.fade(1f, 1f, 1f).spawn(world);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
if(WizardryUtilities.canDamageBlocks(caster, world) && !WizardryUtilities.isBlockUnbreakable(world, pos)
|
||||
&& world.getBlockState(pos).getMaterial().isSolid()
|
||||
&& (world.getTileEntity(pos) == null || !world.getTileEntity(pos).getTileData().hasUniqueId(ArcaneLock.NBT_KEY))){
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
EntityLevitatingBlock block = new EntityLevitatingBlock(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5,
|
||||
world.getBlockState(pos));
|
||||
|
||||
block.fallTime = 1;
|
||||
block.damageMultiplier = modifiers.get(SpellModifiers.POTENCY);
|
||||
block.setCaster(caster);
|
||||
|
||||
world.spawnEntity(block);
|
||||
world.setBlockToAir(pos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onMiss(World world, EntityLivingBase caster, Vec3d origin, Vec3d direction, int ticksInUse, SpellModifiers modifiers){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user