protected override void AddCellsToPlayerShroud(Actor self, Player p, PPos[] uv) { if (!info.ValidStances.HasStance(p.Stances[self.Owner])) return; p.Shroud.AddSource(this, Shroud.SourceType.Shroud, uv); }
public Smoke(World world, PPos pos, string trail) { this.pos = pos; anim = new Animation(trail); anim.PlayThen("idle", () => world.AddFrameEndTask(w => w.Remove(this))); }
public Missile(MissileInfo info, ProjectileArgs args) { Info = info; Args = args; SubPxPosition = Args.src.ToPSubPos(); Altitude = Args.srcAltitude; Facing = Args.facing; if (info.Inaccuracy > 0) offset = (PVecInt)(info.Inaccuracy * args.firedBy.World.SharedRandom.Gauss2D(2)).ToInt2(); if (Info.Image != null) { anim = new Animation(Info.Image, () => Facing); anim.PlayRepeating("idle"); } if (Info.ContrailLength > 0) { Trail = new ContrailHistory(Info.ContrailLength, Info.ContrailUsePlayerColor ? ContrailHistory.ChooseColor(args.firedBy) : Info.ContrailColor, Info.ContrailDelay); } TargetLocation = args.target.CenterLocation; }
public Leap(Actor self, Target target) { this.target = target; initialLocation = (PPos) self.Trait<Mobile>().PxPosition; self.Trait<RenderInfantry>().Attacking(self, target); Sound.Play("dogg5p.aud", self.CenterLocation); }
public IEnumerable<Actor> ActorsInBox(PPos a, PPos b) { var r = Rectangle.FromLTRB(a.X, a.Y, b.X, b.Y); return ActorsInBins(a.X / scale, b.X / scale, a.Y / scale, b.Y / scale) .Distinct() .Where(u => u.IsInWorld && u.ExtendedBounds.Value.IntersectsWith(r)); }
public Explosion(World world, PPos pixelPos, string style, bool isWater, int altitude) { this.pos = pixelPos; this.altitude = altitude; anim = new Animation("explosion"); anim.PlayThen(style, () => world.AddFrameEndTask(w => w.Remove(this))); }
public void ApplyOrders(World world, PPos xy, MouseInput mi) { if (world.OrderGenerator == null) return; var orders = world.OrderGenerator.Order(world, xy.ToCPos(), mi).ToArray(); orders.Do(o => world.IssueOrder(o)); world.PlayVoiceForOrders(orders); }
public HarvesterDockSequence(Actor self, Actor proc) { this.proc = proc; state = State.Turn; harv = self.Trait<Harvester>(); ru = self.Trait<RenderUnit>(); startDock = self.Trait<IHasLocation>().PxPosition; endDock = proc.Trait<IHasLocation>().PxPosition + new PVecInt(-15,8); }
public CashTick(string value, int lifetime, int velocity, PPos pos, Color color) { this.color = color; this.velocity = velocity; this.pos = pos; s = value; font = Game.Renderer.Fonts["TinyBold"]; offset = 0.5f*font.Measure(s).ToFloat2(); remaining = lifetime; }
public Parachute(Actor cargo, PPos location, int altitude) { this.location = location; this.altitude = altitude; this.cargo = cargo; var pai = cargo.Info.Traits.GetOrDefault<ParachuteAttachmentInfo>(); paraAnim = new Animation(pai != null ? pai.ParachuteSprite : "parach"); paraAnim.PlayThen("open", () => paraAnim.PlayRepeating("idle")); if (pai != null) offset = pai.Offset; cargo.Trait<ITeleportable>().SetPxPosition(cargo, location); }
public IEnumerable<Renderable> GenerateRenderables(WorldRenderer wr) { var bright = SequenceProvider.GetSequence(Info.Image, "bright"); var dim = SequenceProvider.GetSequence(Info.Image, "dim"); var src = new PPos(Args.src.X, Args.src.Y - Args.srcAltitude); var dest = new PPos(Args.dest.X, Args.dest.Y - Args.destAltitude); for (var n = 0; n < Info.DimZaps; n++) foreach (var z in DrawZapWandering(wr, src, dest, dim)) yield return z; for (var n = 0; n < Info.BrightZaps; n++) foreach (var z in DrawZapWandering(wr, src, dest, bright)) yield return z; }
public FrozenActor(Actor self, PPos[] footprint, Shroud shroud) { actor = self; this.shroud = shroud; // Consider all cells inside the map area (ignoring the current map bounds) Footprint = footprint .Where(m => shroud.Contains(m)) .ToArray(); CenterPosition = self.CenterPosition; Bounds = self.Bounds; UpdateVisibility(); }
public NukeLaunch(Player firedBy, Actor silo, string weapon, PVecInt spawnOffset, CPos targetLocation) { this.firedBy = firedBy; this.targetLocation = targetLocation; this.weapon = weapon; anim = new Animation(weapon); anim.PlayRepeating("up"); if (silo == null) { altitude = firedBy.World.Map.Bounds.Height*Game.CellSize; StartDescent(firedBy.World); } else pos = silo.CenterLocation + spawnOffset; }
public FrozenActor(Actor self, PPos[] footprint, Shroud shroud, bool startsRevealed) { actor = self; this.shroud = shroud; NeedRenderables = startsRevealed; removeFrozenActors = self.TraitsImplementing<IRemoveFrozenActor>().ToArray(); // Consider all cells inside the map area (ignoring the current map bounds) Footprint = footprint .Where(m => shroud.Contains(m)) .ToArray(); CenterPosition = self.CenterPosition; Bounds = self.Bounds; TargetTypes = self.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes).ToHashSet(); UpdateVisibility(); }
public void Tick(Actor self) { if (--ticks <= 0) { var move = self.Trait<IMove>(); if (move.Altitude > 0 && self.GetDamageState() >= DamageState.Heavy) { var facing = self.Trait<IFacing>(); var altitude = new PVecInt(0, move.Altitude); position = (self.CenterLocation - (PVecInt)Combat.GetTurretPosition(self, facing, smokeTurret).ToInt2()); if (self.World.RenderedShroud.IsVisible(position.ToCPos())) self.World.AddFrameEndTask( w => w.Add(new Smoke(w, position - altitude, "smokey"))); } ticks = interval; } }
public IEnumerable<Renderable> Render(WorldRenderer wr) { if (explosion != null) yield return new Renderable(explosion.Image, args.dest.ToFloat2() - .5f * explosion.Image.size, wr.Palette("effect"), (int)args.dest.Y); if (ticks >= info.BeamDuration) yield break; var rc = Color.FromArgb((info.BeamDuration - ticks)*255/info.BeamDuration, color); var src = new PPos(args.src.X, args.src.Y - args.srcAltitude); var dest = new PPos(args.dest.X, args.dest.Y - args.destAltitude); var wlr = Game.Renderer.WorldLineRenderer; wlr.LineWidth = info.BeamRadius * 2; wlr.DrawLine(src.ToFloat2(), dest.ToFloat2(), rc, rc); wlr.Flush(); wlr.LineWidth = 1f; }
public static void DoExplosion(Actor attacker, string weapontype, PPos pos, int altitude) { var args = new ProjectileArgs { src = pos, dest = pos, srcAltitude = altitude, destAltitude = altitude, firedBy = attacker, target = Target.FromPos(pos), weapon = Rules.Weapons[ weapontype.ToLowerInvariant() ], facing = 0 }; if (args.weapon.Report != null) Sound.Play(args.weapon.Report + ".aud", pos); DoImpacts(args); }
public void AddProjectedVisibility(Actor a, PPos[] visible) { if (!a.Owner.IsAlliedWith(self.Owner)) return; foreach (var puv in visible) { // Force cells outside the visible bounds invisible if (!map.Contains(puv)) continue; var uv = (MPos)puv; visibleCount[uv]++; explored[uv] = true; } if (visibility.ContainsKey(a)) throw new InvalidOperationException("Attempting to add duplicate actor visibility"); visibility[a] = visible; Invalidate(visible); }
public Parachute(Player owner, PPos location, int altitude, Actor cargo) { this.location = location; this.altitude = altitude; this.cargo = cargo; var rs = cargo.Trait<RenderSimple>(); var image = rs.anim.Name; palette = rs.Palette(owner); anim = new Animation(image); if (anim.HasSequence("idle")) anim.PlayFetchIndex("idle", () => 0); else anim.PlayFetchIndex("stand", () => 0); anim.Tick(); var pai = cargo.Info.Traits.GetOrDefault<ParachuteAttachmentInfo>(); paraAnim = new Animation(pai != null ? pai.ParachuteSprite : "parach"); paraAnim.PlayThen("open", () => paraAnim.PlayRepeating("idle")); if (pai != null) offset = pai.Offset; }
public static IEnumerable <Actor> FindAliveCombatantActorsInBox(this World world, PPos a, PPos b) { return(world.FindUnits(a, b).Where(u => u.IsInWorld && u != world.WorldActor && !u.IsDead() && !u.Owner.NonCombatant)); }
IEnumerable<Actor> SelectActorsInBox(World world, PPos a, PPos b, Func<Actor, bool> cond) { return world.FindUnits(a, b) .Where(x => x.HasTrait<Selectable>() && x.Trait<Selectable>().Info.Selectable && !world.FogObscures(x) && cond(x)) .GroupBy(x => x.GetSelectionPriority()) .OrderByDescending(g => g.Key) .Select(g => g.AsEnumerable()) .DefaultIfEmpty(NoActors) .FirstOrDefault(); }
void Initialize(string mapFile) { mapSize = new Size(stream.ReadUInt16(), stream.ReadUInt16()); tileSet = rules.TileSets["ARRAKIS"]; map = new Map(tileSet, mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth) { Title = Path.GetFileNameWithoutExtension(mapFile), Author = "Westwood Studios" }; var tl = new PPos(MapCordonWidth, MapCordonWidth); var br = new PPos(MapCordonWidth + mapSize.Width - 1, MapCordonWidth + mapSize.Height - 1); map.SetBounds(tl, br); // Get all templates from the tileset YAML file that have at least one frame and an Image property corresponding to the requested tileset // Each frame is a tile from the Dune 2000 tileset files, with the Frame ID being the index of the tile in the original file tileSetsFromYaml = tileSet.Templates.Where(t => t.Value.Frames != null && t.Value.Images[0].ToLower() == tilesetName.ToLower()).Select(ts => ts.Value).ToList(); }
public static Fly ToPx( PPos px ) { return new Fly( px ); }
public CashTick(int value, int lifetime, int velocity, PPos pos, Color color) : this(FormatCashAmount(value), lifetime, velocity, pos, color) { }
public static Fly ToPx(PPos px) { return(new Fly(px)); }
public static bool AreaSecuredWithUnits(World world, Player player, PPos location, int range) { var units = world.FindAliveCombatantActorsInCircle(location, range).Where(a => a.HasTrait<IMove>()); return units.Any() && units.All(a => a.Owner == player); }
public HeliFly(PPos dest) { Dest = dest; }
enum IniMapFormat { RedAlert = 3 } // otherwise, cnc (2 variants exist, we don't care to differentiate) public void ConvertIniMap(string iniFile) { using (var stream = Game.ModData.ModFiles.Open(iniFile)) { var file = new IniFile(stream); var basic = file.GetSection("Basic"); var mapSection = file.GetSection("Map"); var legacyMapFormat = (IniMapFormat)Exts.ParseIntegerInvariant(basic.GetValue("NewINIFormat", "0")); var offsetX = Exts.ParseIntegerInvariant(mapSection.GetValue("X", "0")); var offsetY = Exts.ParseIntegerInvariant(mapSection.GetValue("Y", "0")); var width = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0")); var height = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0")); mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64; var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8); map = new Map(rules.TileSets[tileset], mapSize, mapSize) { Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)), Author = "Westwood Studios" }; var tl = new PPos(offsetX, offsetY); var br = new PPos(offsetX + width - 1, offsetY + height - 1); map.SetBounds(tl, br); if (legacyMapFormat == IniMapFormat.RedAlert) { UnpackRATileData(ReadPackedSection(file.GetSection("MapPack"))); UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack"))); ReadRATrees(file); } else { // CnC using (var s = Game.ModData.ModFiles.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin")) UnpackCncTileData(s); ReadCncOverlay(file); ReadCncTrees(file); } LoadVideos(file, "BASIC"); LoadActors(file, "STRUCTURES"); LoadActors(file, "UNITS"); LoadActors(file, "INFANTRY"); LoadActors(file, "SHIPS"); LoadSmudges(file, "SMUDGE"); var wps = file.GetSection("Waypoints") .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0) .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key), LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize))); // Add waypoint actors foreach (var kv in wps) { if (kv.First <= 7) { var ar = new ActorReference("mpspawn") { new LocationInit((CPos)kv.Second), new OwnerInit("Neutral") }; map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save())); } else { var ar = new ActorReference("waypoint") { new LocationInit((CPos)kv.Second), new OwnerInit("Neutral") }; map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save())); } } // Create default player definitions only if there are no players to import mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.SpawnPoints.Value.Length : 0); foreach (var p in players) { LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert); } map.PlayerDefinitions = mapPlayers.ToMiniYaml(); } }
public NewMapLogic(Action onExit, Action <string> onSelect, Widget widget, World world, ModData modData) { panel = widget; panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; var tilesetDropDown = panel.Get <DropDownButtonWidget>("TILESET"); var tilesets = modData.DefaultTileSets.Select(t => t.Key).ToList(); Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => tilesetDropDown.Text == option, () => { tilesetDropDown.Text = option; }); item.Get <LabelWidget>("LABEL").GetText = () => option; return(item); }; tilesetDropDown.Text = tilesets.First(); tilesetDropDown.OnClick = () => tilesetDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, tilesets, setupItem); var widthTextField = panel.Get <TextFieldWidget>("WIDTH"); var heightTextField = panel.Get <TextFieldWidget>("HEIGHT"); panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () => { int.TryParse(widthTextField.Text, out var width); int.TryParse(heightTextField.Text, out var height); // Require at least a 2x2 playable area so that the // ground is visible through the edge shroud width = Math.Max(2, width); height = Math.Max(2, height); var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight; var tileset = modData.DefaultTileSets[tilesetDropDown.Text]; var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2); var tl = new PPos(1, 1 + maxTerrainHeight); var br = new PPos(width, height + maxTerrainHeight); map.SetBounds(tl, br); map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml(); map.FixOpenAreas(); Action <string> afterSave = uid => { // HACK: Work around a synced-code change check. // It's not clear why this is needed here, but not in the other places that load maps. Game.RunAfterTick(() => { ConnectionLogic.Connect(Game.CreateLocalServer(uid), "", () => Game.LoadEditor(uid), () => { Game.CloseServer(); onExit(); }); }); Ui.CloseWindow(); onSelect(uid); }; Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs() { { "onSave", afterSave }, { "onExit", () => { Ui.CloseWindow(); onExit(); } }, { "map", map }, { "playerDefinitions", map.PlayerDefinitions }, { "actorDefinitions", map.ActorDefinitions } }); }; }
public static IEnumerable <Actor> FindAliveNonCombatantActorsInCircle(this World world, PPos location, int range) { return(world.FindUnitsInCircle(location, Game.CellSize * range) .Where(a => a.IsInWorld && a != world.WorldActor && !a.IsDead() && a.Owner.NonCombatant)); }
public bool Contains(PPos uv) { // Check that uv is inside the map area. There is nothing special // about explored here: any of the CellLayers would have been suitable. return(explored.Contains((MPos)uv)); }
public static bool IsInRange(PPos attackOrigin, float range, PPos targetLocation) { var rsq = range * range * Game.CellSize * Game.CellSize; return((attackOrigin - targetLocation).LengthSquared <= rsq); }
public NewMapWithTileSelectionLogic(Action onExit, Action <string> onSelect, Widget widget, World world, ModData modData) { panel = widget; panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; var tileDropDown = panel.Get <DropDownButtonWidget>("TILE"); var tileset = modData.DefaultTerrainInfo.First().Value; var terrainInfo = world.Map.Rules.TerrainInfo as ITemplatedTerrainInfo; var clearTiles = terrainInfo.Templates.Where(t => ((CustomTerrainTemplateInfo)t.Value).ClearTile) .Select(t => (Type: t.Value.Id, Description: terrainInfo.TerrainTypes[terrainInfo.GetTerrainInfo(new TerrainTile(t.Key, 0)).TerrainType].Type)); Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => tileDropDown.Text == option, () => { tileDropDown.Text = option; }); item.Get <LabelWidget>("LABEL").GetText = () => option; return(item); }; tileDropDown.Text = clearTiles.First().Description; var options = clearTiles.Select(t => t.Description); tileDropDown.OnClick = () => tileDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, options, setupItem); var widthTextField = panel.Get <TextFieldWidget>("WIDTH"); var heightTextField = panel.Get <TextFieldWidget>("HEIGHT"); panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () => { int.TryParse(widthTextField.Text, out int width); int.TryParse(heightTextField.Text, out int height); // Require at least a 2x2 playable area so that the // ground is visible through the edge shroud width = Math.Max(2, width); height = Math.Max(2, height); var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight; var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2); var tl = new PPos(1, 1 + maxTerrainHeight); var br = new PPos(width, height + maxTerrainHeight); map.SetBounds(tl, br); var type = clearTiles.First(c => c.Description == tileDropDown.Text).Type; for (var j = map.Bounds.Top; j < map.Bounds.Bottom; j++) { for (var i = map.Bounds.Left; i < map.Bounds.Right; i++) { var template = terrainInfo.Templates[type]; map.Tiles[new MPos(i, j)] = new TerrainTile(type, 0); } } map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml(); if (map.Rules.TerrainInfo is ITerrainInfoNotifyMapCreated notifyMapCreated) { notifyMapCreated.MapCreated(map); } Action <string> afterSave = uid => { // HACK: Work around a synced-code change check. // It's not clear why this is needed here, but not in the other places that load maps. Game.RunAfterTick(() => { ConnectionLogic.Connect(Game.CreateLocalServer(uid), "", () => Game.LoadEditor(uid), () => { Game.CloseServer(); onExit(); }); }); Ui.CloseWindow(); onSelect(uid); }; Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs() { { "onSave", afterSave }, { "onExit", () => { Ui.CloseWindow(); onExit(); } }, { "map", map }, { "playerDefinitions", map.PlayerDefinitions }, { "actorDefinitions", map.ActorDefinitions } }); }; }
public static IEnumerable<Actor> ClosestPlayerUnits(World world, Player player, PPos location, int range) { return world.FindAliveCombatantActorsInCircle(location, range) .Where(a => a.Owner == player && a.HasTrait<IMove>()) .OrderBy(a => (location - a.CenterLocation).LengthSquared); }
public NewMapLogic(Action onExit, Action <string> onSelect, Widget widget, World world, ModData modData) { panel = widget; panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; var tilesetDropDown = panel.Get <DropDownButtonWidget>("TILESET"); var tilesets = modData.DefaultTerrainInfo.Keys; Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => tilesetDropDown.Text == option, () => { tilesetDropDown.Text = option; }); item.Get <LabelWidget>("LABEL").GetText = () => option; return(item); }; tilesetDropDown.Text = tilesets.First(); tilesetDropDown.OnClick = () => tilesetDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, tilesets, setupItem); var widthTextField = panel.Get <TextFieldWidget>("WIDTH"); var heightTextField = panel.Get <TextFieldWidget>("HEIGHT"); panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () => { int.TryParse(widthTextField.Text, out var width); int.TryParse(heightTextField.Text, out var height); // Require at least a 2x2 playable area so that the // ground is visible through the edge shroud width = Math.Max(2, width); height = Math.Max(2, height); var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight; var tileset = modData.DefaultTerrainInfo[tilesetDropDown.Text]; var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2); var tl = new PPos(1, 1 + maxTerrainHeight); var br = new PPos(width, height + maxTerrainHeight); map.SetBounds(tl, br); map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml(); if (map.Rules.TerrainInfo is ITerrainInfoNotifyMapCreated notifyMapCreated) { notifyMapCreated.MapCreated(map); } Action <string> afterSave = uid => { Game.LoadEditor(uid); Ui.CloseWindow(); onSelect(uid); }; Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs() { { "onSave", afterSave }, { "onExit", () => { Ui.CloseWindow(); onExit(); } }, { "map", map }, { "playerDefinitions", map.PlayerDefinitions }, { "actorDefinitions", map.ActorDefinitions } }); }; }
public static IEnumerable<Actor> FindAliveNonCombatantActorsInCircle(this World world, PPos location, int range) { return world.FindUnitsInCircle(location, Game.CellSize * range) .Where(u => u.IsInWorld && u != world.WorldActor && !u.IsDead() && u.Owner.NonCombatant); }
void Calculate(Actor self) { if (dest == null || Reservable.IsReserved(dest)) { dest = ChooseAirfield(self, true); } if (dest == null) { return; } var plane = self.Trait <Plane>(); var res = dest.TraitOrDefault <Reservable>(); if (res != null) { plane.UnReserve(); plane.reservation = res.Reserve(dest, self, plane); } var landPos = dest.CenterLocation; var aircraft = self.Trait <Aircraft>(); var speed = .2f * aircraft.MovementSpeed; /* if the aircraft is on the ground, it will take off to the cruise altitude first before approaching */ var altitude = aircraft.Altitude; if (altitude == 0) { altitude = self.Info.Traits.Get <PlaneInfo>().CruiseAltitude; } var approachStart = landPos.ToInt2() - new float2(altitude * speed, 0); var turnRadius = (128f / self.Info.Traits.Get <AircraftInfo>().ROT) * speed / (float)Math.PI; /* work out the center points */ var fwd = -float2.FromAngle(aircraft.Facing / 128f * (float)Math.PI); var side = new float2(-fwd.Y, fwd.X); /* rotate */ var sideTowardBase = new[] { side, -side } .OrderBy(a => float2.Dot(a, self.CenterLocation.ToInt2() - approachStart)) .First(); var c1 = self.CenterLocation.ToInt2() + turnRadius * sideTowardBase; var c2 = approachStart + new float2(0, turnRadius * Math.Sign(self.CenterLocation.Y - approachStart.Y)); // above or below start point /* work out tangent points */ var d = c2 - c1; var e = (turnRadius / d.Length) * d; var f = new float2(-e.Y, e.X); /* rotate */ /* TODO: support internal tangents, too! */ if (f.X > 0) { f = -f; } w1 = (PPos)(c1 + f).ToInt2(); w2 = (PPos)(c2 + f).ToInt2(); w3 = (PPos)(approachStart).ToInt2(); plane.RTBPathHash = (PVecInt)w1 + (PVecInt)w2 + (PVecInt)w3; isCalculated = true; }
public override bool HandleMouseInput(MouseInput mi) { var xy = Game.viewport.ViewToWorldPx(mi); if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { if (!TakeFocus(mi)) { return(false); } dragStart = dragEnd = xy; ApplyOrders(world, xy, mi); } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move) { dragEnd = xy; } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { if (world.OrderGenerator is UnitOrderGenerator) { if (mi.MultiTapCount == 2) { var unit = SelectActorsInBox(world, xy, xy, _ => true).FirstOrDefault(); var visibleWorld = Game.viewport.ViewBounds(world); var topLeft = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Left, visibleWorld.Top)); var bottomRight = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Right, visibleWorld.Bottom)); var newSelection = SelectActorsInBox(world, topLeft, bottomRight, a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner); world.Selection.Combine(world, newSelection, true, false); } else { var newSelection = SelectActorsInBox(world, dragStart, xy, _ => true); world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); } } dragStart = dragEnd = xy; LoseFocus(mi); } if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move) { dragStart = dragEnd = xy; } if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down) { if (SelectionBox == null) /* don't issue orders while selecting */ { ApplyOrders(world, xy, mi); } } return(true); }
Edges GetEdges(PPos puv, Func <PPos, bool> isVisible) { if (!isVisible(puv)) { return(notVisibleSides); } var cell = ((MPos)puv).ToCPos(map); // If a side is shrouded then we also count the corners. var edge = Edges.None; if (!isVisible((PPos)(cell + new CVec(0, -1)).ToMPos(map))) { edge |= Edges.Top; } if (!isVisible((PPos)(cell + new CVec(1, 0)).ToMPos(map))) { edge |= Edges.Right; } if (!isVisible((PPos)(cell + new CVec(0, 1)).ToMPos(map))) { edge |= Edges.Bottom; } if (!isVisible((PPos)(cell + new CVec(-1, 0)).ToMPos(map))) { edge |= Edges.Left; } if (!info.ShroudOnMapBorders) { var mpos = cell.ToMPos(map); if (edge == Edges.Top && mpos.V <= 1) { edge = Edges.None; } if (edge == Edges.Left && mpos.U <= 1) { edge = Edges.None; } if (edge == Edges.Bottom && mpos.V >= map.Tiles.Size.Height - 2) { edge = Edges.None; } if (edge == Edges.Right && mpos.U >= map.Tiles.Size.Width - 2) { edge = Edges.None; } if (edge == Edges.TopLeft && mpos.V <= 1 && mpos.U <= 1) { edge = Edges.None; } if (edge == Edges.TopRight && mpos.V <= 1 && mpos.U >= map.Tiles.Size.Width - 2) { edge = Edges.None; } if (edge == Edges.BottomLeft && mpos.V >= map.Tiles.Size.Height - 2 && mpos.U <= 1) { edge = Edges.None; } if (edge == Edges.BottomRight && mpos.V >= map.Tiles.Size.Height - 2 && mpos.U >= map.Tiles.Size.Width - 2) { edge = Edges.None; } } return(edge); }
public MoveSecondHalf(Move move, PPos from, PPos to, int fromFacing, int toFacing, int startingFraction) : base(move, from, to, fromFacing, toFacing, startingFraction) { }
Fly(PPos px) { Pos = px; }
public void SetWallPointerType(PPos ppos) { wallPointerType = ppos; }
public void LocatePathPointer(PPos pathPosition, Vector2 direction) { gameObject.transform.localPosition = direction; }
public void SetPxPosition(Actor self, PPos px) { SetPosition(self, px.ToCPos()); }
public static IEnumerable <Actor> ClosestPlayerBuildings(World world, Player player, PPos location, int range) { return(world.FindAliveCombatantActorsInCircle(location, range) .Where(a => a.Owner == player && a.HasTrait <Building>() && !a.HasTrait <Wall>()) .OrderBy(a => (location - a.CenterLocation).LengthSquared)); }
public override bool HandleMouseInput(MouseInput mi) { var xy = Game.viewport.ViewToWorldPx(mi); var UseClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle; var HasBox = (SelectionBox != null) ? true : false; var MultiClick = (mi.MultiTapCount >= 2) ? true : false; if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { if (!TakeFocus(mi)) return false; dragStart = dragEnd = xy; //place buildings if (!UseClassicMouseStyle || (UseClassicMouseStyle && !world.Selection.Actors.Any()) ) ApplyOrders(world, xy, mi); } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move) dragEnd = xy; if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { if (UseClassicMouseStyle && Focused) { //order units around if (!HasBox && world.Selection.Actors.Any() && !MultiClick) { ApplyOrders(world, xy, mi); LoseFocus(mi); return true; } } if (world.OrderGenerator is UnitOrderGenerator) { if (MultiClick) { var unit = SelectActorsInBox(world, xy, xy, _ => true).FirstOrDefault(); var visibleWorld = Game.viewport.ViewBounds(world); var topLeft = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Left, visibleWorld.Top)); var bottomRight = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Right, visibleWorld.Bottom)); var newSelection2= SelectActorsInBox(world, topLeft, bottomRight, a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner); world.Selection.Combine(world, newSelection2, true, false); } else { var newSelection = SelectActorsInBox(world, dragStart, xy, _ => true); world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); } } dragStart = dragEnd = xy; LoseFocus(mi); } if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move) dragStart = dragEnd = xy; if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down) { if (UseClassicMouseStyle) world.Selection.Clear(); if (!HasBox) // don't issue orders while selecting ApplyOrders(world, xy, mi); } return true; }
public static Actor ClosestPlayerBuilding(World world, Player player, PPos location, int range) { return(ClosestPlayerBuildings(world, player, location, range).FirstOrDefault()); }
public override bool HandleMouseInput(MouseInput mi) { var xy = Game.viewport.ViewToWorldPx(mi); var UseClassicMouseStyle = Game.Settings.Game.UseClassicMouseStyle; var HasBox = (SelectionBox != null) ? true : false; var MultiClick = (mi.MultiTapCount >= 2) ? true : false; if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { if (!TakeFocus(mi)) { return(false); } dragStart = dragEnd = xy; //place buildings if (!UseClassicMouseStyle || (UseClassicMouseStyle && !world.Selection.Actors.Any())) { ApplyOrders(world, xy, mi); } } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Move) { dragEnd = xy; } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { if (UseClassicMouseStyle && Focused) { //order units around if (!HasBox && world.Selection.Actors.Any() && !MultiClick) { ApplyOrders(world, xy, mi); LoseFocus(mi); return(true); } } if (world.OrderGenerator is UnitOrderGenerator) { if (MultiClick) { var unit = SelectActorsInBox(world, xy, xy, _ => true).FirstOrDefault(); var visibleWorld = Game.viewport.ViewBounds(world); var topLeft = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Left, visibleWorld.Top)); var bottomRight = Game.viewport.ViewToWorldPx(new int2(visibleWorld.Right, visibleWorld.Bottom)); var newSelection2 = SelectActorsInBox(world, topLeft, bottomRight, a => unit != null && a.Info.Name == unit.Info.Name && a.Owner == unit.Owner); world.Selection.Combine(world, newSelection2, true, false); } else { var newSelection = SelectActorsInBox(world, dragStart, xy, _ => true); world.Selection.Combine(world, newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); } } dragStart = dragEnd = xy; LoseFocus(mi); } if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move) { dragStart = dragEnd = xy; } if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down) { if (UseClassicMouseStyle) { world.Selection.Clear(); } if (!HasBox) // don't issue orders while selecting { ApplyOrders(world, xy, mi); } } return(true); }
public static bool AreaSecuredWithUnits(World world, Player player, PPos location, int range) { var units = world.FindAliveCombatantActorsInCircle(location, range).Where(a => a.HasTrait <IMove>()); return(units.Any() && units.All(a => a.Owner == player)); }
enum IniMapFormat { RedAlert = 3 } // otherwise, cnc (2 variants exist, we don't care to differentiate) public void ConvertIniMap(string iniFile) { using (var stream = GlobalFileSystem.Open(iniFile)) { var file = new IniFile(stream); var basic = file.GetSection("Basic"); var mapSection = file.GetSection("Map"); var legacyMapFormat = (IniMapFormat)Exts.ParseIntegerInvariant(basic.GetValue("NewINIFormat", "0")); var offsetX = Exts.ParseIntegerInvariant(mapSection.GetValue("X", "0")); var offsetY = Exts.ParseIntegerInvariant(mapSection.GetValue("Y", "0")); var width = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0")); var height = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0")); mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64; var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8); map = new Map(rules.TileSets[tileset], mapSize, mapSize) { Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)), Author = "Westwood Studios" }; var tl = new PPos(offsetX, offsetY); var br = new PPos(offsetX + width - 1, offsetY + height - 1); map.SetBounds(tl, br); if (legacyMapFormat == IniMapFormat.RedAlert) { UnpackRATileData(ReadPackedSection(file.GetSection("MapPack"))); UnpackRAOverlayData(ReadPackedSection(file.GetSection("OverlayPack"))); ReadRATrees(file); } else { // CnC using (var s = GlobalFileSystem.Open(iniFile.Substring(0, iniFile.Length - 4) + ".bin")) UnpackCncTileData(s); ReadCncOverlay(file); ReadCncTrees(file); } LoadVideos(file, "BASIC"); LoadActors(file, "STRUCTURES"); LoadActors(file, "UNITS"); LoadActors(file, "INFANTRY"); LoadActors(file, "SHIPS"); LoadSmudges(file, "SMUDGE"); var wps = file.GetSection("Waypoints") .Where(kv => Exts.ParseIntegerInvariant(kv.Value) > 0) .Select(kv => Pair.New(Exts.ParseIntegerInvariant(kv.Key), LocationFromMapOffset(Exts.ParseIntegerInvariant(kv.Value), mapSize))); // Add waypoint actors foreach (var kv in wps) { if (kv.First <= 7) { var ar = new ActorReference("mpspawn") { new LocationInit((CPos)kv.Second), new OwnerInit("Neutral") }; map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save())); } else { var ar = new ActorReference("waypoint") { new LocationInit((CPos)kv.Second), new OwnerInit("Neutral") }; map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save())); } } // Create default player definitions only if there are no players to import mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.SpawnPoints.Value.Length : 0); foreach (var p in players) LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert); map.PlayerDefinitions = mapPlayers.ToMiniYaml(); } }
public void AdjustPxPosition(Actor self, PPos px) /* visual hack only */ { PxPosition = px; }
public static Actor ClosestPlayerUnit(World world, Player player, PPos location, int range) { return ClosestPlayerUnits(world, player, location, range).FirstOrDefault(); }
public void SetPxPosition(Actor self, PPos px) { SubPxPosition = px.ToPSubPos(); }
public static IEnumerable<Actor> FindAliveCombatantActorsInBox(this World world, PPos a, PPos b) { return world.FindUnits(a, b).Where(u => u.IsInWorld && u != world.WorldActor && !u.IsDead() && !u.Owner.NonCombatant); }
public void AdjustPxPosition(Actor self, PPos px) { SetPxPosition(self, px); }
public static Target FromPos(PPos p) { return(new Target { pos = p, valid = true }); }
void StartDescent(World world) { pos = OpenRA.Traits.Util.CenterOfCell(targetLocation); anim.PlayRepeating("down"); goingUp = false; }