static long CalculateActorSelectionPriority(ActorInfo info, Rectangle bounds, int2 selectionPixel) { var centerPixel = new int2(bounds.X, bounds.Y); var pixelDistance = (centerPixel - selectionPixel).Length; return ((long)-pixelDistance << 32) + info.SelectionPriority(); }
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { var occupied = OccupiesSpace ? new Dictionary<CPos, SubCell>() { { location, SubCell.FullCell } } : new Dictionary<CPos, SubCell>(); return new ReadOnlyDictionary<CPos, SubCell>(occupied); }
public static ActorTemplate RenderActor(ActorInfo info, TileSet tileset, Palette p) { var ri = info.Traits.Get<RenderSimpleInfo>(); string image = null; if (ri.OverrideTheater != null) for (int i = 0; i < ri.OverrideTheater.Length; i++) if (ri.OverrideTheater[i] == tileset.Id) image = ri.OverrideImage[i]; image = image ?? ri.Image ?? info.Name; using (var s = FileSystem.OpenWithExts(image, tileset.Extensions)) { var shp = new ShpReader(s); var bitmap = RenderShp(shp, p); try { using (var s2 = FileSystem.OpenWithExts(image + "2", tileset.Extensions)) { var shp2 = new ShpReader(s2); var roofBitmap = RenderShp(shp2, p); using (var g = System.Drawing.Graphics.FromImage(bitmap)) g.DrawImage(roofBitmap, 0, 0); } } catch { } return new ActorTemplate { Bitmap = bitmap, Info = info, Centered = !info.Traits.Contains<BuildingInfo>() }; } }
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 IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { var jamsMissiles = ai.TraitInfoOrDefault<JamsMissilesInfo>(); if (jamsMissiles != null) { yield return new RangeCircleRenderable( centerPosition, jamsMissiles.Range, 0, Color.FromArgb(128, Color.Red), Color.FromArgb(96, Color.Black)); } var jamsRadar = ai.TraitInfoOrDefault<JamsRadarInfo>(); if (jamsRadar != null) { yield return new RangeCircleRenderable( centerPosition, jamsRadar.Range, 0, Color.FromArgb(128, Color.Blue), Color.FromArgb(96, Color.Black)); } foreach (var a in w.ActorsWithTrait<RenderJammerCircle>()) if (a.Actor.Owner.IsAlliedWith(w.RenderPlayer)) foreach (var r in a.Trait.RenderAfterWorld(wr)) yield return r; }
public static ActorTemplate RenderActor(ActorInfo info, TileSet tileset, Palette p) { var image = RenderSimple.GetImage(info, tileset.Id); using (var s = FileSystem.OpenWithExts(image, tileset.Extensions)) { var shp = new ShpReader(s); var bitmap = RenderShp(shp, p); try { using (var s2 = FileSystem.OpenWithExts(image + "2", tileset.Extensions)) { var shp2 = new ShpReader(s2); var roofBitmap = RenderShp(shp2, p); using (var g = System.Drawing.Graphics.FromImage(bitmap)) g.DrawImage(roofBitmap, 0, 0); } } catch { } return new ActorTemplate { Bitmap = bitmap, Info = info, Appearance = info.Traits.GetOrDefault<EditorAppearanceInfo>() }; } }
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 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); }); }
// TODO: This can be removed after the legacy and redundant 0% = not targetable // assumption has been removed from the yaml definitions public override bool CanTargetActor(ActorInfo victim, Actor firedBy) { var health = victim.Traits.GetOrDefault<HealthInfo>(); if (health == null) return false; return DamageVersus(victim) > 0; }
public override IEnumerable<IRenderable> RenderPreview(World world, ActorInfo building, PaletteReference pr) { var p = BaseBuildingPreview(world, building, pr); var anim = new Animation(world, RenderSprites.GetImage(building), () => 0); anim.PlayRepeating("idle-top"); return p.Concat(anim.Render(WPos.Zero, WVec.Zero, 0, pr, Scale)); }
public int CreateActor(ActorInfo info, ActorConfig config, OnFinish finish) { //int id = PlayScript.Instance.director.entityManager.CreateID(); int id = director.entityManager.CreateID(); Actor actor = new Actor(info, config, id, director); return id; }
public static string GetImage(ActorInfo actor, string Tileset) { var Info = actor.Traits.Get<RenderSimpleInfo>(); if (Info.OverrideTileset != null && Tileset != null) for (int i = 0; i < Info.OverrideTileset.Length; i++) if (Info.OverrideTileset[i] == Tileset) return Info.OverrideImage[i]; return Info.Image ?? actor.Name; }
public ProductionItem(ProductionQueue queue, string item, int cost, PowerManager pm, Action onComplete) { Item = item; RemainingTime = TotalTime = 1; RemainingCost = TotalCost = cost; OnComplete = onComplete; Queue = queue; this.pm = pm; ai = Queue.Actor.World.Map.Rules.Actors[Item]; bi = ai.TraitInfo<BuildableInfo>(); }
public string GetImage(ActorInfo actor, SequenceProvider sequenceProvider, string faction) { if (FactionImages != null && !string.IsNullOrEmpty(faction)) { string factionImage = null; if (FactionImages.TryGetValue(faction, out factionImage) && sequenceProvider.HasSequence(factionImage)) return factionImage; } return (Image ?? actor.Name).ToLowerInvariant(); }
bool ValidActor(ActorInfo a, IEnumerable<CPos> cells) { foreach (var c in cells) { var mi = a.TraitInfoOrDefault<MobileInfo>(); if (mi != null && mi.CanEnterCell(self.World, self, c)) return true; } return false; }
public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { wr.DrawRangeCircleWithContrast( Color.FromArgb(128, Color.Cyan), wr.ScreenPxPosition(centerPosition), ai.Traits.Get<CreatesShroudInfo>().Range, Color.FromArgb(96, Color.Black)); foreach (var a in w.ActorsWithTrait<RenderShroudCircle>()) if (a.Actor.Owner == a.Actor.World.LocalPlayer) a.Trait.RenderAfterWorld(wr); }
public int DamageVersus(ActorInfo victim) { var armor = victim.Traits.GetOrDefault<ArmorInfo>(); if (armor != null && armor.Type != null) { int versus; if (Versus.TryGetValue(armor.Type, out versus)) return versus; } return 100; }
public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { wr.DrawRangeCircleWithContrast( Color.FromArgb(128, Color.Yellow), wr.ScreenPxPosition(centerPosition), ai.Traits.WithInterface<ArmamentInfo>() .Select(a => Rules.Weapons[a.Weapon.ToLowerInvariant()].Range).Max(), Color.FromArgb(96, Color.Black)); foreach (var a in w.ActorsWithTrait<RenderRangeCircle>()) if (a.Actor.Owner == a.Actor.World.LocalPlayer) if (a.Actor.Info.Traits.Get<RenderRangeCircleInfo>().RangeCircleType == RangeCircleType) a.Trait.RenderAfterWorld(wr); }
public override bool Produce(Actor self, ActorInfo producee, string factionVariant) { var owner = self.Owner; var aircraftInfo = self.World.Map.Rules.Actors[info.ActorType].TraitInfo<AircraftInfo>(); // WDist required to take off or land var landDistance = aircraftInfo.CruiseAltitude.Length * 1024 / aircraftInfo.MaximumPitch.Tan(); // Start a fixed distance away: the width of the map. // This makes the production timing independent of spawnpoint var startPos = self.Location + new CVec(owner.World.Map.Bounds.Width, 0); var endPos = new CPos(owner.World.Map.Bounds.Left - 2 * landDistance / 1024, self.Location.Y); // Assume a single exit point for simplicity var exit = self.Info.TraitInfos<ExitInfo>().First(); foreach (var tower in self.TraitsImplementing<INotifyDelivery>()) tower.IncomingDelivery(self); owner.World.AddFrameEndTask(w => { if (!self.IsInWorld || self.IsDead) return; var actor = w.CreateActor(info.ActorType, new TypeDictionary { new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, aircraftInfo.CruiseAltitude)), new OwnerInit(owner), new FacingInit(64) }); actor.QueueActivity(new Fly(actor, Target.FromPos(self.CenterPosition + new WVec(landDistance, 0, 0)))); actor.QueueActivity(new Land(actor, Target.FromActor(self))); 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, factionVariant)); 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 owner = self.Owner; // Start a fixed distance away: the width of the map. // This makes the production timing independent of spawnpoint var startPos = self.Location + new CVec(owner.World.Map.Bounds.Width, 0); var endPos = new CPos(owner.World.Map.Bounds.Left - 5, self.Location.Y); // Assume a single exit point for simplicity var exit = self.Info.Traits.WithInterface<ExitInfo>().First(); foreach (var tower in self.TraitsImplementing<INotifyDelivery>()) tower.IncomingDelivery(self); var info = (ProductionAirdropInfo)Info; var actorType = info.ActorType; owner.World.AddFrameEndTask(w => { if (!self.IsInWorld || self.IsDead) return; var altitude = self.World.Map.Rules.Actors[actorType].Traits.Get<PlaneInfo>().CruiseAltitude; var actor = w.CreateActor(actorType, new TypeDictionary { new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WRange.Zero, WRange.Zero, altitude)), new OwnerInit(owner), new FacingInit(64) }); actor.QueueActivity(new Fly(actor, Target.FromCell(w, self.Location + new CVec(9, 0)))); actor.QueueActivity(new Land(actor, Target.FromActor(self))); 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, raceVariant)); Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Country.Race); })); 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.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 IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { yield return new RangeCircleRenderable( centerPosition, ai.TraitInfo<CreatesShroudInfo>().Range, 0, Color.FromArgb(128, Color.Cyan), Color.FromArgb(96, Color.Black)); foreach (var a in w.ActorsWithTrait<RenderShroudCircle>()) if (a.Actor.Owner.IsAlliedWith(w.RenderPlayer)) foreach (var r in a.Trait.RenderAfterWorld(wr)) yield return r; }
public void Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { var jamsMissiles = ai.Traits.GetOrDefault<JamsMissilesInfo>(); if (jamsMissiles != null) RenderJammerCircle.DrawRangeCircle(wr, centerPosition, jamsMissiles.Range, Color.Red); var jamsRadar = ai.Traits.GetOrDefault<JamsRadarInfo>(); if (jamsRadar != null) RenderJammerCircle.DrawRangeCircle(wr, centerPosition, jamsRadar.Range, Color.Blue); foreach (var a in w.ActorsWithTrait<RenderJammerCircle>()) if (a.Actor.Owner == a.Actor.World.LocalPlayer) a.Trait.RenderAfterWorld(wr); }
public IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { yield return new RangeCircleRenderable( centerPosition, Range, 0, Color, Color.FromArgb(96, Color.Black)); foreach (var a in w.ActorsWithTrait<WithRangeCircle>()) if (a.Actor.Owner.IsAlliedWith(w.RenderPlayer) && a.Trait.Info.Type == Type) foreach (var r in a.Trait.RenderAfterWorld(wr)) yield return r; }
public static ActorTemplate RenderActor(ActorInfo info, SequenceProvider sequenceProvider, TileSet tileset, IPalette p, string race) { var image = info.Traits.Get<ILegacyEditorRenderInfo>().EditorImage(info, sequenceProvider, race); image = ResolveFilename(image, tileset); using (var s = GlobalFileSystem.Open(image)) { var shp = new ShpTDSprite(s); var bitmap = RenderShp(shp, p); return new ActorTemplate { Bitmap = bitmap, Info = info, Appearance = info.Traits.GetOrDefault<EditorAppearanceInfo>() }; } }
public Actor( World world, string name, int2 location, Player owner ) { World = world; ActorID = world.NextAID(); Location = location; CenterLocation = Traits.Util.CenterOfCell(Location); Owner = owner; if (name != null) { Info = Rules.Info[name.ToLowerInvariant()]; Health = this.GetMaxHP(); foreach (var trait in Info.TraitsInConstructOrder()) traits.Add(trait.Create(this)); } }
// Prepare sth. public void DirectorPrepare(OnFinish onfinish) { for (int i = 0; i < director.lstRD.Count; ++i) { RoleData rd = director.lstRD[i]; ActorConfig config = new ActorConfig(); ActorInfo info = new ActorInfo(); director.helper.CreateActor(info, config, delegate(bool finish) { }); } director.helper.CreateCamera(); }
public override bool Produce( Actor self, ActorInfo producee ) { var owner = self.Owner; // Start a fixed distance away: the width of the map. // This makes the production timing independent of spawnpoint var startPos = self.Location + new CVec(owner.World.Map.Bounds.Width, 0); var endPos = new CPos(owner.World.Map.Bounds.Left - 5, self.Location.Y); // Assume a single exit point for simplicity var exit = self.Info.Traits.WithInterface<ExitInfo>().First(); var rb = self.Trait<RenderBuilding>(); rb.PlayCustomAnimRepeating(self, "active"); var actorType = (Info as ProductionAirdropInfo).ActorType; owner.World.AddFrameEndTask(w => { var a = w.CreateActor(actorType, new TypeDictionary { new LocationInit( startPos ), new OwnerInit( owner ), new FacingInit( 64 ), new AltitudeInit( Rules.Info[actorType].Traits.Get<PlaneInfo>().CruiseAltitude ), }); a.QueueActivity(Fly.ToCell(self.Location + new CVec(6, 0))); a.QueueActivity(new Land(Target.FromActor(self))); a.QueueActivity(new CallFunc(() => { if (!self.IsInWorld || self.IsDead()) return; rb.PlayCustomAnimRepeating(self, "idle"); self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit)); Sound.PlayToPlayer(self.Owner, (Info as ProductionAirdropInfo).ReadyAudio); })); a.QueueActivity(Fly.ToCell(endPos)); a.QueueActivity(new RemoveSelf()); }); return true; }
private int[] LoadActors(List<RoleData> rds, OnFinish finish) { List<int> roleIds = new List<int>(); for (int i = 0; i < rds.Count; ++i) { RoleData role = rds[i]; ActorInfo actorInfo = new ActorInfo(); /* actorInfo.hp = role.maxBlood; // set current max blood actorInfo.hp = role.blood; //actorInfo.stiffValue = role.stiffValue; actorInfo.campType = role.camp; actorInfo.localIndex = role.localIndex; actorInfo.monsterPackageIndex = role.monsterPackageIndex; actorInfo.unitType = role.unitType; actorInfo.des = role.des; actorInfo.teamId = role.teamId; actorInfo.battleInfo = role.battleInfo; actorInfo.beGoodStatus = role.beGoodStatus; actorInfo.handleInfos = role.handleInfos; actorInfo.skillInfos = role.skillInfos; actorInfo.lookDistance = role.lookDistance; //actorInfo.badStateInfos = role.badStsteInfo; // buffer actorInfo.skillWeight = role.skillWeight; actorInfo.targetPos = format[role.localIndex].pos; actorInfo.startAngle = format[role.localIndex].angle; ActorConfig actorConfig = new ActorConfig(); actorConfig.assetName = role.asset; int actorID = CompetitionManager.Instance.world.CreateActor(actorInfo, actorConfig, format[role.localIndex].pos, Quaternion.Euler(0, format[role.localIndex].angle, 0), role.ReadConfig, delegate(bool isLoad) { if (--remain <= 0) onFinish(true); }); roleIds.Add(actorID); */ } return roleIds.ToArray(); }
void CheckVoices(ActorInfo actorInfo, Action<string> emitError, Ruleset rules, string voiceSet) { var soundInfo = rules.Voices[voiceSet.ToLowerInvariant()]; foreach (var traitInfo in actorInfo.TraitInfos<ITraitInfo>()) { var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute<VoiceReferenceAttribute>()); foreach (var field in fields) { var voices = LintExts.GetFieldValues(traitInfo, field, emitError); foreach (var voice in voices) { if (string.IsNullOrEmpty(voice)) continue; if (!soundInfo.Voices.Keys.Contains(voice)) emitError("Actor {0} using voice set {1} does not define {2} voice required by {3}.".F(actorInfo.Name, voiceSet, voice, traitInfo)); } } } }
public static string GetImage(ActorInfo actor) { var Info = actor.Traits.Get <RenderSimpleInfo>(); return(Info.Image ?? actor.Name); }
IEnumerable <object> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { yield return(new FacingInit(PreviewFacing)); }
public void UpdateVisual(ActorInfo info) { RegisterInfo(info); UpdateVisual(); }
bool ICustomMovementLayer.EnabledForActor(ActorInfo a, MobileInfo mi) { return(mi.Jumpjet); }
IEnumerable <ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { yield return(new TurretFacingInit(this, InitialFacing)); }
public IReadOnlyDictionary <CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return(new ReadOnlyDictionary <CPos, SubCell>()); }
public static string GetImage(ActorInfo actor) { var Info = actor.Traits.Get <RenderSpritesInfo>(); return((Info.Image ?? actor.Name).ToLowerInvariant()); }
public static int SelectionPriority(this ActorInfo a, Modifiers modifiers) { var selectableInfo = a.TraitInfoOrDefault <ISelectableInfo>(); return(selectableInfo != null?BaseSelectionPriority(selectableInfo, modifiers) : int.MinValue); }
public bool IsValidTarget(ActorInfo actorInfo, Actor saboteur) { return(false); } // TODO: bridges don't support frozen under fog
public static IEnumerable <(CPos Cell, Actor Actor)> GetLineBuildCells(World world, CPos cell, ActorInfo ai, BuildingInfo bi, Player owner) { var lbi = ai.TraitInfo <LineBuildInfo>(); var topLeft = cell; // 1x1 assumption! if (world.IsCellBuildable(topLeft, ai, bi)) { yield return(topLeft, null); } // Start at place location, search outwards // TODO: First make it work, then make it nice var vecs = new[] { new CVec(1, 0), new CVec(0, 1), new CVec(-1, 0), new CVec(0, -1) }; int[] dirs = { 0, 0, 0, 0 }; Actor[] connectors = { null, null, null, null }; for (var d = 0; d < 4; d++) { for (var i = 1; i < lbi.Range; i++) { if (dirs[d] != 0) { continue; } var segmentInfo = ai; var segmentBuildingInfo = bi; if (!string.IsNullOrEmpty(lbi.SegmentType)) { segmentInfo = world.Map.Rules.Actors[lbi.SegmentType]; segmentBuildingInfo = segmentInfo.TraitInfo <BuildingInfo>(); } // Continue the search if the cell is empty or not visible var c = topLeft + i * vecs[d]; if (world.IsCellBuildable(c, segmentInfo, segmentBuildingInfo) || !owner.Shroud.IsExplored(c)) { continue; } // Cell contains an actor. Is it the type we want? connectors[d] = world.ActorMap.GetActorsAt(c) .FirstOrDefault(a => a.Info.TraitInfos <LineBuildNodeInfo>() .Any(info => info.Types.Overlaps(lbi.NodeTypes) && info.Connections.Contains(vecs[d]))); dirs[d] = connectors[d] != null ? i : -1; } // Place intermediate-line sections if (dirs[d] > 0) { for (var i = 1; i < dirs[d]; i++) { yield return(topLeft + i * vecs[d], connectors[d]); } } } }
static long CalculateActorSelectionPriority(ActorInfo info, in Polygon bounds, int2 selectionPixel, Modifiers modifiers)
public static bool IsCellBuildable(this World world, CPos cell, ActorInfo ai, BuildingInfo bi, Actor toIgnore = null) { if (!world.Map.Contains(cell)) { return(false); } if (!bi.AllowInvalidPlacement) { // Replaceable actors are rare, so avoid initializing state unless we have to var checkReplacements = ai != null && ai.HasTraitInfo <ReplacementInfo>(); HashSet <string> acceptedReplacements = null; var foundActors = false; foreach (var a in world.ActorMap.GetActorsAt(cell)) { if (a == toIgnore) { continue; } // If this is potentially a replacement actor we must check *all* cell occupants // before we know the placement is invalid // Otherwise, we can bail immediately if (!checkReplacements) { return(false); } foundActors = true; foreach (var r in a.TraitsImplementing <Replaceable>()) { if (r.IsTraitDisabled) { continue; } if (acceptedReplacements == null) { acceptedReplacements = new HashSet <string>(); } acceptedReplacements.UnionWith(r.Info.Types); } } // Replacements are enabled and the cell contained at least one (not ignored) actor or building bib var foundBuilding = world.WorldActor.Trait <BuildingInfluence>().AnyBuildingAt(cell); if (foundActors || foundBuilding) { // The cell contains at least one actor, and none were replaceable if (acceptedReplacements == null) { return(false); } // The cell contains at least one replaceable actor, but not of the types we accept var foundReplacement = ai.TraitInfos <ReplacementInfo>() .Any(r => r.ReplaceableTypes.Overlaps(acceptedReplacements)); if (!foundReplacement) { return(false); } } } else { // HACK: To preserve legacy behaviour, AllowInvalidPlacement should display red placement indicators // if (and only if) there is a building or bib in the cell if (world.WorldActor.Trait <BuildingInfluence>().AnyBuildingAt(cell)) { return(false); } } // Buildings can never be placed on ramps return(world.Map.Ramp[cell] == 0 && bi.TerrainTypes.Contains(world.Map.GetTerrainInfo(cell).Type)); }
public IEnumerable <IRenderable> RenderAnnotations(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition) { if (!RequiresBaseProvider) { return(SpriteRenderable.None); } return(w.ActorsWithTrait <BaseProvider>().SelectMany(a => a.Trait.RangeCircleRenderables(wr))); }
int ICustomMovementLayer.ExitMovementCost(ActorInfo a, MobileInfo mi, CPos cell) { return(ValidTransitionCell(cell, mi) ? mi.JumpjetTransitionCost : int.MaxValue); }
void IMapPreviewSignatureInfo.PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos, Color)> destinationBuffer)
protected virtual ExitInfo SelectExit(Actor self, ActorInfo producee, string productionType, Func <ExitInfo, bool> p) { return(self.RandomExitOrDefault(productionType, p)); }
public bool IsValidTarget(ActorInfo actorInfo, Actor saboteur) { return(true); }
int ICustomMovementLayer.EntryMovementCost(ActorInfo a, LocomotorInfo li, CPos cell) { return(ends.Contains(cell) ? 0 : int.MaxValue); }
Type[] FilterActorCommands(ActorInfo ai) { return(FilterCommands(ai, knownActorCommands)); }
IEnumerable <string> ITechTreePrerequisiteInfo.Prerequisites(ActorInfo info) { return(Prerequisites); }
IEnumerable <ActorInit> IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { yield return(new HideBibPreviewInit()); }
bool HasSufficientPowerForActor(ActorInfo actorInfo) { return((actorInfo.TraitInfos <PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1) .Sum(p => p.Amount) + playerPower.ExcessPower) >= ai.Info.MinimumExcessPower); }
public int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) { return(0); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) { WeaponInfos = Weapons.Select(w => rules.Weapons[w.ToLowerInvariant()]).ToArray(); }
bool ICustomMovementLayer.EnabledForActor(ActorInfo a, LocomotorInfo li) { return(enabled); }
public int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race) { return(0); }
public void SetUp() { allUnits = new Dictionary <string, MiniYaml>(); actorInfo = new ActorInfo("", new MiniYaml(""), allUnits); }
public static string GetInitialFaction(ActorInfo ai, string defaultFaction) { return(ai.TraitInfoOrDefault <BuildableInfo>()?.ForceFaction ?? defaultFaction); }
protected ExitInfo SelectExit(Actor self, ActorInfo producee, string productionType) { return(SelectExit(self, producee, productionType, e => CanUseExit(self, producee, e))); }
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Player player, Func <ProductionIcon> getTooltipIcon) { var world = player.World; var mapRules = world.Map.Rules; var pm = player.PlayerActor.Trait <PowerManager>(); var pr = player.PlayerActor.Trait <PlayerResources>(); widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Actor != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY"); var requiresLabel = widget.Get <LabelWidget>("REQUIRES"); var powerLabel = widget.Get <LabelWidget>("POWER"); var powerIcon = widget.Get <ImageWidget>("POWER_ICON"); var timeLabel = widget.Get <LabelWidget>("TIME"); var timeIcon = widget.Get <ImageWidget>("TIME_ICON"); var costLabel = widget.Get <LabelWidget>("COST"); var costIcon = widget.Get <ImageWidget>("COST_ICON"); var descLabel = widget.Get <LabelWidget>("DESC"); var iconMargin = timeIcon.Bounds.X; var font = Game.Renderer.Fonts[nameLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var requiresFont = Game.Renderer.Fonts[requiresLabel.Font]; var formatBuildTime = new CachedTransform <int, string>(time => WidgetUtils.FormatTime(time, world.Timestep)); var requiresFormat = requiresLabel.Text; ActorInfo lastActor = null; Hotkey lastHotkey = Hotkey.Invalid; var lastPowerState = pm.PowerState; tooltipContainer.BeforeRender = () => { var tooltipIcon = getTooltipIcon(); if (tooltipIcon == null) { return; } var actor = tooltipIcon.Actor; if (actor == null) { return; } var hotkey = tooltipIcon.Hotkey != null?tooltipIcon.Hotkey.GetValue() : Hotkey.Invalid; if (actor == lastActor && hotkey == lastHotkey && pm.PowerState == lastPowerState) { return; } var tooltip = actor.TraitInfos <TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault); var name = tooltip != null ? tooltip.Name : actor.Name; var buildable = actor.TraitInfo <BuildableInfo>(); var cost = actor.TraitInfo <ValuedInfo>().Cost; nameLabel.Text = name; var nameSize = font.Measure(name); var hotkeyWidth = 0; hotkeyLabel.Visible = hotkey.IsValid(); if (hotkeyLabel.Visible) { var hotkeyText = "({0})".F(hotkey.DisplayString()); hotkeyWidth = font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X; hotkeyLabel.Text = hotkeyText; hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X; } var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)).Where(s => !s.StartsWith("~", StringComparison.Ordinal)); requiresLabel.Text = prereqs.Any() ? requiresFormat.F(prereqs.JoinWith(", ")) : ""; var requiresSize = requiresFont.Measure(requiresLabel.Text); var power = actor.TraitInfos <PowerInfo>().Where(i => i.EnabledByDefault).Sum(i => i.Amount); powerLabel.Text = power.ToString(); powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0) ? Color.White : Color.Red; powerLabel.Visible = power != 0; powerIcon.Visible = power != 0; var powerSize = font.Measure(powerLabel.Text); var buildTime = tooltipIcon.ProductionQueue == null ? 0 : tooltipIcon.ProductionQueue.GetBuildTime(actor, buildable); var timeMultiplier = pm.PowerState != PowerState.Normal ? tooltipIcon.ProductionQueue.Info.LowPowerSlowdown : 1; timeLabel.Text = formatBuildTime.Update(buildTime * timeMultiplier); timeLabel.TextColor = pm.PowerState != PowerState.Normal ? Color.Red : Color.White; var timeSize = font.Measure(timeLabel.Text); costLabel.IsVisible = () => cost != 0; costIcon.IsVisible = () => cost != 0; costLabel.Text = cost.ToString(); costLabel.GetColor = () => pr.Cash + pr.Resources >= cost ? Color.White : Color.Red; var costSize = font.Measure(costLabel.Text); descLabel.Text = buildable.Description.Replace("\\n", "\n"); var descSize = descFont.Measure(descLabel.Text); var leftWidth = new[] { nameSize.X + hotkeyWidth, requiresSize.X, descSize.X }.Aggregate(Math.Max); var rightWidth = new[] { powerSize.X, timeSize.X, costSize.X }.Aggregate(Math.Max); timeIcon.Bounds.X = powerIcon.Bounds.X = costIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X; timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin; widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin; var leftHeight = nameSize.Y + requiresSize.Y + descSize.Y; var rightHeight = powerSize.Y + timeSize.Y + costSize.Y; widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y; lastActor = actor; lastHotkey = hotkey; lastPowerState = pm.PowerState; }; }