v0.8.0: significant balance adjustments and design tweaks to traps

This commit is contained in:
Evan Debenham 2019-11-27 20:28:33 -05:00
parent d39fd4b8f9
commit 9326a3bdd4
18 changed files with 275 additions and 129 deletions

View File

@ -63,6 +63,38 @@ public class RatKing extends NPC {
return true;
}
//***This functionality is for when rat king may be summoned by a distortion trap
@Override
protected void onAdd() {
super.onAdd();
if (Dungeon.depth != 5){
yell(Messages.get(this, "confused"));
}
}
@Override
protected boolean act() {
if (Dungeon.depth < 5){
if (pos == Dungeon.level.exit){
destroy();
sprite.killAndErase();
} else {
target = Dungeon.level.exit;
}
} else if (Dungeon.depth > 5){
if (pos == Dungeon.level.entrance){
destroy();
sprite.killAndErase();
} else {
target = Dungeon.level.entrance;
}
}
return super.act();
}
//***
@Override
public boolean interact() {
sprite.turnTo( pos, Dungeon.hero.pos );

View File

@ -30,7 +30,6 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BurningTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ConfusionTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CorrosionTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrippingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GuardianTrap;
@ -96,18 +95,18 @@ public class CavesLevel extends RegularLevel {
@Override
protected Class<?>[] trapClasses() {
return new Class[]{ BurningTrap.class, PoisonDartTrap.class, FrostTrap.class, StormTrap.class, CorrosionTrap.class,
GrippingTrap.class, ExplosiveTrap.class, RockfallTrap.class, GuardianTrap.class,
ConfusionTrap.class, SummoningTrap.class, WarpingTrap.class,
PitfallTrap.class };
return new Class[]{
BurningTrap.class, PoisonDartTrap.class, FrostTrap.class, StormTrap.class, CorrosionTrap.class,
GrippingTrap.class, RockfallTrap.class, GuardianTrap.class,
ConfusionTrap.class, SummoningTrap.class, WarpingTrap.class, PitfallTrap.class };
}
@Override
protected float[] trapChances() {
return new float[]{ 8, 8, 8, 8, 8,
4, 4, 4, 4,
return new float[]{
4, 4, 4, 4, 4,
2, 2, 2,
1 };
1, 1, 1, 1};
}
@Override

View File

@ -31,7 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CorrosionTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisarmingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisintegrationTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DistortionTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FlashingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GuardianTrap;
@ -88,18 +88,18 @@ public class CityLevel extends RegularLevel {
@Override
protected Class<?>[] trapClasses() {
return new Class[]{ FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class,
ExplosiveTrap.class, RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class,
SummoningTrap.class, WarpingTrap.class, CursingTrap.class,
PitfallTrap.class, DisarmingTrap.class };
return new Class[]{
FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class,
RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class,
DisarmingTrap.class, SummoningTrap.class, WarpingTrap.class, CursingTrap.class, PitfallTrap.class, DistortionTrap.class };
}
@Override
protected float[] trapChances() {
return new float[]{ 8, 8, 8, 8, 8,
return new float[]{
4, 4, 4, 4, 4,
2, 2, 2,
1, 1 };
2, 2, 2, 2,
1, 1, 1, 1, 1, 1 };
}
@Override

View File

@ -32,7 +32,6 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisarmingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisintegrationTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DistortionTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FlashingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrimTrap;
@ -100,18 +99,18 @@ public class HallsLevel extends RegularLevel {
@Override
protected Class<?>[] trapClasses() {
return new Class[]{ FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class,
ExplosiveTrap.class, RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class,
SummoningTrap.class, WarpingTrap.class, CursingTrap.class, GrimTrap.class,
PitfallTrap.class, DisarmingTrap.class, DistortionTrap.class };
return new Class[]{
FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class,
RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class,
DisarmingTrap.class, SummoningTrap.class, WarpingTrap.class, CursingTrap.class, GrimTrap.class, PitfallTrap.class, DistortionTrap.class };
}
@Override
protected float[] trapChances() {
return new float[]{ 8, 8, 8, 8, 8,
return new float[]{
4, 4, 4, 4, 4,
2, 2, 2, 2,
1, 1, 1 };
1, 1, 1, 1, 1, 1, 1 };
}
@Override

View File

@ -493,6 +493,8 @@ public abstract class Level implements Bundlable {
@Override
protected boolean act() {
int count = 0;
//TODO some mobs should count for less (ripper shouldn't count at all, ghouls should be 1/2, special enemies should be 0
for (Mob mob : mobs.toArray(new Mob[0])){
if (mob.alignment == Char.Alignment.ENEMY) count++;
}

View File

@ -94,16 +94,18 @@ public class PrisonLevel extends RegularLevel {
@Override
protected Class<?>[] trapClasses() {
return new Class[]{ ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, BurningTrap.class, PoisonDartTrap.class,
return new Class[]{
ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, BurningTrap.class, PoisonDartTrap.class,
AlarmTrap.class, OozeTrap.class, GrippingTrap.class,
ConfusionTrap.class, FlockTrap.class, SummoningTrap.class, TeleportationTrap.class, };
}
@Override
protected float[] trapChances() {
return new float[]{ 8, 8, 8, 8, 8,
4, 4, 4,
2, 2, 2, 2 };
return new float[]{
4, 4, 4, 4, 4,
2, 2, 2,
1, 1, 1, 1 };
}
@Override

View File

@ -141,7 +141,7 @@ public abstract class RegularLevel extends Level {
protected abstract Painter painter();
protected int nTraps() {
return Random.NormalIntRange( 1, 3+(Dungeon.depth/3) );
return Random.NormalIntRange( 2, 3 + (Dungeon.depth/5) );
}
protected Class<?>[] trapClasses(){

View File

@ -90,7 +90,8 @@ public class SewerLevel extends RegularLevel {
protected Class<?>[] trapClasses() {
return Dungeon.depth == 1 ?
new Class<?>[]{ WornDartTrap.class } :
new Class<?>[]{ ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, WornDartTrap.class,
new Class<?>[]{
ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, WornDartTrap.class,
AlarmTrap.class, OozeTrap.class,
ConfusionTrap.class, FlockTrap.class, SummoningTrap.class, TeleportationTrap.class };
}
@ -99,9 +100,10 @@ public class SewerLevel extends RegularLevel {
protected float[] trapChances() {
return Dungeon.depth == 1 ?
new float[]{1} :
new float[]{8, 8, 8, 8,
4, 4,
2, 2, 2, 2};
new float[]{
4, 4, 4, 4,
2, 2,
1, 1, 1, 1};
}
@Override

View File

@ -30,14 +30,13 @@ import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.KindofMisc;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Random;
import java.util.ArrayList;
import java.util.Collections;
@ -76,7 +75,7 @@ public class CursingTrap extends Trap {
ArrayList<Item> canCurse = new ArrayList<>();
KindOfWeapon weapon = hero.belongings.weapon;
if (weapon instanceof Weapon && !weapon.cursed){
if (weapon instanceof Weapon && !(weapon instanceof MagesStaff)){
if (((Weapon) weapon).enchantment == null)
priorityCurse.add(weapon);
else
@ -84,35 +83,21 @@ public class CursingTrap extends Trap {
}
Armor armor = hero.belongings.armor;
if (armor != null && !armor.cursed){
if (armor != null){
if (armor.glyph == null)
priorityCurse.add(armor);
else
canCurse.add(armor);
}
KindofMisc misc1 = hero.belongings.misc1;
if (misc1 != null){
canCurse.add(misc1);
}
KindofMisc misc2 = hero.belongings.misc2;
if (misc2 != null){
canCurse.add(misc2);
}
Collections.shuffle(priorityCurse);
Collections.shuffle(canCurse);
int numCurses = Random.Int(2) == 0 ? 1 : 2;
for (int i = 0; i < numCurses; i++){
if (!priorityCurse.isEmpty()){
curse(priorityCurse.remove(0));
} else if (!canCurse.isEmpty()){
curse(canCurse.remove(0));
}
}
EquipableItem.equipCursed(hero);
GLog.n( Messages.get(CursingTrap.class, "curse") );

View File

@ -67,16 +67,21 @@ public class DisarmingTrap extends Trap{
if (weapon != null && !weapon.cursed) {
int cell = Dungeon.level.randomRespawnCell();
if (cell != -1) {
int cell;
do {
cell = Dungeon.level.randomRespawnCell();
PathFinder.buildDistanceMap(pos, Dungeon.level.passable);
} while (cell == -1 || PathFinder.distance[cell] < 10 || PathFinder.distance[cell] > 20);
hero.belongings.weapon = null;
Dungeon.quickslot.clearItem(weapon);
weapon.updateQuickslot();
Dungeon.level.drop(weapon, cell).seen = true;
for (int i : PathFinder.NEIGHBOURS9)
Dungeon.level.visited[cell+i] = true;
GameScene.updateFog();
Dungeon.level.mapped[cell+i] = true;
GameScene.updateFog(cell, 1);
GLog.w( Messages.get(this, "disarm") );
@ -84,8 +89,6 @@ public class DisarmingTrap extends Trap{
CellEmitter.get(pos).burst(Speck.factory(Speck.LIGHT), 4);
}
}
}
}
}

View File

@ -29,8 +29,6 @@ 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.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
@ -76,24 +74,6 @@ public class DisintegrationTrap extends Trap {
if (!hero.isAlive()){
Dungeon.fail( getClass() );
GLog.n( Messages.get(this, "ondeath") );
} 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 == null || item.level() > 0 || item.unique) return;
if (!item.stackable){
item.detachAll(bag);
GLog.w( Messages.get(this, "one", item.name()) );
} else {
int n = Random.NormalIntRange(1, (item.quantity()+1)/2);
for(int i = 1; i <= n; i++)
item.detach(bag);
GLog.w( Messages.get(this, "some", item.name()) );
}
}
}
}

View File

@ -22,37 +22,136 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.traps;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
import com.shatteredpixel.shatteredpixeldungeon.journal.Notes;
import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene;
import com.watabou.noosa.Game;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Acidic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Albino;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ArmoredBrute;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bandit;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bestiary;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CausticSlime;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Piranha;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Senior;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Statue;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.RatKing;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
import com.watabou.utils.Reflection;
import java.util.ArrayList;
import java.util.Arrays;
public class DistortionTrap extends Trap{
private static final float DELAY = 2f;
{
color = TEAL;
shape = LARGE_DOT;
}
private static final ArrayList<Class<?extends Mob>> RARE = new ArrayList<>(Arrays.asList(
Albino.class, CausticSlime.class,
Bandit.class,
ArmoredBrute.class,
Elemental.Chaos.class, Senior.class,
Acidic.class));
@Override
public void activate() {
InterlevelScene.returnDepth = Dungeon.depth;
Belongings belongings = Dungeon.hero.belongings;
for (Notes.Record rec : Notes.getRecords()){
if (rec.depth() == Dungeon.depth){
Notes.remove(rec);
int nMobs = 3;
if (Random.Int( 2 ) == 0) {
nMobs++;
if (Random.Int( 2 ) == 0) {
nMobs++;
}
}
for (Item i : belongings){
if (i instanceof LloydsBeacon && ((LloydsBeacon) i).returnDepth == Dungeon.depth)
((LloydsBeacon) i).returnDepth = -1;
ArrayList<Integer> candidates = new ArrayList<>();
for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) {
int p = pos + PathFinder.NEIGHBOURS8[i];
if (Actor.findChar( p ) == null && (Dungeon.level.passable[p] || Dungeon.level.avoid[p])) {
candidates.add( p );
}
}
ArrayList<Integer> respawnPoints = new ArrayList<>();
while (nMobs > 0 && candidates.size() > 0) {
int index = Random.index( candidates );
respawnPoints.add( candidates.remove( index ) );
nMobs--;
}
ArrayList<Mob> mobs = new ArrayList<>();
int summoned = 0;
for (Integer point : respawnPoints) {
summoned++;
Mob mob;
switch (summoned){
case 1:
if (Dungeon.depth != 5 && Random.Int(100) == 0){
mob = new RatKing();
break;
}
case 3: case 5 : default:
int floor;
do {
floor = Random.Int(25);
} while( Dungeon.bossLevel(floor));
mob = Reflection.newInstance(Bestiary.getMobRotation(floor).get(0));
break;
case 2:
switch (Random.Int(4)){
case 0: default:
Wraith.spawnAt(point);
continue; //wraiths spawn themselves, no need to do more
case 1:
//yes it's intended that these are likely to die right away
mob = new Piranha();
break;
case 2:
Mimic.spawnAt(point, new ArrayList<>());
continue; //mimics spawn themselves, no need to do more
case 3:
mob = new Statue();
break;
}
break;
case 4:
mob = Reflection.newInstance(Random.element(RARE));
break;
}
mob.maxLvl = Hero.MAX_LEVEL;
mob.state = mob.WANDERING;
mob.pos = point;
GameScene.add(mob, DELAY);
mobs.add(mob);
}
//important to process the visuals and pressing of cells last, so spawned mobs have a chance to occupy cells first
Trap t;
for (Mob mob : mobs){
//manually trigger traps first to avoid sfx spam
if ((t = Dungeon.level.traps.get(mob.pos)) != null && t.active){
t.disarm();
t.reveal();
t.activate();
}
ScrollOfTeleportation.appear(mob, mob.pos);
Dungeon.level.occupyCell(mob);
}
InterlevelScene.mode = InterlevelScene.Mode.RESET;
Game.switchScene(InterlevelScene.class);
}
}

View File

@ -21,11 +21,13 @@
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.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze;
import com.shatteredpixel.shatteredpixeldungeon.effects.Splash;
import com.watabou.utils.PathFinder;
public class OozeTrap extends Trap {
@ -36,11 +38,15 @@ public class OozeTrap extends Trap {
@Override
public void activate() {
Char ch = Actor.findChar( pos );
for( int i : PathFinder.NEIGHBOURS9) {
if (!Dungeon.level.solid[pos + i]) {
Splash.at( pos + i, 0x000000, 5);
Char ch = Actor.findChar( pos + i );
if (ch != null && !ch.flying){
Buff.affect(ch, Ooze.class).set( 20f );
Splash.at( pos, 0x000000, 5);
}
}
}
}
}

View File

@ -24,6 +24,8 @@ 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.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
@ -31,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.PathFinder;
public class PitfallTrap extends Trap {
@ -47,26 +50,57 @@ public class PitfallTrap extends Trap {
return;
}
Heap heap = Dungeon.level.heaps.get( pos );
//TODO visuals
DelayedPit p = Buff.affect(Dungeon.hero, DelayedPit.class, 1);
p.depth = Dungeon.depth;
p.pos = pos;
if (heap != null){
for (Item item : heap.items){
if (pos == Dungeon.hero.pos){
GLog.n(Messages.get(this, "triggered_hero"));
} else if (Dungeon.level.heroFOV[pos]){
GLog.n(Messages.get(this, "triggered"));
}
}
public static class DelayedPit extends FlavourBuff {
int pos;
int depth;
@Override
public boolean act() {
if (depth == Dungeon.depth) {
for (int i : PathFinder.NEIGHBOURS9) {
int cell = pos + i;
Heap heap = Dungeon.level.heaps.get(cell);
if (heap != null) {
for (Item item : heap.items) {
Dungeon.dropToChasm(item);
}
heap.sprite.kill();
GameScene.discard(heap);
Dungeon.level.heaps.remove( pos );
Dungeon.level.heaps.remove(cell);
}
Char ch = Actor.findChar( pos );
Char ch = Actor.findChar(cell);
if (ch != null && !ch.flying) {
if (ch == Dungeon.hero) {
Chasm.heroFall(pos);
Chasm.heroFall(cell);
} else {
Chasm.mobFall((Mob) ch);
}
}
}
}
detach();
return true;
}
}
//TODO these used to become chasms when disarmed, but the functionality was problematic

View File

@ -88,7 +88,7 @@ public class PoisonDartTrap extends Trap {
reset(pos, finalTarget.sprite, new PoisonDart(), new Callback() {
@Override
public void call() {
int dmg = Random.NormalIntRange(1, 4) - finalTarget.drRoll();
int dmg = Random.NormalIntRange(4, 8) - finalTarget.drRoll();
finalTarget.damage(dmg, trap);
if (finalTarget == Dungeon.hero && !finalTarget.isAlive()){
Dungeon.fail( trap.getClass() );

View File

@ -74,7 +74,7 @@ public class WornDartTrap extends Trap {
reset(pos, finalTarget.sprite, new Dart(), new Callback() {
@Override
public void call() {
int dmg = Random.NormalIntRange(1, 4) - finalTarget.drRoll();
int dmg = Random.NormalIntRange(4, 8) - finalTarget.drRoll();
finalTarget.damage(dmg, trap);
if (finalTarget == Dungeon.hero && !finalTarget.isAlive()){
Dungeon.fail( trap.getClass() );

View File

@ -406,6 +406,7 @@ actors.mobs.npcs.prismaticimage.desc=This shimmering illusion bears a close rese
actors.mobs.npcs.ratking.name=rat king
actors.mobs.npcs.ratking.not_sleeping=I'm not sleeping!
actors.mobs.npcs.ratking.what_is_it=What is it? I have no time for this nonsense. My kingdom won't rule itself!
actors.mobs.npcs.ratking.confused=Wha... Where am I? My kingdom needs me!
actors.mobs.npcs.ratking.desc_festive=This rat is a little bigger than a regular marsupial rat. It's wearing a tiny festive hat instead of its usual crown. Happy Holidays!
actors.mobs.npcs.ratking.desc=This rat is a little bigger than a regular marsupial rat and it's wearing a tiny crown on its head.

View File

@ -51,7 +51,7 @@ levels.traps.disintegrationtrap.ondeath=You were killed by the disintegration tr
levels.traps.disintegrationtrap.desc=When triggered, this trap will lance the nearest target with beams of disintegration, dealing significant damage and destroying items.\n\nThankfully the trigger mechanism isn't hidden.
levels.traps.distortiontrap.name=distortion trap
levels.traps.distortiontrap.desc=Built from strange magic of unknown origin, this trap will shift and morph the world around you.
levels.traps.distortiontrap.desc=Built from strange magic of unknown origin, this trap will summon all manner of creatures to this location.
levels.traps.explosivetrap.name=explosive trap
levels.traps.explosivetrap.desc=This trap contains some powdered explosive and a trigger mechanism. Activating it will cause an explosion in the immediate area.
@ -82,8 +82,10 @@ levels.traps.oozetrap.name=ooze trap
levels.traps.oozetrap.desc=This trap will splash out caustic ooze when activated, which will burn until it is washed away.
levels.traps.pitfalltrap.name=pitfall trap
levels.traps.pitfalltrap.triggered_hero=The ground starts to give way around you!
levels.traps.pitfalltrap.triggered=The ground starts to give way around the triggered trap!
levels.traps.pitfalltrap.no_pit=the ground is too solid for a pitfall trap to work here.
levels.traps.pitfalltrap.desc=This trap will cause anything that triggers it to slip right through the ground and fall! It won't work in areas with especially solid floors though.
levels.traps.pitfalltrap.desc=This trap is connected to a large trapdoor mechanism, and shortly after it is triggered anything near it will slip right through the ground and fall! It won't work in areas with especially solid floors though.
levels.traps.poisondarttrap.name=poison dart trap
levels.traps.poisondarttrap.desc=A small dart-blower must be hidden nearby, activating this trap will cause it to shoot a poisoned dart at the nearest target.\n\nThankfully the trigger mechanism isn't hidden.