From 650344a0c8c13c6f315f0497cf663fe1fbd2ee5d Mon Sep 17 00:00:00 2001 From: Electroblob77 <35599699+Electroblob77@users.noreply.github.com> Date: Mon, 18 May 2020 20:41:41 +0100 Subject: [PATCH] Add stormcloud spell --- .../wizardry/client/ClientProxy.java | 1 + .../entity/construct/EntityStormcloud.java | 122 ++++++++++++++++++ .../electroblob/wizardry/registry/Spells.java | 10 +- .../wizardry/registry/WizardryEntities.java | 1 + .../wizardry/registry/WizardrySounds.java | 2 + .../wizardry/spell/Stormcloud.java | 22 ++++ .../assets/ebwizardry/lang/en_gb.lang | 3 + .../assets/ebwizardry/lang/en_us.lang | 3 + .../resources/assets/ebwizardry/sounds.json | 3 + .../assets/ebwizardry/spells/stormcloud.json | 25 ++++ .../ebwizardry/textures/spells/stormcloud.png | Bin 0 -> 5816 bytes 11 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 src/main/java/electroblob/wizardry/entity/construct/EntityStormcloud.java create mode 100644 src/main/java/electroblob/wizardry/spell/Stormcloud.java create mode 100644 src/main/resources/assets/ebwizardry/spells/stormcloud.json create mode 100644 src/main/resources/assets/ebwizardry/textures/spells/stormcloud.png diff --git a/src/main/java/electroblob/wizardry/client/ClientProxy.java b/src/main/java/electroblob/wizardry/client/ClientProxy.java index c64b918d..ddb07c7b 100644 --- a/src/main/java/electroblob/wizardry/client/ClientProxy.java +++ b/src/main/java/electroblob/wizardry/client/ClientProxy.java @@ -795,6 +795,7 @@ public class ClientProxy extends CommonProxy { RenderingRegistry.registerEntityRenderingHandler(EntityStormElemental.class, RenderBlank::new); RenderingRegistry.registerEntityRenderingHandler(EntityEarthquake.class, RenderBlank::new); RenderingRegistry.registerEntityRenderingHandler(EntityHailstorm.class, RenderBlank::new); + RenderingRegistry.registerEntityRenderingHandler(EntityStormcloud.class, RenderBlank::new); // Runes on ground RenderingRegistry.registerEntityRenderingHandler(EntityHealAura.class, diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityStormcloud.java b/src/main/java/electroblob/wizardry/entity/construct/EntityStormcloud.java new file mode 100644 index 00000000..895b5511 --- /dev/null +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityStormcloud.java @@ -0,0 +1,122 @@ +package electroblob.wizardry.entity.construct; + +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.registry.Spells; +import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.spell.Spell; +import electroblob.wizardry.util.MagicDamage; +import electroblob.wizardry.util.ParticleBuilder; +import electroblob.wizardry.util.ParticleBuilder.Type; +import electroblob.wizardry.util.WizardryUtilities; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.world.World; + +import java.util.List; + +public class EntityStormcloud extends EntityMagicConstruct { + +// private static final DataParameter RADIUS = new DataParameter<>(21, DataSerializers.FLOAT); + + public EntityStormcloud(World world){ + super(world); + this.height = 2.0f; + this.width = Spells.stormcloud.getProperty(Spell.EFFECT_RADIUS).floatValue() * 2; + } + +// @Override +// protected void entityInit(){ +// super.entityInit(); +// this.getDataManager().register(RADIUS, width); // TODO: This doesn't work, implement blast modifiers properly into SpellConstruct +// } + +// public void multiplyWidth(float multiplier){ +// this.setSize(width * multiplier, height); +// this.getDataManager().set(RADIUS, width); +// } + + public void onUpdate(){ + + super.onUpdate(); + +// if(world.isRemote){ +// float radius = this.getDataManager().get(RADIUS); +// if(radius != width) this.setSize(radius, height); +// }else{ +// if(this.getDataManager().get(RADIUS) != width) this.getDataManager().set(RADIUS, width); +// } + +// if(this.ticksExisted % 35 == 0) this.playSound(WizardrySounds.ENTITY_STORMCLOUD_AMBIENT, 1, 1); + + if(this.world.isRemote){ + + float areaFactor = (width * width) / 36; // Ensures cloud/raindrop density stays the same for different sizes + + for(int i = 0; i < 2 * areaFactor; i++) ParticleBuilder.create(Type.CLOUD, this) + .clr(0.3f, 0.3f, 0.3f).shaded(true).spawn(world); + } + + List targets = world.getEntitiesWithinAABB(EntityLivingBase.class, + this.getEntityBoundingBox().expand(0, -10, 0)); + + float damage = Spells.stormcloud.getProperty(Spell.DAMAGE).floatValue() * this.damageMultiplier; + + for(EntityLivingBase target : targets){ + + if(this.isValidTarget(target)){ + + if(target.ticksExisted % 150 == 0){ // Use target's lifetime so they don't all get hit at once, looks better + + if(!this.world.isRemote){ + WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeIndirectMagicDamage( + this, this.getCaster(), MagicDamage.DamageType.SHOCK), damage); + }else{ + ParticleBuilder.create(Type.LIGHTNING).pos(target.posX, posY + height/2, target.posZ) + .target(target).scale(2).spawn(world); + ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height, target.posZ); + } + + target.playSound(WizardrySounds.ENTITY_STORMCLOUD_THUNDER, 1, 1.6f); + target.playSound(WizardrySounds.ENTITY_STORMCLOUD_ATTACK, 1, 1); + } + } + } + +// BlockPos pos = new BlockPos(this); +// +// for(int x = -(int)(this.width/2); x <= this.width/2 + 0.5; x++){ +// for(int z = -(int)(this.width/2); z <= this.width/2 + 0.5; z++){ +// +// int y = WizardryUtilities.getNearestFloor() +// +// } +// } + + } + + // Need to sync the caster so they don't have particles spawned at them + + @Override + public void writeSpawnData(ByteBuf data){ + super.writeSpawnData(data); + if(getCaster() != null) data.writeInt(getCaster().getEntityId()); + } + + @Override + public void readSpawnData(ByteBuf data){ + + super.readSpawnData(data); + + if(!data.isReadable()) return; + + Entity entity = world.getEntityByID(data.readInt()); + + if(entity instanceof EntityLivingBase){ + setCaster((EntityLivingBase)entity); + }else{ + Wizardry.logger.warn("Stormcloud caster with ID in spawn data not found"); + } + } + +} diff --git a/src/main/java/electroblob/wizardry/registry/Spells.java b/src/main/java/electroblob/wizardry/registry/Spells.java index d81fd47d..704a956f 100644 --- a/src/main/java/electroblob/wizardry/registry/Spells.java +++ b/src/main/java/electroblob/wizardry/registry/Spells.java @@ -8,7 +8,6 @@ import electroblob.wizardry.item.SpellActions; import electroblob.wizardry.spell.*; import net.minecraft.entity.projectile.EntitySnowball; import net.minecraft.init.MobEffects; -import net.minecraft.item.EnumAction; import net.minecraft.util.ResourceLocation; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod; @@ -239,6 +238,10 @@ public final class Spells { public static final Spell slow_time = placeholder(); public static final Spell resurrection = placeholder(); + // Wizardry 4.3 spells + + public static final Spell stormcloud = placeholder(); + @SubscribeEvent public static void register(RegistryEvent.Register event){ @@ -437,6 +440,11 @@ public final class Spells { registry.register(new SpeedTime()); registry.register(new SlowTime()); registry.register(new Resurrection()); + + // Wizardry 4.3 spells + + registry.register(new Stormcloud()); + } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/registry/WizardryEntities.java b/src/main/java/electroblob/wizardry/registry/WizardryEntities.java index ddb374bb..8324e692 100644 --- a/src/main/java/electroblob/wizardry/registry/WizardryEntities.java +++ b/src/main/java/electroblob/wizardry/registry/WizardryEntities.java @@ -150,6 +150,7 @@ public class WizardryEntities { registry.register(createEntry(EntityArrowRain.class, "arrow_rain", TrackingType.CONSTRUCT).build()); registry.register(createEntry(EntityEarthquake.class, "earthquake", TrackingType.CONSTRUCT).build()); registry.register(createEntry(EntityHailstorm.class, "hailstorm", TrackingType.CONSTRUCT).build()); + registry.register(createEntry(EntityStormcloud.class, "stormcloud", TrackingType.CONSTRUCT).build()); // These ones move, velocity updates are sent if that's not at constant velocity registry.register(createEntry(EntityShield.class, "shield") .tracker(160, 10, true).build()); diff --git a/src/main/java/electroblob/wizardry/registry/WizardrySounds.java b/src/main/java/electroblob/wizardry/registry/WizardrySounds.java index 2e203b04..9f2538c4 100644 --- a/src/main/java/electroblob/wizardry/registry/WizardrySounds.java +++ b/src/main/java/electroblob/wizardry/registry/WizardrySounds.java @@ -86,6 +86,8 @@ public final class WizardrySounds { public static final SoundEvent ENTITY_STORM_ELEMENTAL_WIND = createSound("entity.storm_elemental.wind"); public static final SoundEvent ENTITY_STORM_ELEMENTAL_HURT = createSound("entity.storm_elemental.hurt"); public static final SoundEvent ENTITY_STORM_ELEMENTAL_DEATH = createSound("entity.storm_elemental.death"); + public static final SoundEvent ENTITY_STORMCLOUD_THUNDER = createSound("entity.stormcloud.thunder"); + public static final SoundEvent ENTITY_STORMCLOUD_ATTACK = createSound("entity.stormcloud.attack"); public static final SoundEvent ENTITY_WIZARD_YES = createSound("entity.wizard.yes"); public static final SoundEvent ENTITY_WIZARD_NO = createSound("entity.wizard.no"); public static final SoundEvent ENTITY_WIZARD_AMBIENT = createSound("entity.wizard.ambient"); diff --git a/src/main/java/electroblob/wizardry/spell/Stormcloud.java b/src/main/java/electroblob/wizardry/spell/Stormcloud.java new file mode 100644 index 00000000..5be5ec34 --- /dev/null +++ b/src/main/java/electroblob/wizardry/spell/Stormcloud.java @@ -0,0 +1,22 @@ +package electroblob.wizardry.spell; + +import electroblob.wizardry.entity.construct.EntityStormcloud; +import electroblob.wizardry.util.SpellModifiers; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumFacing; + +import javax.annotation.Nullable; + +public class Stormcloud extends SpellConstructRanged { + + public Stormcloud(){ + super("stormcloud", EntityStormcloud::new, false); + this.addProperties(DAMAGE, EFFECT_RADIUS); + this.floor(true); + } + + @Override + protected void addConstructExtras(EntityStormcloud construct, EnumFacing side, @Nullable EntityLivingBase caster, SpellModifiers modifiers){ + construct.posY += 5; + } +} diff --git a/src/main/resources/assets/ebwizardry/lang/en_gb.lang b/src/main/resources/assets/ebwizardry/lang/en_gb.lang index adcf6990..086a6d18 100644 --- a/src/main/resources/assets/ebwizardry/lang/en_gb.lang +++ b/src/main/resources/assets/ebwizardry/lang/en_gb.lang @@ -485,6 +485,7 @@ entity.ebwizardry\:ring_of_fire.name=Ring of Fire entity.ebwizardry\:earthquake.name=Earthquake entity.ebwizardry\:hailstorm.name=Hailstorm entity.ebwizardry\:lightning_pulse.name=Lightning Pulse +entity.ebwizardry\:stormcloud.name=Stormcloud itemGroup.ebwizardry=Wizardry itemGroup.ebwizardryspells=Spells @@ -747,6 +748,7 @@ spell.ebwizardry\:spectral_pathway=Spectral Pathway spell.ebwizardry\:speed_time=Speed Time spell.ebwizardry\:spider_swarm=Spider Swarm spell.ebwizardry\:static_aura=Static Aura +spell.ebwizardry\:stormcloud=Stormcloud spell.ebwizardry\:summon_blaze=Summon Blaze spell.ebwizardry\:summon_ice_giant=Summon Ice Giant spell.ebwizardry\:summon_ice_wraith=Summon Ice Wraith @@ -921,6 +923,7 @@ spell.ebwizardry\:spectral_pathway.desc=Creates an indestructible magical bridge spell.ebwizardry\:speed_time.desc=...day, night, dawn, dusk, sunrise and sunset\: thus is the passage of time, which traps us in an endless cycle of... spell.ebwizardry\:spider_swarm.desc=Summons a swarm of venomous spiders to fight for you. The spiders will disappear after 30 seconds or if they are killed. spell.ebwizardry\:static_aura.desc=Surrounds the caster with lightning for 30 seconds, firing a spark of lightning at anything that hits them. +spell.ebwizardry\:stormcloud.desc=Conjures a floating stormcloud where you are pointing that strikes lightning beneath it. spell.ebwizardry\:summon_blaze.desc=Summons a blaze to fight for you. The blaze will disappear after 30 seconds or if it is killed. spell.ebwizardry\:summon_ice_giant.desc="Smash them!" spell.ebwizardry\:summon_ice_wraith.desc=Summons an ice wraith to fight for you. The ice wraith will disappear after 30 seconds or if it is killed. diff --git a/src/main/resources/assets/ebwizardry/lang/en_us.lang b/src/main/resources/assets/ebwizardry/lang/en_us.lang index fc4a1010..5fa24eb1 100644 --- a/src/main/resources/assets/ebwizardry/lang/en_us.lang +++ b/src/main/resources/assets/ebwizardry/lang/en_us.lang @@ -485,6 +485,7 @@ entity.ebwizardry\:ring_of_fire.name=Ring of Fire entity.ebwizardry\:earthquake.name=Earthquake entity.ebwizardry\:hailstorm.name=Hailstorm entity.ebwizardry\:lightning_pulse.name=Lightning Pulse +entity.ebwizardry\:stormcloud.name=Stormcloud itemGroup.ebwizardry=Wizardry itemGroup.ebwizardryspells=Spells @@ -747,6 +748,7 @@ spell.ebwizardry\:spectral_pathway=Spectral Pathway spell.ebwizardry\:speed_time=Speed Time spell.ebwizardry\:spider_swarm=Spider Swarm spell.ebwizardry\:static_aura=Static Aura +spell.ebwizardry\:stormcloud=Stormcloud spell.ebwizardry\:summon_blaze=Summon Blaze spell.ebwizardry\:summon_ice_giant=Summon Ice Giant spell.ebwizardry\:summon_ice_wraith=Summon Ice Wraith @@ -921,6 +923,7 @@ spell.ebwizardry\:spectral_pathway.desc=Creates an indestructible magical bridge spell.ebwizardry\:speed_time.desc=...day, night, dawn, dusk, sunrise and sunset\: thus is the passage of time, which traps us in an endless cycle of... spell.ebwizardry\:spider_swarm.desc=Summons a swarm of venomous spiders to fight for you. The spiders will disappear after 30 seconds or if they are killed. spell.ebwizardry\:static_aura.desc=Surrounds the caster with lightning for 30 seconds, firing a spark of lightning at anything that hits them. +spell.ebwizardry\:stormcloud.desc=Conjures a floating stormcloud where you are pointing that strikes lightning beneath it. spell.ebwizardry\:summon_blaze.desc=Summons a blaze to fight for you. The blaze will disappear after 30 seconds or if it is killed. spell.ebwizardry\:summon_ice_giant.desc="Smash them!" spell.ebwizardry\:summon_ice_wraith.desc=Summons an ice wraith to fight for you. The ice wraith will disappear after 30 seconds or if it is killed. diff --git a/src/main/resources/assets/ebwizardry/sounds.json b/src/main/resources/assets/ebwizardry/sounds.json index 7686d7ba..1078a058 100644 --- a/src/main/resources/assets/ebwizardry/sounds.json +++ b/src/main/resources/assets/ebwizardry/sounds.json @@ -33,6 +33,8 @@ "entity.lightning_sigil.trigger": {"category": "spells", "sounds": ["ebwizardry:arc1", "ebwizardry:arc2", "ebwizardry:arc3"]}, "entity.meteor.falling": {"category": "spells", "sounds": ["ebwizardry:flames_loop"]}, "entity.shield.deflect": {"category": "spells", "sounds": ["ebwizardry:effect1", "ebwizardry:effect2"]}, + "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.evil_wizard.ambient": {"category": "hostile", "sounds": ["mob/evocation_illager/idle1", "mob/evocation_illager/idle2", "mob/evocation_illager/idle3", "mob/evocation_illager/idle4"]}, @@ -285,6 +287,7 @@ "spell.spider_swarm": {"category": "spells", "sounds": ["random/fizz"]}, "spell.static_aura": {"category": "spells", "sounds": ["ebwizardry:buff"]}, "spell.static_aura.retaliate": {"category": "spells", "sounds": ["ebwizardry:arc1", "ebwizardry:arc2", "ebwizardry:arc3"]}, + "spell.stormcloud": {"category": "spells", "sounds": ["ambient/weather/thunder1", "ambient/weather/thunder2", "ambient/weather/thunder3"]}, "spell.summon_blaze": {"category": "spells", "sounds": ["mob/wither/idle1", "mob/wither/idle2", "mob/wither/idle3", "mob/wither/idle4"]}, "spell.summon_ice_giant": {"category": "spells", "sounds": ["mob/evocation_illager/prepare_summon"]}, "spell.summon_ice_wraith": {"category": "spells", "sounds": ["mob/wither/idle1", "mob/wither/idle2", "mob/wither/idle3", "mob/wither/idle4"]}, diff --git a/src/main/resources/assets/ebwizardry/spells/stormcloud.json b/src/main/resources/assets/ebwizardry/spells/stormcloud.json new file mode 100644 index 00000000..20a33a0a --- /dev/null +++ b/src/main/resources/assets/ebwizardry/spells/stormcloud.json @@ -0,0 +1,25 @@ +{ + "enabled": { + "book": true, + "scroll": true, + "wands": true, + "npcs": true, + "dispensers": true, + "commands": true, + "treasure": true, + "trades": true, + "looting": true + }, + "tier": "advanced", + "element": "lightning", + "type": "construct", + "cost": 60, + "chargeup": 0, + "cooldown": 150, + "base_properties": { + "duration": 600, + "range": 10, + "damage": 8, + "effect_radius": 3 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ebwizardry/textures/spells/stormcloud.png b/src/main/resources/assets/ebwizardry/textures/spells/stormcloud.png new file mode 100644 index 0000000000000000000000000000000000000000..27340d0b80a40fb3fc113c2904b2f8eaf449c30e GIT binary patch literal 5816 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 literal 0 HcmV?d00001