v0.9.3: dropped support from saves prior to v0.8.0
This commit is contained in:
parent
3314e607d0
commit
c551cd0ef3
|
@ -51,9 +51,9 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.HallsLevel;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.levels.LastLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.LastShopLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCavesBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCityBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewHallsBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.HallsBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.SewerBossLevel;
|
||||
|
@ -267,7 +267,7 @@ public class Dungeon {
|
|||
level = new CavesLevel();
|
||||
break;
|
||||
case 15:
|
||||
level = new NewCavesBossLevel();
|
||||
level = new CavesBossLevel();
|
||||
break;
|
||||
case 16:
|
||||
case 17:
|
||||
|
@ -276,30 +276,16 @@ public class Dungeon {
|
|||
level = new CityLevel();
|
||||
break;
|
||||
case 20:
|
||||
level = new NewCityBossLevel();
|
||||
level = new CityBossLevel();
|
||||
break;
|
||||
case 21:
|
||||
//logic for old city boss levels, need to spawn a shop on floor 21
|
||||
try {
|
||||
Bundle bundle = FileUtils.bundleFromFile(GamesInProgress.depthFile(GamesInProgress.curSlot, 20));
|
||||
Class cls = bundle.getBundle(LEVEL).getClass("__className");
|
||||
if (cls == NewCityBossLevel.class) {
|
||||
level = new HallsLevel();
|
||||
} else {
|
||||
level = new LastShopLevel();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ShatteredPixelDungeon.reportException(e);
|
||||
level = new HallsLevel();
|
||||
}
|
||||
break;
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
level = new HallsLevel();
|
||||
break;
|
||||
case 25:
|
||||
level = new NewHallsBossLevel();
|
||||
level = new HallsBossLevel();
|
||||
break;
|
||||
case 26:
|
||||
level = new LastLevel();
|
||||
|
|
|
@ -102,8 +102,8 @@ public class GamesInProgress {
|
|||
info.slot = slot;
|
||||
Dungeon.preview(info, bundle);
|
||||
|
||||
//saves from before v0.7.5e are not supported
|
||||
if (info.version < ShatteredPixelDungeon.v0_7_5e) {
|
||||
//saves from before v0.8.0b are not supported
|
||||
if (info.version < ShatteredPixelDungeon.v0_8_0b) {
|
||||
info = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,46 +32,18 @@ import com.watabou.utils.PlatformSupport;
|
|||
public class ShatteredPixelDungeon extends Game {
|
||||
|
||||
//variable constants for specific older versions of shattered, used for data conversion
|
||||
//versions older than v0.7.5e are no longer supported, and data from them is ignored
|
||||
public static final int v0_7_5e = 382;
|
||||
|
||||
//versions older than v0.8.0b are no longer supported, and data from them is ignored
|
||||
public static final int v0_8_0b = 414;
|
||||
public static final int v0_8_1a = 422;
|
||||
public static final int v0_8_2d = 463;
|
||||
|
||||
public static final int v0_9_0b = 489;
|
||||
public static final int v0_9_1d = 511;
|
||||
public static final int v0_9_2 = 519;
|
||||
public static final int v0_9_2b = 532;
|
||||
|
||||
public ShatteredPixelDungeon( PlatformSupport platform ) {
|
||||
super( sceneClass == null ? WelcomeScene.class : sceneClass, platform );
|
||||
|
||||
//v0.8.0
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ArmoredBrute.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shielded");
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM100.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shaman");
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental.FireElemental.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental");
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental.NewbornFireElemental.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewbornElemental");
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.OldDM300.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300");
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.levels.OldCavesBossLevel.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel" );
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.levels.OldCityBossLevel.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel" );
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.levels.OldHallsBossLevel.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.levels.HallsBossLevel" );
|
||||
|
||||
//v0.9.3
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Tengu.class,
|
||||
|
@ -79,6 +51,18 @@ public class ShatteredPixelDungeon extends Game {
|
|||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.levels.PrisonBossLevel.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.levels.NewPrisonBossLevel" );
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300" );
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.levels.NewCavesBossLevel" );
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.levels.NewCityBossLevel" );
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.levels.HallsBossLevel.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.levels.NewHallsBossLevel" );
|
||||
com.watabou.utils.Bundle.addAlias(
|
||||
com.shatteredpixel.shatteredpixeldungeon.items.Waterskin.class,
|
||||
"com.shatteredpixel.shatteredpixeldungeon.items.DewVial" );
|
||||
|
|
|
@ -52,7 +52,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.quest.MetalShard;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCavesBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
|
||||
|
@ -75,7 +75,7 @@ import com.watabou.utils.Rect;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NewDM300 extends Mob {
|
||||
public class DM300 extends Mob {
|
||||
|
||||
{
|
||||
spriteClass = DM300Sprite.class;
|
||||
|
@ -316,7 +316,7 @@ public class NewDM300 extends Mob {
|
|||
if (Dungeon.level.map[step] == Terrain.INACTIVE_TRAP && state == HUNTING) {
|
||||
|
||||
//don't gain energy from cells that are energized
|
||||
if (NewCavesBossLevel.PylonEnergy.volumeAt(pos, NewCavesBossLevel.PylonEnergy.class) > 0){
|
||||
if (CavesBossLevel.PylonEnergy.volumeAt(pos, CavesBossLevel.PylonEnergy.class) > 0){
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ public class NewDM300 extends Mob {
|
|||
safeCell = rockCenter + PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||
} while (safeCell == pos
|
||||
|| (Dungeon.level.solid[safeCell] && Random.Int(2) == 0)
|
||||
|| (Blob.volumeAt(safeCell, NewCavesBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0));
|
||||
|| (Blob.volumeAt(safeCell, CavesBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0));
|
||||
|
||||
ArrayList<Integer> rockCells = new ArrayList<>();
|
||||
|
||||
|
@ -481,7 +481,7 @@ public class NewDM300 extends Mob {
|
|||
|
||||
public void supercharge(){
|
||||
supercharged = true;
|
||||
((NewCavesBossLevel)Dungeon.level).activatePylon();
|
||||
((CavesBossLevel)Dungeon.level).activatePylon();
|
||||
pylonsActivated++;
|
||||
|
||||
spend(Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 2f : 3f);
|
||||
|
@ -562,7 +562,7 @@ public class NewDM300 extends Mob {
|
|||
if (bestpos != pos){
|
||||
Sample.INSTANCE.play( Assets.Sounds.ROCKS );
|
||||
|
||||
Rect gate = NewCavesBossLevel.gate;
|
||||
Rect gate = CavesBossLevel.gate;
|
||||
for (int i : PathFinder.NEIGHBOURS9){
|
||||
if (Dungeon.level.map[pos+i] == Terrain.WALL || Dungeon.level.map[pos+i] == Terrain.WALL_DECO){
|
||||
Point p = Dungeon.level.cellToPoint(pos+i);
|
||||
|
@ -639,7 +639,7 @@ public class NewDM300 extends Mob {
|
|||
CellEmitter.get( i ).start( Speck.factory( Speck.ROCK ), 0.07f, 10 );
|
||||
|
||||
Char ch = Actor.findChar(i);
|
||||
if (ch != null && !(ch instanceof NewDM300)){
|
||||
if (ch != null && !(ch instanceof DM300)){
|
||||
Buff.prolong( ch, Paralysis.class, Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 5 : 3 );
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Viscosity;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCityBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CityBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
|
@ -307,7 +307,7 @@ public class DwarfKing extends Mob {
|
|||
|
||||
private boolean summonSubject( int delay, Class<?extends Mob> type ){
|
||||
Summoning s = new Summoning();
|
||||
s.pos = ((NewCityBossLevel)Dungeon.level).getSummoningPos();
|
||||
s.pos = ((CityBossLevel)Dungeon.level).getSummoningPos();
|
||||
if (s.pos == -1) return false;
|
||||
s.summon = type;
|
||||
s.delay = delay;
|
||||
|
@ -455,7 +455,7 @@ public class DwarfKing extends Mob {
|
|||
if (HP <= (Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 100 : 50)) {
|
||||
HP = (Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 100 : 50);
|
||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
|
||||
ScrollOfTeleportation.appear(this, NewCityBossLevel.throne);
|
||||
ScrollOfTeleportation.appear(this, CityBossLevel.throne);
|
||||
properties.add(Property.IMMOVABLE);
|
||||
phase = 2;
|
||||
summonsMade = 0;
|
||||
|
|
|
@ -1,331 +0,0 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2021 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.KingsCrown;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfDisintegration;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.OldCityBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.KingSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.UndeadSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class King extends Mob {
|
||||
|
||||
private static final int MAX_ARMY_SIZE = 5;
|
||||
|
||||
{
|
||||
spriteClass = KingSprite.class;
|
||||
|
||||
HP = HT = 300;
|
||||
EXP = 40;
|
||||
defenseSkill = 25;
|
||||
|
||||
Undead.count = 0;
|
||||
|
||||
properties.add(Property.BOSS);
|
||||
properties.add(Property.UNDEAD);
|
||||
}
|
||||
|
||||
private boolean nextPedestal = true;
|
||||
|
||||
private static final String PEDESTAL = "pedestal";
|
||||
|
||||
@Override
|
||||
public void storeInBundle( Bundle bundle ) {
|
||||
super.storeInBundle( bundle );
|
||||
bundle.put( PEDESTAL, nextPedestal );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle( Bundle bundle ) {
|
||||
super.restoreFromBundle( bundle );
|
||||
nextPedestal = bundle.getBoolean( PEDESTAL );
|
||||
BossHealthBar.assignBoss(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
return Random.NormalIntRange( 25, 40 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackSkill( Char target ) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drRoll() {
|
||||
return Random.NormalIntRange(0, 14);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getCloser( int target ) {
|
||||
return canTryToSummon() ?
|
||||
super.getCloser( ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) ) :
|
||||
super.getCloser( target );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return canTryToSummon() ?
|
||||
pos == ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) :
|
||||
Dungeon.level.adjacent( pos, enemy.pos );
|
||||
}
|
||||
|
||||
protected boolean canTryToSummon() {
|
||||
if (paralysed <= 0 && Undead.count < maxArmySize()) {
|
||||
Char ch = Actor.findChar( ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) );
|
||||
return ch == this || ch == null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean act() {
|
||||
if (canTryToSummon() && pos == ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal )) {
|
||||
summon();
|
||||
return true;
|
||||
} else {
|
||||
if (enemy != null && canTryToSummon() && Actor.findChar( ((OldCityBossLevel)Dungeon.level).pedestal( nextPedestal ) ) == enemy) {
|
||||
nextPedestal = !nextPedestal;
|
||||
}
|
||||
return super.act();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(int dmg, Object src) {
|
||||
super.damage(dmg, src);
|
||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||
if (lock != null) lock.addTime(dmg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die( Object cause ) {
|
||||
|
||||
GameScene.bossSlain();
|
||||
Dungeon.level.drop( new KingsCrown(), pos ).sprite.drop();
|
||||
Dungeon.level.drop( new SkeletonKey( Dungeon.depth ), pos ).sprite.drop();
|
||||
|
||||
super.die( cause );
|
||||
|
||||
Badges.validateBossSlain();
|
||||
|
||||
LloydsBeacon beacon = Dungeon.hero.belongings.getItem(LloydsBeacon.class);
|
||||
if (beacon != null) {
|
||||
beacon.upgrade();
|
||||
}
|
||||
|
||||
yell( Messages.get(this, "defeated", Dungeon.hero.name()) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void aggro(Char ch) {
|
||||
super.aggro(ch);
|
||||
for (Mob mob : Dungeon.level.mobs){
|
||||
if (mob instanceof Undead){
|
||||
mob.aggro(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int maxArmySize() {
|
||||
return 1 + MAX_ARMY_SIZE * (HT - HP) / HT;
|
||||
}
|
||||
|
||||
private void summon() {
|
||||
|
||||
nextPedestal = !nextPedestal;
|
||||
|
||||
sprite.centerEmitter().start( Speck.factory( Speck.SCREAM ), 0.4f, 2 );
|
||||
Sample.INSTANCE.play( Assets.Sounds.CHALLENGE );
|
||||
|
||||
boolean[] passable = Dungeon.level.passable.clone();
|
||||
for (Char c : Actor.chars()) {
|
||||
passable[c.pos] = false;
|
||||
}
|
||||
|
||||
int undeadsToSummon = maxArmySize() - Undead.count;
|
||||
|
||||
PathFinder.buildDistanceMap( pos, passable, undeadsToSummon );
|
||||
PathFinder.distance[pos] = Integer.MAX_VALUE;
|
||||
int dist = 1;
|
||||
|
||||
undeadLabel:
|
||||
for (int i=0; i < undeadsToSummon; i++) {
|
||||
do {
|
||||
for (int j=0; j < Dungeon.level.length(); j++) {
|
||||
if (PathFinder.distance[j] == dist) {
|
||||
|
||||
Undead undead = new Undead();
|
||||
undead.pos = j;
|
||||
GameScene.add( undead );
|
||||
|
||||
ScrollOfTeleportation.appear( undead, j );
|
||||
new Flare( 3, 32 ).color( 0x000000, false ).show( undead.sprite, 2f ) ;
|
||||
|
||||
PathFinder.distance[j] = Integer.MAX_VALUE;
|
||||
|
||||
continue undeadLabel;
|
||||
}
|
||||
}
|
||||
dist++;
|
||||
} while (dist < undeadsToSummon);
|
||||
}
|
||||
|
||||
yell( Messages.get(this, "arise") );
|
||||
spend( TICK );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notice() {
|
||||
super.notice();
|
||||
if (!BossHealthBar.isAssigned()) {
|
||||
BossHealthBar.assignBoss(this);
|
||||
yell(Messages.get(this, "notice"));
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof DriedRose.GhostHero){
|
||||
((DriedRose.GhostHero) ch).sayBoss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
resistances.add( WandOfDisintegration.class );
|
||||
resistances.add( ToxicGas.class );
|
||||
resistances.add( Burning.class );
|
||||
}
|
||||
|
||||
{
|
||||
immunities.add( Paralysis.class );
|
||||
immunities.add( Vertigo.class );
|
||||
immunities.add( Blindness.class );
|
||||
immunities.add( Terror.class );
|
||||
}
|
||||
|
||||
public static class Undead extends Mob {
|
||||
|
||||
public static int count = 0;
|
||||
|
||||
{
|
||||
spriteClass = UndeadSprite.class;
|
||||
|
||||
HP = HT = 28;
|
||||
defenseSkill = 15;
|
||||
|
||||
maxLvl = -2;
|
||||
EXP = 0;
|
||||
|
||||
state = WANDERING;
|
||||
|
||||
properties.add(Property.UNDEAD);
|
||||
properties.add(Property.INORGANIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAdd() {
|
||||
count++;
|
||||
super.onAdd();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemove() {
|
||||
count--;
|
||||
super.onRemove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
return Random.NormalIntRange( 15, 25 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackSkill( Char target ) {
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackProc( Char enemy, int damage ) {
|
||||
damage = super.attackProc( enemy, damage );
|
||||
if (Random.Int( MAX_ARMY_SIZE ) == 0) {
|
||||
Buff.prolong( enemy, Paralysis.class, 1 );
|
||||
}
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage( int dmg, Object src ) {
|
||||
super.damage( dmg, src );
|
||||
if (src instanceof ToxicGas) {
|
||||
((ToxicGas)src).clear( pos );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die( Object cause ) {
|
||||
super.die( cause );
|
||||
|
||||
if (Dungeon.level.heroFOV[pos]) {
|
||||
Sample.INSTANCE.play( Assets.Sounds.BONES );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drRoll() {
|
||||
return Random.NormalIntRange(0, 5);
|
||||
}
|
||||
|
||||
{
|
||||
immunities.add( Grim.class );
|
||||
immunities.add( Paralysis.class );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2021 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.quest.MetalShard;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.DM300Sprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class OldDM300 extends Mob {
|
||||
|
||||
{
|
||||
spriteClass = DM300Sprite.class;
|
||||
|
||||
HP = HT = 200;
|
||||
EXP = 30;
|
||||
defenseSkill = 18;
|
||||
|
||||
|
||||
properties.add(Property.BOSS);
|
||||
properties.add(Property.INORGANIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
return Random.NormalIntRange( 20, 25 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackSkill( Char target ) {
|
||||
return 28;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drRoll() {
|
||||
return Random.NormalIntRange(0, 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act() {
|
||||
|
||||
GameScene.add( Blob.seed( pos, 30, ToxicGas.class ) );
|
||||
|
||||
return super.act();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move( int step ) {
|
||||
super.move( step );
|
||||
|
||||
if (Dungeon.level.map[step] == Terrain.INACTIVE_TRAP && HP < HT) {
|
||||
|
||||
HP += Random.Int( 1, HT - HP );
|
||||
sprite.emitter().burst( ElmoParticle.FACTORY, 5 );
|
||||
|
||||
if (Dungeon.level.heroFOV[step] && Dungeon.hero.isAlive()) {
|
||||
GLog.n( Messages.get(this, "repair") );
|
||||
}
|
||||
}
|
||||
|
||||
int[] cells = {
|
||||
step-1, step+1, step-Dungeon.level.width(), step+Dungeon.level.width(),
|
||||
step-1-Dungeon.level.width(),
|
||||
step-1+Dungeon.level.width(),
|
||||
step+1-Dungeon.level.width(),
|
||||
step+1+Dungeon.level.width()
|
||||
};
|
||||
int cell = cells[Random.Int( cells.length )];
|
||||
|
||||
if (Dungeon.level.heroFOV[cell]) {
|
||||
CellEmitter.get( cell ).start( Speck.factory( Speck.ROCK ), 0.07f, 10 );
|
||||
Camera.main.shake( 3, 0.7f );
|
||||
Sample.INSTANCE.play( Assets.Sounds.ROCKS );
|
||||
|
||||
if (Dungeon.level.water[cell]) {
|
||||
GameScene.ripple( cell );
|
||||
} else if (Dungeon.level.map[cell] == Terrain.EMPTY) {
|
||||
Level.set( cell, Terrain.EMPTY_DECO );
|
||||
GameScene.updateMap( cell );
|
||||
}
|
||||
}
|
||||
|
||||
Char ch = Actor.findChar( cell );
|
||||
if (ch != null && ch != this) {
|
||||
Buff.prolong( ch, Paralysis.class, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(int dmg, Object src) {
|
||||
super.damage(dmg, src);
|
||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||
if (lock != null && !isImmune(src.getClass())) lock.addTime(dmg*1.5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die( Object cause ) {
|
||||
|
||||
super.die( cause );
|
||||
|
||||
GameScene.bossSlain();
|
||||
Dungeon.level.drop( new SkeletonKey( Dungeon.depth ), pos ).sprite.drop();
|
||||
|
||||
//60% chance of 2 shards, 30% chance of 3, 10% chance for 4. Average of 2.5
|
||||
int shards = Random.chances(new float[]{0, 0, 6, 3, 1});
|
||||
for (int i = 0; i < shards; i++){
|
||||
int ofs;
|
||||
do {
|
||||
ofs = PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||
} while (!Dungeon.level.passable[pos + ofs]);
|
||||
Dungeon.level.drop( new MetalShard(), pos + ofs ).sprite.drop( pos );
|
||||
}
|
||||
|
||||
Badges.validateBossSlain();
|
||||
|
||||
LloydsBeacon beacon = Dungeon.hero.belongings.getItem(LloydsBeacon.class);
|
||||
if (beacon != null) {
|
||||
beacon.upgrade();
|
||||
}
|
||||
|
||||
yell( Messages.get(this, "defeated") );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notice() {
|
||||
super.notice();
|
||||
if (!BossHealthBar.isAssigned()) {
|
||||
BossHealthBar.assignBoss(this);
|
||||
yell(Messages.get(this, "notice"));
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof DriedRose.GhostHero){
|
||||
((DriedRose.GhostHero) ch).sayBoss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
immunities.add( ToxicGas.class );
|
||||
immunities.add( Terror.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
BossHealthBar.assignBoss(this);
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.effects.Lightning;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewCavesBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.CavesBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.PylonSprite;
|
||||
|
@ -127,12 +127,12 @@ public class Pylon extends Mob {
|
|||
}
|
||||
|
||||
private void shockChar( Char ch ){
|
||||
if (ch != null && !(ch instanceof NewDM300)){
|
||||
if (ch != null && !(ch instanceof DM300)){
|
||||
ch.sprite.flash();
|
||||
ch.damage(Random.NormalIntRange(10, 20), new Electricity());
|
||||
|
||||
if (ch == Dungeon.hero && !ch.isAlive()){
|
||||
Dungeon.fail(NewDM300.class);
|
||||
Dungeon.fail(DM300.class);
|
||||
GLog.n( Messages.get(Electricity.class, "ondeath") );
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ public class Pylon extends Mob {
|
|||
@Override
|
||||
public void die(Object cause) {
|
||||
super.die(cause);
|
||||
((NewCavesBossLevel)Dungeon.level).eliminatePylon();
|
||||
((CavesBossLevel)Dungeon.level).eliminatePylon();
|
||||
}
|
||||
|
||||
private static final String ALIGNMENT = "alignment";
|
||||
|
|
|
@ -1,423 +0,0 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2021 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrimTrap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.FistSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.LarvaSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.YogSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Yog extends Mob {
|
||||
|
||||
{
|
||||
spriteClass = YogSprite.class;
|
||||
|
||||
HP = HT = 300;
|
||||
|
||||
EXP = 50;
|
||||
|
||||
state = PASSIVE;
|
||||
|
||||
properties.add(Property.BOSS);
|
||||
properties.add(Property.IMMOVABLE);
|
||||
properties.add(Property.DEMONIC);
|
||||
}
|
||||
|
||||
public Yog() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void spawnFists() {
|
||||
RottingFist fist1 = new RottingFist();
|
||||
BurningFist fist2 = new BurningFist();
|
||||
|
||||
do {
|
||||
fist1.pos = pos + PathFinder.NEIGHBOURS8[Random.Int( 8 )];
|
||||
fist2.pos = pos + PathFinder.NEIGHBOURS8[Random.Int( 8 )];
|
||||
} while (!Dungeon.level.passable[fist1.pos] || !Dungeon.level.passable[fist2.pos] || fist1.pos == fist2.pos);
|
||||
|
||||
GameScene.add( fist1 );
|
||||
GameScene.add( fist2 );
|
||||
|
||||
notice();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean act() {
|
||||
//heals 1 health per turn
|
||||
HP = Math.min( HT, HP+1 );
|
||||
|
||||
return super.act();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage( int dmg, Object src ) {
|
||||
|
||||
HashSet<Mob> fists = new HashSet<>();
|
||||
|
||||
for (Mob mob : Dungeon.level.mobs)
|
||||
if (mob instanceof RottingFist || mob instanceof BurningFist)
|
||||
fists.add( mob );
|
||||
|
||||
dmg >>= fists.size();
|
||||
|
||||
super.damage( dmg, src );
|
||||
|
||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||
if (lock != null) lock.addTime(dmg*0.5f);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int defenseProc( Char enemy, int damage ) {
|
||||
|
||||
ArrayList<Integer> spawnPoints = 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])) {
|
||||
spawnPoints.add( p );
|
||||
}
|
||||
}
|
||||
|
||||
if (spawnPoints.size() > 0) {
|
||||
Larva larva = new Larva();
|
||||
larva.pos = Random.element( spawnPoints );
|
||||
|
||||
GameScene.add( larva );
|
||||
Actor.addDelayed( new Pushing( larva, pos, larva.pos ), -1 );
|
||||
}
|
||||
|
||||
for (Mob mob : Dungeon.level.mobs) {
|
||||
if (mob instanceof BurningFist || mob instanceof RottingFist || mob instanceof Larva) {
|
||||
mob.aggro( enemy );
|
||||
}
|
||||
}
|
||||
|
||||
return super.defenseProc(enemy, damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beckon( int cell ) {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void die( Object cause ) {
|
||||
|
||||
for (Mob mob : (Iterable<Mob>)Dungeon.level.mobs.clone()) {
|
||||
if (mob instanceof BurningFist || mob instanceof RottingFist) {
|
||||
mob.die( cause );
|
||||
}
|
||||
}
|
||||
|
||||
GameScene.bossSlain();
|
||||
Dungeon.level.drop( new SkeletonKey( Dungeon.depth ), pos ).sprite.drop();
|
||||
super.die( cause );
|
||||
|
||||
yell( Messages.get(this, "defeated") );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notice() {
|
||||
super.notice();
|
||||
if (!BossHealthBar.isAssigned()) {
|
||||
BossHealthBar.assignBoss(this);
|
||||
yell(Messages.get(this, "notice"));
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch instanceof DriedRose.GhostHero){
|
||||
((DriedRose.GhostHero) ch).sayBoss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
immunities.add( Grim.class );
|
||||
immunities.add( GrimTrap.class );
|
||||
immunities.add( Terror.class );
|
||||
immunities.add( Amok.class );
|
||||
immunities.add( Charm.class );
|
||||
immunities.add( Sleep.class );
|
||||
immunities.add( Burning.class );
|
||||
immunities.add( ToxicGas.class );
|
||||
immunities.add( ScrollOfRetribution.class );
|
||||
immunities.add( ScrollOfPsionicBlast.class );
|
||||
immunities.add( Vertigo.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
BossHealthBar.assignBoss(this);
|
||||
}
|
||||
|
||||
public static class RottingFist extends Mob {
|
||||
|
||||
private static final int REGENERATION = 4;
|
||||
|
||||
{
|
||||
spriteClass = FistSprite.Rotting.class;
|
||||
|
||||
HP = HT = 300;
|
||||
defenseSkill = 25;
|
||||
|
||||
EXP = 0;
|
||||
|
||||
state = WANDERING;
|
||||
|
||||
properties.add(Property.MINIBOSS);
|
||||
properties.add(Property.DEMONIC);
|
||||
properties.add(Property.ACIDIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackSkill( Char target ) {
|
||||
return 36;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
return Random.NormalIntRange( 20, 50 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drRoll() {
|
||||
return Random.NormalIntRange(0, 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackProc( Char enemy, int damage ) {
|
||||
damage = super.attackProc( enemy, damage );
|
||||
|
||||
if (Random.Int( 3 ) == 0) {
|
||||
Buff.affect( enemy, Ooze.class ).set( Ooze.DURATION );
|
||||
enemy.sprite.burst( 0xFF000000, 5 );
|
||||
}
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act() {
|
||||
|
||||
if (Dungeon.level.water[pos] && HP < HT) {
|
||||
sprite.emitter().burst( ShadowParticle.UP, 2 );
|
||||
HP += REGENERATION;
|
||||
}
|
||||
|
||||
return super.act();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(int dmg, Object src) {
|
||||
super.damage(dmg, src);
|
||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||
if (lock != null) lock.addTime(dmg*0.5f);
|
||||
}
|
||||
|
||||
{
|
||||
immunities.add( Paralysis.class );
|
||||
immunities.add( Amok.class );
|
||||
immunities.add( Sleep.class );
|
||||
immunities.add( Terror.class );
|
||||
immunities.add( Poison.class );
|
||||
immunities.add( Vertigo.class );
|
||||
}
|
||||
}
|
||||
|
||||
public static class BurningFist extends Mob {
|
||||
|
||||
{
|
||||
spriteClass = FistSprite.Burning.class;
|
||||
|
||||
HP = HT = 200;
|
||||
defenseSkill = 25;
|
||||
|
||||
EXP = 0;
|
||||
|
||||
state = WANDERING;
|
||||
|
||||
properties.add(Property.MINIBOSS);
|
||||
properties.add(Property.DEMONIC);
|
||||
properties.add(Property.FIERY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackSkill( Char target ) {
|
||||
return 36;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
return Random.NormalIntRange( 26, 32 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drRoll() {
|
||||
return Random.NormalIntRange(0, 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT).collisionPos == enemy.pos;
|
||||
}
|
||||
|
||||
//used so resistances can differentiate between melee and magical attacks
|
||||
public static class DarkBolt{}
|
||||
|
||||
protected boolean doAttack( Char enemy ) {
|
||||
|
||||
if (Dungeon.level.adjacent( pos, enemy.pos )) {
|
||||
|
||||
return super.doAttack( enemy );
|
||||
|
||||
} else {
|
||||
|
||||
if (sprite != null && (sprite.visible || enemy.sprite.visible)) {
|
||||
sprite.zap( enemy.pos );
|
||||
return false;
|
||||
} else {
|
||||
zap();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void zap() {
|
||||
spend( 1f );
|
||||
|
||||
if (hit( this, enemy, true )) {
|
||||
|
||||
int dmg = damageRoll();
|
||||
enemy.damage( dmg, new DarkBolt() );
|
||||
|
||||
if (!enemy.isAlive() && enemy == Dungeon.hero) {
|
||||
Dungeon.fail( getClass() );
|
||||
GLog.n( Messages.get(Char.class, "kill", name()) );
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
enemy.sprite.showStatus( CharSprite.NEUTRAL, enemy.defenseVerb() );
|
||||
}
|
||||
}
|
||||
|
||||
public void onZapComplete() {
|
||||
zap();
|
||||
next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean act() {
|
||||
|
||||
for (int i=0; i < PathFinder.NEIGHBOURS9.length; i++) {
|
||||
GameScene.add( Blob.seed( pos + PathFinder.NEIGHBOURS9[i], 2, Fire.class ) );
|
||||
}
|
||||
|
||||
return super.act();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(int dmg, Object src) {
|
||||
super.damage(dmg, src);
|
||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||
if (lock != null) lock.addTime(dmg*0.5f);
|
||||
}
|
||||
|
||||
{
|
||||
immunities.add( Amok.class );
|
||||
immunities.add( Sleep.class );
|
||||
immunities.add( Terror.class );
|
||||
immunities.add( Vertigo.class );
|
||||
}
|
||||
}
|
||||
|
||||
public static class Larva extends Mob {
|
||||
|
||||
{
|
||||
spriteClass = LarvaSprite.class;
|
||||
|
||||
HP = HT = 25;
|
||||
defenseSkill = 20;
|
||||
|
||||
EXP = 0;
|
||||
maxLvl = -2;
|
||||
|
||||
state = HUNTING;
|
||||
|
||||
properties.add(Property.DEMONIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attackSkill( Char target ) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
return Random.NormalIntRange( 22, 30 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int drRoll() {
|
||||
return Random.NormalIntRange(0, 8);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -63,8 +63,7 @@ public class Heap implements Bundlable {
|
|||
CRYSTAL_CHEST,
|
||||
TOMB,
|
||||
SKELETON,
|
||||
REMAINS,
|
||||
MIMIC //remains for pre-0.8.0 compatibility. There are converted to mimics on level load
|
||||
REMAINS
|
||||
}
|
||||
public Type type = Type.HEAP;
|
||||
|
||||
|
@ -78,9 +77,6 @@ public class Heap implements Bundlable {
|
|||
|
||||
public void open( Hero hero ) {
|
||||
switch (type) {
|
||||
case MIMIC:
|
||||
type = Type.CHEST;
|
||||
break;
|
||||
case TOMB:
|
||||
Wraith.spawnAround( hero.pos );
|
||||
break;
|
||||
|
@ -99,16 +95,14 @@ public class Heap implements Bundlable {
|
|||
Sample.INSTANCE.play( Assets.Sounds.CURSED );
|
||||
}
|
||||
|
||||
if (type != Type.MIMIC) {
|
||||
type = Type.HEAP;
|
||||
ArrayList<Item> bonus = RingOfWealth.tryForBonusDrop(hero, 1);
|
||||
if (bonus != null && !bonus.isEmpty()) {
|
||||
items.addAll(0, bonus);
|
||||
RingOfWealth.showFlareForBonusDrop(sprite);
|
||||
}
|
||||
sprite.link();
|
||||
sprite.drop();
|
||||
type = Type.HEAP;
|
||||
ArrayList<Item> bonus = RingOfWealth.tryForBonusDrop(hero, 1);
|
||||
if (bonus != null && !bonus.isEmpty()) {
|
||||
items.addAll(0, bonus);
|
||||
RingOfWealth.showFlareForBonusDrop(sprite);
|
||||
}
|
||||
sprite.link();
|
||||
sprite.drop();
|
||||
}
|
||||
|
||||
public Heap setHauntedIfCursed(){
|
||||
|
@ -248,7 +242,7 @@ public class Heap implements Bundlable {
|
|||
public void explode() {
|
||||
|
||||
//breaks open most standard containers, mimics die.
|
||||
if (type == Type.MIMIC || type == Type.CHEST || type == Type.SKELETON) {
|
||||
if (type == Type.CHEST || type == Type.SKELETON) {
|
||||
type = Type.HEAP;
|
||||
sprite.link();
|
||||
sprite.drop();
|
||||
|
@ -361,7 +355,6 @@ public class Heap implements Bundlable {
|
|||
return i.toString();
|
||||
}
|
||||
case CHEST:
|
||||
case MIMIC:
|
||||
return Messages.get(this, "chest");
|
||||
case LOCKED_CHEST:
|
||||
return Messages.get(this, "locked_chest");
|
||||
|
@ -381,7 +374,6 @@ public class Heap implements Bundlable {
|
|||
public String info(){
|
||||
switch(type){
|
||||
case CHEST:
|
||||
case MIMIC:
|
||||
return Messages.get(this, "chest_desc");
|
||||
case LOCKED_CHEST:
|
||||
return Messages.get(this, "locked_chest_desc");
|
||||
|
|
|
@ -33,7 +33,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM100;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shaman;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Warlock;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.YogFist;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave;
|
||||
|
@ -86,7 +85,6 @@ public class AntiMagic extends Armor.Glyph {
|
|||
RESISTS.add( Shaman.EarthenBolt.class );
|
||||
RESISTS.add( Warlock.DarkBolt.class );
|
||||
RESISTS.add( Eye.DeathGaze.class );
|
||||
RESISTS.add( Yog.BurningFist.DarkBolt.class );
|
||||
RESISTS.add( YogFist.BrightFist.LightBeam.class );
|
||||
RESISTS.add( YogFist.DarkFist.DarkBolt.class );
|
||||
}
|
||||
|
|
|
@ -55,14 +55,12 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vulnerable;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bee;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.King;
|
||||
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.Statue;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Swarm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
|
@ -144,10 +142,6 @@ public class WandOfCorruption extends Wand {
|
|||
} else if (ch instanceof Wraith) {
|
||||
//divide by 5 as wraiths are always at full HP and are therefore ~5x harder to corrupt
|
||||
enemyResist = (1f + Dungeon.depth/3f) / 5f;
|
||||
} else if (ch instanceof Yog.BurningFist || ch instanceof Yog.RottingFist) {
|
||||
enemyResist = 1 + 30;
|
||||
} else if (ch instanceof Yog.Larva || ch instanceof King.Undead){
|
||||
enemyResist = 1 + 5;
|
||||
} else if (ch instanceof Swarm){
|
||||
//child swarms don't give exp, so we force this here.
|
||||
enemyResist = 1 + 3;
|
||||
|
|
|
@ -30,7 +30,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Pylon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
|
@ -61,7 +61,7 @@ import com.watabou.utils.Rect;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NewCavesBossLevel extends Level {
|
||||
public class CavesBossLevel extends Level {
|
||||
|
||||
{
|
||||
color1 = 0x534f3e;
|
||||
|
@ -273,7 +273,7 @@ public class NewCavesBossLevel extends Level {
|
|||
Camera.main.shake( 3, 0.7f );
|
||||
Sample.INSTANCE.play( Assets.Sounds.ROCKS );
|
||||
|
||||
NewDM300 boss = new NewDM300();
|
||||
DM300 boss = new DM300();
|
||||
boss.state = boss.WANDERING;
|
||||
do {
|
||||
boss.pos = pointToCell(Random.element(mainArena.getPoints()));
|
||||
|
@ -337,8 +337,8 @@ public class NewCavesBossLevel extends Level {
|
|||
customArenaVisuals.updateState();
|
||||
int pylonsRemaining = 0;
|
||||
for (Mob m : mobs){
|
||||
if (m instanceof NewDM300){
|
||||
((NewDM300) m).loseSupercharge();
|
||||
if (m instanceof DM300){
|
||||
((DM300) m).loseSupercharge();
|
||||
PylonEnergy.energySourceSprite = m.sprite;
|
||||
} else if (m instanceof Pylon){
|
||||
pylonsRemaining++;
|
||||
|
@ -371,7 +371,7 @@ public class NewCavesBossLevel extends Level {
|
|||
public String tileDesc( int tile ) {
|
||||
switch (tile) {
|
||||
case Terrain.WATER:
|
||||
return super.tileDesc( tile ) + "\n\n" + Messages.get(NewCavesBossLevel.class, "water_desc");
|
||||
return super.tileDesc( tile ) + "\n\n" + Messages.get(CavesBossLevel.class, "water_desc");
|
||||
case Terrain.ENTRANCE:
|
||||
return Messages.get(CavesLevel.class, "entrance_desc");
|
||||
case Terrain.EXIT:
|
||||
|
@ -716,9 +716,9 @@ public class NewCavesBossLevel extends Level {
|
|||
public String name(int tileX, int tileY) {
|
||||
int i = tileX + tileW*(tileY + this.tileY);
|
||||
if (Dungeon.level.map[i] == Terrain.INACTIVE_TRAP){
|
||||
return Messages.get(NewCavesBossLevel.class, "wires_name");
|
||||
return Messages.get(CavesBossLevel.class, "wires_name");
|
||||
} else if (gate.inside(Dungeon.level.cellToPoint(i))){
|
||||
return Messages.get(NewCavesBossLevel.class, "gate_name");
|
||||
return Messages.get(CavesBossLevel.class, "gate_name");
|
||||
}
|
||||
|
||||
return super.name(tileX, tileY);
|
||||
|
@ -728,12 +728,12 @@ public class NewCavesBossLevel extends Level {
|
|||
public String desc(int tileX, int tileY) {
|
||||
int i = tileX + tileW*(tileY + this.tileY);
|
||||
if (Dungeon.level.map[i] == Terrain.INACTIVE_TRAP){
|
||||
return Messages.get(NewCavesBossLevel.class, "wires_desc");
|
||||
return Messages.get(CavesBossLevel.class, "wires_desc");
|
||||
} else if (gate.inside(Dungeon.level.cellToPoint(i))){
|
||||
if (Dungeon.level.solid[i]){
|
||||
return Messages.get(NewCavesBossLevel.class, "gate_desc");
|
||||
return Messages.get(CavesBossLevel.class, "gate_desc");
|
||||
} else {
|
||||
return Messages.get(NewCavesBossLevel.class, "gate_desc_broken");
|
||||
return Messages.get(CavesBossLevel.class, "gate_desc_broken");
|
||||
}
|
||||
}
|
||||
return super.desc(tileX, tileY);
|
||||
|
@ -771,13 +771,13 @@ public class NewCavesBossLevel extends Level {
|
|||
if (off[cell] > 0){
|
||||
|
||||
Char ch = Actor.findChar(cell);
|
||||
if (ch != null && !(ch instanceof NewDM300)) {
|
||||
if (ch != null && !(ch instanceof DM300)) {
|
||||
Sample.INSTANCE.play( Assets.Sounds.LIGHTNING );
|
||||
ch.damage( Random.NormalIntRange(6, 12), Electricity.class);
|
||||
ch.sprite.flash();
|
||||
|
||||
if (ch == Dungeon.hero && !ch.isAlive()) {
|
||||
Dungeon.fail(NewDM300.class);
|
||||
Dungeon.fail(DM300.class);
|
||||
GLog.n( Messages.get(Electricity.class, "ondeath") );
|
||||
}
|
||||
}
|
||||
|
@ -802,7 +802,7 @@ public class NewCavesBossLevel extends Level {
|
|||
if (c instanceof Pylon && c.alignment != Char.Alignment.NEUTRAL){
|
||||
energySourceSprite = c.sprite;
|
||||
break;
|
||||
} else if (c instanceof NewDM300){
|
||||
} else if (c instanceof DM300){
|
||||
energySourceSprite = c.sprite;
|
||||
}
|
||||
}
|
||||
|
@ -830,7 +830,7 @@ public class NewCavesBossLevel extends Level {
|
|||
|
||||
@Override
|
||||
public String tileDesc() {
|
||||
return Messages.get(NewCavesBossLevel.class, "energy_desc");
|
||||
return Messages.get(CavesBossLevel.class, "energy_desc");
|
||||
}
|
||||
|
||||
@Override
|
|
@ -49,7 +49,7 @@ import com.watabou.utils.Rect;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class NewCityBossLevel extends Level {
|
||||
public class CityBossLevel extends Level {
|
||||
|
||||
{
|
||||
color1 = 0x4b6636;
|
||||
|
@ -505,9 +505,9 @@ public class NewCityBossLevel extends Level {
|
|||
//DK arena tiles
|
||||
} else {
|
||||
if (Dungeon.level.map[cell] == Terrain.SIGN){
|
||||
return Messages.get(NewCityBossLevel.class, "throne_name");
|
||||
return Messages.get(CityBossLevel.class, "throne_name");
|
||||
} else if (Dungeon.level.map[cell] == Terrain.PEDESTAL){
|
||||
return Messages.get(NewCityBossLevel.class, "summoning_name");
|
||||
return Messages.get(CityBossLevel.class, "summoning_name");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,9 +531,9 @@ public class NewCityBossLevel extends Level {
|
|||
//DK arena tiles
|
||||
} else {
|
||||
if (Dungeon.level.map[cell] == Terrain.SIGN){
|
||||
return Messages.get(NewCityBossLevel.class, "throne_desc");
|
||||
return Messages.get(CityBossLevel.class, "throne_desc");
|
||||
} else if (Dungeon.level.map[cell] == Terrain.PEDESTAL){
|
||||
return Messages.get(NewCityBossLevel.class, "summoning_desc");
|
||||
return Messages.get(CityBossLevel.class, "summoning_desc");
|
||||
}
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ import com.watabou.utils.Bundle;
|
|||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class NewHallsBossLevel extends Level {
|
||||
public class HallsBossLevel extends Level {
|
||||
|
||||
{
|
||||
color1 = 0x801500;
|
|
@ -309,8 +309,8 @@ public abstract class Level implements Bundlable {
|
|||
|
||||
version = bundle.getInt( VERSION );
|
||||
|
||||
//saves from before v0.7.5e are not supported
|
||||
if (version < ShatteredPixelDungeon.v0_7_5e){
|
||||
//saves from before v0.8.0b are not supported
|
||||
if (version < ShatteredPixelDungeon.v0_8_0b){
|
||||
throw new RuntimeException("old save");
|
||||
}
|
||||
|
||||
|
@ -396,13 +396,6 @@ public abstract class Level implements Bundlable {
|
|||
buildFlagMaps();
|
||||
cleanWalls();
|
||||
|
||||
//compat with pre-0.8.0 saves
|
||||
for (Heap h : heaps.valueList()){
|
||||
if (h.type == Heap.Type.MIMIC){
|
||||
heaps.remove(h.pos);
|
||||
mobs.add(Mimic.spawnAt(h.pos, h.items));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,316 +0,0 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2021 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.levels;
|
||||
|
||||
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.OldDM300;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
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.levels.traps.ToxicTrap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
import com.watabou.utils.Rect;
|
||||
|
||||
public class OldCavesBossLevel extends Level {
|
||||
|
||||
{
|
||||
color1 = 0x534f3e;
|
||||
color2 = 0xb9d661;
|
||||
|
||||
viewDistance = Math.min(6, viewDistance);
|
||||
}
|
||||
|
||||
private static final int WIDTH = 32;
|
||||
private static final int HEIGHT = 32;
|
||||
|
||||
private static final int ROOM_LEFT = WIDTH / 2 - 3;
|
||||
private static final int ROOM_RIGHT = WIDTH / 2 + 1;
|
||||
private static final int ROOM_TOP = HEIGHT / 2 - 2;
|
||||
private static final int ROOM_BOTTOM = HEIGHT / 2 + 2;
|
||||
|
||||
private int arenaDoor;
|
||||
private boolean enteredArena = false;
|
||||
private boolean keyDropped = false;
|
||||
|
||||
@Override
|
||||
public String tilesTex() {
|
||||
return Assets.Environment.TILES_CAVES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String waterTex() {
|
||||
return Assets.Environment.WATER_CAVES;
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
setSize(WIDTH, HEIGHT);
|
||||
|
||||
Rect space = new Rect();
|
||||
|
||||
space.set(
|
||||
Random.IntRange(2, 6),
|
||||
Random.IntRange(2, 6),
|
||||
Random.IntRange(width-6, width-2),
|
||||
Random.IntRange(height-6, height-2)
|
||||
);
|
||||
|
||||
Painter.fillEllipse( this, space, Terrain.EMPTY );
|
||||
|
||||
exit = space.left + space.width()/2 + (space.top - 1) * width();
|
||||
|
||||
map[exit] = Terrain.LOCKED_EXIT;
|
||||
|
||||
Painter.fill( this, ROOM_LEFT - 1, ROOM_TOP - 1,
|
||||
ROOM_RIGHT - ROOM_LEFT + 3, ROOM_BOTTOM - ROOM_TOP + 3, Terrain.WALL );
|
||||
Painter.fill( this, ROOM_LEFT, ROOM_TOP + 1,
|
||||
ROOM_RIGHT - ROOM_LEFT + 1, ROOM_BOTTOM - ROOM_TOP, Terrain.EMPTY );
|
||||
|
||||
Painter.fill( this, ROOM_LEFT, ROOM_TOP,
|
||||
ROOM_RIGHT - ROOM_LEFT + 1, 1, Terrain.EMPTY_DECO );
|
||||
|
||||
arenaDoor = Random.Int( ROOM_LEFT, ROOM_RIGHT ) + (ROOM_BOTTOM + 1) * width();
|
||||
map[arenaDoor] = Terrain.DOOR;
|
||||
|
||||
entrance = Random.Int( ROOM_LEFT + 1, ROOM_RIGHT - 1 ) +
|
||||
Random.Int( ROOM_TOP + 1, ROOM_BOTTOM - 1 ) * width();
|
||||
map[entrance] = Terrain.ENTRANCE;
|
||||
|
||||
boolean[] patch = Patch.generate( width, height, 0.30f, 6, true );
|
||||
for (int i=0; i < length(); i++) {
|
||||
if (map[i] == Terrain.EMPTY && patch[i]) {
|
||||
map[i] = Terrain.WATER;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i < length(); i++) {
|
||||
if (map[i] == Terrain.EMPTY && Random.Int( 6 ) == 0) {
|
||||
map[i] = Terrain.INACTIVE_TRAP;
|
||||
Trap t = new ToxicTrap().reveal();
|
||||
t.active = false;
|
||||
setTrap(t, i);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=width() + 1; i < length() - width(); i++) {
|
||||
if (map[i] == Terrain.EMPTY) {
|
||||
int n = 0;
|
||||
if (map[i+1] == Terrain.WALL) {
|
||||
n++;
|
||||
}
|
||||
if (map[i-1] == Terrain.WALL) {
|
||||
n++;
|
||||
}
|
||||
if (map[i+width()] == Terrain.WALL) {
|
||||
n++;
|
||||
}
|
||||
if (map[i-width()] == Terrain.WALL) {
|
||||
n++;
|
||||
}
|
||||
if (Random.Int( 8 ) <= n) {
|
||||
map[i] = Terrain.EMPTY_DECO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i < length() - width(); i++) {
|
||||
if (map[i] == Terrain.WALL
|
||||
&& DungeonTileSheet.floorTile(map[i + width()])
|
||||
&& Random.Int( 3 ) == 0) {
|
||||
map[i] = Terrain.WALL_DECO;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMobs() {
|
||||
}
|
||||
|
||||
public Actor addRespawner() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createItems() {
|
||||
Item item = Bones.get();
|
||||
if (item != null) {
|
||||
int pos;
|
||||
do {
|
||||
pos = Random.IntRange( ROOM_LEFT, ROOM_RIGHT ) + Random.IntRange( ROOM_TOP + 1, ROOM_BOTTOM ) * width();
|
||||
} while (pos == entrance);
|
||||
drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int randomRespawnCell( Char ch ) {
|
||||
int cell;
|
||||
do {
|
||||
cell = entrance + PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||
} while (!passable[cell]
|
||||
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell])
|
||||
|| Actor.findChar(cell) != null);
|
||||
return cell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void occupyCell( Char ch ) {
|
||||
|
||||
super.occupyCell( ch );
|
||||
|
||||
if (!enteredArena && outsideEntraceRoom( ch.pos ) && ch == Dungeon.hero) {
|
||||
|
||||
enteredArena = true;
|
||||
seal();
|
||||
|
||||
for (Mob m : mobs){
|
||||
//bring the first ally with you
|
||||
if (m.alignment == Char.Alignment.ALLY && !m.properties().contains(Char.Property.IMMOVABLE)){
|
||||
m.pos = Dungeon.hero.pos + (Random.Int(2) == 0 ? +1 : -1);
|
||||
m.sprite.place(m.pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OldDM300 boss = new OldDM300();
|
||||
boss.state = boss.WANDERING;
|
||||
do {
|
||||
boss.pos = Random.Int( length() );
|
||||
} while (
|
||||
!passable[boss.pos] ||
|
||||
!outsideEntraceRoom( boss.pos ) ||
|
||||
heroFOV[boss.pos]);
|
||||
GameScene.add( boss );
|
||||
|
||||
set( arenaDoor, Terrain.WALL );
|
||||
GameScene.updateMap( arenaDoor );
|
||||
Dungeon.observe();
|
||||
|
||||
CellEmitter.get( arenaDoor ).start( Speck.factory( Speck.ROCK ), 0.07f, 10 );
|
||||
Camera.main.shake( 3, 0.7f );
|
||||
Sample.INSTANCE.play( Assets.Sounds.ROCKS );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Heap drop( Item item, int cell ) {
|
||||
|
||||
if (!keyDropped && item instanceof SkeletonKey) {
|
||||
|
||||
keyDropped = true;
|
||||
unseal();
|
||||
|
||||
CellEmitter.get( arenaDoor ).start( Speck.factory( Speck.ROCK ), 0.07f, 10 );
|
||||
|
||||
set( arenaDoor, Terrain.EMPTY_DECO );
|
||||
GameScene.updateMap( arenaDoor );
|
||||
Dungeon.observe();
|
||||
}
|
||||
|
||||
return super.drop( item, cell );
|
||||
}
|
||||
|
||||
private boolean outsideEntraceRoom( int cell ) {
|
||||
int cx = cell % width();
|
||||
int cy = cell / width();
|
||||
return cx < ROOM_LEFT-1 || cx > ROOM_RIGHT+1 || cy < ROOM_TOP-1 || cy > ROOM_BOTTOM+1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tileName( int tile ) {
|
||||
switch (tile) {
|
||||
case Terrain.GRASS:
|
||||
return Messages.get(CavesLevel.class, "grass_name");
|
||||
case Terrain.HIGH_GRASS:
|
||||
return Messages.get(CavesLevel.class, "high_grass_name");
|
||||
case Terrain.WATER:
|
||||
return Messages.get(CavesLevel.class, "water_name");
|
||||
default:
|
||||
return super.tileName( tile );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tileDesc( int tile ) {
|
||||
switch (tile) {
|
||||
case Terrain.ENTRANCE:
|
||||
return Messages.get(CavesLevel.class, "entrance_desc");
|
||||
case Terrain.EXIT:
|
||||
return Messages.get(CavesLevel.class, "exit_desc");
|
||||
case Terrain.HIGH_GRASS:
|
||||
return Messages.get(CavesLevel.class, "high_grass_desc");
|
||||
case Terrain.WALL_DECO:
|
||||
return Messages.get(CavesLevel.class, "wall_deco_desc");
|
||||
case Terrain.BOOKSHELF:
|
||||
return Messages.get(CavesLevel.class, "bookshelf_desc");
|
||||
default:
|
||||
return super.tileDesc( tile );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group addVisuals() {
|
||||
super.addVisuals();
|
||||
CavesLevel.addCavesVisuals(this, visuals);
|
||||
return visuals;
|
||||
}
|
||||
}
|
|
@ -1,288 +0,0 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2021 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.levels;
|
||||
|
||||
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.King;
|
||||
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.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTileSheet;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.tweeners.AlphaTweener;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class OldCityBossLevel 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 = 4;
|
||||
|
||||
private static final int WIDTH = 32;
|
||||
|
||||
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.Environment.TILES_CITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String waterTex() {
|
||||
return Assets.Environment.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() {
|
||||
|
||||
setSize(32, 32);
|
||||
|
||||
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, HALL_WIDTH, 1, Terrain.BOOKSHELF);
|
||||
map[arenaDoor + width()] = 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 + 3 + Random.Int( CHAMBER_HEIGHT - 2 )) * width() + LEFT + (/*1 +*/ Random.Int( HALL_WIDTH-2 ));
|
||||
map[entrance] = Terrain.ENTRANCE;
|
||||
|
||||
for (int i=0; i < length() - width(); i++) {
|
||||
if (map[i] == Terrain.EMPTY && Random.Int( 10 ) == 0) {
|
||||
map[i] = Terrain.EMPTY_DECO;
|
||||
} else if (map[i] == Terrain.WALL
|
||||
&& DungeonTileSheet.floorTile(map[i + width()])
|
||||
&& Random.Int( 21 - Dungeon.depth ) == 0) {
|
||||
map[i] = Terrain.WALL_DECO;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public 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 addRespawner() {
|
||||
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 + 2, TOP + HALL_HEIGHT + CHAMBER_HEIGHT ) * width();
|
||||
} while (pos == entrance);
|
||||
drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int randomRespawnCell( Char ch ) {
|
||||
int cell;
|
||||
do {
|
||||
cell = entrance + PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||
} while (!passable[cell]
|
||||
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell])
|
||||
|| Actor.findChar(cell) != null);
|
||||
return cell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void occupyCell( Char ch ) {
|
||||
|
||||
super.occupyCell( ch );
|
||||
|
||||
if (!enteredArena && outsideEntraceRoom( ch.pos ) && ch == Dungeon.hero) {
|
||||
|
||||
enteredArena = true;
|
||||
seal();
|
||||
|
||||
for (Mob m : mobs){
|
||||
//bring the first ally with you
|
||||
if (m.alignment == Char.Alignment.ALLY && !m.properties().contains(Char.Property.IMMOVABLE)){
|
||||
m.pos = Dungeon.hero.pos + (Random.Int(2) == 0 ? +1 : -1);
|
||||
m.sprite.place(m.pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
King boss = new King();
|
||||
boss.state = boss.WANDERING;
|
||||
int count = 0;
|
||||
do {
|
||||
boss.pos = Random.Int( length() );
|
||||
} while (
|
||||
!passable[boss.pos] ||
|
||||
!outsideEntraceRoom( boss.pos ) ||
|
||||
(heroFOV[boss.pos] && count++ < 20));
|
||||
GameScene.add( boss );
|
||||
|
||||
if (heroFOV[boss.pos]) {
|
||||
boss.notice();
|
||||
boss.sprite.alpha( 0 );
|
||||
boss.sprite.parent.add( new AlphaTweener( boss.sprite, 1, 0.1f ) );
|
||||
}
|
||||
|
||||
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;
|
||||
unseal();
|
||||
|
||||
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 Messages.get(CityLevel.class, "water_name");
|
||||
case Terrain.HIGH_GRASS:
|
||||
return Messages.get(CityLevel.class, "high_grass_name");
|
||||
default:
|
||||
return super.tileName( tile );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tileDesc(int tile) {
|
||||
switch (tile) {
|
||||
case Terrain.ENTRANCE:
|
||||
return Messages.get(CityLevel.class, "entrance_desc");
|
||||
case Terrain.EXIT:
|
||||
return Messages.get(CityLevel.class, "exit_desc");
|
||||
case Terrain.WALL_DECO:
|
||||
case Terrain.EMPTY_DECO:
|
||||
return Messages.get(CityLevel.class, "deco_desc");
|
||||
case Terrain.EMPTY_SP:
|
||||
return Messages.get(CityLevel.class, "sp_desc");
|
||||
case Terrain.STATUE:
|
||||
case Terrain.STATUE_SP:
|
||||
return Messages.get(CityLevel.class, "statue_desc");
|
||||
case Terrain.BOOKSHELF:
|
||||
return Messages.get(CityLevel.class, "bookshelf_desc");
|
||||
default:
|
||||
return super.tileDesc( tile );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group addVisuals( ) {
|
||||
super.addVisuals();
|
||||
CityLevel.addCityVisuals(this, visuals);
|
||||
return visuals;
|
||||
}
|
||||
}
|
|
@ -1,271 +0,0 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2021 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.levels;
|
||||
|
||||
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.Yog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle;
|
||||
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.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.PathFinder;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class OldHallsBossLevel extends Level {
|
||||
|
||||
{
|
||||
color1 = 0x801500;
|
||||
color2 = 0xa68521;
|
||||
|
||||
viewDistance = Math.min(4, viewDistance);
|
||||
}
|
||||
|
||||
private static final int WIDTH = 32;
|
||||
private static final int HEIGHT = 32;
|
||||
|
||||
private static final int ROOM_LEFT = WIDTH / 2 - 1;
|
||||
private static final int ROOM_RIGHT = WIDTH / 2 + 1;
|
||||
private static final int ROOM_TOP = HEIGHT / 2 - 1;
|
||||
private static final int ROOM_BOTTOM = HEIGHT / 2 + 1;
|
||||
|
||||
private int stairs = -1;
|
||||
private boolean enteredArena = false;
|
||||
private boolean keyDropped = false;
|
||||
|
||||
@Override
|
||||
public String tilesTex() {
|
||||
return Assets.Environment.TILES_HALLS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String waterTex() {
|
||||
return Assets.Environment.WATER_HALLS;
|
||||
}
|
||||
|
||||
private static final String STAIRS = "stairs";
|
||||
private static final String ENTERED = "entered";
|
||||
private static final String DROPPED = "droppped";
|
||||
|
||||
@Override
|
||||
public void storeInBundle( Bundle bundle ) {
|
||||
super.storeInBundle( bundle );
|
||||
bundle.put( STAIRS, stairs );
|
||||
bundle.put( ENTERED, enteredArena );
|
||||
bundle.put( DROPPED, keyDropped );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle( Bundle bundle ) {
|
||||
super.restoreFromBundle( bundle );
|
||||
stairs = bundle.getInt( STAIRS );
|
||||
enteredArena = bundle.getBoolean( ENTERED );
|
||||
keyDropped = bundle.getBoolean( DROPPED );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean build() {
|
||||
|
||||
setSize(32, 32);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
|
||||
int top = Random.IntRange(2, ROOM_TOP - 1);
|
||||
int bottom = Random.IntRange(ROOM_BOTTOM + 1, 22);
|
||||
Painter.fill(this, 2 + i * 4, top, 4, bottom - top + 1, Terrain.EMPTY);
|
||||
|
||||
if (i == 2) {
|
||||
exit = (i * 4 + 3) + (top - 1) * width();
|
||||
}
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (Random.Int(2) == 0) {
|
||||
int y = Random.IntRange(top + 1, bottom - 1);
|
||||
map[i * 4 + j + y * width()] = Terrain.WALL_DECO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map[exit] = Terrain.LOCKED_EXIT;
|
||||
|
||||
Painter.fill(this, ROOM_LEFT - 1, ROOM_TOP - 1,
|
||||
ROOM_RIGHT - ROOM_LEFT + 3, ROOM_BOTTOM - ROOM_TOP + 3, Terrain.WALL);
|
||||
Painter.fill(this, ROOM_LEFT, ROOM_TOP,
|
||||
ROOM_RIGHT - ROOM_LEFT + 1, ROOM_BOTTOM - ROOM_TOP + 1, Terrain.EMPTY);
|
||||
|
||||
entrance = Random.Int(ROOM_LEFT + 1, ROOM_RIGHT - 1) +
|
||||
Random.Int(ROOM_TOP + 1, ROOM_BOTTOM - 1) * width();
|
||||
map[entrance] = Terrain.ENTRANCE;
|
||||
|
||||
boolean[] patch = Patch.generate(width, height, 0.30f, 6, true);
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (map[i] == Terrain.EMPTY && patch[i]) {
|
||||
map[i] = Terrain.WATER;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (map[i] == Terrain.EMPTY && Random.Int(10) == 0) {
|
||||
map[i] = Terrain.EMPTY_DECO;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createMobs() {
|
||||
}
|
||||
|
||||
public Actor addRespawner() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createItems() {
|
||||
Item item = Bones.get();
|
||||
if (item != null) {
|
||||
int pos;
|
||||
do {
|
||||
pos = Random.IntRange( ROOM_LEFT, ROOM_RIGHT ) + Random.IntRange( ROOM_TOP + 1, ROOM_BOTTOM ) * width();
|
||||
} while (pos == entrance);
|
||||
drop( item, pos ).setHauntedIfCursed().type = Heap.Type.REMAINS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int randomRespawnCell( Char ch ) {
|
||||
int pos = entrance == -1 ? stairs : entrance;
|
||||
int cell;
|
||||
do {
|
||||
cell = pos + PathFinder.NEIGHBOURS8[Random.Int(8)];
|
||||
} while (!passable[cell]
|
||||
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell])
|
||||
|| Actor.findChar(cell) != null);
|
||||
return cell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void occupyCell( Char ch ) {
|
||||
|
||||
super.occupyCell( ch );
|
||||
|
||||
if (!enteredArena && ch == Dungeon.hero && ch.pos != entrance) {
|
||||
|
||||
enteredArena = true;
|
||||
seal();
|
||||
|
||||
for (int i=ROOM_LEFT-1; i <= ROOM_RIGHT + 1; i++) {
|
||||
doMagic( (ROOM_TOP - 1) * width() + i );
|
||||
doMagic( (ROOM_BOTTOM + 1) * width() + i );
|
||||
}
|
||||
for (int i=ROOM_TOP; i < ROOM_BOTTOM + 1; i++) {
|
||||
doMagic( i * width() + ROOM_LEFT - 1 );
|
||||
doMagic( i * width() + ROOM_RIGHT + 1 );
|
||||
}
|
||||
doMagic( entrance );
|
||||
GameScene.updateMap();
|
||||
|
||||
Dungeon.observe();
|
||||
|
||||
Yog boss = new Yog();
|
||||
do {
|
||||
boss.pos = Random.Int( length() );
|
||||
} while (
|
||||
!passable[boss.pos] ||
|
||||
heroFOV[boss.pos]);
|
||||
GameScene.add( boss );
|
||||
boss.spawnFists();
|
||||
|
||||
stairs = entrance;
|
||||
entrance = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void doMagic( int cell ) {
|
||||
set( cell, Terrain.EMPTY_SP );
|
||||
CellEmitter.get( cell ).start( FlameParticle.FACTORY, 0.1f, 3 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Heap drop( Item item, int cell ) {
|
||||
|
||||
if (!keyDropped && item instanceof SkeletonKey) {
|
||||
keyDropped = true;
|
||||
unseal();
|
||||
|
||||
entrance = stairs;
|
||||
set( entrance, Terrain.ENTRANCE );
|
||||
GameScene.updateMap( entrance );
|
||||
}
|
||||
|
||||
return super.drop( item, cell );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tileName( int tile ) {
|
||||
switch (tile) {
|
||||
case Terrain.WATER:
|
||||
return Messages.get(HallsLevel.class, "water_name");
|
||||
case Terrain.GRASS:
|
||||
return Messages.get(HallsLevel.class, "grass_name");
|
||||
case Terrain.HIGH_GRASS:
|
||||
return Messages.get(HallsLevel.class, "high_grass_name");
|
||||
case Terrain.STATUE:
|
||||
case Terrain.STATUE_SP:
|
||||
return Messages.get(HallsLevel.class, "statue_name");
|
||||
default:
|
||||
return super.tileName( tile );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String tileDesc(int tile) {
|
||||
switch (tile) {
|
||||
case Terrain.WATER:
|
||||
return Messages.get(HallsLevel.class, "water_desc");
|
||||
case Terrain.STATUE:
|
||||
case Terrain.STATUE_SP:
|
||||
return Messages.get(HallsLevel.class, "statue_desc");
|
||||
case Terrain.BOOKSHELF:
|
||||
return Messages.get(HallsLevel.class, "bookshelf_desc");
|
||||
default:
|
||||
return super.tileDesc( tile );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group addVisuals () {
|
||||
super.addVisuals();
|
||||
HallsLevel.addHallsVisuals( this, visuals );
|
||||
return visuals;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle;
|
||||
|
@ -94,7 +94,7 @@ public class DM300Sprite extends MobSprite {
|
|||
new Callback() {
|
||||
@Override
|
||||
public void call() {
|
||||
((NewDM300)ch).onZapComplete();
|
||||
((DM300)ch).onZapComplete();
|
||||
}
|
||||
} );
|
||||
Sample.INSTANCE.play( Assets.Sounds.GAS );
|
||||
|
@ -119,7 +119,7 @@ public class DM300Sprite extends MobSprite {
|
|||
}
|
||||
|
||||
if (anim == slam){
|
||||
((NewDM300)ch).onSlamComplete();
|
||||
((DM300)ch).onSlamComplete();
|
||||
}
|
||||
|
||||
super.onComplete( anim );
|
||||
|
@ -146,7 +146,7 @@ public class DM300Sprite extends MobSprite {
|
|||
superchargeSparks.pour(SparkParticle.STATIC, 0.05f);
|
||||
superchargeSparks.on = false;
|
||||
|
||||
if (ch instanceof NewDM300 && ((NewDM300) ch).isSupercharged()){
|
||||
if (ch instanceof DM300 && ((DM300) ch).isSupercharged()){
|
||||
updateChargeState(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.YogFist;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Beam;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
|
@ -131,12 +130,7 @@ public abstract class FistSprite extends MobSprite {
|
|||
new Callback() {
|
||||
@Override
|
||||
public void call() {
|
||||
//pre-0.8.0 saves
|
||||
if (ch instanceof Yog.BurningFist){
|
||||
((Yog.BurningFist)ch).onZapComplete();
|
||||
} else {
|
||||
((YogFist)ch).onZapComplete();
|
||||
}
|
||||
((YogFist)ch).onZapComplete();
|
||||
}
|
||||
} );
|
||||
Sample.INSTANCE.play( Assets.Sounds.ZAP );
|
||||
|
|
|
@ -208,7 +208,6 @@ public class ItemSprite extends MovieClip {
|
|||
case HEAP: case FOR_SALE:
|
||||
return view( heap.peek() );
|
||||
case CHEST:
|
||||
case MIMIC:
|
||||
return view( ItemSpriteSheet.CHEST, null );
|
||||
case LOCKED_CHEST:
|
||||
return view( ItemSpriteSheet.LOCKED_CHEST, null );
|
||||
|
|
|
@ -23,7 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.tiles;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.NewHallsBossLevel;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.HallsBossLevel;
|
||||
import com.watabou.noosa.TextureFilm;
|
||||
import com.watabou.noosa.Tilemap;
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class WallBlockingTilemap extends Tilemap {
|
|||
|
||||
//FIXME this is to address the wall blocking looking odd on the new yog floor.
|
||||
// The true solution is to improve the fog of war so the blockers aren't necessary.
|
||||
if (Dungeon.level instanceof NewHallsBossLevel){
|
||||
if (Dungeon.level instanceof HallsBossLevel){
|
||||
data[cell] = CLEARED;
|
||||
super.updateMapCell(cell);
|
||||
return;
|
||||
|
|
|
@ -78,7 +78,7 @@ public class LootIndicator extends Tag {
|
|||
if (heap != null) {
|
||||
|
||||
Item item =
|
||||
heap.type == Heap.Type.CHEST || heap.type == Heap.Type.MIMIC ? ItemSlot.CHEST :
|
||||
heap.type == Heap.Type.CHEST ? ItemSlot.CHEST :
|
||||
heap.type == Heap.Type.LOCKED_CHEST ? ItemSlot.LOCKED_CHEST :
|
||||
heap.type == Heap.Type.CRYSTAL_CHEST ? ItemSlot.CRYSTAL_CHEST :
|
||||
heap.type == Heap.Type.TOMB ? ItemSlot.TOMB :
|
||||
|
|
|
@ -23,7 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui.changelist;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DwarfKing;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewDM300;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM300;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TalismanOfForesight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
|
||||
|
@ -497,7 +497,7 @@ public class v0_8_X_Changes {
|
|||
|
||||
Image i = new Image(new DM300Sprite());
|
||||
i.scale.set(PixelScene.align(0.74f));
|
||||
changes.addButton( new ChangeButton(i, Messages.get(NewDM300.class, "name"),
|
||||
changes.addButton( new ChangeButton(i, Messages.get(DM300.class, "name"),
|
||||
"The DM-300 fight has been reworked! DM-300 now has redesigned abilities, a new boss arena, and multiple phases!\n\n" +
|
||||
"As a part of this rework, DM-300's direct stats have been adjusted:\n" +
|
||||
"_-_ Health increased to 300 from 200\n" +
|
||||
|
|
Loading…
Reference in New Issue
Block a user