From f20a5c1dcfd6c9a076a068613383b811b060b3aa Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 3 Apr 2017 06:00:26 -0400 Subject: [PATCH] v0.6.0: implemented a line builder and improved room connection logic --- .../levels/builders/LineBuilder.java | 179 ++++++++++++++++++ .../levels/rooms/Room.java | 16 +- 2 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java new file mode 100644 index 000000000..0457030f6 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java @@ -0,0 +1,179 @@ +/* + * 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.builders; + +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.tunnel.TunnelRoom; +import com.watabou.utils.Random; + +import java.util.ArrayList; + +//A simple builder which puts most rooms in a straight line with a few branches +public class LineBuilder extends Builder { + @Override + public ArrayList build(ArrayList rooms) { + + Room entrance = null; + Room exit = null; + Room shop = null; + ArrayList standards = new ArrayList<>(); + ArrayList specials = new ArrayList<>(); + + for (Room r : rooms){ + if (r instanceof EntranceRoom){ + entrance = r; + } else if (r instanceof ExitRoom) { + exit = r; + } else if (r instanceof ShopRoom){ + shop = r; + } else if (r instanceof StandardRoom){ + standards.add((StandardRoom)r); + } else if (r instanceof SpecialRoom){ + specials.add((SpecialRoom)r); + } + } + + if (entrance == null || exit == null){ + return null; + } + + ArrayList branchable = new ArrayList<>(); + + entrance.setSize(); + entrance.setPos(0, -entrance.width()/2); + branchable.add(entrance); + + if (shop != null){ + shop.setSize(); + shop.setPos(-shop.width(), -shop.height()/2); + shop.connect(entrance); + } + + int standardsOnPath = standards.size()/2 + Random.Int(3) - 1; + standardsOnPath = Math.min(standardsOnPath, standards.size()); + + //standardsOnPath = standards.size(); + + Room curr = entrance; + + for (int i = 0; i < standardsOnPath; i++){ + if (Random.Int(3) == 0){ + TunnelRoom t = new TunnelRoom(); + t.setSize(); + t.setPos( curr.right, -t.height()/2); + t.connect(curr); + rooms.add(t); + branchable.add(t); + curr = t; + } + if (Random.Int(3) == 0){ + TunnelRoom t = new TunnelRoom(); + t.setSize(); + t.setPos( curr.right, -t.height()/2); + t.connect(curr); + rooms.add(t); + branchable.add(t); + curr = t; + } + StandardRoom s = standards.get(i); + s.setSize(); + s.setPos( curr.right, -s.height()/2); + s.connect(curr); + branchable.add(s); + curr = s; + } + + //place exit + exit.setSize(); + exit.setPos( curr.right, -exit.height()/2); + exit.connect(curr); + branchable.add(exit); + + ArrayList upBrancheable = new ArrayList<>(branchable); + ArrayList downBrancheable = new ArrayList<>(branchable); + + //place branches + int i = standardsOnPath; + while (i < standards.size() + specials.size()){ + boolean up = !upBrancheable.isEmpty() && (Random.Int(2) == 0 || downBrancheable.isEmpty()); + + if (up){ + curr = Random.element(upBrancheable); + upBrancheable.remove(curr); + } else { + curr = Random.element(downBrancheable); + downBrancheable.remove(curr); + } + + if (Random.Int(2) == 0){ + TunnelRoom t = new TunnelRoom(); + if (placeBranchRoom(up, curr, t, rooms)){ + rooms.add(t); + } else { + continue; + } + curr = t; + } + if (Random.Int(3) == 0){ + TunnelRoom t = new TunnelRoom(); + if (placeBranchRoom(up, curr, t, rooms)){ + rooms.add(t); + } else { + continue; + } + curr = t; + } + Room r; + if (i < standards.size()) { + r = standards.get(i); + } else { + r = specials.get(i - standards.size()); + } + + if (!placeBranchRoom(up, curr, r, rooms)){ + continue; + } + if (r instanceof StandardRoom) { + if (up) upBrancheable.add(r); + else downBrancheable.add(r); + } + i++; + } + + return rooms; + + } + + private boolean placeBranchRoom(boolean up, Room curr, Room next, ArrayList collision){ + next.setSize(); + next.setPos( curr.left + (curr.width()-next.width())/2, up ? curr.top - next.height()+1 : curr.bottom); + next.connect(curr); + return true; + } + + +} 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 16a7547da..a4b3eb550 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 @@ -123,22 +123,28 @@ public class Room extends Rect implements Graph.Node, Bundlable { Random.Int( top + 1 + m, bottom - m )); } - public void addNeigbour( Room other ) { + public boolean addNeigbour( Room other ) { + if (neigbours.contains(other)) + return true; Rect i = intersect( other ); - if ((i.width() == 0 && i.height() >= 3) || - (i.height() == 0 && i.width() >= 3)) { + if ((i.width() == 0 && i.height() >= 2) || + (i.height() == 0 && i.width() >= 2)) { neigbours.add( other ); other.neigbours.add( this ); + return true; } - + return false; } - public void connect( Room room ) { + public boolean connect( Room room ) { + if (!neigbours.contains(room) && !addNeigbour(room)) + return false; if (!connected.containsKey( room )) { connected.put( room, null ); room.connected.put( this, null ); } + return true; } public boolean inside( Point p ) {