diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfClairvoyance.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfClairvoyance.java index 3957b7038..ea96a6575 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfClairvoyance.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfClairvoyance.java @@ -23,13 +23,21 @@ package com.shatteredpixel.shatteredpixeldungeon.items.stones; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CheckedCell; +import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping; +import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap; import com.shatteredpixel.shatteredpixeldungeon.mechanics.ShadowCaster; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.watabou.noosa.audio.Sample; import com.watabou.utils.Point; +import com.watabou.utils.Random; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; public class StoneOfClairvoyance extends Runestone { @@ -40,7 +48,7 @@ public class StoneOfClairvoyance extends Runestone { } @Override - protected void activate(int cell) { + protected void activate(final int cell) { boolean[] FOV = new boolean[Dungeon.level.length()]; Point c = Dungeon.level.cellToPoint(cell); ShadowCaster.castShadow(c.x, c.y, FOV, DIST); @@ -51,6 +59,8 @@ public class StoneOfClairvoyance extends Runestone { int sY = Math.max(0, c.y - DIST); int eY = Math.min(Dungeon.level.height()-1, c.y + DIST); + ArrayList disarmCandidates = new ArrayList<>(); + boolean noticed = false; for (int y = sY; y <= eY; y++){ int curr = y*Dungeon.level.width() + sX; @@ -68,11 +78,40 @@ public class StoneOfClairvoyance extends Runestone { noticed = true; } } + + if (Dungeon.level.traps.get(curr) != null){ + disarmCandidates.add(Dungeon.level.traps.get(curr)); + } + } curr++; } } + Collections.sort(disarmCandidates, new Comparator() { + @Override + public int compare(Trap o1, Trap o2) { + float diff = Dungeon.level.trueDistance(cell, o1.pos) - Dungeon.level.trueDistance(cell, o2.pos); + if (diff < 0){ + return -1; + } else if (diff == 0){ + return Random.Int(2) == 0 ? -1 : 1; + } else { + return 1; + } + } + }); + + //disarms at most two traps + if (disarmCandidates.size() > 0){ + disarmCandidates.get(0).disarm(); + CellEmitter.get(disarmCandidates.get(0).pos).burst(Speck.factory(Speck.STEAM), 6); + if (disarmCandidates.size() > 1){ + disarmCandidates.get(1).disarm(); + CellEmitter.get(disarmCandidates.get(1).pos).burst(Speck.factory(Speck.STEAM), 6); + } + } + if (noticed) { Sample.INSTANCE.play( Assets.SND_SECRET ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfShock.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfShock.java index cac85cb24..a055ac0ce 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfShock.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/stones/StoneOfShock.java @@ -23,13 +23,21 @@ package com.shatteredpixel.shatteredpixeldungeon.items.stones; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob; -import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity; -import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +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.Paralysis; +import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; +import com.shatteredpixel.shatteredpixeldungeon.effects.Lightning; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.EnergyParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.utils.BArray; import com.watabou.noosa.audio.Sample; import com.watabou.utils.PathFinder; +import java.util.ArrayList; + public class StoneOfShock extends Runestone { { @@ -41,11 +49,28 @@ public class StoneOfShock extends Runestone { Sample.INSTANCE.play( Assets.SND_LIGHTNING ); - for( int i : PathFinder.NEIGHBOURS9) { - if (!Dungeon.level.solid[cell + i]) { - GameScene.add(Blob.seed(cell + i, 10, Electricity.class)); + ArrayList arcs = new ArrayList<>(); + int hits = 0; + + PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 ); + for (int i = 0; i < PathFinder.distance.length; i++) { + if (PathFinder.distance[i] < Integer.MAX_VALUE) { + Char n = Actor.findChar(i); + if (n != null) { + arcs.add(new Lightning.Arc(cell, n.sprite.center())); + Buff.prolong(n, Paralysis.class, 1f); + hits++; + } } } + + CellEmitter.center( cell ).burst( SparkParticle.FACTORY, 3 ); + + if (hits > 0) { + curUser.sprite.parent.addToFront( new Lightning( arcs, null ) ); + curUser.sprite.centerEmitter().burst(EnergyParticle.FACTORY, 10); + curUser.belongings.charge(1f + hits); + } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java index bdfd6ea5f..88d5e067e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/Trap.java @@ -91,9 +91,9 @@ public abstract class Trap implements Bundlable { public abstract void activate(); - protected void disarm(){ - Dungeon.level.disarmTrap(pos); + public void disarm(){ active = false; + Dungeon.level.disarmTrap(pos); } private static final String POS = "pos"; diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties index c09dec156..593685760 100644 --- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties +++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties @@ -487,7 +487,7 @@ actors.mobs.rotheart.name=rot heart actors.mobs.rotheart.desc=A Rotberry's fruit is very unique. Instead of rotting away and providing nutrients, the fruit grows, hardens, and encompasses the seed. It provides protection for the internal organs which grow inside the fruit. This giant orb is referred to as the heart of an adult rotberry plant. actors.mobs.rotlasher.name=rot lasher -actors.mobs.rotlasher.desc=The rot lasher is a part of a mature rotberry plant's root structure, and also their primary means of defence. Lashers are stuck into the ground, but will violently assault anything that gets near to them. When there is no nearby prey, they stand motionless, attempting to blend in with surrounding vegetation. +actors.mobs.rotlasher.desc=The rot lasher is a part of a mature rotberry plant's root structure, and also their primary means of defense. Lashers are stuck into the ground, but will violently assault anything that gets near to them. When there is no nearby prey, they stand motionless, attempting to blend in with surrounding vegetation. actors.mobs.rotlasher$waiting.status=This %s is idle. actors.mobs.scorpio.name=scorpio diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties index 93159a7e9..8afb403ea 100644 --- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties +++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/items/items.properties @@ -3,7 +3,7 @@ items.armor.curses.antientropy.name=%s of anti-entropy items.armor.curses.antientropy.desc=Anti-entropy curse works against the forces of the universe, pulling energy away from the attacker and into the wearer. This briefly freezes the attacker, but sets the wearer on fire! items.armor.curses.bulk.name=%s of bulk -items.armor.curses.bulk.desc=Armor of bulk looks larger and more imposing, but doesn't actually have enhanced defence. Even worse, the added size makes moving through doorways very difficult. +items.armor.curses.bulk.desc=Armor of bulk looks larger and more imposing, but doesn't actually have enhanced defense. Even worse, the added size makes moving through doorways very difficult. items.armor.curses.corrosion.name=%s of corrosion items.armor.curses.corrosion.desc=Armor of corrosion is capable of bursting with corrosive fluid, coating everything in the area with sticky acidic ooze. @@ -18,7 +18,7 @@ items.armor.curses.multiplicity.name=%s of multiplicity items.armor.curses.multiplicity.desc=Armor cursed with multiplicity contains dangerous duplication magic. It will sometimes create a mirror image of the wearer, but is equally likely to duplicate the attacker! items.armor.curses.overgrowth.name=%s of overgrowth -items.armor.curses.overgrowth.desc=Armor of overgrowth is covered in various blooming plants. While this effect certainly looks interesting, it does nothing for defence, and these plants will randomly activate in combat! +items.armor.curses.overgrowth.desc=Armor of overgrowth is covered in various blooming plants. While this effect certainly looks interesting, it does nothing for defense, and these plants will randomly activate in combat! items.armor.curses.stench.name=%s of stench items.armor.curses.stench.desc=Armor cursed with stench will release clouds of noxious gas, which is hazardous to everything caught in the cloud. @@ -707,7 +707,7 @@ items.stones.stoneofblink.name=stone of blink items.stones.stoneofblink.desc=This runestone will teleport the user to the location it is thrown to. items.stones.stoneofclairvoyance.name=stone of clairvoyance -items.stones.stoneofclairvoyance.desc=This stone will instantly search all tiles which are visible from the location it is thrown to. +items.stones.stoneofclairvoyance.desc=This stone will instantly search all tiles which are visible from the location it is thrown to, and will disarm up to two traps which it finds. items.stones.stoneofdeepenedsleep.name=stone of deepened sleep items.stones.stoneofdeepenedsleep.desc=When this stone is thrown near a sleeping enemy, it will magically deepen their sleep. Magically slept enemies will sleep forever until disturbed. @@ -735,7 +735,7 @@ items.stones.stoneofintuition$wndguess.correct=Correct. The item has been identi items.stones.stoneofintuition$wndguess.incorrect=Your guess was incorrect. items.stones.stoneofshock.name=stone of shock -items.stones.stoneofshock.desc=This runestone unleashes a short-lived electrical storm at the location it is thrown to. +items.stones.stoneofshock.desc=This runestone unleashes a blast of electrical energy which briefly stuns all nearby targets, and grants the thrower wand charge for each target hit. ###wands items.wands.cursedwand.ondeath=You were killed by your own %s.