World gen rewrite, big cleanup, new items & Chest tile.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.5 KiB |
Binary file not shown.
@@ -21,7 +21,7 @@ import mightypork.gamecore.util.annot.DefaultImpl;
|
|||||||
import mightypork.gamecore.util.files.InstanceLock;
|
import mightypork.gamecore.util.files.InstanceLock;
|
||||||
import mightypork.gamecore.util.ion.Ion;
|
import mightypork.gamecore.util.ion.Ion;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,7 +153,7 @@ public abstract class BaseApp implements AppAccess, UncaughtExceptionHandler {
|
|||||||
protected void registerIonizables()
|
protected void registerIonizables()
|
||||||
{
|
{
|
||||||
Ion.registerType(Coord.ION_MARK, Coord.class);
|
Ion.registerType(Coord.ION_MARK, Coord.class);
|
||||||
Ion.registerType(Step.ION_MARK, Step.class);
|
Ion.registerType(Move.ION_MARK, Move.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import mightypork.gamecore.eventbus.event_flags.ImmediateEvent;
|
|||||||
import mightypork.gamecore.eventbus.event_flags.NotLoggedEvent;
|
import mightypork.gamecore.eventbus.event_flags.NotLoggedEvent;
|
||||||
import mightypork.gamecore.eventbus.events.Destroyable;
|
import mightypork.gamecore.eventbus.events.Destroyable;
|
||||||
import mightypork.gamecore.logging.Log;
|
import mightypork.gamecore.logging.Log;
|
||||||
|
import mightypork.gamecore.util.Utils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,10 +143,6 @@ final public class EventBus implements Destroyable, BusAccess {
|
|||||||
/** Messages queued for delivery */
|
/** Messages queued for delivery */
|
||||||
private final DelayQueue<DelayQueueEntry> sendQueue = new DelayQueue<>();
|
private final DelayQueue<DelayQueueEntry> sendQueue = new DelayQueue<>();
|
||||||
|
|
||||||
private volatile boolean sendingDirect = false;
|
|
||||||
|
|
||||||
private BusEvent<?> lastEvt;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a new bus and start it's queue thread.
|
* Make a new bus and start it's queue thread.
|
||||||
@@ -180,13 +177,13 @@ final public class EventBus implements Destroyable, BusAccess {
|
|||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
final DelayedEvent adelay = event.getClass().getAnnotation(DelayedEvent.class);
|
final DelayedEvent adelay = Utils.getAnnotation(event, DelayedEvent.class);
|
||||||
if (adelay != null) {
|
if (adelay != null) {
|
||||||
sendDelayed(event, adelay.delay());
|
sendDelayed(event, adelay.delay());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getClass().isAnnotationPresent(ImmediateEvent.class)) {
|
if (Utils.hasAnnotation(event, ImmediateEvent.class)) {
|
||||||
sendDirect(event);
|
sendDirect(event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -364,7 +361,6 @@ final public class EventBus implements Destroyable, BusAccess {
|
|||||||
|
|
||||||
for (int i = 0; i < 2; i++) { // two tries.
|
for (int i = 0; i < 2; i++) { // two tries.
|
||||||
|
|
||||||
// channels.setBuffering(true);
|
|
||||||
for (final EventChannel<?, ?> b : channels) {
|
for (final EventChannel<?, ?> b : channels) {
|
||||||
if (b.canBroadcast(event)) {
|
if (b.canBroadcast(event)) {
|
||||||
accepted = true;
|
accepted = true;
|
||||||
@@ -373,7 +369,6 @@ final public class EventBus implements Destroyable, BusAccess {
|
|||||||
|
|
||||||
if (event.isConsumed()) break;
|
if (event.isConsumed()) break;
|
||||||
}
|
}
|
||||||
// channels.setBuffering(false);
|
|
||||||
|
|
||||||
if (!accepted) if (addChannelForEvent(event)) continue;
|
if (!accepted) if (addChannelForEvent(event)) continue;
|
||||||
|
|
||||||
@@ -388,7 +383,7 @@ final public class EventBus implements Destroyable, BusAccess {
|
|||||||
private boolean shallLog(BusEvent<?> event)
|
private boolean shallLog(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
if (!detailedLogging) return false;
|
if (!detailedLogging) return false;
|
||||||
if (event.getClass().isAnnotationPresent(NotLoggedEvent.class)) return false;
|
if (Utils.hasAnnotation(event, NotLoggedEvent.class)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package mightypork.gamecore.util;
|
package mightypork.gamecore.util;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assorted utils
|
* Assorted utils
|
||||||
*
|
*
|
||||||
@@ -14,4 +17,32 @@ public final class Utils {
|
|||||||
t.start();
|
t.start();
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean hasAnnotation(Object tested, Class<? extends Annotation> annotation)
|
||||||
|
{
|
||||||
|
return tested.getClass().isAnnotationPresent(annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static <T extends Annotation> T getAnnotation(Object tested, Class<T> annotation)
|
||||||
|
{
|
||||||
|
return tested.getClass().getAnnotation(annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick first non-null option
|
||||||
|
*
|
||||||
|
* @param options options
|
||||||
|
* @return the selected option
|
||||||
|
*/
|
||||||
|
public static Object fallback(Object... options)
|
||||||
|
{
|
||||||
|
for (final Object o : options) {
|
||||||
|
if (o != null) return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // all null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
package mightypork.gamecore.util.error;
|
package mightypork.gamecore.util.error;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a invalid value is given to a method, or found in a data object /
|
||||||
|
* file etc
|
||||||
|
*
|
||||||
|
* @author MightyPork
|
||||||
|
*/
|
||||||
public class IllegalValueException extends RuntimeException {
|
public class IllegalValueException extends RuntimeException {
|
||||||
|
|
||||||
public IllegalValueException()
|
public IllegalValueException()
|
||||||
@@ -25,10 +31,4 @@ public class IllegalValueException extends RuntimeException {
|
|||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IllegalValueException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
|
|
||||||
{
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
package mightypork.gamecore.util.error;
|
package mightypork.gamecore.util.error;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown by a map-like class when the key specified is already taken.
|
||||||
|
*
|
||||||
|
* @author MightyPork
|
||||||
|
*/
|
||||||
public class KeyAlreadyExistsException extends RuntimeException {
|
public class KeyAlreadyExistsException extends RuntimeException {
|
||||||
|
|
||||||
public KeyAlreadyExistsException()
|
public KeyAlreadyExistsException()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import mightypork.gamecore.util.error.CorruptedDataException;
|
import mightypork.gamecore.util.error.CorruptDataException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -360,7 +360,7 @@ public class IonInput {
|
|||||||
return readStrings();
|
return readStrings();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new CorruptedDataException("Invalid mark: " + mark);
|
throw new CorruptDataException("Invalid mark: " + mark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,7 +378,7 @@ public class IonInput {
|
|||||||
if (mark == Ion.ENTRY) return true;
|
if (mark == Ion.ENTRY) return true;
|
||||||
if (mark == Ion.END) return false;
|
if (mark == Ion.END) return false;
|
||||||
|
|
||||||
throw new CorruptedDataException("Unexpected mark in sequence: " + mark);
|
throw new CorruptDataException("Unexpected mark in sequence: " + mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -411,7 +411,7 @@ public class IonInput {
|
|||||||
}
|
}
|
||||||
return filled;
|
return filled;
|
||||||
} catch (final ClassCastException e) {
|
} catch (final ClassCastException e) {
|
||||||
throw new CorruptedDataException("Unexpected element type in sequence.", e);
|
throw new CorruptDataException("Unexpected element type in sequence.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +448,7 @@ public class IonInput {
|
|||||||
}
|
}
|
||||||
return filled;
|
return filled;
|
||||||
} catch (final ClassCastException e) {
|
} catch (final ClassCastException e) {
|
||||||
throw new CorruptedDataException("Unexpected element type in map.", e);
|
throw new CorruptDataException("Unexpected element type in map.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -619,6 +619,19 @@ public class Calc {
|
|||||||
* @return picked element
|
* @return picked element
|
||||||
*/
|
*/
|
||||||
public static <T> T pick(List<T> list)
|
public static <T> T pick(List<T> list)
|
||||||
|
{
|
||||||
|
return pick(rand, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick random element from a given list.
|
||||||
|
*
|
||||||
|
* @param rand RNG
|
||||||
|
* @param list list of choices
|
||||||
|
* @return picked element
|
||||||
|
*/
|
||||||
|
public static <T> T pick(Random rand, List<T> list)
|
||||||
{
|
{
|
||||||
if (list.size() == 0) return null;
|
if (list.size() == 0) return null;
|
||||||
return list.get(rand.nextInt(list.size()));
|
return list.get(rand.nextInt(list.size()));
|
||||||
@@ -718,4 +731,14 @@ public class Calc {
|
|||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int countBits(byte b)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
c += (b >> i) & 1;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package mightypork.gamecore.util.math;
|
package mightypork.gamecore.util.math;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numeric range, able to generate random numbers and give min/max values.
|
* Numeric range, able to generate random numbers and give min/max values.
|
||||||
*
|
*
|
||||||
@@ -71,7 +74,7 @@ public class Range {
|
|||||||
*/
|
*/
|
||||||
public int randInt()
|
public int randInt()
|
||||||
{
|
{
|
||||||
return Calc.randInt(Calc.rand, (int) Math.round(min), (int) Math.round(min));
|
return randInt(Calc.rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -82,7 +85,31 @@ public class Range {
|
|||||||
*/
|
*/
|
||||||
public double randDouble()
|
public double randDouble()
|
||||||
{
|
{
|
||||||
return min + Calc.rand.nextDouble() * (max - min);
|
return randDouble(Calc.rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get random integer from range
|
||||||
|
*
|
||||||
|
* @param rand RNG
|
||||||
|
* @return random int
|
||||||
|
*/
|
||||||
|
public int randInt(Random rand)
|
||||||
|
{
|
||||||
|
return Calc.randInt(rand, (int) Math.round(min), (int) Math.round(min));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get random double from this range
|
||||||
|
*
|
||||||
|
* @param rand RNG
|
||||||
|
* @return random double
|
||||||
|
*/
|
||||||
|
public double randDouble(Random rand)
|
||||||
|
{
|
||||||
|
return min + rand.nextDouble() * (max - min);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class Coord implements IonObjBundled, IonObjBinary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord add(Step added)
|
public Coord add(Move added)
|
||||||
{
|
{
|
||||||
return add(added.x(), added.y());
|
return add(added.x(), added.y());
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -16,18 +16,18 @@ import mightypork.gamecore.util.ion.IonOutput;
|
|||||||
*
|
*
|
||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
public class Step implements IonObjBinary, IonObjBundled {
|
public class Move implements IonObjBinary, IonObjBundled {
|
||||||
|
|
||||||
public static final int ION_MARK = 254;
|
public static final int ION_MARK = 254;
|
||||||
|
|
||||||
public static final Step NORTH = new Step(0, -1);
|
public static final Move NORTH = new Move(0, -1);
|
||||||
public static final Step SOUTH = new Step(0, 1);
|
public static final Move SOUTH = new Move(0, 1);
|
||||||
public static final Step EAST = new Step(1, 0);
|
public static final Move EAST = new Move(1, 0);
|
||||||
public static final Step WEST = new Step(-1, 0);
|
public static final Move WEST = new Move(-1, 0);
|
||||||
public static final Step NONE = new Step(0, 0);
|
public static final Move NONE = new Move(0, 0);
|
||||||
|
|
||||||
|
|
||||||
public static Step make(int x, int y)
|
public static Move make(int x, int y)
|
||||||
{
|
{
|
||||||
x = x < 0 ? -1 : x > 0 ? 1 : 0;
|
x = x < 0 ? -1 : x > 0 ? 1 : 0;
|
||||||
y = y < 0 ? -1 : y > 0 ? 1 : 0;
|
y = y < 0 ? -1 : y > 0 ? 1 : 0;
|
||||||
@@ -38,20 +38,20 @@ public class Step implements IonObjBinary, IonObjBundled {
|
|||||||
if (x == 1 && y == 0) return EAST;
|
if (x == 1 && y == 0) return EAST;
|
||||||
if (x == 0 && y == 0) return NONE;
|
if (x == 0 && y == 0) return NONE;
|
||||||
|
|
||||||
return new Step(x, y);
|
return new Move(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte x;
|
private byte x;
|
||||||
private byte y;
|
private byte y;
|
||||||
|
|
||||||
|
|
||||||
public Step()
|
public Move()
|
||||||
{
|
{
|
||||||
// for ion
|
// for ion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Step(int x, int y)
|
public Move(int x, int y)
|
||||||
{
|
{
|
||||||
this.x = (byte) (x < 0 ? -1 : x > 0 ? 1 : 0);
|
this.x = (byte) (x < 0 ? -1 : x > 0 ? 1 : 0);
|
||||||
this.y = (byte) (y < 0 ? -1 : y > 0 ? 1 : 0);
|
this.y = (byte) (y < 0 ? -1 : y > 0 ? 1 : 0);
|
||||||
@@ -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)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,10 +3,11 @@ package mightypork.gamecore.util.math.algo.floodfill;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
|
|
||||||
|
|
||||||
public abstract class FloodFill {
|
public abstract class FloodFill {
|
||||||
@@ -17,7 +18,7 @@ public abstract class FloodFill {
|
|||||||
public abstract boolean canSpreadFrom(Coord pos);
|
public abstract boolean canSpreadFrom(Coord pos);
|
||||||
|
|
||||||
|
|
||||||
public abstract Step[] getSpreadSides();
|
public abstract List<Move> getSpreadSides();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,7 +50,6 @@ public abstract class FloodFill {
|
|||||||
|
|
||||||
activeNodes.add(start);
|
activeNodes.add(start);
|
||||||
|
|
||||||
final Step[] sides = getSpreadSides();
|
|
||||||
boolean forceSpreadNext = forceSpreadStart();
|
boolean forceSpreadNext = forceSpreadStart();
|
||||||
|
|
||||||
boolean limitReached = false;
|
boolean limitReached = false;
|
||||||
@@ -62,7 +62,7 @@ public abstract class FloodFill {
|
|||||||
|
|
||||||
forceSpreadNext = false;
|
forceSpreadNext = false;
|
||||||
|
|
||||||
for (final Step spr : sides) {
|
for (final Move spr : getSpreadSides()) {
|
||||||
final Coord next = current.add(spr);
|
final Coord next = current.add(spr);
|
||||||
if (activeNodes.contains(next) || foundNodes.contains(next)) continue;
|
if (activeNodes.contains(next) || foundNodes.contains(next)) continue;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.heuristics.DiagonalHeuristic;
|
import mightypork.gamecore.util.math.algo.pathfinding.heuristics.DiagonalHeuristic;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.heuristics.ManhattanHeuristic;
|
import mightypork.gamecore.util.math.algo.pathfinding.heuristics.ManhattanHeuristic;
|
||||||
|
|
||||||
@@ -29,24 +29,24 @@ public abstract class PathFinder {
|
|||||||
private boolean ignoreEnd;
|
private boolean ignoreEnd;
|
||||||
|
|
||||||
|
|
||||||
public List<Step> findPathRelative(Coord start, Coord end)
|
public List<Move> findPathRelative(Coord start, Coord end)
|
||||||
{
|
{
|
||||||
return findPathRelative(start, end, ignoreStart, ignoreEnd);
|
return findPathRelative(start, end, ignoreStart, ignoreEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<Step> findPathRelative(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
public List<Move> findPathRelative(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
||||||
{
|
{
|
||||||
final List<Coord> path = findPath(start, end, ignoreStart, ignoreEnd);
|
final List<Coord> path = findPath(start, end, ignoreStart, ignoreEnd);
|
||||||
|
|
||||||
if (path == null) return null;
|
if (path == null) return null;
|
||||||
|
|
||||||
final List<Step> out = new ArrayList<>();
|
final List<Move> out = new ArrayList<>();
|
||||||
|
|
||||||
final Coord current = start.copy();
|
final Coord current = start.copy();
|
||||||
for (final Coord c : path) {
|
for (final Coord c : path) {
|
||||||
if (c.equals(current)) continue;
|
if (c.equals(current)) continue;
|
||||||
out.add(Step.make(c.x - current.x, c.y - current.y));
|
out.add(Move.make(c.x - current.x, c.y - current.y));
|
||||||
current.x = c.x;
|
current.x = c.x;
|
||||||
current.y = c.y;
|
current.y = c.y;
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,6 @@ public abstract class PathFinder {
|
|||||||
open.add(n);
|
open.add(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Step[] walkDirs = getWalkSides();
|
|
||||||
|
|
||||||
Node current = null;
|
Node current = null;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -93,7 +91,7 @@ public abstract class PathFinder {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Step go : walkDirs) {
|
for (final Move go : getWalkSides()) {
|
||||||
|
|
||||||
final Coord c = current.pos.add(go);
|
final Coord c = current.pos.add(go);
|
||||||
if (!isAccessible(c) && !(c.equals(end) && ignoreEnd) && !(c.equals(start) && ignoreStart)) continue;
|
if (!isAccessible(c) && !(c.equals(end) && ignoreEnd) && !(c.equals(start) && ignoreStart)) continue;
|
||||||
@@ -225,7 +223,7 @@ public abstract class PathFinder {
|
|||||||
protected abstract Heuristic getHeuristic();
|
protected abstract Heuristic getHeuristic();
|
||||||
|
|
||||||
|
|
||||||
protected abstract Step[] getWalkSides();
|
protected abstract List<Move> getWalkSides();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package mightypork.gamecore.util.math.algo.pathfinding;
|
package mightypork.gamecore.util.math.algo.pathfinding;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,7 +53,7 @@ public class PathFinderProxy extends PathFinder {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Step[] getWalkSides()
|
protected List<Move> getWalkSides()
|
||||||
{
|
{
|
||||||
return source.getWalkSides();
|
return source.getWalkSides();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import mightypork.gamecore.util.math.color.Color;
|
|||||||
*
|
*
|
||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
public interface COMMODORE {
|
public interface CMDR {
|
||||||
|
|
||||||
Color BLACK = Color.fromHex(0x040013);
|
Color BLACK = Color.fromHex(0x040013);
|
||||||
Color WHITE = Color.fromHex(0xFFFFFF);
|
Color WHITE = Color.fromHex(0xFFFFFF);
|
||||||
@@ -38,6 +38,7 @@ public class RGB {
|
|||||||
|
|
||||||
public static final Color PINK = Color.fromHex(0xFF3FFC);
|
public static final Color PINK = Color.fromHex(0xFF3FFC);
|
||||||
public static final Color ORANGE = Color.fromHex(0xFC4800);
|
public static final Color ORANGE = Color.fromHex(0xFC4800);
|
||||||
|
public static final Color BROWN = Color.fromHex(0x83501B);
|
||||||
|
|
||||||
public static final Color NONE = Color.rgba(0, 0, 0, 0);
|
public static final Color NONE = Color.rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,7 +50,7 @@ public final class GameLoop extends MainLoop implements ActionRequest.Listener {
|
|||||||
@Override
|
@Override
|
||||||
public void execute()
|
public void execute()
|
||||||
{
|
{
|
||||||
Res.getEffect("gui.shutter").play(1);
|
Res.getSoundEffect("gui.shutter").play(1);
|
||||||
Utils.runAsThread(new TaskTakeScreenshot());
|
Utils.runAsThread(new TaskTakeScreenshot());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -60,9 +60,8 @@ public final class Res {
|
|||||||
fonts.loadFont("tinyutf", font = new DeferredFont("/res/font/TinyUnicode2.ttf", Glyphs.basic, 16));
|
fonts.loadFont("tinyutf", font = new DeferredFont("/res/font/TinyUnicode2.ttf", Glyphs.basic, 16));
|
||||||
font.setDiscardRatio(6 / 16D, 2 / 16D);
|
font.setDiscardRatio(6 / 16D, 2 / 16D);
|
||||||
|
|
||||||
// aliases based on concrete usage
|
// aliases
|
||||||
fonts.addAlias("thick", "press_start");
|
fonts.addAlias("thick", "press_start");
|
||||||
|
|
||||||
fonts.addAlias("thin", "battlenet");
|
fonts.addAlias("thin", "battlenet");
|
||||||
fonts.addAlias("tiny", "tinyutf");
|
fonts.addAlias("tiny", "tinyutf");
|
||||||
}
|
}
|
||||||
@@ -135,6 +134,8 @@ public final class Res {
|
|||||||
textures.add("tile.brick.passage", grid.makeSheet(3, 2, 4, 1));
|
textures.add("tile.brick.passage", grid.makeSheet(3, 2, 4, 1));
|
||||||
textures.add("tile.brick.stairs.up", grid.makeQuad(0, 6));
|
textures.add("tile.brick.stairs.up", grid.makeQuad(0, 6));
|
||||||
textures.add("tile.brick.stairs.down", grid.makeQuad(1, 6));
|
textures.add("tile.brick.stairs.down", grid.makeQuad(1, 6));
|
||||||
|
textures.add("tile.extra.chest.closed", grid.makeQuad(0, 4));
|
||||||
|
textures.add("tile.extra.chest.open", grid.makeQuad(1, 4));
|
||||||
|
|
||||||
// shadows
|
// shadows
|
||||||
textures.add("tile.shadow.n", grid.makeQuad(0, 7));
|
textures.add("tile.shadow.n", grid.makeQuad(0, 7));
|
||||||
@@ -165,12 +166,14 @@ public final class Res {
|
|||||||
textures.add("item.meat", grid.makeQuad(0, 0));
|
textures.add("item.meat", grid.makeQuad(0, 0));
|
||||||
textures.add("item.club", grid.makeQuad(1, 0));
|
textures.add("item.club", grid.makeQuad(1, 0));
|
||||||
textures.add("item.sword", grid.makeQuad(2, 0));
|
textures.add("item.sword", grid.makeQuad(2, 0));
|
||||||
textures.add("item.hammer", grid.makeQuad(3, 0));
|
textures.add("item.axe", grid.makeQuad(3, 0));
|
||||||
textures.add("item.stone", grid.makeQuad(4, 0));
|
textures.add("item.stone", grid.makeQuad(4, 0));
|
||||||
textures.add("item.bone", grid.makeQuad(5, 0));
|
textures.add("item.bone", grid.makeQuad(5, 0));
|
||||||
textures.add("item.cheese", grid.makeQuad(6, 0));
|
textures.add("item.cheese", grid.makeQuad(6, 0));
|
||||||
textures.add("item.sandwich", grid.makeQuad(7, 0));
|
textures.add("item.sandwich", grid.makeQuad(7, 0));
|
||||||
textures.add("item.heart_piece", grid.makeQuad(0, 1));
|
textures.add("item.heart_piece", grid.makeQuad(0, 1));
|
||||||
|
textures.add("item.knife", grid.makeQuad(1, 1));
|
||||||
|
textures.add("item.twig", grid.makeQuad(2, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -192,7 +195,7 @@ public final class Res {
|
|||||||
* @param key
|
* @param key
|
||||||
* @return sheet
|
* @return sheet
|
||||||
*/
|
*/
|
||||||
public static TxSheet txs(String key)
|
public static TxSheet getTxSheet(String key)
|
||||||
{
|
{
|
||||||
return textures.getSheet(key);
|
return textures.getSheet(key);
|
||||||
}
|
}
|
||||||
@@ -204,19 +207,19 @@ public final class Res {
|
|||||||
* @param key
|
* @param key
|
||||||
* @return quad
|
* @return quad
|
||||||
*/
|
*/
|
||||||
public static TxQuad txq(String key)
|
public static TxQuad getTxQuad(String key)
|
||||||
{
|
{
|
||||||
return textures.getQuad(key);
|
return textures.getQuad(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static LoopPlayer getLoop(String key)
|
public static LoopPlayer getSoundLoop(String key)
|
||||||
{
|
{
|
||||||
return sounds.getLoop(key);
|
return sounds.getLoop(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static EffectPlayer getEffect(String key)
|
public static EffectPlayer getSoundEffect(String key)
|
||||||
{
|
{
|
||||||
return sounds.getEffect(key);
|
return sounds.getEffect(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ public class HudLayer extends ScreenLayer {
|
|||||||
final HeartBar hearts = new HeartBar(
|
final HeartBar hearts = new HeartBar(
|
||||||
playerHealthTotal,
|
playerHealthTotal,
|
||||||
playerHealthActive,
|
playerHealthActive,
|
||||||
Res.txq("hud.heart.on"),
|
Res.getTxQuad("hud.heart.on"),
|
||||||
Res.txq("hud.heart.half"),
|
Res.getTxQuad("hud.heart.half"),
|
||||||
Res.txq("hud.heart.off"),
|
Res.getTxQuad("hud.heart.off"),
|
||||||
AlignX.LEFT);
|
AlignX.LEFT);
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
@@ -117,13 +117,13 @@ public class HudLayer extends ScreenLayer {
|
|||||||
|
|
||||||
NavButton btn;
|
NavButton btn;
|
||||||
|
|
||||||
nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.inventory")));
|
nav.addRight(btn = new NavButton(Res.getTxQuad("nav.button.fg.inventory")));
|
||||||
btn.setAction(gameScreen.actionToggleInv);
|
btn.setAction(gameScreen.actionToggleInv);
|
||||||
|
|
||||||
nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.eat")));
|
nav.addRight(btn = new NavButton(Res.getTxQuad("nav.button.fg.eat")));
|
||||||
btn.setAction(gameScreen.actionEat);
|
btn.setAction(gameScreen.actionEat);
|
||||||
|
|
||||||
nav.addRight(btn = new NavButton(Res.txq("nav.button.fg.pause")));
|
nav.addRight(btn = new NavButton(Res.getTxQuad("nav.button.fg.pause")));
|
||||||
btn.setAction(gameScreen.actionTogglePause);
|
btn.setAction(gameScreen.actionTogglePause);
|
||||||
|
|
||||||
|
|
||||||
@@ -131,19 +131,19 @@ public class HudLayer extends ScreenLayer {
|
|||||||
//nav.addLeft(new NavButton(Res.txq("nav.button.fg.options")));
|
//nav.addLeft(new NavButton(Res.txq("nav.button.fg.options")));
|
||||||
//nav.addLeft(new NavButton(Res.txq("nav.button.fg.help")));
|
//nav.addLeft(new NavButton(Res.txq("nav.button.fg.help")));
|
||||||
|
|
||||||
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.menu")));
|
nav.addLeft(btn = new NavButton(Res.getTxQuad("nav.button.fg.menu")));
|
||||||
btn.setAction(gameScreen.actionMenu);
|
btn.setAction(gameScreen.actionMenu);
|
||||||
|
|
||||||
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.save")));
|
nav.addLeft(btn = new NavButton(Res.getTxQuad("nav.button.fg.save")));
|
||||||
btn.setAction(gameScreen.actionSave);
|
btn.setAction(gameScreen.actionSave);
|
||||||
|
|
||||||
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.load")));
|
nav.addLeft(btn = new NavButton(Res.getTxQuad("nav.button.fg.load")));
|
||||||
btn.setAction(gameScreen.actionLoad);
|
btn.setAction(gameScreen.actionLoad);
|
||||||
|
|
||||||
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.map")));
|
nav.addLeft(btn = new NavButton(Res.getTxQuad("nav.button.fg.map")));
|
||||||
btn.setAction(gameScreen.actionToggleMinimap);
|
btn.setAction(gameScreen.actionToggleMinimap);
|
||||||
|
|
||||||
nav.addLeft(btn = new NavButton(Res.txq("nav.button.fg.magnify")));
|
nav.addLeft(btn = new NavButton(Res.getTxQuad("nav.button.fg.magnify")));
|
||||||
btn.setAction(gameScreen.actionToggleZoom);
|
btn.setAction(gameScreen.actionToggleZoom);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class IngameNav extends LayoutComponent {
|
|||||||
|
|
||||||
paintHelper = leftEdge().growRight(height().mul(4));
|
paintHelper = leftEdge().growRight(height().mul(4));
|
||||||
|
|
||||||
bg = Res.txq("nav.bg");
|
bg = Res.getTxQuad("nav.bg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ public class InvSlot extends ClickableComponent {
|
|||||||
public InvSlot(int index, InvSlot[] allSlots)
|
public InvSlot(int index, InvSlot[] allSlots)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.txBase = Res.txq("inv.slot.base");
|
this.txBase = Res.getTxQuad("inv.slot.base");
|
||||||
this.txSelected = Res.txq("inv.slot.selected");
|
this.txSelected = Res.getTxQuad("inv.slot.selected");
|
||||||
|
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.slots = allSlots;
|
this.slots = allSlots;
|
||||||
|
|||||||
+3
-13
@@ -22,7 +22,7 @@ import mightypork.rogue.world.item.Item;
|
|||||||
import mightypork.rogue.world.item.ItemType;
|
import mightypork.rogue.world.item.ItemType;
|
||||||
|
|
||||||
|
|
||||||
public class InvLayer extends ScreenLayer {
|
public class InventoryLayer extends ScreenLayer {
|
||||||
|
|
||||||
private static final int SLOT_COUNT = 8;
|
private static final int SLOT_COUNT = 8;
|
||||||
private static final int SLOT_ROW = 4;
|
private static final int SLOT_ROW = 4;
|
||||||
@@ -86,7 +86,7 @@ public class InvLayer extends ScreenLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public InvLayer(final ScreenGame screen)
|
public InventoryLayer(final ScreenGame screen)
|
||||||
{
|
{
|
||||||
super(screen);
|
super(screen);
|
||||||
|
|
||||||
@@ -200,17 +200,7 @@ public class InvLayer extends ScreenLayer {
|
|||||||
|
|
||||||
final int selected = getSelectedSlot();
|
final int selected = getSelectedSlot();
|
||||||
if (selected != -1) {
|
if (selected != -1) {
|
||||||
final PlayerFacade pl = WorldProvider.get().getPlayer();
|
WorldProvider.get().getPlayer().dropItem(selected);
|
||||||
final Item itm = pl.getInventory().getItem(selected);
|
|
||||||
if (itm != null && !itm.isEmpty()) {
|
|
||||||
|
|
||||||
final Item piece = itm.split(1);
|
|
||||||
if (itm.isEmpty()) pl.getInventory().setItem(selected, null);
|
|
||||||
|
|
||||||
if (!pl.getLevel().getTile(pl.getCoord()).dropItem(piece)) {
|
|
||||||
pl.getInventory().addItem(piece); // add back
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -20,9 +20,9 @@ public class NavButton extends ClickableComponent {
|
|||||||
public NavButton(TxQuad fg)
|
public NavButton(TxQuad fg)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.base = Res.txq("nav.button.bg.base");
|
this.base = Res.getTxQuad("nav.button.bg.base");
|
||||||
this.hover = Res.txq("nav.button.bg.hover");
|
this.hover = Res.getTxQuad("nav.button.bg.hover");
|
||||||
this.down = Res.txq("nav.button.bg.down");
|
this.down = Res.getTxQuad("nav.button.bg.down");
|
||||||
this.fg = fg;
|
this.fg = fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import mightypork.gamecore.gui.screens.LayeredScreen;
|
|||||||
import mightypork.gamecore.input.KeyStroke;
|
import mightypork.gamecore.input.KeyStroke;
|
||||||
import mightypork.gamecore.input.Keys;
|
import mightypork.gamecore.input.Keys;
|
||||||
import mightypork.gamecore.logging.Log;
|
import mightypork.gamecore.logging.Log;
|
||||||
import mightypork.gamecore.util.math.Calc;
|
|
||||||
import mightypork.rogue.Config;
|
import mightypork.rogue.Config;
|
||||||
import mightypork.rogue.GameStateManager.GameState;
|
import mightypork.rogue.GameStateManager.GameState;
|
||||||
import mightypork.rogue.events.GameStateRequest;
|
import mightypork.rogue.events.GameStateRequest;
|
||||||
@@ -32,7 +31,7 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
WORLD, INV;
|
WORLD, INV;
|
||||||
}
|
}
|
||||||
|
|
||||||
private InvLayer invLayer;
|
private InventoryLayer invLayer;
|
||||||
private HudLayer hudLayer;
|
private HudLayer hudLayer;
|
||||||
|
|
||||||
private WorldLayer worldLayer;
|
private WorldLayer worldLayer;
|
||||||
@@ -131,6 +130,17 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public Action actionDropLastPickedItem = new Action() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute()
|
||||||
|
{
|
||||||
|
final PlayerFacade pl = WorldProvider.get().getPlayer();
|
||||||
|
if (pl.isDead() || pl.getWorld().isPaused()) return;
|
||||||
|
pl.dropItem(pl.getInventory().getLastAddIndex());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set gui state (overlay)
|
* Set gui state (overlay)
|
||||||
@@ -175,7 +185,7 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
{
|
{
|
||||||
super(app);
|
super(app);
|
||||||
|
|
||||||
addLayer(invLayer = new InvLayer(this));
|
addLayer(invLayer = new InventoryLayer(this));
|
||||||
invLayer.setEnabled(false);
|
invLayer.setEnabled(false);
|
||||||
invLayer.setVisible(false);
|
invLayer.setVisible(false);
|
||||||
|
|
||||||
@@ -187,29 +197,18 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
worldLayer.setEnabled(true);
|
worldLayer.setEnabled(true);
|
||||||
worldLayer.setVisible(true);
|
worldLayer.setVisible(true);
|
||||||
|
|
||||||
// TODO temporary, remove
|
|
||||||
bindKey(new KeyStroke(Keys.N, Keys.MOD_CONTROL), new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
WorldProvider.get().createWorld(Calc.rand.nextLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//pause key
|
//pause key
|
||||||
bindKey(new KeyStroke(Keys.P), actionTogglePause);
|
bindKey(new KeyStroke(Keys.P), actionTogglePause);
|
||||||
bindKey(new KeyStroke(Keys.PAUSE), actionTogglePause);
|
bindKey(new KeyStroke(Keys.PAUSE), actionTogglePause);
|
||||||
bindKey(new KeyStroke(Keys.SPACE), actionTogglePause);
|
bindKey(new KeyStroke(Keys.SPACE), actionTogglePause);
|
||||||
|
|
||||||
bindKey(new KeyStroke(Keys.I), actionToggleInv);
|
bindKey(new KeyStroke(Keys.I), actionToggleInv);
|
||||||
|
bindKey(new KeyStroke(Keys.D), actionDropLastPickedItem);
|
||||||
bindKey(new KeyStroke(Keys.E), actionEat);
|
bindKey(new KeyStroke(Keys.E), actionEat);
|
||||||
bindKey(new KeyStroke(Keys.M), actionToggleMinimap);
|
bindKey(new KeyStroke(Keys.M), actionToggleMinimap);
|
||||||
bindKey(new KeyStroke(Keys.Z), actionToggleZoom);
|
bindKey(new KeyStroke(Keys.Z), actionToggleZoom);
|
||||||
|
|
||||||
bindKey(new KeyStroke(Keys.R, Keys.MOD_CONTROL), actionLoad);
|
|
||||||
bindKey(new KeyStroke(Keys.L, Keys.MOD_CONTROL), actionLoad);
|
bindKey(new KeyStroke(Keys.L, Keys.MOD_CONTROL), actionLoad);
|
||||||
|
|
||||||
bindKey(new KeyStroke(Keys.S, Keys.MOD_CONTROL), actionSave);
|
bindKey(new KeyStroke(Keys.S, Keys.MOD_CONTROL), actionSave);
|
||||||
|
|
||||||
// add as actions - enableables.
|
// add as actions - enableables.
|
||||||
@@ -224,11 +223,12 @@ public class ScreenGame extends LayeredScreen {
|
|||||||
worldActions.add(actionSave);
|
worldActions.add(actionSave);
|
||||||
worldActions.add(actionLoad);
|
worldActions.add(actionLoad);
|
||||||
worldActions.add(actionMenu);
|
worldActions.add(actionMenu);
|
||||||
|
worldActions.add(actionDropLastPickedItem);
|
||||||
|
|
||||||
worldActions.setEnabled(true);
|
worldActions.setEnabled(true);
|
||||||
|
|
||||||
// TMP TODO remove
|
// CHEAT - X-ray
|
||||||
bindKey(new KeyStroke(Keys.X), new Runnable() {
|
bindKey(new KeyStroke(Keys.F10, Keys.MOD_CONTROL), new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class WorldConsoleRenderer extends BaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (final ConcurrentModificationException e) {
|
} catch (final ConcurrentModificationException e) {
|
||||||
Log.e(e); // this should not happen anymore
|
Log.e(e); // this should not happen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class ScreenMainMenu extends LayeredScreen {
|
|||||||
root.add(layout);
|
root.add(layout);
|
||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
final ImagePainter ip = new ImagePainter(Res.txq("logo"));
|
final ImagePainter ip = new ImagePainter(Res.getTxQuad("logo"));
|
||||||
ip.keepAspectRatio();
|
ip.keepAspectRatio();
|
||||||
layout.put(ip, r, 0, 4, 1);
|
layout.put(ip, r, 0, 4, 1);
|
||||||
r += 5;
|
r += 5;
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ public class WorldSlot extends ConstraintLayout {
|
|||||||
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
label = "<empty>";
|
label = "<empty>";
|
||||||
|
worldBundle = null;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
worldBundle = Ion.fromFile(file);
|
worldBundle = Ion.fromFile(file);
|
||||||
@@ -173,7 +174,8 @@ public class WorldSlot extends ConstraintLayout {
|
|||||||
delBtn.setVisible(true);
|
delBtn.setVisible(true);
|
||||||
delBtn.setEnabled(true);
|
delBtn.setEnabled(true);
|
||||||
|
|
||||||
} catch (final IOException e) {
|
} catch (final Exception e) {
|
||||||
|
Log.w("Error loading world save.", e);
|
||||||
label = "<corrupt>";
|
label = "<corrupt>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public class Inventory implements IonObjBinary {
|
|||||||
|
|
||||||
public static final short ION_MARK = 54;
|
public static final short ION_MARK = 54;
|
||||||
private Item[] items;
|
private Item[] items;
|
||||||
|
private int lastAddIndex = 0;
|
||||||
|
|
||||||
|
|
||||||
public Inventory(int size)
|
public Inventory(int size)
|
||||||
@@ -87,6 +88,8 @@ public class Inventory implements IonObjBinary {
|
|||||||
*/
|
*/
|
||||||
public Item getItem(int i)
|
public Item getItem(int i)
|
||||||
{
|
{
|
||||||
|
if (i < 0 || i > getSize()) return null;
|
||||||
|
|
||||||
verifyIndex(i);
|
verifyIndex(i);
|
||||||
final Item itm = items[i];
|
final Item itm = items[i];
|
||||||
if (itm == null || itm.isEmpty()) return null;
|
if (itm == null || itm.isEmpty()) return null;
|
||||||
@@ -112,6 +115,7 @@ public class Inventory implements IonObjBinary {
|
|||||||
{
|
{
|
||||||
verifyIndex(i);
|
verifyIndex(i);
|
||||||
items[i] = item;
|
items[i] = item;
|
||||||
|
lastAddIndex = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -136,7 +140,10 @@ public class Inventory implements IonObjBinary {
|
|||||||
for (int i = 0; i < getSize(); i++) {
|
for (int i = 0; i < getSize(); i++) {
|
||||||
final Item itm = getItem(i);
|
final Item itm = getItem(i);
|
||||||
if (itm != null) {
|
if (itm != null) {
|
||||||
if (itm.addItem(stored)) return true;
|
if (itm.addItem(stored)) {
|
||||||
|
lastAddIndex = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +152,7 @@ public class Inventory implements IonObjBinary {
|
|||||||
final Item itm = getItem(i);
|
final Item itm = getItem(i);
|
||||||
if (itm == null) {
|
if (itm == null) {
|
||||||
setItem(i, stored.split(stored.getAmount())); // store a copy, empty the original item.
|
setItem(i, stored.split(stored.getAmount())); // store a copy, empty the original item.
|
||||||
|
lastAddIndex = i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,6 +175,12 @@ public class Inventory implements IonObjBinary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getLastAddIndex()
|
||||||
|
{
|
||||||
|
return lastAddIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||||
import mightypork.rogue.world.entity.Entity;
|
import mightypork.rogue.world.entity.Entity;
|
||||||
import mightypork.rogue.world.entity.EntityType;
|
import mightypork.rogue.world.entity.EntityType;
|
||||||
@@ -50,25 +50,25 @@ public abstract class PlayerControl {
|
|||||||
|
|
||||||
public void goNorth()
|
public void goNorth()
|
||||||
{
|
{
|
||||||
go(Step.NORTH);
|
go(Move.NORTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void goSouth()
|
public void goSouth()
|
||||||
{
|
{
|
||||||
go(Step.SOUTH);
|
go(Move.SOUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void goEast()
|
public void goEast()
|
||||||
{
|
{
|
||||||
go(Step.EAST);
|
go(Move.EAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void goWest()
|
public void goWest()
|
||||||
{
|
{
|
||||||
go(Step.WEST);
|
go(Move.WEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ public abstract class PlayerControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean canGo(Step side)
|
public boolean canGo(Move side)
|
||||||
{
|
{
|
||||||
return getPlayer().canGoTo(side);
|
return getPlayer().canGoTo(side);
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ public abstract class PlayerControl {
|
|||||||
* @param side
|
* @param side
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean clickTile(Step side)
|
public boolean clickTile(Move side)
|
||||||
{
|
{
|
||||||
return doClickTile(getPlayer().getCoord().add(side).toVect());
|
return doClickTile(getPlayer().getCoord().add(side).toVect());
|
||||||
}
|
}
|
||||||
@@ -132,14 +132,14 @@ public abstract class PlayerControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void go(Step side)
|
public void go(Move side)
|
||||||
{
|
{
|
||||||
getPlayer().cancelPath();
|
getPlayer().cancelPath();
|
||||||
getPlayer().addPathStep(side);
|
getPlayer().addPathStep(side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean tryGo(Step e)
|
public boolean tryGo(Move e)
|
||||||
{
|
{
|
||||||
if (!canGo(e)) return false;
|
if (!canGo(e)) return false;
|
||||||
go(e);
|
go(e);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import java.util.Comparator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||||
import mightypork.rogue.world.entity.Entity;
|
import mightypork.rogue.world.entity.Entity;
|
||||||
import mightypork.rogue.world.item.Item;
|
import mightypork.rogue.world.item.Item;
|
||||||
@@ -158,7 +158,7 @@ public class PlayerFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addPathStep(Step step)
|
public void addPathStep(Move step)
|
||||||
{
|
{
|
||||||
world.playerEntity.pos.addStep(step);
|
world.playerEntity.pos.addStep(step);
|
||||||
}
|
}
|
||||||
@@ -400,8 +400,32 @@ public class PlayerFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean canGoTo(Step side)
|
public boolean canGoTo(Move side)
|
||||||
{
|
{
|
||||||
return getEntity().pos.canGoTo(side);
|
return getEntity().pos.canGoTo(side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void dropItem(int itemIndex)
|
||||||
|
{
|
||||||
|
final Item itm = getInventory().getItem(itemIndex);
|
||||||
|
if (itm != null && !itm.isEmpty()) {
|
||||||
|
|
||||||
|
final Item piece = itm.split(1);
|
||||||
|
getInventory().clean();
|
||||||
|
|
||||||
|
Coord dropPos;
|
||||||
|
if (world.playerEntity.pos.isMoving()) {
|
||||||
|
dropPos = world.playerEntity.pos.getLastPos();
|
||||||
|
} else {
|
||||||
|
dropPos = getCoord();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getLevel().getTile(dropPos).dropItem(piece)) {
|
||||||
|
getInventory().addItem(piece); // add back
|
||||||
|
} else {
|
||||||
|
world.getConsole().msgDroppedItem(piece);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class WorldConsole implements Updateable {
|
|||||||
|
|
||||||
public void msgDie(Entity attacker)
|
public void msgDie(Entity attacker)
|
||||||
{
|
{
|
||||||
addMessage("You've been defeated by a " + attacker.getVisualName() + "!");
|
addMessage("You've been defeated by " + addArticle(attacker.getVisualName()) + "!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ public class WorldConsole implements Updateable {
|
|||||||
|
|
||||||
public void msgEat(Item item)
|
public void msgEat(Item item)
|
||||||
{
|
{
|
||||||
addMessage("You've eaten a " + item.getVisualName() + ".");
|
addMessage("You've eaten " + addArticle(item.getVisualName()) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ public class WorldConsole implements Updateable {
|
|||||||
|
|
||||||
public void msgEquipWeapon(Item item)
|
public void msgEquipWeapon(Item item)
|
||||||
{
|
{
|
||||||
addMessage("You're now wielding " + (item == null ? "NOTHING" : "a " + item.getVisualName()) + ".");
|
addMessage("You're now wielding " + (item == null ? "NOTHING" : addArticle(item.getVisualName())) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ public class WorldConsole implements Updateable {
|
|||||||
|
|
||||||
public void msgKill(Entity prey)
|
public void msgKill(Entity prey)
|
||||||
{
|
{
|
||||||
addMessage("You've killed a " + prey.getVisualName() + ".");
|
addMessage("You've killed " + addArticle(prey.getVisualName()) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,12 +183,19 @@ public class WorldConsole implements Updateable {
|
|||||||
|
|
||||||
public void msgPick(Item item)
|
public void msgPick(Item item)
|
||||||
{
|
{
|
||||||
addMessage("You've picked up a " + item.getVisualName() + ".");
|
addMessage("You've picked up " + addArticle(item.getVisualName()) + ".");
|
||||||
lastPickupItem = item;
|
lastPickupItem = item;
|
||||||
timeSinceLastPickup = 0;
|
timeSinceLastPickup = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void msgDroppedItem(Item item)
|
||||||
|
{
|
||||||
|
addMessage("You've dropped " + addArticle(item.getVisualName()) + ".");
|
||||||
|
lastPickupItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void msgWeaponBreak(Item item)
|
public void msgWeaponBreak(Item item)
|
||||||
{
|
{
|
||||||
addMessage("Your " + item.getVisualName() + " has broken!");
|
addMessage("Your " + item.getVisualName() + " has broken!");
|
||||||
@@ -217,4 +224,26 @@ public class WorldConsole implements Updateable {
|
|||||||
{
|
{
|
||||||
addMessage("Error while loading; See the log for details.");
|
addMessage("Error while loading; See the log for details.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void msgOpenChest()
|
||||||
|
{
|
||||||
|
addMessage("You've opened a treasure chest!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String addArticle(String name)
|
||||||
|
{
|
||||||
|
switch (Character.toLowerCase(name.charAt(0))) {
|
||||||
|
case 'a':
|
||||||
|
case 'e':
|
||||||
|
case 'i':
|
||||||
|
case 'o':
|
||||||
|
case 'u':
|
||||||
|
case 'y':
|
||||||
|
return "an " + name;
|
||||||
|
default:
|
||||||
|
return "a " + name;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package mightypork.rogue.world.entity;
|
package mightypork.rogue.world.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.Heuristic;
|
import mightypork.gamecore.util.math.algo.pathfinding.Heuristic;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
||||||
|
|
||||||
@@ -53,9 +55,9 @@ public class EntityPathFinder extends PathFinder {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Step[] getWalkSides()
|
public List<Move> getWalkSides()
|
||||||
{
|
{
|
||||||
return Sides.CARDINAL_SIDES;
|
return Moves.CARDINAL_SIDES;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ public class BossRatAi extends GrayRatAi {
|
|||||||
{
|
{
|
||||||
super(entity);
|
super(entity);
|
||||||
|
|
||||||
setAttackTime(0.7);
|
setAttackTime(0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getAttackStrength()
|
protected int getAttackStrength()
|
||||||
{
|
{
|
||||||
return Calc.randInt(5, 11);
|
return Calc.randInt(1, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +52,6 @@ public class BossRatAi extends GrayRatAi {
|
|||||||
@Override
|
@Override
|
||||||
protected double getStepTime()
|
protected double getStepTime()
|
||||||
{
|
{
|
||||||
return isIdle() ? 0.6 : 0.4;
|
return isIdle() ? 0.6 : 0.37;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import mightypork.gamecore.util.annot.DefaultImpl;
|
|||||||
import mightypork.gamecore.util.ion.IonBundle;
|
import mightypork.gamecore.util.ion.IonBundle;
|
||||||
import mightypork.gamecore.util.math.Calc;
|
import mightypork.gamecore.util.math.Calc;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.PathFinderProxy;
|
import mightypork.gamecore.util.math.algo.pathfinding.PathFinderProxy;
|
||||||
import mightypork.rogue.world.entity.AiTimer;
|
import mightypork.rogue.world.entity.AiTimer;
|
||||||
@@ -65,7 +65,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
|||||||
if (entity.pos.isMoving()) return;
|
if (entity.pos.isMoving()) return;
|
||||||
|
|
||||||
if (Calc.rand.nextInt(10) == 0) {
|
if (Calc.rand.nextInt(10) == 0) {
|
||||||
entity.pos.addStep(Sides.randomCardinal());
|
entity.pos.addStep(Moves.randomCardinal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -260,7 +260,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<Step> getPathToPrey(Entity prey)
|
private List<Move> getPathToPrey(Entity prey)
|
||||||
{
|
{
|
||||||
if (!isPreyValid(prey)) return null;
|
if (!isPreyValid(prey)) return null;
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ public class MonsterAi extends EntityModule implements EntityMoveListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Step> preyPath = getPathToPrey(prey);
|
final List<Move> preyPath = getPathToPrey(prey);
|
||||||
|
|
||||||
if (preyPath == null || preyPath.size() > getPreyAbandonDistance()) {
|
if (preyPath == null || preyPath.size() > getPreyAbandonDistance()) {
|
||||||
stopChasing();
|
stopChasing();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import mightypork.gamecore.util.ion.IonBundle;
|
import mightypork.gamecore.util.ion.IonBundle;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.VectConst;
|
import mightypork.gamecore.util.math.constraints.vect.VectConst;
|
||||||
import mightypork.rogue.world.entity.Entity;
|
import mightypork.rogue.world.entity.Entity;
|
||||||
import mightypork.rogue.world.entity.EntityModule;
|
import mightypork.rogue.world.entity.EntityModule;
|
||||||
@@ -22,7 +22,7 @@ public class EntityModulePosition extends EntityModule {
|
|||||||
private final Coord lastPos = new Coord(0, 0);
|
private final Coord lastPos = new Coord(0, 0);
|
||||||
private boolean walking = false;
|
private boolean walking = false;
|
||||||
|
|
||||||
private final Queue<Step> path = new LinkedList<>();
|
private final Queue<Move> path = new LinkedList<>();
|
||||||
private final EntityPos entityPos = new EntityPos();
|
private final EntityPos entityPos = new EntityPos();
|
||||||
private double stepTime = 0.5;
|
private double stepTime = 0.5;
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ public class EntityModulePosition extends EntityModule {
|
|||||||
|
|
||||||
walking = true;
|
walking = true;
|
||||||
|
|
||||||
final Step step = path.poll();
|
final Move step = path.poll();
|
||||||
|
|
||||||
final Coord planned = entityPos.getCoord().add(step.toCoord());
|
final Coord planned = entityPos.getCoord().add(step.toCoord());
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ public class EntityModulePosition extends EntityModule {
|
|||||||
*
|
*
|
||||||
* @param step
|
* @param step
|
||||||
*/
|
*/
|
||||||
public void addStep(Step step)
|
public void addStep(Move step)
|
||||||
{
|
{
|
||||||
if (path.isEmpty() && !canGoTo(step)) return;
|
if (path.isEmpty() && !canGoTo(step)) return;
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ public class EntityModulePosition extends EntityModule {
|
|||||||
public boolean navigateTo(Coord target)
|
public boolean navigateTo(Coord target)
|
||||||
{
|
{
|
||||||
if (target.equals(getCoord())) return true;
|
if (target.equals(getCoord())) return true;
|
||||||
final List<Step> newPath = entity.getPathFinder().findPathRelative(entityPos.getCoord(), target);
|
final List<Move> newPath = entity.getPathFinder().findPathRelative(entityPos.getCoord(), target);
|
||||||
|
|
||||||
if (newPath == null) return false;
|
if (newPath == null) return false;
|
||||||
cancelPath();
|
cancelPath();
|
||||||
@@ -228,7 +228,7 @@ public class EntityModulePosition extends EntityModule {
|
|||||||
*
|
*
|
||||||
* @param path steps
|
* @param path steps
|
||||||
*/
|
*/
|
||||||
public void addSteps(List<Step> path)
|
public void addSteps(List<Move> path)
|
||||||
{
|
{
|
||||||
this.path.addAll(path);
|
this.path.addAll(path);
|
||||||
}
|
}
|
||||||
@@ -284,9 +284,15 @@ public class EntityModulePosition extends EntityModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean canGoTo(Step side)
|
public boolean canGoTo(Move side)
|
||||||
{
|
{
|
||||||
return entity.getPathFinder().isAccessible(getCoord().add(side));
|
return entity.getPathFinder().isAccessible(getCoord().add(side));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Coord getLastPos()
|
||||||
|
{
|
||||||
|
return lastPos;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import mightypork.gamecore.util.ion.IonBundle;
|
|||||||
import mightypork.gamecore.util.ion.IonObjBundled;
|
import mightypork.gamecore.util.ion.IonObjBundled;
|
||||||
import mightypork.gamecore.util.math.Easing;
|
import mightypork.gamecore.util.math.Easing;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.VectConst;
|
import mightypork.gamecore.util.math.constraints.vect.VectConst;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.mutable.VectAnimated;
|
import mightypork.gamecore.util.math.constraints.vect.mutable.VectAnimated;
|
||||||
@@ -128,7 +128,7 @@ class EntityPos implements IonObjBundled, Updateable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void walk(Step step, double secs)
|
public void walk(Move step, double secs)
|
||||||
{
|
{
|
||||||
setTo(coord.x + step.x(), coord.y + step.y());
|
setTo(coord.x + step.x(), coord.y + step.y());
|
||||||
walkOffset.setTo(-step.x(), -step.y());
|
walkOffset.setTo(-step.x(), -step.y());
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class EntityRendererMobLR extends EntityRenderer {
|
|||||||
public EntityRendererMobLR(Entity entity, String sheetKey)
|
public EntityRendererMobLR(Entity entity, String sheetKey)
|
||||||
{
|
{
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.sheet = Res.txs(sheetKey);
|
this.sheet = Res.getTxSheet(sheetKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -30,4 +30,7 @@ public interface MapTheme {
|
|||||||
|
|
||||||
|
|
||||||
TileModel exit();
|
TileModel exit();
|
||||||
|
|
||||||
|
|
||||||
|
TileModel chest();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ import mightypork.gamecore.util.math.algo.Coord;
|
|||||||
*/
|
*/
|
||||||
public interface RoomBuilder {
|
public interface RoomBuilder {
|
||||||
|
|
||||||
RoomDesc buildToFit(ScratchMap map, MapTheme theme, Random rand, Coord center) throws WorldGenError;
|
RoomEntry buildRoom(ScratchMap map, MapTheme theme, Random rand, Coord center) throws WorldGenError;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -5,17 +5,17 @@ import mightypork.gamecore.util.math.algo.Coord;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Room description
|
* Room description entry for {@link ScratchMap}
|
||||||
*
|
*
|
||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
public class RoomDesc {
|
public class RoomEntry {
|
||||||
|
|
||||||
final Coord min;
|
final Coord min;
|
||||||
final Coord max;
|
final Coord max;
|
||||||
|
|
||||||
|
|
||||||
public RoomDesc(Coord min, Coord max)
|
public RoomEntry(Coord min, Coord max)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.min = min;
|
this.min = min;
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,8 +10,8 @@ import java.util.Set;
|
|||||||
import mightypork.gamecore.logging.Log;
|
import mightypork.gamecore.logging.Log;
|
||||||
import mightypork.gamecore.util.math.Calc;
|
import mightypork.gamecore.util.math.Calc;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.Heuristic;
|
import mightypork.gamecore.util.math.algo.pathfinding.Heuristic;
|
||||||
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
import mightypork.gamecore.util.math.algo.pathfinding.PathFinder;
|
||||||
import mightypork.rogue.world.entity.Entity;
|
import mightypork.rogue.world.entity.Entity;
|
||||||
@@ -33,7 +33,7 @@ public class ScratchMap {
|
|||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
private final List<RoomDesc> rooms = new ArrayList<>();
|
private final List<RoomEntry> rooms = new ArrayList<>();
|
||||||
|
|
||||||
/** Coords to connect with corridors */
|
/** Coords to connect with corridors */
|
||||||
private final List<Coord> nodes = new ArrayList<>();
|
private final List<Coord> nodes = new ArrayList<>();
|
||||||
@@ -96,9 +96,9 @@ public class ScratchMap {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Step[] getWalkSides()
|
public List<Move> getWalkSides()
|
||||||
{
|
{
|
||||||
return Sides.CARDINAL_SIDES;
|
return Moves.CARDINAL_SIDES;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -136,83 +136,99 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean addRoom(RoomBuilder rb, boolean critical)
|
public void addRoom(RoomBuilder rb, boolean critical) throws WorldGenError
|
||||||
{
|
{
|
||||||
final Coord center = Coord.make(0, 0);
|
try {
|
||||||
|
if (rooms.size() > 0) minimizeBounds();
|
||||||
|
|
||||||
int failed = 0;
|
final Coord roomPos = Coord.make(0, 0);
|
||||||
|
|
||||||
int failed_total = 0;
|
int failed = 0;
|
||||||
|
int failed_total = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
final int sizeX = genMax.x - genMin.x;
|
final int sizeX = genMax.x - genMin.x;
|
||||||
final int sizeY = genMax.y - genMin.y;
|
final int sizeY = genMax.y - genMin.y;
|
||||||
|
|
||||||
center.x = genMin.x + rand.nextInt(sizeX);
|
roomPos.x = genMin.x + rand.nextInt(sizeX + 1);
|
||||||
center.y = genMin.y + rand.nextInt(sizeY);
|
roomPos.y = genMin.y + rand.nextInt(sizeY + 1);
|
||||||
|
|
||||||
switch (rand.nextInt(4)) {
|
switch (rand.nextInt(4)) {
|
||||||
case 0:
|
case 0:
|
||||||
center.x += (failed_total / 35);
|
roomPos.x += (failed_total / 35);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
center.x -= (failed_total / 35);
|
roomPos.x -= (failed_total / 35);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
center.y += (failed_total / 35);
|
roomPos.y += (failed_total / 35);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
center.y -= (failed_total / 35);
|
roomPos.y -= (failed_total / 35);
|
||||||
}
|
|
||||||
|
|
||||||
final RoomDesc rd = rb.buildToFit(this, theme, rand, center);
|
|
||||||
if (rd != null) {
|
|
||||||
rooms.add(rd);
|
|
||||||
|
|
||||||
genMin.x = Math.min(genMin.x, rd.min.x);
|
|
||||||
genMin.y = Math.min(genMin.y, rd.min.y);
|
|
||||||
|
|
||||||
genMax.x = Math.max(genMax.x, rd.max.x);
|
|
||||||
genMax.y = Math.max(genMax.y, rd.max.y);
|
|
||||||
clampBounds();
|
|
||||||
|
|
||||||
nodes.add(center);
|
|
||||||
// Log.f3("Placed room (failed " + failed_total + " x).");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
failed++;
|
|
||||||
failed_total++;
|
|
||||||
|
|
||||||
if (failed_total > 1000) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed > 300) {
|
final RoomEntry rd = rb.buildRoom(this, theme, rand, roomPos);
|
||||||
Log.w("Faild to build room.");
|
if (rd != null) {
|
||||||
if (critical) {
|
|
||||||
|
|
||||||
genMin.x -= 5;
|
rooms.add(rd);
|
||||||
genMin.y -= 5;
|
|
||||||
genMax.x += 5;
|
|
||||||
genMax.y += 5;
|
|
||||||
clampBounds();
|
|
||||||
|
|
||||||
failed = 0;
|
genMin.x = Math.min(genMin.x, rd.min.x);
|
||||||
Log.f3("Trying again.");
|
genMin.y = Math.min(genMin.y, rd.min.y);
|
||||||
continue;
|
|
||||||
|
|
||||||
} else {
|
genMax.x = Math.max(genMax.x, rd.max.x);
|
||||||
return false;
|
genMax.y = Math.max(genMax.y, rd.max.y);
|
||||||
|
clampBounds();
|
||||||
|
|
||||||
|
nodes.add(roomPos);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
failed++;
|
||||||
|
failed_total++;
|
||||||
|
|
||||||
|
if (failed_total > 1000) {
|
||||||
|
throw new WorldGenError("Failed to add a room.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed > 300) {
|
||||||
|
Log.w("Faild to build room.");
|
||||||
|
if (critical) {
|
||||||
|
|
||||||
|
// expand gen bounds
|
||||||
|
genMin.x -= 5;
|
||||||
|
genMin.y -= 5;
|
||||||
|
genMax.x += 5;
|
||||||
|
genMax.y += 5;
|
||||||
|
|
||||||
|
clampBounds();
|
||||||
|
|
||||||
|
failed = 0;
|
||||||
|
Log.f3("Trying again.");
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new WorldGenError("Failed to add a room.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (final WorldGenError e) {
|
||||||
|
if (!critical) {
|
||||||
|
Log.w("Could not place a room.", e);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// rethrow
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp bounds to available area
|
||||||
|
*/
|
||||||
private void clampBounds()
|
private void clampBounds()
|
||||||
{
|
{
|
||||||
genMin.x = Calc.clamp(genMin.x, 0, width - 1);
|
genMin.x = Calc.clamp(genMin.x, 0, width - 1);
|
||||||
@@ -222,6 +238,27 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimize gen bounds based on defined room bounds
|
||||||
|
*/
|
||||||
|
private void minimizeBounds()
|
||||||
|
{
|
||||||
|
final Coord low = Coord.make(width, height);
|
||||||
|
final Coord high = Coord.make(0, 0);
|
||||||
|
|
||||||
|
for (final RoomEntry rd : rooms) {
|
||||||
|
low.x = Math.min(low.x, rd.min.x);
|
||||||
|
low.y = Math.min(low.y, rd.min.y);
|
||||||
|
|
||||||
|
high.x = Math.max(high.x, rd.max.x);
|
||||||
|
high.y = Math.max(high.y, rd.max.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
genMin.setTo(low);
|
||||||
|
genMax.setTo(high);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isIn(Coord pos)
|
public boolean isIn(Coord pos)
|
||||||
{
|
{
|
||||||
return pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height;
|
return pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height;
|
||||||
@@ -258,7 +295,7 @@ public class ScratchMap {
|
|||||||
public boolean isClear(Coord min, Coord max)
|
public boolean isClear(Coord min, Coord max)
|
||||||
{
|
{
|
||||||
if (!isIn(min) || !isIn(max)) return false;
|
if (!isIn(min) || !isIn(max)) return false;
|
||||||
for (final RoomDesc r : rooms) {
|
for (final RoomEntry r : rooms) {
|
||||||
if (r.intersectsWith(min, max)) return false;
|
if (r.intersectsWith(min, max)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +303,12 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void protect(Coord pos, TileProtectLevel prot)
|
||||||
|
{
|
||||||
|
protect(pos, pos, prot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void protect(Coord min, Coord max, TileProtectLevel prot)
|
public void protect(Coord min, Coord max, TileProtectLevel prot)
|
||||||
{
|
{
|
||||||
if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max);
|
if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max);
|
||||||
@@ -327,7 +370,7 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
starts.add(start);
|
starts.add(start);
|
||||||
start = Calc.pick(nodes);
|
start = Calc.pick(rand, nodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,31 +420,24 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return dimensions of the area taken by non-null tiles
|
||||||
|
*/
|
||||||
public Coord getNeededSize()
|
public Coord getNeededSize()
|
||||||
{
|
{
|
||||||
return Coord.make(genMax.x - genMin.x + 1, genMax.y - genMin.y + 1);
|
return Coord.make(genMax.x - genMin.x + 1, genMax.y - genMin.y + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int countBits(byte b)
|
|
||||||
{
|
|
||||||
int c = 0;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
c += (b >> i) & 1;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public byte findWalls(Coord pos)
|
public byte findWalls(Coord pos)
|
||||||
{
|
{
|
||||||
byte walls = 0;
|
byte walls = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
final Coord cc = pos.add(Sides.get(i));
|
final Coord cc = pos.add(Moves.getSide(i));
|
||||||
if (!isIn(cc)) continue;
|
if (!isIn(cc)) continue;
|
||||||
|
|
||||||
if (getTile(cc).isWall()) {
|
if (getTile(cc).isWall()) {
|
||||||
walls |= Sides.bit(i);
|
walls |= Moves.getBit(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return walls;
|
return walls;
|
||||||
@@ -412,11 +448,11 @@ public class ScratchMap {
|
|||||||
{
|
{
|
||||||
byte floors = 0;
|
byte floors = 0;
|
||||||
for (int i = 0; i <= 7; i++) {
|
for (int i = 0; i <= 7; i++) {
|
||||||
final Coord cc = pos.add(Sides.get(i));
|
final Coord cc = pos.add(Moves.getSide(i));
|
||||||
if (!isIn(cc)) continue;
|
if (!isIn(cc)) continue;
|
||||||
|
|
||||||
if (getTile(cc).isFloor()) {
|
if (getTile(cc).isFloor()) {
|
||||||
floors |= Sides.bit(i);
|
floors |= Moves.getBit(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return floors;
|
return floors;
|
||||||
@@ -427,11 +463,11 @@ public class ScratchMap {
|
|||||||
{
|
{
|
||||||
byte doors = 0;
|
byte doors = 0;
|
||||||
for (int i = 0; i <= 7; i++) {
|
for (int i = 0; i <= 7; i++) {
|
||||||
final Coord cc = pos.add(Sides.get(i));
|
final Coord cc = pos.add(Moves.getSide(i));
|
||||||
if (!isIn(cc)) continue;
|
if (!isIn(cc)) continue;
|
||||||
|
|
||||||
if (getTile(cc).isDoor()) {
|
if (getTile(cc).isDoor()) {
|
||||||
doors |= Sides.bit(i);
|
doors |= Moves.getBit(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return doors;
|
return doors;
|
||||||
@@ -442,16 +478,119 @@ public class ScratchMap {
|
|||||||
{
|
{
|
||||||
byte nils = 0;
|
byte nils = 0;
|
||||||
for (int i = 0; i <= 7; i++) {
|
for (int i = 0; i <= 7; i++) {
|
||||||
final Coord cc = pos.add(Sides.get(i));
|
final Coord cc = pos.add(Moves.getSide(i));
|
||||||
|
|
||||||
if (!isIn(cc) || getTile(cc).isNull()) {
|
if (!isIn(cc) || getTile(cc).isNull()) {
|
||||||
nils |= Sides.bit(i);
|
nils |= Moves.getBit(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nils;
|
return nils;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix generator glitches and reduce size to the actual used size
|
||||||
|
*/
|
||||||
|
public void fixGlitches()
|
||||||
|
{
|
||||||
|
final Tile[][] out = new Tile[height][width];
|
||||||
|
|
||||||
|
// bounds will be adjusted by the actual tiles in the map
|
||||||
|
genMin.x = width;
|
||||||
|
genMin.y = height;
|
||||||
|
genMax.x = 0;
|
||||||
|
genMax.y = 0;
|
||||||
|
|
||||||
|
final Coord c = Coord.make(0, 0);
|
||||||
|
for (c.x = 0; c.x < width; c.x++) {
|
||||||
|
for (c.y = 0; c.y < height; c.y++) {
|
||||||
|
|
||||||
|
final Tile t = getTile(c);
|
||||||
|
final boolean isNull = t.isNull();
|
||||||
|
|
||||||
|
final boolean isDoor = !isNull && t.isDoor();
|
||||||
|
final boolean isFloor = !isNull && t.isFloor();
|
||||||
|
final boolean isWall = !isNull && t.isWall();
|
||||||
|
|
||||||
|
// bitmasks
|
||||||
|
final byte walls = findWalls(c);
|
||||||
|
final byte nils = findNils(c);
|
||||||
|
final byte floors = findFloors(c);
|
||||||
|
|
||||||
|
boolean toWall = false;
|
||||||
|
boolean toFloor = false;
|
||||||
|
boolean toNull = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (isWall && floors == 0) {
|
||||||
|
toNull = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFloor && (nils & Moves.BITS_CARDINAL) != 0) {
|
||||||
|
toWall = true; // floor with adjacent cardinal null
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNull && (floors & Moves.BITS_DIAGONAL) != 0) {
|
||||||
|
toWall = true; // null with adjacent diagonal floor
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDoor) {
|
||||||
|
|
||||||
|
if (Calc.countBits((byte) (floors & Moves.BITS_CARDINAL)) < 2) {
|
||||||
|
toWall = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Calc.countBits((byte) (walls & Moves.BITS_CARDINAL)) > 2) {
|
||||||
|
toWall = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Calc.countBits((byte) (floors & Moves.BITS_CARDINAL)) > 2) {
|
||||||
|
toFloor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((floors & Moves.BITS_NW_CORNER) == Moves.BITS_NW_CORNER) toWall = true;
|
||||||
|
if ((floors & Moves.BITS_NE_CORNER) == Moves.BITS_NE_CORNER) toWall = true;
|
||||||
|
if ((floors & Moves.BITS_SW_CORNER) == Moves.BITS_SW_CORNER) toWall = true;
|
||||||
|
if ((floors & Moves.BITS_SE_CORNER) == Moves.BITS_SE_CORNER) toWall = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
if (toNull) {
|
||||||
|
out[c.y][c.x] = Tiles.NULL.createTile();
|
||||||
|
} else if (toWall) {
|
||||||
|
out[c.y][c.x] = theme.wall().createTile();
|
||||||
|
} else if (toFloor) {
|
||||||
|
out[c.y][c.x] = theme.floor().createTile();
|
||||||
|
} else {
|
||||||
|
out[c.y][c.x] = map[c.y][c.x];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!out[c.y][c.x].isNull()) {
|
||||||
|
genMin.x = Math.min(genMin.x, c.x);
|
||||||
|
genMin.y = Math.min(genMin.y, c.y);
|
||||||
|
|
||||||
|
genMax.x = Math.max(genMax.x, c.x);
|
||||||
|
genMax.y = Math.max(genMax.y, c.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write tiles and entities into a level
|
||||||
|
*
|
||||||
|
* @param level the level
|
||||||
|
*/
|
||||||
public void writeToLevel(Level level)
|
public void writeToLevel(Level level)
|
||||||
{
|
{
|
||||||
if (level.getWorld() == null) {
|
if (level.getWorld() == null) {
|
||||||
@@ -462,85 +601,6 @@ public class ScratchMap {
|
|||||||
final Coord c = Coord.make(0, 0);
|
final Coord c = Coord.make(0, 0);
|
||||||
final Coord c1 = Coord.make(0, 0);
|
final Coord c1 = Coord.make(0, 0);
|
||||||
|
|
||||||
if (FIX_GLITCHES) {
|
|
||||||
|
|
||||||
final Tile[][] out = new Tile[height][width];
|
|
||||||
|
|
||||||
for (c.x = 0; c.x < width; c.x++) {
|
|
||||||
for (c.y = 0; c.y < height; c.y++) {
|
|
||||||
|
|
||||||
final Tile t = getTile(c);
|
|
||||||
final boolean isNull = t.isNull();
|
|
||||||
|
|
||||||
final boolean isDoor = !isNull && t.isDoor();
|
|
||||||
final boolean isFloor = !isNull && t.isFloor();
|
|
||||||
final boolean isWall = !isNull && t.isWall();
|
|
||||||
|
|
||||||
// bitmasks
|
|
||||||
final byte walls = findWalls(c);
|
|
||||||
final byte nils = findNils(c);
|
|
||||||
final byte floors = findFloors(c);
|
|
||||||
|
|
||||||
boolean toWall = false;
|
|
||||||
boolean toFloor = false;
|
|
||||||
boolean toNull = false;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (isWall && floors == 0) {
|
|
||||||
toNull = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFloor && (nils & Sides.MASK_CARDINAL) != 0) {
|
|
||||||
toWall = true; // floor with adjacent cardinal null
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNull && (floors & Sides.MASK_DIAGONAL) != 0) {
|
|
||||||
toWall = true; // null with adjacent diagonal floor
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDoor) {
|
|
||||||
|
|
||||||
if (countBits((byte) (floors & Sides.MASK_CARDINAL)) < 2) {
|
|
||||||
toWall = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (countBits((byte) (walls & Sides.MASK_CARDINAL)) > 2) {
|
|
||||||
toWall = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (countBits((byte) (floors & Sides.MASK_CARDINAL)) > 2) {
|
|
||||||
toFloor = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((floors & Sides.NW_CORNER) == Sides.NW_CORNER) toWall = true;
|
|
||||||
if ((floors & Sides.NE_CORNER) == Sides.NE_CORNER) toWall = true;
|
|
||||||
if ((floors & Sides.SW_CORNER) == Sides.SW_CORNER) toWall = true;
|
|
||||||
if ((floors & Sides.SE_CORNER) == Sides.SE_CORNER) toWall = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
} while (false);
|
|
||||||
|
|
||||||
if (toNull) {
|
|
||||||
out[c.y][c.x] = Tiles.NULL.createTile();
|
|
||||||
} else if (toWall) {
|
|
||||||
out[c.y][c.x] = theme.wall().createTile();
|
|
||||||
} else if (toFloor) {
|
|
||||||
out[c.y][c.x] = theme.floor().createTile();
|
|
||||||
} else {
|
|
||||||
out[c.y][c.x] = map[c.y][c.x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
map = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (c.x = genMin.x, c1.x = 0; c.x <= genMax.x; c.x++, c1.x++) {
|
for (c.x = genMin.x, c1.x = 0; c.x <= genMax.x; c.x++, c1.x++) {
|
||||||
for (c.y = genMin.y, c1.y = 0; c.y <= genMax.y; c.y++, c1.y++) {
|
for (c.y = genMin.y, c1.y = 0; c.y <= genMax.y; c.y++, c1.y++) {
|
||||||
level.setTile(c1, getTile(c));
|
level.setTile(c1, getTile(c));
|
||||||
@@ -582,60 +642,74 @@ public class ScratchMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean putItem(Item item, Coord pos)
|
public boolean addItem(Item item, Coord pos)
|
||||||
|
{
|
||||||
|
return addItem(item, pos, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean addItem(Item item, Coord pos, boolean canStack)
|
||||||
{
|
{
|
||||||
if (!isIn(pos)) return false;
|
if (!isIn(pos)) return false;
|
||||||
|
|
||||||
final Tile t = getTile(pos);
|
final Tile t = getTile(pos);
|
||||||
|
if (!canStack && t.hasItem()) return false;
|
||||||
if (t.dropItem(item)) return true;
|
if (t.dropItem(item)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean putItemInArea(Item item, Coord min, Coord max, int tries)
|
public boolean addItemInArea(Item item, Coord min, Coord max, int tries)
|
||||||
{
|
{
|
||||||
final Coord pos = Coord.zero();
|
final Coord pos = Coord.zero();
|
||||||
|
|
||||||
for (int i = 0; i < tries; i++) {
|
for (int i = 0; i < tries / 2; i++) {
|
||||||
pos.x = min.x + rand.nextInt(max.x - min.x);
|
pos.x = Calc.randInt(rand, min.x, max.x);
|
||||||
pos.y = min.y + rand.nextInt(max.y - min.y);
|
pos.y = Calc.randInt(rand, min.y, max.y);
|
||||||
if (putItem(item, pos)) return true;
|
if (addItem(item, pos, false)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < tries - (tries / 2); i++) {
|
||||||
|
pos.x = Calc.randInt(rand, min.x, max.x);
|
||||||
|
pos.y = Calc.randInt(rand, min.y, max.y);
|
||||||
|
if (addItem(item, pos, true)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean putItemInMap(Item item, int tries)
|
public boolean addItemInMap(Item item, int tries)
|
||||||
{
|
{
|
||||||
return putItemInArea(item, genMin, genMax, tries);
|
Log.f3("gen bounds: " + genMin + " -> " + genMax);
|
||||||
|
return addItemInArea(item, genMin, genMax, tries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean putEntityInArea(Entity entity, Coord min, Coord max, int tries)
|
public boolean addEntityInArea(Entity entity, Coord min, Coord max, int tries)
|
||||||
{
|
{
|
||||||
final Coord pos = Coord.zero();
|
final Coord pos = Coord.zero();
|
||||||
|
|
||||||
for (int i = 0; i < tries; i++) {
|
for (int i = 0; i < tries; i++) {
|
||||||
pos.x = min.x + rand.nextInt(max.x - min.x);
|
pos.x = Calc.randInt(rand, min.x, max.x);
|
||||||
pos.y = min.y + rand.nextInt(max.y - min.y);
|
pos.y = Calc.randInt(rand, min.y, max.y);
|
||||||
if (!isIn(pos)) continue;
|
if (!isIn(pos)) continue;
|
||||||
|
|
||||||
if (putEntity(entity, pos)) return true;
|
if (addEntity(entity, pos)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean putEntityInMap(Entity entity, int tries)
|
public boolean addEntityInMap(Entity entity, int tries)
|
||||||
{
|
{
|
||||||
return putEntityInArea(entity, genMin, genMax, tries);
|
return addEntityInArea(entity, genMin, genMax, tries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean putEntity(Entity entity, Coord pos)
|
public boolean addEntity(Entity entity, Coord pos)
|
||||||
{
|
{
|
||||||
if (!isIn(pos)) return false;
|
if (!isIn(pos)) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,21 @@
|
|||||||
package mightypork.rogue.world.gen;
|
package mightypork.rogue.world.gen;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import mightypork.gamecore.logging.Log;
|
||||||
|
import mightypork.gamecore.util.math.Calc;
|
||||||
|
import mightypork.gamecore.util.math.Range;
|
||||||
import mightypork.rogue.world.World;
|
import mightypork.rogue.world.World;
|
||||||
|
import mightypork.rogue.world.entity.Entities;
|
||||||
|
import mightypork.rogue.world.entity.Entity;
|
||||||
|
import mightypork.rogue.world.gen.LevelBuilder.BuildOrder;
|
||||||
|
import mightypork.rogue.world.gen.themes.ThemeBrick;
|
||||||
|
import mightypork.rogue.world.item.Item;
|
||||||
|
import mightypork.rogue.world.item.ItemModel;
|
||||||
|
import mightypork.rogue.world.item.Items;
|
||||||
|
|
||||||
|
|
||||||
public class WorldCreator {
|
public class WorldCreator {
|
||||||
@@ -15,20 +27,127 @@ public class WorldCreator {
|
|||||||
{
|
{
|
||||||
synchronized (rand) {
|
synchronized (rand) {
|
||||||
rand.setSeed(seed);
|
rand.setSeed(seed);
|
||||||
|
final MapTheme theme = new ThemeBrick();
|
||||||
|
|
||||||
final World w = new World();
|
final World w = new World();
|
||||||
w.setSeed(seed);
|
w.setSeed(seed);
|
||||||
|
|
||||||
final int count = 7;
|
final LevelBuilder levelBuilders[] = new LevelBuilder[7];
|
||||||
|
|
||||||
for (int lvl = 1; lvl <= count; lvl++) {
|
// build the level rooms
|
||||||
w.addLevel(LevelGenerator.build(w, rand.nextLong(), lvl, LevelGenerator.DUNGEON_THEME, lvl == count));
|
for (int floor = 1; floor <= 7; floor++) {
|
||||||
|
final LevelBuilder lb = prepareFloor(rand.nextLong(), floor, theme, floor == 7);
|
||||||
|
|
||||||
|
levelBuilders[floor - 1] = lb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final List<ItemModel> weaponsBasic = new ArrayList<>();
|
||||||
|
weaponsBasic.add(Items.ROCK);
|
||||||
|
weaponsBasic.add(Items.BONE);
|
||||||
|
weaponsBasic.add(Items.TWIG);
|
||||||
|
|
||||||
|
|
||||||
|
final List<ItemModel> weaponsMedium = new ArrayList<>();
|
||||||
|
weaponsMedium.add(Items.CLUB);
|
||||||
|
|
||||||
|
|
||||||
|
final List<ItemModel> weaponsGood = new ArrayList<>();
|
||||||
|
weaponsGood.add(Items.AXE);
|
||||||
|
weaponsGood.add(Items.SWORD);
|
||||||
|
weaponsBasic.add(Items.KNIFE);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 10, 15); i++) {
|
||||||
|
final Item item = Calc.pick(rand, weaponsBasic).createItemDamaged(50);
|
||||||
|
final LevelBuilder lb = levelBuilders[-1 + Calc.randInt(1, 7)];
|
||||||
|
lb.addItem(item, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 1, 3); i++) {
|
||||||
|
final Item item = Calc.pick(rand, weaponsMedium).createItemDamaged(60);
|
||||||
|
final LevelBuilder lb = levelBuilders[-1 + Calc.randInt(1, 3)];
|
||||||
|
lb.addItem(item, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < Calc.randInt(rand, 2, 3); i++) {
|
||||||
|
final Item item = Calc.pick(rand, weaponsGood).createItemDamaged(60);
|
||||||
|
final LevelBuilder lb = levelBuilders[-1 + Calc.randInt(3, 7)];
|
||||||
|
|
||||||
|
lb.addRoom(Rooms.treasure(item), BuildOrder.MIDDLE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// place random foods
|
||||||
|
final List<ItemModel> randomFood = new ArrayList<>();
|
||||||
|
randomFood.add(Items.CHEESE);
|
||||||
|
randomFood.add(Items.MEAT);
|
||||||
|
|
||||||
|
for (int level = 1; level <= 7; level++) {
|
||||||
|
|
||||||
|
final LevelBuilder lb = levelBuilders[level - 1];
|
||||||
|
final Range amount = Range.make(1, level);
|
||||||
|
|
||||||
|
for (int i = 0; i < amount.randInt(rand); i++) {
|
||||||
|
lb.addItem(Calc.pick(rand, randomFood).createItem(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// place monsters
|
||||||
|
for (int level = 1; level <= 7; level++) {
|
||||||
|
|
||||||
|
final LevelBuilder lb = levelBuilders[level - 1];
|
||||||
|
|
||||||
|
final Range amount = Range.make(2 + level * 2, 5 + level * 3.5);
|
||||||
|
|
||||||
|
for (int i = 0; i < amount.randInt(rand); i++) {
|
||||||
|
Entity e;
|
||||||
|
|
||||||
|
if (level > 2 && rand.nextInt(7 - level + 1) == 0) {
|
||||||
|
e = Entities.RAT_BROWN.createEntity();
|
||||||
|
} else {
|
||||||
|
e = Entities.RAT_GRAY.createEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
lb.addEntity(e, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// compile levels
|
||||||
|
for (final LevelBuilder lb : levelBuilders) {
|
||||||
|
w.addLevel(lb.build(w));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
w.createPlayer();
|
w.createPlayer();
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static LevelBuilder prepareFloor(long seed, int floor, MapTheme theme, boolean lastLevel) throws WorldGenError
|
||||||
|
{
|
||||||
|
Log.f3("Generating level: " + floor);
|
||||||
|
|
||||||
|
final LevelBuilder lb = new LevelBuilder(128, theme, seed);
|
||||||
|
|
||||||
|
lb.addRoom(Rooms.ENTRANCE, BuildOrder.FIRST, true);
|
||||||
|
|
||||||
|
lb.addRoom(Rooms.BASIC, Range.make(1 + floor, 1 + floor * 1.5), BuildOrder.MIDDLE, false);
|
||||||
|
lb.addRoom(Rooms.DEAD_END, Range.make(0, 1 + floor * 0.6), BuildOrder.MIDDLE, false);
|
||||||
|
lb.addRoom(Rooms.STORAGE, Range.make(1, Math.ceil(floor / 2D)), BuildOrder.MIDDLE, false);
|
||||||
|
|
||||||
|
if (lastLevel) lb.addRoom(Rooms.BOSS, BuildOrder.LAST, true);
|
||||||
|
if (!lastLevel) lb.addRoom(Rooms.EXIT, BuildOrder.LAST, true);
|
||||||
|
|
||||||
|
final RoomBuilder heartRoom = Rooms.shrine(Items.HEART_PIECE.createItem());
|
||||||
|
lb.addRoom(heartRoom, BuildOrder.LAST, true);
|
||||||
|
|
||||||
|
return lb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import java.util.Random;
|
|||||||
|
|
||||||
import mightypork.gamecore.util.annot.DefaultImpl;
|
import mightypork.gamecore.util.annot.DefaultImpl;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.rogue.world.gen.MapTheme;
|
import mightypork.rogue.world.gen.MapTheme;
|
||||||
import mightypork.rogue.world.gen.RoomBuilder;
|
import mightypork.rogue.world.gen.RoomBuilder;
|
||||||
import mightypork.rogue.world.gen.RoomDesc;
|
import mightypork.rogue.world.gen.RoomEntry;
|
||||||
import mightypork.rogue.world.gen.ScratchMap;
|
import mightypork.rogue.world.gen.ScratchMap;
|
||||||
import mightypork.rogue.world.gen.TileProtectLevel;
|
import mightypork.rogue.world.gen.TileProtectLevel;
|
||||||
import mightypork.rogue.world.tile.TileModel;
|
import mightypork.rogue.world.tile.TileModel;
|
||||||
@@ -17,7 +17,7 @@ import mightypork.rogue.world.tile.TileModel;
|
|||||||
public abstract class AbstractRectRoom implements RoomBuilder {
|
public abstract class AbstractRectRoom implements RoomBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoomDesc buildToFit(ScratchMap map, MapTheme theme, Random rand, Coord center)
|
public RoomEntry buildRoom(ScratchMap map, MapTheme theme, Random rand, Coord center)
|
||||||
{
|
{
|
||||||
// half width, half height actually
|
// half width, half height actually
|
||||||
final Coord innerSize = getInnerSize(rand);
|
final Coord innerSize = getInnerSize(rand);
|
||||||
@@ -42,7 +42,7 @@ public abstract class AbstractRectRoom implements RoomBuilder {
|
|||||||
|
|
||||||
buildExtras(map, theme, rand, min, max);
|
buildExtras(map, theme, rand, min, max);
|
||||||
|
|
||||||
return new RoomDesc(min.add(-1, -1), max);
|
return new RoomEntry(min.add(-1, -1), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ public abstract class AbstractRectRoom implements RoomBuilder {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((map.findDoors(door) & Sides.MASK_CARDINAL) == 0) {
|
if ((map.findDoors(door) & Moves.BITS_CARDINAL) == 0) {
|
||||||
map.set(door, getDoorType(theme, rand));
|
map.set(door, getDoorType(theme, rand));
|
||||||
i++; // increment pointer
|
i++; // increment pointer
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package mightypork.rogue.world.gen.rooms;
|
|||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.Calc;
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.rogue.world.entity.Entities;
|
import mightypork.rogue.world.entity.Entities;
|
||||||
import mightypork.rogue.world.entity.Entity;
|
import mightypork.rogue.world.entity.Entity;
|
||||||
@@ -17,21 +16,42 @@ public class BossRoom extends SecretRoom {
|
|||||||
@Override
|
@Override
|
||||||
protected int getDoorCount(Random rand)
|
protected int getDoorCount(Random rand)
|
||||||
{
|
{
|
||||||
return Calc.randInt(rand, 1, 3);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
||||||
{
|
{
|
||||||
|
final Coord bossPos = min.add(3, 3);
|
||||||
|
|
||||||
final Entity boss = Entities.RAT_BOSS.createEntity();
|
final Entity boss = Entities.RAT_BOSS.createEntity();
|
||||||
if (!map.putEntityInArea(boss, min, max, 100)) {
|
if (!map.addEntity(boss, bossPos)) {
|
||||||
|
throw new WorldGenError("Could not place boss.");
|
||||||
// just place it anywhere then
|
|
||||||
if (!map.putEntityInMap(boss, 100)) {
|
|
||||||
throw new WorldGenError("Could not place boss.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Entity rat;
|
||||||
|
|
||||||
|
// 4 guardian rats
|
||||||
|
|
||||||
|
rat = Entities.RAT_BROWN.createEntity();
|
||||||
|
map.addEntity(rat, min.add(1, 1));
|
||||||
|
|
||||||
|
rat = Entities.RAT_BROWN.createEntity();
|
||||||
|
map.addEntity(rat, Coord.make(max.x - 1, min.y + 1));
|
||||||
|
|
||||||
|
rat = Entities.RAT_BROWN.createEntity();
|
||||||
|
map.addEntity(rat, max.add(-1, -1));
|
||||||
|
|
||||||
|
rat = Entities.RAT_BROWN.createEntity();
|
||||||
|
map.addEntity(rat, Coord.make(min.x + 1, max.y - 1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Coord getInnerSize(Random rand)
|
||||||
|
{
|
||||||
|
return Coord.make(5, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import java.util.Random;
|
|||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.rogue.world.gen.MapTheme;
|
import mightypork.rogue.world.gen.MapTheme;
|
||||||
import mightypork.rogue.world.gen.RoomBuilder;
|
import mightypork.rogue.world.gen.RoomBuilder;
|
||||||
import mightypork.rogue.world.gen.RoomDesc;
|
import mightypork.rogue.world.gen.RoomEntry;
|
||||||
import mightypork.rogue.world.gen.ScratchMap;
|
import mightypork.rogue.world.gen.ScratchMap;
|
||||||
|
|
||||||
|
|
||||||
public class DeadEndRoom implements RoomBuilder {
|
public class DeadEndRoom implements RoomBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoomDesc buildToFit(ScratchMap map, MapTheme theme, Random rand, Coord center)
|
public RoomEntry buildRoom(ScratchMap map, MapTheme theme, Random rand, Coord center)
|
||||||
{
|
{
|
||||||
final Coord low = center.add(-1, -1);
|
final Coord low = center.add(-1, -1);
|
||||||
final Coord high = center;
|
final Coord high = center;
|
||||||
@@ -21,6 +21,6 @@ public class DeadEndRoom implements RoomBuilder {
|
|||||||
|
|
||||||
map.set(center, theme.floor());
|
map.set(center, theme.floor());
|
||||||
|
|
||||||
return new RoomDesc(low, high);
|
return new RoomEntry(low, high);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-11
@@ -9,30 +9,33 @@ import mightypork.rogue.world.gen.MapTheme;
|
|||||||
import mightypork.rogue.world.gen.ScratchMap;
|
import mightypork.rogue.world.gen.ScratchMap;
|
||||||
import mightypork.rogue.world.gen.WorldGenError;
|
import mightypork.rogue.world.gen.WorldGenError;
|
||||||
import mightypork.rogue.world.item.Item;
|
import mightypork.rogue.world.item.Item;
|
||||||
import mightypork.rogue.world.item.Items;
|
|
||||||
|
|
||||||
|
|
||||||
public class HeartPieceRoom extends SecretRoom {
|
public class ItemShrineRoom extends SecretRoom {
|
||||||
|
|
||||||
|
private final Item item;
|
||||||
|
|
||||||
|
|
||||||
|
public ItemShrineRoom(Item item)
|
||||||
|
{
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getDoorCount(Random rand)
|
protected int getDoorCount(Random rand)
|
||||||
{
|
{
|
||||||
return Calc.randInt(rand, 1, 3);
|
return Calc.randInt(rand, 1, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max)
|
||||||
{
|
{
|
||||||
final Item heart = Items.HEART_PIECE.createItem();
|
final Coord center = min.add(2, 2);
|
||||||
|
|
||||||
if (!map.putItem(heart, min.add(2, 2))) {
|
if (!map.addItem(item, center)) {
|
||||||
if (!map.putItemInArea(heart, min, max, 100)) {
|
throw new WorldGenError("Could not place item in chest.");
|
||||||
if (!map.putItemInMap(heart, 100)) {
|
|
||||||
throw new WorldGenError("Could not place heart piece.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -56,4 +56,11 @@ public class ThemeBrick implements MapTheme {
|
|||||||
{
|
{
|
||||||
return Tiles.BRICK_EXIT;
|
return Tiles.BRICK_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileModel chest()
|
||||||
|
{
|
||||||
|
return Tiles.BRICK_CHEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import mightypork.gamecore.input.InputSystem;
|
|||||||
import mightypork.gamecore.input.Keys;
|
import mightypork.gamecore.input.Keys;
|
||||||
import mightypork.gamecore.input.events.KeyEvent;
|
import mightypork.gamecore.input.events.KeyEvent;
|
||||||
import mightypork.gamecore.input.events.KeyListener;
|
import mightypork.gamecore.input.events.KeyListener;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||||
import mightypork.rogue.world.entity.impl.PlayerEntity;
|
import mightypork.rogue.world.entity.impl.PlayerEntity;
|
||||||
import mightypork.rogue.world.events.PlayerStepEndListener;
|
import mightypork.rogue.world.events.PlayerStepEndListener;
|
||||||
@@ -17,7 +17,7 @@ import mightypork.rogue.world.gui.MapView;
|
|||||||
public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndListener, KeyListener, Updateable {
|
public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndListener, KeyListener, Updateable {
|
||||||
|
|
||||||
private static final int[] keys = { Keys.LEFT, Keys.RIGHT, Keys.UP, Keys.DOWN };
|
private static final int[] keys = { Keys.LEFT, Keys.RIGHT, Keys.UP, Keys.DOWN };
|
||||||
private static final Step[] sides = { Sides.W, Sides.E, Sides.N, Sides.S };
|
private static final Move[] sides = { Moves.W, Moves.E, Moves.N, Moves.S };
|
||||||
|
|
||||||
|
|
||||||
public MIPKeyboard(MapView mapView)
|
public MIPKeyboard(MapView mapView)
|
||||||
@@ -72,7 +72,7 @@ public class MIPKeyboard extends MapInteractionPlugin implements PlayerStepEndLi
|
|||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (InputSystem.isKeyDown(keys[i])) {
|
if (InputSystem.isKeyDown(keys[i])) {
|
||||||
|
|
||||||
final Step side = sides[i];
|
final Move side = sides[i];
|
||||||
if (mapView.plc.canGo(side)) {
|
if (mapView.plc.canGo(side)) {
|
||||||
mapView.plc.go(side);
|
mapView.plc.go(side);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import mightypork.gamecore.input.InputSystem;
|
|||||||
import mightypork.gamecore.util.math.Calc.Deg;
|
import mightypork.gamecore.util.math.Calc.Deg;
|
||||||
import mightypork.gamecore.util.math.Polar;
|
import mightypork.gamecore.util.math.Polar;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||||
import mightypork.rogue.world.entity.impl.PlayerEntity;
|
import mightypork.rogue.world.entity.impl.PlayerEntity;
|
||||||
import mightypork.rogue.world.events.PlayerStepEndListener;
|
import mightypork.rogue.world.events.PlayerStepEndListener;
|
||||||
@@ -97,16 +97,16 @@ public class MIPMouse extends MapInteractionPlugin implements PlayerStepEndListe
|
|||||||
|
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case 0:
|
case 0:
|
||||||
return mapView.plc.tryGo(Sides.E);
|
return mapView.plc.tryGo(Moves.E);
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return mapView.plc.tryGo(Sides.S);
|
return mapView.plc.tryGo(Moves.S);
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
return mapView.plc.tryGo(Sides.W);
|
return mapView.plc.tryGo(Moves.W);
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
return mapView.plc.tryGo(Sides.N);
|
return mapView.plc.tryGo(Moves.N);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -10,11 +10,7 @@ import mightypork.rogue.world.item.impl.active.ItemHeartPiece;
|
|||||||
import mightypork.rogue.world.item.impl.food.ItemCheese;
|
import mightypork.rogue.world.item.impl.food.ItemCheese;
|
||||||
import mightypork.rogue.world.item.impl.food.ItemMeat;
|
import mightypork.rogue.world.item.impl.food.ItemMeat;
|
||||||
import mightypork.rogue.world.item.impl.food.ItemSandwich;
|
import mightypork.rogue.world.item.impl.food.ItemSandwich;
|
||||||
import mightypork.rogue.world.item.impl.weapons.ItemBone;
|
import mightypork.rogue.world.item.impl.weapons.*;
|
||||||
import mightypork.rogue.world.item.impl.weapons.ItemClub;
|
|
||||||
import mightypork.rogue.world.item.impl.weapons.ItemHammer;
|
|
||||||
import mightypork.rogue.world.item.impl.weapons.ItemStone;
|
|
||||||
import mightypork.rogue.world.item.impl.weapons.ItemSword;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,10 +27,12 @@ public final class Items {
|
|||||||
public static final ItemModel BONE = new ItemModel(3, ItemBone.class);
|
public static final ItemModel BONE = new ItemModel(3, ItemBone.class);
|
||||||
public static final ItemModel SANDWICH = new ItemModel(4, ItemSandwich.class);
|
public static final ItemModel SANDWICH = new ItemModel(4, ItemSandwich.class);
|
||||||
public static final ItemModel CLUB = new ItemModel(5, ItemClub.class);
|
public static final ItemModel CLUB = new ItemModel(5, ItemClub.class);
|
||||||
public static final ItemModel HAMMER = new ItemModel(6, ItemHammer.class);
|
public static final ItemModel AXE = new ItemModel(6, ItemAxe.class);
|
||||||
public static final ItemModel SWORD = new ItemModel(7, ItemSword.class);
|
public static final ItemModel SWORD = new ItemModel(7, ItemSword.class);
|
||||||
public static final ItemModel ROCK = new ItemModel(8, ItemStone.class);
|
public static final ItemModel ROCK = new ItemModel(8, ItemRock.class);
|
||||||
public static final ItemModel HEART_PIECE = new ItemModel(9, ItemHeartPiece.class);
|
public static final ItemModel HEART_PIECE = new ItemModel(9, ItemHeartPiece.class);
|
||||||
|
public static final ItemModel TWIG = new ItemModel(10, ItemTwig.class);
|
||||||
|
public static final ItemModel KNIFE = new ItemModel(11, ItemKnife.class);
|
||||||
|
|
||||||
|
|
||||||
public static void register(int id, ItemModel model)
|
public static void register(int id, ItemModel model)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class ItemHeartPiece extends Item {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.heart_piece"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.heart_piece"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class ItemCheese extends ItemBaseFood {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.cheese"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.cheese"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class ItemMeat extends ItemBaseFood {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.meat"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.meat"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class ItemSandwich extends ItemBaseFood {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.sandwich"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.sandwich"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -8,9 +8,9 @@ import mightypork.rogue.world.item.impl.ItemBaseWeapon;
|
|||||||
import mightypork.rogue.world.item.render.QuadItemRenderer;
|
import mightypork.rogue.world.item.render.QuadItemRenderer;
|
||||||
|
|
||||||
|
|
||||||
public class ItemHammer extends ItemBaseWeapon {
|
public class ItemAxe extends ItemBaseWeapon {
|
||||||
|
|
||||||
public ItemHammer(ItemModel model)
|
public ItemAxe(ItemModel model)
|
||||||
{
|
{
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ public class ItemHammer extends ItemBaseWeapon {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.hammer"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.axe"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -33,13 +33,13 @@ public class ItemHammer extends ItemBaseWeapon {
|
|||||||
@Override
|
@Override
|
||||||
public int getMaxUses()
|
public int getMaxUses()
|
||||||
{
|
{
|
||||||
return 100;
|
return 70;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVisualName()
|
public String getVisualName()
|
||||||
{
|
{
|
||||||
return "Hammer";
|
return "Axe";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ public class ItemBone extends ItemBaseWeapon {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.bone"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.bone"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class ItemClub extends ItemBaseWeapon {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.club"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.club"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -8,9 +8,9 @@ import mightypork.rogue.world.item.impl.ItemBaseWeapon;
|
|||||||
import mightypork.rogue.world.item.render.QuadItemRenderer;
|
import mightypork.rogue.world.item.render.QuadItemRenderer;
|
||||||
|
|
||||||
|
|
||||||
public class ItemStone extends ItemBaseWeapon {
|
public class ItemRock extends ItemBaseWeapon {
|
||||||
|
|
||||||
public ItemStone(ItemModel model)
|
public ItemRock(ItemModel model)
|
||||||
{
|
{
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ public class ItemStone extends ItemBaseWeapon {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.stone"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.stone"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -19,14 +19,14 @@ public class ItemSword extends ItemBaseWeapon {
|
|||||||
@Override
|
@Override
|
||||||
protected ItemRenderer makeRenderer()
|
protected ItemRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new QuadItemRenderer(this, Res.txq("item.sword"));
|
return new QuadItemRenderer(this, Res.getTxQuad("item.sword"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAttackPoints()
|
public int getAttackPoints()
|
||||||
{
|
{
|
||||||
return 6;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,8 +16,8 @@ import mightypork.gamecore.util.ion.IonObjBinary;
|
|||||||
import mightypork.gamecore.util.ion.IonOutput;
|
import mightypork.gamecore.util.ion.IonOutput;
|
||||||
import mightypork.gamecore.util.math.Calc;
|
import mightypork.gamecore.util.math.Calc;
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.gamecore.util.math.algo.floodfill.FloodFill;
|
import mightypork.gamecore.util.math.algo.floodfill.FloodFill;
|
||||||
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
import mightypork.gamecore.util.math.constraints.vect.Vect;
|
||||||
import mightypork.gamecore.util.math.noise.NoiseGen;
|
import mightypork.gamecore.util.math.noise.NoiseGen;
|
||||||
@@ -63,9 +63,9 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl
|
|||||||
private final FloodFill exploreFiller = new FloodFill() {
|
private final FloodFill exploreFiller = new FloodFill() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Step[] getSpreadSides()
|
public List<Move> getSpreadSides()
|
||||||
{
|
{
|
||||||
return Sides.ALL_SIDES;
|
return Moves.ALL_SIDES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package mightypork.rogue.world.level.render;
|
|||||||
|
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
import mightypork.gamecore.util.math.algo.Step;
|
import mightypork.gamecore.util.math.algo.Move;
|
||||||
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
||||||
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
|
import mightypork.gamecore.util.math.constraints.rect.proxy.RectBound;
|
||||||
import mightypork.gamecore.util.math.noise.NoiseGen;
|
import mightypork.gamecore.util.math.noise.NoiseGen;
|
||||||
@@ -46,7 +46,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
|
|||||||
* @param offset offsets
|
* @param offset offsets
|
||||||
* @return the tile at that position
|
* @return the tile at that position
|
||||||
*/
|
*/
|
||||||
public Tile getAdjacentTile(Step offset)
|
public Tile getAdjacentTile(Move offset)
|
||||||
{
|
{
|
||||||
return map.getTile(pos.add(offset));
|
return map.getTile(pos.add(offset));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ public abstract class Tile implements BusAccess, IonObjBlob {
|
|||||||
@DefaultImpl
|
@DefaultImpl
|
||||||
public void renderExtra(TileRenderContext context)
|
public void renderExtra(TileRenderContext context)
|
||||||
{
|
{
|
||||||
|
initRenderer();
|
||||||
|
renderer.renderExtra(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,7 +4,8 @@ package mightypork.rogue.world.tile;
|
|||||||
import mightypork.gamecore.eventbus.events.Updateable;
|
import mightypork.gamecore.eventbus.events.Updateable;
|
||||||
import mightypork.gamecore.render.Render;
|
import mightypork.gamecore.render.Render;
|
||||||
import mightypork.gamecore.resources.textures.TxQuad;
|
import mightypork.gamecore.resources.textures.TxQuad;
|
||||||
import mightypork.gamecore.util.math.algo.Sides;
|
import mightypork.gamecore.util.annot.DefaultImpl;
|
||||||
|
import mightypork.gamecore.util.math.algo.Moves;
|
||||||
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
import mightypork.gamecore.util.math.constraints.rect.Rect;
|
||||||
import mightypork.rogue.Res;
|
import mightypork.rogue.Res;
|
||||||
import mightypork.rogue.world.level.render.TileRenderContext;
|
import mightypork.rogue.world.level.render.TileRenderContext;
|
||||||
@@ -44,24 +45,24 @@ public abstract class TileRenderer implements Updateable {
|
|||||||
this.tile = tile;
|
this.tile = tile;
|
||||||
|
|
||||||
if (!inited) {
|
if (!inited) {
|
||||||
SH_N = Res.txq("tile.shadow.n");
|
SH_N = Res.getTxQuad("tile.shadow.n");
|
||||||
SH_S = Res.txq("tile.shadow.s");
|
SH_S = Res.getTxQuad("tile.shadow.s");
|
||||||
SH_E = Res.txq("tile.shadow.e");
|
SH_E = Res.getTxQuad("tile.shadow.e");
|
||||||
SH_W = Res.txq("tile.shadow.w");
|
SH_W = Res.getTxQuad("tile.shadow.w");
|
||||||
SH_NW = Res.txq("tile.shadow.nw");
|
SH_NW = Res.getTxQuad("tile.shadow.nw");
|
||||||
SH_NE = Res.txq("tile.shadow.ne");
|
SH_NE = Res.getTxQuad("tile.shadow.ne");
|
||||||
SH_SW = Res.txq("tile.shadow.sw");
|
SH_SW = Res.getTxQuad("tile.shadow.sw");
|
||||||
SH_SE = Res.txq("tile.shadow.se");
|
SH_SE = Res.getTxQuad("tile.shadow.se");
|
||||||
|
|
||||||
UFOG_N = Res.txq("tile.ufog.n");
|
UFOG_N = Res.getTxQuad("tile.ufog.n");
|
||||||
UFOG_S = Res.txq("tile.ufog.s");
|
UFOG_S = Res.getTxQuad("tile.ufog.s");
|
||||||
UFOG_E = Res.txq("tile.ufog.e");
|
UFOG_E = Res.getTxQuad("tile.ufog.e");
|
||||||
UFOG_W = Res.txq("tile.ufog.w");
|
UFOG_W = Res.getTxQuad("tile.ufog.w");
|
||||||
UFOG_NW = Res.txq("tile.ufog.nw");
|
UFOG_NW = Res.getTxQuad("tile.ufog.nw");
|
||||||
UFOG_NE = Res.txq("tile.ufog.ne");
|
UFOG_NE = Res.getTxQuad("tile.ufog.ne");
|
||||||
UFOG_SW = Res.txq("tile.ufog.sw");
|
UFOG_SW = Res.getTxQuad("tile.ufog.sw");
|
||||||
UFOG_SE = Res.txq("tile.ufog.se");
|
UFOG_SE = Res.getTxQuad("tile.ufog.se");
|
||||||
UFOG_FULL = Res.txq("tile.ufog.full");
|
UFOG_FULL = Res.getTxQuad("tile.ufog.full");
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,9 +79,9 @@ public abstract class TileRenderer implements Updateable {
|
|||||||
shadows = 0; // reset the mask
|
shadows = 0; // reset the mask
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
final Tile t2 = context.getAdjacentTile(Sides.get(i));
|
final Tile t2 = context.getAdjacentTile(Moves.getSide(i));
|
||||||
if (!t2.isNull() && t2.doesCastShadow()) {
|
if (!t2.isNull() && t2.doesCastShadow()) {
|
||||||
shadows |= Sides.bit(i);
|
shadows |= Moves.getBit(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,16 +91,22 @@ public abstract class TileRenderer implements Updateable {
|
|||||||
if (shadows == 0) return;
|
if (shadows == 0) return;
|
||||||
final Rect rect = context.getRect();
|
final Rect rect = context.getRect();
|
||||||
|
|
||||||
if ((shadows & Sides.NW_CORNER) == Sides.MASK_NW) Render.quadTextured(rect, SH_NW);
|
if ((shadows & Moves.BITS_NW_CORNER) == Moves.BIT_NW) Render.quadTextured(rect, SH_NW);
|
||||||
if ((shadows & Sides.MASK_N) != 0) Render.quadTextured(rect, SH_N);
|
if ((shadows & Moves.BIT_N) != 0) Render.quadTextured(rect, SH_N);
|
||||||
if ((shadows & Sides.NE_CORNER) == Sides.MASK_NE) Render.quadTextured(rect, SH_NE);
|
if ((shadows & Moves.BITS_NE_CORNER) == Moves.BIT_NE) Render.quadTextured(rect, SH_NE);
|
||||||
|
|
||||||
if ((shadows & Sides.MASK_W) != 0) Render.quadTextured(rect, SH_W);
|
if ((shadows & Moves.BIT_W) != 0) Render.quadTextured(rect, SH_W);
|
||||||
if ((shadows & Sides.MASK_E) != 0) Render.quadTextured(rect, SH_E);
|
if ((shadows & Moves.BIT_E) != 0) Render.quadTextured(rect, SH_E);
|
||||||
|
|
||||||
if ((shadows & Sides.SW_CORNER) == Sides.MASK_SW) Render.quadTextured(rect, SH_SW);
|
if ((shadows & Moves.BITS_SW_CORNER) == Moves.BIT_SW) Render.quadTextured(rect, SH_SW);
|
||||||
if ((shadows & Sides.MASK_S) != 0) Render.quadTextured(rect, SH_S);
|
if ((shadows & Moves.BIT_S) != 0) Render.quadTextured(rect, SH_S);
|
||||||
if ((shadows & Sides.SE_CORNER) == Sides.MASK_SE) Render.quadTextured(rect, SH_SE);
|
if ((shadows & Moves.BITS_SE_CORNER) == Moves.BIT_SE) Render.quadTextured(rect, SH_SE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@DefaultImpl
|
||||||
|
public void renderExtra(TileRenderContext context)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -117,24 +124,24 @@ public abstract class TileRenderer implements Updateable {
|
|||||||
byte ufog = 0;
|
byte ufog = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
final Tile t2 = context.getAdjacentTile(Sides.get(i));
|
final Tile t2 = context.getAdjacentTile(Moves.getSide(i));
|
||||||
if (t2.isNull() || !t2.isExplored()) {
|
if (t2.isNull() || !t2.isExplored()) {
|
||||||
ufog |= Sides.bit(i);
|
ufog |= Moves.getBit(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ufog == 0) return;
|
if (ufog == 0) return;
|
||||||
|
|
||||||
if ((ufog & Sides.NW_CORNER) == Sides.MASK_NW) Render.quadTextured(rect, UFOG_NW);
|
if ((ufog & Moves.BITS_NW_CORNER) == Moves.BIT_NW) Render.quadTextured(rect, UFOG_NW);
|
||||||
if ((ufog & Sides.MASK_N) != 0) Render.quadTextured(rect, UFOG_N);
|
if ((ufog & Moves.BIT_N) != 0) Render.quadTextured(rect, UFOG_N);
|
||||||
if ((ufog & Sides.NE_CORNER) == Sides.MASK_NE) Render.quadTextured(rect, UFOG_NE);
|
if ((ufog & Moves.BITS_NE_CORNER) == Moves.BIT_NE) Render.quadTextured(rect, UFOG_NE);
|
||||||
|
|
||||||
if ((ufog & Sides.MASK_W) != 0) Render.quadTextured(rect, UFOG_W);
|
if ((ufog & Moves.BIT_W) != 0) Render.quadTextured(rect, UFOG_W);
|
||||||
if ((ufog & Sides.MASK_E) != 0) Render.quadTextured(rect, UFOG_E);
|
if ((ufog & Moves.BIT_E) != 0) Render.quadTextured(rect, UFOG_E);
|
||||||
|
|
||||||
if ((ufog & Sides.SW_CORNER) == Sides.MASK_SW) Render.quadTextured(rect, UFOG_SW);
|
if ((ufog & Moves.BITS_SW_CORNER) == Moves.BIT_SW) Render.quadTextured(rect, UFOG_SW);
|
||||||
if ((ufog & Sides.MASK_S) != 0) Render.quadTextured(rect, UFOG_S);
|
if ((ufog & Moves.BIT_S) != 0) Render.quadTextured(rect, UFOG_S);
|
||||||
if ((ufog & Sides.SE_CORNER) == Sides.MASK_SE) Render.quadTextured(rect, UFOG_SE);
|
if ((ufog & Moves.BITS_SE_CORNER) == Moves.BIT_SE) Render.quadTextured(rect, UFOG_SE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package mightypork.rogue.world.tile;
|
|||||||
|
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.color.Color;
|
import mightypork.gamecore.util.math.color.Color;
|
||||||
import mightypork.gamecore.util.math.color.pal.PAL16;
|
|
||||||
import mightypork.gamecore.util.math.color.pal.RGB;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,25 +12,25 @@ import mightypork.gamecore.util.math.color.pal.RGB;
|
|||||||
public enum TileType
|
public enum TileType
|
||||||
{
|
{
|
||||||
/** No tile */
|
/** No tile */
|
||||||
NULL(RGB.NONE, false),
|
NULL(TileColors.NULL, false),
|
||||||
/** Floor tile */
|
/** Floor tile */
|
||||||
FLOOR(RGB.GRAY_DARK, true),
|
FLOOR(TileColors.FLOOR, true),
|
||||||
/** Wall tile */
|
/** Wall tile */
|
||||||
WALL(RGB.GRAY_LIGHT, false),
|
WALL(TileColors.WALL, false),
|
||||||
/** Door/gate tile */
|
/** Door/gate tile */
|
||||||
DOOR(PAL16.NEWPOOP, true),
|
DOOR(TileColors.DOOR, true),
|
||||||
/** Passage (ie secret door) */
|
/** Passage (ie secret door) */
|
||||||
PASSAGE(RGB.GRAY, true),
|
PASSAGE(TileColors.COLLAPSED_WALL, true),
|
||||||
/** Stairs */
|
/** Stairs */
|
||||||
STAIRS(RGB.CYAN, false);
|
STAIRS(TileColors.WALL, false);
|
||||||
|
|
||||||
private final Color mapColor;
|
private final Color mapColor;
|
||||||
private final boolean potentiallyWalkable;
|
private final boolean potentiallyWalkable;
|
||||||
|
|
||||||
|
|
||||||
private TileType(Color mapColor, boolean potentiallyWalkable)
|
private TileType(Color defaultMapColor, boolean potentiallyWalkable)
|
||||||
{
|
{
|
||||||
this.mapColor = mapColor;
|
this.mapColor = defaultMapColor;
|
||||||
this.potentiallyWalkable = potentiallyWalkable;
|
this.potentiallyWalkable = potentiallyWalkable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public final class Tiles {
|
|||||||
public static final TileModel BRICK_HIDDEN_DOOR = new TileModel(14, TileBrickSecretDoor.class);
|
public static final TileModel BRICK_HIDDEN_DOOR = new TileModel(14, TileBrickSecretDoor.class);
|
||||||
public static final TileModel BRICK_ENTRANCE = new TileModel(15, TileBrickEntrance.class);
|
public static final TileModel BRICK_ENTRANCE = new TileModel(15, TileBrickEntrance.class);
|
||||||
public static final TileModel BRICK_EXIT = new TileModel(16, TileBrickExit.class);
|
public static final TileModel BRICK_EXIT = new TileModel(16, TileBrickExit.class);
|
||||||
|
public static final TileModel BRICK_CHEST = new TileModel(17, TileBrickChest.class);
|
||||||
|
|
||||||
|
|
||||||
public static void register(int id, TileModel model)
|
public static void register(int id, TileModel model)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@ package mightypork.rogue.world.tile.impl;
|
|||||||
|
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
|
import mightypork.gamecore.util.math.color.Color;
|
||||||
import mightypork.rogue.world.events.WorldAscendRequest;
|
import mightypork.rogue.world.events.WorldAscendRequest;
|
||||||
|
import mightypork.rogue.world.tile.TileColors;
|
||||||
import mightypork.rogue.world.tile.TileModel;
|
import mightypork.rogue.world.tile.TileModel;
|
||||||
|
|
||||||
|
|
||||||
@@ -31,4 +33,11 @@ public abstract class TileBaseEntrance extends TileBaseStairs {
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getMapColor()
|
||||||
|
{
|
||||||
|
return TileColors.ENTRANCE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package mightypork.rogue.world.tile.impl;
|
|||||||
|
|
||||||
|
|
||||||
import mightypork.gamecore.util.math.algo.Coord;
|
import mightypork.gamecore.util.math.algo.Coord;
|
||||||
|
import mightypork.gamecore.util.math.color.Color;
|
||||||
import mightypork.rogue.world.events.WorldDescendRequest;
|
import mightypork.rogue.world.events.WorldDescendRequest;
|
||||||
|
import mightypork.rogue.world.tile.TileColors;
|
||||||
import mightypork.rogue.world.tile.TileModel;
|
import mightypork.rogue.world.tile.TileModel;
|
||||||
|
|
||||||
|
|
||||||
@@ -31,4 +33,11 @@ public abstract class TileBaseExit extends TileBaseStairs {
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getMapColor()
|
||||||
|
{
|
||||||
|
return TileColors.EXIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ import java.io.IOException;
|
|||||||
import mightypork.gamecore.resources.textures.TxSheet;
|
import mightypork.gamecore.resources.textures.TxSheet;
|
||||||
import mightypork.gamecore.util.ion.IonInput;
|
import mightypork.gamecore.util.ion.IonInput;
|
||||||
import mightypork.gamecore.util.ion.IonOutput;
|
import mightypork.gamecore.util.ion.IonOutput;
|
||||||
import mightypork.gamecore.util.math.Calc;
|
|
||||||
import mightypork.gamecore.util.math.color.Color;
|
import mightypork.gamecore.util.math.color.Color;
|
||||||
import mightypork.gamecore.util.math.color.pal.RGB;
|
import mightypork.rogue.world.tile.TileColors;
|
||||||
import mightypork.rogue.world.tile.TileModel;
|
import mightypork.rogue.world.tile.TileModel;
|
||||||
import mightypork.rogue.world.tile.TileType;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class TileBaseSecretDoor extends TileBaseDoor {
|
public abstract class TileBaseSecretDoor extends TileBaseDoor {
|
||||||
|
|
||||||
private int clicks = Calc.randInt(2, 3);
|
private int clicks = 2;
|
||||||
|
|
||||||
|
|
||||||
public TileBaseSecretDoor(TileModel model, TxSheet secret, TxSheet closed, TxSheet open)
|
public TileBaseSecretDoor(TileModel model, TxSheet secret, TxSheet closed, TxSheet open)
|
||||||
@@ -43,8 +41,8 @@ public abstract class TileBaseSecretDoor extends TileBaseDoor {
|
|||||||
@Override
|
@Override
|
||||||
public Color getMapColor()
|
public Color getMapColor()
|
||||||
{
|
{
|
||||||
if (locked) return TileType.WALL.getMapColor();
|
if (locked) return TileColors.SECRET_DOOR_HIDDEN;
|
||||||
return RGB.PINK;
|
return TileColors.SECRET_DOOR_REVEALED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,20 @@ public abstract class TileWithItems extends Tile {
|
|||||||
@Override
|
@Override
|
||||||
public void renderExtra(TileRenderContext context)
|
public void renderExtra(TileRenderContext context)
|
||||||
{
|
{
|
||||||
if ((isExplored() || !Config.RENDER_UFOG) && !items.isEmpty()) {
|
super.renderExtra(context);
|
||||||
|
|
||||||
|
if ((isExplored() || !Config.RENDER_UFOG) && hasItem() && shouldRenderItems()) {
|
||||||
itemRenderer.render(items, context);
|
itemRenderer.render(items, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected boolean shouldRenderItems()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(double delta)
|
public void updateTile(double 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,9 +13,9 @@ public class TileBrickDoor extends TileBaseDoor {
|
|||||||
//@formatter:off
|
//@formatter:off
|
||||||
super(
|
super(
|
||||||
model,
|
model,
|
||||||
Res.txs("tile.brick.door.closed"), // LOCKED
|
Res.getTxSheet("tile.brick.door.closed"), // LOCKED
|
||||||
Res.txs("tile.brick.door.closed"),
|
Res.getTxSheet("tile.brick.door.closed"),
|
||||||
Res.txs("tile.brick.door.open")
|
Res.getTxSheet("tile.brick.door.open")
|
||||||
);
|
);
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class TileBrickEntrance extends TileBaseEntrance {
|
|||||||
@Override
|
@Override
|
||||||
protected TileRenderer makeRenderer()
|
protected TileRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new OneFrameTileRenderer(this, Res.txq("tile.brick.stairs.up"));
|
return new OneFrameTileRenderer(this, Res.getTxQuad("tile.brick.stairs.up"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class TileBrickExit extends TileBaseExit {
|
|||||||
@Override
|
@Override
|
||||||
protected TileRenderer makeRenderer()
|
protected TileRenderer makeRenderer()
|
||||||
{
|
{
|
||||||
return new OneFrameTileRenderer(this, Res.txq("tile.brick.stairs.down"));
|
return new OneFrameTileRenderer(this, Res.getTxQuad("tile.brick.stairs.down"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class TileBrickFloor extends TileBaseFloor {
|
|||||||
|
|
||||||
public TileBrickFloor(TileModel model)
|
public TileBrickFloor(TileModel model)
|
||||||
{
|
{
|
||||||
super(model, Res.txs("tile.brick.floor"));
|
super(model, Res.getTxSheet("tile.brick.floor"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class TileBrickPassage extends TileBasePassage {
|
|||||||
|
|
||||||
public TileBrickPassage(TileModel model)
|
public TileBrickPassage(TileModel model)
|
||||||
{
|
{
|
||||||
super(model, Res.txs("tile.brick.passage"));
|
super(model, Res.getTxSheet("tile.brick.passage"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ public class TileBrickSecretDoor extends TileBaseSecretDoor {
|
|||||||
//@formatter:off
|
//@formatter:off
|
||||||
super(
|
super(
|
||||||
model,
|
model,
|
||||||
Res.txs("tile.brick.door.secret"),
|
Res.getTxSheet("tile.brick.door.secret"),
|
||||||
Res.txs("tile.brick.door.closed"),
|
Res.getTxSheet("tile.brick.door.closed"),
|
||||||
Res.txs("tile.brick.door.open")
|
Res.getTxSheet("tile.brick.door.open")
|
||||||
);
|
);
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class TileBrickWall extends TileBaseWall {
|
|||||||
|
|
||||||
public TileBrickWall(TileModel model)
|
public TileBrickWall(TileModel model)
|
||||||
{
|
{
|
||||||
super(model, Res.txs("tile.brick.wall"));
|
super(model, Res.getTxSheet("tile.brick.wall"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user