private void jump() { timeToJump = JUMP_DELAY; for (int i = 0; i < 4; i++) { int trapPos; do { trapPos = Random.Int(Level.LENGTH); } while (!Level.fieldOfView[trapPos] || !Level.passable[trapPos]); if (Dungeon.level.map[trapPos] == Terrain.INACTIVE_TRAP) { Level.set(trapPos, Terrain.POISON_TRAP); GameScene.updateMap(trapPos); ScrollOfMagicMapping.discover(trapPos); } } int newPos; do { newPos = Random.Int(Level.LENGTH); } while (!Level.fieldOfView[newPos] || !Level.passable[newPos] || (enemy != null && Level.adjacent(newPos, enemy.pos)) || Actor.findChar(newPos) != null); sprite.move(pos, newPos); move(newPos); if (Dungeon.visible[newPos]) { CellEmitter.get(newPos).burst(Speck.factory(Speck.WOOL), 6); Sample.INSTANCE.play(Assets.SND_PUFF); } spend(1 / speed()); }
public static void paint(Level level, Room room) { fill(level, room, Terrain.WALL); fill(level, room, 1, Terrain.EMPTY_SP); Room.Door entrance = room.entrance(); Point pot = null; if (entrance.x == room.left) { pot = new Point(room.right - 1, Random.Int(2) == 0 ? room.top + 1 : room.bottom - 1); } else if (entrance.x == room.right) { pot = new Point(room.left + 1, Random.Int(2) == 0 ? room.top + 1 : room.bottom - 1); } else if (entrance.y == room.top) { pot = new Point(Random.Int(2) == 0 ? room.left + 1 : room.right - 1, room.bottom - 1); } else if (entrance.y == room.bottom) { pot = new Point(Random.Int(2) == 0 ? room.left + 1 : room.right - 1, room.top + 1); } set(level, pot, Terrain.ALCHEMY); Alchemy alchemy = new Alchemy(); alchemy.seed(pot.x + level.getWidth() * pot.y, 1); level.blobs.put(Alchemy.class, alchemy); int n = Random.IntRange(2, 3); for (int i = 0; i < n; i++) { int pos; do { pos = room.random(level); } while (level.map[pos] != Terrain.EMPTY_SP || level.getHeap(pos) != null); level.drop(prize(level), pos); } entrance.set(Room.Door.Type.LOCKED); level.addItemToSpawn(new IronKey()); }
private static Item prize(Level level) { Item prize = level.itemToSpanAsPrize(); if (prize instanceof Potion) { return prize; } else if (prize != null) { level.addItemToSpawn(prize); } return Generator.random(Generator.Category.POTION); }
public static void paint(Level level, Room room) { Integer traps[] = { Terrain.TOXIC_TRAP, Terrain.TOXIC_TRAP, Terrain.TOXIC_TRAP, Terrain.PARALYTIC_TRAP, Terrain.PARALYTIC_TRAP, !Dungeon.bossLevel(Dungeon.depth + 1) ? Terrain.CHASM : Terrain.SUMMONING_TRAP }; fill(level, room, Terrain.WALL); fill(level, room, 1, Random.element(traps)); Room.Door door = room.entrance(); door.set(Room.Door.Type.REGULAR); int lastRow = level.map[room.left + 1 + (room.top + 1) * Level.WIDTH] == Terrain.CHASM ? Terrain.CHASM : Terrain.EMPTY; int x = -1; int y = -1; if (door.x == room.left) { x = room.right - 1; y = room.top + room.height() / 2; fill(level, x, room.top + 1, 1, room.height() - 1, lastRow); } else if (door.x == room.right) { x = room.left + 1; y = room.top + room.height() / 2; fill(level, x, room.top + 1, 1, room.height() - 1, lastRow); } else if (door.y == room.top) { x = room.left + room.width() / 2; y = room.bottom - 1; fill(level, room.left + 1, y, room.width() - 1, 1, lastRow); } else if (door.y == room.bottom) { x = room.left + room.width() / 2; y = room.top + 1; fill(level, room.left + 1, y, room.width() - 1, 1, lastRow); } int pos = x + y * Level.WIDTH; if (Random.Int(3) == 0) { if (lastRow == Terrain.CHASM) { set(level, pos, Terrain.EMPTY); } level.drop(prize(level), pos).type = Heap.Type.CHEST; } else { set(level, pos, Terrain.PEDESTAL); level.drop(prize(level), pos); } level.addItemToSpawn(new PotionOfLevitation()); }
public static void reallyDie(Object cause) { int length = Level.LENGTH; int[] map = Dungeon.level.map; boolean[] visited = Dungeon.level.visited; boolean[] discoverable = Level.discoverable; for (int i = 0; i < length; i++) { int terr = map[i]; if (discoverable[i]) { visited[i] = true; if ((Terrain.flags[terr] & Terrain.SECRET) != 0) { Level.set(i, Terrain.discover(terr)); GameScene.updateMap(i); } } } Bones.leave(); Dungeon.observe(); Dungeon.hero.belongings.identify(); GameScene.gameOver(); if (cause instanceof Hero.Doom) { ((Hero.Doom) cause).onDeath(); } Dungeon.deleteGame(Dungeon.hero.heroClass, true); }
@Override public void onOperateComplete() { if (curAction instanceof HeroAction.Unlock) { if (theKey != null) { theKey.detach(belongings.backpack); theKey = null; } int doorCell = ((HeroAction.Unlock) curAction).dst; int door = Dungeon.level.map[doorCell]; Level.set(doorCell, door == Terrain.LOCKED_DOOR ? Terrain.DOOR : Terrain.UNLOCKED_EXIT); GameScene.updateMap(doorCell); } else if (curAction instanceof HeroAction.OpenChest) { if (theKey != null) { theKey.detach(belongings.backpack); theKey = null; } Heap heap = Dungeon.level.heaps.get(((HeroAction.OpenChest) curAction).dst); if (heap.type == Type.SKELETON) { Sample.INSTANCE.play(Assets.SND_BONES); } heap.open(this); } curAction = null; super.onOperateComplete(); }
public static void resetLevel() { Actor.clear(); Arrays.fill(visible, false); level.reset(); switchLevel(level, level.entrance); }
@Override protected boolean doAttack(Char enemy) { timeToJump--; if (timeToJump <= 0 && Level.adjacent(pos, enemy.pos)) { jump(); return true; } else { return super.doAttack(enemy); } }
private boolean actOpenChest(HeroAction.OpenChest action) { int dst = action.dst; if (Level.adjacent(pos, dst) || pos == dst) { Heap heap = Dungeon.level.heaps.get(dst); if (heap != null && (heap.type == Type.CHEST || heap.type == Type.TOMB || heap.type == Type.SKELETON || heap.type == Type.LOCKED_CHEST || heap.type == Type.CRYSTAL_CHEST)) { theKey = null; if (heap.type == Type.LOCKED_CHEST || heap.type == Type.CRYSTAL_CHEST) { theKey = belongings.getKey(GoldenKey.class, Dungeon.depth); if (theKey == null) { GLog.w(TXT_LOCKED_CHEST); ready(); return false; } } switch (heap.type) { case TOMB: Sample.INSTANCE.play(Assets.SND_TOMB); Camera.main.shake(1, 0.5f); break; case SKELETON: break; default: Sample.INSTANCE.play(Assets.SND_UNLOCK); } spend(Key.TIME_TO_UNLOCK); sprite.operate(dst); } else { ready(); } return false; } else if (getCloser(dst)) { return true; } else { ready(); return false; } }
@SuppressWarnings("deprecation") public static void switchLevel(final Level level, int pos) { nightMode = new Date().getHours() < 7; Dungeon.level = level; Actor.init(); Actor respawner = level.respawner(); if (respawner != null) { Actor.add(level.respawner()); } hero.pos = pos != -1 ? pos : level.exit; Light light = hero.buff(Light.class); hero.viewDistance = light == null ? level.viewDistance : Math.max(Light.DISTANCE, level.viewDistance); observe(); }
public static void paint(Level level, Room room) { fill(level, room, Terrain.WALL); fill(level, room, 1, Terrain.EMPTY); Room.Door entrance = room.entrance(); entrance.set(Room.Door.Type.LOCKED); Point well = null; if (entrance.x == room.left) { well = new Point(room.right - 1, Random.Int(2) == 0 ? room.top + 1 : room.bottom - 1); } else if (entrance.x == room.right) { well = new Point(room.left + 1, Random.Int(2) == 0 ? room.top + 1 : room.bottom - 1); } else if (entrance.y == room.top) { well = new Point(Random.Int(2) == 0 ? room.left + 1 : room.right - 1, room.bottom - 1); } else if (entrance.y == room.bottom) { well = new Point(Random.Int(2) == 0 ? room.left + 1 : room.right - 1, room.top + 1); } set(level, well, Terrain.EMPTY_WELL); int remains = room.random(); while (level.map[remains] == Terrain.EMPTY_WELL) { remains = room.random(); } level.drop(new IronKey(), remains).type = Type.SKELETON; if (Random.Int(5) == 0) { level.drop(Generator.random(Generator.Category.RING), remains); } else { level.drop( Generator.random(Random.oneOf(Generator.Category.WEAPON, Generator.Category.ARMOR)), remains); } int n = Random.IntRange(1, 2); for (int i = 0; i < n; i++) { level.drop(prize(level), remains); } }
public static void observe() { if (level == null) { return; } level.updateFieldOfView(hero); System.arraycopy(Level.fieldOfView, 0, visible, 0, visible.length); BArray.or(level.visited, visible, level.visited); GameScene.afterObserve(); }
private static Item prize(Level level) { Item prize = level.itemToSpanAsPrize(); if (prize != null) { return prize; } return Generator.random( Random.oneOf( Generator.Category.POTION, Generator.Category.SCROLL, Generator.Category.FOOD, Generator.Category.GOLD)); }
private boolean getCloser(final int target) { if (rooted) { return false; } int step = -1; if (Level.adjacent(pos, target)) { if (Actor.findChar(target) == null) { if (Level.pit[target] && !flying && !Chasm.jumpConfirmed) { Chasm.heroJump(this); interrupt(); return false; } if (Level.passable[target] || Level.avoid[target]) { step = target; } } } else { int len = Level.LENGTH; boolean[] p = Level.passable; boolean[] v = Dungeon.level.visited; boolean[] m = Dungeon.level.mapped; boolean[] passable = new boolean[len]; for (int i = 0; i < len; i++) { passable[i] = p[i] && (v[i] || m[i]); } step = Dungeon.findPath(this, pos, target, passable, Level.fieldOfView); } if (step != -1) { int oldPos = pos; move(step); sprite.move(oldPos, pos); spend(1 / speed()); return true; } else { return false; } }
@Override public int attackSkill(Char target) { int bonus = 0; for (Buff buff : buffs(RingOfAccuracy.Accuracy.class)) { bonus += ((RingOfAccuracy.Accuracy) buff).level; } float accuracy = (bonus == 0) ? 1 : (float) Math.pow(1.4, bonus); if (rangedWeapon != null && Level.distance(pos, target.pos) == 1) { accuracy *= 0.5f; } KindOfWeapon wep = rangedWeapon != null ? rangedWeapon : belongings.weapon; if (wep != null) { return (int) (attackSkill * accuracy * wep.acuracyFactor(this)); } else { return (int) (attackSkill * accuracy); } }
private static Item prize(Level level) { Item prize = level.itemToSpanAsPrize(); if (prize != null) { return prize; } prize = Generator.random(Random.oneOf(Generator.Category.WEAPON, Generator.Category.ARMOR)); for (int i = 0; i < 3; i++) { Item another = Generator.random(Random.oneOf(Generator.Category.WEAPON, Generator.Category.ARMOR)); if (another.level > prize.level) { prize = another; } } return prize; }
private boolean actUnlock(HeroAction.Unlock action) { int doorCell = action.dst; if (Level.adjacent(pos, doorCell)) { theKey = null; int door = Dungeon.level.map[doorCell]; if (door == Terrain.LOCKED_DOOR) { theKey = belongings.getKey(IronKey.class, Dungeon.depth); } else if (door == Terrain.LOCKED_EXIT) { theKey = belongings.getKey(SkeletonKey.class, Dungeon.depth); } if (theKey != null) { spend(Key.TIME_TO_UNLOCK); sprite.operate(doorCell); Sample.INSTANCE.play(Assets.SND_UNLOCK); } else { GLog.w(TXT_LOCKED_DOOR); ready(); } return false; } else if (getCloser(doorCell)) { return true; } else { ready(); return false; } }
private boolean actBuy(HeroAction.Buy action) { int dst = action.dst; if (pos == dst || Level.adjacent(pos, dst)) { ready(); Heap heap = Dungeon.level.heaps.get(dst); if (heap != null && heap.type == Type.FOR_SALE && heap.size() == 1) { GameScene.show(new WndTradeItem(heap, true)); } return false; } else if (getCloser(dst)) { return true; } else { ready(); return false; } }
public static int findPath(Char ch, int from, int to, boolean pass[], boolean[] visible) { if (Level.adjacent(from, to)) { return Actor.findChar(to) == null && (pass[to] || Level.avoid[to]) ? to : -1; } if (ch.flying || ch.buff(Amok.class) != null) { BArray.or(pass, Level.avoid, passable); } else { System.arraycopy(pass, 0, passable, 0, Level.LENGTH); } for (Actor actor : Actor.all()) { if (actor instanceof Char) { int pos = ((Char) actor).pos; if (visible[pos]) { passable[pos] = false; } } } return PathFinder.getStep(from, to, passable); }
private boolean actAttack(HeroAction.Attack action) { enemy = action.target; if (Level.adjacent(pos, enemy.pos) && enemy.isAlive() && !pacified) { spend(attackDelay()); sprite.attack(enemy.pos); return false; } else { if (Level.fieldOfView[enemy.pos] && getCloser(enemy.pos)) { return true; } else { ready(); return false; } } }
private boolean actInteract(HeroAction.Interact action) { NPC npc = action.npc; if (Level.adjacent(pos, npc.pos)) { ready(); sprite.turnTo(pos, npc.pos); npc.interact(); return false; } else { if (Level.fieldOfView[npc.pos] && getCloser(npc.pos)) { return true; } else { ready(); return false; } } }
public boolean search(boolean intentional) { boolean smthFound = false; int positive = 0; int negative = 0; for (Buff buff : buffs(RingOfDetection.Detection.class)) { int bonus = ((RingOfDetection.Detection) buff).level; if (bonus > positive) { positive = bonus; } else if (bonus < 0) { negative += bonus; } } int distance = 1 + positive + negative; float level = intentional ? (2 * awareness - awareness * awareness) : awareness; if (distance <= 0) { level /= 2 - distance; distance = 1; } int cx = pos % Level.WIDTH; int cy = pos / Level.WIDTH; int ax = cx - distance; if (ax < 0) { ax = 0; } int bx = cx + distance; if (bx >= Level.WIDTH) { bx = Level.WIDTH - 1; } int ay = cy - distance; if (ay < 0) { ay = 0; } int by = cy + distance; if (by >= Level.HEIGHT) { by = Level.HEIGHT - 1; } for (int y = ay; y <= by; y++) { for (int x = ax, p = ax + y * Level.WIDTH; x <= bx; x++, p++) { if (Dungeon.visible[p]) { if (intentional) { sprite.parent.addToBack(new CheckedCell(p)); } if (Level.secret[p] && (intentional || Random.Float() < level)) { int oldValue = Dungeon.level.map[p]; GameScene.discoverTile(p, oldValue); Level.set(p, Terrain.discover(oldValue)); GameScene.updateMap(p); ScrollOfMagicMapping.discover(p); smthFound = true; } } } } if (intentional) { sprite.showStatus(CharSprite.DEFAULT, TXT_SEARCH); sprite.operate(pos); if (smthFound) { spendAndNext(Random.Float() < level ? TIME_TO_SEARCH : TIME_TO_SEARCH * 2); } else { spendAndNext(TIME_TO_SEARCH); } } if (smthFound) { GLog.w(TXT_NOTICED_SMTH); Sample.INSTANCE.play(Assets.SND_SECRET); interrupt(); } return smthFound; }
public static Level newLevel() { Dungeon.level = null; Actor.clear(); depth++; if (depth > Statistics.deepestFloor) { Statistics.deepestFloor = depth; if (Statistics.qualifiedForNoKilling) { Statistics.completedWithNoKilling = true; } else { Statistics.completedWithNoKilling = false; } } Arrays.fill(visible, false); Level level; switch (depth) { case 1: case 2: case 3: case 4: level = new SewerLevel(); break; case 5: level = new SewerBossLevel(); break; case 6: case 7: case 8: case 9: level = new PrisonLevel(); break; case 10: level = new PrisonBossLevel(); break; case 11: case 12: case 13: case 14: level = new CavesLevel(); break; case 15: level = new CavesBossLevel(); break; case 16: case 17: case 18: case 19: level = new CityLevel(); break; case 20: level = new CityBossLevel(); break; case 21: level = new LastShopLevel(); break; case 22: case 23: case 24: level = new HallsLevel(); break; case 25: level = new HallsBossLevel(); break; case 26: level = new LastLevel(); break; default: level = new DeadEndLevel(); Statistics.deepestFloor--; } level.create(); Statistics.qualifiedForNoKilling = !bossLevel(); return level; }