public TileSet(ModData modData, string filepath) { var yaml = MiniYaml.DictFromFile(filepath); // General info FieldLoader.Load(this, yaml["General"]); // TerrainTypes TerrainInfo = yaml["Terrain"].ToDictionary().Values .Select(y => new TerrainTypeInfo(y)) .OrderBy(tt => tt.Type) .ToArray(); if (TerrainInfo.Length >= byte.MaxValue) throw new InvalidDataException("Too many terrain types."); for (byte i = 0; i < TerrainInfo.Length; i++) { var tt = TerrainInfo[i].Type; if (terrainIndexByType.ContainsKey(tt)) throw new InvalidDataException("Duplicate terrain type '{0}' in '{1}'.".F(tt, filepath)); terrainIndexByType.Add(tt, i); } defaultWalkableTerrainIndex = GetTerrainIndex("Clear"); // Templates Templates = yaml["Templates"].ToDictionary().Values .Select(y => new TileTemplate(this, y)).ToDictionary(t => t.Id); }
public WidgetLoader(ModData modData) { foreach (var file in modData.Manifest.ChromeLayout.Select(a => MiniYaml.FromFile(a))) foreach( var w in file ) { var key = w.Key.Substring( w.Key.IndexOf('@') + 1); if (widgets.ContainsKey(key)) throw new InvalidDataException("Widget has duplicate Key `{0}` at {1}".F(w.Key, w.Location)); widgets.Add(key, w); } }
public TileSet(ModData modData, string filepath) { var yaml = MiniYaml.DictFromFile(filepath); // General info FieldLoader.Load(this, yaml["General"]); // TerrainTypes Terrain = yaml["Terrain"].NodesDict.Values .Select(y => new TerrainTypeInfo(y)).ToDictionary(t => t.Type); // Templates Templates = yaml["Templates"].NodesDict.Values .Select(y => new TileTemplate(y)).ToDictionary(t => t.Id); }
public MapPreview(ModData modData, string uid, MapGridType gridType, MapCache cache) { this.cache = cache; this.modData = modData; Uid = uid; innerData = new InnerData { Title = "Unknown Map", Categories = new[] { "Unknown" }, Author = "Unknown Author", TileSet = "unknown", Players = null, PlayerCount = 0, SpawnPoints = NoSpawns, GridType = gridType, Bounds = Rectangle.Empty, Preview = null, Status = MapStatus.Unavailable, Class = MapClassification.Unknown, Visibility = MapVisibility.Lobby, }; }
public WidgetLoader( ModData modData ) { foreach( var file in modData.Manifest.ChromeLayout.Select( a => MiniYaml.FromFile( a ) ) ) foreach( var w in file ) widgets.Add( w.Key.Substring( w.Key.IndexOf( '@' ) + 1 ), w ); }
public void SetRulesetGenerator(ModData modData, Func<Pair<Ruleset, bool>> generator) { InvalidCustomRules = false; RulesLoaded = false; DefinesUnsafeCustomRules = false; // Note: multiple threads may try to access the value at the same time // We rely on the thread-safety guarantees given by Lazy<T> to prevent race conitions. // If you're thinking about replacing this, then you must be careful to keep this safe. rules = Exts.Lazy(() => { if (generator == null) return Ruleset.LoadDefaultsForTileSet(modData, TileSet); try { var ret = generator(); DefinesUnsafeCustomRules = ret.Second; return ret.First; } catch (Exception e) { Log.Write("debug", "Failed to load rules for `{0}` with error :{1}", Title, e.Message); InvalidCustomRules = true; return Ruleset.LoadDefaultsForTileSet(modData, TileSet); } finally { RulesLoaded = true; } }); }
public Map(ModData modData, IReadOnlyPackage package) { this.modData = modData; Package = package; if (!Package.Contains("map.yaml") || !Package.Contains("map.bin")) throw new InvalidDataException("Not a valid map\n File: {0}".F(package.Name)); var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name)); foreach (var field in YamlFields) field.Deserialize(this, yaml.Nodes); if (MapFormat != SupportedMapFormat) throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name)); PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players"); ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors"); Grid = modData.Manifest.Get<MapGrid>(); var size = new Size(MapSize.X, MapSize.Y); Tiles = new CellLayer<TerrainTile>(Grid.Type, size); Resources = new CellLayer<ResourceTile>(Grid.Type, size); Height = new CellLayer<byte>(Grid.Type, size); using (var s = Package.GetStream("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.TilesOffset > 0) { s.Position = header.TilesOffset; for (var i = 0; i < MapSize.X; i++) { for (var j = 0; j < MapSize.Y; j++) { var tile = s.ReadUInt16(); var index = s.ReadUInt8(); // TODO: Remember to remove this when rewriting tile variants / PickAny if (index == byte.MaxValue) index = (byte)(i % 4 + (j % 4) * 4); Tiles[new MPos(i, j)] = new TerrainTile(tile, index); } } } if (header.ResourcesOffset > 0) { s.Position = header.ResourcesOffset; for (var i = 0; i < MapSize.X; i++) { for (var j = 0; j < MapSize.Y; j++) { var type = s.ReadUInt8(); var density = s.ReadUInt8(); Resources[new MPos(i, j)] = new ResourceTile(type, density); } } } if (header.HeightsOffset > 0) { s.Position = header.HeightsOffset; for (var i = 0; i < MapSize.X; i++) for (var j = 0; j < MapSize.Y; j++) Height[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight); } } if (Grid.MaximumTerrainHeight > 0) { Tiles.CellEntryChanged += UpdateProjection; Height.CellEntryChanged += UpdateProjection; } PostInit(); Uid = ComputeUID(Package); }
/// <summary> /// Initializes a new map created by the editor or importer. /// The map will not receive a valid UID until after it has been saved and reloaded. /// </summary> public Map(ModData modData, TileSet tileset, int width, int height) { this.modData = modData; var size = new Size(width, height); Grid = modData.Manifest.Get<MapGrid>(); var tileRef = new TerrainTile(tileset.Templates.First().Key, 0); Title = "Name your map here"; Author = "Your name here"; MapSize = new int2(size); Tileset = tileset.Id; // Empty rules that can be added to by the importers. // Will be dropped on save if nothing is added to it RuleDefinitions = new MiniYaml(""); Tiles = new CellLayer<TerrainTile>(Grid.Type, size); Resources = new CellLayer<ResourceTile>(Grid.Type, size); Height = new CellLayer<byte>(Grid.Type, size); if (Grid.MaximumTerrainHeight > 0) { Height.CellEntryChanged += UpdateProjection; Tiles.CellEntryChanged += UpdateProjection; } Tiles.Clear(tileRef); PostInit(); }
public Utility(ModData modData, InstalledMods mods) { ModData = modData; Mods = mods; }
internal MapChooserLogic(Widget widget, ModData modData, string initialMap, MapClassification initialTab, Action onExit, Action<string> onSelect, MapVisibility filter) { this.widget = widget; this.modData = modData; this.onSelect = onSelect; var approving = new Action(() => { Ui.CloseWindow(); onSelect(selectedUid); }); var canceling = new Action(() => { Ui.CloseWindow(); onExit(); }); var okButton = widget.Get<ButtonWidget>("BUTTON_OK"); okButton.Disabled = this.onSelect == null; okButton.OnClick = approving; widget.Get<ButtonWidget>("BUTTON_CANCEL").OnClick = canceling; gameModeDropdown = widget.GetOrNull<DropDownButtonWidget>("GAMEMODE_FILTER"); var itemTemplate = widget.Get<ScrollItemWidget>("MAP_TEMPLATE"); widget.RemoveChild(itemTemplate); var mapFilterInput = widget.GetOrNull<TextFieldWidget>("MAPFILTER_INPUT"); if (mapFilterInput != null) { mapFilterInput.TakeKeyboardFocus(); mapFilterInput.OnEscKey = () => { if (mapFilterInput.Text.Length == 0) canceling(); else { mapFilter = mapFilterInput.Text = null; EnumerateMaps(currentTab, itemTemplate); } return true; }; mapFilterInput.OnEnterKey = () => { approving(); return true; }; mapFilterInput.OnTextEdited = () => { mapFilter = mapFilterInput.Text; EnumerateMaps(currentTab, itemTemplate); }; } var randomMapButton = widget.GetOrNull<ButtonWidget>("RANDOMMAP_BUTTON"); if (randomMapButton != null) { randomMapButton.OnClick = () => { var uid = visibleMaps.Random(Game.CosmeticRandom); selectedUid = uid; scrollpanels[currentTab].ScrollToItem(uid, smooth: true); }; randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Length == 0; } var deleteMapButton = widget.Get<ButtonWidget>("DELETE_MAP_BUTTON"); deleteMapButton.IsDisabled = () => modData.MapCache[selectedUid].Class != MapClassification.User; deleteMapButton.IsVisible = () => currentTab == MapClassification.User; deleteMapButton.OnClick = () => { DeleteOneMap(selectedUid, (string newUid) => { RefreshMaps(currentTab, filter); EnumerateMaps(currentTab, itemTemplate); if (!tabMaps[currentTab].Any()) SwitchTab(modData.MapCache[newUid].Class, itemTemplate); }); }; var deleteAllMapsButton = widget.Get<ButtonWidget>("DELETE_ALL_MAPS_BUTTON"); deleteAllMapsButton.IsVisible = () => currentTab == MapClassification.User; deleteAllMapsButton.OnClick = () => { DeleteAllMaps(visibleMaps, (string newUid) => { RefreshMaps(currentTab, filter); EnumerateMaps(currentTab, itemTemplate); SwitchTab(modData.MapCache[newUid].Class, itemTemplate); }); }; SetupMapTab(MapClassification.User, filter, "USER_MAPS_TAB_BUTTON", "USER_MAPS_TAB", itemTemplate); SetupMapTab(MapClassification.System, filter, "SYSTEM_MAPS_TAB_BUTTON", "SYSTEM_MAPS_TAB", itemTemplate); if (initialMap == null && tabMaps.Keys.Contains(initialTab) && tabMaps[initialTab].Any()) { selectedUid = Game.ModData.MapCache.ChooseInitialMap(tabMaps[initialTab].Select(mp => mp.Uid).First(), Game.CosmeticRandom); currentTab = initialTab; } else { selectedUid = Game.ModData.MapCache.ChooseInitialMap(initialMap, Game.CosmeticRandom); currentTab = tabMaps.Keys.FirstOrDefault(k => tabMaps[k].Select(mp => mp.Uid).Contains(selectedUid)); } SwitchTab(currentTab, itemTemplate); }
public static void InitializeWithMods(string[] mods) { // Clear static state if we have switched mods LobbyInfoChanged = () => {}; AddChatLine = (a, b, c) => {}; ConnectionStateChanged = om => {}; BeforeGameStart = () => {}; Ui.ResetAll(); worldRenderer = null; if (server != null) { server.Shutdown(); } if (orderManager != null) { orderManager.Dispose(); } // Discard any invalid mods, set RA as default var mm = mods.Where(m => Mod.AllMods.ContainsKey(m)).ToArray(); if (mm.Length == 0) { mm = new[] { "ra" } } ; Console.WriteLine("Loading mods: {0}", mm.JoinWith(",")); Settings.Game.Mods = mm; Sound.StopMusic(); Sound.StopVideo(); Sound.Initialize(); modData = new ModData(mm); Renderer.InitializeFonts(modData.Manifest); modData.LoadInitialAssets(); PerfHistory.items["render"].hasNormalTick = false; PerfHistory.items["batches"].hasNormalTick = false; PerfHistory.items["render_widgets"].hasNormalTick = false; PerfHistory.items["render_flip"].hasNormalTick = false; JoinLocal(); viewport = new Viewport(new int2(Renderer.Resolution), Rectangle.Empty, Renderer); if (Game.Settings.Server.Dedicated) { while (true) { Game.Settings.Server.Map = WidgetUtils.ChooseInitialMap(Game.Settings.Server.Map); Game.Settings.Save(); Game.CreateServer(new ServerSettings(Game.Settings.Server)); while (true) { System.Threading.Thread.Sleep(100); if ((server.GameStarted) && (server.conns.Count <= 1)) { Console.WriteLine("No one is playing, shutting down..."); server.Shutdown(); break; } } if (Game.Settings.Server.DedicatedLoop) { Console.WriteLine("Starting a new server instance..."); continue; } else { break; } } System.Environment.Exit(0); } else { modData.LoadScreen.StartGame(); Settings.Save(); } }
public static void InitializeMod(string mod, Arguments args) { // Clear static state if we have switched mods LobbyInfoChanged = () => { }; ConnectionStateChanged = om => { }; BeforeGameStart = () => { }; OnRemoteDirectConnect = (a, b) => { }; delayedActions = new ActionQueue(); Ui.ResetAll(); if (worldRenderer != null) { worldRenderer.Dispose(); } worldRenderer = null; if (server != null) { server.Shutdown(); } if (OrderManager != null) { OrderManager.Dispose(); } if (ModData != null) { ModData.ModFiles.UnmountAll(); ModData.Dispose(); } ModData = null; if (mod == null) { throw new InvalidOperationException("Game.Mod argument missing."); } if (!Mods.ContainsKey(mod)) { throw new InvalidOperationException("Unknown or invalid mod '{0}'.".F(mod)); } Console.WriteLine("Loading mod: {0}", mod); Sound.StopVideo(); ModData = new ModData(Mods[mod], Mods, true); if (!ModData.LoadScreen.BeforeLoad()) { return; } using (new PerfTimer("LoadMaps")) ModData.MapCache.LoadMaps(); ModData.InitializeLoaders(ModData.DefaultFileSystem); Renderer.InitializeFonts(ModData); var grid = ModData.Manifest.Contains <MapGrid>() ? ModData.Manifest.Get <MapGrid>() : null; Renderer.InitializeDepthBuffer(grid); if (Cursor != null) { Cursor.Dispose(); } if (Settings.Graphics.HardwareCursors) { try { Cursor = new HardwareCursor(ModData.CursorProvider); } catch (Exception e) { Log.Write("debug", "Failed to initialize hardware cursors. Falling back to software cursors."); Log.Write("debug", "Error was: " + e.Message); Console.WriteLine("Failed to initialize hardware cursors. Falling back to software cursors."); Console.WriteLine("Error was: " + e.Message); Cursor = new SoftwareCursor(ModData.CursorProvider); } } else { Cursor = new SoftwareCursor(ModData.CursorProvider); } PerfHistory.Items["render"].HasNormalTick = false; PerfHistory.Items["batches"].HasNormalTick = false; PerfHistory.Items["render_widgets"].HasNormalTick = false; PerfHistory.Items["render_flip"].HasNormalTick = false; JoinLocal(); try { if (discoverNat != null) { discoverNat.Wait(); } } catch (Exception e) { Console.WriteLine("NAT discovery failed: {0}", e.Message); Log.Write("nat", e.ToString()); } ModData.LoadScreen.StartGame(args); }