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); }); }
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; }
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(); }
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; }
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); }); }
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); }); }
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 ) ); }
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(); } }
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); }); }
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); }
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 ) ); }
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; }); }
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); }); }
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; }
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); } } }); }
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); } } }); }
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); }); }
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); } }
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); }
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); } }
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); }); }
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>()); }
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); } } }
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); } }
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)); } }
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)); }
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); }); }
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); }); } }
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)); } }
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); } }
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)); }
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)); } }
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); }); }
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)); }
void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) { inits.Add(new BodyAnimationFrameInit(frame)); }
void IDeathActorInitModifier.ModifyDeathActorInit(Actor self, TypeDictionary init) { init.Add(new FacingInit(Facing)); }
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); }
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); }
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; } } }
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(); }
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); }
void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) { if (!inits.Contains<FactionInit>()) inits.Add(new FactionInit(faction)); }
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); }); }
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); }); }
// 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)); }
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); }