Converted ShatteredPD to Build from Gradle

Major Changes:
- Shattered now builds effortlessly either from gradle CLI or android studio
- Much better dependency management through gradle (although it's not really used atm)
- Separate PD-classes repo is now SPD-classes module within main repo
This commit is contained in:
Evan Debenham
2016-08-13 02:11:29 -04:00
parent 188523b2a5
commit 36e44340a8
954 changed files with 8530 additions and 14 deletions
@@ -0,0 +1,125 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class BitmapCache {
private static final String DEFAULT = "__default";
private static HashMap<String,Layer> layers = new HashMap<String, BitmapCache.Layer>();
private static BitmapFactory.Options opts = new BitmapFactory.Options();
static {
opts.inDither = false;
}
public static Context context;
public static Bitmap get( String assetName ) {
return get( DEFAULT, assetName );
}
public static Bitmap get( String layerName, String assetName ) {
Layer layer;
if (!layers.containsKey( layerName )) {
layer = new Layer();
layers.put( layerName, layer );
} else {
layer = layers.get( layerName );
}
if (layer.containsKey( assetName )) {
return layer.get( assetName );
} else {
try {
InputStream stream = context.getResources().getAssets().open( assetName );
Bitmap bmp = BitmapFactory.decodeStream( stream, null, opts );
layer.put( assetName, bmp );
return bmp;
} catch (IOException e) {
return null;
}
}
}
public static Bitmap get( int resID ) {
return get( DEFAULT, resID );
}
public static Bitmap get( String layerName, int resID ) {
Layer layer;
if (!layers.containsKey( layerName )) {
layer = new Layer();
layers.put( layerName, layer );
} else {
layer = layers.get( layerName );
}
if (layer.containsKey( resID )) {
return layer.get( resID );
} else {
Bitmap bmp = BitmapFactory.decodeResource( context.getResources(), resID );
layer.put( resID, bmp );
return bmp;
}
}
public static void clear( String layerName ) {
if (layers.containsKey( layerName )) {
layers.get( layerName ).clear();
layers.remove( layerName );
}
}
public static void clear() {
for (Layer layer:layers.values()) {
layer.clear();
}
layers.clear();
}
@SuppressWarnings("serial")
private static class Layer extends HashMap<Object,Bitmap> {
@Override
public void clear() {
for (Bitmap bmp:values()) {
bmp.recycle();
}
super.clear();
}
}
}
@@ -0,0 +1,63 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.HashMap;
import android.graphics.Bitmap;
import android.graphics.Rect;
public class BitmapFilm {
public Bitmap bitmap;
protected HashMap<Object,Rect> frames = new HashMap<Object, Rect>();
public BitmapFilm( Bitmap bitmap ) {
this.bitmap = bitmap;
add( null, new Rect( 0, 0, bitmap.getWidth(), bitmap.getHeight() ) );
}
public BitmapFilm( Bitmap bitmap, int width ) {
this( bitmap, width, bitmap.getHeight() );
}
public BitmapFilm( Bitmap bitmap, int width, int height ) {
this.bitmap = bitmap;
int cols = bitmap.getWidth() / width;
int rows = bitmap.getHeight() / height;
for (int i=0; i < rows; i++) {
for (int j=0; j < cols; j++) {
Rect rect = new Rect( j * width, i * height, (j+1) * width, (i+1) * height );
add( i * cols + j, rect );
}
}
}
public void add( Object id, Rect rect ) {
frames.put( id, rect );
}
public Rect get( Object id ) {
return frames.get( id );
}
}
@@ -0,0 +1,29 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
public interface Bundlable {
void restoreFromBundle( Bundle bundle );
void storeInBundle( Bundle bundle );
}
@@ -0,0 +1,411 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PushbackInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class Bundle {
private static final String CLASS_NAME = "__className";
private static HashMap<String,String> aliases = new HashMap<String, String>();
private JSONObject data;
public Bundle() {
this( new JSONObject() );
}
public String toString() {
return data.toString();
}
private Bundle( JSONObject data ) {
this.data = data;
}
public boolean isNull() {
return data == null;
}
public boolean contains( String key ) {
return !data.isNull( key );
}
public boolean getBoolean( String key ) {
return data.optBoolean( key );
}
public int getInt( String key ) {
return data.optInt( key );
}
public float getFloat( String key ) {
return (float)data.optDouble( key, 0.0 );
}
public String getString( String key ) {
return data.optString( key );
}
public Class getClass( String key ) {
String clName = getString(key).replace("class ", "");;
if (clName != null){
if (aliases.containsKey( clName )) {
clName = aliases.get( clName );
}
try {
Class cl = Class.forName( clName );
return cl;
} catch (ClassNotFoundException e) {
return null;
}
}
return null;
}
public Bundle getBundle( String key ) {
return new Bundle( data.optJSONObject( key ) );
}
private Bundlable get() {
if (data == null) return null;
try {
String clName = getString( CLASS_NAME );
if (aliases.containsKey( clName )) {
clName = aliases.get( clName );
}
Class<?> cl = Class.forName( clName );
if (cl != null) {
Bundlable object = (Bundlable)cl.newInstance();
object.restoreFromBundle( this );
return object;
} else {
return null;
}
} catch (ClassNotFoundException e ) {
return null;
} catch (InstantiationException e ) {
return null;
} catch (IllegalAccessException e ) {
return null;
}
}
public Bundlable get( String key ) {
return getBundle( key ).get();
}
public <E extends Enum<E>> E getEnum( String key, Class<E> enumClass ) {
try {
return Enum.valueOf( enumClass, data.getString( key ) );
} catch (JSONException e) {
return enumClass.getEnumConstants()[0];
}
}
public int[] getIntArray( String key ) {
try {
JSONArray array = data.getJSONArray( key );
int length = array.length();
int[] result = new int[length];
for (int i=0; i < length; i++) {
result[i] = array.getInt( i );
}
return result;
} catch (JSONException e) {
return null;
}
}
public boolean[] getBooleanArray( String key ) {
try {
JSONArray array = data.getJSONArray( key );
int length = array.length();
boolean[] result = new boolean[length];
for (int i=0; i < length; i++) {
result[i] = array.getBoolean( i );
}
return result;
} catch (JSONException e) {
return null;
}
}
public String[] getStringArray( String key ) {
try {
JSONArray array = data.getJSONArray( key );
int length = array.length();
String[] result = new String[length];
for (int i=0; i < length; i++) {
result[i] = array.getString( i );
}
return result;
} catch (JSONException e) {
return null;
}
}
public Class[] getClassArray( String key ) {
try {
JSONArray array = data.getJSONArray( key );
int length = array.length();
Class[] result = new Class[length];
for (int i=0; i < length; i++) {
String clName = array.getString( i ).replace("class ", "");
if (aliases.containsKey( clName )) {
clName = aliases.get( clName );
}
try {
Class cl = Class.forName( clName );
result[i] = cl;
} catch (ClassNotFoundException e) {
result[i] = null;
}
}
return result;
} catch (JSONException e) {
return null;
}
}
public Collection<Bundlable> getCollection( String key ) {
ArrayList<Bundlable> list = new ArrayList<Bundlable>();
try {
JSONArray array = data.getJSONArray( key );
for (int i=0; i < array.length(); i++) {
Bundlable O = new Bundle( array.getJSONObject( i ) ).get();
if (O != null) list.add( O );
}
} catch (JSONException e) {
}
return list;
}
public void put( String key, boolean value ) {
try {
data.put( key, value );
} catch (JSONException e) {
}
}
public void put( String key, int value ) {
try {
data.put( key, value );
} catch (JSONException e) {
}
}
public void put( String key, float value ) {
try {
data.put( key, value );
} catch (JSONException e) {
}
}
public void put( String key, String value ) {
try {
data.put( key, value );
} catch (JSONException e) {
}
}
public void put( String key, Class value ){
try {
data.put( key, value );
} catch (JSONException e) {
}
}
public void put( String key, Bundle bundle ) {
try {
data.put( key, bundle.data );
} catch (JSONException e) {
}
}
public void put( String key, Bundlable object ) {
if (object != null) {
try {
Bundle bundle = new Bundle();
bundle.put( CLASS_NAME, object.getClass().getName() );
object.storeInBundle( bundle );
data.put( key, bundle.data );
} catch (JSONException e) {
}
}
}
public void put( String key, Enum<?> value ) {
if (value != null) {
try {
data.put( key, value.name() );
} catch (JSONException e) {
}
}
}
public void put( String key, int[] array ) {
try {
JSONArray jsonArray = new JSONArray();
for (int i=0; i < array.length; i++) {
jsonArray.put( i, array[i] );
}
data.put( key, jsonArray );
} catch (JSONException e) {
}
}
public void put( String key, boolean[] array ) {
try {
JSONArray jsonArray = new JSONArray();
for (int i=0; i < array.length; i++) {
jsonArray.put( i, array[i] );
}
data.put( key, jsonArray );
} catch (JSONException e) {
}
}
public void put( String key, String[] array ) {
try {
JSONArray jsonArray = new JSONArray();
for (int i=0; i < array.length; i++) {
jsonArray.put( i, array[i] );
}
data.put( key, jsonArray );
} catch (JSONException e) {
}
}
public void put( String key, Class[] array ){
try {
JSONArray jsonArray = new JSONArray();
for (int i=0; i < array.length; i++) {
jsonArray.put( i, array[i] );
}
data.put( key, jsonArray );
} catch (JSONException e) {
}
}
public void put( String key, Collection<? extends Bundlable> collection ) {
JSONArray array = new JSONArray();
for (Bundlable object : collection) {
if (object != null) {
Bundle bundle = new Bundle();
bundle.put(CLASS_NAME, object.getClass().getName());
object.storeInBundle(bundle);
array.put(bundle.data);
}
}
try {
data.put( key, array );
} catch (JSONException e) {
}
}
//useful to turn this off for save data debugging.
private static final boolean compressByDefault = true;
private static final int GZIP_BUFFER = 1024*4; //4 kb
public static Bundle read( InputStream stream ) throws IOException {
try {
BufferedReader reader;
//determines if we're reading a regular, or compressed file
PushbackInputStream pb = new PushbackInputStream( stream, 2 );
byte[] header = new byte[2];
pb.unread(header, 0, pb.read(header));
//GZIP header is 0x1f8b
if( header[ 0 ] == (byte) 0x1f && header[ 1 ] == (byte) 0x8b )
reader = new BufferedReader( new InputStreamReader( new GZIPInputStream( pb, GZIP_BUFFER ) ) );
else
reader = new BufferedReader( new InputStreamReader( pb ) );
JSONObject json = (JSONObject)new JSONTokener( reader.readLine() ).nextValue();
reader.close();
return new Bundle( json );
} catch (Exception e) {
throw new IOException();
}
}
public static boolean write( Bundle bundle, OutputStream stream ){
return write(bundle, stream, compressByDefault);
}
public static boolean write( Bundle bundle, OutputStream stream, boolean compressed ) {
try {
BufferedWriter writer;
if (compressed) writer = new BufferedWriter( new OutputStreamWriter( new GZIPOutputStream(stream, GZIP_BUFFER ) ) );
else writer = new BufferedWriter( new OutputStreamWriter( stream ) );
writer.write( bundle.data.toString() );
writer.close();
return true;
} catch (IOException e) {
return false;
}
}
public static void addAlias( Class<?> cl, String alias ) {
aliases.put( alias, cl.getName() );
}
}
@@ -0,0 +1,28 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
public interface Callback {
void call();
}
@@ -0,0 +1,65 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
public class ColorMath {
public static int interpolate( int A, int B, float p ) {
if (p <= 0) {
return A;
} else if (p >= 1) {
return B;
}
int ra = A >> 16;
int ga = (A >> 8) & 0xFF;
int ba = A & 0xFF;
int rb = B >> 16;
int gb = (B >> 8) & 0xFF;
int bb = B & 0xFF;
float p1 = 1 - p;
int r = (int)(p1 * ra + p * rb);
int g = (int)(p1 * ga + p * gb);
int b = (int)(p1 * ba + p * bb);
return (r << 16) + (g << 8) + b;
}
public static int interpolate( float p, int... colors ) {
if (p <= 0) {
return colors[0];
} else if (p >= 1) {
return colors[colors.length-1];
}
int segment = (int)(colors.length * p);
return interpolate( colors[segment], colors[segment+1], (p * (colors.length - 1)) % 1 );
}
public static int random( int a, int b ) {
return interpolate( a, b, Random.Float() );
}
}
@@ -0,0 +1,46 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import com.watabou.noosa.Game;
public class GameMath {
public static float speed( float speed, float acc ) {
if (acc != 0) {
speed += acc * Game.elapsed;
}
return speed;
}
public static float gate( float min, float value, float max ) {
if (value < min) {
return min;
} else if (value > max) {
return max;
} else {
return value;
}
}
}
@@ -0,0 +1,107 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class Graph {
public static <T extends Node> void setPrice( List<T> nodes, int value ) {
for (T node : nodes) {
node.price( value );
}
}
public static <T extends Node> void buildDistanceMap( Collection<T> nodes, Node focus ) {
for (T node : nodes) {
node.distance( Integer.MAX_VALUE );
}
LinkedList<Node> queue = new LinkedList<Node>();
focus.distance( 0 );
queue.add( focus );
while (!queue.isEmpty()) {
Node node = queue.poll();
int distance = node.distance();
int price = node.price();
for (Node edge : node.edges()) {
if (edge.distance() > distance + price) {
queue.add( edge );
edge.distance( distance + price );
}
}
}
}
@SuppressWarnings("unchecked")
public static <T extends Node> List<T> buildPath( Collection<T> nodes, T from, T to ) {
List<T> path = new ArrayList<T>();
T room = from;
while (room != to) {
int min = room.distance();
T next = null;
Collection<? extends Node> edges = room.edges();
for (Node edge : edges) {
int distance = edge.distance();
if (distance < min) {
min = distance;
next = (T)edge;
}
}
if (next == null) {
return null;
}
path.add( next );
room = next;
}
return path;
}
public interface Node {
int distance();
void distance( int value );
int price();
void price( int value );
Collection<? extends Node> edges();
}
}
@@ -0,0 +1,81 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Highlighter {
private static final Pattern HIGHLIGHTER = Pattern.compile( "_(.*?)_" );
private static final Pattern STRIPPER = Pattern.compile( "[ \n]" );
public String text;
public boolean[] mask;
public Highlighter( String text ) {
String stripped = STRIPPER.matcher( text ).replaceAll( "" );
mask = new boolean[stripped.length()];
Matcher m = HIGHLIGHTER.matcher( stripped );
int pos = 0;
int lastMatch = 0;
while (m.find()) {
pos += (m.start() - lastMatch);
int groupLen = m.group( 1 ).length();
for (int i=pos; i < pos + groupLen; i++) {
mask[i] = true;
}
pos += groupLen;
lastMatch = m.end();
}
m.reset( text );
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement( sb, m.group( 1 ) );
}
m.appendTail( sb );
this.text = sb.toString();
}
public boolean[] inverted() {
boolean[] result = new boolean[mask.length];
for (int i=0; i < result.length; i++) {
result[i] = !mask[i];
}
return result;
}
public boolean isHighlighted() {
for (int i=0; i < mask.length; i++) {
if (mask[i]) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,340 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.Arrays;
import java.util.LinkedList;
public class PathFinder {
public static int[] distance;
private static boolean[] goals;
private static int[] queue;
private static int size = 0;
private static int[] dir;
public static void setMapSize( int width, int height ) {
int size = width * height;
if (PathFinder.size != size) {
PathFinder.size = size;
distance = new int[size];
goals = new boolean[size];
queue = new int[size];
dir = new int[]{-1, +1, -width, +width, -width-1, -width+1, +width-1, +width+1};
}
}
public static Path find( int from, int to, boolean[] passable ) {
if (!buildDistanceMap( from, to, passable )) {
return null;
}
Path result = new Path();
int s = from;
// From the starting position we are moving downwards,
// until we reach the ending point
do {
int minD = distance[s];
int mins = s;
for (int i=0; i < dir.length; i++) {
int n = s + dir[i];
int thisD = distance[n];
if (thisD < minD) {
minD = thisD;
mins = n;
}
}
s = mins;
result.add( s );
} while (s != to);
return result;
}
public static int getStep( int from, int to, boolean[] passable ) {
if (!buildDistanceMap( from, to, passable )) {
return -1;
}
// From the starting position we are making one step downwards
int minD = distance[from];
int best = from;
int step, stepD;
for (int i=0; i < dir.length; i++) {
if ((stepD = distance[step = from + dir[i]]) < minD) {
minD = stepD;
best = step;
}
}
return best;
}
public static int getStepBack( int cur, int from, boolean[] passable ) {
int d = buildEscapeDistanceMap( cur, from, 2f, passable );
for (int i=0; i < size; i++) {
goals[i] = distance[i] == d;
}
if (!buildDistanceMap( cur, goals, passable )) {
return -1;
}
int s = cur;
// From the starting position we are making one step downwards
int minD = distance[s];
int mins = s;
for (int i=0; i < dir.length; i++) {
int n = s + dir[i];
int thisD = distance[n];
if (thisD < minD) {
minD = thisD;
mins = n;
}
}
return mins;
}
private static boolean buildDistanceMap( int from, int to, boolean[] passable ) {
if (from == to) {
return false;
}
Arrays.fill( distance, Integer.MAX_VALUE );
boolean pathFound = false;
int head = 0;
int tail = 0;
// Add to queue
queue[tail++] = to;
distance[to] = 0;
while (head < tail) {
// Remove from queue
int step = queue[head++];
if (step == from) {
pathFound = true;
break;
}
int nextDistance = distance[step] + 1;
for (int i=0; i < dir.length; i++) {
int n = step + dir[i];
if (n == from || (n >= 0 && n < size && passable[n] && (distance[n] > nextDistance))) {
// Add to queue
queue[tail++] = n;
distance[n] = nextDistance;
}
}
}
return pathFound;
}
public static void buildDistanceMap( int to, boolean[] passable, int limit ) {
Arrays.fill( distance, Integer.MAX_VALUE );
int head = 0;
int tail = 0;
// Add to queue
queue[tail++] = to;
distance[to] = 0;
while (head < tail) {
// Remove from queue
int step = queue[head++];
int nextDistance = distance[step] + 1;
if (nextDistance > limit) {
return;
}
for (int i=0; i < dir.length; i++) {
int n = step + dir[i];
if (n >= 0 && n < size && passable[n] && (distance[n] > nextDistance)) {
// Add to queue
queue[tail++] = n;
distance[n] = nextDistance;
}
}
}
}
private static boolean buildDistanceMap( int from, boolean[] to, boolean[] passable ) {
if (to[from]) {
return false;
}
Arrays.fill( distance, Integer.MAX_VALUE );
boolean pathFound = false;
int head = 0;
int tail = 0;
// Add to queue
for (int i=0; i < size; i++) {
if (to[i]) {
queue[tail++] = i;
distance[i] = 0;
}
}
while (head < tail) {
// Remove from queue
int step = queue[head++];
if (step == from) {
pathFound = true;
break;
}
int nextDistance = distance[step] + 1;
for (int i=0; i < dir.length; i++) {
int n = step + dir[i];
if (n == from || (n >= 0 && n < size && passable[n] && (distance[n] > nextDistance))) {
// Add to queue
queue[tail++] = n;
distance[n] = nextDistance;
}
}
}
return pathFound;
}
private static int buildEscapeDistanceMap( int cur, int from, float factor, boolean[] passable ) {
Arrays.fill( distance, Integer.MAX_VALUE );
int destDist = Integer.MAX_VALUE;
int head = 0;
int tail = 0;
// Add to queue
queue[tail++] = from;
distance[from] = 0;
int dist = 0;
while (head < tail) {
// Remove from queue
int step = queue[head++];
dist = distance[step];
if (dist > destDist) {
return destDist;
}
if (step == cur) {
destDist = (int)(dist * factor) + 1;
}
int nextDistance = dist + 1;
for (int i=0; i < dir.length; i++) {
int n = step + dir[i];
if (n >= 0 && n < size && passable[n] && distance[n] > nextDistance) {
// Add to queue
queue[tail++] = n;
distance[n] = nextDistance;
}
}
}
return dist;
}
@SuppressWarnings("unused")
private static void buildDistanceMap( int to, boolean[] passable ) {
Arrays.fill( distance, Integer.MAX_VALUE );
int head = 0;
int tail = 0;
// Add to queue
queue[tail++] = to;
distance[to] = 0;
while (head < tail) {
// Remove from queue
int step = queue[head++];
int nextDistance = distance[step] + 1;
for (int i=0; i < dir.length; i++) {
int n = step + dir[i];
if (n >= 0 && n < size && passable[n] && (distance[n] > nextDistance)) {
// Add to queue
queue[tail++] = n;
distance[n] = nextDistance;
}
}
}
}
@SuppressWarnings("serial")
public static class Path extends LinkedList<Integer> {
}
}
@@ -0,0 +1,85 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
public class Point {
public int x;
public int y;
public Point() {
}
public Point( int x, int y ) {
this.x = x;
this.y = y;
}
public Point( Point p ) {
this.x = p.x;
this.y = p.y;
}
public Point set( int x, int y ) {
this.x = x;
this.y = y;
return this;
}
public Point set( Point p ) {
x = p.x;
y = p.y;
return this;
}
public Point clone() {
return new Point( this );
}
public Point scale( float f ) {
this.x *= f;
this.y *= f;
return this;
}
public Point offset( int dx, int dy ) {
x += dx;
y += dy;
return this;
}
public Point offset( Point d ) {
x += d.x;
y += d.y;
return this;
}
@Override
public boolean equals( Object obj ) {
if (obj instanceof Point) {
Point p = (Point)obj;
return p.x == x && p.y == y;
} else {
return false;
}
}
}
@@ -0,0 +1,154 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import android.annotation.SuppressLint;
import android.util.FloatMath;
@SuppressLint("FloatMath")
public class PointF {
public static final float PI = 3.1415926f;
public static final float PI2 = PI * 2;
public static final float G2R = PI / 180;
public float x;
public float y;
public PointF() {
}
public PointF( float x, float y ) {
this.x = x;
this.y = y;
}
public PointF( PointF p ) {
this.x = p.x;
this.y = p.y;
}
public PointF( Point p ) {
this.x = p.x;
this.y = p.y;
}
public PointF clone() {
return new PointF( this );
}
public PointF scale( float f ) {
this.x *= f;
this.y *= f;
return this;
}
public PointF invScale( float f ) {
this.x /= f;
this.y /= f;
return this;
}
public PointF set( float x, float y ) {
this.x = x;
this.y = y;
return this;
}
public PointF set( PointF p ) {
this.x = p.x;
this.y = p.y;
return this;
}
public PointF set( float v ) {
this.x = v;
this.y = v;
return this;
}
public PointF polar( float a, float l ) {
this.x = l * (float)Math.cos( a );
this.y = l * (float)Math.sin( a );
return this;
}
public PointF offset( float dx, float dy ) {
x += dx;
y += dy;
return this;
}
public PointF offset( PointF p ) {
x += p.x;
y += p.y;
return this;
}
public PointF negate() {
x = -x;
y = -y;
return this;
}
public PointF normalize() {
float l = length();
x /= l;
y /= l;
return this;
}
public Point floor() {
return new Point( (int)x, (int)y );
}
public float length() {
return (float)Math.sqrt( x * x + y * y );
}
public static PointF sum( PointF a, PointF b ) {
return new PointF( a.x + b.x, a.y + b.y );
}
public static PointF diff( PointF a, PointF b ) {
return new PointF( a.x - b.x, a.y - b.y );
}
public static PointF inter( PointF a, PointF b, float d ) {
return new PointF( a.x + (b.x - a.x) * d, a.y + (b.y - a.y) * d );
}
public static float distance( PointF a, PointF b ) {
float dx = a.x - b.x;
float dy = a.y - b.y;
return (float)Math.sqrt( dx * dx + dy * dy );
}
public static float angle( PointF start, PointF end ) {
return (float)Math.atan2( end.y - start.y, end.x - start.x );
}
@Override
public String toString() {
return "" + x + ", " + y;
}
}
@@ -0,0 +1,154 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.Collection;
import java.util.HashMap;
public class Random {
public static float Float( float min, float max ) {
return (float)(min + Math.random() * (max - min));
}
public static float Float( float max ) {
return (float)(Math.random() * max);
}
public static float Float() {
return (float)Math.random();
}
public static int Int( int max ) {
return max > 0 ? (int)(Math.random() * max) : 0;
}
public static int Int( int min, int max ) {
return min + (int)(Math.random() * (max - min));
}
public static int IntRange( int min, int max ) {
return min + (int)(Math.random() * (max - min + 1));
}
public static int NormalIntRange( int min, int max ) {
return min + (int)((Math.random() + Math.random()) * (max - min + 1) / 2f);
}
public static int chances( float[] chances ) {
int length = chances.length;
float sum = 0;
for (int i=0; i < length; i++) {
sum += chances[i];
}
float value = Float( sum );
sum = 0;
for (int i=0; i < length; i++) {
sum += chances[i];
if (value < sum) {
return i;
}
}
return -1;
}
@SuppressWarnings("unchecked")
public static <K> K chances( HashMap<K,Float> chances ) {
int size = chances.size();
Object[] values = chances.keySet().toArray();
float[] probs = new float[size];
float sum = 0;
for (int i=0; i < size; i++) {
probs[i] = chances.get( values[i] );
sum += probs[i];
}
float value = Float( sum );
sum = probs[0];
for (int i=0; i < size; i++) {
if (value < sum) {
return (K)values[i];
}
sum += probs[i + 1];
}
return null;
}
public static int index( Collection<?> collection ) {
return (int)(Math.random() * collection.size());
}
@SafeVarargs
public static<T> T oneOf( T... array ) {
return array[(int)(Math.random() * array.length)];
}
public static<T> T element( T[] array ) {
return element( array, array.length );
}
public static<T> T element( T[] array, int max ) {
return array[(int)(Math.random() * max)];
}
@SuppressWarnings("unchecked")
public static<T> T element( Collection<? extends T> collection ) {
int size = collection.size();
return size > 0 ?
(T)collection.toArray()[Int( size )] :
null;
}
public static<T> void shuffle( T[] array ) {
for (int i=0; i < array.length - 1; i++) {
int j = Int( i, array.length );
if (j != i) {
T t = array[i];
array[i] = array[j];
array[j] = t;
}
}
}
public static<U,V> void shuffle( U[] u, V[]v ) {
for (int i=0; i < u.length - 1; i++) {
int j = Int( i, u.length );
if (j != i) {
U ut = u[i];
u[i] = u[j];
u[j] = ut;
V vt = v[i];
v[i] = v[j];
v[j] = vt;
}
}
}
}
@@ -0,0 +1,132 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.HashSet;
public class Rect {
public int left;
public int top;
public int right;
public int bottom;
public Rect() {
this( 0, 0, 0, 0 );
}
public Rect( Rect rect ) {
this( rect.left, rect.top, rect.right, rect.bottom );
}
public Rect( int left, int top, int right, int bottom ) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public int width() {
return right - left;
}
public int height() {
return bottom - top;
}
public int square() {
return (right - left) * (bottom - top);
}
public Rect set( int left, int top, int right, int bottom ) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
return this;
}
public Rect set( Rect rect ) {
return set( rect.left, rect.top, rect.right, rect.bottom );
}
public boolean isEmpty() {
return right <= left || bottom <= top;
}
public Rect setEmpty() {
left = right = top = bottom = 0;
return this;
}
public Rect intersect( Rect other ) {
Rect result = new Rect();
result.left = Math.max( left, other.left );
result.right = Math.min( right, other.right );
result.top = Math.max( top, other.top );
result.bottom = Math.min( bottom, other.bottom );
return result;
}
public Rect union( int x, int y ) {
if (isEmpty()) {
return set( x, y, x + 1, y + 1 );
} else {
if (x < left) {
left = x;
} else if (x >= right) {
right = x + 1;
}
if (y < top) {
top = y;
} else if (y >= bottom) {
bottom = y + 1;
}
return this;
}
}
public Rect union( Point p ) {
return union( p.x, p.y );
}
public boolean inside( Point p ) {
return p.x >= left && p.x < right && p.y >= top && p.y < bottom;
}
public Rect shrink( int d ) {
return new Rect( left + d, top + d, right - d, bottom - d );
}
public Rect shrink() {
return shrink( 1 );
}
public HashSet<Point> getPoints() {
HashSet<Point> points = new HashSet<>(square()*2);
for (int i = left; i <= right; i++)
for (int j = top; j <= bottom; j++)
points.add(new Point(i, j));
return points;
}
}
@@ -0,0 +1,96 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.LinkedList;
public class Signal<T> {
private LinkedList<Listener<T>> listeners = new LinkedList<Signal.Listener<T>>();
private boolean canceled;
private boolean stackMode;
public Signal() {
this( false );
}
public Signal( boolean stackMode ) {
this.stackMode = stackMode;
}
public void add( Listener<T> listener ) {
if (!listeners.contains( listener )) {
if (stackMode) {
listeners.addFirst( listener );
} else {
listeners.addLast( listener );
}
}
}
public void remove( Listener<T> listener ) {
listeners.remove( listener );
}
public void removeAll() {
listeners.clear();
}
public void replace( Listener<T> listener ) {
removeAll();
add( listener );
}
public int numListeners() {
return listeners.size();
}
public void dispatch( T t ) {
@SuppressWarnings("unchecked")
Listener<T>[] list = listeners.toArray( new Listener[0] );
canceled = false;
for (int i=0; i < list.length; i++) {
Listener<T> listener = list[i];
if (listeners.contains( listener )) {
listener.onSignal( t );
if (canceled) {
return;
}
}
}
}
public void cancel() {
canceled = true;
}
public static interface Listener<T> {
public void onSignal( T t );
}
}
@@ -0,0 +1,46 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
import java.util.ArrayList;
import java.util.List;
public class SparseArray<T> extends android.util.SparseArray<T> {
public int[] keyArray() {
int size = size();
int[] array = new int[size];
for (int i=0; i < size; i++) {
array[i] = keyAt( i );
}
return array;
}
public List<T> values() {
int size = size();
ArrayList<T> list = new ArrayList<T>( size );
for (int i=0; i < size; i++) {
list.add( i, valueAt( i ) );
}
return list;
}
}
@@ -0,0 +1,32 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.watabou.utils;
public class SystemTime {
public static long now;
public static void tick() {
now = System.currentTimeMillis();
}
}