Add boulder spell
This commit is contained in:
@@ -815,6 +815,7 @@ public class ClientProxy extends CommonProxy {
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityForcefield.class, RenderForcefield::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityZombieSpawner.class, RenderZombieSpawner::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityRadiantTotem.class, RenderRadiantTotem::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityBoulder.class, RenderBoulder::new);
|
||||
//RenderingRegistry.registerEntityRenderingHandler(EntityContainmentField.class, RenderContainmentField::new);
|
||||
|
||||
// Stuff that doesn't render
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.client.model.ModelBox;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
// Made with Blockbench 3.5.2
|
||||
public class ModelBoulder extends ModelBase {
|
||||
|
||||
private final ModelRenderer mainGroup;
|
||||
private final ModelRenderer box1;
|
||||
private final ModelRenderer box2;
|
||||
private final ModelRenderer box3;
|
||||
private final ModelRenderer box4;
|
||||
private final ModelRenderer box5;
|
||||
private final ModelRenderer box6;
|
||||
|
||||
public ModelBoulder(){
|
||||
|
||||
textureWidth = 64;
|
||||
textureHeight = 32;
|
||||
|
||||
mainGroup = new ModelRenderer(this);
|
||||
mainGroup.setRotationPoint(0.0F, 24.0F, 0.0F);
|
||||
|
||||
box1 = new ModelRenderer(this);
|
||||
box1.setRotationPoint(0.0F, -19.0F, 0.0F);
|
||||
mainGroup.addChild(box1);
|
||||
box1.cubeList.add(new ModelBox(box1, 0, 0, -11.0F, -11.0F, 11.0F, 22, 22, 8, 0.0F, false));
|
||||
|
||||
box2 = new ModelRenderer(this);
|
||||
box2.setRotationPoint(0.0F, -19.0F, 0.0F);
|
||||
mainGroup.addChild(box2);
|
||||
setRotationAngle(box2, -1.5708F, 0.0F, 0.0F);
|
||||
box2.cubeList.add(new ModelBox(box2, 0, 0, -11.0F, -11.0F, 11.0F, 22, 22, 8, 0.0F, false));
|
||||
|
||||
box3 = new ModelRenderer(this);
|
||||
box3.setRotationPoint(0.0F, -19.0F, 0.0F);
|
||||
mainGroup.addChild(box3);
|
||||
setRotationAngle(box3, 0.0F, -1.5708F, 0.0F);
|
||||
box3.cubeList.add(new ModelBox(box3, 0, 0, -11.0F, -11.0F, 11.0F, 22, 22, 8, 0.0F, false));
|
||||
|
||||
box4 = new ModelRenderer(this);
|
||||
box4.setRotationPoint(0.0F, -19.0F, 0.0F);
|
||||
mainGroup.addChild(box4);
|
||||
setRotationAngle(box4, 0.0F, 1.5708F, 0.0F);
|
||||
box4.cubeList.add(new ModelBox(box4, 0, 0, -11.0F, -11.0F, 11.0F, 22, 22, 8, 0.0F, false));
|
||||
|
||||
box5 = new ModelRenderer(this);
|
||||
box5.setRotationPoint(0.0F, -19.0F, 0.0F);
|
||||
mainGroup.addChild(box5);
|
||||
setRotationAngle(box5, 1.5708F, 0.0F, 0.0F);
|
||||
box5.cubeList.add(new ModelBox(box5, 0, 0, -11.0F, -11.0F, 11.0F, 22, 22, 8, 0.0F, false));
|
||||
|
||||
box6 = new ModelRenderer(this);
|
||||
box6.setRotationPoint(0.0F, -19.0F, 0.0F);
|
||||
mainGroup.addChild(box6);
|
||||
setRotationAngle(box6, 3.1416F, 0.0F, 0.0F);
|
||||
box6.cubeList.add(new ModelBox(box6, 0, 0, -11.0F, -11.0F, 11.0F, 22, 22, 8, 0.0F, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
|
||||
mainGroup.render(f5);
|
||||
}
|
||||
|
||||
public void setRotationAngle(ModelRenderer modelRenderer, float x, float y, float z){
|
||||
modelRenderer.rotateAngleX = x;
|
||||
modelRenderer.rotateAngleY = y;
|
||||
modelRenderer.rotateAngleZ = z;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package electroblob.wizardry.client.renderer.entity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.client.DrawingUtils;
|
||||
import electroblob.wizardry.client.model.ModelBoulder;
|
||||
import electroblob.wizardry.entity.construct.EntityBoulder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class RenderBoulder extends Render<EntityBoulder> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/boulder.png");
|
||||
|
||||
private ModelBoulder model = new ModelBoulder();
|
||||
|
||||
public RenderBoulder(RenderManager manager){
|
||||
super(manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(EntityBoulder entity, double x, double y, double z, float yaw, float partialTicks){
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(x, y + 1.2, z);
|
||||
GlStateManager.rotate(180, 0F, 0F, 1F);
|
||||
GlStateManager.rotate(yaw - 90, 0, 1, 0);
|
||||
GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, 0, 0, 1);
|
||||
GlStateManager.translate(0, entity.height/2 - 1.5, 0);
|
||||
|
||||
// Pass in -1 for the lifetime as the boulder crumbles when the time expires
|
||||
float s = DrawingUtils.smoothScaleFactor(-1, entity.ticksExisted, partialTicks, 10, 10);
|
||||
GlStateManager.scale(s, s, s);
|
||||
|
||||
this.bindTexture(TEXTURE);
|
||||
|
||||
model.render(entity, 0, 0, 0, 0, 0, 0.0625f);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(EntityBoulder entity){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
package electroblob.wizardry.entity.construct;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Boulder;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.MagicDamage;
|
||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.MoverType;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EntityBoulder extends EntityScaledConstruct {
|
||||
|
||||
private double velX, velZ;
|
||||
private int hitsRemaining;
|
||||
private boolean soundStarted = false;
|
||||
|
||||
public EntityBoulder(World world){
|
||||
super(world);
|
||||
setSize(2.375f, 2.375f);
|
||||
this.noClip = false;
|
||||
this.setNoGravity(false);
|
||||
this.stepHeight = 1;
|
||||
hitsRemaining = 5;
|
||||
}
|
||||
|
||||
public void setHorizontalVelocity(double velX, double velZ){
|
||||
this.velX = velX;
|
||||
this.velZ = velZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(){
|
||||
|
||||
if(world.isRemote && !soundStarted && onGround){
|
||||
soundStarted = true;
|
||||
Wizardry.proxy.playMovingSound(this, WizardrySounds.ENTITY_BOULDER_ROLL, WizardrySounds.SPELLS, 1, 1, true);
|
||||
}
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
this.motionY -= 0.03999999910593033D;
|
||||
this.move(MoverType.SELF, velX, motionY, velZ);
|
||||
|
||||
List<EntityLivingBase> collided = world.getEntitiesWithinAABB(EntityLivingBase.class, this.getEntityBoundingBox());
|
||||
|
||||
float damage = Spells.boulder.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier;
|
||||
float knockback = Spells.boulder.getProperty(Boulder.KNOCKBACK_STRENGTH).floatValue();
|
||||
|
||||
for(EntityLivingBase entity : collided){
|
||||
|
||||
if(!isValidTarget(entity)) break;
|
||||
|
||||
if(EntityUtils.attackEntityWithoutKnockback(entity, MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.MAGIC), damage)){
|
||||
EntityUtils.applyStandardKnockback(this, entity, knockback);
|
||||
entity.motionX += this.motionX;
|
||||
entity.motionZ += this.motionZ;
|
||||
}
|
||||
entity.playSound(WizardrySounds.ENTITY_BOULDER_HIT, 1, 1);
|
||||
}
|
||||
|
||||
if(EntityUtils.canDamageBlocks(getCaster(), world) && collidedHorizontally){
|
||||
smashBlocks(BlockUtils.getBlockSphere(new BlockPos(posX + velX, posY + height / 2, posZ + velZ), height * 0.8), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to smash the given list of blocks. If the boulder has exhausted its hits, or if any of the blocks are
|
||||
* too hard to be smashed and breakIfTooHard is true, the boulder is destroyed.
|
||||
* @param blocks A list of block positions at which any solid blocks that are weak enough will be destroyed
|
||||
* @param breakIfTooHard True if the boulder should break if any of the blocks are too hard, false if it should stop
|
||||
* on those blocks
|
||||
* @return True if something was destroyed (either the boulder, one or more blocks, or both), false otherwise
|
||||
*/
|
||||
private boolean smashBlocks(List<BlockPos> blocks, boolean breakIfTooHard){
|
||||
|
||||
if(blocks.removeIf(p -> world.getBlockState(p).getBlock().getExplosionResistance(world, p, this, null) > 3)){
|
||||
// If any of the blocks were not breakable, the boulder is smashed
|
||||
if(breakIfTooHard){
|
||||
this.despawn();
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
if(!world.isRemote){
|
||||
blocks.forEach(p -> world.destroyBlock(p, false));
|
||||
if(--hitsRemaining <= 0) this.despawn();
|
||||
}else{
|
||||
world.playSound(posX, posY, posZ, WizardrySounds.ENTITY_BOULDER_BREAK_BLOCK, SoundCategory.BLOCKS, 1, 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
shakeNearbyPlayers();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void shakeNearbyPlayers(){
|
||||
EntityUtils.getEntitiesWithinRadius(10, posX, posY, posZ, world, EntityPlayer.class)
|
||||
.forEach(p -> Wizardry.proxy.shakeScreen(p, 8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void despawn(){
|
||||
|
||||
if(world.isRemote){
|
||||
|
||||
for(int i = 0; i < 100; i++){
|
||||
double x = posX + (rand.nextDouble() - 0.5) * width;
|
||||
double y = posY + rand.nextDouble() * height;
|
||||
double z = posZ + (rand.nextDouble() - 0.5) * width;
|
||||
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, x, y, z, (x - posX) * 0.1,
|
||||
(y - posY + height / 2) * 0.1, (z - posZ) * 0.1, Block.getStateId(Blocks.DIRT.getDefaultState()));
|
||||
}
|
||||
|
||||
world.playSound(posX, posY, posZ, WizardrySounds.ENTITY_BOULDER_BREAK_BLOCK, SoundCategory.BLOCKS, 1, 1, false);
|
||||
}
|
||||
|
||||
super.despawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(MoverType type, double x, double y, double z){
|
||||
super.move(type, x, y, z);
|
||||
this.rotationPitch += Math.toDegrees(MathHelper.sqrt(x*x + y*y + z*z) / (width/2)); // That's how we roll
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fall(float distance, float damageMultiplier){
|
||||
|
||||
super.fall(distance, damageMultiplier);
|
||||
|
||||
if(EntityUtils.canDamageBlocks(getCaster(), world) && distance > 3){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(new BlockPos(posX + velX, posY + height / 2 + motionY, posZ + velZ), height * 0.8);
|
||||
if(smashBlocks(sphere, distance > 8)) return;
|
||||
hitsRemaining--;
|
||||
}
|
||||
|
||||
if(world.isRemote){
|
||||
|
||||
for(int i = 0; i < 40; i++){
|
||||
|
||||
double particleX = this.posX - 1.5 + 3 * rand.nextDouble();
|
||||
double particleZ = this.posZ - 1.5 + 3 * rand.nextDouble();
|
||||
// Roundabout way of getting a block instance for the block the boulder is standing on (if any).
|
||||
IBlockState block = world.getBlockState(new BlockPos(this.posX, this.posY - 2, this.posZ));
|
||||
|
||||
if(block.getBlock() != Blocks.AIR){
|
||||
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, this.posY, particleZ,
|
||||
particleX - this.posX, 0, particleZ - this.posZ, Block.getStateId(block));
|
||||
}
|
||||
}
|
||||
|
||||
if(distance > 1.2){
|
||||
world.playSound(posX, posY, posZ, WizardrySounds.ENTITY_BOULDER_LAND, SoundCategory.BLOCKS, Math.min(2, distance / 4), 1, false);
|
||||
shakeNearbyPlayers();
|
||||
// EntityUtils.getEntitiesWithinRadius(Math.min(12, distance * 2), posX, posY, posZ, world, EntityPlayer.class)
|
||||
// .forEach(p -> Wizardry.proxy.shakeScreen(p, Math.min(12, distance * 2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeCollidedWith(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getCollisionBoundingBox(){
|
||||
return this.getEntityBoundingBox();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readEntityFromNBT(NBTTagCompound nbt){
|
||||
super.readEntityFromNBT(nbt);
|
||||
velX = nbt.getDouble("velX");
|
||||
velZ = nbt.getDouble("velZ");
|
||||
hitsRemaining = nbt.getInteger("hitsRemaining");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeEntityToNBT(NBTTagCompound nbt){
|
||||
super.writeEntityToNBT(nbt);
|
||||
nbt.setDouble("velX", velX);
|
||||
nbt.setDouble("velZ", velZ);
|
||||
nbt.setInteger("hitsRemaining", hitsRemaining);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
super.writeSpawnData(data);
|
||||
data.writeDouble(velX);
|
||||
data.writeDouble(velZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(ByteBuf data){
|
||||
super.readSpawnData(data);
|
||||
this.velX = data.readDouble();
|
||||
this.velZ = data.readDouble();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -248,6 +248,7 @@ public final class Spells {
|
||||
|
||||
public static final Spell firestorm = placeholder();
|
||||
public static final Spell zombie_apocalypse = placeholder();
|
||||
public static final Spell boulder = placeholder();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void register(RegistryEvent.Register<Spell> event){
|
||||
@@ -458,6 +459,7 @@ public final class Spells {
|
||||
|
||||
registry.register(new Firestorm());
|
||||
registry.register(new ZombieApocalypse());
|
||||
registry.register(new Boulder());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntityBubble.class, "bubble") .tracker(160, 3, false).build());
|
||||
registry.register(createEntry(EntityTornado.class, "tornado") .tracker(160, 3, false).build());
|
||||
registry.register(createEntry(EntityIceSpike.class, "ice_spike") .tracker(160, 1, true).build());
|
||||
registry.register(createEntry(EntityBoulder.class, "boulder") .tracker(160, 1, true).build()); // Vertical velocity is not constant
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -47,8 +47,12 @@ public final class WizardrySounds {
|
||||
public static final SoundEvent ENTITY_BLACK_HOLE_AMBIENT = createSound("entity.black_hole.ambient");
|
||||
public static final SoundEvent ENTITY_BLACK_HOLE_VANISH = createSound("entity.black_hole.vanish");
|
||||
public static final SoundEvent ENTITY_BLACK_HOLE_BREAK_BLOCK = createSound("entity.black_hole.break_block");
|
||||
public static final SoundEvent ENTITY_BUBBLE_POP = createSound("entity.bubble.pop");
|
||||
public static final SoundEvent ENTITY_BLIZZARD_AMBIENT = createSound("entity.blizzard.ambient");
|
||||
public static final SoundEvent ENTITY_BOULDER_ROLL = createSound("entity.boulder.roll");
|
||||
public static final SoundEvent ENTITY_BOULDER_LAND = createSound("entity.boulder.land");
|
||||
public static final SoundEvent ENTITY_BOULDER_HIT = createSound("entity.boulder.hit");
|
||||
public static final SoundEvent ENTITY_BOULDER_BREAK_BLOCK = createSound("entity.boulder.break_block");
|
||||
public static final SoundEvent ENTITY_BUBBLE_POP = createSound("entity.bubble.pop");
|
||||
public static final SoundEvent ENTITY_DECAY_AMBIENT = createSound("entity.decay.ambient");
|
||||
public static final SoundEvent ENTITY_ENTRAPMENT_AMBIENT = createSound("entity.entrapment.ambient");
|
||||
public static final SoundEvent ENTITY_ENTRAPMENT_VANISH = createSound("entity.entrapment.vanish");
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.entity.construct.EntityBoulder;
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.util.GeometryUtils;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumFacing.Axis;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class Boulder extends SpellConstruct<EntityBoulder> {
|
||||
|
||||
public static final String SPEED = "speed";
|
||||
public static final String KNOCKBACK_STRENGTH = "knockback_strength";
|
||||
|
||||
public Boulder(){
|
||||
super("boulder", SpellActions.SUMMON, EntityBoulder::new, false);
|
||||
addProperties(SPEED, DAMAGE, KNOCKBACK_STRENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addConstructExtras(EntityBoulder construct, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
||||
float speed = getProperty(SPEED).floatValue();
|
||||
// Unlike tornado, boulder always has the same speed
|
||||
Vec3d direction = caster == null ? new Vec3d(side.getDirectionVec())
|
||||
: GeometryUtils.replaceComponent(caster.getLookVec(), Axis.Y, 0).normalize();
|
||||
construct.setHorizontalVelocity(direction.x * speed, direction.z * speed);
|
||||
construct.rotationYaw = caster == null ? side.getHorizontalAngle() : caster.rotationYaw;
|
||||
double yOffset = caster == null ? 0 : 1.6;
|
||||
construct.setPosition(construct.posX + direction.x, construct.posY + yOffset, construct.posZ + direction.z);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -172,22 +172,34 @@ public final class EntityUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the standard (non-enchanted) amount of knockback to the given target, using the same calculation as
|
||||
* {@link EntityLivingBase#attackEntityFrom(DamageSource, float)}. Use in conjunction with
|
||||
* Applies the standard (non-enchanted) amount of knockback to the given target, using the same calculation and
|
||||
* strength value (0.4) as {@link EntityLivingBase#attackEntityFrom(DamageSource, float)}. Use in conjunction with
|
||||
* {@link EntityUtils#attackEntityWithoutKnockback(Entity, DamageSource, float)} to change the source of
|
||||
* knockback for an attack.
|
||||
*
|
||||
* @param attacker The entity that caused the knockback; the target will be pushed away from this entity.
|
||||
* @param target The entity to be knocked back.
|
||||
* @param attacker The entity that caused the knockback; the target will be pushed away from this entity
|
||||
* @param target The entity to be knocked back
|
||||
*/
|
||||
public static void applyStandardKnockback(Entity attacker, EntityLivingBase target){
|
||||
applyStandardKnockback(attacker, target, 0.4f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the standard knockback calculation to the given target, using the same calculation as
|
||||
* {@link EntityLivingBase#attackEntityFrom(DamageSource, float)}.
|
||||
*
|
||||
* @param attacker The entity that caused the knockback; the target will be pushed away from this entity
|
||||
* @param target The entity to be knocked back
|
||||
* @param strength The strength of the knockback
|
||||
*/
|
||||
public static void applyStandardKnockback(Entity attacker, EntityLivingBase target, float strength){
|
||||
double dx = attacker.posX - target.posX;
|
||||
double dz;
|
||||
for(dz = attacker.posZ - target.posZ; dx * dx + dz * dz < 1.0E-4D; dz = (Math.random() - Math.random())
|
||||
* 0.01D){
|
||||
dx = (Math.random() - Math.random()) * 0.01D;
|
||||
}
|
||||
target.knockBack(attacker, 0.4f, dx, dz);
|
||||
target.knockBack(attacker, strength, dx, dz);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,7 +356,7 @@ public final class EntityUtils {
|
||||
|
||||
/** Checks that the given entity is allowed to damage blocks in the given world. If the entity is a player or null,
|
||||
* this checks the player block damage config setting, otherwise it posts a mob griefing event and returns the result. */
|
||||
public static boolean canDamageBlocks(EntityLivingBase entity, World world){
|
||||
public static boolean canDamageBlocks(@Nullable EntityLivingBase entity, World world){
|
||||
// TODO: Dispenser griefing!
|
||||
if(entity == null || entity instanceof EntityPlayer) return Wizardry.settings.playerBlockDamage;
|
||||
return ForgeEventFactory.getMobGriefingEvent(world, entity);
|
||||
|
||||
@@ -625,6 +625,7 @@ entity.ebwizardry\:hailstorm.name=Hailstorm
|
||||
entity.ebwizardry\:lightning_pulse.name=Lightning Pulse
|
||||
entity.ebwizardry\:stormcloud.name=Stormcloud
|
||||
entity.ebwizardry\:zombie_spawner.name=Zombie Spawner
|
||||
entity.ebwizardry\:boulder.name=Boulder
|
||||
|
||||
itemGroup.ebwizardry=Wizardry
|
||||
itemGroup.ebwizardryspells=Spells
|
||||
@@ -753,6 +754,7 @@ spell.ebwizardry\:black_hole=Black Hole
|
||||
spell.ebwizardry\:blinding_flash=Blinding Flash
|
||||
spell.ebwizardry\:blink=Blink
|
||||
spell.ebwizardry\:blizzard=Blizzard
|
||||
spell.ebwizardry\:boulder=Boulder
|
||||
spell.ebwizardry\:bubble=Bubble
|
||||
spell.ebwizardry\:chain_lightning=Chain Lightning
|
||||
spell.ebwizardry\:charge=Charge
|
||||
@@ -933,6 +935,7 @@ spell.ebwizardry\:black_hole.desc=Tear reality asunder.
|
||||
spell.ebwizardry\:blinding_flash.desc=Emits an intense flash of light that blinds all nearby creatures.
|
||||
spell.ebwizardry\:blink.desc=Teleports the caster over a short distance to where they are pointing.
|
||||
spell.ebwizardry\:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed.
|
||||
spell.ebwizardry\:boulder.desc="Let the world be my bowling alley, and my foes be the pins!"
|
||||
spell.ebwizardry\:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged.
|
||||
spell.ebwizardry\:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice.
|
||||
spell.ebwizardry\:charge.desc=Causes the caster to charge rapidly in the direction they are looking, damaging and knocking back anything in their path.
|
||||
|
||||
@@ -625,6 +625,7 @@ entity.ebwizardry\:hailstorm.name=Hailstorm
|
||||
entity.ebwizardry\:lightning_pulse.name=Lightning Pulse
|
||||
entity.ebwizardry\:stormcloud.name=Stormcloud
|
||||
entity.ebwizardry\:zombie_spawner.name=Zombie Spawner
|
||||
entity.ebwizardry\:boulder.name=Boulder
|
||||
|
||||
itemGroup.ebwizardry=Wizardry
|
||||
itemGroup.ebwizardryspells=Spells
|
||||
@@ -753,6 +754,7 @@ spell.ebwizardry\:black_hole=Black Hole
|
||||
spell.ebwizardry\:blinding_flash=Blinding Flash
|
||||
spell.ebwizardry\:blink=Blink
|
||||
spell.ebwizardry\:blizzard=Blizzard
|
||||
spell.ebwizardry\:boulder=Boulder
|
||||
spell.ebwizardry\:bubble=Bubble
|
||||
spell.ebwizardry\:chain_lightning=Chain Lightning
|
||||
spell.ebwizardry\:charge=Charge
|
||||
@@ -933,6 +935,7 @@ spell.ebwizardry\:black_hole.desc=Tear reality asunder.
|
||||
spell.ebwizardry\:blinding_flash.desc=Emits an intense flash of light that blinds all nearby creatures.
|
||||
spell.ebwizardry\:blink.desc=Teleports the caster over a short distance to where they are pointing.
|
||||
spell.ebwizardry\:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed.
|
||||
spell.ebwizardry\:boulder.desc="Let the world be my bowling alley, and my foes be the pins!"
|
||||
spell.ebwizardry\:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged.
|
||||
spell.ebwizardry\:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice.
|
||||
spell.ebwizardry\:charge.desc=Causes the caster to charge rapidly in the direction they are looking, damaging and knocking back anything in their path.
|
||||
|
||||
@@ -18,8 +18,12 @@
|
||||
"entity.black_hole.ambient": {"category": "spells", "sounds": ["portal/portal"]},
|
||||
"entity.black_hole.vanish": {"category": "spells", "sounds": ["portal/trigger"]},
|
||||
"entity.black_hole.break_block": {"category": "spells", "sounds": ["mob/zombie/woodbreak"]},
|
||||
"entity.bubble.pop": {"category": "spells", "sounds": ["random/pop"]},
|
||||
"entity.blizzard.ambient": {"category": "spells", "sounds": ["ebwizardry:wind"]},
|
||||
"entity.boulder.roll": {"category": "spells", "sounds": ["ebwizardry:roll"]},
|
||||
"entity.boulder.land": {"category": "spells", "sounds": ["ebwizardry:rumble"]},
|
||||
"entity.boulder.hit": {"category": "spells", "sounds": ["damage/hit1", "damage/hit2", "damage/hit3"]},
|
||||
"entity.boulder.break_block": {"category": "spells", "sounds": ["mob/zombie/woodbreak"]},
|
||||
"entity.bubble.pop": {"category": "spells", "sounds": ["random/pop"]},
|
||||
"entity.decay.ambient": {"category": "spells", "sounds": ["liquid/lava"]},
|
||||
"entity.entrapment.ambient": {"category": "spells", "sounds": ["portal/portal"]},
|
||||
"entity.entrapment.vanish": {"category": "spells", "sounds": ["portal/trigger"]},
|
||||
@@ -130,6 +134,7 @@
|
||||
"spell.blinding_flash": {"category": "spells", "sounds": ["ebwizardry:flash"]},
|
||||
"spell.blink": {"category": "spells", "sounds": ["mob/endermen/portal", "mob/endermen/portal2"]},
|
||||
"spell.blizzard": {"category": "spells", "sounds": ["ebwizardry:ice_age"]},
|
||||
"spell.boulder": {"category": "spells", "sounds": ["random/bow"]},
|
||||
"spell.bubble.shoot": {"category": "spells", "sounds": ["ebwizardry:ice"]},
|
||||
"spell.bubble.splash": {"category": "spells", "sounds": ["liquid/swim1", "liquid/swim2", "liquid/swim3", "liquid/swim4"], "volume": 2},
|
||||
"spell.chain_lightning": {"category": "spells", "sounds": ["ebwizardry:arc1", "ebwizardry:arc2", "ebwizardry:arc3"]},
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"enabled": {
|
||||
"book": true,
|
||||
"scroll": true,
|
||||
"wands": true,
|
||||
"npcs": true,
|
||||
"dispensers": true,
|
||||
"commands": true,
|
||||
"treasure": true,
|
||||
"trades": true,
|
||||
"looting": true
|
||||
},
|
||||
"tier": "master",
|
||||
"element": "earth",
|
||||
"type": "attack",
|
||||
"cost": 125,
|
||||
"chargeup": 25,
|
||||
"cooldown": 350,
|
||||
"base_properties": {
|
||||
"duration": 200,
|
||||
"speed": 0.33,
|
||||
"damage": 10,
|
||||
"knockback_strength": 1
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
Reference in New Issue
Block a user