From c6c125756cdb4779cea1566e65d0862358150fac Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 9 Mar 2022 14:07:54 -0500 Subject: [PATCH] v1.2.0: roughly implemented eternal fire room --- .../assets/messages/levels/levels.properties | 2 + .../actors/buffs/BlobImmunity.java | 2 + .../items/artifacts/EtherealChains.java | 3 +- .../levels/rooms/special/MagicalFireRoom.java | 202 ++++++++++++++++++ 4 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java diff --git a/core/src/main/assets/messages/levels/levels.properties b/core/src/main/assets/messages/levels/levels.properties index dc2f566fb..f41e521b8 100644 --- a/core/src/main/assets/messages/levels/levels.properties +++ b/core/src/main/assets/messages/levels/levels.properties @@ -9,6 +9,8 @@ levels.features.chasm.rankings_desc=Died on Impact ###rooms +levels.rooms.special.magicalfireroom$eternalfire.desc=A wall of dense magical fire is here. It's so hot that you can't move through it, and it ignites anything that gets too close. It shows no signs of burning down naturally, you'll need to use something to extinguish it. + levels.rooms.special.massgraveroom$bones.name=Mass grave levels.rooms.special.massgraveroom$bones.desc=Bones litter the floor, what happened here? diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/BlobImmunity.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/BlobImmunity.java index f3f638b93..2dcb8acf5 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/BlobImmunity.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/BlobImmunity.java @@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.StormCloud; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Web; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Tengu; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.MagicalFireRoom; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; @@ -69,6 +70,7 @@ public class BlobImmunity extends FlavourBuff { immunities.add( CorrosiveGas.class ); immunities.add( Electricity.class ); immunities.add( Fire.class ); + immunities.add( MagicalFireRoom.EternalFire.class ); immunities.add( Freezing.class ); immunities.add( Inferno.class ); immunities.add( ParalyticGas.class ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java index f763b42b6..56b838218 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/EtherealChains.java @@ -202,7 +202,8 @@ public class EtherealChains extends Artifact { } //don't pull if the collision spot is in a wall - if (Dungeon.level.solid[chain.collisionPos]){ + if (Dungeon.level.solid[chain.collisionPos] + || !(Dungeon.level.passable[chain.collisionPos] || Dungeon.level.avoid[chain.collisionPos])){ GLog.i( Messages.get(this, "inside_wall")); return; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java new file mode 100644 index 000000000..5f491664e --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java @@ -0,0 +1,202 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2022 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blizzard; +import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob; +import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire; +import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Freezing; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots; +import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EmptyRoom; +import com.watabou.utils.PathFinder; +import com.watabou.utils.Point; +import com.watabou.utils.Random; +import com.watabou.utils.Rect; + +public class MagicalFireRoom extends SpecialRoom { + + @Override + public void paint(Level level) { + + Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1, Terrain.EMPTY ); + + Door door = entrance(); + door.set( Door.Type.REGULAR ); + + int x = -1; + int y = -1; + Point firePos = center(); + Room behindFire = new EmptyRoom(); + + if (door.x == left || door.x == right){ + firePos.y = top+1; + while (firePos.y != bottom){ + Blob.seed(level.pointToCell(firePos), 1, EternalFire.class, level); + Painter.set(level, firePos, Terrain.EMPTY_SP); + firePos.y++; + } + if (door.x == left){ + behindFire.set(firePos.x+1, top+1, right-1, bottom-1); + } else { + behindFire.set(left+1, top+1, firePos.x-1, bottom-1); + } + } else { + firePos.x = left+1; + while (firePos.x != right){ + Blob.seed(level.pointToCell(firePos), 1, EternalFire.class, level); + Painter.set(level, firePos, Terrain.EMPTY_SP); + firePos.x++; + } + if (door.y == top){ + behindFire.set(left+1, firePos.y+1, right-1, bottom-1); + } else { + behindFire.set(left+1, top+1, right-1, firePos.y-1); + } + } + + Painter.fill(level, behindFire, Terrain.EMPTY_SP); + + int pos = level.pointToCell(Random.element(behindFire.getPoints())); + if (Random.Int( 3 ) == 0) { + level.drop( prize( level ), pos ).type = Heap.Type.CHEST; + } else { + level.drop( prize( level ), pos ).type = Heap.Type.CHEST; + } + + level.addItemToSpawn(new PotionOfFrost()); + + } + + private static Item prize(Level level ) { + + Item prize = level.findPrizeItem(); + + //TODO prize! + + return prize; + } + + @Override + public boolean canPlaceGrass(Point p) { + return false; + } + + public static class EternalFire extends Fire { + @Override + protected void evolve() { + + int cell; + + Freezing freeze = (Freezing)Dungeon.level.blobs.get( Freezing.class ); + Blizzard bliz = (Blizzard)Dungeon.level.blobs.get( Blizzard.class ); + + Level l = Dungeon.level; + for (int i = area.left; i < area.right; i++){ + for (int j = area.top; j < area.bottom; j++){ + cell = i + j*l.width(); + if (cur[cell] <= 0) continue; + + cur[cell]++; + + //evaporates in the presence of water, frost, or blizzard + //this blob is not considered interchangeable with fire, so those blobs do not interact with it otherwise + //potion of purity can cleanse it though + if (l.water[cell]){ + cur[cell] = 0; + } + if (freeze != null && freeze.volume > 0 && freeze.cur[cell] > 0){ + freeze.clear(cell); + cur[cell] = 0; + } + if (bliz != null && bliz.volume > 0 && bliz.cur[cell] > 0){ + bliz.clear(cell); + cur[cell] = 0; + } + + //if the hero is adjacent, set them on fire briefly + //TODO all chars, but prevent random wandering into the fire? + if (cur[cell] > 0){ + for (int k : PathFinder.NEIGHBOURS4){ + if (Actor.findChar(cell+k) == Dungeon.hero + && !Dungeon.hero.isImmune(getClass())){ + Buff.affect(Dungeon.hero, Burning.class).reignite(Dungeon.hero, 4f); + } + } + } + + l.passable[cell] = cur[cell] == 0 && (Terrain.flags[l.map[cell]] & Terrain.PASSABLE) != 0; + } + } + super.evolve(); + } + + @Override + public void seed(Level level, int cell, int amount) { + super.seed(level, cell, amount); + level.passable[cell] = cur[cell] == 0 && (Terrain.flags[level.map[cell]] & Terrain.PASSABLE) != 0; + } + + @Override + public void clear(int cell) { + super.clear(cell); + if (cur == null) return; + Level l = Dungeon.level; + l.passable[cell] = cur[cell] == 0 && (Terrain.flags[l.map[cell]] & Terrain.PASSABLE) != 0; + } + + @Override + public void fullyClear() { + super.fullyClear(); + Dungeon.level.buildFlagMaps(); + } + + @Override + public void use( BlobEmitter emitter ) { + super.use( emitter ); + emitter.pour( ElmoParticle.FACTORY, 0.02f ); + } + + @Override + public void onBuildFlagMaps( Level l ) { + if (volume > 0){ + for (int i=0; i < l.length(); i++) { + l.passable[i] = l.passable[i] && cur[i] == 0; + } + } + } + } + +}