public bool CanStructureBePlaced(Point location, int size, Unit builder, bool cutCorners) { List<PathNode> placingStructurePathNodes = new List<PathNode>(); Circle collisionCircle = new Circle(new Vector2(location.X * Map.TileSize + (size / 2) * Map.TileSize, location.Y * Map.TileSize + (size / 2) * Map.TileSize), size * Map.TileSize); //placingStructureCenterPoint = collisionCircle.CenterPoint; for (int x = location.X; x < location.X + size; x++) { for (int y = location.Y; y < location.Y + size; y++) { PathNode node = Rts.pathFinder.PathNodes[(int)MathHelper.Clamp(y, 0, Map.Height - 1), (int)MathHelper.Clamp(x, 0, Map.Width - 1)]; if (collisionCircle.Intersects(node.Tile)) { placingStructurePathNodes.Add(node); } } } // remove corners if (cutCorners) { placingStructurePathNodes.Remove(Rts.pathFinder.PathNodes[location.Y, location.X]); if (location.X + size <= Map.Width - 1) placingStructurePathNodes.Remove(Rts.pathFinder.PathNodes[location.Y, location.X + size - 1]); else return false; if (location.Y + size <= Map.Height - 1) placingStructurePathNodes.Remove(Rts.pathFinder.PathNodes[location.Y + size - 1, location.X]); else return false; placingStructurePathNodes.Remove(Rts.pathFinder.PathNodes[location.Y + size - 1, location.X + size - 1]); } foreach (PathNode node in placingStructurePathNodes) { if (!node.Tile.Walkable || node.Blocked) return false; if (node.UnitsContained.Count > 0) { if (node.UnitsContained.Count == 1 && node.UnitsContained.ElementAt<Unit>(0) == builder) continue; else { bool allow = true; foreach (Unit unit in node.UnitsContained) { if (unit.Team != builder.Team) { allow = false; break; } } if (!allow) return false; } } } return true; }
public Structure(StructureType type, Point tilePosition, Unit builder, short team) : this(type, tilePosition, team) { UnderConstruction = true; PercentDone = 0f; Builder = builder; //preciseHp = MaxHp * STARTING_HP_PERCENT; Hp = (int)(MaxHp * STARTING_HP_PERCENT); constructionHpPerTick = (MaxHp - (MaxHp * STARTING_HP_PERCENT)) / (BuildTime / 1000) / 8; //((Rts)Game1.Game.CurrentGameState).CogWheels.Add(new StructureCogWheel(this, (int)(Type.Size * Map.TileSize / 2.5f))); //if (team == Player.Me.Team) //{ CogWheel = new StructureCogWheel(this, (int)(type.Size * Rts.map.TileSize / 2.5f)); ((Rts)Game1.Game.CurrentGameState).CogWheels.Add(CogWheel); //} foreach (PathNode pathNode in OccupiedPathNodes) { foreach (Unit unit in pathNode.UnitsContained) { if (unit != Builder) { unit.PushSimple((float)(rand.NextDouble() * MathHelper.TwoPi), Radius * .5f); //unit.CheckForPush(true); unit.CheckForWallHit(); } } } }
/*public AttackCommand(List<Vector2> wayPoints, RtsObject target) : base(wayPoints, 1) { this.target = target; }*/ public AttackCommand(Unit unit, RtsObject target, bool willingToChangeTarget, bool holdPosition) : base(unit, target.CenterPoint) { Target = target; this.willingToChangeTarget = willingToChangeTarget; this.holdPosition = holdPosition; }
public RtsBullet(Unit shooter, RtsObject target, Vector2 position, int size, float speed) : base(new Rectangle(0, 0, size, size), new Vector2(speed, speed)) { this.shooter = shooter; this.target = target; CenterPoint = position; RtsBullets.Add(this); }
public RtsBullet(BulletType type, Unit shooter, RtsObject target, Vector2 position, int size, float speed) : base(new Rectangle(0, 0, size, size), new Vector2(speed, speed)) { Type = type; /*if (type.Animated) animation = new Animation(0, 1 * Rts.GameSpeed, Util.SplitTexture(type.Texture, type.SheetWidth, type.SheetHeight)); else Texture = type.Texture;*/ if (type.Textures.Length > 1) animation = new Animation(0, 10 * Rts.GameSpeed, type.Textures); else Texture = type.Textures[0]; this.shooter = shooter; this.target = target; CenterPoint = position; RtsBullets.Add(this); }
public List<Vector2> CurvePath(List<Vector2> path, Unit unit) { /*if (path.Count < 2) return path; path.Insert(0, path[0]); if (path.Count < 4) path.Add(path[2]);*/ if (path.Count < 4) return path; //path.Insert(0, unit.CenterPoint); List<Vector2> curvedPath = new List<Vector2>(); //curvedPath.Add(unit.CenterPoint); //curvedPath.Add(path[path.Count - 1]); List<Vector2> curvePoints1 = new List<Vector2>(); List<Vector2> curvePoints2 = new List<Vector2>(); float weightIncrement = 1f / numberOfCurvePoints; for (float s = weightIncrement; s < 1f; s += weightIncrement) { //curvedPath.Add(Vector2.CatmullRom(unit.CenterPoint, path[0], path[1], path[2], s)); curvePoints1.Add(Vector2.CatmullRom(unit.CenterPoint, path[0], path[1], path[2], s)); } for (float s = weightIncrement; s < 1f; s += weightIncrement) { //curvedPath.Add(Vector2.CatmullRom(unit.CenterPoint, path[0], path[1], path[2], s)); curvePoints2.Add(Vector2.CatmullRom(path[0], path[1], path[2], path[3], s)); } //path.InsertRange(0, curvePoints1); path.InsertRange(1, curvePoints2); //curvedPath.Add(path[0]); //curvedPath.Add(path[0]); /*for (int i = 1; i < path.Count - 2; i++) { Vector2 point1 = path[i - 1]; Vector2 point2 = path[i]; Vector2 point3 = path[i + 1]; Vector2 point4 = path[i + 2]; curvedPath.Add(point2); for (float s = 0; s < 1f; s += weightIncrement) { curvedPath.Add(Vector2.CatmullRom(point1, point2, point3, point4, s)); } curvedPath.Add(point3); } for (float s = 0; s < 1f; s += weightIncrement) { curvedPath.Add(Vector2.CatmullRom(path[path.Count - 3], path[path.Count - 2], path[path.Count - 1], path[path.Count - 1], s)); } curvedPath.Add(path[path.Count - 1]); return curvedPath;*/ return path; }
bool isPathWalkable(List<Vector2> path, Unit unit) { return Walkable(path[0], path[path.Count - 1], unit, path.Count * 4); }
public bool Walkable(Vector2 point1, Vector2 point2, Unit unit, int numberOfIntermediatePoints) { //float radius = unit.Radius; float lerpAmountIncrement = 1f / (numberOfIntermediatePoints + 1); for (float l = lerpAmountIncrement; l < 1f; l += lerpAmountIncrement) //for (float l = 1f - lerpAmountIncrement; l > 0; l -= lerpAmountIncrement) { Vector2 intermediatePoint = Vector2.Lerp(point1, point2, l); if (!IsPointWalkable(intermediatePoint, unit)) return false; } return true; }
public void SmoothPathEnd(List<Vector2> path, Unit unit) { if (path.Count == 2) { Vector2 point = path[path.Count - 1]; if (Walkable(unit.CenterPoint, point, unit, (int)(Vector2.Distance(unit.CenterPoint, point) / unit.Diameter))) { path.RemoveAt(path.Count - 2); } } else { Vector2 point1 = path[path.Count - 3]; Vector2 point2 = path[path.Count - 1]; if (Walkable(point1, point2, unit, (int)(Vector2.Distance(point1, point2) / unit.Diameter))) { path.RemoveAt(path.Count - 2); } } }
public bool Intersects(Unit u) { return Vector2.Distance(centerPoint, u.centerPoint) < (this.Radius + u.Radius); //return Vector2.DistanceSquared(centerPoint, u.centerPoint) < Math.Pow(this.Radius + u.Radius, 2); }
public ReturnCargoCommand(Unit unit, Structure targetStructure, Resource source) : base(unit, targetStructure.CenterPoint) { TargetStructure = targetStructure; Source = source; }
/*public MoveCommand(List<Vector2> wayPoints, int priority) { WayPoints = wayPoints; Priority = priority; } public MoveCommand(Vector2 wayPoint, int priority) { WayPoints = new List<Vector2>(); WayPoints.Add(wayPoint); Priority = priority; }*/ public MoveCommand(Unit unit, Vector2 destination) : base(unit) { this.destination = destination; WayPoints = new List<Vector2>(); WayPoints.Add(destination); }
public bool IsPointWalkable(Vector2 point, Unit unit) { /*float radius = unit.Radius; if (!IsPointWalkable(new Vector2(point.X - radius, point.Y - radius))) return false; if (!IsPointWalkable(new Vector2(point.X + radius, point.Y + radius))) return false; if (!IsPointWalkable(new Vector2(point.X + radius, point.Y - radius))) return false; if (!IsPointWalkable(new Vector2(point.X - radius, point.Y + radius))) return false; return true;*/ int y = (int)(point.Y / Map.TileSize); int x = (int)(point.X / Map.TileSize); //return IsTileWalkable((int)(point.Y / Map.TileSize), (int)(point.X / Map.TileSize), unit); return (!(y < 0 || y >= Map.Height || x < 0 || x >= Map.Width) && IsNodeWalkable(PathNodes[y, x], unit)); }
// for mouse position when giving commands public bool IsNodeWalkable(int tileY, int tileX, Unit unit) { if (!Map.Tiles[tileY, tileX].Walkable || PathNodes[tileY, tileX].Blocked) return false; Vector2 unitPosition = Map.Tiles[tileY, tileX].CenterPoint - new Vector2(unit.Radius, unit.Radius); int posX = (int)MathHelper.Clamp(unitPosition.X / Map.TileSize, 0, Map.Width - 1); int posY = (int)MathHelper.Clamp(unitPosition.Y / Map.TileSize, 0, Map.Height - 1); int rightBoundX = (int)MathHelper.Clamp(posX + (int)Math.Ceiling(unit.Width / (float)Map.TileSize), 0, Map.Width - 1) - 1; int bottomBoundY = (int)MathHelper.Clamp(posY + (int)Math.Ceiling(unit.Height / (float)Map.TileSize), 0, Map.Height - 1) - 1; for (int x = posX; x <= rightBoundX; x++) { for (int y = posY; y <= bottomBoundY; y++) { if (!Map.Tiles[y, x].Walkable || PathNodes[y, x].Blocked) return false; } } /*int howManyTilesToExpand = (int)(unit.Radius / (Map.TileSize + .01f)); int lowY = (int)MathHelper.Max(tileY - howManyTilesToExpand, 0); int lowX = (int)MathHelper.Max(tileX - howManyTilesToExpand, 0); int highY = (int)MathHelper.Min(tileY + howManyTilesToExpand, Map.Height); int highX = (int)MathHelper.Min(tileX + howManyTilesToExpand, Map.Width); for (int y = lowY; y <= highY; y++) { for (int x = lowX; x <= highX; x++) { if (!Map.Tiles[y, x].Walkable || PathNodes[y, x].Blocked) return false; } }*/ return true; }
public static void AddUnit(Unit u) { lock (Units) { units.Add(u); } lock (UnitsSorted) { unitsSorted.Add(u); } lock (RtsObject.RtsObjects) { RtsObject.AddObject(u); } }
// find nearest walkable path node (considers unit size) public PathNode FindNearestPathNode(int startY, int startX, Unit unit) { startX = (int)MathHelper.Clamp(startX, 0, Map.Width - 1); startY = (int)MathHelper.Clamp(startY, 0, Map.Height - 1); if (IsNodeWalkable(startY, startX, unit)) return PathNodes[startY, startX]; /*for (int i = 0; ; i++) { if (y - i >= 0) { if (IsTileWalkable(y - i, x, unit)) return PathNodes[y - i, x]; } if (y + i < Map.Height) { if (IsTileWalkable(y + i, x, unit)) return PathNodes[y + i, x]; } if (x - i >= 0) { if (IsTileWalkable(y, x - i, unit)) return PathNodes[y, x - i]; } if (x + i < Map.Width) { if (IsTileWalkable(y, x + i, unit)) return PathNodes[y, x + i]; } if (y - i >= 0 && x - i >= 0) { if (IsTileWalkable(y - i, x - i, unit)) return PathNodes[y - i, x - i]; } if (y - i >= 0 && x + i < Map.Width) { if (IsTileWalkable(y - i, x + i, unit)) return PathNodes[y - i, x + i]; } if (y + i < Map.Height && x - i >= 0) { if (IsTileWalkable(y + i, x - i, unit)) return PathNodes[y + i, x - i]; } if (y + i < Map.Height && x + i < Map.Width) { if (IsTileWalkable(y + i, x + i, unit)) return PathNodes[y + i, x + i]; } }*/ // searches outward from start node for walkable nodes List<PathNode> walkableNodes = new List<PathNode>(); for (int i = 1; ; i++) { for (int x = startX - i; x <= startX + i; x += i * 2) { if (x < 0 || x > Map.Width - 1) continue; for (int y = startY - i; y <= startY + i; y += i * 2) { if (y < 0 || y > Map.Height - 1) continue; if (IsNodeWalkable(y, x, unit)) //return PathNodes[y, x]; walkableNodes.Add(PathNodes[y, x]); } } if (walkableNodes.Count > 0) break; } // return discovered path node that is closest to unit float shortestDistanceToUnit = float.MaxValue; int shortestIndex = 0; for (int i = 0; i < walkableNodes.Count; i++) { float distance = Vector2.Distance(walkableNodes[i].Tile.CenterPoint, unit.CenterPoint); if (distance < shortestDistanceToUnit) { shortestDistanceToUnit = distance; shortestIndex = i; } } return walkableNodes[shortestIndex]; }
TownHall findNearestTownHall(Unit unit) { TownHall nearestTownHall = null; float nearest = int.MaxValue; foreach (TownHall townHall in TownHall.TownHalls) { if (townHall.Team != unit.Team || townHall.UnderConstruction) continue; float distance = Vector2.DistanceSquared(CenterPoint, townHall.CenterPoint); if (distance < nearest) { nearestTownHall = townHall; nearest = distance; } } return nearestTownHall; }
public void Push(Unit pusher, float angle, float force) { pushCount++; float angleX = (float)Math.Cos(angle); float angleY = (float)Math.Sin(angle); CenterPoint += new Vector2(force * angleX, force * angleY); HasMoved = true; checkForWallHit(null); //if (isFollowing) // return; //lock (PotentialCollisions) { foreach (Unit unit in PotentialCollisions) { if (!unit.IgnoringCollision && unit.pushCount < 1 && Intersects(unit)) { angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); //if (unit.Team != Team) // PushSimple(angle, force); //else if (unit.pushCount < 1) unit.Push(this, angle, force); //unit.Push(this, angle, force * .1f); //PushSimple(angle + (float)Math.PI, force * .9f); } } } }
public HarvestCommand(Unit unit, Resource targetResource) : base(unit, targetResource.CenterPoint) { TargetResource = targetResource; }
public StopCommand(Unit unit) : base(unit) { }
public HoldPositionCommand(Unit unit) : base(unit) { }
public AttackMoveCommand(Unit unit, Vector2 destination) : base(unit, destination) { }
public void NextWayPoint(Unit unit, PathFinder pathFinder) { WayPoints.RemoveAt(0); //pathFinder.SmoothImmediatePath(WayPoints, unit); }
public Farm(Point tilePosition, Unit builder, short team) : base(StructureType.Farm, tilePosition, builder, team) { }
// uses starting point (for rally points) /*public PathNode FindNearestPathNode(int startY, int startX, Vector2 startingPoint) { startX = (int)MathHelper.Clamp(startX, 0, Map.Width - 1); startY = (int)MathHelper.Clamp(startY, 0, Map.Height - 1); if (IsNodeWalkable(startY, startX, unit)) return PathNodes[startY, startX]; List<PathNode> walkableNodes = new List<PathNode>(); for (int i = 1; ; i++) { for (int x = startX - i; x <= startX + i; x += i*2) { if (x < 0 || x > Map.Width - 1) continue; for (int y = startY - i; y <= startY + i; y += i*2) { if (y < 0 || y > Map.Height - 1) continue; if (IsNodeWalkable(y, x, unit)) //return PathNodes[y, x]; walkableNodes.Add(PathNodes[y, x]); } } if (walkableNodes.Count > 0) break; } // return discovered path node that is closest to unit float shortestDistanceToUnit = float.MaxValue; int shortestIndex = 0; for (int i = 0; i < walkableNodes.Count; i++) { float distance = Vector2.Distance(walkableNodes[i].Tile.CenterPoint, unit.CenterPoint); if (distance < shortestDistanceToUnit) { shortestDistanceToUnit = distance; shortestIndex = i; } }*/ public bool IsStructureInLineOfSight(Unit unit, Structure structure) { float lerpAmountIncrement = 1f / ((int)(Vector2.Distance(unit.CenterPoint, structure.CenterPoint) / unit.Diameter) + 1); for (float l = lerpAmountIncrement; l < 1f; l += lerpAmountIncrement) //for (float l = 1f - lerpAmountIncrement; l > 0; l -= lerpAmountIncrement) { Vector2 intermediatePoint = Vector2.Lerp(unit.CenterPoint, structure.CenterPoint, l); //if (!IsPointWalkable(intermediatePoint, unit)) // return false; int y = (int)(intermediatePoint.Y / Map.TileSize); int x = (int)(intermediatePoint.X / Map.TileSize); //return IsTileWalkable((int)(point.Y / Map.TileSize), (int)(point.X / Map.TileSize), unit); if (y < 0 || y >= Map.Height || x < 0 || x >= Map.Width)// || !IsNodeWalkable(PathNodes[y, x], unit)) return false; if (!PathNodes[y, x].Tile.Walkable || (PathNodes[y, x].Blocked && PathNodes[y, x].Blocker != structure)) return false; } return true; }
public static void RemoveUnit(Unit u) { lock (Units) { units.Remove(u); } lock (UnitsSorted) { unitsSorted.Remove(u); } RtsObject.RemoveObject(u); }
protected UnitCommand(Unit unit) { Player.Players[unit.Team].UnitCommands.Add(this); ID = (short)(Player.Players[unit.Team].UnitCommands.Count - 1); //ID = Player.Players[unit.Team].CommandIDCounter++; Unit = unit; }
public void SmoothImmediatePath(List<Vector2> path, Unit unit, Vector2 beginLocation, bool queued) { if (path.Count < 2) return; // if path is for a queued command, insert beginLocation to beginning of path // otherwise path will be smoothed out of existence. not sure why if (queued) path.Insert(0, beginLocation); /*for (int i = path.Count - 1; i >= 1; i--) { if (Walkable(unit.CenterPoint, path[i], unit, (int)(Vector2.Distance(unit.CenterPoint, path[i]) / unit.Diameter))) { path.RemoveRange(0, i); break; } }*/ int count = 0; for (int i = 1; i < path.Count; i++) { if (Walkable(beginLocation, path[i], unit, (int)(Vector2.Distance(beginLocation, path[i]) / unit.Diameter))) { path.RemoveAt(i - 1); } else { if (++count == 5) return; } } /*for (int i = 0; i < path.Count; i++) { if (!Walkable(unit.CenterPoint, path[i], unit, (int)(Vector2.Distance(unit.CenterPoint, path[i]) / unit.Radius))) { if (i != 0) path.RemoveRange(0, i - 1); break; } }*/ /*for (int i = 0; i < path.Count - 1; ) { if (Walkable(unit.CenterPoint, path[i + 1], unit, (int)(Vector2.Distance(unit.CenterPoint, path[i + 1]) / unit.Radius) * 2)) { path.RemoveAt(i); } else break; }*/ }
public BuildStructureCommand(Unit unit, StructureType structureType, Point structureLocation, Vector2 moveDestination) : base(unit, moveDestination) { StructureType = structureType; StructureLocation = structureLocation; }
public void SmoothPath(List<Vector2> path, Unit unit) { if (path.Count < 2) return; /*int i; if (Walkable(unit.CenterPoint, path[0], unit, 2)) i = 0; else i = 1; for (; i < path.Count - 1; i++) { if (Walkable(path[i], path[i + 1], unit, 2)) { path.RemoveAt(i); i--; } else return; }*/ /*for (int i = 0; i < path.Count - 1; ) { if (Walkable(unit.CenterPoint, path[i + 1], unit, (int)(Vector2.Distance(unit.CenterPoint, path[i + 1]) / unit.Radius) * 2)) { path.RemoveAt(i); } else break; }*/ for (int i = 0; i < path.Count - 2; i++) { if (Walkable(path[i], path[i + 2], unit, (int)(Vector2.Distance(path[i], path[i + 2]) / unit.Diameter))) { path.RemoveAt(i + 1); i--; } } /*for (int i = path.Count - 1; i >= 2; i--) { if (Walkable(path[i], path[i - 2], unit, (int)(Vector2.Distance(path[i], path[i + 2]) / unit.Radius) * 2)) { path.RemoveAt(i - 1); i++; } }*/ }