/* * Pixel Dungeon * Copyright (C) 2012-2014 Oleg Dolya * * 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; import com.watabou.noosa.Scene; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Bones; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bestiary; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.watabou.utils.Bundle; import com.watabou.utils.Random; public class CityBossLevel extends Level { { color1 = 0x4b6636; color2 = 0xf2f2f2; } private static final int TOP = 2; private static final int HALL_WIDTH = 7; private static final int HALL_HEIGHT = 15; private static final int CHAMBER_HEIGHT = 3; private static final int LEFT = (WIDTH - HALL_WIDTH) / 2; private static final int CENTER = LEFT + HALL_WIDTH / 2; private int arenaDoor; private boolean enteredArena = false; private boolean keyDropped = false; @Override public String tilesTex() { return Assets.TILES_CITY; } @Override public String waterTex() { return Assets.WATER_CITY; } private static final String DOOR = "door"; private static final String ENTERED = "entered"; private static final String DROPPED = "droppped"; @Override public void storeInBundle( Bundle bundle ) { super.storeInBundle( bundle ); bundle.put( DOOR, arenaDoor ); bundle.put( ENTERED, enteredArena ); bundle.put( DROPPED, keyDropped ); } @Override public void restoreFromBundle( Bundle bundle ) { super.restoreFromBundle( bundle ); arenaDoor = bundle.getInt( DOOR ); enteredArena = bundle.getBoolean( ENTERED ); keyDropped = bundle.getBoolean( DROPPED ); } @Override protected boolean build() { Painter.fill( this, LEFT, TOP, HALL_WIDTH, HALL_HEIGHT, Terrain.EMPTY ); Painter.fill( this, CENTER, TOP, 1, HALL_HEIGHT, Terrain.EMPTY_SP ); int y = TOP + 1; while (y < TOP + HALL_HEIGHT) { map[y * WIDTH + CENTER - 2] = Terrain.STATUE_SP; map[y * WIDTH + CENTER + 2] = Terrain.STATUE_SP; y += 2; } int left = pedestal( true ); int right = pedestal( false ); map[left] = map[right] = Terrain.PEDESTAL; for (int i=left+1; i < right; i++) { map[i] = Terrain.EMPTY_SP; } exit = (TOP - 1) * WIDTH + CENTER; map[exit] = Terrain.LOCKED_EXIT; arenaDoor = (TOP + HALL_HEIGHT) * WIDTH + CENTER; map[arenaDoor] = Terrain.DOOR; Painter.fill( this, LEFT, TOP + HALL_HEIGHT + 1, HALL_WIDTH, CHAMBER_HEIGHT, Terrain.EMPTY ); Painter.fill( this, LEFT, TOP + HALL_HEIGHT + 1, 1, CHAMBER_HEIGHT, Terrain.BOOKSHELF ); Painter.fill( this, LEFT + HALL_WIDTH - 1, TOP + HALL_HEIGHT + 1, 1, CHAMBER_HEIGHT, Terrain.BOOKSHELF ); entrance = (TOP + HALL_HEIGHT + 2 + Random.Int( CHAMBER_HEIGHT - 1 )) * WIDTH + LEFT + (/*1 +*/ Random.Int( HALL_WIDTH-2 )); map[entrance] = Terrain.ENTRANCE; return true; } @Override protected void decorate() { for (int i=0; i < LENGTH; i++) { if (map[i] == Terrain.EMPTY && Random.Int( 10 ) == 0) { map[i] = Terrain.EMPTY_DECO; } else if (map[i] == Terrain.WALL && Random.Int( 8 ) == 0) { map[i] = Terrain.WALL_DECO; } } int sign = arenaDoor + WIDTH + 1; map[sign] = Terrain.SIGN; } public static int pedestal( boolean left ) { if (left) { return (TOP + HALL_HEIGHT / 2) * WIDTH + CENTER - 2; } else { return (TOP + HALL_HEIGHT / 2) * WIDTH + CENTER + 2; } } @Override protected void createMobs() { } public Actor respawner() { return null; } @Override protected void createItems() { Item item = Bones.get(); if (item != null) { int pos; do { pos = Random.IntRange( LEFT + 1, LEFT + HALL_WIDTH - 2 ) + Random.IntRange( TOP + HALL_HEIGHT + 1, TOP + HALL_HEIGHT + CHAMBER_HEIGHT ) * WIDTH; } while (pos == entrance || map[pos] == Terrain.SIGN); drop( item, pos ).type = Heap.Type.SKELETON; } } @Override public int randomRespawnCell() { return -1; } @Override public void press( int cell, Char hero ) { super.press( cell, hero ); if (!enteredArena && outsideEntraceRoom( cell ) && hero == Dungeon.hero) { enteredArena = true; Mob boss = Bestiary.mob( Dungeon.depth ); boss.state = Mob.State.HUNTING; do { boss.pos = Random.Int( LENGTH ); } while ( !passable[boss.pos] || !outsideEntraceRoom( boss.pos ) || Dungeon.visible[boss.pos]); GameScene.add( boss ); set( arenaDoor, Terrain.LOCKED_DOOR ); GameScene.updateMap( arenaDoor ); Dungeon.observe(); } } @Override public Heap drop( Item item, int cell ) { if (!keyDropped && item instanceof SkeletonKey) { keyDropped = true; set( arenaDoor, Terrain.DOOR ); GameScene.updateMap( arenaDoor ); Dungeon.observe(); } return super.drop( item, cell ); } private boolean outsideEntraceRoom( int cell ) { return cell / WIDTH < arenaDoor / WIDTH; } @Override public String tileName( int tile ) { switch (tile) { case Terrain.WATER: return "Suspiciously colored water"; case Terrain.HIGH_GRASS: return "High blooming flowers"; default: return super.tileName( tile ); } } @Override public String tileDesc(int tile) { switch (tile) { case Terrain.ENTRANCE: return "A ramp leads up to the upper depth."; case Terrain.EXIT: return "A ramp leads down to the lower depth."; case Terrain.WALL_DECO: case Terrain.EMPTY_DECO: return "Several tiles are missing here."; case Terrain.EMPTY_SP: return "Thick carpet covers the floor."; case Terrain.STATUE: case Terrain.STATUE_SP: return "The statue depicts some dwarf standing in a heroic stance."; case Terrain.BOOKSHELF: return "The rows of books on different disciplines fill the bookshelf."; default: return super.tileDesc( tile ); } } @Override public void addVisuals( Scene scene ) { CityLevel.addVisuals( this, scene ); } }