From 397096ebd4de4da2b9114f9ef4004a97216ba184 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 13 Jul 2021 21:49:18 -0400 Subject: [PATCH] v0.9.4: added gateway traps! --- .../assets/messages/levels/levels.properties | 3 + .../levels/traps/GatewayTrap.java | 148 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GatewayTrap.java diff --git a/core/src/main/assets/messages/levels/levels.properties b/core/src/main/assets/messages/levels/levels.properties index bc9149989..93d7edfb6 100644 --- a/core/src/main/assets/messages/levels/levels.properties +++ b/core/src/main/assets/messages/levels/levels.properties @@ -65,6 +65,9 @@ levels.traps.flocktrap.desc=Perhaps a joke from some amateur mage, triggering th levels.traps.frosttrap.name=frost trap levels.traps.frosttrap.desc=When activated, chemicals in this trap will rapidly freeze the air in a wide range around its location. +levels.traps.gatewaytrap.name=grim trap +levels.traps.gatewaytrap.desc=This special teleportation trap can activate an infinite numbers of times and always teleports to the same location. + levels.traps.grimtrap.name=grim trap levels.traps.grimtrap.ondeath=You were killed by the blast of a grim trap... levels.traps.grimtrap.desc=Extremely powerful destructive magic is stored within this trap, enough to instantly kill all but the healthiest of heroes. Triggering it will send a ranged blast of lethal magic towards the nearest character.\n\nThankfully the trigger mechanism isn't hidden. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GatewayTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GatewayTrap.java new file mode 100644 index 000000000..7dafe4125 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GatewayTrap.java @@ -0,0 +1,148 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels.traps; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Bundle; +import com.watabou.utils.PathFinder; +import com.watabou.utils.Random; + +import java.util.ArrayList; + +public class GatewayTrap extends Trap { + + { + color = TEAL; + shape = CROSSHAIR; + } + + private int telePos = -1; + + @Override + public void trigger() { + if (Dungeon.level.heroFOV[pos]){ + Sample.INSTANCE.play(Assets.Sounds.TRAP); + } + //this trap is not disarmed by being triggered + reveal(); + Level.set(pos, Terrain.TRAP); + activate(); + } + + @Override + public void activate() { + + if (telePos == -1){ + for (int i : PathFinder.NEIGHBOURS9){ + Char ch = Actor.findChar(pos + i); + if (ch != null){ + if (ScrollOfTeleportation.teleportChar(ch)) { + if (ch instanceof Mob && ((Mob) ch).state == ((Mob) ch).HUNTING) { + ((Mob) ch).state = ((Mob) ch).WANDERING; + } + telePos = ch.pos; + break; + } + } + Heap heap = Dungeon.level.heaps.get(pos + i); + if (heap != null){ + int cell = Dungeon.level.randomRespawnCell( null ); + + Item item = heap.pickUp(); + + if (cell != -1) { + Heap dropped = Dungeon.level.drop( item, cell ); + dropped.type = heap.type; + dropped.sprite.view( dropped ); + telePos = cell; + break; + + } + } + } + } + + if (telePos != -1){ + + ArrayList telePositions = new ArrayList<>(); + for (int i : PathFinder.NEIGHBOURS8){ + if (Dungeon.level.passable[telePos+i] + && Actor.findChar( telePos+i ) == null){ + telePositions.add(telePos+i); + } + } + Random.shuffle(telePositions); + + if (Dungeon.level.passable[telePos] + && Actor.findChar( telePos ) == null){ + telePositions.add(0, telePos); + } + + ArrayList largeCharPositions = new ArrayList<>(); + for (int pos : telePositions){ + if (Dungeon.level.openSpace[pos]){ + largeCharPositions.add(pos); + } + } + + for (int i : PathFinder.NEIGHBOURS9){ + + Char ch = Actor.findChar(pos + i); + if (ch != null){ + int newPos = -1; + if (Char.hasProp(ch, Char.Property.LARGE)){ + if (!largeCharPositions.isEmpty()){ + newPos = largeCharPositions.get(0); + } + } else { + if (!telePositions.isEmpty()) { + newPos = telePositions.get(0); + } + } + + if (newPos != -1){ + telePositions.remove((Integer)newPos); + largeCharPositions.remove((Integer)newPos); + + if (ScrollOfTeleportation.teleportToLocation(ch, newPos)){ + if (ch instanceof Mob && ((Mob) ch).state == ((Mob) ch).HUNTING) { + ((Mob) ch).state = ((Mob) ch).WANDERING; + } + } + } + } + + Heap heap = Dungeon.level.heaps.get(pos + i); + if (heap != null){ + Item item = heap.pickUp(); + Heap dropped = Dungeon.level.drop( item, telePos ); + dropped.type = heap.type; + dropped.sprite.view( dropped ); + } + } + } + + } + + private static final String TELE_POS = "tele_pos"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(TELE_POS, telePos); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + telePos = bundle.getInt(TELE_POS); + } +}