WPos PreviewPosition(World world, ActorReference actor) { var centerPositionInit = actor.GetOrDefault <CenterPositionInit>(); if (centerPositionInit != null) { return(centerPositionInit.Value); } var locationInit = actor.GetOrDefault <LocationInit>(); if (locationInit != null) { var cell = locationInit.Value; var offset = WVec.Zero; var subCellInit = reference.GetOrDefault <SubCellInit>(); var subCell = subCellInit != null ? subCellInit.Value : SubCell.Any; var buildingInfo = Info.TraitInfoOrDefault <BuildingInfo>(); if (buildingInfo != null) { offset = buildingInfo.CenterOffset(world); } return(world.Map.CenterOfSubCell(cell, subCell) + offset); } else { throw new InvalidDataException("Actor {0} must define Location or CenterPosition".F(ID)); } }
void IUtilityCommand.Run(Utility utility, string[] args) { var modData = Game.ModData = utility.ModData; map = new Map(modData, new Folder(Platform.EngineDir).OpenPackage(args[1], modData.ModFiles)); Console.WriteLine("Resizing map {0} from {1} to {2},{3}", map.Title, map.MapSize, width, height); map.Resize(width, height); var forRemoval = new List <MiniYamlNode>(); foreach (var kv in map.ActorDefinitions) { var actor = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); var locationInit = actor.GetOrDefault <LocationInit>(); if (locationInit == null) { continue; } if (!map.Contains(locationInit.Value)) { Console.WriteLine($"Removing actor {actor.Type} located at {locationInit.Value} due being outside of the new map boundaries."); forRemoval.Add(kv); } } foreach (var kv in forRemoval) { map.ActorDefinitions.Remove(kv); } map.Save((IReadWritePackage)map.Package); }
public EditorActorPreview(WorldRenderer worldRenderer, string id, ActorReference reference, PlayerReference owner) { ID = id; this.reference = reference; Owner = owner; this.worldRenderer = worldRenderer; if (!reference.Contains <FactionInit>()) { reference.Add(new FactionInit(owner.Faction)); } if (!reference.Contains <OwnerInit>()) { reference.Add(new OwnerInit(owner.Name)); } var world = worldRenderer.World; if (!world.Map.Rules.Actors.TryGetValue(reference.Type.ToLowerInvariant(), out Info)) { throw new InvalidDataException($"Actor {id} of unknown type {reference.Type.ToLowerInvariant()}"); } CenterPosition = PreviewPosition(world, reference); var location = reference.Get <LocationInit>().Value; var ios = Info.TraitInfoOrDefault <IOccupySpaceInfo>(); var subCellInit = reference.GetOrDefault <SubCellInit>(); var subCell = subCellInit != null ? subCellInit.Value : SubCell.Any; var radarColorInfo = Info.TraitInfoOrDefault <RadarColorFromTerrainInfo>(); RadarColor = radarColorInfo == null ? owner.Color : radarColorInfo.GetColorFromTerrain(world); Footprint = ios?.OccupiedCells(Info, location, subCell) ?? new Dictionary <CPos, SubCell>() { { location, SubCell.FullCell } }; tooltip = Info.TraitInfos <EditorOnlyTooltipInfo>().FirstOrDefault(info => info.EnabledByDefault) as TooltipInfoBase ?? Info.TraitInfos <TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault); DescriptiveName = tooltip != null ? tooltip.Name : Info.Name; GeneratePreviews(); // Bounds are fixed from the initial render. // If this is a problem, then we may need to fetch the area from somewhere else var r = previews.SelectMany(p => p.ScreenBounds(worldRenderer, CenterPosition)); Bounds = r.Union(); SelectionBox = new SelectionBoxAnnotationRenderable(new WPos(CenterPosition.X, CenterPosition.Y, 8192), new Rectangle(Bounds.X, Bounds.Y, Bounds.Width, Bounds.Height), Color.White); }
public void Run(Action <string> emitError, Action <string> emitWarning, ModData modData, Map map) { var playerNames = new MapPlayers(map.PlayerDefinitions).Players.Values .Select(p => p.Name) .ToHashSet(); // Check for actors that require specific owners var actorsWithRequiredOwner = map.Rules.Actors .Where(a => a.Value.HasTraitInfo <RequiresSpecificOwnersInfo>()) .ToDictionary(a => a.Key, a => a.Value.TraitInfo <RequiresSpecificOwnersInfo>()); foreach (var kv in map.ActorDefinitions) { var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); var ownerInit = actorReference.GetOrDefault <OwnerInit>(); if (ownerInit == null) { emitError("Actor {0} is not owned by any player.".F(kv.Key)); } else { var ownerName = ownerInit.InternalName; if (!playerNames.Contains(ownerName)) { emitError("Actor {0} is owned by unknown player {1}.".F(kv.Key, ownerName)); } if (actorsWithRequiredOwner.TryGetValue(kv.Value.Value, out var info)) { if (!info.ValidOwnerNames.Contains(ownerName)) { emitError("Actor {0} owner {1} is not one of ValidOwnerNames: {2}".F(kv.Key, ownerName, info.ValidOwnerNames.JoinWith(", "))); } } } } }
public void Run(Action <string> emitError, Action <string> emitWarning, ModData modData, Map map) { var players = new MapPlayers(map.PlayerDefinitions).Players; if (players.Count > 64) { emitError("Defining more than 64 players is not allowed."); } var worldOwnerFound = false; var playerNames = players.Values.Select(p => p.Name).ToHashSet(); foreach (var player in players.Values) { foreach (var ally in player.Allies) { if (!playerNames.Contains(ally)) { emitError("Allies contains player {0} that is not in list.".F(ally)); } } foreach (var enemy in player.Enemies) { if (!playerNames.Contains(enemy)) { emitError("Enemies contains player {0} that is not in list.".F(enemy)); } } if (player.OwnsWorld) { worldOwnerFound = true; if (player.Enemies.Any() || player.Allies.Any()) { emitWarning("The player {0} owning the world should not have any allies or enemies.".F(player.Name)); } if (player.Playable) { emitError("The player {0} owning the world can't be playable.".F(player.Name)); } } else if (map.Visibility == MapVisibility.MissionSelector && player.Playable && !player.LockFaction) { // Missions must lock the faction of the player to force the server to override the default Random faction emitError("The player {0} must specify LockFaction: True.".F(player.Name)); } } if (!worldOwnerFound) { emitError("Found no player owning the world."); } var worldActor = map.Rules.Actors[SystemActors.World]; var factions = worldActor.TraitInfos <FactionInfo>().Select(f => f.InternalName).ToHashSet(); foreach (var player in players.Values) { if (!string.IsNullOrWhiteSpace(player.Faction) && !factions.Contains(player.Faction)) { emitError("Invalid faction {0} chosen for player {1}.".F(player.Faction, player.Name)); } } if (worldActor.HasTraitInfo <MapStartingLocationsInfo>()) { var playerCount = players.Count(p => p.Value.Playable); var spawns = new List <CPos>(); foreach (var kv in map.ActorDefinitions.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); spawns.Add(s.Get <LocationInit>().Value); } if (playerCount > spawns.Count) { emitError("The map allows {0} possible players, but defines only {1} spawn points".F(playerCount, spawns.Count)); } if (spawns.Distinct().Count() != spawns.Count) { emitError("Duplicate spawn point locations detected."); } } // Check for actors that require specific owners var actorsWithRequiredOwner = map.Rules.Actors .Where(a => a.Value.HasTraitInfo <RequiresSpecificOwnersInfo>()) .ToDictionary(a => a.Key, a => a.Value.TraitInfo <RequiresSpecificOwnersInfo>()); foreach (var kv in map.ActorDefinitions) { var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); var ownerInit = actorReference.GetOrDefault <OwnerInit>(); if (ownerInit == null) { emitError("Actor {0} is not owned by any player.".F(kv.Key)); } else { var ownerName = ownerInit.InternalName; if (!playerNames.Contains(ownerName)) { emitError("Actor {0} is owned by unknown player {1}.".F(kv.Key, ownerName)); } if (actorsWithRequiredOwner.TryGetValue(kv.Value.Value, out var info)) { if (!info.ValidOwnerNames.Contains(ownerName)) { emitError("Actor {0} owner {1} is not one of ValidOwnerNames: {2}".F(kv.Key, ownerName, info.ValidOwnerNames.JoinWith(", "))); } } } } }
public T GetInitOrDefault <T>(TraitInfo info) where T : ActorInit { return(reference.GetOrDefault <T>(info)); }
protected void Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = ModData = utility.ModData; var filename = args[1]; var flag = args[2]; if (string.IsNullOrWhiteSpace(flag)) { flag = "VH"; } bool flipHorizontal = flag.Contains("H"); bool flipVertical = flag.Contains("V"); MirrorType mirrorType = MirrorType.Horizontal; if (flipVertical) { mirrorType = MirrorType.Vertical; } if (flipHorizontal && flipVertical) { mirrorType = MirrorType.HorizontalAndVertical; } var targetPath = "..\\mods\\dr\\maps"; var package = new Folder(targetPath).OpenPackage(filename, ModData.ModFiles); if (package == null) { Console.WriteLine("Couldn't find map file: " + filename); return; } Map = new Map(ModData, package); var size = Map.MapSize; switch (mirrorType) { case MirrorType.Horizontal: size = size.WithX(size.X / 2); break; case MirrorType.Vertical: size = size.WithY(size.Y / 2); break; case MirrorType.HorizontalAndVertical: size = size / 2; break; } // Tiles for (int x = 0; x < size.X; x++) { for (int y = 0; y < size.Y; y++) { var pos = new CPos(x, y); var transformTile = new TileTransform() { Tile = Map.Tiles[pos], MirrorType = mirrorType, Position = pos }; foreach (var tt in transformTile.GetTransforms(Map)) { var newPos = tt.Position; Map.Tiles[newPos] = tt.Tile; } } } // Actors actorIndex = GetHighestActorIndex(); int multiCount = 0; var actorDefs = new List <ActorReference>(); var removeActors = new List <MiniYamlNode>(); foreach (var a in Map.ActorDefinitions) { var existing = new ActorReference(a.Value.Value, a.Value.ToDictionary()); var pos = existing.GetOrDefault <LocationInit>().Value; var owner = existing.Get <OwnerInit>(); if (pos.X < 0 || pos.X >= size.X || pos.Y < 0 || pos.Y >= size.Y) { removeActors.Add(a); continue; } var actor = new ActorTransform() { Actor = existing, Position = pos, MirrorType = mirrorType, }; if (actor.Actor.Type == "mpspawn") { multiCount++; } foreach (var at in actor.GetTransforms(Map)) { var ar = new ActorReference(actor.Actor.Type) { new LocationInit(at.Position), owner }; actorDefs.Add(ar); if (at.Actor.Type == "mpspawn") { multiCount++; } } } foreach (var a in actorDefs) { Map.ActorDefinitions.Add(new MiniYamlNode("Actor" + ++actorIndex, a.Save())); } foreach (var a in removeActors) { Map.ActorDefinitions.Remove(a); } if (multiCount > 0) { var mapPlayers = new MapPlayers(Map.Rules, multiCount); Map.PlayerDefinitions = mapPlayers.ToMiniYaml(); } // Resources for (int x = 0; x < size.X; x++) { for (int y = 0; y < size.Y; y++) { var pos = new CPos(x, y); var resource = new ResourceTransform() { Tile = Map.Resources[pos], MirrorType = mirrorType, Position = pos }; foreach (var rt in resource.GetTransforms(Map)) { var newPos = rt.Position; Map.Resources[newPos] = rt.Tile; } } } var dest = Path.Combine(targetPath, Path.GetFileNameWithoutExtension(filename) + ".oramap"); Map.Save(ZipFileLoader.Create(dest)); Console.WriteLine(dest + " saved."); }