Esempio n. 1
0
        public virtual bool Produce(Actor self, ActorInfo producee, string productionType, TypeDictionary inits, ManipulateActorCallback OnSpawnCallback)
        {
            if (IsTraitDisabled || IsTraitPaused || Reservable.IsReserved(self))
            {
                return(false);
            }

            // Pick a spawn/exit point pair
            var exit = SelectExit(self, producee, productionType);

            if (exit != null || self.OccupiesSpace == null || !producee.HasTraitInfo <IOccupySpaceInfo>())
            {
                DoProduction(self, producee, exit == null ? null : exit.Info, productionType, inits, OnSpawnCallback);

                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        public virtual void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string productionType, TypeDictionary inits, ManipulateActorCallback OnSpawnCallback)
        {
            var exit          = CPos.Zero;
            var exitLocations = new List <CPos>();

            // Clone the initializer dictionary for the new actor
            var td = new TypeDictionary();

            foreach (var init in inits)
            {
                td.Add(init);
            }

            if (exitinfo != null && self.OccupiesSpace != null && producee.HasTraitInfo <IOccupySpaceInfo>())
            {
                exit = self.Location + exitinfo.ExitCell;
                var spawn = self.CenterPosition + exitinfo.SpawnOffset;
                var to    = self.World.Map.CenterOfCell(exit);

                var initialFacing = exitinfo.Facing;
                if (exitinfo.Facing < 0)
                {
                    var delta = to - spawn;
                    if (delta.HorizontalLengthSquared == 0)
                    {
                        var fi = producee.TraitInfoOrDefault <IFacingInfo>();
                        initialFacing = fi != null?fi.GetInitialFacing() : 0;
                    }
                    else
                    {
                        initialFacing = delta.Yaw.Facing;
                    }
                }

                exitLocations = rp.Value != null && rp.Value.Path.Count > 0 ? rp.Value.Path : new List <CPos> {
                    exit
                };

                td.Add(new LocationInit(exit));
                td.Add(new CenterPositionInit(spawn));
                td.Add(new FacingInit(initialFacing));
                if (exitinfo != null)
                {
                    td.Add(new CreationActivityDelayInit(exitinfo.ExitDelay));
                }
            }

            self.World.AddFrameEndTask(w =>
            {
                var newUnit = self.World.CreateActor(producee.Name, td);

                OnSpawnCallback(newUnit);

                var move = newUnit.TraitOrDefault <IMove>();
                if (exitinfo != null && move != null)
                {
                    foreach (var cell in exitLocations)
                    {
                        newUnit.QueueActivity(new AttackMoveActivity(newUnit, () => move.MoveTo(cell, 1, evaluateNearestMovableCell: true, targetLineColor: Color.OrangeRed)));
                    }
                }

                if (!self.IsDead)
                {
                    foreach (var t in self.TraitsImplementing <INotifyProduction>())
                    {
                        t.UnitProduced(self, newUnit, exit);
                    }
                }

                var notifyOthers = self.World.ActorsWithTrait <INotifyOtherProduction>();
                foreach (var notify in notifyOthers)
                {
                    notify.Trait.UnitProducedByOther(notify.Actor, self, newUnit, productionType, td);
                }
            });
        }