package Roguelike.Sprite;
import Roguelike.AssetManager;
import Roguelike.Global;
import Roguelike.Util.EnumBitflag;
import Roguelike.Util.ImageUtils;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.XmlReader.Element;
// Naming priority: NSEW
public class TilingSprite
{
private static final int CENTER = 1 << ( Global.Direction.CENTER.ordinal() + 1 );
private static final int SOUTH = 1 << ( Global.Direction.SOUTH.ordinal() + 1 );
public TilingSprite()
{
}
public TilingSprite( Sprite topSprite, Sprite frontSprite )
{
sprites.put( CENTER, topSprite );
sprites.put( SOUTH, frontSprite );
hasAllElements = true;
}
public TilingSprite ( String name, String texture, String mask )
{
Element spriteBase = new Element("Sprite", null);
load( name, name, texture, mask, spriteBase, null );
}
public IntMap<Sprite> sprites = new IntMap<Sprite>( );
public long thisID;
public long checkID;
public String texName;
public String maskName;
public Element spriteBase = new Element( "Sprite", null );
public boolean additive = false;
public boolean hasAllElements;
public Sprite overhangSprite;
public TilingSprite copy()
{
TilingSprite copy = new TilingSprite();
copy.checkID = checkID;
copy.thisID = thisID;
copy.texName = texName;
copy.maskName = maskName;
copy.spriteBase = spriteBase;
copy.hasAllElements = hasAllElements;
copy.overhangSprite = overhangSprite;
for (IntMap.Entry<Sprite> pair : sprites.entries())
{
copy.sprites.put( pair.key, pair.value.copy() );
}
return copy;
}
public void parse( Element xml )
{
String checkName, thisName;
checkName = thisName = xml.get( "Name", null );
checkName = xml.get( "CheckName", checkName );
thisName = xml.get( "ThisName", thisName );
Element overhangElement = xml.getChildByName( "Overhang" );
Element topElement = xml.getChildByName("Top");
if (topElement != null)
{
Sprite topSprite = AssetManager.loadSprite( topElement );
Sprite frontSprite = AssetManager.loadSprite( xml.getChildByName( "Front" ) );
sprites.put( CENTER, topSprite );
sprites.put( SOUTH, frontSprite );
hasAllElements = true;
}
Element spriteElement = xml.getChildByName( "Sprite" );
String texName = spriteElement != null ? spriteElement.get( "Name" ) : null;
String maskName = xml.get( "Mask", null );
this.additive = xml.getBoolean( "Additive", false );
load(thisName, checkName, texName, maskName, spriteElement, overhangElement);
}
public void load( String thisName, String checkName, String texName, String maskName, Element spriteElement, Element overhangElement )
{
this.thisID = thisName.toLowerCase().hashCode();
this.checkID = checkName.toLowerCase().hashCode();
this.texName = texName;
this.maskName = maskName;
this.spriteBase = spriteElement;
if ( overhangElement != null )
{
overhangSprite = AssetManager.loadSprite( overhangElement );
}
}
public static TilingSprite load( Element xml )
{
TilingSprite sprite = new TilingSprite();
sprite.parse( xml );
return sprite;
}
private static TextureRegion getMaskedSprite( String baseName, String maskBaseName, Array<String> masks, boolean additive )
{
// If no masks then just return the original texture
if ( masks.size == 0)
{
return AssetManager.loadTextureRegion( "Sprites/" + baseName + ".png" );
}
// Build the mask suffix
String mask = "";
for ( String m : masks)
{
mask += "_" + m;
}
String maskedName = baseName + "_" + maskBaseName + mask + "_" + additive;
TextureRegion tex = AssetManager.loadTextureRegion( "Sprites/" + maskedName + ".png" );
// We have the texture, so return it
if (tex != null)
{
return tex;
}
throw new RuntimeException( "No masked sprite packed for file: " + maskedName );
// // If we havent been given a valid mask, then just return the original texture
// if (maskBaseName == null)
// {
// return AssetManager.loadTextureRegion( "Sprites/" + baseName + ".png" );
// }
//
// Pixmap base = ImageUtils.textureToPixmap( AssetManager.loadTexture( "Sprites/" + baseName + ".png" ) );
// Pixmap merged = base;
// for (String maskSuffix : masks)
// {
// Texture maskTex = AssetManager.loadTexture( "Sprites/" + maskBaseName + "_" + maskSuffix + ".png" );
//
// if (maskTex == null)
// {
// maskTex = AssetManager.loadTexture( "Sprites/" + maskBaseName + "_C.png" );
// }
//
// if (maskTex == null)
// {
// continue;
// }
//
// Pixmap maskedTex = ImageUtils.maskPixmap( merged, ImageUtils.textureToPixmap( maskTex ) );
// if (merged != base) { merged.dispose(); }
// merged = maskedTex;
// }
//
// return AssetManager.packPixmap( "Sprites/" + maskedName + ".png", merged );
}
public static Array<String> getMasks( EnumBitflag<Global.Direction> emptyDirections )
{
Array<String> masks = new Array<String>();
if (emptyDirections.getBitFlag() == 0)
{
masks.add("C");
}
if (emptyDirections.contains( Global.Direction.NORTH ))
{
if (emptyDirections.contains( Global.Direction.EAST ))
{
masks.add("NE");
}
if (emptyDirections.contains( Global.Direction.WEST ))
{
masks.add("NW");
}
if (!emptyDirections.contains( Global.Direction.EAST ) && !emptyDirections.contains( Global.Direction.WEST ))
{
masks.add("N");
}
}
if (emptyDirections.contains( Global.Direction.SOUTH ))
{
if (emptyDirections.contains( Global.Direction.EAST ))
{
masks.add("SE");
}
if (emptyDirections.contains( Global.Direction.WEST ))
{
masks.add("SW");
}
if (!emptyDirections.contains( Global.Direction.EAST ) && !emptyDirections.contains( Global.Direction.WEST ))
{
masks.add("S");
}
}
if (emptyDirections.contains( Global.Direction.EAST ))
{
if (!emptyDirections.contains( Global.Direction.NORTH ) && !emptyDirections.contains( Global.Direction.SOUTH ))
{
masks.add("E");
}
}
if (emptyDirections.contains( Global.Direction.WEST ))
{
if (!emptyDirections.contains( Global.Direction.NORTH ) && !emptyDirections.contains( Global.Direction.SOUTH ))
{
masks.add("W");
}
}
if (emptyDirections.contains( Global.Direction.NORTHEAST ) && !emptyDirections.contains( Global.Direction.NORTH ) && !emptyDirections.contains( Global.Direction.EAST ))
{
masks.add("DNE");
}
if (emptyDirections.contains( Global.Direction.NORTHWEST ) && !emptyDirections.contains( Global.Direction.NORTH ) && !emptyDirections.contains( Global.Direction.WEST ))
{
masks.add("DNW");
}
if (emptyDirections.contains( Global.Direction.SOUTHEAST ) && !emptyDirections.contains( Global.Direction.SOUTH ) && !emptyDirections.contains( Global.Direction.EAST ))
{
masks.add("DSE");
}
if (emptyDirections.contains( Global.Direction.SOUTHWEST ) && !emptyDirections.contains( Global.Direction.SOUTH ) && !emptyDirections.contains( Global.Direction.WEST ))
{
masks.add("DSW");
}
return masks;
}
public Sprite getSprite( EnumBitflag<Global.Direction> emptyDirections )
{
if (hasAllElements)
{
if (emptyDirections.contains( Global.Direction.SOUTH ))
{
return sprites.get( SOUTH );
}
else
{
return sprites.get( CENTER );
}
}
else
{
Sprite sprite = sprites.get( emptyDirections.getBitFlag() );
if (sprite != null)
{
return sprite;
}
else
{
Array<String> masks = getMasks( emptyDirections );
String mask = "";
for ( String m : masks)
{
mask += "_" + m;
}
if (texName != null)
{
TextureRegion region = getMaskedSprite( texName, maskName, masks, additive );
sprite = AssetManager.loadSprite( spriteBase, region );
}
else
{
sprite = sprites.get( CENTER );
}
sprites.put( emptyDirections.getBitFlag(), sprite );
return sprite;
}
}
}
}