diff --git a/src/main/java/electroblob/wizardry/client/ClientProxy.java b/src/main/java/electroblob/wizardry/client/ClientProxy.java index 4ad38117..95a72691 100644 --- a/src/main/java/electroblob/wizardry/client/ClientProxy.java +++ b/src/main/java/electroblob/wizardry/client/ClientProxy.java @@ -379,6 +379,7 @@ public class ClientProxy extends CommonProxy { ParticleWizardry.registerParticle(Type.DARK_MAGIC, ParticleDarkMagic::new); ParticleWizardry.registerParticle(Type.DUST, ParticleDust::new); ParticleWizardry.registerParticle(Type.FLASH, ParticleFlash::new); + ParticleWizardry.registerParticle(Type.GUARDIAN_BEAM, ParticleGuardianBeam::new); ParticleWizardry.registerParticle(Type.ICE, ParticleIce::new); ParticleWizardry.registerParticle(Type.LEAF, ParticleLeaf::new); ParticleWizardry.registerParticle(Type.LIGHTNING, ParticleLightning::new); diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleGuardianBeam.java b/src/main/java/electroblob/wizardry/client/particle/ParticleGuardianBeam.java new file mode 100644 index 00000000..ee92031b --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/ParticleGuardianBeam.java @@ -0,0 +1,78 @@ +package electroblob.wizardry.client.particle; + +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.vertex.DefaultVertexFormats; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import org.lwjgl.opengl.GL11; + +public class ParticleGuardianBeam extends ParticleTargeted { + + /** Half the width of the beam. */ + private static final float THICKNESS = 0.15f; + + private static final ResourceLocation TEXTURE = new ResourceLocation("minecraft:textures/entity/guardian_beam.png"); + + public ParticleGuardianBeam(World world, double x, double y, double z){ + super(world, x, y, z); // Does't use TextureAtlasSprite + this.setRBGColorF(1, 1, 1); + this.setMaxAge(3); + this.particleScale = 1; + } + + @Override + public int getFXLayer(){ + return 3; + } + + @Override + protected void draw(Tessellator tessellator, double length, float partialTicks){ + + float scale = this.particleScale; + + BufferBuilder buffer = tessellator.getBuffer(); + + GlStateManager.disableLighting(); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + + GlStateManager.pushMatrix(); + // Enables texture tiling (Also used for guardian beam, beacon beam and ender crystal beam, amongst others) + GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); + GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); + + GlStateManager.rotate(Minecraft.getMinecraft().player.ticksExisted + partialTicks, 0, 0, 1); + + Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + + float t = THICKNESS * scale; + float v1 = 2 * (particleAge + partialTicks) / particleMaxAge; + float v2 = v1 + (float)length * 2; // Multiply by 2 to make it squished like it is in vanilla + + buffer.pos(-t, 0, 0) .tex(0, v1) .color(particleRed, particleGreen, particleBlue, 1).endVertex(); + buffer.pos( t, 0, 0) .tex(0.5, v1) .color(particleRed, particleGreen, particleBlue, 1).endVertex(); + buffer.pos( t, 0, length).tex(0.5, v2).color(particleRed, particleGreen, particleBlue, 1).endVertex(); + buffer.pos(-t, 0, length).tex(0, v2).color(particleRed, particleGreen, particleBlue, 1).endVertex(); + + buffer.pos(0, -t, 0) .tex(0, v1) .color(particleRed, particleGreen, particleBlue, 1).endVertex(); + buffer.pos(0, t, 0) .tex(0.5, v1) .color(particleRed, particleGreen, particleBlue, 1).endVertex(); + buffer.pos(0, t, length).tex(0.5, v2).color(particleRed, particleGreen, particleBlue, 1).endVertex(); + buffer.pos(0, -t, length).tex(0, v2).color(particleRed, particleGreen, particleBlue, 1).endVertex(); + + tessellator.draw(); + +// GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); +// GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); + + GlStateManager.popMatrix(); + + // Makes the rain go weird + //GlStateManager.enableLighting(); + } + +} diff --git a/src/main/java/electroblob/wizardry/registry/Spells.java b/src/main/java/electroblob/wizardry/registry/Spells.java index e9c5f1a8..5827d72c 100644 --- a/src/main/java/electroblob/wizardry/registry/Spells.java +++ b/src/main/java/electroblob/wizardry/registry/Spells.java @@ -249,6 +249,7 @@ public final class Spells { public static final Spell stormcloud = placeholder(); public static final Spell withering_totem = placeholder(); public static final Spell fangs = placeholder(); + public static final Spell guardian_beam = placeholder(); public static final Spell radiant_totem = placeholder(); public static final Spell firestorm = placeholder(); @@ -465,6 +466,7 @@ public final class Spells { registry.register(new Stormcloud()); registry.register(new WitheringTotem()); registry.register(new Fangs()); + registry.register(new GuardianBeam()); registry.register(new RadiantTotem()); registry.register(new Firestorm()); diff --git a/src/main/java/electroblob/wizardry/spell/GuardianBeam.java b/src/main/java/electroblob/wizardry/spell/GuardianBeam.java new file mode 100644 index 00000000..14b4108b --- /dev/null +++ b/src/main/java/electroblob/wizardry/spell/GuardianBeam.java @@ -0,0 +1,90 @@ +package electroblob.wizardry.spell; + +import electroblob.wizardry.item.SpellActions; +import electroblob.wizardry.util.*; +import electroblob.wizardry.util.MagicDamage.DamageType; +import electroblob.wizardry.util.ParticleBuilder.Type; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.MobEffects; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +public class GuardianBeam extends SpellRay { + + public static final String AIR_DEPLETION = "air_depletion"; + + public GuardianBeam(){ + super("guardian_beam", SpellActions.POINT, true); + addProperties(DAMAGE, AIR_DEPLETION); + } + + @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){ + + if(EntityUtils.isLiving(target)){ + + if(ticksInUse % 50 == 1){ + + EntityUtils.attackEntityWithoutKnockback(target, + MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), + getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY)); + + if(!((EntityLivingBase)target).canBreatheUnderwater() && !((EntityLivingBase)target).isPotionActive(MobEffects.WATER_BREATHING)){ + target.setAir(Math.max(-20, target.getAir() - getProperty(AIR_DEPLETION).intValue())); + } + } + + if(world.isRemote){ + + float t = (ticksInUse % 50) / 50f; + float yellowness = t * t; + int r = 64 + (int)(yellowness * 191.0F); + int g = 32 + (int)(yellowness * 191.0F); + int b = 128 - (int)(yellowness * 64.0F); + + if(ticksInUse % 3 == 0) ParticleBuilder.create(Type.GUARDIAN_BEAM).entity(caster) + .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target) + .clr(r, g, b).spawn(world); + + Vec3d direction = GeometryUtils.getCentre(target).subtract(origin); + Vec3d pos = origin.add(direction.scale(world.rand.nextFloat())); + ParticleBuilder.create(Type.MAGIC_BUBBLE, world.rand, pos.x, pos.y, pos.z, 0.15, false).spawn(world); + } + } + + return true; + } + + @Override + protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){ + return false; + } + + @Override + protected boolean onMiss(World world, EntityLivingBase caster, Vec3d origin, Vec3d direction, int ticksInUse, SpellModifiers modifiers){ + return false; // Only works on hit + } + + @Override + protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){ + } +} diff --git a/src/main/java/electroblob/wizardry/util/ParticleBuilder.java b/src/main/java/electroblob/wizardry/util/ParticleBuilder.java index 7603d8f6..618be8b8 100644 --- a/src/main/java/electroblob/wizardry/util/ParticleBuilder.java +++ b/src/main/java/electroblob/wizardry/util/ParticleBuilder.java @@ -107,6 +107,8 @@ public final class ParticleBuilder { public static final ResourceLocation DUST = new ResourceLocation(Wizardry.MODID,"dust"); /** Rapid flash, like fireworks.
Defaults: