void CheckTrait(ActorInfo actorInfo, TraitInfo traitInfo, Ruleset rules) { var actualType = traitInfo.GetType(); foreach (var field in actualType.GetFields()) { if (field.HasAttribute <ActorReferenceAttribute>()) { CheckActorReference(actorInfo, traitInfo, field, rules.Actors, field.GetCustomAttributes <ActorReferenceAttribute>(true)[0]); } if (field.HasAttribute <WeaponReferenceAttribute>()) { CheckWeaponReference(actorInfo, traitInfo, field, rules.Weapons, field.GetCustomAttributes <WeaponReferenceAttribute>(true)[0]); } if (field.HasAttribute <VoiceSetReferenceAttribute>()) { CheckVoiceReference(actorInfo, traitInfo, field, rules.Voices, field.GetCustomAttributes <VoiceSetReferenceAttribute>(true)[0]); } } }
void CheckActorReference(Action <string> emitError, ActorInfo actorInfo, TraitInfo traitInfo, FieldInfo fieldInfo, IReadOnlyDictionary <string, ActorInfo> dict, ActorReferenceAttribute attribute) { var values = LintExts.GetFieldValues(traitInfo, fieldInfo, emitError, attribute.DictionaryReference); foreach (var value in values) { if (value == null) { continue; } // NOTE: Once https://github.com/OpenRA/OpenRA/issues/4124 is resolved we won't // have to .ToLower* anything here. var v = value.ToLowerInvariant(); if (!dict.ContainsKey(v)) { emitError($"{actorInfo.Name}.{traitInfo.GetType().Name}.{fieldInfo.Name}: Missing actor `{value}`."); continue; } foreach (var requiredTrait in attribute.RequiredTraits) { if (!dict[v].TraitsInConstructOrder().Any(t => t.GetType() == requiredTrait || t.GetType().IsSubclassOf(requiredTrait))) { emitError($"Actor type {value} does not have trait {requiredTrait.Name} which is required by {traitInfo.GetType().Name}.{fieldInfo.Name}."); } } } }
public static IEnumerable <Type> PrerequisitesOf(TraitInfo info) { return(info .GetType() .GetInterfaces() .Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Requires <>)) .Select(t => t.GetGenericArguments()[0])); }
void CheckVoiceReference(Action <string> emitError, ActorInfo actorInfo, TraitInfo traitInfo, FieldInfo fieldInfo, IReadOnlyDictionary <string, SoundInfo> dict) { var values = LintExts.GetFieldValues(traitInfo, fieldInfo); foreach (var value in values) { if (value == null) { continue; } if (!dict.ContainsKey(value.ToLowerInvariant())) { emitError($"{actorInfo.Name}.{traitInfo.GetType().Name}.{fieldInfo.Name}: Missing voice `{value}`."); } } }
void CheckWeaponReference(Action <string> emitError, ActorInfo actorInfo, TraitInfo traitInfo, FieldInfo fieldInfo, IReadOnlyDictionary <string, WeaponInfo> dict) { var values = LintExts.GetFieldValues(traitInfo, fieldInfo, emitError); foreach (var value in values) { if (value == null) { continue; } if (!dict.ContainsKey(value.ToLowerInvariant())) { emitError("{0}.{1}.{2}: Missing weapon `{3}`." .F(actorInfo.Name, traitInfo.GetType().Name, fieldInfo.Name, value)); } } }
void CheckVoiceReference(ActorInfo actorInfo, TraitInfo traitInfo, FieldInfo fieldInfo, IReadOnlyDictionary <string, SoundInfo> dict, VoiceSetReferenceAttribute attribute) { var values = LintExts.GetFieldValues(traitInfo, fieldInfo, emitError); foreach (var value in values) { if (value == null) { continue; } if (!dict.ContainsKey(value.ToLowerInvariant())) { emitError("{0}.{1}.{2}: Missing voice `{3}`." .F(actorInfo.Name, traitInfo.GetType().Name, fieldInfo.Name, value)); } } }