parent
f71fa66c1e
commit
1ca0b9e0e9
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.5 KiB |
Binary file not shown.
@ -0,0 +1,37 @@ |
|||||||
|
package mightypork.gamecore.util.error; |
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Thrown when data could not be read successfully. |
||||||
|
* |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
|
public class CorruptDataException extends IOException { |
||||||
|
|
||||||
|
public CorruptDataException() |
||||||
|
{ |
||||||
|
super(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public CorruptDataException(String message, Throwable cause) |
||||||
|
{ |
||||||
|
super(message, cause); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public CorruptDataException(String message) |
||||||
|
{ |
||||||
|
super(message); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public CorruptDataException(Throwable cause) |
||||||
|
{ |
||||||
|
super(cause); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,37 +0,0 @@ |
|||||||
package mightypork.gamecore.util.error; |
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* To be used when a data could not be read successfully. |
|
||||||
* |
|
||||||
* @author MightyPork |
|
||||||
*/ |
|
||||||
public class CorruptedDataException extends IOException { |
|
||||||
|
|
||||||
public CorruptedDataException() |
|
||||||
{ |
|
||||||
super(); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public CorruptedDataException(String message, Throwable cause) |
|
||||||
{ |
|
||||||
super(message, cause); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public CorruptedDataException(String message) |
|
||||||
{ |
|
||||||
super(message); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public CorruptedDataException(Throwable cause) |
|
||||||
{ |
|
||||||
super(cause); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,95 @@ |
|||||||
|
package mightypork.gamecore.util.math.algo; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.Calc; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Move lists, bit masks and other utilities |
||||||
|
* |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
|
public class Moves { |
||||||
|
|
||||||
|
public static final byte BIT_NW = (byte) 0b10000000; |
||||||
|
public static final byte BIT_N = (byte) 0b01000000; |
||||||
|
public static final byte BIT_NE = (byte) 0b00100000; |
||||||
|
public static final byte BIT_E = (byte) 0b00010000; |
||||||
|
public static final byte BIT_SE = (byte) 0b00001000; |
||||||
|
public static final byte BIT_S = (byte) 0b00000100; |
||||||
|
public static final byte BIT_SW = (byte) 0b00000010; |
||||||
|
public static final byte BIT_W = (byte) 0b00000001; |
||||||
|
|
||||||
|
public static final byte BITS_CARDINAL = BIT_N | BIT_S | BIT_E | BIT_W; |
||||||
|
public static final byte BITS_DIAGONAL = BIT_NE | BIT_NW | BIT_SE | BIT_SW; |
||||||
|
|
||||||
|
public static final byte BITS_NW_CORNER = BIT_W | BIT_NW | BIT_N; |
||||||
|
public static final byte BITS_NE_CORNER = BIT_E | BIT_NE | BIT_N; |
||||||
|
public static final byte BITS_SW_CORNER = BIT_W | BIT_SW | BIT_S; |
||||||
|
public static final byte BITS_SE_CORNER = BIT_E | BIT_SE | BIT_S; |
||||||
|
|
||||||
|
public static final Move NW = Move.make(-1, -1); |
||||||
|
public static final Move N = Move.make(0, -1); |
||||||
|
public static final Move NE = Move.make(1, -1); |
||||||
|
public static final Move E = Move.make(1, 0); |
||||||
|
public static final Move SE = Move.make(1, 1); |
||||||
|
public static final Move S = Move.make(0, 1); |
||||||
|
public static final Move SW = Move.make(-1, 1); |
||||||
|
public static final Move W = Move.make(-1, 0); |
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
/** All sides, in the order of bits. */ |
||||||
|
public final static List<Move> ALL_SIDES = Collections.unmodifiableList(Arrays.asList( |
||||||
|
NW, |
||||||
|
N, |
||||||
|
NE, |
||||||
|
E, |
||||||
|
SE, |
||||||
|
S, |
||||||
|
SW, |
||||||
|
W |
||||||
|
)); |
||||||
|
|
||||||
|
public final static List<Move> CARDINAL_SIDES = Collections.unmodifiableList(Arrays.asList( |
||||||
|
N, |
||||||
|
E, |
||||||
|
S, |
||||||
|
W |
||||||
|
)); |
||||||
|
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
/** |
||||||
|
* Get element from all sides |
||||||
|
* |
||||||
|
* @param i side index |
||||||
|
* @return the side coord |
||||||
|
*/ |
||||||
|
public static Move getSide(int i) |
||||||
|
{ |
||||||
|
return ALL_SIDES.get(i); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static byte getBit(int i) |
||||||
|
{ |
||||||
|
return (byte) (1 << (7 - i)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static Move randomCardinal() |
||||||
|
{ |
||||||
|
return Calc.pick(CARDINAL_SIDES); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static Move randomCardinal(Random rand) |
||||||
|
{ |
||||||
|
return Calc.pick(rand, CARDINAL_SIDES); |
||||||
|
} |
||||||
|
} |
@ -1,79 +0,0 @@ |
|||||||
package mightypork.gamecore.util.math.algo; |
|
||||||
|
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.Calc; |
|
||||||
|
|
||||||
|
|
||||||
public class Sides { |
|
||||||
|
|
||||||
public static final byte MASK_NW = (byte) 0b10000000; |
|
||||||
public static final byte MASK_N = (byte) 0b01000000; |
|
||||||
public static final byte MASK_NE = (byte) 0b00100000; |
|
||||||
public static final byte MASK_E = (byte) 0b00010000; |
|
||||||
public static final byte MASK_SE = (byte) 0b00001000; |
|
||||||
public static final byte MASK_S = (byte) 0b00000100; |
|
||||||
public static final byte MASK_SW = (byte) 0b00000010; |
|
||||||
public static final byte MASK_W = (byte) 0b00000001; |
|
||||||
|
|
||||||
public static final byte MASK_CARDINAL = MASK_N | MASK_S | MASK_E | MASK_W; |
|
||||||
public static final byte MASK_DIAGONAL = MASK_NE | MASK_NW | MASK_SE | MASK_SW; |
|
||||||
|
|
||||||
public static final byte NW_CORNER = MASK_W | MASK_NW | MASK_N; |
|
||||||
public static final byte NE_CORNER = MASK_E | MASK_NE | MASK_N; |
|
||||||
public static final byte SW_CORNER = MASK_W | MASK_SW | MASK_S; |
|
||||||
public static final byte SE_CORNER = MASK_E | MASK_SE | MASK_S; |
|
||||||
|
|
||||||
public static final Step NW = Step.make(-1, -1); |
|
||||||
public static final Step N = Step.make(0, -1); |
|
||||||
public static final Step NE = Step.make(1, -1); |
|
||||||
public static final Step E = Step.make(1, 0); |
|
||||||
public static final Step SE = Step.make(1, 1); |
|
||||||
public static final Step S = Step.make(0, 1); |
|
||||||
public static final Step SW = Step.make(-1, 1); |
|
||||||
public static final Step W = Step.make(-1, 0); |
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
/** All sides, in the order of bits. */ |
|
||||||
public final static Step[] ALL_SIDES = { |
|
||||||
NW, |
|
||||||
N, |
|
||||||
NE, |
|
||||||
E, |
|
||||||
SE, |
|
||||||
S, |
|
||||||
SW, |
|
||||||
W |
|
||||||
}; |
|
||||||
|
|
||||||
public final static Step[] CARDINAL_SIDES = { |
|
||||||
N, |
|
||||||
E, |
|
||||||
S, |
|
||||||
W |
|
||||||
}; |
|
||||||
|
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
/** |
|
||||||
* Get element from all sides |
|
||||||
* |
|
||||||
* @param i side index |
|
||||||
* @return the side coord |
|
||||||
*/ |
|
||||||
public static Step get(int i) |
|
||||||
{ |
|
||||||
return ALL_SIDES[i]; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public static byte bit(int i) |
|
||||||
{ |
|
||||||
return (byte) (1 << (7 - i)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public static Step randomCardinal() |
|
||||||
{ |
|
||||||
return CARDINAL_SIDES[Calc.randInt(0, 3)]; |
|
||||||
} |
|
||||||
} |
|
@ -1,50 +0,0 @@ |
|||||||
package mightypork.gamecore.util.objects; |
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import mightypork.gamecore.logging.Log; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Object utils class
|
|
||||||
* |
|
||||||
* @author MightyPork |
|
||||||
*/ |
|
||||||
public class ObjectUtils { |
|
||||||
|
|
||||||
public static Object fallback(Object... options) |
|
||||||
{ |
|
||||||
for (final Object o : options) { |
|
||||||
if (o != null) return o; |
|
||||||
} |
|
||||||
return null; // error
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public static <T> String arrayToString(T[] arr) |
|
||||||
{ |
|
||||||
final StringBuilder sb = new StringBuilder(); |
|
||||||
|
|
||||||
sb.append('['); |
|
||||||
final boolean first = true; |
|
||||||
for (final T o : arr) { |
|
||||||
if (!first) sb.append(','); |
|
||||||
sb.append(Log.str(o)); |
|
||||||
} |
|
||||||
sb.append(']'); |
|
||||||
|
|
||||||
return sb.toString(); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public static <T> List<T> arrayToList(T[] objs) |
|
||||||
{ |
|
||||||
final ArrayList<T> list = new ArrayList<>(); |
|
||||||
for (final T o : objs) { |
|
||||||
list.add(o); |
|
||||||
} |
|
||||||
return list; |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,119 @@ |
|||||||
|
/* |
||||||
|
* The Alphanum Algorithm is an improved sorting algorithm for strings |
||||||
|
* containing numbers. Instead of sorting numbers in ASCII order like |
||||||
|
* a standard sort, this algorithm sorts numbers in numeric order. |
||||||
|
* |
||||||
|
* The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
|
||||||
|
* |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License as published by the Free Software Foundation; either |
||||||
|
* version 2.1 of the License, or any later version. |
||||||
|
* |
||||||
|
* This library 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 |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public |
||||||
|
* License along with this library; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
package mightypork.gamecore.util.strings; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.Comparator; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* String comparator taking care of strings with numbers. |
||||||
|
* |
||||||
|
* @author Daniel Migowski |
||||||
|
* @author Andre Bogus |
||||||
|
* @author David Koelle |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
|
public class AlphanumComparator implements Comparator<String> { |
||||||
|
|
||||||
|
public static final AlphanumComparator instance = new AlphanumComparator(); |
||||||
|
|
||||||
|
|
||||||
|
private final boolean isDigit(char ch) |
||||||
|
{ |
||||||
|
return ch >= '0' && ch <= '9'; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Length of string is passed in for improved efficiency (only need to |
||||||
|
* calculate it once) |
||||||
|
**/ |
||||||
|
private final String getChunk(String s, int slength, int marker) |
||||||
|
{ |
||||||
|
final StringBuilder chunk = new StringBuilder(); |
||||||
|
char c = s.charAt(marker); |
||||||
|
chunk.append(c); |
||||||
|
marker++; |
||||||
|
|
||||||
|
if (isDigit(c)) { |
||||||
|
while (marker < slength) { |
||||||
|
c = s.charAt(marker); |
||||||
|
if (!isDigit(c)) break; |
||||||
|
chunk.append(c); |
||||||
|
marker++; |
||||||
|
} |
||||||
|
} else { |
||||||
|
while (marker < slength) { |
||||||
|
c = s.charAt(marker); |
||||||
|
if (isDigit(c)) break; |
||||||
|
chunk.append(c); |
||||||
|
marker++; |
||||||
|
} |
||||||
|
} |
||||||
|
return chunk.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int compare(String s1, String s2) |
||||||
|
{ |
||||||
|
int thisMarker = 0; |
||||||
|
int thatMarker = 0; |
||||||
|
final int s1Length = s1.length(); |
||||||
|
final int s2Length = s2.length(); |
||||||
|
|
||||||
|
while (thisMarker < s1Length && thatMarker < s2Length) { |
||||||
|
final String thisChunk = getChunk(s1, s1Length, thisMarker); |
||||||
|
thisMarker += thisChunk.length(); |
||||||
|
|
||||||
|
final String thatChunk = getChunk(s2, s2Length, thatMarker); |
||||||
|
thatMarker += thatChunk.length(); |
||||||
|
|
||||||
|
// If both chunks contain numeric characters, sort them numerically
|
||||||
|
int result = 0; |
||||||
|
if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) { |
||||||
|
// Simple chunk comparison by length.
|
||||||
|
final int thisChunkLength = thisChunk.length(); |
||||||
|
result = thisChunkLength - thatChunk.length(); |
||||||
|
// If equal, the first different number counts
|
||||||
|
if (result == 0) { |
||||||
|
for (int i = 0; i < thisChunkLength; i++) { |
||||||
|
result = thisChunk.charAt(i) - thatChunk.charAt(i); |
||||||
|
if (result != 0) { |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
result = thisChunk.compareTo(thatChunk); |
||||||
|
} |
||||||
|
|
||||||
|
if (result != 0) return result; |
||||||
|
} |
||||||
|
|
||||||
|
return s1Length - s2Length; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,253 @@ |
|||||||
|
package mightypork.rogue.world.gen; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.Range; |
||||||
|
import mightypork.gamecore.util.math.algo.Coord; |
||||||
|
import mightypork.rogue.world.World; |
||||||
|
import mightypork.rogue.world.entity.Entity; |
||||||
|
import mightypork.rogue.world.item.Item; |
||||||
|
import mightypork.rogue.world.level.Level; |
||||||
|
|
||||||
|
|
||||||
|
public class LevelBuilder { |
||||||
|
|
||||||
|
public static enum BuildOrder |
||||||
|
{ |
||||||
|
FIRST, MIDDLE, LAST |
||||||
|
} |
||||||
|
|
||||||
|
private class RoomEntry { |
||||||
|
|
||||||
|
int count; |
||||||
|
RoomBuilder room; |
||||||
|
boolean important; |
||||||
|
|
||||||
|
|
||||||
|
public RoomEntry(RoomBuilder room, int count, boolean important) |
||||||
|
{ |
||||||
|
this.count = count; |
||||||
|
this.room = room; |
||||||
|
this.important = important; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class ItemEntry { |
||||||
|
|
||||||
|
Item item; |
||||||
|
boolean important; |
||||||
|
|
||||||
|
|
||||||
|
public ItemEntry(Item item, boolean important) |
||||||
|
{ |
||||||
|
this.item = item; |
||||||
|
this.important = important; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class EntityEntry { |
||||||
|
|
||||||
|
Entity entity; |
||||||
|
boolean important; |
||||||
|
|
||||||
|
|
||||||
|
public EntityEntry(Entity item, boolean important) |
||||||
|
{ |
||||||
|
this.entity = item; |
||||||
|
this.important = important; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private final ScratchMap map; |
||||||
|
private final Random rand; |
||||||
|
private boolean built; |
||||||
|
|
||||||
|
private final LinkedList<RoomEntry> roomsFirst = new LinkedList<>(); |
||||||
|
private final LinkedList<RoomEntry> roomsMiddle = new LinkedList<>(); |
||||||
|
private final LinkedList<RoomEntry> roomsLast = new LinkedList<>(); |
||||||
|
|
||||||
|
private final LinkedList<ItemEntry> items = new LinkedList<>(); |
||||||
|
private final LinkedList<EntityEntry> entities = new LinkedList<>(); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* make a new level builder instance. |
||||||
|
* |
||||||
|
* @param max_size max map size (square side - tiles) |
||||||
|
* @param theme tiles theme |
||||||
|
* @param seed level seed |
||||||
|
*/ |
||||||
|
public LevelBuilder(int max_size, MapTheme theme, long seed) |
||||||
|
{ |
||||||
|
this.rand = new Random(seed); |
||||||
|
this.map = new ScratchMap(max_size, theme, rand); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Add a single room to the room buffer. |
||||||
|
* |
||||||
|
* @param room room builder |
||||||
|
* @param order build order |
||||||
|
* @param important try harder and throw error on fail |
||||||
|
*/ |
||||||
|
public void addRoom(RoomBuilder room, BuildOrder order, boolean important) |
||||||
|
{ |
||||||
|
addRoom(room, Range.make(1, 1), order, important); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Add multiple rooms of the type to the room buffer. |
||||||
|
* |
||||||
|
* @param room room builder |
||||||
|
* @param count number of rooms to build |
||||||
|
* @param order build order |
||||||
|
* @param important try harder and throw error on fail |
||||||
|
*/ |
||||||
|
public void addRoom(RoomBuilder room, Range count, BuildOrder order, boolean important) |
||||||
|
{ |
||||||
|
final List<RoomEntry> list; |
||||||
|
|
||||||
|
switch (order) { |
||||||
|
case FIRST: |
||||||
|
list = roomsFirst; |
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
case MIDDLE: |
||||||
|
list = roomsMiddle; |
||||||
|
break; |
||||||
|
|
||||||
|
case LAST: |
||||||
|
list = roomsLast; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
list.add(new RoomEntry(room, count.randInt(rand), important)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void buildRooms(LinkedList<RoomEntry> list) |
||||||
|
{ |
||||||
|
while (!list.isEmpty()) { |
||||||
|
|
||||||
|
Collections.shuffle(list, rand); |
||||||
|
|
||||||
|
for (final Iterator<RoomEntry> iter = list.iterator(); iter.hasNext();) { |
||||||
|
final RoomEntry rge = iter.next(); |
||||||
|
|
||||||
|
map.addRoom(rge.room, rge.important); |
||||||
|
|
||||||
|
if ((--rge.count) <= 0) { |
||||||
|
iter.remove(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void buildCorridors() throws WorldGenError |
||||||
|
{ |
||||||
|
map.buildCorridors(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void buildEntities() |
||||||
|
{ |
||||||
|
for (final EntityEntry entry : entities) { |
||||||
|
final int tries = entry.important ? 200 : 50; |
||||||
|
final boolean success = map.addEntityInMap(entry.entity, tries); |
||||||
|
|
||||||
|
if (entry.important && !success) { |
||||||
|
throw new WorldGenError("Could not place an important entity: " + entry.entity); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void buildItems() |
||||||
|
{ |
||||||
|
for (final ItemEntry entry : items) { |
||||||
|
final int tries = entry.important ? 200 : 50; |
||||||
|
final boolean success = map.addItemInMap(entry.item, tries); |
||||||
|
|
||||||
|
if (entry.important && !success) { |
||||||
|
throw new WorldGenError("Could not place an important item: " + entry.item); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void writeToMap() |
||||||
|
{ |
||||||
|
buildRooms(roomsFirst); |
||||||
|
buildRooms(roomsMiddle); |
||||||
|
buildRooms(roomsLast); |
||||||
|
buildCorridors(); |
||||||
|
|
||||||
|
map.fixGlitches(); |
||||||
|
|
||||||
|
buildItems(); |
||||||
|
buildEntities(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Write to a new level instance. |
||||||
|
* |
||||||
|
* @param world level's world |
||||||
|
* @return the level |
||||||
|
* @throws WorldGenError on error in generation |
||||||
|
*/ |
||||||
|
public Level build(World world) throws WorldGenError |
||||||
|
{ |
||||||
|
if (built) { |
||||||
|
throw new WorldGenError("Level already built."); |
||||||
|
} |
||||||
|
built = true; |
||||||
|
|
||||||
|
writeToMap(); |
||||||
|
|
||||||
|
final Coord size = map.getNeededSize(); |
||||||
|
final Level lvl = new Level(size.x, size.y); |
||||||
|
lvl.setWorld(world); // important for creating entities
|
||||||
|
|
||||||
|
map.writeToLevel(lvl); |
||||||
|
|
||||||
|
return lvl; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Add an item to be added to the level when tiles are built. |
||||||
|
* |
||||||
|
* @param item item to add |
||||||
|
* @param important try harder and throw error on fail |
||||||
|
* @throws WorldGenError on fail |
||||||
|
*/ |
||||||
|
public void addItem(Item item, boolean important) throws WorldGenError |
||||||
|
{ |
||||||
|
items.add(new ItemEntry(item, important)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Add an entity to be added to the level when tiles are built.<br> |
||||||
|
* It's EID will be assigned during writing to level. |
||||||
|
* |
||||||
|
* @param entity entity to add |
||||||
|
* @param important try harder and throw error on fail |
||||||
|
* @throws WorldGenError on fail |
||||||
|
*/ |
||||||
|
public void addEntity(Entity entity, boolean important) throws WorldGenError |
||||||
|
{ |
||||||
|
entities.add(new EntityEntry(entity, important)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,124 +0,0 @@ |
|||||||
package mightypork.rogue.world.gen; |
|
||||||
|
|
||||||
|
|
||||||
import java.util.Random; |
|
||||||
|
|
||||||
import mightypork.gamecore.logging.Log; |
|
||||||
import mightypork.gamecore.util.math.Calc; |
|
||||||
import mightypork.gamecore.util.math.algo.Coord; |
|
||||||
import mightypork.rogue.world.World; |
|
||||||
import mightypork.rogue.world.entity.Entities; |
|
||||||
import mightypork.rogue.world.entity.Entity; |
|
||||||
import mightypork.rogue.world.gen.rooms.Rooms; |
|
||||||
import mightypork.rogue.world.gen.themes.ThemeBrick; |
|
||||||
import mightypork.rogue.world.item.Items; |
|
||||||
import mightypork.rogue.world.level.Level; |
|
||||||
|
|
||||||
|
|
||||||
public class LevelGenerator { |
|
||||||
|
|
||||||
public static final MapTheme DUNGEON_THEME = new ThemeBrick(); |
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("fallthrough") |
|
||||||
public static Level build(World world, long seed, int level, MapTheme theme, boolean lastLevel) throws WorldGenError |
|
||||||
{ |
|
||||||
Log.f3("Generating level of complexity: " + level); |
|
||||||
|
|
||||||
final Random rand = new Random(seed + 13); |
|
||||||
|
|
||||||
final int max_size = 128; |
|
||||||
|
|
||||||
final ScratchMap map = new ScratchMap(max_size, theme, rand); |
|
||||||
|
|
||||||
// start
|
|
||||||
if (!map.addRoom(Rooms.ENTRANCE, true)) { |
|
||||||
throw new WorldGenError("Could not place entrance room."); |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 1 + level, (int) (1 + level * 1.5)); i++) { |
|
||||||
map.addRoom(Rooms.BASIC, false); |
|
||||||
|
|
||||||
// spice it up with dead ends
|
|
||||||
if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END, false); |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 1, (int) Math.ceil(level / 2D)); i++) { |
|
||||||
map.addRoom(Rooms.TREASURE, false); |
|
||||||
} |
|
||||||
|
|
||||||
if (!lastLevel) { |
|
||||||
if (!map.addRoom(Rooms.EXIT, true)) { |
|
||||||
throw new WorldGenError("Could not place exit room."); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (lastLevel) { |
|
||||||
if (!map.addRoom(Rooms.BOSS, true)) { |
|
||||||
throw new WorldGenError("Could not place boss room."); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
map.addRoom(Rooms.HEART_ROOM, true); |
|
||||||
|
|
||||||
|
|
||||||
map.buildCorridors(); |
|
||||||
|
|
||||||
switch (level) { |
|
||||||
default: |
|
||||||
case 3: |
|
||||||
case 2: |
|
||||||
if (rand.nextInt(2) == 0) map.putItemInMap(Items.CLUB.createItemDamaged(30), 50); |
|
||||||
case 1: |
|
||||||
if (rand.nextInt(2) == 0) map.putItemInMap(Items.ROCK.createItemDamaged(10), 50); |
|
||||||
} |
|
||||||
|
|
||||||
if (level == 1) { |
|
||||||
map.putItemInMap(Items.BONE.createItemDamaged(20), 60); |
|
||||||
} |
|
||||||
|
|
||||||
if (level == 2) { |
|
||||||
map.putItemInMap(Items.CLUB.createItemDamaged(50), 60); |
|
||||||
} |
|
||||||
|
|
||||||
if (level == 6) { |
|
||||||
map.putItemInMap(Items.SWORD.createItemDamaged(60), 200); |
|
||||||
} |
|
||||||
|
|
||||||
if (level == 4) { |
|
||||||
map.putItemInMap(Items.HAMMER.createItemDamaged(40), 100); |
|
||||||
} |
|
||||||
|
|
||||||
// entities - random rats
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 2 + level * 2, 5 + level * 3); i++) { |
|
||||||
Entity e; |
|
||||||
|
|
||||||
if (level > 2 && rand.nextInt(level - 2 + 1) != 0) { |
|
||||||
e = Entities.RAT_BROWN.createEntity(); |
|
||||||
} else { |
|
||||||
e = Entities.RAT_GRAY.createEntity(); |
|
||||||
} |
|
||||||
|
|
||||||
map.putEntityInMap(e, 30); |
|
||||||
|
|
||||||
if (rand.nextInt(6 + level / 2) == 0) { |
|
||||||
map.putItemInMap(Items.CHEESE.createItem(), 10); |
|
||||||
} |
|
||||||
|
|
||||||
if (rand.nextInt(6) == 0) { |
|
||||||
map.putItemInMap(Items.MEAT.createItem(), 10); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
final Coord size = map.getNeededSize(); |
|
||||||
final Level lvl = new Level(size.x, size.y); |
|
||||||
lvl.setWorld(world); // important for creating entities
|
|
||||||
|
|
||||||
map.writeToLevel(lvl); |
|
||||||
|
|
||||||
return lvl; |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,28 @@ |
|||||||
|
package mightypork.rogue.world.gen; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.gen.rooms.*; |
||||||
|
import mightypork.rogue.world.item.Item; |
||||||
|
|
||||||
|
|
||||||
|
public class Rooms { |
||||||
|
|
||||||
|
public static final RoomBuilder BASIC = new BasicRoom(); |
||||||
|
public static final RoomBuilder STORAGE = new StorageRoom(); |
||||||
|
public static final RoomBuilder DEAD_END = new DeadEndRoom(); |
||||||
|
public static final RoomBuilder ENTRANCE = new EntranceRoom(); |
||||||
|
public static final RoomBuilder EXIT = new ExitRoom(); |
||||||
|
public static final RoomBuilder BOSS = new BossRoom(); |
||||||
|
|
||||||
|
|
||||||
|
public static RoomBuilder treasure(Item item) |
||||||
|
{ |
||||||
|
return new TreasureChestRoom(item); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static RoomBuilder shrine(Item item) |
||||||
|
{ |
||||||
|
return new ItemShrineRoom(item); |
||||||
|
} |
||||||
|
} |
@ -1,16 +0,0 @@ |
|||||||
package mightypork.rogue.world.gen.rooms; |
|
||||||
|
|
||||||
|
|
||||||
import mightypork.rogue.world.gen.RoomBuilder; |
|
||||||
|
|
||||||
|
|
||||||
public class Rooms { |
|
||||||
|
|
||||||
public static final RoomBuilder BASIC = new BasicRoom(); |
|
||||||
public static final RoomBuilder TREASURE = new TreasureRoom(); |
|
||||||
public static final RoomBuilder DEAD_END = new DeadEndRoom(); |
|
||||||
public static final RoomBuilder ENTRANCE = new EntranceRoom(); |
|
||||||
public static final RoomBuilder EXIT = new ExitRoom(); |
|
||||||
public static final RoomBuilder BOSS = new BossRoom(); |
|
||||||
public static final RoomBuilder HEART_ROOM = new HeartPieceRoom(); |
|
||||||
} |
|
@ -0,0 +1,50 @@ |
|||||||
|
package mightypork.rogue.world.gen.rooms; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.Calc; |
||||||
|
import mightypork.gamecore.util.math.algo.Coord; |
||||||
|
import mightypork.rogue.world.gen.MapTheme; |
||||||
|
import mightypork.rogue.world.gen.ScratchMap; |
||||||
|
import mightypork.rogue.world.item.Items; |
||||||
|
|
||||||
|
|
||||||
|
public class StorageRoom extends SecretRoom { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) |
||||||
|
{ |
||||||
|
int maxStuff = 3; |
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { |
||||||
|
map.addItemInArea(Items.SANDWICH.createItem(), min, max, 50); |
||||||
|
if (--maxStuff == 0) break; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { |
||||||
|
map.addItemInArea(Items.TWIG.createItemDamaged(40), min, max, 50); |
||||||
|
if (--maxStuff == 0) break; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { |
||||||
|
map.addItemInArea(Items.BONE.createItemDamaged(40), min, max, 50); |
||||||
|
if (--maxStuff == 0) break; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { |
||||||
|
map.addItemInArea(Items.MEAT.createItem(), min, max, 50); |
||||||
|
if (--maxStuff == 0) break; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { |
||||||
|
map.addItemInArea(Items.CHEESE.createItem(), min, max, 50); |
||||||
|
if (--maxStuff == 0) break; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { |
||||||
|
map.addItemInArea(Items.ROCK.createItemDamaged(30), min, max, 50); |
||||||
|
if (--maxStuff == 0) break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
package mightypork.rogue.world.gen.rooms; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.algo.Coord; |
||||||
|
import mightypork.rogue.world.gen.MapTheme; |
||||||
|
import mightypork.rogue.world.gen.ScratchMap; |
||||||
|
import mightypork.rogue.world.gen.TileProtectLevel; |
||||||
|
import mightypork.rogue.world.item.Item; |
||||||
|
|
||||||
|
|
||||||
|
public class TreasureChestRoom extends ItemShrineRoom { |
||||||
|
|
||||||
|
public TreasureChestRoom(Item item) |
||||||
|
{ |
||||||
|
super(item); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) |
||||||
|
{ |
||||||
|
// set tile
|
||||||
|
final Coord center = min.add(2, 2); |
||||||
|
|
||||||
|
map.set(center, theme.chest()); |
||||||
|
map.protect(center, TileProtectLevel.STRONG); |
||||||
|
|
||||||
|
// drop item
|
||||||
|
super.buildExtras(map, theme, rand, min, max); |
||||||
|
} |
||||||
|
} |
@ -1,38 +0,0 @@ |
|||||||
package mightypork.rogue.world.gen.rooms; |
|
||||||
|
|
||||||
|
|
||||||
import java.util.Random; |
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.Calc; |
|
||||||
import mightypork.gamecore.util.math.algo.Coord; |
|
||||||
import mightypork.rogue.world.gen.MapTheme; |
|
||||||
import mightypork.rogue.world.gen.ScratchMap; |
|
||||||
import mightypork.rogue.world.item.Items; |
|
||||||
|
|
||||||
|
|
||||||
public class TreasureRoom extends SecretRoom { |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) |
|
||||||
{ |
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { |
|
||||||
map.putItemInArea(Items.SANDWICH.createItem(), min, max, 50); |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { |
|
||||||
map.putItemInArea(Items.BONE.createItemDamaged(20), min, max, 50); |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { |
|
||||||
map.putItemInArea(Items.ROCK.createItemDamaged(30), min, max, 50); |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 3); i++) { |
|
||||||
map.putItemInArea(Items.MEAT.createItem(), min, max, 50); |
|
||||||
} |
|
||||||
|
|
||||||
for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { |
|
||||||
map.putItemInArea(Items.CHEESE.createItem(), min, max, 50); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,45 @@ |
|||||||
|
package mightypork.rogue.world.item.impl.weapons; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.Res; |
||||||
|
import mightypork.rogue.world.item.ItemModel; |
||||||
|
import mightypork.rogue.world.item.ItemRenderer; |
||||||
|
import mightypork.rogue.world.item.impl.ItemBaseWeapon; |
||||||
|
import mightypork.rogue.world.item.render.QuadItemRenderer; |
||||||
|
|
||||||
|
|
||||||
|
public class ItemKnife extends ItemBaseWeapon { |
||||||
|
|
||||||
|
public ItemKnife(ItemModel model) |
||||||
|
{ |
||||||
|
super(model); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected ItemRenderer makeRenderer() |
||||||
|
{ |
||||||
|
return new QuadItemRenderer(this, Res.getTxQuad("item.knife")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int getAttackPoints() |
||||||
|
{ |
||||||
|
return 4; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int getMaxUses() |
||||||
|
{ |
||||||
|
return 60; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public String getVisualName() |
||||||
|
{ |
||||||
|
return "Knife"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package mightypork.rogue.world.item.impl.weapons; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.Res; |
||||||
|
import mightypork.rogue.world.item.ItemModel; |
||||||
|
import mightypork.rogue.world.item.ItemRenderer; |
||||||
|
import mightypork.rogue.world.item.impl.ItemBaseWeapon; |
||||||
|
import mightypork.rogue.world.item.render.QuadItemRenderer; |
||||||
|
|
||||||
|
|
||||||
|
public class ItemTwig extends ItemBaseWeapon { |
||||||
|
|
||||||
|
public ItemTwig(ItemModel model) |
||||||
|
{ |
||||||
|
super(model); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected ItemRenderer makeRenderer() |
||||||
|
{ |
||||||
|
return new QuadItemRenderer(this, Res.getTxQuad("item.twig")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int getAttackPoints() |
||||||
|
{ |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int getMaxUses() |
||||||
|
{ |
||||||
|
return 10; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public String getVisualName() |
||||||
|
{ |
||||||
|
return "Twig"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
package mightypork.rogue.world.tile; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.gamecore.util.math.color.Color; |
||||||
|
import mightypork.gamecore.util.math.color.pal.RGB; |
||||||
|
|
||||||
|
|
||||||
|
public class TileColors { |
||||||
|
|
||||||
|
public static final Color NULL = RGB.NONE; |
||||||
|
public static final Color FLOOR = RGB.GRAY_DARK; |
||||||
|
public static final Color WALL = RGB.GRAY_LIGHT; |
||||||
|
public static final Color DOOR = RGB.BROWN; |
||||||
|
public static final Color COLLAPSED_WALL = RGB.GRAY; |
||||||
|
|
||||||
|
public static final Color ENTRANCE = RGB.CYAN; |
||||||
|
public static final Color EXIT = Color.fromHex(0x00EA8C); |
||||||
|
|
||||||
|
public static final Color SECRET_DOOR_REVEALED = RGB.PINK; |
||||||
|
public static final Color SECRET_DOOR_HIDDEN = WALL; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,101 @@ |
|||||||
|
package mightypork.rogue.world.tile.impl; |
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
import mightypork.gamecore.util.ion.IonInput; |
||||||
|
import mightypork.gamecore.util.ion.IonOutput; |
||||||
|
import mightypork.rogue.world.tile.TileModel; |
||||||
|
import mightypork.rogue.world.tile.TileType; |
||||||
|
|
||||||
|
|
||||||
|
public abstract class TileBaseChest extends TileWithItems { |
||||||
|
|
||||||
|
public static final double POST_OPEN_DURA = 0.3; |
||||||
|
public boolean opened = false; |
||||||
|
public boolean removed = false; |
||||||
|
public double timeSinceOpen = 10000; |
||||||
|
|
||||||
|
private int clicks = 1; |
||||||
|
|
||||||
|
|
||||||
|
public TileBaseChest(TileModel model) |
||||||
|
{ |
||||||
|
super(model); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public TileType getType() |
||||||
|
{ |
||||||
|
return TileType.FLOOR; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isWalkable() |
||||||
|
{ |
||||||
|
return removed; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected boolean shouldRenderItems() |
||||||
|
{ |
||||||
|
return removed; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onClick() |
||||||
|
{ |
||||||
|
if (opened & removed) return false; |
||||||
|
|
||||||
|
if (clicks > 0) { |
||||||
|
clicks--; |
||||||
|
|
||||||
|
if (clicks == 0) { |
||||||
|
opened = true; |
||||||
|
timeSinceOpen = 0; |
||||||
|
getWorld().getConsole().msgOpenChest(); |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
if (opened && !removed && timeSinceOpen > POST_OPEN_DURA) { |
||||||
|
removed = true; |
||||||
|
clicks--; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void save(IonOutput out) throws IOException |
||||||
|
{ |
||||||
|
super.save(out); |
||||||
|
out.writeIntByte(clicks); |
||||||
|
out.writeBoolean(opened); |
||||||
|
out.writeBoolean(removed); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void load(IonInput in) throws IOException |
||||||
|
{ |
||||||
|
super.load(in); |
||||||
|
clicks = in.readIntByte(); |
||||||
|
opened = in.readBoolean(); |
||||||
|
removed = in.readBoolean(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateTile(double delta) |
||||||
|
{ |
||||||
|
super.updateTile(delta); |
||||||
|
if (opened && timeSinceOpen < 10000) timeSinceOpen += delta; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package mightypork.rogue.world.tile.impl.brick; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.Res; |
||||||
|
import mightypork.rogue.world.tile.TileModel; |
||||||
|
import mightypork.rogue.world.tile.TileRenderer; |
||||||
|
import mightypork.rogue.world.tile.impl.TileBaseChest; |
||||||
|
import mightypork.rogue.world.tile.render.ChestRenderer; |
||||||
|
|
||||||
|
|
||||||
|
public class TileBrickChest extends TileBaseChest { |
||||||
|
|
||||||
|
public TileBrickChest(TileModel model) |
||||||
|
{ |
||||||
|
super(model); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected TileRenderer makeRenderer() |
||||||
|
{ |
||||||
|
return new ChestRenderer(this, Res.getTxQuad("tile.brick.floor"), Res.getTxQuad("tile.extra.chest.closed"), Res.getTxQuad("tile.extra.chest.open")); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
package mightypork.rogue.world.tile.render; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.gamecore.render.Render; |
||||||
|
import mightypork.gamecore.resources.textures.TxQuad; |
||||||
|
import mightypork.rogue.world.level.render.TileRenderContext; |
||||||
|
import mightypork.rogue.world.tile.TileRenderer; |
||||||
|
import mightypork.rogue.world.tile.impl.TileBaseChest; |
||||||
|
|
||||||
|
|
||||||
|
public class ChestRenderer extends TileRenderer { |
||||||
|
|
||||||
|
private final TxQuad txqFloor; |
||||||
|
private final TxQuad txqChest; |
||||||
|
|
||||||
|
private final TileBaseChest chestTile; |
||||||
|
private final TxQuad txqChestOpen; |
||||||
|
|
||||||
|
|
||||||
|
public ChestRenderer(TileBaseChest tile, TxQuad txq, TxQuad chest, TxQuad chestOpen) |
||||||
|
{ |
||||||
|
super(tile); |
||||||
|
|
||||||
|
this.chestTile = tile; |
||||||
|
|
||||||
|
this.txqFloor = txq; |
||||||
|
this.txqChest = chest; |
||||||
|
this.txqChestOpen = chestOpen; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void renderTile(TileRenderContext context) |
||||||
|
{ |
||||||
|
Render.quadTextured(context.getRect(), txqFloor); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void renderExtra(TileRenderContext context) |
||||||
|
{ |
||||||
|
if (!chestTile.opened) { |
||||||
|
Render.quadTextured(context.getRect(), txqChest); |
||||||
|
} else { |
||||||
|
if (!chestTile.removed) { |
||||||
|
Render.quadTextured(context.getRect(), txqChestOpen); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue