From 3cd27528c03b0c008e1d78502eb7522a0d2fd779 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Sat, 6 May 2017 18:51:15 -0400 Subject: [PATCH] v0.6.0: rooms can now specify allowed locations for traps/water/grass --- .../levels/painters/RegularPainter.java | 100 ++++++++++++------ .../levels/rooms/Room.java | 43 +++++++- .../rooms/connection/ConnectionRoom.java | 8 ++ 3 files changed, 112 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java index 2d73e86d7..2b6e5e097 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java @@ -24,10 +24,8 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.painters; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Patch; -import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.connection.ConnectionRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EmptyRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap; import com.watabou.utils.PathFinder; @@ -116,15 +114,15 @@ public abstract class RegularPainter extends Painter { } if (waterFill > 0f) { - paintWater( level ); + paintWater( level, rooms ); } if (grassFill > 0f){ - paintGrass( level ); + paintGrass( level, rooms ); } if (nTraps > 0){ - paintTraps( level ); + paintTraps( level, rooms ); } decorate( level, rooms ); @@ -249,47 +247,79 @@ public abstract class RegularPainter extends Painter { return true; } - protected void paintWater( Level l ){ - boolean[] lake = - Patch.generate( l.width(), l.height(), waterFill, waterSmoothness, true ); - for (int i=0; i < l.length(); i++) { - if (l.map[i] == Terrain.EMPTY && lake[i]) { - l.map[i] = Terrain.WATER; - } - } - } - - protected void paintGrass( Level l ) { - boolean[] grass = - Patch.generate( l.width(), l.height(), grassFill, grassSmoothness, true ); + protected void paintWater( Level l, ArrayList rooms ){ + boolean[] lake = Patch.generate( l.width(), l.height(), waterFill, waterSmoothness, true ); - //adds some chaos to grass distribution, note that this does decrease the fill rate slightly - //TODO: analyize statistical changes on fill rate - for (int i=l.width()+1; i < l.length()-l.width()-1; i++) { - if (l.map[i] == Terrain.EMPTY && grass[i]) { - int count = 1; - for (int n : PathFinder.NEIGHBOURS8) { - if (grass[i + n]) { - count++; + if (!rooms.isEmpty()){ + for (Room r : rooms){ + for (Point p : r.terrainModifiablePoints()){ + int i = l.pointToCell(p); + if (lake[i] && l.map[i] == Terrain.EMPTY){ + l.map[i] = Terrain.WATER; } } - l.map[i] = (Random.Float() < count / 12f) ? Terrain.HIGH_GRASS : Terrain.GRASS; } + } else { + for (int i = 0; i < l.length(); i ++) { + if (lake[i] && l.map[i] == Terrain.EMPTY){ + l.map[i] = Terrain.WATER; + } + } + } + + } + + protected void paintGrass( Level l, ArrayList rooms ) { + boolean[] grass = Patch.generate( l.width(), l.height(), grassFill, grassSmoothness, true ); + + ArrayList grassCells = new ArrayList<>(); + + if (!rooms.isEmpty()){ + for (Room r : rooms){ + for (Point p : r.terrainModifiablePoints()){ + int i = l.pointToCell(p); + if (grass[i] && l.map[i] == Terrain.EMPTY){ + grassCells.add(i); + } + } + } + } else { + for (int i = 0; i < l.length(); i ++) { + if (grass[i] && l.map[i] == Terrain.EMPTY){ + grassCells.add(i); + } + } + } + + //Adds chaos to grass height distribution. Ratio of high grass depends on fill and smoothing + //Full range is 8.3% to 75%, but most commonly (20% fill with 3 smoothing) is around 60% + //low smoothing, or very low fill, will begin to push the ratio down, normally to 50-30% + for (int i : grassCells) { + int count = 1; + for (int n : PathFinder.NEIGHBOURS8) { + if (grass[i + n]) { + count++; + } + } + l.map[i] = (Random.Float() < count / 12f) ? Terrain.HIGH_GRASS : Terrain.GRASS; } } - protected void paintTraps( Level l ) { + protected void paintTraps( Level l, ArrayList rooms ) { ArrayList validCells = new ArrayList<>(); - for (int i = 0; i < l.length(); i ++) { - if (l.map[i] == Terrain.EMPTY){ - //TODO rooms should probably be able to handle trap placement - if (Dungeon.depth == 1){ - Room r = ((RegularLevel)l).room(i); - if (r != null && !(r instanceof ConnectionRoom)){ + if (!rooms.isEmpty()){ + for (Room r : rooms){ + for (Point p : r.trapPlaceablePoints()){ + int i = l.pointToCell(p); + if (l.map[i] == Terrain.EMPTY){ validCells.add(i); } - } else { + } + } + } else { + for (int i = 0; i < l.length(); i ++) { + if (l.map[i] == Terrain.EMPTY){ validCells.add(i); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java index 416531dae..a834a1b67 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java @@ -68,10 +68,6 @@ public class Room extends Rect implements Graph.Node, Bundlable { return this; } - //TODO make abstract - public void paint(Level level){ } - - // **** Spatial logic **** //Note: when overriding these YOU MUST store any randomly decided values. @@ -143,6 +139,7 @@ public class Room extends Rect implements Graph.Node, Bundlable { Random.IntRange( top + m, bottom - m )); } + //a point is only considered to be inside if it is within the 1 tile perimeter public boolean inside( Point p ) { return p.x > left && p.y > top && p.x < right && p.y < bottom; } @@ -261,6 +258,44 @@ public class Room extends Rect implements Graph.Node, Bundlable { connected.clear(); } + // **** Painter Logic **** + + //TODO make abstract + public void paint(Level level){} + + //whether or not a painter can make its own modifications to a specific point + public boolean canModifyTerrain(Point p){ + return inside(p); + } + + public final ArrayList terrainModifiablePoints(){ + ArrayList points = new ArrayList<>(); + for (int i = left; i <= right; i++) { + for (int j = top; j <= bottom; j++) { + Point p = new Point(i, j); + if (canModifyTerrain(p)) points.add(p); + } + } + return points; + } + + //whether or not a painter can place a trap at a specific point + public boolean canPlaceTrap(Point p){ + return inside(p); + } + + public final ArrayList trapPlaceablePoints(){ + ArrayList points = new ArrayList<>(); + for (int i = left; i <= right; i++) { + for (int j = top; j <= bottom; j++) { + Point p = new Point(i, j); + if (canPlaceTrap(p)) points.add(p); + } + } + return points; + } + + // **** Graph.Node interface **** @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/connection/ConnectionRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/connection/ConnectionRoom.java index 1127b1499..29ee3708c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/connection/ConnectionRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/connection/ConnectionRoom.java @@ -21,8 +21,10 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.connection; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.watabou.utils.Point; import com.watabou.utils.Random; import java.util.HashMap; @@ -50,6 +52,12 @@ public abstract class ConnectionRoom extends Room { else return 4; } + @Override + public boolean canPlaceTrap(Point p) { + //traps cannot appear in connection rooms on floor 1 + return super.canPlaceTrap(p) && Dungeon.depth > 1; + } + private static HashMap, Float> chances = new LinkedHashMap<>(); static {