package Roguelike.Levels; import Roguelike.DungeonGeneration.DungeonFileParser; import Roguelike.Global; import Roguelike.Quests.Quest; import Roguelike.RoguelikeGame; import Roguelike.Save.SaveLevel; import Roguelike.Screens.GameScreen; import Roguelike.Screens.LoadingScreen; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader; import java.io.IOException; import java.util.Random; /** * Created by Philip on 18-Dec-15. */ public class LevelManager { public int hpDropCounter = 0; public int totalDepth = 1; public LevelData root; public LevelData current; public Array<Quest> activeQuests = new Array<Quest>( ); public LevelManager() { XmlReader xmlReader = new XmlReader(); XmlReader.Element xml = null; try { xml = xmlReader.parse( Gdx.files.internal( "Levels/LevelGraph.xml" ) ); } catch ( IOException e ) { e.printStackTrace(); } root = new LevelData( this ); root.parse( xml ); current = root; } public void evaluateQuestOutput() { for (Quest quest : activeQuests) { quest.evaluateOutputs(); } activeQuests.clear(); } public void nextLevel( String name ) { if (name.equals( "Town" )) { TownCreator townCreator = new TownCreator(); townCreator.create(); return; } evaluateQuestOutput(); LevelData prev = current; current = getLevel( current, name ); int depth = prev.levelName.equals( name ) ? prev.currentLevel.depth + 1 : 1; prev.currentLevel = null; SaveLevel level = new SaveLevel( current.levelName, depth, current.getExtraRooms( prev.levelName, depth, new Random() ), MathUtils.random( Long.MAX_VALUE - 1 ) ); current.currentLevel = level; if (depth == current.maxDepth) { // spawn boss current.currentLevel.isBossLevel = true; } else if (depth == 1) { GameScreen.Instance.displayLevelEntryMessage( current.levelTitle, current.levelDescription ); } LoadingScreen.Instance.set( level, Global.CurrentLevel.player, "PlayerSpawn", null ); RoguelikeGame.Instance.switchScreen( RoguelikeGame.ScreenEnum.LOADING ); totalDepth++; } public LevelData getLevel( LevelData current, String name ) { if (name.equals( current.levelName )) { return current; } LevelData nextLevel = null; if (current.nextLevel.levelName.equals( name )) { nextLevel = current.nextLevel; } for (BranchData branch : current.branches) { if (branch.level.levelName.equals( name )) { nextLevel = branch.level; } } if ( nextLevel != null ) { if ( nextLevel.levelName.equals( "GoTo" ) ) { nextLevel = root.getLabelledLevel( nextLevel.label ); } return nextLevel; } throw new RuntimeException( "Cant find level with name '" + name + "' connected to level '" + current.levelName + "'" ); } public static class LevelData { public String levelName; public int maxDepth; public String label; public SaveLevel currentLevel; public LevelData nextLevel; public Array<BranchData> branches = new Array<BranchData>( ); public LevelManager root; public String levelTitle; public String levelDescription; public LevelData() {} public LevelData( LevelManager root ) { this.root = root; } public Array<DungeonFileParser.DFPRoom> getExtraRooms( String prevLevel, int depth, Random ran ) { Array<DungeonFileParser.DFPRoom> rooms = new Array<DungeonFileParser.DFPRoom>( ); DungeonFileParser dfp = DungeonFileParser.load( levelName + "/" + levelName ); if (dfp.entranceRooms.containsKey( prevLevel.toLowerCase() )) { rooms.add( dfp.entranceRooms.get( prevLevel.toLowerCase() )[1] ); } else if (dfp.entranceRooms.get( "all" ) != null) { rooms.add( dfp.entranceRooms.get( "all" )[1] ); } else { rooms.add( dfp.entranceRooms.values().iterator().next()[1] ); } // If depth == levelDepth, getEntranceRoom of nextLevel if (depth == maxDepth) { if (nextLevel != null) { rooms.add( nextLevel.getEntranceRoom( levelName ) ); } } else { rooms.add( getEntranceRoom( levelName ) ); } // For each branch check if should spawn, if so get entrance room of those for (BranchData branch : branches) { if (depth == branch.depth) { if (ran.nextFloat() <= branch.chance) { rooms.add( branch.level.getEntranceRoom( levelName ) ); } } } // For each quest get rooms int numQuests = (int)(ran.nextFloat() * ran.nextFloat() * 2.0f) + 1; for (int i = 0; i < numQuests; i++) { Quest quest = Global.QuestManager.getQuest( levelName, ran ); if (quest != null) { root.activeQuests.add( quest ); rooms.addAll( quest.rooms ); } } return rooms; } public DungeonFileParser.DFPRoom getEntranceRoom(String prevLevel) { String name = levelName; if ( name.equals( "GoTo" ) ) { name = root.root.getLabelledLevel( label ).levelName; } // Pull entrance room from level xml DungeonFileParser dfp = DungeonFileParser.load( name + "/" + name ); if (dfp.entranceRooms.containsKey( prevLevel.toLowerCase() )) { return dfp.entranceRooms.get( prevLevel.toLowerCase() )[0]; } else { return dfp.entranceRooms.get( "all" )[0]; } } public void parse( XmlReader.Element xml ) { levelName = xml.getName(); maxDepth = xml.getIntAttribute( "MaxDepth", 1 ); label = xml.getAttribute( "Label", levelName ); levelTitle = xml.getAttribute( "Title", levelName ); levelDescription = xml.getAttribute( "Description", "PHILIP YOU SHOULD FILL THIS IN" ); if (xml.getChildCount() > 0) { nextLevel = new LevelData( root ); nextLevel.parse( xml.getChild( 0 ) ); } XmlReader.Element branchesElement = xml.getChildByName( "Branches" ); if (branchesElement != null) { for (int i = 0; i < branchesElement.getChildCount(); i++) { XmlReader.Element branchElement = branchesElement.getChild( i ); LevelData branchLevel = new LevelData( root ); branchLevel.parse( branchElement ); BranchData branch = new BranchData(); branch.level = branchLevel; branch.depth = branchElement.getIntAttribute( "SpawnDepth", maxDepth ); branch.chance = branchElement.getFloatAttribute( "SpawnChance", 0.5f ); branches.add(branch); } } } public LevelData getLabelledLevel( String labelString ) { if ( !levelName.equals( "GoTo" ) && label != null && label.equals( labelString ) ) { return this; } if ( nextLevel != null ) { LevelData found = nextLevel.getLabelledLevel( labelString ); if ( found != null ) { return found; } } for ( BranchData branch : branches ) { LevelData found = branch.level.getLabelledLevel( labelString ); if ( found != null ) { return found; } } return null; } } public static class BranchData { public int depth; public float chance; public LevelData level; } }