v1.2.0: roughly implemented eternal fire room

This commit is contained in:
Evan Debenham 2022-03-09 14:07:54 -05:00
parent a1197debd2
commit c6c125756c
4 changed files with 208 additions and 1 deletions

View File

@ -9,6 +9,8 @@ levels.features.chasm.rankings_desc=Died on Impact
###rooms ###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.name=Mass grave
levels.rooms.special.massgraveroom$bones.desc=Bones litter the floor, what happened here? levels.rooms.special.massgraveroom$bones.desc=Bones litter the floor, what happened here?

View File

@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.StormCloud;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Web; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Web;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Tengu; 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.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
@ -69,6 +70,7 @@ public class BlobImmunity extends FlavourBuff {
immunities.add( CorrosiveGas.class ); immunities.add( CorrosiveGas.class );
immunities.add( Electricity.class ); immunities.add( Electricity.class );
immunities.add( Fire.class ); immunities.add( Fire.class );
immunities.add( MagicalFireRoom.EternalFire.class );
immunities.add( Freezing.class ); immunities.add( Freezing.class );
immunities.add( Inferno.class ); immunities.add( Inferno.class );
immunities.add( ParalyticGas.class ); immunities.add( ParalyticGas.class );

View File

@ -202,7 +202,8 @@ public class EtherealChains extends Artifact {
} }
//don't pull if the collision spot is in a wall //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")); GLog.i( Messages.get(this, "inside_wall"));
return; return;
} }

View File

@ -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 <http://www.gnu.org/licenses/>
*/
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;
}
}
}
}
}