private ResolvedValue GetRefValue(string refName, Cache cache, string parent, IResolver resolver, IFormatter formatter = null) { if (refName.Length > 1 && refName[0] == '~') { refName = refName.Substring(1); } string fullRefName = parent + "." + refName; Entity refAttrib; try { refAttrib = resolver.FindEntity(fullRefName); var refValue = new ResolvedValue(fullRefName, refAttrib.Type, refAttrib.Value); try { resolver.Resolve(refValue, cache); } catch (Exception e) { throw new Exception($"references unresolvable attribute '{refName}': {e.Message}"); } return(refValue); } catch (Exception) { // Allow an unknown attribute if it's in the cache (might be a temporary attribute created by a mod) try { return(cache.GetValue(fullRefName)); } catch { // do nothing } if (formatter != null) { // Might be a complete entity rather than an attribute Entity refEntity; try { refEntity = resolver.FindEntity(refName); // The value is the entity in JSON format string strValue = formatter.EntityToJson(refEntity, cache); var refValue = new ResolvedValue("", Entity.Types.OBJ, strValue); refValue.SetValue(strValue); return(refValue); } catch (Exception) { throw new Exception($"references unknown attribute or entity '{refName}'"); } } throw new Exception($"references unknown attribute '{refName}'"); } }
/// <summary> /// Sample function /// /// The sample function has a circular dependency on the resolver (so we can /// have samples based on the gender of other fields which may not be resolved /// yet) so we have to pass the resolver in as a parameter. /// </summary> public string FuncSample(string called, string[] args, Cache cache, string parent, IResolver resolver, out Sample.Genders gender) { string help = "Use func.sample(--help) for help."; if (args.Length == 1 && args[0].Equals("--help", StringComparison.CurrentCultureIgnoreCase)) { // Show usage string usage = "Usage: func.sample(arg1, [arg2]) where arg1 is the name of the samples file to use and arg2 is " + "either another attribute to take the gender from, or M or F to use a fixed gender."; throw new Exception(usage); } if (args.Length < 1 || args.Length > 2) { throw new Exception($"{called} has bad number of arguments. {help}"); } if (args[0].Length == 0) { throw new Exception($"{called} has empty argument. {help}"); } gender = Sample.Genders.NEUTRAL; if (args.Length == 2) { if (args[1].Equals("M", StringComparison.CurrentCultureIgnoreCase)) { gender = Sample.Genders.MALE; } else if (args[1].Equals("F", StringComparison.CurrentCultureIgnoreCase)) { gender = Sample.Genders.FEMALE; } else { // Inherit gender from referenced attribute. string refName; if (args[1].Length > 1 && args[1][0] == '~') { refName = parent + "." + args[1].Substring(1); } else { refName = parent + "." + args[1]; } Entity refAttrib; try { refAttrib = resolver.FindEntity(refName); } catch (Exception) { throw new Exception($"{called} references unknown attribute '{refName}'"); } var refValue = new ResolvedValue(refName, refAttrib.Type, refAttrib.Value); try { resolver.Resolve(refValue, cache); } catch (Exception e) { throw new Exception($"{called} references unresolvable attribute '{refName}': {e.Message}"); } gender = refValue.Gender; } } var samples = resolver.GetSamples(args[0]); var sample = samples.Pick(gender); gender = sample.Gender; return(sample.Value); }