From 08686f8e92ef253c709f4da1980bd613316a646d Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 14 May 2015 23:24:28 -0400 Subject: [PATCH] v0.3.0: added wand of corruption --- .../actors/buffs/Corruption.java | 59 +++++++++++++ .../actors/mobs/Mob.java | 22 +++-- .../effects/DarkBlock.java | 46 ++++++++++ .../items/Generator.java | 6 +- .../items/wands/Wand.java | 2 +- .../items/wands/WandOfCorruption.java | 86 +++++++++++++++++++ .../items/wands/WandOfTransfusion.java | 4 +- .../sprites/CharSprite.java | 14 ++- 8 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Corruption.java create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/effects/DarkBlock.java create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Corruption.java b/src/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Corruption.java new file mode 100644 index 000000000..bb65cc0d9 --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Corruption.java @@ -0,0 +1,59 @@ +package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; + +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; +import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; + +/** + * Created by Evan on 14/05/2015. + */ +public class Corruption extends Buff { + + { + type = buffType.NEGATIVE; + } + + //TODO: need to bundle this + private float buildToDamage = 0f; + + @Override + public boolean act() { + buildToDamage += target.HT/100f; + + int damage = (int)buildToDamage; + buildToDamage -= damage; + + if (damage > 0) + target.damage(damage, this); + + spend(TICK); + + return true; + } + + @Override + public void fx(boolean on) { + if (on) target.sprite.add( CharSprite.State.DARKENED ); + else if (target.invisible == 0) target.sprite.remove( CharSprite.State.DARKENED ); + } + + @Override + //TODO: new icon + public int icon() { + return BuffIndicator.POISON; + } + + @Override + public String toString() { + return "Corrupted"; + } + + @Override + public String desc() { + return "Corruption seeps into the essence of a being, twisting them against their former nature.\n" + + "\n" + + "Corrupted creatures will attack and aggravate their allies, and ignore their former enemies. " + + "Corruption is damaging as well, and will slowly cause its target to succumb.\n" + + "\n" + + "Corruption is permanent, its effects only end in death."; + } +} diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java b/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java index fa6563211..30bb14bce 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java @@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; @@ -173,10 +174,10 @@ public abstract class Mob extends Char { } //resets target if: the target is dead, the target has been lost (wandering) - //or if the mob is amoked and targeting the hero (will try to target something else) + //or if the mob is amoked/corrupted and targeting the hero (will try to target something else) if ( enemy != null && !enemy.isAlive() || state == WANDERING || - (buff( Amok.class ) != null && enemy == Dungeon.hero )) + ((buff( Amok.class ) != null || buff(Corruption.class) != null) && enemy == Dungeon.hero )) enemy = null; //if there is no current target, find a new one. @@ -184,8 +185,8 @@ public abstract class Mob extends Char { HashSet enemies = new HashSet(); - //if the mob is amoked... - if ( buff(Amok.class) != null ) { + //if the mob is amoked or corrupted... + if ( buff(Amok.class) != null || buff(Corruption.class) != null) { //try to find an enemy mob to attack first. for (Mob mob : Dungeon.level.mobs) @@ -199,8 +200,9 @@ public abstract class Mob extends Char { enemies.add(mob); if (enemies.size() > 0) return Random.element(enemies); - //if there is nothing, go for the hero. - return Dungeon.hero; + //if there is nothing, go for the hero, unless corrupted, then go for nothing. + if (buff(Corruption.class) != null) return null; + else return Dungeon.hero; //if the mob is not amoked... } else { @@ -359,6 +361,14 @@ public abstract class Mob extends Char { Surprise.hit(this); } } + + //become aggro'd by a corrupted enemy + if (enemy.buff(Corruption.class) != null) { + aggro(enemy); + target = enemy.pos; + state = HUNTING; + } + return damage; } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/effects/DarkBlock.java b/src/com/shatteredpixel/shatteredpixeldungeon/effects/DarkBlock.java new file mode 100644 index 000000000..646661da4 --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/effects/DarkBlock.java @@ -0,0 +1,46 @@ +package com.shatteredpixel.shatteredpixeldungeon.effects; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; +import com.watabou.noosa.Game; +import com.watabou.noosa.Gizmo; +import com.watabou.noosa.audio.Sample; + +/** + * Created by Evan on 14/05/2015. + */ +public class DarkBlock extends Gizmo{ + + private CharSprite target; + + public DarkBlock( CharSprite target ) { + super(); + + this.target = target; + } + + @Override + public void update() { + super.update(); + + target.brightness(0.4f); + + } + + public void lighten() { + + target.resetColor(); + killAndErase(); + + } + + public static DarkBlock darken( CharSprite sprite ) { + + DarkBlock darkBlock = new DarkBlock( sprite ); + if (sprite.parent != null) + sprite.parent.add( darkBlock ); + + return darkBlock; + } + +} diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java index 6220d84f1..2353eb3aa 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java @@ -130,7 +130,7 @@ public class Generator { WandOfTransfusion.class, //WandOfCorruption.class, WandOfRegrowth.class }; - Category.WAND.probs = new float[]{ 4, 4, 4, 4, 4, 3, /*3,*/ 3, 3, /*3,*/ 3, /*3,*/ 3 }; + Category.WAND.probs = new float[]{ 4, 4, 4, 4, 4, 3, /*3,*/ 3, 3, /*3,*/ 3, 3, 3 }; Category.WEAPON.classes = new Class[]{ Dagger.class, @@ -174,12 +174,12 @@ public class Generator { RingOfForce.class, RingOfFuror.class, RingOfHaste.class, - RingOfMagic.class, + //RingOfMagic.class, RingOfMight.class, RingOfSharpshooting.class, RingOfTenacity.class, RingOfWealth.class}; - Category.RING.probs = new float[]{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; + Category.RING.probs = new float[]{ 1, 1, 1, 1, 1, 1, /*1,*/ 1, 1, 1, 1 }; Category.ARTIFACT.classes = new Class[]{ CapeOfThorns.class, diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.java index b67afab56..c4df4546c 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.java @@ -69,7 +69,7 @@ public abstract class Wand extends Item { private boolean curChargeKnown = false; - private int usagesToKnow = USAGES_TO_KNOW; + protected int usagesToKnow = USAGES_TO_KNOW; protected int collisionProperties = Ballistica.MAGIC_BOLT; diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java new file mode 100644 index 000000000..6722af990 --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfCorruption.java @@ -0,0 +1,86 @@ +package com.shatteredpixel.shatteredpixeldungeon.items.wands; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption; +import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Callback; +import com.watabou.utils.Random; + +/** + * Created by Evan on 14/05/2015. + */ +//TODO: balancing +public class WandOfCorruption extends Wand { + + { + name = "Wand of Corruption"; + image = ItemSpriteSheet.WAND_CORRUPTION; + } + + @Override + protected void onZap(Ballistica bolt) { + Char ch = Actor.findChar(bolt.collisionPos); + + if (ch != null){ + + int basePower = 5 + 5*level; + int mobPower = Random.NormalIntRange(0, ch.HT+ch.HP); + + int extraCharges = 0; + //try to use extra charges to overpower the mob + while (basePower <= mobPower){ + extraCharges++; + basePower += 10 + 2.5*level; + } + + //if we fail, lose all charges, remember we have 1 left to lose from using the wand. + if (extraCharges >= curCharges){ + curCharges = 1; + GLog.w("The corrupting power was not strong enough, nothing happens."); + return; + } + + //otherwise corrupt the mob & spend charges + Buff.append(ch, Corruption.class); + ch.HP = ch.HT; + curCharges -= extraCharges; + usagesToKnow -= extraCharges; + } + } + + @Override + public void onHit(MagesStaff staff, Char attacker, Char defender, int damage) { + // lvl 0 - 25% + // lvl 1 - 40% + // lvl 2 - 50% + if (Random.Int( level + 4 ) >= 3){ + Buff.prolong( defender, Amok.class, 3+level); + } + } + + @Override + protected void fx(Ballistica bolt, Callback callback) { + MagicMissile.shadow(curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback); + Sample.INSTANCE.play( Assets.SND_ZAP ); + } + + @Override + public String desc() { + return "This wand radiates dark energy, if that weren't already obvious from the small decorative skull shaped onto its tip.\n" + + "\n" + + "This wand will release a blast of corrupting energy, attempting to bend enemies to your will. " + + "The weaker an enemy is, the easier they are to corrupt. " + + "Successfully corrupting an enemy restores them to full health.\n" + + "\n" + + "This wand uses at least one charge per cast, but will often use more in an attempt to overpower tougher enemies."; + } +} diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfTransfusion.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfTransfusion.java index 77130126a..089a9ac81 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfTransfusion.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfTransfusion.java @@ -8,6 +8,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.*; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost; import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; @@ -83,8 +84,7 @@ public class WandOfTransfusion extends Wand { if (ch != null && ch instanceof Mob){ //heals an ally, or charmed/corrupted enemy - //TODO: add corruption here - if (((Mob) ch).ally || ch.buff(Charm.class) != null){ + if (((Mob) ch).ally || ch.buff(Charm.class) != null || ch.buff(Corruption.class) != null){ int missingHP = ch.HT - ch.HP; //heals 30%+3%*lvl missing HP. diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java b/src/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java index 05e23780f..5a721e36d 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/sprites/CharSprite.java @@ -17,6 +17,7 @@ */ package com.shatteredpixel.shatteredpixeldungeon.sprites; +import com.shatteredpixel.shatteredpixeldungeon.effects.DarkBlock; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SnowParticle; import com.watabou.noosa.Game; import com.watabou.noosa.MovieClip; @@ -56,7 +57,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip private static final float FLASH_INTERVAL = 0.05f; public enum State { - BURNING, LEVITATING, INVISIBLE, PARALYSED, FROZEN, ILLUMINATED, CHILLED + BURNING, LEVITATING, INVISIBLE, PARALYSED, FROZEN, ILLUMINATED, CHILLED, DARKENED } protected Animation idle; @@ -75,6 +76,7 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip protected Emitter levitation; protected IceBlock iceBlock; + protected DarkBlock darkBlock; protected TorchHalo halo; protected EmoIcon emo; @@ -282,6 +284,9 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip chilled = emitter(); chilled.pour(SnowParticle.FACTORY, 0.1f); break; + case DARKENED: + darkBlock = DarkBlock.darken( this ); + break; } } @@ -322,6 +327,13 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip chilled.on = false; chilled = null; } + //TODO: maybe add some particles here? + case DARKENED: + if (darkBlock != null) { + darkBlock.lighten(); + darkBlock = null; + } + break; } }