Example #1
0
        public void WorldLoaded(World w, WorldRenderer wr)
        {
            world   = w;
            tiles   = new Dictionary <CPos, Smudge>();
            dirty   = new Dictionary <CPos, Smudge>();
            smudges = new Dictionary <string, Sprite[]>();

            var types = SequenceProvider.Sequences(Info.Sequence);

            foreach (var t in types)
            {
                var seq     = SequenceProvider.GetSequence(Info.Sequence, t);
                var sprites = Exts.MakeArray(seq.Length, x => seq.GetSprite(x));
                smudges.Add(t, sprites);
            }

            // Add map smudges
            foreach (var s in w.Map.Smudges.Value.Where(s => smudges.Keys.Contains(s.Type)))
            {
                var smudge = new Smudge
                {
                    Type   = s.Type,
                    Depth  = s.Depth,
                    Sprite = smudges[s.Type][s.Depth]
                };

                tiles.Add((CPos)s.Location, smudge);
            }
        }
Example #2
0
        void Run(Action <string> emitError, Action <string> emitWarning, Ruleset rules, SequenceProvider sequences)
        {
            var factions = rules.Actors[SystemActors.World].TraitInfos <FactionInfo>().Select(f => f.InternalName).ToArray();

            foreach (var actorInfo in rules.Actors)
            {
                // Actors may have 0 or 1 RenderSprites traits
                var renderInfo = actorInfo.Value.TraitInfoOrDefault <RenderSpritesInfo>();
                if (renderInfo == null)
                {
                    continue;
                }

                var images = new HashSet <string>()
                {
                    renderInfo.GetImage(actorInfo.Value, sequences, null).ToLowerInvariant()
                };

                // Some actors define faction-specific artwork
                foreach (var faction in factions)
                {
                    images.Add(renderInfo.GetImage(actorInfo.Value, sequences, faction).ToLowerInvariant());
                }

                foreach (var traitInfo in actorInfo.Value.TraitInfos <TraitInfo>())
                {
                    // Remove the "Info" suffix
                    var traitName = traitInfo.GetType().Name;
                    traitName = traitName.Remove(traitName.Length - 4);

                    var fields = traitInfo.GetType().GetFields();
                    foreach (var field in fields)
                    {
                        var sequenceReference = field.GetCustomAttributes <SequenceReferenceAttribute>(true).FirstOrDefault();
                        if (sequenceReference == null)
                        {
                            continue;
                        }

                        // Some sequences may specify their own Image override
                        IEnumerable <string> sequenceImages = images;
                        if (!string.IsNullOrEmpty(sequenceReference.ImageReference))
                        {
                            var imageField    = fields.First(f => f.Name == sequenceReference.ImageReference);
                            var imageOverride = (string)imageField.GetValue(traitInfo);
                            if (string.IsNullOrEmpty(imageOverride))
                            {
                                if (!sequenceReference.AllowNullImage)
                                {
                                    emitError("Actor type `{0}` trait `{1}` must define a value for `{2}`".F(actorInfo.Value.Name, traitName, sequenceReference.ImageReference));
                                }
                                continue;
                            }

                            sequenceImages = new[] { imageOverride.ToLowerInvariant() };
                        }

                        foreach (var sequence in LintExts.GetFieldValues(traitInfo, field, emitError, sequenceReference.DictionaryReference))
                        {
                            if (string.IsNullOrEmpty(sequence))
                            {
                                continue;
                            }

                            foreach (var i in sequenceImages)
                            {
                                if (sequenceReference.Prefix)
                                {
                                    // TODO: Remove prefixed sequence references and instead use explicit lists of lintable references
                                    if (!sequences.Sequences(i).Any(s => s.StartsWith(sequence)))
                                    {
                                        emitWarning("Actor type `{0}` trait `{1}` field `{2}` defines a prefix `{3}` that does not match any sequences on image `{4}`.".F(actorInfo.Value.Name, traitName, field.Name, sequence, i));
                                    }
                                }
                                else if (!sequences.HasSequence(i, sequence))
                                {
                                    emitError("Actor type `{0}` trait `{1}` field `{2}` references an undefined sequence `{3}` on image `{4}`.".F(actorInfo.Value.Name, traitName, field.Name, sequence, i));
                                }
                            }
                        }
                    }
                }
            }

            foreach (var weaponInfo in rules.Weapons)
            {
                var projectileInfo = weaponInfo.Value.Projectile;
                if (projectileInfo == null)
                {
                    continue;
                }

                var fields = projectileInfo.GetType().GetFields();
                foreach (var field in fields)
                {
                    var sequenceReference = field.GetCustomAttributes <SequenceReferenceAttribute>(true).FirstOrDefault();
                    if (sequenceReference == null)
                    {
                        continue;
                    }

                    // All weapon sequences must specify their corresponding image
                    var image = ((string)fields.First(f => f.Name == sequenceReference.ImageReference).GetValue(projectileInfo));
                    if (string.IsNullOrEmpty(image))
                    {
                        if (!sequenceReference.AllowNullImage)
                        {
                            emitError("Weapon type `{0}` projectile field `{1}` must define a value".F(weaponInfo.Key, sequenceReference.ImageReference));
                        }

                        continue;
                    }

                    image = image.ToLowerInvariant();
                    foreach (var sequence in LintExts.GetFieldValues(projectileInfo, field, emitError, sequenceReference.DictionaryReference))
                    {
                        if (string.IsNullOrEmpty(sequence))
                        {
                            continue;
                        }

                        if (sequenceReference.Prefix)
                        {
                            // TODO: Remove prefixed sequence references and instead use explicit lists of lintable references
                            if (!sequences.Sequences(image).Any(s => s.StartsWith(sequence)))
                            {
                                emitWarning("Weapon type `{0}` projectile field `{1}` defines a prefix `{2}` that does not match any sequences on image `{3}`.".F(weaponInfo.Key, field.Name, sequence, image));
                            }
                        }
                        else if (!sequences.HasSequence(image, sequence))
                        {
                            emitError("Weapon type `{0}` projectile field `{1}` references an undefined sequence `{2}` on image `{3}`.".F(weaponInfo.Key, field.Name, sequence, image));
                        }
                    }
                }
            }
        }