v0.9.3: dropped support from saves prior to v0.8.0

This commit is contained in:
Evan Debenham 2021-05-20 21:59:00 -04:00
parent 3314e607d0
commit c551cd0ef3
25 changed files with 78 additions and 1960 deletions

View File

@ -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();

View File

@ -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;
}

View File

@ -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" );

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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 );
}
}
}

View File

@ -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);
}
}

View File

@ -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";

View File

@ -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);
}
}
}

View File

@ -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");

View File

@ -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 );
}

View File

@ -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;

View File

@ -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

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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;

View File

@ -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 :

View File

@ -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" +