// Natural Disaster That Damages Buildings private void CreateEarthquake(ImpactRegion r) { List <LightningParticle> particles = new List <LightningParticle>(); foreach (var ic in r.Cells) { Point c = new Point(ic.X * 2, ic.Y * 2); for (int x = 0; x < 2 && c.X + x < GameState.CGrid.numCells.X; x++) { for (int y = 0; y < 2 && c.Y + y < GameState.CGrid.numCells.Y; y++) { RTSBuilding b = GameState.CGrid.EStatic[c.X + x, c.Y + y]; if (b != null && b.Team.Index != Team.Index) { bool takeDamage = (random.Next(100) <= EarthquakeHitP); if (true) { b.Damage(EarthquakeDamage); bool canSee = GameState.CGrid.GetFogOfWar(b.GridPosition, playerIndex) == FogOfWar.Active; if (canSee) { particles.Add(new LightningParticle(b.WorldPosition, 3, 10, 2, 0.6f, 1, Color.Red)); } } } } } } GameState.AddParticles(particles); }
private void SetInitTarget(ImpactRegion r) { List <IEntity> selected = r.Selected; // Select Units Not In A Squad AddEvent(new SelectEvent(TeamIndex, selected)); // Set The Target For Those Units IEntity target = null; Vector2 sumPos = Vector2.Zero; foreach (var s in selected) { sumPos += s.GridPosition; } Vector2 averagePos = new Vector2(sumPos.X / selected.Count, sumPos.Y / selected.Count); foreach (var t in GameState.activeTeams) { if (t.Index != TeamIndex) { foreach (var u in t.Team.Units) { if (target == null || Vector2.Distance(u.GridPosition, averagePos) < Vector2.Distance(u.GridPosition, target.GridPosition)) { target = u; } } } } AddEvent(new SetTargetEvent(TeamIndex, target)); }
// Find The Region An Entity Is Located In private ImpactRegion FindRegion(IEntity e) { Point ic = HashHelper.Hash(e.GridPosition, grid.numCells, grid.size); ImpactRegion r = grid.Region[ic.X, ic.Y]; return(r); }
// Natural Disaster That Damages Units private void CreateLightning(ImpactRegion r) { List <LightningParticle> particles = new List <LightningParticle>(); foreach (var ic in r.Cells) { Point c = new Point(ic.X * 2, ic.Y * 2); for (int x = 0; x < 2 && c.X + x < GameState.CGrid.numCells.X; x++) { for (int y = 0; y < 2 && c.Y + y < GameState.CGrid.numCells.Y; y++) { foreach (var u in GameState.CGrid.EDynamic[c.X + x, c.Y + y]) { if (u.Team.Index != Team.Index) { bool takeDamage = (random.Next(100) <= LightningHitP); if (takeDamage) { u.Damage(LightningDamage); bool canSee = GameState.CGrid.GetFogOfWar(u.GridPosition, playerIndex) == FogOfWar.Active; if (canSee) { particles.Add(new LightningParticle(u.WorldPosition, 1, 7, 1, 0.6f, 1, Color.BlueViolet)); } } } } } } } GameState.AddParticles(particles); }
// Recovery Phase private void Recover() { if (treeLocations == null || treeLocations.Count < 1) { return; } foreach (var r in GameState.Regions) { if (r.RegionImpact < PointOfNoReturn && r.RegionImpact > 0) { // Randomly Choose The Location Of A Starting Tree In Region List <Point> treesInRegion = new List <Point>(); foreach (var tl in treeLocations) { ImpactRegion rr = FindRegion(tl); if (rr == r) { treesInRegion.Add(tl); } } // Spawn Trees Around The Starting Tree if (treesInRegion.Count > 0) { int i = random.Next(treesInRegion.Count); Point treeC = treesInRegion[i]; for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { Point newTreeC = new Point(treeC.X + x, treeC.Y + y); bool noBuilding = GameState.CGrid.EStatic[newTreeC.X, newTreeC.Y] == null; bool noUnits = GameState.CGrid.EDynamic[newTreeC.X, newTreeC.Y].Count == 0; if (noBuilding && noUnits && r.RegionImpact > 0) { DevConsole.AddCommand("recover4"); AddEvent(new SpawnBuildingEvent(TeamIndex, FloraType, newTreeC)); Vector2 newTreePos = new Vector2(newTreeC.X, newTreeC.Y) * GameState.CGrid.cellSize + Vector2.One; grid.AddImpact(newTreePos, -1 * (FloraData.Impact * FloraData.Health)); } } } } // Regenerate Ore Health foreach (var c in r.Cells) { foreach (var o in GameState.IGrid.ImpactGenerators[c.X, c.Y]) { if (o.Data.FriendlyName.Equals(OreData.FriendlyName)) { o.Health += OreRecoverHealth; r.AddToRegionImpact(-(OreData.Impact * OreRecoverHealth)); } } } } } }
// Find The Region A Collision Cell Is Located In private ImpactRegion FindRegion(Point cc) { Vector2 pos = new Vector2(cc.X, cc.Y) * GameState.CGrid.cellSize + Vector2.One; Point ic = HashHelper.Hash(pos, grid.numCells, grid.size); ImpactRegion r = grid.Region[ic.X, ic.Y]; return(r); }
private void OnUnitSpawn(RTSUnit u) { ImpactRegion r = FindRegion(u); r.Selected.Add(u); r.PopCount++; u.OnDestruction += OnUnitDeath; }
public void ReadGridData(string rootPath, string filePath) { string path = Path.Combine(rootPath, filePath); int[] ids; int w, h; using (var bmp = System.Drawing.Bitmap.FromFile(path) as System.Drawing.Bitmap) { w = bmp.Width; h = bmp.Height; ids = new int[w * h]; // Convert Bitmap System.Drawing.Imaging.BitmapData bd = bmp.LockBits(new System.Drawing.Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat); System.Runtime.InteropServices.Marshal.Copy(bd.Scan0, ids, 0, ids.Length); bmp.UnlockBits(bd); } var regionCells = new Dictionary <int, List <Microsoft.Xna.Framework.Point> >(); LGrid.L2 = new ImpactGrid(w, h); // Find All The Regions int ii = 0; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (regionCells.ContainsKey(ids[ii])) { regionCells[ids[ii]].Add(new Microsoft.Xna.Framework.Point(x, y)); } else { var l = new List <Microsoft.Xna.Framework.Point>(); l.Add(new Microsoft.Xna.Framework.Point(x, y)); regionCells.Add(ids[ii], l); } ii++; } } // Create The Regions foreach (var kv in regionCells) { ImpactRegion r = new ImpactRegion(kv.Value); Regions.Add(r); foreach (var p in r.Cells) { LGrid.L2.Region[p.X, p.Y] = r; } } }
// Natural Disaster That Damages Both Units And Buildings private void CreateFire(ImpactRegion r) { // Find Impact Cell With Highest Impact int i = random.Next(r.Cells.Count); Point highest = r.Cells.ElementAt(i); foreach (var ic in r.Cells) { if (grid.CellImpact[highest.X, highest.Y] > grid.CellImpact[ic.X, ic.Y]) { highest = ic; } } // Use That Impact Cell As A Fire Starting Point FireStarts.Add(highest); }
private void OnUnitDeath(IEntity e) { ImpactRegion r = FindRegion(e); r.PopCount--; IEntity dead = null; foreach (var u in r.Selected) { if (e.UUID == u.UUID) { dead = e; } } if (dead != null) { r.Selected.Remove(dead); } }
private void SpawnUnits(ImpactRegion r, int level) { // Decide Spawn Cap int spawnCap; if (level == 1) { spawnCap = L1SpawnCap; } else if (level == 2) { spawnCap = L2SpawnCap; } else if (level == 3) { spawnCap = L3SpawnCap; } else { spawnCap = 0; } // Return If Population Count Of Region Is Greater Than The Spawn Cap For The Region if (r.PopCount >= spawnCap) { return; } // Decide On A Starting Point Point start = new Point(-1, -1); foreach (var u in GameState.activeTeams[playerIndex].Team.Units) { Point cc = HashHelper.Hash(u.GridPosition, GameState.CGrid.numCells, GameState.CGrid.size); start = cc; } // Find Possible Spawn Points List <Point> spawnPoints = new List <Point>(); Queue <Point> unvisited = new Queue <Point>(); int width = GameState.CGrid.numCells.X; int height = GameState.CGrid.numCells.Y; bool[,] visited = new bool[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { visited[x, y] = false; } } if (start.X > 0 && start.Y > 0) { unvisited.Enqueue(start); visited[start.X, start.Y] = true; } while (unvisited.Count > 0) { Point at = unvisited.Dequeue(); for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { Point p = new Point(at.X + x, at.Y + y); if ((p.X != at.X || p.Y != at.Y) && p.X > 0 && p.Y > 0 && p.X < width && p.Y < height) { ImpactRegion pr = FindRegion(p); RTSBuilding b = GameState.CGrid.EStatic[p.X, p.Y]; if (pr.Cells.First() == r.Cells.First() && b != null) { bool isOre = b.Data.FriendlyName.Equals(OreData.FriendlyName); bool isTree = b.Data.FriendlyName.Equals(FloraData.FriendlyName); if (isOre || isTree) { spawnPoints.Add(at); } } else if (pr.Cells.First() == r.Cells.First() && b == null && !visited[p.X, p.Y]) { unvisited.Enqueue(p); visited[p.X, p.Y] = true; } } } } } if (spawnPoints.Count > 0) { // Choose A Random Spawn Point int ii = random.Next(spawnPoints.Count); Point spawnPoint = spawnPoints.ElementAt(ii); Vector2 spawnPos = new Vector2(spawnPoint.X, spawnPoint.Y) * GameState.CGrid.cellSize + Vector2.One; // Spawn Environmental Units int numSpawn; int ti = 0; foreach (var spawnType in Spawns) { numSpawn = random.Next(minNumSpawn[level - 1][ti], maxNumSpawn[level - 1][ti]); for (int j = 0; j < numSpawn && r.PopCount < spawnCap; j++) { AddEvent(new SpawnUnitEvent(TeamIndex, spawnType, spawnPos)); r.PopCount++; } ti++; } } SetInitTarget(r); }
public void ReadGridData(string rootPath, string filePath) { string path = Path.Combine(rootPath, filePath); int[] ids; int w, h; using(var bmp = System.Drawing.Bitmap.FromFile(path) as System.Drawing.Bitmap) { w = bmp.Width; h = bmp.Height; ids = new int[w * h]; // Convert Bitmap System.Drawing.Imaging.BitmapData bd = bmp.LockBits(new System.Drawing.Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat); System.Runtime.InteropServices.Marshal.Copy(bd.Scan0, ids, 0, ids.Length); bmp.UnlockBits(bd); } var regionCells = new Dictionary<int, List<Microsoft.Xna.Framework.Point>>(); LGrid.L2 = new ImpactGrid(w, h); // Find All The Regions int ii = 0; for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { if(regionCells.ContainsKey(ids[ii])) { regionCells[ids[ii]].Add(new Microsoft.Xna.Framework.Point(x, y)); } else { var l = new List<Microsoft.Xna.Framework.Point>(); l.Add(new Microsoft.Xna.Framework.Point(x, y)); regionCells.Add(ids[ii], l); } ii++; } } // Create The Regions foreach(var kv in regionCells) { ImpactRegion r = new ImpactRegion(kv.Value); Regions.Add(r); foreach(var p in r.Cells) { LGrid.L2.Region[p.X, p.Y] = r; } } }