Exemple #1
0
        internal Actor(World world, string name, TypeDictionary initDict)
        {
            var init = new ActorInitializer(this, initDict);

            World   = world;
            ActorID = world.NextAID();
            if (initDict.Contains <OwnerInit>())
            {
                Owner = init.Get <OwnerInit, Player>();
            }

            if (name != null)
            {
                name = name.ToLowerInvariant();

                if (!world.Map.Rules.Actors.ContainsKey(name))
                {
                    throw new NotImplementedException("No rules definition for unit " + name);
                }

                Info = world.Map.Rules.Actors[name];
                foreach (var trait in Info.TraitsInConstructOrder())
                {
                    AddTrait(trait.Create(init));

                    // Some traits rely on properties provided by IOccupySpace in their initialization,
                    // so we must ready it now, we cannot wait until all traits have finished construction.
                    if (trait is IOccupySpaceInfo)
                    {
                        OccupiesSpace = Trait <IOccupySpace>();
                    }
                }
            }

            // PERF: Cache all these traits as soon as the actor is created. This is a fairly cheap one-off cost per
            // actor that allows us to provide some fast implementations of commonly used methods that are relied on by
            // performance-sensitive parts of the core game engine, such as pathfinding, visibility and rendering.
            EffectiveOwner      = TraitOrDefault <IEffectiveOwner>();
            facing              = TraitOrDefault <IFacing>();
            health              = TraitOrDefault <IHealth>();
            renderModifiers     = TraitsImplementing <IRenderModifier>().ToArray();
            renders             = TraitsImplementing <IRender>().ToArray();
            mouseBounds         = TraitsImplementing <IMouseBounds>().ToArray();
            visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray();
            defaultVisibility   = Trait <IDefaultVisibility>();
            Targetables         = TraitsImplementing <ITargetable>().ToArray();
            targetablePositions = TraitsImplementing <ITargetablePositions>().ToArray();
            world.AddFrameEndTask(w =>
            {
                // Caching this in a AddFrameEndTask, because trait construction order might cause problems if done directly at creation time.
                // All actors that can move or teleport should have IPositionable, if not it's pretty safe to assume the actor is completely immobile and
                // all targetable positions can be cached if all ITargetablePositions have no conditional requirements.
                if (!Info.HasTraitInfo <IPositionableInfo>() && targetablePositions.Any() && targetablePositions.All(tp => tp.AlwaysEnabled))
                {
                    staticTargetablePositions = targetablePositions.SelectMany(tp => tp.TargetablePositions(this)).ToArray();
                }
            });

            SyncHashes = TraitsImplementing <ISync>().Select(sync => new SyncHash(sync)).ToArray();
        }
Exemple #2
0
        internal Actor(World world, string name, TypeDictionary initDict)
        {
            var init = new ActorInitializer(this, initDict);

            World   = world;
            ActorID = world.NextAID();
            if (initDict.Contains <OwnerInit>())
            {
                Owner = init.Get <OwnerInit, Player>();
            }

            if (name != null)
            {
                name = name.ToLowerInvariant();

                if (!world.Map.Rules.Actors.ContainsKey(name))
                {
                    throw new NotImplementedException("No rules definition for unit " + name);
                }

                Info = world.Map.Rules.Actors[name];
                foreach (var trait in Info.TraitsInConstructOrder())
                {
                    AddTrait(trait.Create(init));

                    // Some traits rely on properties provided by IOccupySpace in their initialization,
                    // so we must ready it now, we cannot wait until all traits have finished construction.
                    if (trait is IOccupySpaceInfo)
                    {
                        OccupiesSpace = Trait <IOccupySpace>();
                    }
                }
            }

            // PERF: Cache all these traits as soon as the actor is created. This is a fairly cheap one-off cost per
            // actor that allows us to provide some fast implementations of commonly used methods that are relied on by
            // performance-sensitive parts of the core game engine, such as pathfinding, visibility and rendering.
            Bounds              = DetermineBounds();
            VisualBounds        = DetermineVisualBounds();
            EffectiveOwner      = TraitOrDefault <IEffectiveOwner>();
            facing              = TraitOrDefault <IFacing>();
            health              = TraitOrDefault <IHealth>();
            renderModifiers     = TraitsImplementing <IRenderModifier>().ToArray();
            renders             = TraitsImplementing <IRender>().ToArray();
            disables            = TraitsImplementing <IDisable>().ToArray();
            visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray();
            defaultVisibility   = Trait <IDefaultVisibility>();
            Targetables         = TraitsImplementing <ITargetable>().ToArray();

            SyncHashes =
                TraitsImplementing <ISync>()
                .Select(sync => Pair.New(sync, Sync.GetHashFunction(sync)))
                .ToArray()
                .Select(pair => new SyncHash(pair.First, pair.Second(pair.First)));
        }
        public GpsDotEffectAS(Actor actor, GpsDotAS trait)
        {
            this.actor = actor;
            this.trait = trait;
            anim       = new Animation(actor.World, trait.Info.Image);
            anim.PlayRepeating(trait.Info.Sequence);

            visibility          = actor.Trait <IDefaultVisibility>();
            visibilityModifiers = actor.TraitsImplementing <IVisibilityModifier>().ToArray();

            dotStates = new PlayerDictionary <DotState>(actor.World,
                                                        p => new DotState(actor, p.PlayerActor.Trait <GpsASWatcher>(), p.FrozenActorLayer));
        }
        public GpsDotEffect(Actor actor, GpsDotInfo info)
        {
            this.actor = actor;
            this.info  = info;
            anim       = new Animation(actor.World, info.Image);
            anim.PlayRepeating(info.String);

            visibility          = actor.Trait <IDefaultVisibility>();
            visibilityModifiers = actor.TraitsImplementing <IVisibilityModifier>().ToArray();

            dotStates = new PlayerDictionary <DotState>(actor.World,
                                                        p => new DotState(actor, p.PlayerActor.Trait <GpsWatcher>(), p.PlayerActor.TraitOrDefault <FrozenActorLayer>()));
        }
Exemple #5
0
        internal Actor(World world, string name, TypeDictionary initDict)
        {
            var init = new ActorInitializer(this, initDict);

            World   = world;
            ActorID = world.NextAID();

            if (initDict.Contains <OwnerInit>())
            {
                Owner = init.Get <OwnerInit, Player>();
            }
            if (name != null)
            {
                name = name.ToLowerInvariant();

                if (!world.Map.Rules.Actors.ContainsKey(name))
                {
                    throw new NotImplementedException("No rules definition for unit {0}".F(name));
                }
                Info = world.Map.Rules.Actors[name];
                foreach (var trait in Info.TraitsInConstructOrder())
                {
                    AddTrait(trait.Create(init));
                    if (trait is IOccupySpaceInfo)
                    {
                        OccupiesSpace = Trait <IOccupySpace>();
                    }
                }
            }

            EffectiveOwner = TraitOrDefault <IEffectiveOwner>();

            facing              = TraitOrDefault <IFacing>();
            health              = TraitOrDefault <IHealth>();
            disables            = TraitsImplementing <IDisable>().ToArray();
            renders             = TraitsImplementing <IRender>().ToArray();
            renderModifiers     = TraitsImplementing <IRenderModifier>().ToArray();
            visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray();
            defaultVisibility   = Trait <IDefaultVisibility>();
            Targetables         = TraitsImplementing <ITargetable>().ToArray();
            mouseBounds         = TraitsImplementing <IMouseBounds>().ToArray();
            //Bounds = DetermineBounds();

            //SyncHashes = TraitsImplementing<ISync>()
            //    .Select(sync => Pair.New(sync, Sync.GetHashFunction(sync)))
            //    .ToArray()
            //    .Select(pair => new SyncHash(pair.First, pair.Second(pair.First)));
            SyncHashes = TraitsImplementing <ISync>().Select(sync => new SyncHash(sync)).ToArray();
        }
Exemple #6
0
        internal Actor(World world, string name, TypeDictionary initDict)
        {
            var init = new ActorInitializer(this, initDict);

            World   = world;
            ActorID = world.NextAID();
            if (initDict.Contains <OwnerInit>())
            {
                Owner = init.Get <OwnerInit, Player>();
            }

            if (name != null)
            {
                name = name.ToLowerInvariant();

                if (!world.Map.Rules.Actors.ContainsKey(name))
                {
                    throw new NotImplementedException("No rules definition for unit " + name);
                }

                Info = world.Map.Rules.Actors[name];
                foreach (var trait in Info.TraitsInConstructOrder())
                {
                    AddTrait(trait.Create(init));

                    // Some traits rely on properties provided by IOccupySpace in their initialization,
                    // so we must ready it now, we cannot wait until all traits have finished construction.
                    if (trait is IOccupySpaceInfo)
                    {
                        OccupiesSpace = Trait <IOccupySpace>();
                    }
                }
            }

            Bounds              = DetermineBounds();
            VisualBounds        = DetermineVisualBounds();
            EffectiveOwner      = TraitOrDefault <IEffectiveOwner>();
            facing              = TraitOrDefault <IFacing>();
            health              = TraitOrDefault <IHealth>();
            renderModifiers     = TraitsImplementing <IRenderModifier>().ToArray();
            renders             = TraitsImplementing <IRender>().ToArray();
            disables            = TraitsImplementing <IDisable>().ToArray();
            visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray();
            defaultVisibility   = Trait <IDefaultVisibility>();
        }
Exemple #7
0
        internal Actor(World world, string name, TypeDictionary initDict)
        {
            var duplicateInit = initDict.WithInterface <ISingleInstanceInit>().GroupBy(i => i.GetType())
                                .FirstOrDefault(i => i.Count() > 1);

            if (duplicateInit != null)
            {
                throw new InvalidDataException("Duplicate initializer '{0}'".F(duplicateInit.Key.Name));
            }

            var init = new ActorInitializer(this, initDict);

            readOnlyConditionCache = new ReadOnlyDictionary <string, int>(conditionCache);

            World   = world;
            ActorID = world.NextAID();
            var ownerInit = init.GetOrDefault <OwnerInit>();

            if (ownerInit != null)
            {
                Owner = ownerInit.Value(world);
            }

            if (name != null)
            {
                name = name.ToLowerInvariant();

                if (!world.Map.Rules.Actors.ContainsKey(name))
                {
                    throw new NotImplementedException("No rules definition for unit " + name);
                }

                Info = world.Map.Rules.Actors[name];

                IPositionable positionable            = null;
                var           resolveOrdersList       = new List <IResolveOrder>();
                var           renderModifiersList     = new List <IRenderModifier>();
                var           rendersList             = new List <IRender>();
                var           mouseBoundsList         = new List <IMouseBounds>();
                var           visibilityModifiersList = new List <IVisibilityModifier>();
                var           becomingIdlesList       = new List <INotifyBecomingIdle>();
                var           tickIdlesList           = new List <INotifyIdle>();
                var           targetablesList         = new List <ITargetable>();
                var           targetablePositionsList = new List <ITargetablePositions>();
                var           syncHashesList          = new List <SyncHash>();

                foreach (var traitInfo in Info.TraitsInConstructOrder())
                {
                    var trait = traitInfo.Create(init);
                    AddTrait(trait);

                    // PERF: Cache all these traits as soon as the actor is created. This is a fairly cheap one-off cost per
                    // actor that allows us to provide some fast implementations of commonly used methods that are relied on by
                    // performance-sensitive parts of the core game engine, such as pathfinding, visibility and rendering.
                    // Note: The blocks are required to limit the scope of the t's, so we make an exception to our normal style
                    // rules for spacing in order to keep these assignments compact and readable.
                    { if (trait is IPositionable t)
                      {
                          positionable = t;
                      }
                    }
                    { if (trait is IOccupySpace t)
                      {
                          OccupiesSpace = t;
                      }
                    }
                    { if (trait is IEffectiveOwner t)
                      {
                          EffectiveOwner = t;
                      }
                    }
                    { if (trait is IFacing t)
                      {
                          facing = t;
                      }
                    }
                    { if (trait is IHealth t)
                      {
                          health = t;
                      }
                    }
                    { if (trait is IResolveOrder t)
                      {
                          resolveOrdersList.Add(t);
                      }
                    }
                    { if (trait is IRenderModifier t)
                      {
                          renderModifiersList.Add(t);
                      }
                    }
                    { if (trait is IRender t)
                      {
                          rendersList.Add(t);
                      }
                    }
                    { if (trait is IMouseBounds t)
                      {
                          mouseBoundsList.Add(t);
                      }
                    }
                    { if (trait is IVisibilityModifier t)
                      {
                          visibilityModifiersList.Add(t);
                      }
                    }
                    { if (trait is IDefaultVisibility t)
                      {
                          defaultVisibility = t;
                      }
                    }
                    { if (trait is INotifyBecomingIdle t)
                      {
                          becomingIdlesList.Add(t);
                      }
                    }
                    { if (trait is INotifyIdle t)
                      {
                          tickIdlesList.Add(t);
                      }
                    }
                    { if (trait is ITargetable t)
                      {
                          targetablesList.Add(t);
                      }
                    }
                    { if (trait is ITargetablePositions t)
                      {
                          targetablePositionsList.Add(t);
                      }
                    }
                    { if (trait is ISync t)
                      {
                          syncHashesList.Add(new SyncHash(t));
                      }
                    }
                }

                resolveOrders       = resolveOrdersList.ToArray();
                renderModifiers     = renderModifiersList.ToArray();
                renders             = rendersList.ToArray();
                mouseBounds         = mouseBoundsList.ToArray();
                visibilityModifiers = visibilityModifiersList.ToArray();
                becomingIdles       = becomingIdlesList.ToArray();
                tickIdles           = tickIdlesList.ToArray();
                Targetables         = targetablesList.ToArray();
                var targetablePositions = targetablePositionsList.ToArray();
                enabledTargetablePositions = targetablePositions.Where(Exts.IsTraitEnabled);
                SyncHashes = syncHashesList.ToArray();

                setStaticTargetablePositions = positionable == null && targetablePositions.Any() && targetablePositions.All(tp => tp.AlwaysEnabled);
            }
        }
Exemple #8
0
        internal Actor(World world, string name, TypeDictionary initDict)
        {
            var init = new ActorInitializer(this, initDict);

            World   = world;
            ActorID = world.NextAID();
            if (initDict.Contains <OwnerInit>())
            {
                Owner = init.Get <OwnerInit, Player>();
            }

            occupySpace = Exts.Lazy(() => TraitOrDefault <IOccupySpace>());

            if (name != null)
            {
                name = name.ToLowerInvariant();

                if (!world.Map.Rules.Actors.ContainsKey(name))
                {
                    throw new NotImplementedException("No rules definition for unit " + name);
                }

                Info = world.Map.Rules.Actors[name];
                foreach (var trait in Info.TraitsInConstructOrder())
                {
                    AddTrait(trait.Create(init));
                }
            }

            facing         = Exts.Lazy(() => TraitOrDefault <IFacing>());
            health         = Exts.Lazy(() => TraitOrDefault <Health>());
            effectiveOwner = Exts.Lazy(() => TraitOrDefault <IEffectiveOwner>());

            bounds = Exts.Lazy(() =>
            {
                var si   = Info.Traits.GetOrDefault <SelectableInfo>();
                var size = (si != null && si.Bounds != null) ? new int2(si.Bounds[0], si.Bounds[1]) :
                           TraitsImplementing <IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();

                var offset = -size / 2;
                if (si != null && si.Bounds != null && si.Bounds.Length > 2)
                {
                    offset += new int2(si.Bounds[2], si.Bounds[3]);
                }

                return(new Rectangle(offset.X, offset.Y, size.X, size.Y));
            });

            visualBounds = Exts.Lazy(() =>
            {
                var sd = Info.Traits.GetOrDefault <ISelectionDecorationsInfo>();
                if (sd == null || sd.SelectionBoxBounds == null)
                {
                    return(bounds.Value);
                }

                var size = new int2(sd.SelectionBoxBounds[0], sd.SelectionBoxBounds[1]);

                var offset = -size / 2;
                if (sd.SelectionBoxBounds.Length > 2)
                {
                    offset += new int2(sd.SelectionBoxBounds[2], sd.SelectionBoxBounds[3]);
                }

                return(new Rectangle(offset.X, offset.Y, size.X, size.Y));
            });

            renderModifiers     = TraitsImplementing <IRenderModifier>().ToArray();
            renders             = TraitsImplementing <IRender>().ToArray();
            disables            = TraitsImplementing <IDisable>().ToArray();
            visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray();
            defaultVisibility   = Trait <IDefaultVisibility>();
        }