From b6400c72a7bd6fbbb8ba542f8279fc40f4ddb133 Mon Sep 17 00:00:00 2001 From: Electroblob <35599699+Electroblob77@users.noreply.github.com> Date: Sat, 9 Jun 2018 17:36:54 +0100 Subject: [PATCH] Genericise spell casting AI class --- .../entity/living/EntityAIAttackSpell.java | 51 ++++++++----------- .../entity/living/EntityEvilWizard.java | 2 +- .../wizardry/entity/living/EntityPhoenix.java | 2 +- .../entity/living/EntityShadowWraith.java | 2 +- .../entity/living/EntityStormElemental.java | 2 +- .../wizardry/entity/living/EntityWizard.java | 2 +- 6 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityAIAttackSpell.java b/src/main/java/electroblob/wizardry/entity/living/EntityAIAttackSpell.java index e4384e9b..57e5cadf 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityAIAttackSpell.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityAIAttackSpell.java @@ -22,14 +22,14 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage; * Entity AI class for use by instances of {@link ISpellCaster}. This deals with pathing, the spell casting itself and * the attack cooldown. Also provides an automatic implementation of continuous spell casting using the methods * specified in {@code ISpellCaster}; all the entity class needs to do is implement those methods. + * @param The type of entity that this AI belongs to; must both extend EntityLiving and implement ISpellCaster */ -public class EntityAIAttackSpell extends EntityAIBase { +// Mmmm generics... +public class EntityAIAttackSpell extends EntityAIBase { - /** The entity the AI instance has been applied to. */ - private final EntityLiving attacker; - /** The entity the AI instance has been applied to, but as an ISpellCaster. */ - private final ISpellCaster caster; - /** The tagret to be attacked. */ + /** The entity the AI instance has been applied to. Thanks to type parameters, methods from both EntityLiving and + * ISummonedCreature may be invoked on this field. */ + private final T attacker; private EntityLivingBase target; /** * Decremented each tick while greater than 0. When a spell is cast, this is set to that spell's cooldown plus the @@ -65,23 +65,14 @@ public class EntityAIAttackSpell extends EntityAIBase { * attacking, and also the amount that is added to the cooldown of the spell that has just been cast. * @param continuousSpellDuration The number of ticks that continuous spells will be cast for before cooling down. */ - public EntityAIAttackSpell(ISpellCaster attacker, double speed, float maxDistance, int baseCooldown, - int continuousSpellDuration){ - + public EntityAIAttackSpell(T attacker, double speed, float maxDistance, int baseCooldown, int continuousSpellDuration){ this.cooldown = -1; - - if(!(attacker instanceof EntityLiving)){ - throw new IllegalArgumentException( - "Tried to create an EntityAICastSpell for an entity that isn't an EntityLiving"); - }else{ - this.caster = attacker; - this.attacker = (EntityLiving)attacker; - this.baseCooldown = baseCooldown; - this.continuousSpellDuration = continuousSpellDuration; - this.speed = speed; - this.maxAttackDistance = maxDistance * maxDistance; - this.setMutexBits(3); - } + this.attacker = attacker; + this.baseCooldown = baseCooldown; + this.continuousSpellDuration = continuousSpellDuration; + this.speed = speed; + this.maxAttackDistance = maxDistance * maxDistance; + this.setMutexBits(3); } @Override @@ -112,7 +103,7 @@ public class EntityAIAttackSpell extends EntityAIBase { } private void setContinuousSpellAndNotify(Spell spell, SpellModifiers modifiers){ - caster.setContinuousSpell(spell); + attacker.setContinuousSpell(spell); WizardryPacketHandler.net.sendToAllAround( new PacketNPCCastSpell.Message(attacker.getEntityId(), target == null ? -1 : target.getEntityId(), EnumHand.MAIN_HAND, spell.id(), modifiers), @@ -151,11 +142,11 @@ public class EntityAIAttackSpell extends EntityAIBase { if(distanceSq > (double)this.maxAttackDistance || !targetIsVisible // ...or the spell is cancelled via events... || MinecraftForge.EVENT_BUS - .post(new SpellCastEvent.Tick(attacker, caster.getContinuousSpell(), caster.getModifiers(), + .post(new SpellCastEvent.Tick(attacker, attacker.getContinuousSpell(), attacker.getModifiers(), Source.NPC, this.continuousSpellDuration - this.continuousSpellTimer)) // ...or the spell no longer succeeds... - || !caster.getContinuousSpell().cast(attacker.world, attacker, EnumHand.MAIN_HAND, - this.continuousSpellDuration - this.continuousSpellTimer, target, caster.getModifiers()) + || !attacker.getContinuousSpell().cast(attacker.world, attacker, EnumHand.MAIN_HAND, + this.continuousSpellDuration - this.continuousSpellTimer, target, attacker.getModifiers()) // ...or the time has elapsed... || this.continuousSpellTimer == 0){ @@ -167,8 +158,8 @@ public class EntityAIAttackSpell extends EntityAIBase { }else if(this.continuousSpellDuration - this.continuousSpellTimer == 1){ // On the first tick, if the spell did succeed, fire SpellCastEvent.Post. - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(attacker, caster.getContinuousSpell(), - caster.getModifiers(), Source.NPC)); + MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(attacker, attacker.getContinuousSpell(), + attacker.getModifiers(), Source.NPC)); } }else if(--this.cooldown == 0){ @@ -180,7 +171,7 @@ public class EntityAIAttackSpell extends EntityAIBase { double dx = target.posX - attacker.posX; double dz = target.posZ - attacker.posZ; - List spells = new ArrayList(caster.getSpells()); + List spells = new ArrayList(attacker.getSpells()); if(spells.size() > 0){ @@ -194,7 +185,7 @@ public class EntityAIAttackSpell extends EntityAIBase { spell = spells.get(attacker.world.rand.nextInt(spells.size())); - SpellModifiers modifiers = caster.getModifiers(); + SpellModifiers modifiers = attacker.getModifiers(); if(spell != null && attemptCastSpell(spell, modifiers)){ // The spell worked, so we're done! diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java b/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java index 74b4e734..ad9119b3 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java @@ -55,7 +55,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntityAdditionalSpawnData { - private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50); + private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50); public int textureIndex = 0; diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java b/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java index 0414dfc8..54325cd5 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java @@ -27,7 +27,7 @@ public class EntityPhoenix extends EntitySummonedCreature implements ISpellCaste private double AISpeed = 0.5; // Can attack for 7 seconds, then must cool down for 3. - private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 60, 140); + private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 60, 140); private Spell continuousSpell; diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java b/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java index 9b03593b..835fab80 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java @@ -31,7 +31,7 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell private double AISpeed = 1.0; - private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 30, 0); + private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 30, 0); private static final List attack = Collections.singletonList(Spells.darkness_orb); diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java b/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java index 6991713a..f86586c5 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java @@ -29,7 +29,7 @@ public class EntityStormElemental extends EntitySummonedCreature implements ISpe private double AISpeed = 1.0; - private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 30, 0); + private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 30, 0); private static final List attack = Collections.singletonList(Spells.lightning_disc); diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java index 62da92ce..ccdec06d 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java @@ -84,7 +84,7 @@ import net.minecraftforge.oredict.OreDictionary; @Mod.EventBusSubscriber public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISpellCaster, IEntityAdditionalSpawnData { - private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50); + private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell<>(this, 0.5D, 14.0F, 30, 50); public int textureIndex = 0;