From b4f6bf1b0bcad7baa6d1852c5ea39c99d5ef4ee8 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 8 Jul 2015 02:47:48 -0400 Subject: [PATCH] v0.3.1: more traps --- .../levels/traps/DisintegrationTrap.java | 101 ++++++++++++++++++ .../levels/traps/ExplosiveTrap.java | 4 +- .../levels/traps/GrimTrap.java | 99 +++++++++++++++++ .../levels/traps/PitfallTrap.java | 93 ++++++++++++++++ .../levels/traps/RockfallTrap.java | 78 ++++++++++++++ 5 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GrimTrap.java create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/RockfallTrap.java diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java new file mode 100644 index 000000000..96161656d --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java @@ -0,0 +1,101 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2015 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ +package com.shatteredpixel.shatteredpixeldungeon.levels.traps; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap; +import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.utils.Utils; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Random; + +public class DisintegrationTrap extends Trap { + + { + name = "Disintegration trap"; + color = TrapSprite.VIOLET; + shape = TrapSprite.LARGE_DOT; + } + + @Override + public void activate() { + + if (Dungeon.visible[ pos ]) { + sprite.parent.add( new Beam.DeathRay( DungeonTilemap.tileCenterToWorld(pos-1), + DungeonTilemap.tileCenterToWorld(pos+1))); + sprite.parent.add(new Beam.DeathRay(DungeonTilemap.tileCenterToWorld(pos - Level.WIDTH), + DungeonTilemap.tileCenterToWorld(pos + Level.WIDTH))); + Sample.INSTANCE.play( Assets.SND_RAY ); + } + + + Heap heap = Dungeon.level.heaps.get(pos); + if (heap != null) heap.explode(); + + Char ch = Actor.findChar(pos); + if (ch != null){ + ch.damage( Math.max( ch.HT/5, Random.Int(ch.HP / 2, 2 * ch.HP / 3) ), this ); + if (ch == Dungeon.hero){ + Hero hero = (Hero)ch; + if (!hero.isAlive()){ + Dungeon.fail(Utils.format(ResultDescriptions.TRAP, name)); + GLog.n("You were killed by the disintegration trap..."); + } else { + Item item = hero.belongings.randomUnequipped(); + Bag bag = hero.belongings.backpack; + //bags do not protect against this trap + if (item instanceof Bag){ + bag = (Bag)item; + item = Random.element(bag.items); + } + if (item.level > 0 || item.unique) return; + if (!item.stackable){ + item.detachAll(bag); + GLog.w("the trap disintegrates your " + item.name() + "!"); + } else { + int n = Random.NormalIntRange(1, (item.quantity()+1)/2); + for(int i = 1; i <= n; i++) + item.detach(bag); + GLog.w("the trap disintegrates some of your " + item.name() + "!"); + } + } + } + } + + } + + @Override + public String desc() { + return "Then triggered, this trap will lance the target with beams of disintegration, " + + "dealing significant damage and destroying items."; + } +} diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/ExplosiveTrap.java b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/ExplosiveTrap.java index 6662be827..ae4aa76df 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/ExplosiveTrap.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/ExplosiveTrap.java @@ -27,8 +27,8 @@ public class ExplosiveTrap extends Trap { { name = "Explosive trap"; - color = TrapSprite.GREY; - shape = TrapSprite.WAVES; + color = TrapSprite.ORANGE; + shape = TrapSprite.DIAMOND; } @Override diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GrimTrap.java b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GrimTrap.java new file mode 100644 index 000000000..c0d1b967c --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/GrimTrap.java @@ -0,0 +1,99 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2015 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ +package com.shatteredpixel.shatteredpixeldungeon.levels.traps; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; +import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.utils.Utils; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Callback; + +public class GrimTrap extends Trap { + + { + name = "Grim trap"; + color = TrapSprite.GREY; + shape = TrapSprite.LARGE_DOT; + } + + @Override + public void activate() { + Char target = Actor.findChar(pos); + + //find the closest char that can be aimed at + if (target == null){ + for (Char ch : Actor.chars()){ + Ballistica bolt = new Ballistica(pos, ch.pos, Ballistica.PROJECTILE); + if (bolt.collisionPos == ch.pos && + (target == null || Level.distance(pos, ch.pos) < Level.distance(pos, target.pos))){ + target = ch; + } + } + } + + if (target != null){ + final Char finalTarget = target; + MagicMissile.shadow(target.sprite.parent, pos, target.pos, new Callback() { + @Override + public void call() { + + if (finalTarget == Dungeon.hero) { + //almost kill the player + if ((finalTarget.HP/finalTarget.HT) > 0.25f){ + finalTarget.damage((int)(finalTarget.HP*0.8f), this); + //kill 'em + } else { + finalTarget.damage(finalTarget.HP, this); + } + Sample.INSTANCE.play(Assets.SND_CURSED); + if (!finalTarget.isAlive()) { + Dungeon.fail(Utils.format(ResultDescriptions.TRAP, name)); + GLog.n("You were killed by the blast of a grim trap..."); + } + } else { + finalTarget.damage(finalTarget.HP, this); + Sample.INSTANCE.play(Assets.SND_BURNING); + } + finalTarget.sprite.emitter().burst(ShadowParticle.UP, 10); + } + }); + } else { + CellEmitter.get(pos).burst(ShadowParticle.UP, 10); + Sample.INSTANCE.play(Assets.SND_BURNING); + } + } + + @Override + public String desc() { + return "Extremely powerful destructive magic is stored within this trap, enough to instantly kill all but the strongest heroes. " + + "Triggering it will send a lethal blast of magic towards the nearest character."; + } +} diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java new file mode 100644 index 000000000..ac95293dc --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java @@ -0,0 +1,93 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2015 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ +package com.shatteredpixel.shatteredpixeldungeon.levels.traps; + +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.effects.particles.FlowParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.WindParticle; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite; + +public class PitfallTrap extends Trap { + + { + name = "Pitfall trap"; + color = TrapSprite.RED; + shape = TrapSprite.DIAMOND; + + } + + @Override + public void activate() { + Heap heap = Dungeon.level.heaps.get( pos ); + + if (heap != null){ + for (Item item : heap.items){ + Dungeon.dropToChasm(item); + } + heap.sprite.kill(); + GameScene.discard(heap); + Dungeon.level.heaps.delete( pos ); + } + + Char ch = Actor.findChar( pos ); + + if (ch == Dungeon.hero){ + Chasm.heroFall( pos ); + } else if (ch != null){ + Chasm.mobFall((Mob)ch); + } + } + + @Override + protected void disarm() { + super.disarm(); + + //if making a pit here wouldn't block any paths, make a pit tile instead of a disarmed trap tile. + if (!(Dungeon.level.map[pos - Level.WIDTH] == Terrain.WALL && Dungeon.level.map[pos + Level.WIDTH] == Terrain.WALL) + && !(Dungeon.level.map[pos - 1] == Terrain.WALL && Dungeon.level.map[pos + 1] == Terrain.WALL)){ + + int c = Dungeon.level.map[pos - Level.WIDTH]; + + if (c == Terrain.WALL || c == Terrain.WALL_DECO) { + Level.set(pos, Terrain.CHASM_WALL); + } else { + Level.set( pos, Terrain.CHASM_FLOOR ); + } + + sprite.parent.add(new WindParticle.Wind(pos)); + GameScene.updateMap( pos ); + } + } + + @Override + public String desc() { + return super.desc(); + } +} diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/RockfallTrap.java b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/RockfallTrap.java new file mode 100644 index 000000000..073eb6dbd --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/levels/traps/RockfallTrap.java @@ -0,0 +1,78 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2015 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ +package com.shatteredpixel.shatteredpixeldungeon.levels.traps; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions; +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.Speck; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.utils.Utils; +import com.watabou.noosa.Camera; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Random; + +public class RockfallTrap extends Trap { + + { + name = "Rockfall trap"; + color = TrapSprite.GREY; + shape = TrapSprite.DIAMOND; + } + + @Override + public void activate() { + + if (Dungeon.visible[ pos ]){ + CellEmitter.get( pos - Level.WIDTH ).start(Speck.factory(Speck.ROCK), 0.07f, 10); + Camera.main.shake( 3, 0.7f ); + Sample.INSTANCE.play( Assets.SND_ROCKS ); + } + + Char ch = Actor.findChar( pos ); + + if (ch != null){ + int damage = Random.NormalIntRange(5+Dungeon.depth, 10+Dungeon.depth*3); + damage -= Random.IntRange( 0, ch.dr()); + ch.damage(damage, this); + + Buff.prolong( ch, Paralysis.class, Paralysis.duration(ch)*2); + + if (!ch.isAlive() && ch == Dungeon.hero){ + Dungeon.fail(Utils.format(ResultDescriptions.TRAP, name)); + GLog.n("You were crushed by the rockfall trap..."); + } + } + } + + @Override + public String desc() { + return "This trap is connected to a series of loose rocks above, " + + "triggering it will cause them to come crashing down."; + } +}