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:
Lifetime: 6 ticks
Colour: white */ public static final ResourceLocation FLASH = new ResourceLocation(Wizardry.MODID,"flash"); + /** Particle that looks like the guardian's beam attack.

Defaults:
Lifetime: 1 tick */ + public static final ResourceLocation GUARDIAN_BEAM = new ResourceLocation(Wizardry.MODID,"guardian_beam"); /** Small shard of ice.

Defaults:
Lifetime: 8-40 ticks
Gravity: true */ public static final ResourceLocation ICE = new ResourceLocation(Wizardry.MODID,"ice"); /** Single leaf.

Defaults:
Lifetime: 10-15 ticks
Velocity: (0, -0.03, 0) diff --git a/src/main/resources/assets/ebwizardry/lang/en_gb.lang b/src/main/resources/assets/ebwizardry/lang/en_gb.lang index aef87af2..82d1fc1e 100644 --- a/src/main/resources/assets/ebwizardry/lang/en_gb.lang +++ b/src/main/resources/assets/ebwizardry/lang/en_gb.lang @@ -850,6 +850,7 @@ spell.ebwizardry\:greater_telekinesis=Greater Telekinesis spell.ebwizardry\:greater_ward=Greater Ward spell.ebwizardry\:group_heal=Group Heal spell.ebwizardry\:growth_aura=Growth Aura +spell.ebwizardry\:guardian_beam=Guardian Beam spell.ebwizardry\:hailstorm=Hailstorm spell.ebwizardry\:heal=Heal spell.ebwizardry\:heal_ally=Heal Ally @@ -1035,6 +1036,7 @@ spell.ebwizardry\:greater_telekinesis.desc=Allows the caster to pick up a block spell.ebwizardry\:greater_ward.desc=Grants the caster a strong shielding effect that greatly reduces incoming magic damage for 30 seconds. spell.ebwizardry\:group_heal.desc=Heals the caster and all nearby allies and summoned creatures by 3 hearts. spell.ebwizardry\:growth_aura.desc=Grows all crops near the caster. Also grows tall grass and flowers on grass. +spell.ebwizardry\:guardian_beam.desc=Fires a guardian eye beam in the direction you are pointing, which damages targets and depletes their air supply when underwater. spell.ebwizardry\:hailstorm.desc=It was during the great winter of the third age that the ice mages discovered their true power. spell.ebwizardry\:heal.desc=Heals the caster by 2 hearts. spell.ebwizardry\:heal_ally.desc=Heals the target by 2 and a half hearts. diff --git a/src/main/resources/assets/ebwizardry/lang/en_us.lang b/src/main/resources/assets/ebwizardry/lang/en_us.lang index 27722758..f5515718 100644 --- a/src/main/resources/assets/ebwizardry/lang/en_us.lang +++ b/src/main/resources/assets/ebwizardry/lang/en_us.lang @@ -850,6 +850,7 @@ spell.ebwizardry\:greater_telekinesis=Greater Telekinesis spell.ebwizardry\:greater_ward=Greater Ward spell.ebwizardry\:group_heal=Group Heal spell.ebwizardry\:growth_aura=Growth Aura +spell.ebwizardry\:guardian_beam=Guardian Beam spell.ebwizardry\:hailstorm=Hailstorm spell.ebwizardry\:heal=Heal spell.ebwizardry\:heal_ally=Heal Ally @@ -1035,6 +1036,7 @@ spell.ebwizardry\:greater_telekinesis.desc=Allows the caster to pick up a block spell.ebwizardry\:greater_ward.desc=Grants the caster a strong shielding effect that greatly reduces incoming magic damage for 30 seconds. spell.ebwizardry\:group_heal.desc=Heals the caster and all nearby allies and summoned creatures by 3 hearts. spell.ebwizardry\:growth_aura.desc=Grows all crops near the caster. Also grows tall grass and flowers on grass. +spell.ebwizardry\:guardian_beam.desc=Fires a guardian eye beam in the direction you are pointing, which damages targets and depletes their air supply when underwater. spell.ebwizardry\:hailstorm.desc=It was during the great winter of the third age that the ice mages discovered their true power. spell.ebwizardry\:heal.desc=Heals the caster by 2 hearts. spell.ebwizardry\:heal_ally.desc=Heals the target by 2 and a half hearts. diff --git a/src/main/resources/assets/ebwizardry/sounds.json b/src/main/resources/assets/ebwizardry/sounds.json index f967a670..a94a296f 100644 --- a/src/main/resources/assets/ebwizardry/sounds.json +++ b/src/main/resources/assets/ebwizardry/sounds.json @@ -218,6 +218,9 @@ "spell.greater_ward": {"category": "spells", "sounds": ["ebwizardry:buff_large"]}, "spell.group_heal": {"category": "spells", "sounds": ["ebwizardry:heal"]}, "spell.growth_aura": {"category": "spells", "sounds": ["ebwizardry:conjure_large"]}, + "spell.guardian_beam.start": {"category": "spells", "sounds": ["mob/guardian/attack_loop"]}, + "spell.guardian_beam.loop": {"category": "spells", "sounds": ["mob/guardian/attack_loop"]}, + "spell.guardian_beam.end": {"category": "spells", "sounds": ["mob/guardian/attack_loop"]}, "spell.hailstorm": {"category": "spells", "sounds": ["mob/illusion_illager/prepare_blind"]}, "spell.heal": {"category": "spells", "sounds": ["ebwizardry:heal"]}, "spell.heal_ally": {"category": "spells", "sounds": ["ebwizardry:heal"]}, diff --git a/src/main/resources/assets/ebwizardry/spells/guardian_beam.json b/src/main/resources/assets/ebwizardry/spells/guardian_beam.json new file mode 100644 index 00000000..b3a465e1 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/spells/guardian_beam.json @@ -0,0 +1,24 @@ +{ + "enabled": { + "book": true, + "scroll": true, + "wands": true, + "npcs": true, + "dispensers": true, + "commands": true, + "treasure": true, + "trades": true, + "looting": true + }, + "tier": "advanced", + "element": "sorcery", + "type": "attack", + "cost": 10, + "chargeup": 0, + "cooldown": 50, + "base_properties": { + "range": 12, + "damage": 5, + "air_depletion": 70 + } +} \ No newline at end of file