public static int DistanceBetweenEntities(Entity a, Entity b) { var aPos = a.TryGetPosition(); var bPos = b.TryGetPosition(); return(ArenaState.DistanceBetweenPositions(aPos.X, aPos.Y, bPos.X, bPos.Y)); }
private void HandleAttack(GameEvent_PrepareAttack ev) { if (ev.ExecutorEntity == this.Parent) { // If it's out of range, then the attack misses int weaponRange = ev.ExecutorEntity.TryGetAttribute(EntityAttributeType.MAX_RANGE, ev.ExecutorEntity) .Value; int distance = ArenaState.DistanceBetweenEntities(ev.Target, ev.CommandEntity); if (distance > weaponRange) { ev.RegisterResult("MISS (out of range)"); return; } // TODO: This sequence of early exists is crufty because there's a lot of "before-exit-do" stuff here! // If any of the cells isn't walkable, then your shot is blocked and the attack stops var targetPos = ev.Target.TryGetPosition(); var attackerPos = ev.CommandEntity.TryGetPosition(); var lineCells = ev.GameMap.GetCellsAlongLine(attackerPos.X, attackerPos.Y, targetPos.X, targetPos.Y); if (lineCells.Any(c => !c.IsWalkable)) { ev.RegisterResult("MISS (no straight shot)"); return; } // Forward the attack to the target var receiveAttack = new GameEvent_ReceiveAttack(ev); ev.Target.HandleEvent(receiveAttack); if (!receiveAttack.Completed) { Log.DebugLine("Could not resolve attack against " + ev.Target.ToString()); } } }
private static bool InScanRangeOfPlayer(Entity player, Entity aiEntity, Cell possiblePosition) { var scanRange = aiEntity.TryGetAttribute(EntityAttributeType.SCAN_REQUIRED_RADIUS).Value; var playerPos = player.TryGetPosition(); var dist = ArenaState.DistanceBetweenPositions(playerPos.X, playerPos.Y, possiblePosition.X, possiblePosition.Y); return(dist <= scanRange); }
public static ArenaState TestArena(Entity baseMech1, Entity baseMech2) { var arenaMap = Map.Create(new RogueSharp.MapCreation.BorderOnlyMapCreationStrategy <Map>(15, 15)); var mapEntities = new List <Entity>() { baseMech1, baseMech2 }; ArenaState arena = new ArenaState(mapEntities, "test", arenaMap, new PathFinder(arenaMap), 0); arena.PlaceEntityNear(baseMech1, 5, 5); arena.PlaceEntityNear(baseMech2, 10, 10); return(arena); }
public void DeterminePatrolPath(ArenaState state, IRandom rand) { this.PatrolStart = this.Parent.TryGetPosition(); var cells = state.WalkableCells(); Cell cell = rand.RandomElement(cells); while (Config.MinPatrolDistance < ArenaState.DistanceBetweenPositions(this.PatrolStart.X, this.PatrolStart.Y, cell.X, cell.Y)) { cell = rand.RandomElement(cells); } var endPos = new GameQuery_Position(); endPos.RegisterPosition(cell.X, cell.Y, false); this.PatrolEnd = endPos; }
private void HandleQueryCommand(GameQuery_Command q) { if (this.Alerted) { this.activeBook.TryRegisterCommand(q); } else if (ArenaState.DistanceBetweenEntities(this.Parent, q.ArenaState.Player) <= this.Parent.TryGetAttribute(EntityAttributeType.DETECTION_RADIUS).Value) { q.ArenaState.AlertAllAIs(); } else { var myPos = this.Parent.TryGetPosition(); if (myPos.X == this.PatrolStart.X && myPos.Y == this.PatrolStart.Y) { this.OnReturnLeg = false; } else if (myPos.X == this.PatrolEnd.X && myPos.Y == this.PatrolEnd.Y) { this.OnReturnLeg = true; } Cell myCell = q.ArenaState.ArenaMap.GetCell(myPos.X, myPos.Y); Path patrolPath; if (!this.OnReturnLeg) { patrolPath = q.ArenaState.ShortestPath(myCell, this.PositionToCell(this.PatrolEnd, q.ArenaState)); } else { patrolPath = q.ArenaState.ShortestPath(myCell, this.PositionToCell(this.PatrolStart, q.ArenaState)); } if (patrolPath != null) { q.RegisterCommand(this.MoveEventForPath(q, patrolPath)); } else { q.RegisterCommand(new CommandStub_Delay(this.Parent.EntityID, Config.ONE)); } } }
private static ArenaState BuildArena(int width, int height, string mapID, IEnumerable <Entity> entities, int level) { if (!seedsToMaps.ContainsKey(mapID)) { var map = Map.Create(new RogueSharp.MapCreation.RandomRoomsMapCreationStrategy <Map>(width, height, 2000, 9, 5, new DotNetRandom(Int32.Parse(mapID)))); var pathFinder = new PathFinder(map); seedsToMaps[mapID] = new Tuple <IMap, PathFinder>(map, pathFinder); } var mapEntities = new List <Entity>(); foreach (var e in entities) { mapEntities.Add(e.DeepCopy()); } ArenaState arena = new ArenaState(mapEntities, mapID, seedsToMaps[mapID].Item1, seedsToMaps[mapID].Item2, level); var openCells = arena.ArenaMap.GetAllCells().Where(c => c.IsWalkable).ToList(); var placementRand = new DotNetRandom(Int32.Parse(mapID)); foreach (var e in mapEntities) { while (!e.HasComponentOfType <Component_Position>()) { var cell = openCells[placementRand.Next(openCells.Count - 1)]; Component_AI ai = e.GetComponentOfType <Component_AI>(); if (ai != null && !ArenaBuilder.InScanRangeOfPlayer(arena.Player, e, cell)) { arena.PlaceEntityNear(e, cell.X, cell.Y); ai.DeterminePatrolPath(arena, placementRand); } else if (ai == null) { arena.PlaceEntityNear(e, cell.X, cell.Y); } } } return(arena); }
// TODO: Whoops, I designed the stubs badly. I should swap the resolution function to the stub classes. public void ResolveStub(CommandStub stub) { var gameEvent = stub.ReifyStub(this); if (gameEvent != null && gameEvent.CommandEntity == this.nextCommandEntity) { gameEvent.CommandEntity.HandleEvent(gameEvent); if (gameEvent.ShouldLog) { this.ArenaLog.Add(gameEvent.LogMessage); } this.executedCommands.Add(gameEvent); } else if (gameEvent != null) { Log.ErrorLine("Can't resolve stub " + stub + " against entity " + gameEvent.CommandEntity + " as next Entity is " + this.nextCommandEntity); } else { throw new NullReferenceException("Stub " + stub + " reified to null; instead, return a delay!"); } // Hacky if (this.nextCommandEntity == this.Player) { foreach (var ai in this.mapEntities.Where(e => e.HasComponentOfType <Component_AI>())) { if (!ai.GetComponentOfType <Component_AI>().Scanned&& ArenaState.DistanceBetweenEntities(this.Player, ai) <= ai.TryGetAttribute(EntityAttributeType.SCAN_REQUIRED_RADIUS).Value) { ai.GetComponentOfType <Component_AI>().Scanned = true; this.ArenaLog.Add("Scanned " + ai.Label + "!"); } } } this.ForwardToNextAction(); }
public CellInfo AlertCells(ArenaState arena) { var info = new CellInfo(); var scanRadius = this.Parent.TryGetAttribute(EntityAttributeType.SCAN_REQUIRED_RADIUS).Value; var detectRadius = this.Parent.TryGetAttribute(EntityAttributeType.DETECTION_RADIUS).Value; var myPosition = this.Parent.TryGetPosition(); for (int x = -scanRadius; x <= scanRadius; ++x) { for (int y = -scanRadius; y <= scanRadius; ++y) { var d = (int)Math.Floor(Math.Sqrt(x * x + y * y)); int mx = myPosition.X + x; int my = myPosition.Y + y; Cell cell = null; if (mx >= 0 && my >= 0 && mx < arena.ArenaMap.Width && my < arena.ArenaMap.Height) { cell = arena.ArenaMap.GetCell(myPosition.X + x, myPosition.Y + y); } if (cell != null && d <= detectRadius && !this.Alerted) { if (cell.IsWalkable) { info.AlertCells.Add(cell); } } else if (!this.Scanned && cell != null && d <= scanRadius) { if (cell.IsWalkable) { info.ScanCells.Add(cell); } } } } return(info); }
private Cell PositionToCell(GameQuery_Position pos, ArenaState arena) { return(arena.ArenaMap.GetCell(pos.X, pos.Y)); }