Beispiel #1
0
        public void Killed(Actor self, AttackInfo e)
        {
            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary()
                {
                    new LocationInit( self.Location ),
                    new CenterLocationInit(self.CenterLocation),
                    new OwnerInit( self.Owner ),
                    new SkipMakeAnimsInit()
                };

                // Allows the husk to drag to its final position
                var mobile = self.TraitOrDefault<Mobile>();
                if (mobile != null)
                {
                    if (!mobile.CanEnterCell(self.Location, self, false)) return;
                    td.Add(new HuskSpeedInit(mobile.MovementSpeedForCell(self, self.Location)));
                }

                var facing = self.TraitOrDefault<IFacing>();
                if (facing != null)
                    td.Add(new FacingInit( facing.Facing ));

                var turreted = self.TraitOrDefault<Turreted>();
                if (turreted != null)
                    td.Add( new TurretFacingInit(turreted.turretFacing) );

                var huskActor = self.TraitsImplementing<IHuskModifier>()
                    .Select(ihm => ihm.HuskActor(self))
                    .FirstOrDefault(a => a != null);

                w.CreateActor(huskActor ?? Info.HuskActor, td);
            });
        }
Beispiel #2
0
        public override Activity Tick( Actor self )
        {
            if (IsCanceled) return NextActivity;

            self.World.AddFrameEndTask(w =>
            {
                var selected = w.Selection.Contains(self);

                self.Destroy();
                foreach (var s in Sounds)
                    Sound.PlayToPlayer(self.Owner, s, self.CenterLocation);

                var init = new TypeDictionary
                {
                    new LocationInit( self.Location + Offset ),
                    new OwnerInit( self.Owner ),
                    new FacingInit( Facing ),
                };
                var health = self.TraitOrDefault<Health>();
                if (health != null)
                {
                    // TODO: Fix bogus health init
                    if (ForceHealthPercentage > 0)
                        init.Add( new HealthInit( ForceHealthPercentage * 1f / 100 ));
                    else
                        init.Add( new HealthInit( (float)health.HP / health.MaxHP ));
                }
                var a = w.CreateActor( ToActor, init );

                if (selected)
                    w.Selection.Add(w, a);
            });

            return this;
        }
Beispiel #3
0
        public EditorActorBrush(EditorViewportControllerWidget editorWidget, ActorInfo actor, PlayerReference owner, WorldRenderer wr)
        {
            this.editorWidget = editorWidget;
            worldRenderer = wr;
            world = wr.World;
            editorLayer = world.WorldActor.Trait<EditorActorLayer>();

            Actor = actor;
            this.owner = owner;

            preview = editorWidget.Get<ActorPreviewWidget>("DRAG_ACTOR_PREVIEW");
            preview.GetScale = () => worldRenderer.Viewport.Zoom;
            preview.IsVisible = () => editorWidget.CurrentBrush == this;

            var buildingInfo = actor.Traits.GetOrDefault<BuildingInfo>();
            if (buildingInfo != null)
            {
                locationOffset = -FootprintUtils.AdjustForBuildingSize(buildingInfo);
                previewOffset = FootprintUtils.CenterOffset(world, buildingInfo);
            }

            var td = new TypeDictionary();
            td.Add(new FacingInit(facing));
            td.Add(new TurretFacingInit(facing));
            td.Add(new OwnerInit(owner.Name));
            td.Add(new RaceInit(owner.Race));
            preview.SetPreview(actor, td);

            // The preview widget may be rendered by the higher-level code before it is ticked.
            // Force a manual tick to ensure the bounds are set correctly for this first draw.
            Tick();
        }
Beispiel #4
0
        public override Activity Tick(Actor self)
        {
            if (IsCanceled)
                return NextActivity;

            self.World.AddFrameEndTask(w =>
            {
                if (self.IsDead())
                    return;

                foreach (var nt in self.TraitsImplementing<INotifyTransform>())
                    nt.OnTransform(self);

                var selected = w.Selection.Contains(self);
                var controlgroup = w.Selection.GetControlGroupForActor(self);

                self.Destroy();
                foreach (var s in Sounds)
                    Sound.PlayToPlayer(self.Owner, s, self.CenterPosition);

                var init = new TypeDictionary
                {
                    new LocationInit(self.Location + Offset),
                    new OwnerInit(self.Owner),
                    new FacingInit(Facing),
                };

                if (SkipMakeAnims)
                    init.Add(new SkipMakeAnimsInit());

                if (Race != null)
                    init.Add(new RaceInit(Race));

                var health = self.TraitOrDefault<Health>();
                if (health != null)
                {
                    var newHP = (ForceHealthPercentage > 0)
                        ? ForceHealthPercentage / 100f
                        : (float)health.HP / health.MaxHP;

                    init.Add(new HealthInit(newHP));
                }

                var cargo = self.TraitOrDefault<Cargo>();
                if (cargo != null)
                    init.Add(new RuntimeCargoInit(cargo.Passengers.ToArray()));

                var a = w.CreateActor(ToActor, init);
                foreach (var nt in self.TraitsImplementing<INotifyTransform>())
                    nt.AfterTransform(a);

                if (selected)
                    w.Selection.Add(w, a);
                if (controlgroup.HasValue)
                    w.Selection.AddToControlGroup(a, controlgroup.Value);
            });

            return this;
        }
Beispiel #5
0
        public void Killed(Actor self, AttackInfo e)
        {
            if (!self.IsInWorld)
                return;

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary
                {
                    new ParentActorInit(self),
                    new LocationInit(self.Location),
                    new CenterPositionInit(self.CenterPosition),
                    new OwnerInit(self.Owner),
                    new RaceInit(race),
                    new SkipMakeAnimsInit()
                };

                // Allows the husk to drag to its final position
                var mobile = self.TraitOrDefault<Mobile>();
                if (mobile != null)
                {
                    if (!mobile.CanEnterCell(self.Location, self, false)) return;
                    td.Add(new HuskSpeedInit(mobile.MovementSpeedForCell(self, self.Location)));
                }

                var facing = self.TraitOrDefault<IFacing>();
                if (facing != null)
                    td.Add(new FacingInit(facing.Facing));

                // TODO: This will only take the first turret if there are multiple
                // This isn't a problem with the current units, but may be a problem for mods
                var turreted = self.TraitsImplementing<Turreted>().FirstOrDefault();
                if (turreted != null)
                    td.Add(new TurretFacingInit(turreted.TurretFacing));

                var chronoshiftable = self.TraitOrDefault<Chronoshiftable>();
                if (chronoshiftable != null && chronoshiftable.ReturnTicks > 0)
                {
                    td.Add(new ChronoshiftOriginInit(chronoshiftable.Origin));
                    td.Add(new ChronoshiftReturnInit(chronoshiftable.ReturnTicks));
                }

                var huskActor = self.TraitsImplementing<IHuskModifier>()
                    .Select(ihm => ihm.HuskActor(self))
                    .FirstOrDefault(a => a != null);

                w.CreateActor(huskActor ?? info.HuskActor, td);
            });
        }
Beispiel #6
0
        public void Killed(Actor self, AttackInfo e)
        {
            if (info.RequiresLobbyCreeps && !self.World.LobbyInfo.GlobalSettings.Creeps)
                return;

            if (!self.IsInWorld)
                return;

            if (self.World.SharedRandom.Next(100) > info.Probability)
                return;

            var warhead = e.Warhead as DamageWarhead;
            if (info.DeathType != null && (warhead == null || !warhead.DamageTypes.Contains(info.DeathType)))
                return;

            self.World.AddFrameEndTask(w =>
            {
                // Actor has been disposed by something else before its death (for example `Enter`).
                if (self.Disposed)
                    return;

                var td = new TypeDictionary
                {
                    new ParentActorInit(self),
                    new LocationInit(self.Location),
                    new CenterPositionInit(self.CenterPosition),
                    new FactionInit(faction)
                };

                if (info.OwnerType == OwnerType.Victim)
                    td.Add(new OwnerInit(self.Owner));
                else if (info.OwnerType == OwnerType.Killer)
                    td.Add(new OwnerInit(e.Attacker.Owner));
                else
                    td.Add(new OwnerInit(self.World.Players.First(p => p.InternalName == info.InternalOwner)));

                if (info.SkipMakeAnimations)
                    td.Add(new SkipMakeAnimsInit());

                foreach (var modifier in self.TraitsImplementing<IDeathActorInitModifier>())
                    modifier.ModifyDeathActorInit(self, td);

                var huskActor = self.TraitsImplementing<IHuskModifier>()
                    .Select(ihm => ihm.HuskActor(self))
                    .FirstOrDefault(a => a != null);

                w.CreateActor(huskActor ?? info.Actor, td);
            });
        }
Beispiel #7
0
 public ActorReference( string type, Dictionary<string, MiniYaml> inits )
 {
     Type = type;
     InitDict = new TypeDictionary();
     foreach( var i in inits )
         InitDict.Add( LoadInit( i.Key, i.Value ) );
 }
Beispiel #8
0
		public Actor Create(string type, bool addToWorld, LuaTable initTable)
		{
			var initDict = new TypeDictionary();

			// Convert table entries into ActorInits
			foreach (var kv in initTable)
			{
				// Find the requested type
				var typeName = kv.Key.ToString();
				var initType = Game.modData.ObjectCreator.FindType(typeName + "Init");
				if (initType == null)
					throw new LuaException("Unknown initializer type '{0}'".F(typeName));

				// Cast it up to an IActorInit<T>
				var genericType = initType.GetInterfaces()
					.First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IActorInit<>));
				var innerType = genericType.GetGenericArguments().First();

				// Try and coerce the table value to the required type
				object value;
				if (!kv.Value.TryGetClrValue(innerType, out value))
					throw new LuaException("Invalid data type for '{0}' (expected '{1}')".F(typeName, innerType.Name));

				// Construct the ActorInit. Phew!
				var test = initType.GetConstructor(new[] { innerType }).Invoke(new[] { value });
				initDict.Add(test);
			}

			// The actor must be added to the world at the end of the tick
			var a = context.World.CreateActor(false, type, initDict);
			if (addToWorld)
				context.World.AddFrameEndTask(w => w.Add(a));

			return a;
		}
		public override void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
		{
			var map = firedBy.World.Map;
			var targetCell = map.CellContaining(target.CenterPosition);

			if (!IsValidImpact(target.CenterPosition, firedBy))
				return;

			var targetCells = map.FindTilesInCircle(targetCell, Range);
			var cell = targetCells.GetEnumerator();

			foreach (var a in Actors)
			{
				var placed = false;
				var td = new TypeDictionary();
				if (Owner == null)
					td.Add(new OwnerInit(firedBy.Owner));
				else
					td.Add(new OwnerInit(firedBy.World.Players.First(p => p.InternalName == Owner)));

				var unit = firedBy.World.CreateActor(false, a.ToLowerInvariant(), td);

				while (cell.MoveNext())
				{
					if (unit.Trait<IPositionable>().CanEnterCell(cell.Current))
					{
						var cellpos = firedBy.World.Map.CenterOfCell(cell.Current);
						var pos = cellpos.Z < target.CenterPosition.Z
							? new WPos(cellpos.X, cellpos.Y, target.CenterPosition.Z)
							: cellpos;
						firedBy.World.AddFrameEndTask(w =>
						{
							w.Add(unit);
							if (Paradrop)
								unit.QueueActivity(new Parachute(unit, pos));
							else
								unit.QueueActivity(new FallDown(unit, pos, FallRate));
						});
						placed = true;
						break;
					}
				}

				if (!placed)
					unit.Dispose();
			}
		}
Beispiel #10
0
        public void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string raceVariant)
        {
            var exit = self.Location + exitinfo.ExitCell;
            var spawn = self.CenterPosition + exitinfo.SpawnOffset;
            var to = self.World.Map.CenterOfCell(exit);

            var fi = producee.Traits.GetOrDefault<IFacingInfo>();
            var initialFacing = exitinfo.Facing < 0 ? Util.GetFacing(to - spawn, fi == null ? 0 : fi.GetInitialFacing()) : exitinfo.Facing;

            var exitLocation = rp.Value != null ? rp.Value.Location : exit;
            var target = Target.FromCell(self.World, exitLocation);

            var bi = producee.Traits.GetOrDefault<BuildableInfo>();
            if (bi != null && bi.ForceRace != null)
                raceVariant = bi.ForceRace;

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary
                {
                    new OwnerInit(self.Owner),
                    new LocationInit(exit),
                    new CenterPositionInit(spawn),
                    new FacingInit(initialFacing)
                };

                if (raceVariant != null)
                    td.Add(new RaceInit(raceVariant));

                var newUnit = self.World.CreateActor(producee.Name, td);

                var move = newUnit.TraitOrDefault<IMove>();
                if (move != null)
                {
                    if (exitinfo.MoveIntoWorld)
                    {
                        if (exitinfo.ExitDelay > 0)
                            newUnit.QueueActivity(new Wait(exitinfo.ExitDelay));

                        newUnit.QueueActivity(move.MoveIntoWorld(newUnit, exit));
                        newUnit.QueueActivity(new AttackMoveActivity(
                            newUnit, move.MoveTo(exitLocation, 1)));
                    }
                }

                newUnit.SetTargetLine(target, rp.Value != null ? Color.Red : Color.Green, false);

                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);

                foreach (var t in newUnit.TraitsImplementing<INotifyBuildComplete>())
                    t.BuildingComplete(newUnit);
            });
        }
Beispiel #11
0
        public ColorPickerLogic(Widget widget, ModData modData, World world, HSLColor initialColor, Action<HSLColor> onChange, WorldRenderer worldRenderer)
        {
            string actorType;
            if (!ChromeMetrics.TryGet("ColorPickerActorType", out actorType))
                actorType = "mcv";

            var preview = widget.GetOrNull<ActorPreviewWidget>("PREVIEW");
            var actor = world.Map.Rules.Actors[actorType];

            var td = new TypeDictionary();
            td.Add(new HideBibPreviewInit());
            td.Add(new OwnerInit(world.WorldActor.Owner));
            td.Add(new FactionInit(world.WorldActor.Owner.PlayerReference.Faction));

            if (preview != null)
                preview.SetPreview(actor, td);

            var hueSlider = widget.Get<SliderWidget>("HUE");
            var mixer = widget.Get<ColorMixerWidget>("MIXER");
            var randomButton = widget.GetOrNull<ButtonWidget>("RANDOM_BUTTON");

            hueSlider.OnChange += _ => mixer.Set(hueSlider.Value);
            mixer.OnChange += () => onChange(mixer.Color);

            if (randomButton != null)
                randomButton.OnClick = () =>
                {
                    // Avoid colors with low sat or lum
                    var hue = (byte)Game.CosmeticRandom.Next(255);
                    var sat = (byte)Game.CosmeticRandom.Next(70, 255);
                    var lum = (byte)Game.CosmeticRandom.Next(70, 255);

                    mixer.Set(new HSLColor(hue, sat, lum));
                    hueSlider.Value = hue / 255f;
                };

            // Set the initial state
            var validator = modData.Manifest.Get<ColorValidator>();
            mixer.SetPaletteRange(validator.HsvSaturationRange[0], validator.HsvSaturationRange[1], validator.HsvValueRange[0], validator.HsvValueRange[1]);
            mixer.Set(initialColor);

            hueSlider.Value = initialColor.H / 255f;
            onChange(mixer.Color);
        }
Beispiel #12
0
        public ActorReference( string type, Dictionary<string, MiniYaml> inits )
        {
            if (Rules.Info != null && !Rules.Info.ContainsKey(type))
                throw new InvalidDataException("Unknown actor: `{0}'".F(type));

            Type = type;
            InitDict = new TypeDictionary();
            foreach( var i in inits )
                InitDict.Add( LoadInit( i.Key, i.Value ) );
        }
Beispiel #13
0
		public ActorReference(string type, Dictionary<string, MiniYaml> inits)
		{
			Type = type;
			initDict = Exts.Lazy(() =>
			{
				var dict = new TypeDictionary();
				foreach (var i in inits)
					dict.Add(LoadInit(i.Key, i.Value));
				return dict;
			});
		}
Beispiel #14
0
 public ActorReference(string type, Dictionary <string, MiniYaml> inits)
 {
     Type     = type;
     initDict = Exts.Lazy(() =>
     {
         var dict = new TypeDictionary();
         foreach (var i in inits)
         {
             dict.Add(LoadInit(i.Key, i.Value));
         }
         return(dict);
     });
 }
Beispiel #15
0
 public ActorReference(string type, TypeDictionary inits)
 {
     Type     = type;
     initDict = new Lazy <TypeDictionary>(() =>
     {
         var dict = new TypeDictionary();
         foreach (var i in inits)
         {
             dict.Add(i);
         }
         return(dict);
     });
 }
        public override bool Produce(Actor self, ActorInfo producee, string raceVariant)
        {
            var location = self.World.Map.ChooseClosestEdgeCell(self.Location);
            var pos = self.World.Map.CenterOfCell(location);

            // If aircraft, spawn at cruise altitude
            var aircraftInfo = producee.Traits.GetOrDefault<AircraftInfo>();
            if (aircraftInfo != null)
                pos += new WVec(0, 0, aircraftInfo.CruiseAltitude.Range);

            var initialFacing = self.World.Map.FacingBetween(location, self.Location, 0);

            self.World.AddFrameEndTask(w =>
                {
                    var td = new TypeDictionary
                    {
                        new OwnerInit(self.Owner),
                        new LocationInit(location),
                        new CenterPositionInit(pos),
                        new FacingInit(initialFacing)
                    };

                    if (raceVariant != null)
                        td.Add(new RaceInit(raceVariant));

                    var newUnit = self.World.CreateActor(producee.Name, td);

                    var move = newUnit.TraitOrDefault<IMove>();
                    if (move != null)
                        newUnit.QueueActivity(move.MoveIntoWorld(newUnit, self.Location));

                    newUnit.SetTargetLine(Target.FromCell(self.World, self.Location), Color.Green, false);

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

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

                    var bi = newUnit.Info.Traits.GetOrDefault<BuildableInfo>();
                    if (bi != null && bi.InitialActivity != null)
                        newUnit.QueueActivity(Game.CreateObject<Activity>(bi.InitialActivity));

                    foreach (var t in newUnit.TraitsImplementing<INotifyBuildComplete>())
                        t.BuildingComplete(newUnit);
                });

            return true;
        }
Beispiel #17
0
        public void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string raceVariant)
        {
            var exit  = self.Location + exitinfo.ExitCell;
            var spawn = self.CenterPosition + exitinfo.SpawnOffset;
            var to    = self.World.Map.CenterOfCell(exit);

            var fi            = producee.Traits.Get <IFacingInfo>();
            var initialFacing = exitinfo.Facing < 0 ? Util.GetFacing(to - spawn, fi.GetInitialFacing()) : exitinfo.Facing;

            var exitLocation = rp.Value != null ? rp.Value.Location : exit;
            var target       = Target.FromCell(self.World, exitLocation);

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary
                {
                    new OwnerInit(self.Owner),
                    new LocationInit(exit),
                    new CenterPositionInit(spawn),
                    new FacingInit(initialFacing)
                };

                if (raceVariant != null)
                {
                    td.Add(new RaceInit(raceVariant));
                }

                var newUnit = self.World.CreateActor(producee.Name, td);

                var move = newUnit.TraitOrDefault <IMove>();
                if (move != null)
                {
                    if (exitinfo.MoveIntoWorld)
                    {
                        newUnit.QueueActivity(move.MoveIntoWorld(newUnit, exit));
                        newUnit.QueueActivity(new AttackMove.AttackMoveActivity(
                                                  newUnit, move.MoveTo(exitLocation, 1)));
                    }
                }

                newUnit.SetTargetLine(target, rp.Value != null ? Color.Red : Color.Green, false);

                if (!self.IsDead())
                {
                    foreach (var t in self.TraitsImplementing <INotifyProduction>())
                    {
                        t.UnitProduced(self, newUnit, exit);
                    }
                }
            });
        }
Beispiel #18
0
        void INotifyKilled.Killed(Actor self, AttackInfo attack)
        {
            if (IsTraitDisabled)
            {
                return;
            }

            if (!Info.DeathTypes.IsEmpty && !attack.Damage.DamageTypes.Overlaps(Info.DeathTypes))
            {
                return;
            }

            var buildingInfo      = self.Info.TraitInfoOrDefault <BuildingInfo>();
            var eligibleLocations = buildingInfo != null
                                ? buildingInfo.Tiles(self.Location).ToList()
                                : new List <CPos>()
            {
                self.World.Map.CellContaining(self.CenterPosition)
            };

            self.World.AddFrameEndTask(w =>
            {
                foreach (var actorType in Info.Actors)
                {
                    var td = new TypeDictionary();

                    td.Add(new OwnerInit(self.Owner));
                    td.Add(new LocationInit(eligibleLocations.Random(w.SharedRandom)));

                    var unit   = w.CreateActor(true, actorType.ToLowerInvariant(), td);
                    var mobile = unit.TraitOrDefault <Mobile>();
                    if (mobile != null)
                    {
                        mobile.Nudge(unit);
                    }
                }
            });
        }
Beispiel #19
0
        public void Killed(Actor self, AttackInfo e)
        {
            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary
                {
                    new ParentActorInit(self),
                    new LocationInit(self.Location),
                    new CenterLocationInit(self.CenterLocation),
                    new OwnerInit(self.Owner),
                    new SkipMakeAnimsInit()
                };

                // Allows the husk to drag to its final position
                var mobile = self.TraitOrDefault <Mobile>();
                if (mobile != null)
                {
                    if (!mobile.CanEnterCell(self.Location, self, false))
                    {
                        return;
                    }
                    td.Add(new HuskSpeedInit(mobile.MovementSpeedForCell(self, self.Location)));
                }

                var aircraft = self.TraitOrDefault <Aircraft>();
                if (aircraft != null)
                {
                    td.Add(new AltitudeInit(aircraft.CenterPosition.Z * Game.CellSize / 1024));
                }

                var facing = self.TraitOrDefault <IFacing>();
                if (facing != null)
                {
                    td.Add(new FacingInit(facing.Facing));
                }

                // TODO: This will only take the first turret if there are multiple
                // This isn't a problem with the current units, but may be a problem for mods
                var turreted = self.TraitsImplementing <Turreted>().FirstOrDefault();
                if (turreted != null)
                {
                    td.Add(new TurretFacingInit(turreted.turretFacing));
                }

                var chronoshiftable = self.TraitOrDefault <Chronoshiftable>();
                if (chronoshiftable != null && chronoshiftable.ReturnTicks > 0)
                {
                    td.Add(new ChronoshiftOriginInit(chronoshiftable.Origin));
                    td.Add(new ChronoshiftReturnInit(chronoshiftable.ReturnTicks));
                }

                var huskActor = self.TraitsImplementing <IHuskModifier>()
                                .Select(ihm => ihm.HuskActor(self))
                                .FirstOrDefault(a => a != null);

                w.CreateActor(huskActor ?? info.HuskActor, td);
            });
        }
Beispiel #20
0
        public void ModifyDeathActorInit(Actor self, TypeDictionary init)
        {
            var facings = init.GetOrDefault <TurretFacingsInit>();

            if (facings == null)
            {
                facings = new TurretFacingsInit();
                init.Add(facings);
            }

            if (!facings.Value(self.World).ContainsKey(Name))
            {
                facings.Value(self.World).Add(Name, TurretFacing);
            }
        }
Beispiel #21
0
        public ActorInfo(ObjectCreator creator, string name, MiniYaml node, Dictionary <string, MiniYaml> allUnits)
        {
            try
            {
                Name = name;

                var allParents        = new HashSet <string>();
                var abstractActorType = name.StartsWith("^");

                // Guard against circular inheritance
                allParents.Add(name);

                var partial = MergeWithParents(node, allUnits, allParents);
                foreach (var t in MiniYaml.ApplyRemovals(partial.Nodes))
                {
                    if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@"))
                    {
                        try
                        {
                            traits.Add(LoadTraitInfo(creator, t.Key.Split('@')[0], t.Value));
                        }
                        catch (FieldLoader.MissingFieldsException e)
                        {
                            if (!abstractActorType)
                            {
                                throw new YamlException(e.Message);
                            }
                        }
                    }
                }
            }
            catch (YamlException e)
            {
                throw new YamlException("Actor type {0}: {1}".F(name, e.Message));
            }
        }
		Actor CreateActor(Player owner, string actorType, bool addToWorld, CPos? entryLocation = null, CPos? nextLocation = null)
		{
			ActorInfo ai;
			if (!Context.World.Map.Rules.Actors.TryGetValue(actorType, out ai))
				throw new LuaException("Unknown actor type '{0}'".F(actorType));

			var initDict = new TypeDictionary();

			initDict.Add(new OwnerInit(owner));

			if (entryLocation.HasValue)
			{
				var pi = ai.TraitInfoOrDefault<AircraftInfo>();
				initDict.Add(new CenterPositionInit(owner.World.Map.CenterOfCell(entryLocation.Value) + new WVec(0, 0, pi != null ? pi.CruiseAltitude.Length : 0)));
				initDict.Add(new LocationInit(entryLocation.Value));
			}

			if (entryLocation.HasValue && nextLocation.HasValue)
				initDict.Add(new FacingInit(Context.World.Map.FacingBetween(CPos.Zero, CPos.Zero + (nextLocation.Value - entryLocation.Value), 0)));

			var actor = Context.World.CreateActor(addToWorld, actorType, initDict);

			return actor;
		}
        public Actor Create(string type, bool addToWorld, LuaTable initTable)
        {
            var initDict = new TypeDictionary();

            // Convert table entries into ActorInits
            foreach (var kv in initTable)
            {
                using (kv.Key)
                    using (kv.Value)
                    {
                        // Find the requested type
                        var typeName = kv.Key.ToString();
                        var initType = Game.ModData.ObjectCreator.FindType(typeName + "Init");
                        if (initType == null)
                        {
                            throw new LuaException("Unknown initializer type '{0}'".F(typeName));
                        }

                        // Cast it up to an IActorInit<T>
                        var genericType = initType.GetInterfaces()
                                          .First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IActorInit <>));
                        var innerType = genericType.GetGenericArguments().First();
                        var valueType = innerType.IsEnum ? typeof(int) : innerType;

                        // Try and coerce the table value to the required type
                        object value;
                        if (!kv.Value.TryGetClrValue(valueType, out value))
                        {
                            throw new LuaException("Invalid data type for '{0}' (expected '{1}')".F(typeName, valueType.Name));
                        }

                        // Construct the ActorInit. Phew!
                        var test = initType.GetConstructor(new[] { innerType }).Invoke(new[] { value });
                        initDict.Add(test);
                    }
            }

            // The actor must be added to the world at the end of the tick
            var a = Context.World.CreateActor(false, type, initDict);

            if (addToWorld)
            {
                Context.World.AddFrameEndTask(w => w.Add(a));
            }

            return(a);
        }
Beispiel #24
0
        public PlaceBuildingOrderGenerator(ProductionQueue queue, string name, WorldRenderer worldRenderer)
        {
            var world = queue.Actor.World;

            this.queue        = queue;
            placeBuildingInfo = queue.Actor.Owner.PlayerActor.Info.TraitInfo <PlaceBuildingInfo>();
            buildingInfluence = world.WorldActor.Trait <BuildingInfluence>();
            viewport          = worldRenderer.Viewport;

            // Clear selection if using Left-Click Orders
            if (Game.Settings.Game.UseClassicMouseStyle)
            {
                world.Selection.Clear();
            }

            actorInfo    = world.Map.Rules.Actors[name];
            buildingInfo = actorInfo.TraitInfo <BuildingInfo>();

            var previewGeneratorInfo = actorInfo.TraitInfoOrDefault <IPlaceBuildingPreviewGeneratorInfo>();

            if (previewGeneratorInfo != null)
            {
                var faction = actorInfo.TraitInfo <BuildableInfo>().ForceFaction;
                if (faction == null)
                {
                    var mostLikelyProducer = queue.MostLikelyProducer();
                    faction = mostLikelyProducer.Trait != null ? mostLikelyProducer.Trait.Faction : queue.Actor.Owner.Faction.InternalName;
                }

                var td = new TypeDictionary()
                {
                    new FactionInit(faction),
                    new OwnerInit(queue.Actor.Owner),
                };

                foreach (var api in actorInfo.TraitInfos <IActorPreviewInitInfo>())
                {
                    foreach (var o in api.ActorPreviewInits(actorInfo, ActorPreviewType.PlaceBuilding))
                    {
                        td.Add(o);
                    }
                }

                preview = previewGeneratorInfo.CreatePreview(worldRenderer, queue.Actor, actorInfo, td);
            }
        }
Beispiel #25
0
        public void Killed(Actor self, AttackInfo e)
        {
            if (e.Warhead != null && e.Warhead.InfDeath == Info.InfDeath
                    && self.World.SharedRandom.Next(100) <= Info.Probability)
                self.World.AddFrameEndTask(w =>
                    {
                        var td = new TypeDictionary
                        {
                            new LocationInit( self.Location ),
                            new OwnerInit( self.World.Players.First(p => p.InternalName == Info.Owner) )
                        };

                        if (self.HasTrait<IFacing>())
                            td.Add(new FacingInit( self.Trait<IFacing>().Facing ));
                        w.CreateActor(Info.ViceroidActor, td);
                    });
        }
Beispiel #26
0
        public void Add()
        {
            var td = new TypeDictionary <IServiceCollection, IServiceProvider>();

            Should.Throw <ArgumentException>(() => td.Add(typeof(ServiceDescriptor), typeof(ServiceProvider)));
            Should.Throw <ArgumentException>(() => td.Add(typeof(ServiceCollection), typeof(ServiceDescriptor)));
            Should.Throw <ArgumentException>(() => td.Add(new KeyValuePair <Type, Type>(typeof(ServiceCollection), typeof(ServiceDescriptor))));
            Should.NotThrow(() => td.Add(typeof(ServiceCollection), typeof(ServiceProvider)));
            Should.Throw <ArgumentException>(() => td.Add <ServiceCollection, ServiceProvider>());
            td.Clear();
            Should.NotThrow(() => td.Add <ServiceCollection, ServiceProvider>());
        }
Beispiel #27
0
        public static void Load(List <TextNode> nodes)
        {
            foreach (MissionType type in Enum.GetValues(typeof(MissionType)))
            {
                missionMaps.Add(type, new List <MapType>());
            }

            foreach (var node in nodes)
            {
                var type = MapType.FromRules(node);

                Types.Add(type.Name, type);

                foreach (var missionType in type.MissionTypes)
                {
                    missionMaps[missionType].Add(type);
                }
            }
        }
Beispiel #28
0
        private static void UpdateEntities(float dt)
        {
            // Add/Remove entities
            foreach (var e in _removeEntities)
            {
                _entities.Remove(e);
            }
            foreach (var e in _addEntities)
            {
                _entities.Add(e);
            }
            _removeEntities.Clear(); _addEntities.Clear();

            // Update Entities
            foreach (var entity in _entities)
            {
                entity.Update(dt);
            }
        }
Beispiel #29
0
        public ActorInfo(string name, MiniYaml node, Dictionary <string, MiniYaml> allUnits)
        {
            try
            {
                var mergedNode = MergeWithParent(node, allUnits).NodesDict;

                Name = name;
                foreach (var t in mergedNode)
                {
                    if (t.Key != "Inherits" && !t.Key.StartsWith("-"))
                    {
                        Traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value));
                    }
                }
            }
            catch (YamlException e)
            {
                throw new YamlException("Actor type {0}: {1}".F(name, e.Message));
            }
        }
Beispiel #30
0
        void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits)
        {
            Func <WAngle> bodyFacing    = () => facing.Facing;
            var           dynamicFacing = inits.GetOrDefault <DynamicFacingInit>();
            var           staticFacing  = inits.GetOrDefault <FacingInit>();

            if (dynamicFacing != null)
            {
                bodyFacing = dynamicFacing.Value;
            }
            else if (staticFacing != null)
            {
                bodyFacing = () => staticFacing.Value;
            }

            // Freeze the relative turret facing to its current value
            var facingOffset = WAngle.FromFacing(TurretFacing) - bodyFacing();

            inits.Add(new DynamicTurretFacingInit(Info, () => bodyFacing() + facingOffset));
        }
Beispiel #31
0
        public void Killed(Actor self, AttackInfo e)
        {
            if (e.Warhead == null || e.Warhead.DeathType != spawnViceroidInfo.DeathType) return;
            if (self.World.SharedRandom.Next(100) > spawnViceroidInfo.Probability) return;

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary
                {
                    new LocationInit(self.Location),
                    new OwnerInit(self.World.Players.First(p => p.InternalName == spawnViceroidInfo.Owner))
                };

                var facing = self.TraitOrDefault<IFacing>();
                if (facing != null)
                    td.Add(new FacingInit(facing.Facing));

                w.CreateActor(spawnViceroidInfo.ViceroidActor, td);
            });
        }
Beispiel #32
0
        public ActorReference(string type, Dictionary <string, MiniYaml> inits)
        {
            Type     = type;
            initDict = Exts.Lazy(() =>
            {
                var dict = new TypeDictionary();
                foreach (var i in inits)
                {
                    var init = LoadInit(i.Key, i.Value);
                    if (init is ISingleInstanceInit && dict.Contains(init.GetType()))
                    {
                        throw new InvalidDataException("Duplicate initializer '{0}'".F(init.GetType().Name));
                    }

                    dict.Add(init);
                }

                return(dict);
            });
        }
        public void ResolveOrder(Actor self, Order order)
        {
            if (order.OrderString == "StructureChronoTeleport" && CanTeleport)
            {
                var maxDistance = Info.HasDistanceLimit ? Info.MaxDistance : (int?)null;

                self.CancelActivity();
                //self.QueueActivity(new Teleport(self, order.TargetLocation, maxDistance, true, false, Info.ChronoshiftSound));

                self.World.AddFrameEndTask(w =>
                {
                    var init = new TypeDictionary
                    {
                        new LocationInit(order.TargetLocation),
                        new OwnerInit(order.Player),
                        new FactionInit(self.Owner.Faction.InternalName)
                    };

                    var health = self.TraitOrDefault <Health>();
                    if (health != null)
                    {
                        var newHP = (health.HP * 100) / health.MaxHP;
                        init.Add(new HealthInit(newHP));
                    }

                    // TODO: I'm assuming that structures don't get veterrancy.
                    // If necessary, add veterrancy to the new actor.

                    var building = w.CreateActor(self.Info.Name, init);

                    // Chronoshift is "used".
                    building.Trait <StructureChrono>().chargeTick = self.Info.TraitInfo <StructureChronoInfo>().ChargeDelay;

                    // "sell" the old one.
                    self.Dispose();

                    // Play chrono sound
                    Game.Sound.PlayToPlayer(order.Player, Info.ChronoshiftSound, building.CenterPosition);
                });
            }
        }
Beispiel #34
0
        public ActorInfo(string name, MiniYaml node, Dictionary <string, MiniYaml> allUnits)
        {
            try
            {
                var allParents        = new HashSet <string>();
                var abstractActorType = name.StartsWith("^");

                // Guard against circular inheritance
                allParents.Add(name);
                var mergedNode = MergeWithParents(node, allUnits, allParents).ToDictionary();

                Name = name;

                foreach (var t in mergedNode)
                {
                    if (t.Key[0] == '-')
                    {
                        throw new YamlException("Bogus trait removal: " + t.Key);
                    }

                    if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@"))
                    {
                        try
                        {
                            Traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value));
                        }
                        catch (FieldLoader.MissingFieldsException e)
                        {
                            if (!abstractActorType)
                            {
                                throw new YamlException(e.Message);
                            }
                        }
                    }
                }
            }
            catch (YamlException e)
            {
                throw new YamlException("Actor type {0}: {1}".F(name, e.Message));
            }
        }
Beispiel #35
0
            public VariantWrapper(WorldRenderer wr, ProductionQueue queue, ActorInfo ai)
            {
                ActorInfo     = ai;
                BuildingInfo  = ActorInfo.TraitInfo <BuildingInfo>();
                PlugInfo      = ActorInfo.TraitInfoOrDefault <PlugInfo>();
                LineBuildInfo = ActorInfo.TraitInfoOrDefault <LineBuildInfo>();

                var previewGeneratorInfo = ActorInfo.TraitInfoOrDefault <IPlaceBuildingPreviewGeneratorInfo>();

                if (previewGeneratorInfo != null)
                {
                    string faction;
                    var    buildableInfo = ActorInfo.TraitInfoOrDefault <BuildableInfo>();
                    if (buildableInfo != null && buildableInfo.ForceFaction != null)
                    {
                        faction = buildableInfo.ForceFaction;
                    }
                    else
                    {
                        var mostLikelyProducer = queue.MostLikelyProducer();
                        faction = mostLikelyProducer.Trait != null ? mostLikelyProducer.Trait.Faction : queue.Actor.Owner.Faction.InternalName;
                    }

                    var td = new TypeDictionary()
                    {
                        new FactionInit(faction),
                        new OwnerInit(queue.Actor.Owner),
                    };

                    foreach (var api in ActorInfo.TraitInfos <IActorPreviewInitInfo>())
                    {
                        foreach (var o in api.ActorPreviewInits(ActorInfo, ActorPreviewType.PlaceBuilding))
                        {
                            td.Add(o);
                        }
                    }

                    Preview = previewGeneratorInfo.CreatePreview(wr, ActorInfo, td);
                }
            }
Beispiel #36
0
        void INotifyKilled.Killed(Actor self, AttackInfo e)
        {
            if (newOwner == null)
            {
                return;
            }

            var td = new TypeDictionary
            {
                new ParentActorInit(self),
                new LocationInit(self.Location + info.Offset),
                new CenterPositionInit(self.CenterPosition),
                new OwnerInit(newOwner),
                new HealthInit(info.ResurrectHealth),
            };

            foreach (var t in turreted)
            {
                td.Add(new TurretFacingInit(t.Info, t.LocalOrientation.Yaw));
            }

            self.World.AddFrameEndTask(w => w.CreateActor(info.SpawnsActor, td));
        }
Beispiel #37
0
        public static void Load(List <TextNode> nodes)
        {
            foreach (var node in nodes)
            {
                var name  = node.Key;
                var parts = new PartInfo[node.Children.Count];

                var currentPartCounts = new Dictionary <string, int>();
                for (int i = 0; i < parts.Length; i++)
                {
                    var child = node.Children[i];

                    if (!currentPartCounts.ContainsKey(child.Key))
                    {
                        currentPartCounts[child.Key] = 0;
                    }

                    parts[i] = TypeLoader.GetPart(currentPartCounts[child.Key]++, child);
                }

                Types.Add(name, new ActorType(parts));
            }
        }
Beispiel #38
0
        public void Killed(Actor self, AttackInfo e)
        {
            if (!self.World.LobbyInfo.GlobalSettings.Creeps) return;
            if (self.World.SharedRandom.Next(100) > info.Probability) return;

            var warhead = e.Warhead as DamageWarhead;
            if (warhead == null || !warhead.DamageTypes.Contains(info.DeathType))
                return;

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary
                {
                    new LocationInit(self.Location),
                    new OwnerInit(self.World.Players.First(p => p.InternalName == info.Owner))
                };

                var facing = self.TraitOrDefault<IFacing>();
                if (facing != null)
                    td.Add(new FacingInit(facing.Facing));

                w.CreateActor(info.ViceroidActor, td);
            });
        }
Beispiel #39
0
        void INotifyKilled.Killed(Actor self, AttackInfo e)
        {
            if (!self.IsInWorld)
            {
                return;
            }

            Game.Sound.Play(SoundType.World, info.LostSound, self.CenterPosition);

            var td = new TypeDictionary
            {
                new ParentActorInit(self),
                new LocationInit(self.Location + info.Offset),
                new CenterPositionInit(self.CenterPosition),
                new OwnerInit(info.NewOwner),
            };

            foreach (var t in turreted)
            {
                td.Add(new TurretFacingInit(t.Info, t.LocalOrientation.Yaw));
            }

            self.World.AddFrameEndTask(w => w.CreateActor(info.SpawnsActor, td));
        }
Beispiel #40
0
 void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits)
 {
     inits.Add(new BodyAnimationFrameInit(frame));
 }
Beispiel #41
0
 void IDeathActorInitModifier.ModifyDeathActorInit(Actor self, TypeDictionary init)
 {
     init.Add(new FacingInit(Facing));
 }
Beispiel #42
0
        public override Activity Tick(Actor self)
        {
            if (IsCanceled)
            {
                return(NextActivity);
            }

            self.World.AddFrameEndTask(w =>
            {
                if (self.IsDead)
                {
                    return;
                }

                foreach (var nt in self.TraitsImplementing <INotifyTransform>())
                {
                    nt.OnTransform(self);
                }

                var selected     = w.Selection.Contains(self);
                var controlgroup = w.Selection.GetControlGroupForActor(self);

                self.Dispose();
                foreach (var s in Sounds)
                {
                    Game.Sound.PlayToPlayer(self.Owner, s, self.CenterPosition);
                }

                Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Notification, self.Owner.Faction.InternalName);

                var init = new TypeDictionary
                {
                    new LocationInit(self.Location + Offset),
                    new OwnerInit(self.Owner),
                    new FacingInit(Facing),
                };

                if (SkipMakeAnims)
                {
                    init.Add(new SkipMakeAnimsInit());
                }

                if (Faction != null)
                {
                    init.Add(new FactionInit(Faction));
                }

                var health = self.TraitOrDefault <Health>();
                if (health != null)
                {
                    var newHP = ForceHealthPercentage > 0 ? ForceHealthPercentage : (health.HP * 100) / health.MaxHP;
                    init.Add(new HealthInit(newHP));
                }

                var cargo = self.TraitOrDefault <Cargo>();
                if (cargo != null)
                {
                    init.Add(new RuntimeCargoInit(cargo.Passengers.ToArray()));
                }

                var a = w.CreateActor(ToActor, init);
                foreach (var nt in self.TraitsImplementing <INotifyTransform>())
                {
                    nt.AfterTransform(a);
                }

                if (selected)
                {
                    w.Selection.Add(w, a);
                }
                if (controlgroup.HasValue)
                {
                    w.Selection.AddToControlGroup(a, controlgroup.Value);
                }
            });

            return(this);
        }
Beispiel #43
0
        public virtual void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string factionVariant)
        {
            var exit = CPos.Zero;
            var exitLocation = CPos.Zero;
            var target = Target.Invalid;

            var bi = producee.TraitInfoOrDefault<BuildableInfo>();
            if (bi != null && bi.ForceFaction != null)
                factionVariant = bi.ForceFaction;

            var td = new TypeDictionary
            {
                new OwnerInit(self.Owner),
            };

            if (self.OccupiesSpace != null)
            {
                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;
                }

                exitLocation = rp.Value != null ? rp.Value.Location : exit;
                target = Target.FromCell(self.World, exitLocation);

                td.Add(new LocationInit(exit));
                td.Add(new CenterPositionInit(spawn));
                td.Add(new FacingInit(initialFacing));
            }

            self.World.AddFrameEndTask(w =>
            {
                if (factionVariant != null)
                    td.Add(new FactionInit(factionVariant));

                var newUnit = self.World.CreateActor(producee.Name, td);

                var move = newUnit.TraitOrDefault<IMove>();
                if (move != null)
                {
                    if (exitinfo.MoveIntoWorld)
                    {
                        if (exitinfo.ExitDelay > 0)
                            newUnit.QueueActivity(new Wait(exitinfo.ExitDelay, false));

                        newUnit.QueueActivity(move.MoveIntoWorld(newUnit, exit));
                        newUnit.QueueActivity(new AttackMoveActivity(
                            newUnit, move.MoveTo(exitLocation, 1)));
                    }
                }

                newUnit.SetTargetLine(target, rp.Value != null ? Color.Red : Color.Green, false);

                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);

                foreach (var t in newUnit.TraitsImplementing<INotifyBuildComplete>())
                    t.BuildingComplete(newUnit);
            });
        }
        public override bool Produce(Actor self, ActorInfo producee, string raceVariant)
        {
            var location = self.World.Map.ChooseClosestEdgeCell(self.Location);
            var pos      = self.World.Map.CenterOfCell(location);

            // If aircraft, spawn at cruise altitude
            var aircraftInfo = producee.Traits.GetOrDefault <AircraftInfo>();

            if (aircraftInfo != null)
            {
                pos += new WVec(0, 0, aircraftInfo.CruiseAltitude.Range);
            }

            var initialFacing = self.World.Map.FacingBetween(location, self.Location, 0);

            self.World.AddFrameEndTask(w =>
            {
                var td = new TypeDictionary
                {
                    new OwnerInit(self.Owner),
                    new LocationInit(location),
                    new CenterPositionInit(pos),
                    new FacingInit(initialFacing)
                };

                if (raceVariant != null)
                {
                    td.Add(new RaceInit(raceVariant));
                }

                var newUnit = self.World.CreateActor(producee.Name, td);

                var move = newUnit.TraitOrDefault <IMove>();
                if (move != null)
                {
                    newUnit.QueueActivity(move.MoveIntoWorld(newUnit, self.Location));
                }

                newUnit.SetTargetLine(Target.FromCell(self.World, self.Location), Color.Green, false);

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

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

                var bi = newUnit.Info.Traits.GetOrDefault <BuildableInfo>();
                if (bi != null && bi.InitialActivity != null)
                {
                    newUnit.QueueActivity(Game.CreateObject <Activity>(bi.InitialActivity));
                }

                foreach (var t in newUnit.TraitsImplementing <INotifyBuildComplete>())
                {
                    t.BuildingComplete(newUnit);
                }
            });

            return(true);
        }
Beispiel #45
0
		void IntializeActorPreviews()
		{
			panel.RemoveChildren();

			var actors = modRules.Actors.Where(a => !a.Value.Name.Contains('^'))
				.Select(a => a.Value);

			foreach (var a in actors)
			{
				var actor = a;
				if (actor.HasTraitInfo<BridgeInfo>()) // bridge layer takes care about that automatically
					continue;

				if (!actor.HasTraitInfo<IRenderActorPreviewInfo>())
					continue;

				var filter = actor.TraitInfoOrDefault<EditorTilesetFilterInfo>();
				if (filter != null)
				{
					if (filter.ExcludeTilesets != null && filter.ExcludeTilesets.Contains(world.TileSet.Id))
						continue;
					if (filter.RequireTilesets != null && !filter.RequireTilesets.Contains(world.TileSet.Id))
						continue;
				}

				var td = new TypeDictionary();
				td.Add(new FacingInit(92));
				td.Add(new TurretFacingInit(92));
				td.Add(new HideBibPreviewInit());
				td.Add(new OwnerInit(selectedOwner.Name));
				td.Add(new FactionInit(selectedOwner.Faction));

				try
				{
					var item = ScrollItemWidget.Setup(itemTemplate,
						() => { var brush = editor.CurrentBrush as EditorActorBrush; return brush != null && brush.Actor == actor; },
						() => editor.SetBrush(new EditorActorBrush(editor, actor, selectedOwner, worldRenderer)));

					var preview = item.Get<ActorPreviewWidget>("ACTOR_PREVIEW");
					preview.SetPreview(actor, td);

					// Scale templates to fit within the panel
					var scale = 1f;
					if (scale * preview.IdealPreviewSize.X > itemTemplate.Bounds.Width)
						scale = (float)(itemTemplate.Bounds.Width - panel.ItemSpacing) / (float)preview.IdealPreviewSize.X;

					preview.GetScale = () => scale;
					preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.X);
					preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y);

					item.Bounds.Width = preview.Bounds.Width + 2 * preview.Bounds.X;
					item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y;
					item.IsVisible = () => true;

					var tooltip = actor.TraitInfoOrDefault<TooltipInfo>();
					item.GetTooltipText = () => tooltip == null ? actor.Name : tooltip.Name + " (" + actor.Name + ")";

					panel.AddChild(item);
				}
				catch
				{
					Log.Write("debug", "Map editor ignoring actor {0}, because of missing sprites for tileset {1}.",
						actor.Name, world.TileSet.Id);
					continue;
				}
			}
		}
Beispiel #46
0
        public Server(List <IPEndPoint> endpoints, ServerSettings settings, ModData modData, ServerType type)
        {
            Log.AddChannel("server", "server.log", true);

            SocketException lastException   = null;
            var             checkReadServer = new List <Socket>();

            foreach (var endpoint in endpoints)
            {
                var listener = new TcpListener(endpoint);
                try
                {
                    try
                    {
                        listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 1);
                    }
                    catch (Exception ex)
                    {
                        if (ex is SocketException || ex is ArgumentException)
                        {
                            Log.Write("server", "Failed to set socket option on {0}: {1}", endpoint.ToString(), ex.Message);
                        }
                        else
                        {
                            throw;
                        }
                    }

                    listener.Start();
                    listeners.Add(listener);
                    checkReadServer.Add(listener.Server);
                }
                catch (SocketException ex)
                {
                    lastException = ex;
                    Log.Write("server", "Failed to listen on {0}: {1}", endpoint.ToString(), ex.Message);
                }
            }

            if (listeners.Count == 0)
            {
                throw lastException;
            }

            Type     = type;
            Settings = settings;

            Settings.Name = OpenRA.Settings.SanitizedServerName(Settings.Name);

            ModData = modData;

            playerDatabase = modData.Manifest.Get <PlayerDatabase>();

            randomSeed = (int)DateTime.Now.ToBinary();

            if (type != ServerType.Local && settings.EnableGeoIP)
            {
                GeoIP.Initialize();
            }

            if (UPnP.Status == UPnPStatus.Enabled)
            {
                UPnP.ForwardPort(Settings.ListenPort, Settings.ListenPort).Wait();
            }

            foreach (var trait in modData.Manifest.ServerTraits)
            {
                serverTraits.Add(modData.ObjectCreator.CreateObject <ServerTrait>(trait));
            }

            serverTraits.TrimExcess();

            LobbyInfo = new Session
            {
                GlobalSettings =
                {
                    RandomSeed         = randomSeed,
                    Map                = settings.Map,
                    ServerName         = settings.Name,
                    EnableSingleplayer = settings.EnableSingleplayer || Type != ServerType.Dedicated,
                    EnableSyncReports  = settings.EnableSyncReports,
                    GameUid            = Guid.NewGuid().ToString(),
                    Dedicated          = Type == ServerType.Dedicated
                }
            };

            new Thread(_ =>
            {
                foreach (var t in serverTraits.WithInterface <INotifyServerStart>())
                {
                    t.ServerStarted(this);
                }

                Log.Write("server", "Initial mod: {0}", ModData.Manifest.Id);
                Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);

                while (true)
                {
                    var checkRead = new List <Socket>();
                    if (State == ServerState.WaitingPlayers)
                    {
                        checkRead.AddRange(checkReadServer);
                    }

                    checkRead.AddRange(Conns.Select(c => c.Socket));
                    checkRead.AddRange(PreConns.Select(c => c.Socket));

                    // Block for at most 1 second in order to guarantee a minimum tick rate for ServerTraits
                    // Decrease this to 100ms to improve responsiveness if we are waiting for an authentication query
                    var localTimeout = waitingForAuthenticationCallback > 0 ? 100000 : 1000000;
                    if (checkRead.Count > 0)
                    {
                        Socket.Select(checkRead, null, null, localTimeout);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        break;
                    }

                    foreach (var s in checkRead)
                    {
                        var serverIndex = checkReadServer.IndexOf(s);
                        if (serverIndex >= 0)
                        {
                            AcceptConnection(listeners[serverIndex]);
                            continue;
                        }

                        var preConn = PreConns.SingleOrDefault(c => c.Socket == s);
                        if (preConn != null)
                        {
                            preConn.ReadData(this);
                            continue;
                        }

                        var conn = Conns.SingleOrDefault(c => c.Socket == s);
                        conn?.ReadData(this);
                    }

                    delayedActions.PerformActions(0);

                    // PERF: Dedicated servers need to drain the action queue to remove references blocking the GC from cleaning up disposed objects.
                    if (Type == ServerType.Dedicated)
                    {
                        Game.PerformDelayedActions();
                    }

                    foreach (var t in serverTraits.WithInterface <ITick>())
                    {
                        t.Tick(this);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        if (UPnP.Status == UPnPStatus.Enabled)
                        {
                            UPnP.RemovePortForward().Wait();
                        }
                        break;
                    }
                }

                foreach (var t in serverTraits.WithInterface <INotifyServerShutdown>())
                {
                    t.ServerShutdown(this);
                }

                PreConns.Clear();
                Conns.Clear();

                foreach (var listener in listeners)
                {
                    try { listener.Stop(); }
                    catch { }
                }
            })
            {
                IsBackground = true
            }.Start();
        }
Beispiel #47
0
        public override Activity Tick(Actor self)
        {
            if (IsCanceled)
            {
                return(NextActivity);
            }

            self.World.AddFrameEndTask(w =>
            {
                foreach (var nt in self.TraitsImplementing <INotifyTransform>())
                {
                    nt.OnTransform(self);
                }

                var selected = w.Selection.Contains(self);

                self.Destroy();
                foreach (var s in Sounds)
                {
                    Sound.PlayToPlayer(self.Owner, s, self.CenterLocation);
                }

                var init = new TypeDictionary
                {
                    new LocationInit(self.Location + Offset),
                    new OwnerInit(self.Owner),
                    new FacingInit(Facing),
                };

                if (SkipMakeAnims)
                {
                    init.Add(new SkipMakeAnimsInit());
                }

                var health = self.TraitOrDefault <Health>();
                if (health != null)
                {
                    var newHP = (ForceHealthPercentage > 0)
                                                ? ForceHealthPercentage / 100f
                                                : (float)health.HP / health.MaxHP;

                    init.Add(new HealthInit(newHP));
                }

                var cargo = self.TraitOrDefault <Cargo>();
                if (cargo != null)
                {
                    init.Add(new CargoInit(cargo.Passengers.ToArray()));
                }

                var a = w.CreateActor(ToActor, init);

                foreach (var nt in self.TraitsImplementing <INotifyTransformed>())
                {
                    nt.OnTransformed(a);
                }

                if (selected)
                {
                    w.Selection.Add(w, a);
                }
            });

            return(this);
        }
Beispiel #48
0
 void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits)
 {
     if (!inits.Contains<FactionInit>())
         inits.Add(new FactionInit(faction));
 }
Beispiel #49
0
		public void Killed(Actor self, AttackInfo e)
		{
			if (info.RequiresLobbyCreeps && !self.World.LobbyInfo.GlobalSettings.Creeps)
				return;

			if (!self.IsInWorld)
				return;

			if (self.World.SharedRandom.Next(100) > info.Probability)
				return;

			var warhead = e.Warhead as DamageWarhead;
			if (info.DeathType != null && (warhead == null || !warhead.DamageTypes.Contains(info.DeathType)))
				return;

			self.World.AddFrameEndTask(w =>
			{
				var td = new TypeDictionary
				{
					new ParentActorInit(self),
					new LocationInit(self.Location),
					new CenterPositionInit(self.CenterPosition),
					new FactionInit(faction)
				};

				if (info.OwnerType == OwnerType.Victim)
					td.Add(new OwnerInit(self.Owner));
				else if (info.OwnerType == OwnerType.Killer)
					td.Add(new OwnerInit(e.Attacker.Owner));
				else
					td.Add(new OwnerInit(self.World.Players.First(p => p.InternalName == info.InternalOwner)));

				if (info.SkipMakeAnimations)
					td.Add(new SkipMakeAnimsInit());

				// Allows the husk to drag to its final position
				var mobile = self.TraitOrDefault<Mobile>();
				if (mobile != null)
				{
					if (!mobile.CanEnterCell(self.Location, self, false)) return;
					td.Add(new HuskSpeedInit(mobile.MovementSpeedForCell(self, self.Location)));
				}

				var facing = self.TraitOrDefault<IFacing>();
				if (facing != null)
					td.Add(new FacingInit(facing.Facing));

				// TODO: This will only take the first turret if there are multiple
				// This isn't a problem with the current units, but may be a problem for mods
				var turreted = self.TraitsImplementing<Turreted>().FirstOrDefault();
				if (turreted != null)
					td.Add(new TurretFacingInit(turreted.TurretFacing));

				// TODO: untie this and move to Mods.Common
				var chronoshiftable = self.TraitOrDefault<Chronoshiftable>();
				if (chronoshiftable != null && chronoshiftable.ReturnTicks > 0)
				{
					td.Add(new ChronoshiftOriginInit(chronoshiftable.Origin));
					td.Add(new ChronoshiftReturnInit(chronoshiftable.ReturnTicks));
				}

				var huskActor = self.TraitsImplementing<IHuskModifier>()
					.Select(ihm => ihm.HuskActor(self))
					.FirstOrDefault(a => a != null);

				w.CreateActor(huskActor ?? info.Actor, td);
			});
		}
Beispiel #50
0
        void DoTransform(Actor self)
        {
            // Hack: repeat the first frame of the make anim instead
            // of flashing the full structure for a frame
            if (rb != null)
                rb.PlayCustomAnim(self, "make");

            self.World.AddFrameEndTask(w =>
            {
                var selected = w.Selection.Contains(self);

                self.Destroy();
                foreach (var s in sounds)
                    Sound.PlayToPlayer(self.Owner, s, self.CenterLocation);

                var init = new TypeDictionary
                {
                    new LocationInit( self.Location + offset ),
                    new OwnerInit( self.Owner ),
                    new FacingInit( facing ),
                };
                if (self.HasTrait<Health>())
                    init.Add( new HealthInit( self.Trait<Health>().HPFraction ));

                var a = w.CreateActor( actor, init );

                if (selected)
                    w.Selection.Add(w, a);
            });
        }
Beispiel #51
0
        // Don't add the new actor to the world before all RemovedFromWorld callbacks have run
        void INotifyRemovedFromWorld.RemovedFromWorld(Actor self)
        {
            if (attackingPlayer == null)
            {
                return;
            }

            var defeated = self.Owner.WinState == WinState.Lost;

            if (defeated && !Info.SpawnAfterDefeat)
            {
                return;
            }

            var td = new TypeDictionary
            {
                new ParentActorInit(self),
                new LocationInit(self.Location + Info.Offset),
                new CenterPositionInit(self.CenterPosition),
                new FactionInit(faction)
            };

            if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised)
            {
                td.Add(new EffectiveOwnerInit(self.EffectiveOwner.Owner));
            }
            else if (Info.EffectiveOwnerFromOwner)
            {
                td.Add(new EffectiveOwnerInit(self.Owner));
            }

            if (Info.OwnerType == OwnerType.Victim)
            {
                // Fall back to InternalOwner if the Victim was defeated,
                // but only if InternalOwner is defined
                if (!defeated || string.IsNullOrEmpty(Info.InternalOwner))
                {
                    td.Add(new OwnerInit(self.Owner));
                }
                else
                {
                    td.Add(new OwnerInit(self.World.Players.First(p => p.InternalName == Info.InternalOwner)));
                    if (!td.Contains <EffectiveOwnerInit>())
                    {
                        td.Add(new EffectiveOwnerInit(self.Owner));
                    }
                }
            }
            else if (Info.OwnerType == OwnerType.Killer)
            {
                td.Add(new OwnerInit(attackingPlayer));
            }
            else
            {
                td.Add(new OwnerInit(self.World.Players.First(p => p.InternalName == Info.InternalOwner)));
            }

            if (Info.SkipMakeAnimations)
            {
                td.Add(new SkipMakeAnimsInit());
            }

            foreach (var modifier in self.TraitsImplementing <IDeathActorInitModifier>())
            {
                modifier.ModifyDeathActorInit(self, td);
            }

            var huskActor = self.TraitsImplementing <IHuskModifier>()
                            .Select(ihm => ihm.HuskActor(self))
                            .FirstOrDefault(a => a != null);

            self.World.AddFrameEndTask(w => w.CreateActor(huskActor ?? Info.Actor, td));
        }
Beispiel #52
0
 public static Actor CreateActor(this World world, bool addToWorld, string name, Player owner, CPos? location, int? facing)
 {
     var td = new TypeDictionary { new OwnerInit(owner) };
     if (location.HasValue)
         td.Add(new LocationInit(location.Value));
     if (facing.HasValue)
         td.Add(new FacingInit(facing.Value));
     return world.CreateActor(addToWorld, name, td);
 }