Add withering totem spell
This commit is contained in:
@@ -816,6 +816,7 @@ public class ClientProxy extends CommonProxy {
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityZombieSpawner.class, RenderZombieSpawner::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityRadiantTotem.class, RenderRadiantTotem::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityBoulder.class, RenderBoulder::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityWitheringTotem.class, RenderWitheringTotem::new);
|
||||
//RenderingRegistry.registerEntityRenderingHandler(EntityContainmentField.class, RenderContainmentField::new);
|
||||
|
||||
// Stuff that doesn't render
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
package electroblob.wizardry.client.renderer.entity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.client.DrawingUtils;
|
||||
import electroblob.wizardry.entity.construct.EntityWitheringTotem;
|
||||
import electroblob.wizardry.util.GeometryUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class RenderWitheringTotem extends Render<EntityWitheringTotem> {
|
||||
|
||||
private static final ResourceLocation FLARE_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/totem/flare.png");
|
||||
private static final ResourceLocation[] CUBE_TEXTURES = new ResourceLocation[14];
|
||||
|
||||
static {
|
||||
for(int i = 0; i< CUBE_TEXTURES.length; i++) CUBE_TEXTURES[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/totem/cube_" + i + ".png");
|
||||
}
|
||||
|
||||
public RenderWitheringTotem(RenderManager manager){
|
||||
super(manager);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(EntityWitheringTotem entity){
|
||||
return CUBE_TEXTURES[entity.ticksExisted % CUBE_TEXTURES.length];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(EntityWitheringTotem entity, double x, double y, double z, float entityYaw, float partialTicks){
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.disableLighting();
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
||||
GlStateManager.depthMask(false);
|
||||
GlStateManager.disableCull();
|
||||
|
||||
GlStateManager.translate(x, y + entity.height/2, z);
|
||||
|
||||
float charge = entity.getHealthDrained() / 50f;
|
||||
|
||||
float s = DrawingUtils.smoothScaleFactor(entity.lifetime, entity.ticksExisted, partialTicks, 10, 10);
|
||||
s *= 1 + charge * 0.3f; // Gets bigger the more health it drains
|
||||
GlStateManager.scale(s, s, s);
|
||||
|
||||
drawFlare(charge, tessellator);
|
||||
drawCube(entity, tessellator, partialTicks);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.depthMask(true);
|
||||
GlStateManager.enableCull();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
private void drawFlare(float redness, Tessellator tessellator){
|
||||
|
||||
BufferBuilder buffer = tessellator.getBuffer();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
int c = DrawingUtils.mix(0xb333e6, 0xff0044, redness);
|
||||
int r = c >> 16 & 255;
|
||||
int g = c >> 8 & 255;
|
||||
int b = c & 255;
|
||||
|
||||
// Makes the colour add to the colour of the texture pixels, rather than the default multiplying
|
||||
GlStateManager.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_ADD);
|
||||
GlStateManager.color(r/255f, g/255f, b/255f); // Gets redder the more health it drains
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
bindTexture(FLARE_TEXTURE);
|
||||
|
||||
// This counteracts the reverse rotation behaviour when in front f5 view.
|
||||
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
|
||||
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2
|
||||
? Minecraft.getMinecraft().getRenderManager().playerViewX
|
||||
: -Minecraft.getMinecraft().getRenderManager().playerViewX;
|
||||
GlStateManager.rotate(180.0F - Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F);
|
||||
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
|
||||
|
||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
||||
|
||||
float radius = 0.5f;
|
||||
|
||||
buffer.pos(-radius, radius, 0).tex(0, 0).endVertex();
|
||||
buffer.pos( radius, radius, 0).tex(1, 0).endVertex();
|
||||
buffer.pos( radius, -radius, 0).tex(1, 1).endVertex();
|
||||
buffer.pos(-radius, -radius, 0).tex(0, 1).endVertex();
|
||||
|
||||
tessellator.draw();
|
||||
|
||||
// Reverses the colour addition change
|
||||
GlStateManager.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
|
||||
GlStateManager.color(1, 1, 1, 1);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
private void drawCube(EntityWitheringTotem entity, Tessellator tessellator, float partialTicks){
|
||||
|
||||
BufferBuilder buffer = tessellator.getBuffer();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
float age = entity.ticksExisted + partialTicks;
|
||||
float rotationSpeed = 2;
|
||||
|
||||
GlStateManager.rotate(age * rotationSpeed/2, 0.0F, 1.0F, 0.0F);
|
||||
GlStateManager.rotate(60.0F, 0.7071F, 0.0F, 0.7071F);
|
||||
GlStateManager.rotate(age * rotationSpeed, 0.0F, 1.0F, 0.0F);
|
||||
|
||||
GlStateManager.scale(0.5, 0.5, 0.5);
|
||||
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
|
||||
|
||||
bindEntityTexture(entity);
|
||||
|
||||
Vec3d[] vertices = GeometryUtils.getVertices(entity.getEntityBoundingBox().offset(entity.getPositionVector()
|
||||
.add(0, entity.height/2, 0).scale(-1)));
|
||||
|
||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
||||
|
||||
// Outside
|
||||
drawFace(buffer, vertices[0], vertices[1], vertices[3], vertices[2], 0.5f, 0, 0.75f, 0.5f); // Bottom
|
||||
drawFace(buffer, vertices[6], vertices[7], vertices[2], vertices[3], 0.75f, 0.5f, 1, 1); // South
|
||||
drawFace(buffer, vertices[5], vertices[6], vertices[1], vertices[2], 0, 0.5f, 0.25f, 1); // East
|
||||
drawFace(buffer, vertices[4], vertices[5], vertices[0], vertices[1], 0.25f, 0.5f, 0.5f, 1); // North
|
||||
drawFace(buffer, vertices[7], vertices[4], vertices[3], vertices[0], 0.5f, 0.5f, 0.75f, 1); // West
|
||||
drawFace(buffer, vertices[5], vertices[4], vertices[6], vertices[7], 0.25f, 0, 0.5f, 0.5f); // Top
|
||||
|
||||
tessellator.draw();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
private static void drawFace(BufferBuilder buffer, Vec3d topLeft, Vec3d topRight, Vec3d bottomLeft, Vec3d bottomRight, float u1, float v1, float u2, float v2){
|
||||
buffer.pos(topLeft.x, topLeft.y, topLeft.z).tex(u1, v1).endVertex();
|
||||
buffer.pos(topRight.x, topRight.y, topRight.z).tex(u2, v1).endVertex();
|
||||
buffer.pos(bottomRight.x, bottomRight.y, bottomRight.z).tex(u2, v2).endVertex();
|
||||
buffer.pos(bottomLeft.x, bottomLeft.y, bottomLeft.z).tex(u1, v2).endVertex();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package electroblob.wizardry.entity.construct;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.spell.WitheringTotem;
|
||||
import electroblob.wizardry.util.*;
|
||||
import electroblob.wizardry.util.BlockUtils.SurfaceCriteria;
|
||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.init.MobEffects;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class EntityWitheringTotem extends EntityScaledConstruct {
|
||||
|
||||
private static final int PERIMETER_PARTICLE_DENSITY = 6;
|
||||
|
||||
private static final DataParameter<Float> HEALTH_DRAINED = EntityDataManager.createKey(EntityWitheringTotem.class, DataSerializers.FLOAT);
|
||||
|
||||
public EntityWitheringTotem(World world){
|
||||
super(world);
|
||||
this.setSize(1, 1); // This entity is different in that its area of effect is kind of 'outside' it
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit(){
|
||||
dataManager.register(HEALTH_DRAINED, 0f);
|
||||
}
|
||||
|
||||
public float getHealthDrained(){
|
||||
return dataManager.get(HEALTH_DRAINED);
|
||||
}
|
||||
|
||||
public void addHealthDrained(float health){
|
||||
dataManager.set(HEALTH_DRAINED, getHealthDrained() + health);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldScaleWidth(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldScaleHeight(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(){
|
||||
|
||||
if(world.isRemote && this.ticksExisted == 1){
|
||||
Wizardry.proxy.playMovingSound(this, WizardrySounds.ENTITY_WITHERING_TOTEM_AMBIENT, WizardrySounds.SPELLS, 1, 1, true);
|
||||
}
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
double radius = Spells.withering_totem.getProperty(Spell.EFFECT_RADIUS).floatValue() * sizeMultiplier;
|
||||
|
||||
if(world.isRemote){
|
||||
|
||||
ParticleBuilder.create(Type.DUST, rand, posX, posY + 0.2, posZ, 0.3, false)
|
||||
.vel(0, -0.02 - world.rand.nextFloat() * 0.01, 0).clr(0xf575f5).fade(0x382366).spawn(world);
|
||||
|
||||
for(int i=0; i<PERIMETER_PARTICLE_DENSITY; i++){
|
||||
|
||||
float angle = ((float)Math.PI * 2)/PERIMETER_PARTICLE_DENSITY * (i + rand.nextFloat());
|
||||
|
||||
double x = posX + radius * MathHelper.sin(angle);
|
||||
double z = posZ + radius * MathHelper.cos(angle);
|
||||
|
||||
Integer y = BlockUtils.getNearestSurface(world, new BlockPos(x, posY, z), EnumFacing.UP, 5, true, SurfaceCriteria.COLLIDABLE);
|
||||
|
||||
if(y != null){
|
||||
ParticleBuilder.create(Type.DUST).pos(x, y, z).vel(0, 0.01, 0).clr(0xf575f5).fade(0x382366).spawn(world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<EntityLivingBase> nearby = EntityUtils.getLivingWithinRadius(radius, posX, posY, posZ, world);
|
||||
nearby.removeIf(e -> !isValidTarget(e));
|
||||
nearby.sort(Comparator.comparingDouble(e -> e.getDistanceSq(this)));
|
||||
|
||||
int targetsRemaining = Spells.withering_totem.getProperty(WitheringTotem.MAX_TARGETS).intValue()
|
||||
+ (int)((damageMultiplier - 1) / Constants.POTENCY_INCREASE_PER_TIER);
|
||||
|
||||
while(!nearby.isEmpty() && targetsRemaining > 0){
|
||||
|
||||
EntityLivingBase target = nearby.remove(0);
|
||||
|
||||
if(EntityUtils.isLiving(target)){
|
||||
|
||||
if(target.ticksExisted % target.maxHurtResistantTime == 1){
|
||||
|
||||
float damage = Spells.withering_totem.getProperty(Spell.DAMAGE).floatValue();
|
||||
|
||||
if(EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeIndirectMagicDamage(this,
|
||||
getCaster(), DamageType.WITHER), damage)){
|
||||
addHealthDrained(damage);
|
||||
}
|
||||
}
|
||||
|
||||
targetsRemaining--;
|
||||
|
||||
if(world.isRemote){
|
||||
|
||||
Vec3d centre = GeometryUtils.getCentre(this);
|
||||
Vec3d pos = GeometryUtils.getCentre(target);
|
||||
|
||||
ParticleBuilder.create(Type.BEAM).pos(centre).target(target)
|
||||
.clr(0.1f + 0.2f * world.rand.nextFloat(), 0, 0.3f).spawn(world);
|
||||
|
||||
for(int i = 0; i < 3; i++){
|
||||
ParticleBuilder.create(Type.DUST, rand, pos.x, pos.y, pos.z, 0.3, false)
|
||||
.vel(pos.subtract(centre).normalize().scale(-0.1)).clr(0x0c0024).fade(0x610017).spawn(world);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void despawn(){
|
||||
|
||||
double radius = Spells.withering_totem.getProperty(Spell.EFFECT_RADIUS).floatValue() * sizeMultiplier;
|
||||
|
||||
List<EntityLivingBase> nearby = EntityUtils.getLivingWithinRadius(radius, posX, posY, posZ, world);
|
||||
nearby.removeIf(e -> !isValidTarget(e));
|
||||
|
||||
float damage = Math.min(getHealthDrained() * 0.2f, Spells.withering_totem.getProperty(WitheringTotem.MAX_EXPLOSION_DAMAGE).floatValue());
|
||||
|
||||
for(EntityLivingBase target : nearby){
|
||||
|
||||
if(EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeIndirectMagicDamage(this,
|
||||
getCaster(), DamageType.MAGIC), damage)){
|
||||
target.addPotionEffect(new PotionEffect(MobEffects.WITHER, Spells.withering_totem.getProperty(Spell.EFFECT_DURATION).intValue(),
|
||||
Spells.withering_totem.getProperty(Spell.EFFECT_STRENGTH).intValue()));
|
||||
}
|
||||
}
|
||||
|
||||
if(world.isRemote) ParticleBuilder.create(Type.SPHERE).pos(GeometryUtils.getCentre(this)).scale((float)radius).clr(0xbe1a53)
|
||||
.fade(0x210f4a).spawn(world);
|
||||
|
||||
this.playSound(WizardrySounds.ENTITY_WITHERING_TOTEM_EXPLODE, 1, 1);
|
||||
super.despawn();
|
||||
}
|
||||
|
||||
// Usually damage multipliers don't need syncing, but here we're using it for the non-standard purpose of targeting
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
super.writeSpawnData(data);
|
||||
data.writeFloat(damageMultiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(ByteBuf data){
|
||||
super.readSpawnData(data);
|
||||
damageMultiplier = data.readFloat();
|
||||
}
|
||||
}
|
||||
@@ -244,6 +244,7 @@ public final class Spells {
|
||||
public static final Spell mark_sacrifice = placeholder();
|
||||
|
||||
public static final Spell stormcloud = placeholder();
|
||||
public static final Spell withering_totem = placeholder();
|
||||
public static final Spell fangs = placeholder();
|
||||
public static final Spell radiant_totem = placeholder();
|
||||
|
||||
@@ -456,6 +457,7 @@ public final class Spells {
|
||||
registry.register(new MarkSacrifice());
|
||||
|
||||
registry.register(new Stormcloud());
|
||||
registry.register(new WitheringTotem());
|
||||
registry.register(new Fangs());
|
||||
registry.register(new RadiantTotem());
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntityDecay.class, "decay", TrackingType.CONSTRUCT).build());
|
||||
registry.register(createEntry(EntityZombieSpawner.class, "zombie_spawner", TrackingType.CONSTRUCT).build());
|
||||
registry.register(createEntry(EntityRadiantTotem.class, "radiant_totem", TrackingType.CONSTRUCT).build());
|
||||
registry.register(createEntry(EntityWitheringTotem.class, "withering_totem", TrackingType.CONSTRUCT).build());
|
||||
|
||||
// These ones don't render, currently that makes no difference here but we might as well separate them
|
||||
registry.register(createEntry(EntityArrowRain.class, "arrow_rain", TrackingType.CONSTRUCT).build());
|
||||
|
||||
@@ -73,6 +73,8 @@ public final class WizardrySounds {
|
||||
public static final SoundEvent ENTITY_RADIANT_TOTEM_VANISH = createSound("entity.radiant_totem.vanish");
|
||||
public static final SoundEvent ENTITY_SHIELD_DEFLECT = createSound("entity.shield.deflect");
|
||||
public static final SoundEvent ENTITY_TORNADO_AMBIENT = createSound("entity.tornado.ambient");
|
||||
public static final SoundEvent ENTITY_WITHERING_TOTEM_AMBIENT = createSound("entity.withering_totem.ambient");
|
||||
public static final SoundEvent ENTITY_WITHERING_TOTEM_EXPLODE = createSound("entity.withering_totem.explode");
|
||||
public static final SoundEvent ENTITY_ZOMBIE_SPAWNER_SPAWN = createSound("entity.zombie_spawner.spawn");
|
||||
|
||||
public static final SoundEvent ENTITY_EVIL_WIZARD_AMBIENT = createSound("entity.evil_wizard.ambient");
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.entity.construct.EntityWitheringTotem;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class WitheringTotem extends SpellConstructRanged<EntityWitheringTotem> {
|
||||
|
||||
public static final String MAX_TARGETS = "max_targets";
|
||||
public static final String MAX_EXPLOSION_DAMAGE = "max_explosion_damage";
|
||||
|
||||
public WitheringTotem(){
|
||||
super("withering_totem", EntityWitheringTotem::new, false);
|
||||
this.addProperties(EFFECT_RADIUS, MAX_TARGETS, DAMAGE, MAX_EXPLOSION_DAMAGE, EFFECT_DURATION, EFFECT_STRENGTH);
|
||||
this.floor(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addConstructExtras(EntityWitheringTotem construct, EnumFacing side, @Nullable EntityLivingBase caster, SpellModifiers modifiers){
|
||||
construct.posY += 1.2;
|
||||
}
|
||||
}
|
||||
@@ -629,6 +629,7 @@ entity.ebwizardry\:stormcloud.name=Stormcloud
|
||||
entity.ebwizardry\:zombie_spawner.name=Zombie Spawner
|
||||
entity.ebwizardry\:boulder.name=Boulder
|
||||
entity.ebwizardry\:radiant_totem.name=Radiant Totem
|
||||
entity.ebwizardry\:withering_totem.name=Withering Totem
|
||||
|
||||
itemGroup.ebwizardry=Wizardry
|
||||
itemGroup.ebwizardryspells=Spells
|
||||
@@ -938,6 +939,7 @@ spell.ebwizardry\:water_breathing=Water Breathing
|
||||
spell.ebwizardry\:whirlwind=Whirlwind
|
||||
spell.ebwizardry\:wither=Wither
|
||||
spell.ebwizardry\:wither_skull=Wither Skull
|
||||
spell.ebwizardry\:withering_totem=Withering Totem
|
||||
spell.ebwizardry\:zombie_apocalypse=Zombie Apocalypse
|
||||
|
||||
spell.ebwizardry\:agility.desc=Grants the caster faster movement speed and greater jump height for 30 seconds.
|
||||
@@ -1120,6 +1122,7 @@ spell.ebwizardry\:water_breathing.desc=Allows the caster to breathe underwater f
|
||||
spell.ebwizardry\:whirlwind.desc=Causes the target to be blown upwards and away from you at speed.
|
||||
spell.ebwizardry\:wither.desc=Fires a ray of darkness which withers anything it touches.
|
||||
spell.ebwizardry\:wither_skull.desc=Launches a wither skull in the direction you are pointing.
|
||||
spell.ebwizardry\:withering_totem.desc=Summons a withering totem where you are pointing, which slowly drains health from nearby creatures. After 30 seconds, the totem explodes, releasing a wave of withering energy that deals more damage the more health that was drained.
|
||||
spell.ebwizardry\:zombie_apocalypse.desc=Opening a portal to the underworld is easy. The difficult part is shutting it again when things go wrong...
|
||||
|
||||
spell.ebwizardry\:invoke_weather.sun=The rain begins to stop...
|
||||
|
||||
@@ -629,6 +629,7 @@ entity.ebwizardry\:stormcloud.name=Stormcloud
|
||||
entity.ebwizardry\:zombie_spawner.name=Zombie Spawner
|
||||
entity.ebwizardry\:boulder.name=Boulder
|
||||
entity.ebwizardry\:radiant_totem.name=Radiant Totem
|
||||
entity.ebwizardry\:withering_totem.name=Withering Totem
|
||||
|
||||
itemGroup.ebwizardry=Wizardry
|
||||
itemGroup.ebwizardryspells=Spells
|
||||
@@ -938,6 +939,7 @@ spell.ebwizardry\:water_breathing=Water Breathing
|
||||
spell.ebwizardry\:whirlwind=Whirlwind
|
||||
spell.ebwizardry\:wither=Wither
|
||||
spell.ebwizardry\:wither_skull=Wither Skull
|
||||
spell.ebwizardry\:withering_totem=Withering Totem
|
||||
spell.ebwizardry\:zombie_apocalypse=Zombie Apocalypse
|
||||
|
||||
spell.ebwizardry\:agility.desc=Grants the caster faster movement speed and greater jump height for 30 seconds.
|
||||
@@ -1120,6 +1122,7 @@ spell.ebwizardry\:water_breathing.desc=Allows the caster to breathe underwater f
|
||||
spell.ebwizardry\:whirlwind.desc=Causes the target to be blown upwards and away from you at speed.
|
||||
spell.ebwizardry\:wither.desc=Fires a ray of darkness which withers anything it touches.
|
||||
spell.ebwizardry\:wither_skull.desc=Launches a wither skull in the direction you are pointing.
|
||||
spell.ebwizardry\:withering_totem.desc=Summons a withering totem where you are pointing, which slowly drains health from nearby creatures. After 30 seconds, the totem explodes, releasing a wave of withering energy that deals more damage the more health that was drained.
|
||||
spell.ebwizardry\:zombie_apocalypse.desc=Opening a portal to the underworld is easy. The difficult part is shutting it again when things go wrong...
|
||||
|
||||
spell.ebwizardry\:invoke_weather.sun=The rain begins to stop...
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
"entity.stormcloud.thunder": {"category": "spells", "sounds": ["ambient/weather/thunder1", "ambient/weather/thunder2", "ambient/weather/thunder3"]},
|
||||
"entity.stormcloud.attack": {"category": "spells", "sounds": ["ebwizardry:arc1", "ebwizardry:arc2", "ebwizardry:arc3"]},
|
||||
"entity.tornado.ambient": {"category": "spells", "sounds": ["ebwizardry:wind"]},
|
||||
"entity.withering_totem.ambient": {"category": "spells", "sounds": ["ebwizardry:dark_aura_loop"]},
|
||||
"entity.withering_totem.explode": {"category": "spells", "sounds": ["mob/wither/death"]},
|
||||
"entity.zombie_spawner.spawn": {"category": "spells", "sounds": ["mob/guardian/elder_death"]},
|
||||
|
||||
"entity.evil_wizard.ambient": {"category": "hostile", "sounds": ["mob/evocation_illager/idle1", "mob/evocation_illager/idle2", "mob/evocation_illager/idle3", "mob/evocation_illager/idle4"]},
|
||||
@@ -341,6 +343,7 @@
|
||||
"spell.whirlwind": {"category": "spells", "sounds": ["ebwizardry:ice"]},
|
||||
"spell.wither": {"category": "spells", "sounds": ["mob/wither/hurt1", "mob/wither/hurt2", "mob/wither/hurt3", "mob/wither/hurt4"]},
|
||||
"spell.wither_skull": {"category": "spells", "sounds": ["mob/wither/shoot"]},
|
||||
"spell.withering_totem": {"category": "spells", "sounds": ["ebwizardry:beam_start"]},
|
||||
"spell.zombie_apocalypse.start": {"category": "spells", "sounds": ["ebwizardry:dark_aura_start"]},
|
||||
"spell.zombie_apocalypse.loop": {"category": "spells", "sounds": ["ebwizardry:dark_aura_loop"]},
|
||||
"spell.zombie_apocalypse.end": {"category": "spells", "sounds": ["ebwizardry:dark_aura_end"]},
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"enabled": {
|
||||
"book": true,
|
||||
"scroll": true,
|
||||
"wands": true,
|
||||
"npcs": true,
|
||||
"dispensers": true,
|
||||
"commands": true,
|
||||
"treasure": true,
|
||||
"trades": true,
|
||||
"looting": true
|
||||
},
|
||||
"tier": "advanced",
|
||||
"element": "necromancy",
|
||||
"type": "construct",
|
||||
"cost": 50,
|
||||
"chargeup": 20,
|
||||
"cooldown": 200,
|
||||
"base_properties": {
|
||||
"range": 8,
|
||||
"duration": 600,
|
||||
"effect_radius": 6,
|
||||
"max_targets": 1,
|
||||
"damage": 1,
|
||||
"max_explosion_damage": 10,
|
||||
"effect_duration": 120,
|
||||
"effect_strength": 0
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
Reference in New Issue
Block a user