public BuildingInfluence(World world) { map = world.Map; influence = new CellLayer<Actor>(map); world.ActorAdded += a => { var b = a.Info.TraitInfoOrDefault<BuildingInfo>(); if (b == null) return; foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b, a.Location)) if (influence.Contains(u) && influence[u] == null) influence[u] = a; }; world.ActorRemoved += a => { var b = a.Info.TraitInfoOrDefault<BuildingInfo>(); if (b == null) return; foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b, a.Location)) if (influence.Contains(u) && influence[u] == a) influence[u] = null; }; }
public void WorldLoaded(World w, WorldRenderer wr) { bridges = new CellLayer<Bridge>(w.Map); // Build a list of templates that should be overlayed with bridges foreach (var bridge in info.Bridges) { var bi = w.Map.Rules.Actors[bridge].Traits.Get<BridgeInfo>(); foreach (var template in bi.Templates) bridgeTypes.Add(template.First, Pair.New(bridge, template.Second)); } // Loop through the map looking for templates to overlay for (var i = w.Map.Bounds.Left; i < w.Map.Bounds.Right; i++) { for (var j = w.Map.Bounds.Top; j < w.Map.Bounds.Bottom; j++) { var cell = new CPos(i, j); if (bridgeTypes.ContainsKey(w.Map.MapTiles.Value[cell].Type)) ConvertBridgeToActor(w, cell); } } // Link adjacent (long)-bridges so that artwork is updated correctly foreach (var b in w.Actors.SelectMany(a => a.TraitsImplementing<Bridge>())) b.LinkNeighbouringBridges(w, this); }
public void Dispose() { if (Layer == null) return; layerPool.ReturnLayer(Layer); Layer = null; layerPool = null; }
public CellInfoLayerPool(Map map) { defaultLayer = CellLayer<CellInfo>.CreateInstance( mpos => new CellInfo(int.MaxValue, int.MaxValue, mpos.ToCPos(map), CellStatus.Unvisited), new Size(map.MapSize.X, map.MapSize.Y), map.Grid.Type); }
public Shroud(Actor self) { this.self = self; map = self.World.Map; visibleCount = new CellLayer<short>(map); generatedShroudCount = new CellLayer<short>(map); explored = new CellLayer<bool>(map); }
public ResourceLayer(Actor self) { world = self.World; buildingInfluence = self.Trait <BuildingInfluence>(); Content = new CellLayer <CellContents>(world.Map); RenderContent = new CellLayer <CellContents>(world.Map); // этот метод обновл¤ет TerrainSpriteLayer, через данное событие. //RenderContent.CellEntryChanged += SubmitCellToVertexBuffer; }
public PathGraph(CellInfoLayerPool layerPool, MobileInfo mobileInfo, Actor actor, World world, bool checkForBlocked) { pooledLayer = layerPool.Get(); cellInfo = pooledLayer.Layer; World = world; this.mobileInfo = mobileInfo; worldMovementInfo = mobileInfo.GetWorldMovementInfo(world); Actor = actor; LaneBias = 1; checkConditions = checkForBlocked ? CellConditions.TransientActors : CellConditions.None; }
public ResourceLayer(Actor self, ResourceLayerInfo info) { this.info = info; world = self.World; Map = world.Map; BuildingInfluence = self.Trait <BuildingInfluence>(); Content = new CellLayer <ResourceLayerContents>(Map); ResourceTypesByIndex = info.ResourceTypes.ToDictionary( kv => kv.Value.ResourceIndex, kv => kv.Key); }
public ResourceLayer(Actor self) { world = self.World; buildingInfluence = self.Trait <BuildingInfluence>(); Content = new CellLayer <CellContents>(world.Map); RenderContent = new CellLayer <CellContents>(world.Map); RenderContent.CellEntryChanged += UpdateSpriteLayers; }
public ShroudRenderer(World world, ShroudRendererInfo info) { if (info.ShroudVariants.Length != info.FogVariants.Length) throw new ArgumentException("ShroudRenderer must define the same number of shroud and fog variants!", "info"); if ((info.OverrideFullFog == null) ^ (info.OverrideFullShroud == null)) throw new ArgumentException("ShroudRenderer cannot define overrides for only one of shroud or fog!", "info"); if (info.ShroudVariants.Length > byte.MaxValue) throw new ArgumentException("ShroudRenderer cannot define this many shroud and fog variants.", "info"); if (info.Index.Length >= byte.MaxValue) throw new ArgumentException("ShroudRenderer cannot define this many indexes for shroud directions.", "info"); this.info = info; map = world.Map; tileInfos = new CellLayer<TileInfo>(map); // Load sprite variants var variantCount = info.ShroudVariants.Length; variantStride = (byte)(info.Index.Length + (info.OverrideFullShroud != null ? 1 : 0)); shroudSprites = new Sprite[variantCount * variantStride]; fogSprites = new Sprite[variantCount * variantStride]; var sequenceProvider = map.Rules.Sequences; for (var j = 0; j < variantCount; j++) { var shroud = sequenceProvider.GetSequence(info.Sequence, info.ShroudVariants[j]); var fog = sequenceProvider.GetSequence(info.Sequence, info.FogVariants[j]); for (var i = 0; i < info.Index.Length; i++) { shroudSprites[j * variantStride + i] = shroud.GetSprite(i); fogSprites[j * variantStride + i] = fog.GetSprite(i); } if (info.OverrideFullShroud != null) { var i = (j + 1) * variantStride - 1; shroudSprites[i] = sequenceProvider.GetSequence(info.Sequence, info.OverrideFullShroud).GetSprite(0); fogSprites[i] = sequenceProvider.GetSequence(info.Sequence, info.OverrideFullFog).GetSprite(0); } } // Mapping of shrouded directions -> sprite index edgesToSpriteIndexOffset = new byte[(byte)(info.UseExtendedIndex ? Edges.All : Edges.AllCorners) + 1]; for (var i = 0; i < info.Index.Length; i++) edgesToSpriteIndexOffset[info.Index[i]] = (byte)i; if (info.OverrideFullShroud != null) edgesToSpriteIndexOffset[info.OverrideShroudIndex] = (byte)(variantStride - 1); notVisibleEdges = info.UseExtendedIndex ? Edges.AllSides : Edges.AllCorners; }
CellLayer<CellInfo> GetLayer() { CellLayer<CellInfo> layer = null; lock (pool) if (pool.Count > 0) layer = pool.Pop(); if (layer == null) layer = new CellLayer<CellInfo>(defaultLayer.GridType, defaultLayer.Size); layer.CopyValuesFrom(defaultLayer); return layer; }
public PathSearch(World world, MobileInfo mobileInfo, Actor self) { this.self = self; CellInfo = InitCellInfo(); this.mobileInfo = mobileInfo; this.self = self; customCost = null; Queue = new PriorityQueue <PathDistance>(); Considered = new HashSet <CPos>(); MaxCost = 0; nextDirections = CVec.directions.Select(d => new Pair <CVec, int>(d, 0)).ToArray(); }
public TSVeinsRenderer(Actor self, TSVeinsRendererInfo info) { this.info = info; world = self.World; resourceLayer = self.Trait <IResourceLayer>(); resourceLayer.CellChanged += AddDirtyCell; maxDensity = resourceLayer.GetMaxDensity(info.ResourceType); renderIndices = new CellLayer <int[]>(world.Map); borders = new CellLayer <Adjacency>(world.Map); }
public PathSearch(World world, MobileInfo mobileInfo, Actor self) { this.self = self; CellInfo = InitCellInfo(); this.mobileInfo = mobileInfo; this.self = self; customCost = null; Queue = new PriorityQueue<PathDistance>(); Considered = new HashSet<CPos>(); MaxCost = 0; nextDirections = CVec.directions.Select(d => new Pair<CVec, int>(d, 0)).ToArray(); }
/// <summary> /// Calculate the density of alive cells for the given layer /// </summary> /// <returns></returns> private float CalculateDensity(CellLayer layer) { var cells = layer.Cells; int aliveCount = 0; foreach (var cell in cells) { aliveCount += cell.State; } return((float)aliveCount / cells.Length); }
public Shroud(Actor self, ShroudInfo info) { this.self = self; this.info = info; map = this.self.World.Map; passiveVisibleCount = new CellLayer <short>(map); visibleCount = new CellLayer <short>(map); generatedShroudCount = new CellLayer <short>(map); explored = new CellLayer <bool>(map); resolvedType = new CellLayer <ShroudCellType>(map); }
public Shroud(Actor self) { this.self = self; map = self.World.Map; visibleCount = new CellLayer <short>(map); generatedShroudCount = new CellLayer <short>(map); explored = new CellLayer <bool>(map); shroudEdgeTest = map.Contains; isExploredTest = IsExploredCore; isVisibleTest = IsVisibleCore; }
public Shroud(Actor self) { this.self = self; map = self.World.Map; visibleCount = new CellLayer<short>(map); generatedShroudCount = new CellLayer<short>(map); explored = new CellLayer<bool>(map); shroudEdgeTest = map.Contains; isExploredTest = IsExploredCore; isVisibleTest = IsVisibleCore; }
public void WorldLoaded(World w, WorldRenderer wr) { var map = w.Map; actorMap = w.ActorMap; actorMap.CellUpdated += CellUpdated; cellsCost = new[] { new CellLayer <short>(map) }; blockingCache = new[] { new CellLayer <CellCache>(map) }; foreach (var cell in map.AllCells) { UpdateCellCost(cell); } map.CustomTerrain.CellEntryChanged += UpdateCellCost; map.Tiles.CellEntryChanged += UpdateCellCost; // This section needs to run after WorldLoaded() because we need to be sure that all types of ICustomMovementLayer have been initialized. w.AddFrameEndTask(_ => { var customMovementLayers = world.GetCustomMovementLayers(); Array.Resize(ref cellsCost, customMovementLayers.Length); Array.Resize(ref blockingCache, customMovementLayers.Length); foreach (var cml in customMovementLayers) { if (cml == null) { continue; } var cellLayer = new CellLayer <short>(map); cellsCost[cml.Index] = cellLayer; blockingCache[cml.Index] = new CellLayer <CellCache>(map); foreach (var cell in map.AllCells) { var index = cml.GetTerrainIndex(cell); var cost = PathGraph.MovementCostForUnreachableCell; if (index != byte.MaxValue) { cost = terrainInfos[index].Cost; } cellLayer[cell] = cost; } } }); }
/// <summary> /// /// </summary> public void UpdateAnalysis() { int currentLayer = _model.CurrentLayer; CellLayer layer = _model.Stack.Layers[currentLayer]; //update layer current density var density = CalculateDensity(layer); layer.Density = density; _densitySum += density; // add to running sum //update stack mean density _model.Stack.SetMeanStackDensity(MeanStackDensity); //update the stack //update layer avg age var avgage = CalculateAverageAge(layer); layer.AvgAge = avgage; _ageSum += avgage; // add to running sum //update stack avg age _model.Stack.SetAvgAge(MeanStackAge);//update the stack //update stack max layer density if (layer.Density > _model.Stack.MaxLayerDensity) { _model.Stack.SetMaxLayerDensity(layer.Density); _model.Stack.SetMaxLayerDensityNumebr(currentLayer); } //update stack min layer density if (layer.Density < _model.Stack.MinLayerDensity) { _model.Stack.SetMinLayerDensity(layer.Density); _model.Stack.SetMinLayerDensityNumebr(currentLayer); } //update max age in current layer var maxage = CalculateMaxAge(layer); layer.MaxAge = maxage; _model.Stack.SetMaxAge(maxage);//update the stack //update level density CalculateEachLevelDensity(_model); _currentLayer = currentLayer; }
public Shroud(Actor self, ShroudInfo info) { this.self = self; this.info = info; map = self.World.Map; passiveVisibleCount = new CellLayer<short>(map); visibleCount = new CellLayer<short>(map); generatedShroudCount = new CellLayer<short>(map); explored = new CellLayer<bool>(map); // Defaults to 0 = Shroud resolvedType = new CellLayer<ShroudCellType>(map); }
public EditorResourceLayer(Actor self) { if (self.World.Type != WorldType.Editor) { return; } Map = self.World.Map; Tiles = new CellLayer <ResourceLayerContents>(Map); Resources = self.TraitsImplementing <ResourceType>() .ToDictionary(r => r.Info.ResourceType, r => r); Map.Resources.CellEntryChanged += UpdateCell; }
public TerrainRenderer(World world, WorldRenderer wr) { theater = wr.Theater; mapTiles = world.Map.MapTiles.Value; terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette("terrain"), wr.World.Type != WorldType.Editor); foreach (var cell in world.Map.AllCells) UpdateCell(cell); world.Map.MapTiles.Value.CellEntryChanged += UpdateCell; world.Map.MapHeight.Value.CellEntryChanged += UpdateCell; }
public void Dispose() { if (disposed) { return; } disposed = true; PutBackIntoPool(CellInfo); CellInfo = null; GC.SuppressFinalize(this); }
//calculate max age in the stack (by lu) // Calculate mean density in each level (written by Lu) private void CalculateEachLevelDensity(StackModelManager model) { //get current layer int currentLayer = _model.CurrentLayer; CellLayer layer = _model.Stack.Layers[currentLayer]; int aliveCount = 0; // get cells in layers var cells = layer.Cells; //outcome float _densityLevel1; float _densityLevel2; float _densityLevel3; if (currentLayer <= 30) { foreach (var cell in cells) { aliveCount += cell.State; _densityLevel1 = (float)aliveCount / cells.Length; _densityLevels[0] = _densityLevel1; } } if (currentLayer > 30 && currentLayer < 60) { foreach (var cell in cells) { aliveCount += cell.State; _densityLevel2 = (float)aliveCount / cells.Length; _densityLevels[1] = _densityLevel2; } } if (currentLayer >= 60) { foreach (var cell in cells) { aliveCount += cell.State; _densityLevel3 = (float)aliveCount / cells.Length; _densityLevels[2] = _densityLevel3; } } ; }
public void SetCellColour(int x, int y, int cellIndex, CellLayer layer, Color colour) { WorldCell cell = null; if (cellIndex >= 0 && cellIndex < BaseWorldCells.Count) { cell = BaseWorldCells[cellIndex]; } var tilePos = new Vector3Int(x, y, 1); Tilemap tilemap = GetTilemap(layer); tilemap.SetColor(tilePos, colour); }
public void Dispose() { if (disposed) { return; } disposed = true; CellInfoLayerManager.Instance.PutBackIntoPool(cellInfo); cellInfo = null; GC.SuppressFinalize(this); }
public void FloodFillCells(int x, int y, int cellIndex, CellLayer layer) { WorldCell cell = null; if (cellIndex >= 0 && cellIndex < BaseWorldCells.Count) { cell = BaseWorldCells[cellIndex]; } var tilePos = new Vector3Int(x, y, 1); Tilemap tilemap = GetTilemap(layer); tilemap.FloodFill(tilePos, cell); }
// NOTE: can not check aircraft bool AnyActorsAt(MPos uv, CellLayer <InfluenceNode> layer, SubCell sub, Func <Actor, bool> withCondition) { var always = sub == SubCell.FullCell || sub == SubCell.Any; for (var i = layer[uv]; i != null; i = i.Next) { if ((always || i.SubCell == sub || i.SubCell == SubCell.FullCell) && !i.Actor.Disposed && withCondition(i.Actor)) { return(true); } } return(false); }
public void BoxFillCells(int x, int y, int cellIndex, CellLayer layer, int startX, int startY, int endX, int endY) { WorldCell cell = null; if (cellIndex >= 0 && cellIndex < BaseWorldCells.Count) { cell = BaseWorldCells[cellIndex]; } var tilePos = new Vector3Int(x, y, 1); Tilemap tilemap = GetTilemap(layer); tilemap.BoxFill(tilePos, cell, startX, startY, endX, endY); }
public void WorldLoaded(World w, WorldRenderer wr) { var map = w.Map; actorMap = w.ActorMap; map.CustomTerrain.CellEntryChanged += UpdateCellCost; map.Tiles.CellEntryChanged += UpdateCellCost; actorMap.CellUpdated += CellUpdated; cellsCost = new[] { new CellLayer <short>(map) }; blockingCache = new[] { new CellLayer <CellCache>(map) }; foreach (var cell in map.AllCells) { UpdateCellCost(cell); UpdateCellBlocking(cell); } // NotBefore<> ensures all custom movement layers have been initialized. var customMovementLayers = world.GetCustomMovementLayers(); Array.Resize(ref cellsCost, customMovementLayers.Length); Array.Resize(ref blockingCache, customMovementLayers.Length); foreach (var cml in customMovementLayers) { if (cml == null) { continue; } var cellLayer = new CellLayer <short>(map); cellsCost[cml.Index] = cellLayer; blockingCache[cml.Index] = new CellLayer <CellCache>(map); foreach (var cell in map.AllCells) { var index = cml.GetTerrainIndex(cell); var cost = PathGraph.MovementCostForUnreachableCell; if (index != byte.MaxValue) { cost = terrainInfos[index].Cost; } cellLayer[cell] = cost; } } }
static List <CPos> MakePath(CellLayer <CellInfo> cellInfo, CPos destination) { var ret = new List <CPos>(); var pathNode = destination; while (cellInfo[pathNode].Path != pathNode) { ret.Add(pathNode); pathNode = cellInfo[pathNode].Path; } ret.Add(pathNode); CheckSanePath(ret); return(ret); }
/// <summary> /// Calculate the average age of live cells for the given layer /// </summary> /// <returns></returns> private float CalculateAverageAge(CellLayer layer) { var cells = layer.Cells; int aliveCount = 0; int ageCount = 0; foreach (var cell in cells) { aliveCount += cell.State; ageCount += cell.Age; } return((float)((float)ageCount) / ((float)aliveCount)); }
public ShroudRenderer(World world, ShroudRendererInfo info) { this.info = info; map = world.Map; tiles = new CellLayer<ShroudTile>(map); // Force update on first render shroudHash = -1; // Load sprite variants if (info.ShroudVariants.Length != info.FogVariants.Length) throw new InvalidOperationException("ShroudRenderer must define the same number of shroud and fog variants!"); if ((info.OverrideFullFog == null) ^ (info.OverrideFullShroud == null)) throw new InvalidOperationException("ShroudRenderer cannot define overrides for only one of shroud or fog!"); var variantCount = info.ShroudVariants.Length; variantStride = info.Index.Length + (info.OverrideFullShroud != null ? 1 : 0); shroudSprites = new Sprite[variantCount * variantStride]; fogSprites = new Sprite[variantCount * variantStride]; for (var j = 0; j < variantCount; j++) { var shroud = map.SequenceProvider.GetSequence(info.Sequence, info.ShroudVariants[j]); var fog = map.SequenceProvider.GetSequence(info.Sequence, info.FogVariants[j]); for (var i = 0; i < info.Index.Length; i++) { shroudSprites[j * variantStride + i] = shroud.GetSprite(i); fogSprites[j * variantStride + i] = fog.GetSprite(i); } if (info.OverrideFullShroud != null) { var i = (j + 1) * variantStride - 1; shroudSprites[i] = map.SequenceProvider.GetSequence(info.Sequence, info.OverrideFullShroud).GetSprite(0); fogSprites[i] = map.SequenceProvider.GetSequence(info.Sequence, info.OverrideFullFog).GetSprite(0); } } // Mapping of shrouded directions -> sprite index spriteMap = new int[info.UseExtendedIndex ? 256 : 16]; for (var i = 0; i < info.Index.Length; i++) spriteMap[info.Index[i]] = i; if (info.OverrideFullShroud != null) spriteMap[info.OverrideShroudIndex] = variantStride - 1; }
public ActorMap(World world, ActorMapInfo info) { this.info = info; map = world.Map; influence = new CellLayer<InfluenceNode>(world.Map); cols = world.Map.MapSize.X / info.BinSize + 1; rows = world.Map.MapSize.Y / info.BinSize + 1; bins = new Bin[rows * cols]; for (var j = 0; j < rows; j++) for (var i = 0; i < cols; i++) bins[j * cols + i] = new Bin(); // Cache this delegate so it does not have to be allocated repeatedly. actorShouldBeRemoved = removeActorPosition.Contains; }
public ActorMap(World world, ActorMapInfo info) { this.info = info; map = world.Map; influence = new CellLayer<InfluenceNode>(world.Map); cols = CellCoordToBinIndex(world.Map.MapSize.X) + 1; rows = CellCoordToBinIndex(world.Map.MapSize.Y) + 1; bins = new Bin[rows * cols]; for (var row = 0; row < rows; row++) for (var col = 0; col < cols; col++) bins[row * cols + col] = new Bin(); // Cache this delegate so it does not have to be allocated repeatedly. actorShouldBeRemoved = removeActorPosition.Contains; }
public TerrainRenderer(World world, WorldRenderer wr) { theater = wr.Theater; mapTiles = world.Map.MapTiles.Value; terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette("terrain"), wr.World.Type != WorldType.Editor); foreach (var cell in world.Map.AllCells) { UpdateCell(cell); } world.Map.MapTiles.Value.CellEntryChanged += UpdateCell; world.Map.MapHeight.Value.CellEntryChanged += UpdateCell; }
public CopyPasteEditorAction(MapCopyFilters copyFilters, Map map, Dictionary <CPos, Tuple <TerrainTile, ResourceTile, byte> > tiles, Dictionary <string, ActorReference> previews, EditorActorLayer editorLayer, CellRegion dest) { this.copyFilters = copyFilters; this.tiles = tiles; this.previews = previews; this.editorLayer = editorLayer; this.dest = dest; mapTiles = map.Tiles; mapHeight = map.Height; mapResources = map.Resources; Text = "Copied {0} tiles".F(tiles.Count); }
CellLayer <CellInfo> GetLayer() { CellLayer <CellInfo> layer = null; lock (pool) if (pool.Count > 0) { layer = pool.Pop(); } if (layer == null) { layer = new CellLayer <CellInfo>(defaultLayer.GridType, defaultLayer.Size); } layer.CopyValuesFrom(defaultLayer); return(layer); }
public Shroud(Actor self) { this.self = self; map = self.World.Map; visibleCount = new CellLayer <int>(map); generatedShroudCount = new CellLayer <int>(map); explored = new CellLayer <bool>(map); self.World.ActorAdded += AddVisibility; self.World.ActorRemoved += RemoveVisibility; self.World.ActorAdded += AddShroudGeneration; self.World.ActorRemoved += RemoveShroudGeneration; fogVisibilities = Exts.Lazy(() => self.TraitsImplementing <IFogVisibilityModifier>().ToArray()); }
private Tilemap GetTilemap(CellLayer layer) { switch (layer) { case CellLayer.Foreground: return(ForegroundTilemap); case CellLayer.Background: return(BackgroundTilemap); case CellLayer.Light: return(LightingTilemap); default: return(null); } }
public Shroud(Actor self) { this.self = self; map = self.World.Map; visibleCount = new CellLayer<int>(map); generatedShroudCount = new CellLayer<int>(map); explored = new CellLayer<bool>(map); self.World.ActorAdded += AddVisibility; self.World.ActorRemoved += RemoveVisibility; self.World.ActorAdded += AddShroudGeneration; self.World.ActorRemoved += RemoveShroudGeneration; fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray()); }
public void WorldLoaded(World w, WorldRenderer wr) { trees = new CellLayer <Tree>(w.Map); // Build a list of templates that should be overlayed with trees foreach (var tree in info.Trees) { var treeInfo = w.Map.Rules.Actors[tree].TraitInfo <TreeInfo>(); treeTypes.Add(treeInfo.Template, tree); } // Take all templates to overlay from the map foreach (var cell in w.Map.AllCells.Where(cell => treeTypes.ContainsKey(w.Map.Tiles[cell].Type))) { ConvertTreeToActor(w, cell); } }
public void WorldLoaded(World w, WorldRenderer wr) { this.world = w; buildingInfluence = world.WorldActor.Trait <BuildingInfluence>(); content = new CellLayer <CellContents>(w.Map); render = new CellLayer <CellContents>(w.Map); dirty = new List <CPos>(); var resources = w.WorldActor.TraitsImplementing <ResourceType>() .ToDictionary(r => r.Info.ResourceType, r => r); foreach (var cell in w.Map.Cells) { ResourceType t; if (!resources.TryGetValue(w.Map.MapResources.Value[cell].Type, out t)) { continue; } if (!AllowResourceAt(t, cell)) { continue; } content[cell] = CreateResourceCell(t, cell); } // Set initial density based on the number of neighboring resources foreach (var cell in w.Map.Cells) { var type = content[cell].Type; if (type != null) { // Adjacent includes the current cell, so is always >= 1 var adjacent = GetAdjacentCellsWith(type, cell); var density = int2.Lerp(0, type.Info.MaxDensity, adjacent, 9); var temp = content[cell]; temp.Density = Math.Max(density, 1); render[cell] = content[cell] = temp; UpdateRenderedSprite(cell); } } }
public void WorldLoaded(World w, WorldRenderer wr) { world = w; var map = w.Map; actorMap = w.ActorMap; actorMap.CellUpdated += CellUpdated; terrainInfos = Info.TilesetTerrainInfo[map.Rules.TileSet]; blockingCache = new CellLayer <CellCache>(map); cellsCost = new CellLayer <short>(map); foreach (var cell in map.AllCells) { UpdateCellCost(cell); } map.CustomTerrain.CellEntryChanged += UpdateCellCost; map.Tiles.CellEntryChanged += UpdateCellCost; // This section needs to run after WorldLoaded() because we need to be sure that all types of ICustomMovementLayer have been initialized. w.AddFrameEndTask(_ => { var customMovementLayers = w.WorldActor.TraitsImplementing <ICustomMovementLayer>(); foreach (var cml in customMovementLayers) { var cellLayer = new CellLayer <short>(map); customLayerCellsCost[cml.Index] = cellLayer; customLayerBlockingCache[cml.Index] = new CellLayer <CellCache>(map); foreach (var cell in map.AllCells) { var index = cml.GetTerrainIndex(cell); var cost = short.MaxValue; if (index != byte.MaxValue) { cost = terrainInfos[index].Cost; } cellLayer[cell] = cost; } } }); }
public void WorldLoaded(World w, WorldRenderer wr) { bridges = new CellLayer<Bridge>(w.Map); // Build a list of templates that should be overlayed with bridges foreach (var bridge in info.Bridges) { var bi = w.Map.Rules.Actors[bridge].TraitInfo<BridgeInfo>(); foreach (var template in bi.Templates) bridgeTypes.Add(template.First, Pair.New(bridge, template.Second)); } // Take all templates to overlay from the map foreach (var cell in w.Map.AllCells.Where(cell => bridgeTypes.ContainsKey(w.Map.MapTiles.Value[cell].Type))) ConvertBridgeToActor(w, cell); // Link adjacent (long)-bridges so that artwork is updated correctly foreach (var p in w.ActorsWithTrait<Bridge>()) p.Trait.LinkNeighbouringBridges(w, this); }
public TerrainRenderer(World world, WorldRenderer wr) { worldRenderer = wr; theater = wr.Theater; map = world.Map; mapTiles = map.MapTiles.Value; terrainPaletteIndex = wr.Palette("terrain").TextureIndex; rowStride = 4 * map.Bounds.Width; vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(rowStride * map.Bounds.Height); UpdateMap(); map.MapTiles.Value.CellEntryChanged += UpdateCell; map.MapHeight.Value.CellEntryChanged += UpdateCell; wr.PaletteInvalidated += () => { terrainPaletteIndex = wr.Palette("terrain").TextureIndex; UpdateMap(); }; }
public Shroud(Actor self) { this.self = self; map = self.World.Map; visibleCount = new CellLayer<short>(map); generatedShroudCount = new CellLayer<short>(map); explored = new CellLayer<bool>(map); self.World.ActorAdded += AddVisibility; self.World.ActorRemoved += RemoveVisibility; self.World.ActorAdded += AddShroudGeneration; self.World.ActorRemoved += RemoveShroudGeneration; fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray()); shroudEdgeTest = cell => map.Contains(cell); fastExploredTest = IsExploredCore; slowExploredTest = IsExplored; fastVisibleTest = IsVisibleCore; slowVisibleTest = IsVisible; }
public CellLayer<TerrainTile> LoadMapTiles() { var tiles = new CellLayer<TerrainTile>(this); using (var dataStream = Container.GetContent("map.bin")) { if (dataStream.ReadUInt8() != 1) throw new InvalidDataException("Unknown binary map format"); // Load header info var width = dataStream.ReadUInt16(); var height = dataStream.ReadUInt16(); if (width != MapSize.X || height != MapSize.Y) throw new InvalidDataException("Invalid tile data"); // Load tile data var data = dataStream.ReadBytes(MapSize.X * MapSize.Y * 3); var d = 0; for (var i = 0; i < MapSize.X; i++) { for (var j = 0; j < MapSize.Y; j++) { var tile = BitConverter.ToUInt16(data, d); d += 2; var index = data[d++]; if (index == byte.MaxValue) index = (byte)(i % 4 + (j % 4) * 4); tiles[i, j] = new TerrainTile(tile, index); } } } return tiles; }
public void Dispose() { if (disposed) return; disposed = true; PutBackIntoPool(CellInfo); CellInfo = null; GC.SuppressFinalize(this); }
CellLayer<CellInfo> InitCellInfo() { CellLayer<CellInfo> result = null; var mapSize = new Size(self.World.Map.MapSize.X, self.World.Map.MapSize.Y); // HACK: Uses a static cache so that double-ended searches (which have two PathSearch instances) // can implicitly share data. The PathFinder should allocate the CellInfo array and pass it // explicitly to the things that need to share it. while (CellInfoPool.Count > 0) { var cellInfo = GetFromPool(); if (cellInfo.Size != mapSize || cellInfo.Shape != self.World.Map.TileShape) { Log.Write("debug", "Discarding old pooled CellInfo of wrong size."); continue; } result = cellInfo; break; } if (result == null) result = new CellLayer<CellInfo>(self.World.Map); foreach (var cell in self.World.Map.Cells) result[cell] = new CellInfo(int.MaxValue, cell, false); return result; }
static void PutBackIntoPool(CellLayer<CellInfo> ci) { lock (CellInfoPool) CellInfoPool.Enqueue(ci); }
void PostInit() { rules = Exts.Lazy(() => Game.modData.RulesetCache.LoadMapRules(this)); cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]); var tl = Map.MapToCell(TileShape, new CPos(Bounds.Left, Bounds.Top)); var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1)); Cells = new CellRegion(TileShape, tl, br); CustomTerrain = new CellLayer<int>(this); foreach (var cell in Cells) CustomTerrain[cell] = -1; }
void ReturnLayer(CellLayer<CellInfo> layer) { lock (pool) if (pool.Count < MaxPoolSize) pool.Push(layer); }
public CellLayer<ResourceTile> LoadResourceTiles() { var resources = new CellLayer<ResourceTile>(this); using (var dataStream = Container.GetContent("map.bin")) { if (dataStream.ReadUInt8() != 1) throw new InvalidDataException("Unknown binary map format"); // Load header info var width = dataStream.ReadUInt16(); var height = dataStream.ReadUInt16(); if (width != MapSize.X || height != MapSize.Y) throw new InvalidDataException("Invalid tile data"); // Skip past tile data dataStream.Seek(3 * MapSize.X * MapSize.Y, SeekOrigin.Current); var data = dataStream.ReadBytes(MapSize.X * MapSize.Y * 2); var d = 0; // Load resource data for (var i = 0; i < MapSize.X; i++) for (var j = 0; j < MapSize.Y; j++) resources[i, j] = new ResourceTile(data[d++], data[d++]); } return resources; }
public static Map FromTileset(TileSet tileset) { var size = new Size(1, 1); var tileShape = Game.ModData.Manifest.TileShape; var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0); var makeMapTiles = Exts.Lazy(() => { var ret = new CellLayer<TerrainTile>(tileShape, size); ret.Clear(tileRef); return ret; }); var makeMapHeight = Exts.Lazy(() => { var ret = new CellLayer<byte>(tileShape, size); ret.Clear(0); return ret; }); var map = new Map() { Title = "Name your map here", Description = "Describe your map here", Author = "Your name here", MapSize = new int2(size), Tileset = tileset.Id, Videos = new MapVideos(), Options = new MapOptions(), MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(tileShape, size)), MapTiles = makeMapTiles, MapHeight = makeMapHeight, SpawnPoints = Exts.Lazy(() => new CPos[0]) }; map.PostInit(); return map; }
public CellLayer<byte> LoadMapHeight() { var maxHeight = cachedTileSet.Value.MaxGroundHeight; var tiles = new CellLayer<byte>(this); using (var s = Container.GetContent("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.HeightsOffset > 0) { s.Position = header.HeightsOffset; for (var i = 0; i < MapSize.X; i++) for (var j = 0; j < MapSize.Y; j++) tiles[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, maxHeight); } } return tiles; }
public CellLayer<TerrainTile> LoadMapTiles() { var tiles = new CellLayer<TerrainTile>(this); using (var s = Container.GetContent("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); } } } } return tiles; }
public CellLayer<ResourceTile> LoadResourceTiles() { var resources = new CellLayer<ResourceTile>(this); using (var s = Container.GetContent("map.bin")) { var header = new BinaryDataHeader(s, MapSize); 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); } } } } return resources; }
void PostInit() { rules = Exts.Lazy(() => { try { return Game.ModData.RulesetCache.LoadMapRules(this); } catch (Exception e) { InvalidCustomRules = true; Log.Write("debug", "Failed to load rules for {0} with error {1}", Title, e.Message); } return Game.ModData.DefaultRules; }); cachedTileSet = Exts.Lazy(() => Rules.TileSets[Tileset]); var tl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this); var br = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this); Cells = new CellRegion(TileShape, tl, br); CustomTerrain = new CellLayer<byte>(this); foreach (var uv in Cells.MapCoords) CustomTerrain[uv] = byte.MaxValue; var leftDelta = TileShape == TileShape.Diamond ? new WVec(-512, 0, 0) : new WVec(-512, -512, 0); var topDelta = TileShape == TileShape.Diamond ? new WVec(0, -512, 0) : new WVec(512, -512, 0); var rightDelta = TileShape == TileShape.Diamond ? new WVec(512, 0, 0) : new WVec(512, 512, 0); var bottomDelta = TileShape == TileShape.Diamond ? new WVec(0, 512, 0) : new WVec(-512, 512, 0); CellCorners = CellCornerHalfHeights.Select(ramp => new WVec[] { leftDelta + new WVec(0, 0, 512 * ramp[0]), topDelta + new WVec(0, 0, 512 * ramp[1]), rightDelta + new WVec(0, 0, 512 * ramp[2]), bottomDelta + new WVec(0, 0, 512 * ramp[3]) }).ToArray(); }