package Roguelike.Items; import Roguelike.Ability.AbilityTree; import Roguelike.Sprite.Sprite; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectSet; import com.badlogic.gdx.utils.XmlReader; import java.io.IOException; import java.util.HashMap; import java.util.Random; /** * Created by Philip on 22-Dec-15. */ public class TreasureGenerator { public static Array<Item> generateLoot( int quality, String typeBlock, Random ran ) { Array<Item> items = new Array<Item>( ); String[] types = typeBlock.toLowerCase().split( "," ); for (String type : types) { if ( type.equals( "currency" ) ) { items.addAll( TreasureGenerator.generateCurrency( quality, ran ) ); } else if ( type.startsWith( "ability" ) ) { String[] abilityParts = type.split( "[\\(\\)]" ); String[] tags = new String[]{}; if (abilityParts.length > 1) { tags = new String[]{ abilityParts[1] }; } items.addAll( TreasureGenerator.generateAbility( quality, ran, tags ) ); } else if ( type.equals( "armour" ) ) { items.addAll( TreasureGenerator.generateArmour( quality, ran ) ); } else if ( type.equals( "weapon" ) ) { items.addAll( TreasureGenerator.generateWeapon( quality, ran ) ); } else if ( type.equals( "item" ) ) { if ( ran.nextBoolean() ) { items.addAll( TreasureGenerator.generateArmour( quality, ran ) ); } else { items.addAll( TreasureGenerator.generateWeapon( quality, ran ) ); } } else if ( type.equals( "random" ) ) { items.addAll( TreasureGenerator.generateRandom( quality, ran ) ); } else if ( type.startsWith( "item(" ) ) { String[] parts = type.split( "[\\(\\)]" ); items.addAll( TreasureGenerator.generateItemFromMaterial( parts[1], quality, ran ) ); } } return items; } public static Array<Item> generateRandom( int quality, Random ran ) { Array<Item> items = new Array<Item>( ); // Chances, // Currency 3 // Weapon 2 // Armour 2 // Ability 1 int[] chances = { 0, // currency 3, // armour 3, // weapons 2 // abilities }; int count = 0; for (int i : chances) { count += chances[i]; } int chance = ran.nextInt( count ); if ( chance < chances[0] ) { items.addAll( TreasureGenerator.generateCurrency( quality, ran ) ); return items; } chance -= chances[0]; if ( chance < chances[1] ) { items.addAll( TreasureGenerator.generateArmour( quality, ran ) ); return items; } chance -= chances[1]; if ( chance < chances[2] ) { items.addAll( TreasureGenerator.generateWeapon( quality, ran ) ); return items; } chance -= chances[2]; if ( chance < chances[3] ) { items.addAll( TreasureGenerator.generateAbility( quality, ran, new String[]{} ) ); return items; } return items; } public static Array<Item> generateCurrency( int quality, Random ran ) { Array<Item> items = new Array<Item>( ); int val = ran.nextInt(100) * quality; Item money = Item.load( "Treasure/Money" ); money.count = val; items.add(money); return items; } public static Array<Item> generateAbility( int quality, Random ran, String[] tags ) { Array<Item> items = new Array<Item>( ); Array<QualityData> validList = new Array<QualityData>( ); for (int i = 0; i < quality && i < abilityList.qualityData.size; i++) { for (QualityData qd : abilityList.qualityData.get( i )) { boolean valid = true; for (String tag : tags) { if (!qd.tags.contains( tag )) { valid = false; break; } } if (valid) { validList.add( qd ); } } } String chosen = validList.get( ran.nextInt( validList.size ) ).name; AbilityTree tree = new AbilityTree( chosen ); Item item = new Item(); item.ability = tree; items.add(item); return items; } public static Array<Item> generateArmour( int quality, Random ran ) { Array<Item> items = new Array<Item>( ); RecipeData recipe = recipeList.armourRecipes.get( ran.nextInt( recipeList.armourRecipes.size ) ); items.add( itemFromRecipe( recipe, quality, ran ) ); return items; } public static Array<Item> generateWeapon( int quality, Random ran ) { Array<Item> items = new Array<Item>( ); RecipeData recipe = recipeList.weaponRecipes.get( ran.nextInt( recipeList.weaponRecipes.size ) ); items.add( itemFromRecipe( recipe, quality, ran ) ); return items; } public static Array<Item> generateItemFromMaterial( String materialType, int quality, Random ran ) { Array<RecipeData> validRecipes = new Array<RecipeData>( ); for (RecipeData recipe : recipeList.weaponRecipes) { if (recipe.acceptsMaterial( materialType )) { validRecipes.add( recipe ); } } for (RecipeData recipe : recipeList.armourRecipes) { if (recipe.acceptsMaterial( materialType )) { validRecipes.add( recipe ); } } Array<Item> items = new Array<Item>( ); if (validRecipes.size == 0) { return items; } RecipeData chosen = validRecipes.get( ran.nextInt( validRecipes.size ) ); items.add( itemFromRecipe( chosen, quality, ran ) ); return items; } public static Item itemFromRecipe( RecipeData recipe, int quality, Random ran ) { String materialType = recipe.acceptedMaterials[ ran.nextInt( recipe.acceptedMaterials.length ) ]; Item materialItem = getMaterial( materialType, quality, ran ); Item item = Recipe.createRecipe( recipe.recipeName, materialItem ); item.getIcon().colour.mul( materialItem.getIcon().colour ); int numModifiers = ran.nextInt( Math.max( 2, quality / 2 ) ); int maxModifierQuality = Math.min( quality, modifierList.qualityData.size ); while (numModifiers > 0) { int chosenQuality = ran.nextInt( maxModifierQuality ); int numChoices = modifierList.qualityData.get( chosenQuality ).size; int choice = ran.nextInt( numChoices ); String modifier = modifierList.qualityData.get( chosenQuality ).get( choice ).name; Recipe.applyModifer( item, modifier, Math.max( 1, quality - chosenQuality), ran.nextBoolean() ); numModifiers--; } return item; } public static Item getMaterial( String materialType, int quality, Random ran ) { if (!materialLists.containsKey( materialType )) { if (Gdx.files.internal( "Items/Material/" + materialType + ".xml" ).exists()) { QualityMap materialMap = new QualityMap( "Items/Material/" + materialType + ".xml" ); materialLists.put( materialType, materialMap ); } else { materialLists.put( materialType, null ); } } QualityMap materialMap = materialLists.get( materialType ); if (materialMap == null) { return null; } int materialQuality = Math.min( quality, materialMap.qualityData.size ); String material = null; String colour = null; { int numChoices = materialMap.qualityData.get( materialQuality - 1 ).size; int choice = ran.nextInt( numChoices ); QualityData qdata = materialMap.qualityData.get( materialQuality - 1 ).get( choice ); material = qdata.name; colour = qdata.colour; } Item materialItem = null; if ( Gdx.files.internal( "Items/Material/"+material+".xml" ).exists() ) { materialItem = Item.load( "Material/" + material ); } else { materialItem = new Item(); materialItem.name = material; materialItem.quality = materialQuality; } if ( colour != null ) { Color col = new Color(); String[] cols = colour.split( "," ); col.r = Float.parseFloat( cols[0] ) / 255.0f; col.g = Float.parseFloat( cols[1] ) / 255.0f; col.b = Float.parseFloat( cols[2] ) / 255.0f; col.a = 1; materialItem.getIcon().colour = col; } return materialItem; } private static final QualityMap abilityList = new QualityMap( "Abilities/AbilityList.xml" ); private static final QualityMap modifierList = new QualityMap( "Items/Modifiers/ModifierList.xml" ); private static final HashMap<String, QualityMap> materialLists = new HashMap<String, QualityMap>( ); private static final RecipeList recipeList = new RecipeList( "Items/Recipes/Recipes.xml" ); private static class RecipeList { public Array<RecipeData> armourRecipes = new Array<RecipeData>( ); public Array<RecipeData> weaponRecipes = new Array<RecipeData>( ); public RecipeList( String path ) { XmlReader reader = new XmlReader(); XmlReader.Element xml = null; try { xml = reader.parse( Gdx.files.internal( path ) ); } catch ( IOException e ) { e.printStackTrace(); } XmlReader.Element armoursElement = xml.getChildByName( "Armours" ); for (int i = 0; i < armoursElement.getChildCount(); i++) { XmlReader.Element armourElement = armoursElement.getChild( i ); armourRecipes.add( new RecipeData( armourElement.getName(), armourElement.getText().split( "," ) ) ); } XmlReader.Element weaponsElement = xml.getChildByName( "Weapons" ); for (int i = 0; i < weaponsElement.getChildCount(); i++) { XmlReader.Element weaponElement = weaponsElement.getChild( i ); weaponRecipes.add( new RecipeData( weaponElement.getName(), weaponElement.getText().split( "," ) ) ); } } } private static class RecipeData { public String recipeName; public String[] acceptedMaterials; public RecipeData( String recipeName, String[] acceptedMaterials ) { this.recipeName = recipeName; this.acceptedMaterials = acceptedMaterials; } public boolean acceptsMaterial( String material ) { for (int i = 0; i < acceptedMaterials.length; i++) { if (acceptedMaterials[i].equalsIgnoreCase( material )) { return true; } } return false; } } private static class QualityMap { public Array<Array<QualityData>> qualityData = new Array<Array<QualityData>>( ); public QualityMap( String file ) { XmlReader reader = new XmlReader(); XmlReader.Element xml = null; try { xml = reader.parse( Gdx.files.internal( file ) ); } catch ( IOException e ) { e.printStackTrace(); } for (int i = 0; i < xml.getChildCount(); i++) { XmlReader.Element qualityElement = xml.getChild( i ); Array<QualityData> qualityLevel = new Array<QualityData>( ); for (int ii = 0; ii < qualityElement.getChildCount(); ii++) { XmlReader.Element qEl = qualityElement.getChild( ii ); String name = qEl.getName(); String colour = qEl.getAttribute( "RGB", null ); String tagString = qEl.getText(); if (tagString == null) { tagString = ""; } String[] tags = tagString.toLowerCase().split( "," ); qualityLevel.add( new QualityData( name, colour, tags ) ); } qualityData.add( qualityLevel ); } } } private static class QualityData { public String name; public String colour; public ObjectSet<String> tags = new ObjectSet<String>( ); public QualityData( String name, String colour, String[] tags ) { this.name = name; this.colour = colour; this.tags.addAll( tags ); } } }