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 void SetPreview(ActorInfo actor, TypeDictionary td) { var init = new ActorPreviewInitializer(actor, worldRenderer, td); preview = actor.TraitInfos<IRenderActorPreviewInfo>() .SelectMany(rpi => rpi.RenderPreview(init)) .ToArray(); // Calculate the preview bounds PreviewOffset = int2.Zero; IdealPreviewSize = int2.Zero; var r = preview .SelectMany(p => p.Render(worldRenderer, WPos.Zero)) .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey) .Select(rr => rr.PrepareRender(worldRenderer)); if (r.Any()) { var b = r.First().ScreenBounds(worldRenderer); foreach (var rr in r.Skip(1)) b = Rectangle.Union(b, rr.ScreenBounds(worldRenderer)); IdealPreviewSize = new int2(b.Width, b.Height); PreviewOffset = -new int2(b.Left, b.Top) - IdealPreviewSize / 2; } }
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 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 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 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); }); }
static void CheckResult(string content, string expected) { var folder = new FolderTestModel(); var memory = new TypeDictionary(); memory.GetItem<Settings>().OutputFolder = "output"; var file = new StoryTestFile("myfile", new StoryTestFolder(memory, folder), folder); file.WriteTest(new PageResult("title", content, new TestCounts())); Assert.AreEqual(expected, folder.GetPageContent(new FilePath("output\\myfile.html"))); }
public static Memory InitAssembliesAndNamespaces() { var memory = new TypeDictionary(); memory.GetItem<ApplicationUnderTest>().AddAssembly(Assembly.GetAssembly(typeof (TestUtils)).CodeBase); memory.GetItem<ApplicationUnderTest>().AddNamespace("fit.Test.NUnit"); memory.GetItem<ApplicationUnderTest>().AddNamespace("fit.Test.Acceptance"); return memory; }
public void Run(IList<string> commandLineArguments) { var memory = new TypeDictionary(); var reporter = new CollectingReporter(); var runner = new SuiteRunnerShell(memory, reporter, NewService); runner.SuiteRunner.StartTest += OnStartTest; runner.SuiteRunner.EndTest += OnEndTest; runner.Run(commandLineArguments, memory); }
static CommandFactory() { CommandFactory.commands = new TypeDictionary<string, ICommandHandler>( TypeHelpers .ClassesForInterfaceInAssembly<ICommandHandler>() .SelectMany(t => (Attribute.GetCustomAttribute(t, typeof(HandlerAttribute)) as HandlerAttribute).words.Select(cw => new { CommandWord = cw, Type = t })) .ToDictionary(c => c.CommandWord.ToUpperInvariant(), c => c.Type) ); }
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 ) ); }
static void CheckResult(string content, string expected) { Clock.Instance = new TestClock {Now = new DateTime(2016, 1, 2, 13, 14, 15)}; var folder = new FolderTestModel(); var memory = new TypeDictionary(); memory.GetItem<Settings>().OutputFolder = "output"; var file = new StoryTestFile("myfile", new StoryTestFolder(memory, folder), folder); file.WriteTest(new PageResult("title", content, new TestCounts())); Clock.Instance = new Clock(); Assert.AreEqual(comment + expected, folder.GetPageContent(new FilePath("output\\myfile.html"))); }
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 vTypeDictionary(TypeDictionary model) { DB db =new DB(); this.ID = model.ID; this.TypeValue = model.TypeValue; this.Time = model.Time.ToString(); this.NeedAuthorize = model.NeedAuthorize; this.Belonger = model.Belonger; this.FatherID = model.FatherID; this.Children = db.TypeDictionaries.Where(td => td.FatherID == model.ID).ToList(); }
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 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 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 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 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 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 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 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 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); }); }
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 void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string factionVariant) { 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.ForceFaction != null) { factionVariant = bi.ForceFaction; } self.World.AddFrameEndTask(w => { var td = new TypeDictionary { new OwnerInit(self.Owner), new LocationInit(exit), new CenterPositionInit(spawn), new FacingInit(initialFacing) }; 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)); } 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 IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr, World world) { var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo); var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo); var rules = world.Map.Rules; var actorInfo = rules.Actors[building]; foreach (var dec in actorInfo.TraitInfos<IPlaceBuildingDecorationInfo>()) foreach (var r in dec.Render(wr, world, actorInfo, offset)) yield return r; var cells = new Dictionary<CPos, bool>(); var plugInfo = rules.Actors[building].TraitInfoOrDefault<PlugInfo>(); if (plugInfo != null) { if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1) throw new InvalidOperationException("Plug requires a 1x1 sized Building"); cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo)); } else if (rules.Actors[building].HasTraitInfo<LineBuildInfo>()) { // Linebuild for walls. if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1) throw new InvalidOperationException("LineBuild requires a 1x1 sized Building"); if (!Game.GetModifierKeys().HasModifier(Modifiers.Shift)) foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, building, buildingInfo)) cells.Add(t, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, t)); else cells.Add(topLeft, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft)); } else { if (!initialized) { var td = new TypeDictionary() { new FactionInit(faction), new OwnerInit(queue.Actor.Owner), new HideBibPreviewInit() }; var init = new ActorPreviewInitializer(rules.Actors[building], wr, td); preview = rules.Actors[building].TraitInfos<IRenderActorPreviewInfo>() .SelectMany(rpi => rpi.RenderPreview(init)) .ToArray(); initialized = true; } var previewRenderables = preview .SelectMany(p => p.Render(wr, offset)) .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey); foreach (var r in previewRenderables) yield return r; var res = world.WorldActor.Trait<ResourceLayer>(); var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft); foreach (var t in FootprintUtils.Tiles(rules, building, buildingInfo, topLeft)) cells.Add(t, isCloseEnough && world.IsCellBuildable(t, buildingInfo) && res.GetResource(t) == null); } var pal = wr.Palette(placeBuildingInfo.Palette); var topLeftPos = world.Map.CenterOfCell(topLeft); foreach (var c in cells) { var tile = c.Value ? buildOk : buildBlocked; var pos = world.Map.CenterOfCell(c.Key); yield return new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z), -511, pal, 1f, true); } }
public ActorInitializer(Actor actor, TypeDictionary dict) { Self = actor; Dict = dict; }
public override bool Produce(Actor self, ActorInfo producee, string productionType, TypeDictionary inits) { if (IsTraitDisabled || IsTraitPaused) { return(false); } var owner = self.Owner; var exit = SelectExit(self, producee, productionType); // Start a fixed distance away: the width of the map. // This makes the production timing independent of spawnpoint var dropPos = exit != null ? self.Location + exit.Info.ExitCell : self.Location; var startPos = dropPos + new CVec(owner.World.Map.Bounds.Width, 0); var endPos = new CPos(owner.World.Map.Bounds.Left - 5, dropPos.Y); foreach (var notify in self.TraitsImplementing <INotifyDelivery>()) { notify.IncomingDelivery(self); } var info = (ProductionParadropInfo)Info; var actorType = info.ActorType; owner.World.AddFrameEndTask(w => { if (!self.IsInWorld || self.IsDead) { return; } var altitude = self.World.Map.Rules.Actors[actorType].TraitInfo <AircraftInfo>().CruiseAltitude; var actor = w.CreateActor(actorType, new TypeDictionary { new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, altitude)), new OwnerInit(owner), new FacingInit(64) }); actor.QueueActivity(new Fly(actor, Target.FromCell(w, dropPos))); actor.QueueActivity(new CallFunc(() => { if (!self.IsInWorld || self.IsDead) { return; } foreach (var cargo in self.TraitsImplementing <INotifyDelivery>()) { cargo.Delivered(self); } self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit.Info, productionType, inits)); Game.Sound.Play(SoundType.World, info.ChuteSound, self.CenterPosition); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName); })); actor.QueueActivity(new Fly(actor, Target.FromCell(w, endPos))); actor.QueueActivity(new RemoveSelf()); }); return(true); }
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.Length); } 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); } foreach (var t in newUnit.TraitsImplementing <INotifyBuildComplete>()) { t.BuildingComplete(newUnit); } }); return(true); }
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init) { init.Add(new RuntimeCargoInit(Passengers.ToArray())); }
public bool TryParseSprite(Stream s, string filename, out ISpriteFrame[] frames, out TypeDictionary metadata) { metadata = null; if (!IsShpRemastered(s)) { frames = null; return(false); } frames = new ShpRemasteredSprite(s).Frames.ToArray(); return(true); }
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); }); }
public ActorPreviewInitializer(ActorInfo actor, WorldRenderer worldRenderer, TypeDictionary dict) { Actor = actor; WorldRenderer = worldRenderer; reference = new ActorReference(actor.Name, dict); }
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 virtual void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string productionType, TypeDictionary inits) { var exit = CPos.Zero; var exitLocation = CPos.Zero; var target = Target.Invalid; // Clone the initializer dictionary for the new actor var td = new TypeDictionary(); foreach (var init in inits) { td.Add(init); } 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 => { 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, productionType); } foreach (var t in newUnit.TraitsImplementing <INotifyBuildComplete>()) { t.BuildingComplete(newUnit); } }); }
public virtual bool Produce(Actor self, ActorInfo producee, string productionType, TypeDictionary inits) { if (IsTraitDisabled || IsTraitPaused || Reservable.IsReserved(self) || (building != null && building.Locked)) { return(false); } // Pick a spawn/exit point pair var exit = SelectExit(self, producee, productionType); if (exit != null || self.OccupiesSpace == null) { DoProduction(self, producee, exit, productionType, inits); return(true); } return(false); }
public void UnitProducedByOther(Actor self, Actor producer, Actor produced, string productionType, TypeDictionary init) { // If the produced Actor doesn't occupy space, it can't be in range if (produced.OccupiesSpace == null) { return; } // We don't grant conditions when disabled if (IsTraitDisabled) { return; } // Work around for actors produced within the region not triggering until the second tick if ((produced.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= Info.Range.LengthSquared) { var stance = self.Owner.RelationshipWith(produced.Owner); if (!Info.ValidRelationships.HasRelationship(stance)) { return; } var external = produced.TraitsImplementing <ExternalCondition>() .FirstOrDefault(t => t.Info.Condition == Info.Condition && t.CanGrantCondition(produced, self)); if (external != null) { tokens[produced] = external.GrantCondition(produced, self); } } }
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; } } }
// 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)); }
internal Actor(World world, string name, TypeDictionary initDict) { var duplicateInit = initDict.WithInterface <ISingleInstanceInit>().GroupBy(i => i.GetType()) .FirstOrDefault(i => i.Count() > 1); if (duplicateInit != null) { throw new InvalidDataException("Duplicate initializer '{0}'".F(duplicateInit.Key.Name)); } var init = new ActorInitializer(this, initDict); readOnlyConditionCache = new ReadOnlyDictionary <string, int>(conditionCache); World = world; ActorID = world.NextAID(); var ownerInit = init.GetOrDefault <OwnerInit>(); if (ownerInit != null) { Owner = ownerInit.Value(world); } if (name != null) { name = name.ToLowerInvariant(); if (!world.Map.Rules.Actors.ContainsKey(name)) { throw new NotImplementedException("No rules definition for unit " + name); } Info = world.Map.Rules.Actors[name]; foreach (var trait in Info.TraitsInConstructOrder()) { AddTrait(trait.Create(init)); // Some traits rely on properties provided by IOccupySpace in their initialization, // so we must ready it now, we cannot wait until all traits have finished construction. if (trait is IOccupySpaceInfo) { OccupiesSpace = Trait <IOccupySpace>(); } } } // PERF: Cache all these traits as soon as the actor is created. This is a fairly cheap one-off cost per // actor that allows us to provide some fast implementations of commonly used methods that are relied on by // performance-sensitive parts of the core game engine, such as pathfinding, visibility and rendering. EffectiveOwner = TraitOrDefault <IEffectiveOwner>(); facing = TraitOrDefault <IFacing>(); health = TraitOrDefault <IHealth>(); renderModifiers = TraitsImplementing <IRenderModifier>().ToArray(); renders = TraitsImplementing <IRender>().ToArray(); mouseBounds = TraitsImplementing <IMouseBounds>().ToArray(); visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray(); defaultVisibility = Trait <IDefaultVisibility>(); becomingIdles = TraitsImplementing <INotifyBecomingIdle>().ToArray(); tickIdles = TraitsImplementing <INotifyIdle>().ToArray(); Targetables = TraitsImplementing <ITargetable>().ToArray(); targetablePositions = TraitsImplementing <ITargetablePositions>().ToArray(); world.AddFrameEndTask(w => { // Caching this in a AddFrameEndTask, because trait construction order might cause problems if done directly at creation time. // All actors that can move or teleport should have IPositionable, if not it's pretty safe to assume the actor is completely immobile and // all targetable positions can be cached if all ITargetablePositions have no conditional requirements. if (!Info.HasTraitInfo <IPositionableInfo>() && targetablePositions.Any() && targetablePositions.All(tp => tp.AlwaysEnabled)) { staticTargetablePositions = targetablePositions.SelectMany(tp => tp.TargetablePositions(this)).ToArray(); } }); SyncHashes = TraitsImplementing <ISync>().Select(sync => new SyncHash(sync)).ToArray(); }
public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world) { var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo); var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo); var rules = world.Map.Rules; var actorInfo = rules.Actors[building]; foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>()) { foreach (var r in dec.Render(wr, world, actorInfo, offset)) { yield return(r); } } var cells = new Dictionary <CPos, CellType>(); var plugInfo = rules.Actors[building].TraitInfoOrDefault <PlugInfo>(); if (plugInfo != null) { if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1) { throw new InvalidOperationException("Plug requires a 1x1 sized Building"); } cells.Add(topLeft, MakeCellType(AcceptsPlug(topLeft, plugInfo))); } else if (rules.Actors[building].HasTraitInfo <LineBuildInfo>()) { // Linebuild for walls. if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1) { throw new InvalidOperationException("LineBuild requires a 1x1 sized Building"); } if (!Game.GetModifierKeys().HasModifier(Modifiers.Shift)) { foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, building, buildingInfo)) { cells.Add(t.First, MakeCellType(buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, t.First), true)); } } cells[topLeft] = MakeCellType(buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft)); } else { if (!initialized) { var td = new TypeDictionary() { new FactionInit(faction), new OwnerInit(queue.Actor.Owner), new HideBibPreviewInit() }; var init = new ActorPreviewInitializer(rules.Actors[building], wr, td); preview = rules.Actors[building].TraitInfos <IRenderActorPreviewInfo>() .SelectMany(rpi => rpi.RenderPreview(init)) .ToArray(); initialized = true; } var previewRenderables = preview .SelectMany(p => p.Render(wr, offset)) .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey); foreach (var r in previewRenderables) { yield return(r); } var res = world.WorldActor.Trait <ResourceLayer>(); var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft); foreach (var t in FootprintUtils.Tiles(rules, building, buildingInfo, topLeft)) { cells.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, buildingInfo) && res.GetResource(t) == null)); } } var cellPalette = wr.Palette(placeBuildingInfo.Palette); var linePalette = wr.Palette(placeBuildingInfo.LineBuildSegmentPalette); var topLeftPos = world.Map.CenterOfCell(topLeft); foreach (var c in cells) { var tile = !c.Value.HasFlag(CellType.Invalid) ? buildOk : buildBlocked; var pal = c.Value.HasFlag(CellType.LineBuild) ? linePalette : cellPalette; var pos = world.Map.CenterOfCell(c.Key); yield return(new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z), -511, pal, 1f, true)); } }
public override void DoImpact(Target target, Actor firedBy, IEnumerable <int> damageModifiers) { if (!target.IsValidFor(firedBy)) { return; } 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(); var ai = map.Rules.Actors[a.ToLowerInvariant()]; if (Owner == null) { td.Add(new OwnerInit(firedBy.Owner)); } else { td.Add(new OwnerInit(firedBy.World.Players.First(p => p.InternalName == Owner))); } // HACK HACK HACK // Immobile does not offer a check directly if the actor can exist in a position. // It also crashes the game if it's actor's created without a LocationInit. // See AS/Engine#84. if (ai.HasTraitInfo <ImmobileInfo>()) { var immobileInfo = ai.TraitInfo <ImmobileInfo>(); while (cell.MoveNext()) { if (!immobileInfo.OccupiesSpace || !firedBy.World.ActorMap.GetActorsAt(cell.Current).Any()) { td.Add(new LocationInit(cell.Current)); var immobileunit = firedBy.World.CreateActor(false, a.ToLowerInvariant(), td); firedBy.World.AddFrameEndTask(w => { w.Add(immobileunit); var palette = Palette; if (UsePlayerPalette) { palette += immobileunit.Owner.InternalName; } var immobilespawnpos = firedBy.World.Map.CenterOfCell(cell.Current); if (Image != null) { w.Add(new SpriteEffect(immobilespawnpos, w, Image, Sequence, palette)); } var sound = Sounds.RandomOrDefault(Game.CosmeticRandom); if (sound != null) { Game.Sound.Play(SoundType.World, sound, immobilespawnpos); } }); break; } } return; } Actor unit = null; if (targetCells.Count() > 1) { 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 = !ForceGround && 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)); } var palette = Palette; if (UsePlayerPalette) { palette += unit.Owner.InternalName; } if (Image != null) { w.Add(new SpriteEffect(pos, w, Image, Sequence, palette)); } var sound = Sounds.RandomOrDefault(Game.CosmeticRandom); if (sound != null) { Game.Sound.Play(SoundType.World, sound, pos); } }); placed = true; break; } } } else { td.Add(new LocationInit(firedBy.World.Map.CellContaining(target.CenterPosition))); td.Add(new CenterPositionInit(target.CenterPosition)); unit = firedBy.World.CreateActor(false, a.ToLowerInvariant(), td); firedBy.World.AddFrameEndTask(w => { w.Add(unit); }); placed = true; } if (!placed) { unit.Dispose(); } } }
void IDeathActorInitModifier.ModifyDeathActorInit(Actor self, TypeDictionary init) { ModifyActorInit(init); }
void ITick.Tick(Actor self) { if (!IsTraitDisabled || (self.Owner.PlayerActor.TraitOrDefault <DeveloperMode>() != null && self.Owner.PlayerActor.TraitOrDefault <DeveloperMode>().FastBuild)) { if (self.IsDead) { return; } foreach (var nt in self.TraitsImplementing <INotifyTransform>()) { nt.OnTransform(self); } selected = self.World.Selection.Contains(self); controlgroup = self.World.Selection.GetControlGroupForActor(self); health = self.TraitOrDefault <Health>(); cargo = self.TraitOrDefault <Cargo>(); enabled = true; facong = info.Facing; if (info.Facing == -1) { var face = self.TraitOrDefault <IFacing>(); if (face != null && info.Facing < 0) { facong = face.Facing; } } init = new TypeDictionary { new LocationInit(self.Location + info.Offset), new OwnerInit(self.Owner), new FacingInit(facong), }; if (info.SkipMakeAnims) { init.Add(new SkipMakeAnimsInit()); } if (faction != null) { init.Add(new FactionInit(faction)); } if (health != null) { var newHP = (health.HP * 100) / health.MaxHP; init.Add(new HealthInit(newHP)); } if (cargo != null) { init.Add(new RuntimeCargoInit(cargo.Passengers.ToArray())); } Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName); self.Dispose(); } }
public bool TryParseSprite(Stream stream, string filename, out ISpriteFrame[] frames, out TypeDictionary metadata) { if (!filename.EndsWith(".mapd")) { metadata = null; frames = null; return(false); } frames = new Mapd(stream as SegmentStream).Layers.Select(layer => new MapdSpriteFrame(layer)).ToArray(); metadata = null; return(true); }
public ActorPreviewInitializer(ActorInfo actor, WorldRenderer worldRenderer, TypeDictionary dict) { Actor = actor; WorldRenderer = worldRenderer; this.dict = dict; }
private static void Main(string[] args) { Application.Run(() => { // Create spatial collection Spatial = new BoundingTreeSpatialCollection <ISpatialObject>(); // Pipes = new PipeManager(); // Create entities collection _entities = new TypeDictionary <Entity>(); _removeEntities = new HashSet <Entity>(); _addEntities = new HashSet <Entity>(); // Create the game window Window = new Window("Superfluid!"); Window.Graphics.EnableFPSOverlay = true; Window.Maximize(); // Bind Input Input.AttachToWindow(Window); // Load BGM Music = new AudioSource(Files.OpenStream("assets/music/4222-pixelland-by-kevin-macleod.mp3")); Music.IsLooping = true; Music.Play(); // Load game assets Assets.LoadDatabase(); PackImageAtlas(); // Center origins on assets prefixed by string given Assets.SetImagesCenterOrigin("crosshair102", "particle"); Assets.SetImagesCenterOrigin("alien", "slime"); // alienpink_walk1, etc // Setup the cursors var cursorImage = Assets.GetImage("crosshair102"); HealCursor = CreateImageClone(cursorImage, Color.Green); KillCursor = CreateImageClone(cursorImage, Color.Red); Window.SetCursor(KillCursor); // ... // Load the background image Background = Assets.GetImage("colored_desert"); // _elapsedTime = 0; // Create the player actor Player = AddEntity(new Player()); Player.Transform.Position = (200, 300); // Load the test map LoadMap(StageNames[StageIndex]); // Create main loop Loop = RenderLoop.Create(Window.Graphics, OnUpdate); Loop.Start(); }); }
public override void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string productionType, TypeDictionary inits) { var exit = CPos.Zero; var exitLocation = CPos.Zero; var target = Target.Invalid; var info = (ProductionParadropInfo)Info; var actorType = info.ActorType; var altitude = self.World.Map.Rules.Actors[actorType].TraitInfo <AircraftInfo>().CruiseAltitude; // Clone the initializer dictionary for the new actor var td = new TypeDictionary(); foreach (var init in inits) { td.Add(init); } if (self.OccupiesSpace != null) { exit = self.Location + exitinfo.ExitCell; var spawn = self.World.Map.CenterOfCell(exit) + new WVec(WDist.Zero, WDist.Zero, altitude); var to = self.World.Map.CenterOfCell(exit); var initialFacing = exitinfo.Facing < 0 ? (to - spawn).Yaw.Facing : exitinfo.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 => { var newUnit = self.World.CreateActor(producee.Name, td); newUnit.QueueActivity(new Parachute(newUnit, newUnit.CenterPosition, self)); 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, productionType, td); } }); }
void DoTransform(Actor self) { // This activity may be buried as a child within one or more parents // We need to consider the top-level activities when transferring orders to the new actor! var currentActivity = self.CurrentActivity; self.World.AddFrameEndTask(w => { if (self.IsDead || self.WillDispose) { 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(SoundType.World, 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), new CenterPositionInit(Altitude), }; if (SkipMakeAnims) { init.Add(new SkipMakeAnimsInit()); } if (Faction != null) { init.Add(new FactionInit(Faction)); } var health = self.TraitOrDefault <IHealth>(); if (health != null) { // Cast to long to avoid overflow when multiplying by the health var newHP = ForceHealthPercentage > 0 ? ForceHealthPercentage : (int)(health.HP * 100L / health.MaxHP); init.Add(new HealthInit(newHP)); } foreach (var modifier in self.TraitsImplementing <ITransformActorInitModifier>()) { modifier.ModifyTransformActorInit(self, init); } var a = w.CreateActor(ToActor, init); foreach (var nt in self.TraitsImplementing <INotifyTransform>()) { nt.AfterTransform(a); } // Use self.CurrentActivity to capture the parent activity if Transform is a child foreach (var transfer in currentActivity.ActivitiesImplementing <IssueOrderAfterTransform>(false)) { if (transfer.IsCanceling) { continue; } var order = transfer.IssueOrderForTransformedActor(a); foreach (var t in a.TraitsImplementing <IResolveOrder>()) { t.ResolveOrder(a, order); } } self.ReplacedByActor = a; if (selected) { w.Selection.Add(a); } if (controlgroup.HasValue) { w.Selection.AddToControlGroup(a, controlgroup.Value); } }); }
public override bool Produce(Actor self, ActorInfo producee, string factionVariant) { var aircraftInfo = producee.TraitInfoOrDefault <AircraftInfo>(); var mobileInfo = producee.TraitInfoOrDefault <MobileInfo>(); var passable = mobileInfo != null ? (uint)mobileInfo.GetMovementClass(self.World.Map.Rules.TileSet) : 0; var destination = rp != null ? rp.Location : self.Location; var location = spawnLocation; if (!location.HasValue) { if (aircraftInfo != null) { location = self.World.Map.ChooseClosestEdgeCell(self.Location); } if (mobileInfo != null) { location = self.World.Map.ChooseClosestMatchingEdgeCell(self.Location, c => mobileInfo.CanEnterCell(self.World, null, c) && domainIndex.IsPassable(c, destination, passable)); } } // No suitable spawn location could be found, so production has failed. if (!location.HasValue) { return(false); } var pos = self.World.Map.CenterOfCell(location.Value); // If aircraft, spawn at cruise altitude if (aircraftInfo != null) { pos += new WVec(0, 0, aircraftInfo.CruiseAltitude.Length); } var initialFacing = self.World.Map.FacingBetween(location.Value, destination, 0); self.World.AddFrameEndTask(w => { var td = new TypeDictionary { new OwnerInit(self.Owner), new LocationInit(location.Value), new CenterPositionInit(pos), new FacingInit(initialFacing) }; if (factionVariant != null) { td.Add(new FactionInit(factionVariant)); } var newUnit = self.World.CreateActor(producee.Name, td); var move = newUnit.TraitOrDefault <IMove>(); if (move != null) { newUnit.QueueActivity(move.MoveTo(destination, 2)); } newUnit.SetTargetLine(Target.FromCell(self.World, destination), Color.Green, false); if (!self.IsDead) { foreach (var t in self.TraitsImplementing <INotifyProduction>()) { t.UnitProduced(self, newUnit, destination); } } 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); } }); return(true); }
public Actor CreateActor(string name, TypeDictionary initDict) { return(CreateActor(true, name, initDict)); }
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); }
void INotifyKilled.Killed(Actor self, AttackInfo e) { if (IsTraitDisabled || self.Owner.WinState == WinState.Lost || !self.World.Map.Contains(self.Location)) { return; } if (self.World.SharedRandom.Next(100) >= Info.SuccessRate) { return; } var cp = self.CenterPosition; var inAir = !self.IsAtGroundLevel(); if ((inAir && !Info.EjectInAir) || (!inAir && !Info.EjectOnGround)) { return; } self.World.AddFrameEndTask(w => { if (!Info.AllowUnsuitableCell) { var pilotInfo = self.World.Map.Rules.Actors[Info.PilotActor.ToLowerInvariant()]; var pilotPositionable = pilotInfo.TraitInfo <IPositionableInfo>(); if (!pilotPositionable.CanEnterCell(self.World, null, self.Location)) { return; } } var td = new TypeDictionary { new OwnerInit(self.Owner), new LocationInit(self.Location), }; // If airborne, offset the spawn location so the pilot doesn't drop on another infantry's head var spawnPos = cp; if (inAir) { var subCell = self.World.ActorMap.FreeSubCell(self.Location); if (subCell != SubCell.Invalid) { td.Add(new SubCellInit(subCell)); spawnPos = self.World.Map.CenterOfSubCell(self.Location, subCell) + new WVec(0, 0, spawnPos.Z); } } td.Add(new CenterPositionInit(spawnPos)); var pilot = self.World.CreateActor(true, Info.PilotActor.ToLowerInvariant(), td); if (!inAir) { var pilotMobile = pilot.TraitOrDefault <Mobile>(); if (pilotMobile != null) { pilotMobile.Nudge(pilot); } } else { Game.Sound.Play(SoundType.World, Info.ChuteSound, cp); } }); }
void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) { inits.Add(new BodyAnimationFrameInit(frame)); }
public void Tick(Actor self) { if (IsTraitDisabled) { return; } timer++; alive.Remove(alive.Find(a => a.IsDead)); if (alive.Count >= info.AliveMax) { timer = 0; return; } if (info.TicksMin >= timer) { return; } if (info.TicksMax >= timer && self.World.SharedRandom.Next(0, info.Chance) != 0) { return; } self.World.AddFrameEndTask(w => { var cells = self.World.Map.FindTilesInAnnulus(self.Location, info.RadiusMin.Length, info.RadiusMax.Length) .Where(c => { if (info.CheckReachability && forbiddenCells.Contains(c)) { return(false); } return(true); }); var actor = info.Actors[self.World.SharedRandom.Next(0, info.Actors.Length)].ToLowerInvariant(); IPositionableInfo ip = null; BuildingInfo ip2 = null; IEnumerable <CPos> validCells = null; if (self.World.Map.Rules.Actors[actor].HasTraitInfo <IPositionableInfo>()) { ip = self.World.Map.Rules.Actors[actor].TraitInfo <IPositionableInfo>(); validCells = cells.Where(c => ip.CanEnterCell(self.World, null, c)); } else if (self.World.Map.Rules.Actors[actor].HasTraitInfo <BuildingInfo>()) { ip2 = self.World.Map.Rules.Actors[actor].TraitInfo <BuildingInfo>(); validCells = cells.Where(c => self.World.CanPlaceBuilding(actor, ip2, c, null)); } if (validCells != null && !validCells.Any()) { return; } var randomlocation = validCells.ElementAt(self.World.SharedRandom.Next(validCells.Count())); var facong = 0; var face = self.TraitOrDefault <IFacing>(); if (face != null) { facong = face.Facing; } var td = new TypeDictionary { new LocationInit(randomlocation), new CenterPositionInit(self.World.Map.CenterOfCell(randomlocation)), new FacingInit(facong), new OwnerInit(self.Owner), }; var Create = w.CreateActor(actor, td); alive.Add(Create); }); timer = 0; }
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init) { ModifyActorInit(init); }
public void ModifyDeathActorInit(Actor self, TypeDictionary init) { init.Add(new FacingInit(Facing)); }
/// <summary> /// Initializes a new instance of the <see cref="ContextVariableRepository"/> class. /// </summary> /// <param name="dictionary"> /// The dictionary. /// </param> public ContextVariableRepository([NotNull] TypeDictionary dictionary) { this._dic = dictionary; }
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); 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); } }); return(this); }