From 7a197a1fe8828362a0f9032354ff310d684f3cdf Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 9 May 2017 22:51:08 -0400 Subject: [PATCH] v0.6.0: improved burned room logic --- .../levels/rooms/standard/BurnedRoom.java | 38 +++++++-- .../levels/rooms/standard/PatchRoom.java | 82 +++++++++++++++++++ 2 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PatchRoom.java diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BurnedRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BurnedRoom.java index 5c37bacc9..1e0426f4b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BurnedRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BurnedRoom.java @@ -25,34 +25,51 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FireTrap; +import com.watabou.utils.Point; import com.watabou.utils.Random; -public class BurnedRoom extends StandardRoom { +public class BurnedRoom extends PatchRoom { + + @Override + public float[] sizeCatProbs() { + return new float[]{4, 1, 0}; + } @Override public void paint(Level level) { Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1, Terrain.EMPTY ); for (Door door : connected.values()) { door.set( Door.Type.REGULAR ); } + //past 8x8 each point of width/height decreases fill by 3% + // e.g. a 14x14 burned room has a fill of 54% + float fill = Math.min( 1f, 1.48f - (width()+height())*0.03f); + setupPatch(level, fill, 2, false ); + for (int i=top + 1; i < bottom; i++) { for (int j=left + 1; j < right; j++) { + if (!patch[xyToPatchCoords(j, i)]) + continue; int cell = i * level.width() + j; - int t = Terrain.EMBERS; + int t; switch (Random.Int( 5 )) { - case 0: + case 0: default: t = Terrain.EMPTY; break; case 1: + t = Terrain.EMBERS; + break; + case 2: t = Terrain.TRAP; level.setTrap(new FireTrap().reveal(), cell); break; - case 2: + case 3: t = Terrain.SECRET_TRAP; level.setTrap(new FireTrap().hide(), cell); break; - case 3: + case 4: t = Terrain.INACTIVE_TRAP; FireTrap trap = new FireTrap(); trap.reveal().active = false; @@ -63,4 +80,15 @@ public class BurnedRoom extends StandardRoom { } } } + + @Override + public boolean canModifyTerrain(Point p) { + return super.canModifyTerrain(p) && !patch[xyToPatchCoords(p.x, p.y)]; + } + + @Override + public boolean canPlaceTrap(Point p) { + return super.canPlaceTrap(p) && !patch[xyToPatchCoords(p.x, p.y)]; + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PatchRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PatchRoom.java new file mode 100644 index 000000000..87dcc1ad5 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PatchRoom.java @@ -0,0 +1,82 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2017 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.standard; + +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Patch; +import com.shatteredpixel.shatteredpixeldungeon.utils.BArray; +import com.watabou.utils.PathFinder; + +//This room type uses the patch system to fill itself in in some manner +//it's still up to the specific room to implement paint, but utility methods are provided +public abstract class PatchRoom extends StandardRoom { + + protected boolean[] patch; + + protected void setupPatch(Level level, float fill, int clustering, boolean ensurePath){ + + if (ensurePath){ + PathFinder.setMapSize(width()-2, height()-2); + boolean valid; + do { + patch = Patch.generate(width()-2, height()-2, fill, clustering, true); + int startPoint = 0; + for (Door door : connected.values()) { + if (door.x == left) { + startPoint = xyToPatchCoords(door.x + 1, door.y); + patch[xyToPatchCoords(door.x + 1, door.y)] = false; + patch[xyToPatchCoords(door.x + 2, door.y)] = false; + } else if (door.x == right) { + startPoint = xyToPatchCoords(door.x - 1, door.y); + patch[xyToPatchCoords(door.x - 1, door.y)] = false; + patch[xyToPatchCoords(door.x - 2, door.y)] = false; + } else if (door.y == top) { + startPoint = xyToPatchCoords(door.x, door.y + 1); + patch[xyToPatchCoords(door.x, door.y + 1)] = false; + patch[xyToPatchCoords(door.x, door.y + 2)] = false; + } else if (door.y == bottom) { + startPoint = xyToPatchCoords(door.x, door.y - 1); + patch[xyToPatchCoords(door.x, door.y - 1)] = false; + patch[xyToPatchCoords(door.x, door.y - 2)] = false; + } + } + + PathFinder.buildDistanceMap(startPoint, BArray.not(patch, null)); + + valid = true; + for (int i = 0; i < patch.length; i++){ + if (!patch[i] && PathFinder.distance[i] == Integer.MAX_VALUE){ + valid = false; + break; + } + } + } while (!valid); + PathFinder.setMapSize(level.width(), level.height()); + } else { + patch = Patch.generate(width()-2, height()-2, fill, clustering, true); + } + } + + protected int xyToPatchCoords(int x, int y){ + return (x-left-1) + ((y-top-1) * (width()-2)); + } +}