From 1b90092ad8ee0b43c8aa036ed848753cd632d215 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 16 Aug 2024 15:23:54 -0400 Subject: [PATCH] v2.5.0: added 3 common and 2 uncommon cursed wand effects --- .../effects/MagicMissile.java | 5 + .../items/wands/CursedWand.java | 122 ++++++++++++++++++ .../levels/traps/FlockTrap.java | 6 +- 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java index be145dec3..4e0153a7d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java @@ -73,6 +73,7 @@ public class MagicMissile extends Emitter { public static final int TOXIC_VENT = 14; public static final int ELMO = 15; public static final int POISON = 16; + public static final int BUBBLES = 17; public static final int MAGIC_MISS_CONE = 100; public static final int FROST_CONE = 101; @@ -191,6 +192,10 @@ public class MagicMissile extends Emitter { size( 3 ); pour( PoisonParticle.MISSILE, 0.01f ); break; + case BUBBLES: + size( 10 ); + pour( Speck.factory(Speck.BUBBLE), 0.02f ); + break; case MAGIC_MISS_CONE: size( 10 ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java index ea452c631..cefdb112f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java @@ -76,7 +76,12 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfSir import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.WondrousResin; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BurningTrap; +import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ChillingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap; +import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FlockTrap; +import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GeyserTrap; +import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ShockingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.SummoningTrap; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE; @@ -185,6 +190,9 @@ public class CursedWand { COMMON_EFFECTS.add(new SpawnRegrowth()); COMMON_EFFECTS.add(new RandomTeleport()); COMMON_EFFECTS.add(new RandomGas()); + COMMON_EFFECTS.add(new RandomAreaEffect()); + COMMON_EFFECTS.add(new Bubbles()); + COMMON_EFFECTS.add(new RandomWand()); } public static CursedEffect randomCommonEffect(){ @@ -281,6 +289,90 @@ public class CursedWand { } } + public static class RandomAreaEffect extends CursedEffect { + @Override + public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) { + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); + if (Actor.findChar(bolt.collisionPos) == null){ + Dungeon.level.pressCell(bolt.collisionPos); + } + switch (Random.Int(3)) { + case 0: default: + new BurningTrap().set(bolt.collisionPos).activate(); + return true; + case 1: + new ChillingTrap().set(bolt.collisionPos).activate(); + return true; + case 2: + new ShockingTrap().set(bolt.collisionPos).activate(); + return true; + } + } + } + + public static class Bubbles extends CursedEffect { + + @Override + public void FX(Item origin, Char user, Ballistica bolt, Callback callback) { + MagicMissile.boltFromChar(user.sprite.parent, + MagicMissile.BUBBLES, + user.sprite, + bolt.collisionPos, + callback); + Sample.INSTANCE.play( Assets.Sounds.ZAP ); + } + + @Override + public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) { + if (Actor.findChar(bolt.collisionPos) == null){ + Dungeon.level.pressCell(bolt.collisionPos); + } + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); + for (int i : PathFinder.NEIGHBOURS9){ + if (!Dungeon.level.solid[bolt.collisionPos+i]){ + CellEmitter.get(bolt.collisionPos+i).start(Speck.factory(Speck.BUBBLE), 0.25f, 40); + } + } + return true; + } + } + + public static class RandomWand extends CursedEffect { + + private Wand wand; + + @Override + public boolean valid(Item origin, Char user, Ballistica bolt, boolean positiveOnly) { + //TODO we have this limit atm because some wands are coded to depend on their fx logic + // and chaos elementals trigger the effect directly, with no FX first + return super.valid(origin, user, bolt, positiveOnly) && user instanceof Hero; + } + + @Override + public void FX(Item origin, Char user, Ballistica bolt, Callback callback) { + if (wand == null){ + wand = (Wand)Generator.randomUsingDefaults(Generator.Category.WAND); + } + wand.fx(bolt, callback); + } + + @Override + public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) { + if (wand == null){ + wand = (Wand)Generator.randomUsingDefaults(Generator.Category.WAND); + } + if (origin instanceof Wand){ + wand.upgrade(origin.level()); + } else { + wand.upgrade(Dungeon.scalingDepth()/5); + } + wand.levelKnown = false; + wand.onZap(bolt); + wand = null; + return true; + } + } + //************************ //*** Uncommon Effects *** //************************ @@ -291,6 +383,8 @@ public class CursedWand { UNCOMMON_EFFECTS.add(new HealthTransfer()); UNCOMMON_EFFECTS.add(new Explosion()); UNCOMMON_EFFECTS.add(new LightningBolt()); + UNCOMMON_EFFECTS.add(new Geyser()); + UNCOMMON_EFFECTS.add(new SummonSheep()); } public static CursedEffect randomUncommonEffect(){ @@ -324,6 +418,7 @@ public class CursedWand { @Override public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) { if (valid(origin, user, bolt, positiveOnly)) { + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); Dungeon.level.plant((Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED), bolt.collisionPos); return true; } else { @@ -433,6 +528,8 @@ public class CursedWand { } } + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); + for (Char ch : affected){ if (ch instanceof Hero) { Buff.prolong(ch, Recharging.class, Recharging.DURATION/3f); @@ -461,6 +558,27 @@ public class CursedWand { } } + public static class Geyser extends CursedEffect{ + @Override + public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) { + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); + GeyserTrap geyser = new GeyserTrap(); + geyser.pos = bolt.collisionPos; + geyser.source = origin == null ? user : origin; + geyser.activate(); + return true; + } + } + + public static class SummonSheep extends CursedEffect{ + @Override + public boolean effect(Item origin, Char user, Ballistica bolt, boolean positiveOnly) { + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); + new FlockTrap().set(bolt.collisionPos).activate(); + return true; + } + } + //******************** //*** Rare Effects *** //******************** @@ -604,6 +722,8 @@ public class CursedWand { boolean[] fieldOfView = new boolean[Dungeon.level.length()]; ShadowCaster.castShadow(c.x, c.y, Dungeon.level.width(), fieldOfView, Dungeon.level.solid, 3); + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); + for (int i = 0; i < Dungeon.level.length(); i++){ if (fieldOfView[i] && !Dungeon.level.solid[i]){ //does not directly harm allies @@ -688,6 +808,8 @@ public class CursedWand { } } + tryForWandProc(Actor.findChar(bolt.collisionPos), origin); + for (Char ch : affectedChars){ //positive only does not harm allies if (positiveOnly && ch.alignment == Char.Alignment.ALLY){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/FlockTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/FlockTrap.java index be1c4bf7f..7fa49cc8a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/FlockTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/FlockTrap.java @@ -29,8 +29,8 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.journal.Bestiary; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; -import com.watabou.utils.BArray; import com.watabou.noosa.audio.Sample; +import com.watabou.utils.BArray; import com.watabou.utils.PathFinder; import java.util.ArrayList; @@ -72,10 +72,10 @@ public class FlockTrap extends Trap { t.activate(); } Dungeon.level.occupyCell(sheep); - Sample.INSTANCE.play(Assets.Sounds.PUFF); - Sample.INSTANCE.play(Assets.Sounds.SHEEP); } } + Sample.INSTANCE.play(Assets.Sounds.PUFF); + Sample.INSTANCE.play(Assets.Sounds.SHEEP); } }