package greymerk.roguelike.dungeon.settings;
import java.util.Random;
import greymerk.roguelike.config.RogueConfig;
import greymerk.roguelike.util.WeightedChoice;
import greymerk.roguelike.util.WeightedRandomizer;
import greymerk.roguelike.worldgen.Coord;
import greymerk.roguelike.worldgen.IWorldEditor;
public class SettingsResolver {
private ISettingsContainer settings;
public SettingsResolver(ISettingsContainer settings) throws Exception{
this.settings = settings;
}
// called from Dungeon class
public ISettings getSettings(IWorldEditor editor, Random rand, Coord pos) throws Exception{
if(RogueConfig.getBoolean(RogueConfig.RANDOM)) return new SettingsRandom(rand);
DungeonSettings builtin = this.getBuiltin(editor, rand, pos);
DungeonSettings custom = this.getCustom(editor, rand, pos);
// there are no valid dungeons for this location
if(builtin == null && custom == null) return null;
DungeonSettings exclusive = (custom != null) ? custom : builtin;
return applyInclusives(exclusive, editor, rand, pos);
}
public ISettings getWithName(String name, IWorldEditor editor, Random rand, Coord pos) throws Exception{
if(name.equals("random")) return new SettingsRandom(rand);
DungeonSettings byName = this.getByName(name);
if(byName == null) return null;
DungeonSettings withInclusives = applyInclusives(byName, editor, rand, pos);
return new DungeonSettings(new SettingsBlank(), withInclusives);
}
public static DungeonSettings processInheritance(DungeonSettings toProcess, ISettingsContainer settings) throws Exception{
DungeonSettings setting = new SettingsBlank();
for(SettingIdentifier id : toProcess.getInherits()){
if(settings.contains(id)){
DungeonSettings inherited = new DungeonSettings(settings.get(id));
if(!inherited.getInherits().isEmpty()){
inherited = processInheritance(inherited, settings);
}
setting = new DungeonSettings(setting, inherited);
} else {
throw new Exception("Setting not found: " + id.toString());
}
}
return new DungeonSettings(setting, toProcess);
}
public ISettings getDefaultSettings(){
return new DungeonSettings(settings.get(new SettingIdentifier(SettingsContainer.BUILTIN_NAMESPACE, "base")));
}
private DungeonSettings getByName(String name) throws Exception{
SettingIdentifier id;
try{
id = new SettingIdentifier(name);
} catch (Exception e){
throw new Exception("Malformed Setting ID String: " + name);
}
if(!this.settings.contains(id)) return null;
DungeonSettings setting = new DungeonSettings(this.settings.get(id));
return processInheritance(setting, this.settings);
}
private DungeonSettings getBuiltin(IWorldEditor editor, Random rand, Coord pos) throws Exception{
WeightedRandomizer<DungeonSettings> settingsRandomizer = new WeightedRandomizer<DungeonSettings>();
for(DungeonSettings setting : settings.getBuiltinSettings()){
if(setting.isValid(editor, pos)){
settingsRandomizer.add(new WeightedChoice<DungeonSettings>(setting, setting.criteria.weight));
}
}
DungeonSettings chosen = settingsRandomizer.get(rand);
return processInheritance(chosen, settings);
}
private DungeonSettings getCustom(IWorldEditor editor, Random rand, Coord pos) throws Exception{
WeightedRandomizer<DungeonSettings> settingsRandomizer = new WeightedRandomizer<DungeonSettings>();
for(DungeonSettings setting : settings.getCustomSettings()){
if(setting.isValid(editor, pos) && setting.isExclusive()){
settingsRandomizer.add(new WeightedChoice<DungeonSettings>(setting, setting.criteria.weight));
}
}
DungeonSettings chosen = settingsRandomizer.get(rand);
if(chosen == null) return null;
return processInheritance(chosen, settings);
}
private DungeonSettings applyInclusives(DungeonSettings setting, IWorldEditor editor, Random rand, Coord pos) throws Exception{
DungeonSettings toReturn = new DungeonSettings(setting);
for(DungeonSettings s : settings.getCustomSettings()){
if(!s.isValid(editor, pos)) continue;
if(s.isExclusive()) continue;
toReturn = new DungeonSettings(toReturn, processInheritance(s, settings));
}
return toReturn;
}
@Override
public String toString(){
return this.settings.toString();
}
}