static public List<TimedEffect> ReadTimedEffects(Game game) { if (!memoryAddressesRead) { throw new InvalidOperationException("Cannot read timed effects before reading memory addresses."); } Debug.WriteLine("Reading timed effects from file."); var timedEffects = XmlUtils.getXDocument(game.Abbreviation, timedEffectsFilename).Descendants("timedeffect") .Select(effect => { if (effect.Element("script") != null) { return new TimedEffect ( effect.Element("name").Value, effect.Element("category").Value, Int32.Parse(effect.Element("difficulty").Value), effect.Element("script").Value ); } else { return new TimedEffect ( effect.Element("name").Value, effect.Element("category").Value, Int32.Parse(effect.Element("difficulty").Value), effect.Descendants("activator") .Select(activator => new EffectActivator ( activator.Element("target").Value, game.FindMemoryAddressByName(activator.Element("address").Value), (ActivationType)Enum.Parse(typeof(ActivationType), activator.Element("activation")?.Value ?? default(ActivationType).ToString(), true), (DeactivationType)Enum.Parse(typeof(DeactivationType), activator.Element("deactivation")?.Value ?? default(DeactivationType).ToString(), true) )) .ToList(), UInt32.Parse(effect.Element("duration")?.Value ?? "0"), effect.Descendants("limitation") .Select(limit => { var limitation = ReadLimitation(game, limit.Element("name").Value); limitation.Target = Boolean.Parse(limit.Element("target").Value); limitation.SetParameters(ReadParameters(limit)); return limitation; }) .ToList() ); } }) .ToList(); // TODO(Ligh): Validate everything has been read correctly. return timedEffects; }
static private Limitation ReadLimitation(Game game, string limitationName) { if (!memoryAddressesRead) { throw new InvalidOperationException("Cannot read timed effects before reading memory addresses."); } Debug.WriteLine($"Reading limitation {limitationName} from file."); var file = XmlUtils.getXDocument(game.Abbreviation, limitationsFilename); var limitation = file.Descendants("limitation") .Where(limit => limit.Element("name")?.Value == limitationName) .Select(limit => new Limitation ( limitationName, limit.Descendants("check") .Select<XElement, ICheck>(check => { switch (check.Attribute(XmlUtils.xsiNamespace + "type").Value) { case "parameter": return new ParameterCheck ( game.FindMemoryAddressByName(check.Element("address").Value), check.Element("value")?.Value ); case "limitation": return new LimitationCheck ( ReadLimitation(game, check.Element("limitation").Value), Boolean.Parse(check.Element("target").Value), ReadParameters(check) ); case "comparison": return new ComparisonCheck ( check.Descendants("address").Select(c => game.FindMemoryAddressByName(c.Value)).ToList(), Boolean.Parse(check.Element("equal").Value) ); default: throw new NotSupportedException($"Tried to process unknown limitation check type: {check.Attribute(XmlUtils.xsiNamespace + "type").Value}"); } }) .ToList() )) .FirstOrDefault(); // TODO(Ligh): Validate everything has been read correctly. return limitation; }
static public List<BaseCheck> ReadBaseChecks(Game game) { Debug.WriteLine("Reading base checks from file."); var file = XmlUtils.getXDocument(game.Abbreviation, limitationsFilename); var baseChecks = file.Descendants("base").First().Descendants("check") .Select(check => new BaseCheck ( game.FindMemoryAddressByName(check.Element("address").Value), check.Element("failCase").Value, (FailType)Enum.Parse(typeof(FailType), check.Element("failType")?.Value, true) )) .ToList(); // TODO(Ligh): Validate everything has been read correctly. return baseChecks; }