void TryToFindAlternativeStartingTile() { _character.logger.Log(_character.name + " is not on a tile, will look for an alternative starting tile..."); // TODO Need a better method for finding a good point that is both close to the current position and in the general direction of the goal tile (which is not set yet) PointTileNode node = _character.room.FindClosestTile(_character.localPoint); //PointTileNode node = Randomizer.RandNth (_character.room.tiles); // ALTERNATIVE METHOD, NOT VERY GOOD if (node != null) { #if LOG _character.logger.Log("Found an alternative starting tile at " + node.worldPoint); #endif _startTileNode = node; } else { #if LOG _character.logger.Log("Found no alternative starting tile, it will be null (and no path will be found)"); #endif } }
static bool FindCloseAlternativeTile(Ting pTing, out PointTileNode tile) { var room = pTing.room; int x = pTing.localPoint.x; int y = pTing.localPoint.y; for (int dist = 1; dist < 20; dist++) { var north = room.GetTile(new IntPoint(x, y + 1)); var east = room.GetTile(new IntPoint(x + 1, y)); var south = room.GetTile(new IntPoint(x, y - 1)); var west = room.GetTile(new IntPoint(x - 1, y)); var tiles = new List <PointTileNode>() { north, east, south, west }; Shuffle(tiles); foreach (var t in tiles) { if (t != null && t.group > -1) { tile = t; return(true); } } } tile = new PointTileNode(IntPoint.Zero, pTing.room); return(false); }
public Path(PointTileNode[] pNodes, float pPathLength, PathStatus pStatus, int pPathSearchTestCount) { nodes = pNodes; pathLength = pPathLength; status = pStatus; pathSearchTestCount = pPathSearchTestCount; }
public void GetCurrentTile() { Ting t = _tingRunner.GetTing("Ting0"); PointTileNode n = t.tile; Assert.NotNull(n); Assert.AreEqual(t.localPoint, n.localPoint); }
public void GetTingOfTypeOnTile() { MyTing myTing = _tingRunner.CreateTing <MyTing>("MyTing", new WorldCoordinate(ROOM_NAME, new IntPoint(0, 0))); Room room = _roomRunner.GetRoom(ROOM_NAME); IntPoint p = new IntPoint(3, 3); myTing.position = new WorldCoordinate(ROOM_NAME, p); PointTileNode tileNode = room.GetTile(p); Assert.AreEqual(null, tileNode.GetOccupantOfType <WeirdTing>()); Assert.AreSame(myTing, tileNode.GetOccupantOfType <MyTing>()); }
public override void Init() { base.Init(); PointTileNode tileA = room.GetTile(interactionPoints[0]); PointTileNode tileB = room.GetTile(interactionPoints[1]); tileA.teleportTarget = tile; tileB.teleportTarget = tile; this.tile.RemoveAllLinks(); }
public void BasicUsage() { { RelayTwo relay = new RelayTwo(); relay.CreateTable(Room.TABLE_NAME); RoomRunner roomRunner = new RoomRunner(relay); foreach (string s in roomRunner.Preload()) ; Room r1 = roomRunner.CreateRoom<Room>("r1"); PointTileNode door1 = null; for(int i = 0; i < 100; i++) { int x = i % 10; int y = i / 10; if(x == 9 && y == 9) { door1 = new PointTileNode(new IntPoint(9, 9), r1); r1.AddTile(door1); } else { r1.AddTile(new PointTileNode(new IntPoint(x, y), r1 )); } } r1.worldPosition = new IntPoint(50, 0); relay.SaveAll("room_test.json"); } { RelayTwo relay = new RelayTwo("room_test.json"); RoomRunner roomRunner = new RoomRunner(relay); foreach (string s in roomRunner.Preload()) ; Room r1 = roomRunner.GetRoom("r1"); PointTileNode start = r1.GetTile(new IntPoint(0, 5)); PointTileNode goal = r1.GetTile(new IntPoint(9, 5)); D.isNull(start); D.isNull(goal); PathSolver pathSolver = new PathSolver(); Path path = pathSolver.FindPath(start, goal, roomRunner, true); Console.WriteLine("path resolved using " + path.pathSearchTestCount + " node tests"); Console.WriteLine("path tile count " + path.nodes.Length); Assert.AreEqual(PathStatus.FOUND_GOAL, path.status); } }
public void TingOccupyingATile() { IntPoint p = new IntPoint(5, 3); Ting t = _tingRunner.GetTing("Ting0"); t.position = new WorldCoordinate(ROOM_NAME, p); Room room = _roomRunner.GetRoom(ROOM_NAME); PointTileNode tileNode = room.GetTile(p); Ting[] occupants = tileNode.GetOccupants(); Assert.AreEqual(1, occupants.Length); Assert.AreSame(t, occupants[0]); }
World CreateWorldWithSomeRooms() { InitialSaveFileCreator isc = new InitialSaveFileCreator(); World world = new World(isc.CreateEmptyRelay()); SimpleRoomBuilder srb = new SimpleRoomBuilder(world.roomRunner); srb.CreateRoomWithSize("Eden", 10, 10); var middleRoom = srb.CreateRoomWithSize("MiddleRoom", 10, 10); var wrongRoom = srb.CreateRoomWithSize("WrongRoom", 10, 10); var distantRoom = srb.CreateRoomWithSize("DistantRoom", 10, 10); middleRoom.worldPosition = new IntPoint(10, 0); wrongRoom.worldPosition = new IntPoint(30, 0); distantRoom.worldPosition = new IntPoint(50, 0); // Add doors var edenDoor = world.tingRunner.CreateTing <Door>("edenDoor", new WorldCoordinate("Eden", new IntPoint(4, 4))); var middleRoomDoor1 = world.tingRunner.CreateTing <Door>("middleRoomDoor1", new WorldCoordinate("MiddleRoom", new IntPoint(2, 4))); var middleRoomDoor2 = world.tingRunner.CreateTing <Door>("middleRoomDoor2", new WorldCoordinate("MiddleRoom", new IntPoint(7, 4))); var middleRoomDoor3 = world.tingRunner.CreateTing <Door>("middleRoomDoor3", new WorldCoordinate("MiddleRoom", new IntPoint(4, 4))); var wrongRoomDoor = world.tingRunner.CreateTing <Door>("wrongRoomDoor", new WorldCoordinate("WrongRoom", new IntPoint(4, 4))); var distantRoomDoor = world.tingRunner.CreateTing <Door>("distantRoomDoor", new WorldCoordinate("DistantRoom", new IntPoint(2, 4))); edenDoor.targetDoorName = "middleRoomDoor1"; middleRoomDoor1.targetDoorName = "edenDoor"; middleRoomDoor2.targetDoorName = "distantRoomDoor"; middleRoomDoor3.targetDoorName = "wrongRoomDoor"; wrongRoomDoor.targetDoorName = "middleRoomDoor3"; distantRoomDoor.targetDoorName = "middleRoomDoor2"; var distantTile = new PointTileNode(new IntPoint(200, 200), wrongRoom); distantTile.group = 1; wrongRoom.AddTile(distantTile); var wrongRoomUnattachedDoor = world.tingRunner.CreateTing <Door>("wrongRoomUnattachedDoor", new WorldCoordinate("WrongRoom", new IntPoint(200, 200))); wrongRoomUnattachedDoor.targetDoorName = "edenDoor"; world.sourceCodeDispenser.CreateSourceCodeFromString("OnDoorUsed", ""); if (!world.isReadyToPlay) { foreach (string s in world.Preload()) { } } return(world); }
protected void FixGroupIfOutsideIslandOfTiles() { if (this.tile == null) { var newTile = new PointTileNode(localPoint, room); room.AddTile(newTile); #if CACHING this.SetCachedTile(); // the caching doesn't account for adding new tiles under an existing Ting #endif #if LOG_TILE_GROUP_FIX D.Log("Created tile at local point for " + name); #endif } for (int i = 0; i < interactionPoints.Length; i++) { PointTileNode tileAtInteractionPoint = room.GetTile(interactionPoints[i]); if (tileAtInteractionPoint == null) { #if LOG_TILE_GROUP_FIX D.Log("Tile at interaction point of " + name + " is null!"); #endif continue; } if (this.tile.group == -1 && tileAtInteractionPoint.group == -1) { throw new Exception("Both tile at position and tile at interaction point belong to group -1 for " + name); } if (this.tile.group != tileAtInteractionPoint.group) { this.tile.group = tileAtInteractionPoint.group; #if LOG_TILE_GROUP_FIX D.Log("Fixed the group of tile under " + name + " to " + tileAtInteractionPoint.group + ", got group from tile " + tileAtInteractionPoint + "(interaction point " + i + ") which has occupants: " + tileAtInteractionPoint.GetOccupantsAsString()); #endif break; // BREAK OUT, WE'RE DONE! } } }
void TryToFindAlternativeGoalTile() { #if LOG _character.logger.Log(_character.name + " has an invalid goal tile, will look for an alternative one close to target pos " + _character.targetPositionInRoom.localPosition); #endif PointTileNode node = _character.room.FindClosestFreeTile(_character.targetPositionInRoom.localPosition, _character.tileGroup); if (node != null) { #if LOG _character.logger.Log("Found an alternative goal tile at " + node.worldPoint); #endif _goalTileNode = node; } else { #if LOG _character.logger.Log("Found no alternative goal tile, it will be null (and no path will be found)"); #endif } }
public string API_Teleport(float x, float y) { if (IsAllowedToTeleport(_user as Character)) { WorldCoordinate coord = new WorldCoordinate(_user.room.name, (int)x, (int)y); PointTileNode tile = _user.room.GetTile(coord.localPosition); if (tile != null) { _user.position = coord; return("Success"); } else { return("Can't move there"); } } else { D.Log("Not allowed to teleport"); return("Not allowed"); } }
public void API_MoveToRoom(string roomName) { if (currentTrash == null) { Say("No current trash", ""); return; } currentTrash.isBeingHeld = false; var targetRoom = _roomRunner.GetRoomUnsafe(roomName); if (targetRoom == null) { throw new Error("Can't find a room called " + roomName); } var tilePoints = targetRoom.points; PointTileNode freeTileNode = null; foreach (var p in tilePoints) { var tile = targetRoom.GetTile(p); if (!tile.HasOccupants()) { freeTileNode = tile; break; } } if (freeTileNode != null) { currentTrash.position = freeTileNode.position; } else { Say("Can't throw away thing, " + roomName + " is full!", ""); } }
private void WriteTargetToTile() { D.isNull(room, "room is null"); D.isNull(_roomRunner, "room runner is null!"); PointTileNode tileAtInteractionPoint = room.GetTile(interactionPoints[0]); if (tileAtInteractionPoint == null) { return; } tileAtInteractionPoint.AddOccupant(this); if (targetPosition == WorldCoordinate.NONE) { tileAtInteractionPoint.teleportTarget = null; } else { tileAtInteractionPoint.teleportTarget = _roomRunner.GetRoom(targetPosition.roomName).GetTile(targetPosition.localPosition); } }
protected void FixGroupIfOutsideIslandOfTiles() { if(this.tile == null) { var newTile = new PointTileNode(localPoint, room); room.AddTile(newTile); #if CACHING this.SetCachedTile (); // the caching doesn't account for adding new tiles under an existing Ting #endif #if LOG_TILE_GROUP_FIX D.Log("Created tile at local point for " + name); #endif } for(int i = 0; i < interactionPoints.Length; i++) { PointTileNode tileAtInteractionPoint = room.GetTile(interactionPoints[i]); if(tileAtInteractionPoint == null) { #if LOG_TILE_GROUP_FIX D.Log("Tile at interaction point of " + name + " is null!"); #endif continue; } if(this.tile.group == -1 && tileAtInteractionPoint.group == -1) { throw new Exception("Both tile at position and tile at interaction point belong to group -1 for " + name); } if(this.tile.group != tileAtInteractionPoint.group) { this.tile.group = tileAtInteractionPoint.group; #if LOG_TILE_GROUP_FIX D.Log("Fixed the group of tile under " + name + " to " + tileAtInteractionPoint.group + ", got group from tile " + tileAtInteractionPoint + "(interaction point " + i + ") which has occupants: " + tileAtInteractionPoint.GetOccupantsAsString()); #endif break; // BREAK OUT, WE'RE DONE! } } }
public void TingChangesTileToOccupy() { Ting ting = _tingRunner.GetTing("Ting0"); Room room = _roomRunner.GetRoom(ROOM_NAME); IntPoint p1 = new IntPoint(2, 2); IntPoint p2 = new IntPoint(4, 4); PointTileNode tileNode1 = room.GetTile(p1); PointTileNode tileNode2 = room.GetTile(p2); Assert.AreEqual(0, tileNode1.GetOccupants().Length); Assert.AreEqual(0, tileNode2.GetOccupants().Length); ting.position = new WorldCoordinate(ROOM_NAME, p1); Assert.AreEqual(1, tileNode1.GetOccupants().Length); Assert.AreEqual(0, tileNode2.GetOccupants().Length); ting.position = new WorldCoordinate(ROOM_NAME, p2); Assert.AreEqual(0, tileNode1.GetOccupants().Length); Assert.AreEqual(1, tileNode2.GetOccupants().Length); }
private void ConnectNodes(PointTileNode pA, PointTileNode pB) { PathLink l = pB.GetLinkTo(pA); if (l == null) { l = new PathLink(pA, pB); l.distance = 1f; pA.AddLink(l); pB.AddLink(l); } }
private void AddTileLinks(PointTileNode tileNode) { PointTileNode start = tileNode; int x = start.localPoint.x; int y = start.localPoint.y; PointTileNode outputNode; if (_tilesByLocalPositionHash.TryGetValue(new IntPoint(x + 1, y).GetHashCode(), out outputNode)) { ConnectNodes(start, outputNode); } if (_tilesByLocalPositionHash.TryGetValue(new IntPoint(x - 1, y).GetHashCode(), out outputNode)) { ConnectNodes(start, outputNode); } if (_tilesByLocalPositionHash.TryGetValue(new IntPoint(x, y + 1).GetHashCode(), out outputNode)) { ConnectNodes(start, outputNode); } if (_tilesByLocalPositionHash.TryGetValue(new IntPoint(x, y - 1).GetHashCode(), out outputNode)) { ConnectNodes(start, outputNode); } }
public void SetTiles(IList<IntPoint> pPoints) { _tilesByLocalPositionHash.Clear(); foreach (IntPoint t in pPoints) { PointTileNode newNode = new PointTileNode(t, this); _tilesByLocalPositionHash.Add(newNode.localPoint.GetHashCode(), newNode); } ApplyTileData(); UpdateBounds(); }
public void AddTile(PointTileNode pTileNode) { #if DEBUG //Console.WriteLine("Called Room.AddTile() Warning, this is slow"); //. Callstack: " + Environment.StackTrace); #endif try { _tilesByLocalPositionHash.Add(pTileNode.localPoint.GetHashCode(), pTileNode); } catch (Exception e) { throw new Exception("Could not add tileNode at: " + pTileNode.localPoint.ToString() + " hashcode " + pTileNode.GetHashCode(), e); } AddTileLinks(pTileNode); RefreshTileData(); UpdateBounds(); }
void TryToFindAlternativeGoalTile() { #if LOG _character.logger.Log(_character.name + " has an invalid goal tile, will look for an alternative one close to target pos " + _character.targetPositionInRoom.localPosition); #endif PointTileNode node = _character.room.FindClosestFreeTile(_character.targetPositionInRoom.localPosition, _character.tileGroup); if(node != null) { #if LOG _character.logger.Log("Found an alternative goal tile at " + node.worldPoint); #endif _goalTileNode = node; } else { #if LOG _character.logger.Log("Found no alternative goal tile, it will be null (and no path will be found)"); #endif } }
public Path FindPath(PointTileNode pStart, PointTileNode pGoal, RoomRunner pNetwork, bool pReset) { #if DEBUG if(pNetwork == null) { throw new Exception("pNetwork is null"); } #endif if (pStart == null || pGoal == null) { return new Path(new PointTileNode[] {}, 0f, PathStatus.DESTINATION_UNREACHABLE, 0); } if (pStart == pGoal) { return new Path(new PointTileNode[] {}, 0f, PathStatus.ALREADY_THERE, 0); } int testCount = 0; if(pReset) { pNetwork.Reset(); } pStart.isStartNode = true; pGoal.isGoalNode = true; List<PointTileNode> resultNodeList = new List<PointTileNode>(); PointTileNode currentNode = pStart; PointTileNode goalNode = pGoal; currentNode.visited = true; currentNode.linkLeadingHere = null; AStarStack nodesToVisit = new AStarStack(); PathStatus pathResult = PathStatus.NOT_CALCULATED_YET; testCount = 1; while (pathResult == PathStatus.NOT_CALCULATED_YET) { foreach (PathLink l in currentNode.links) { PointTileNode otherNode = l.GetOtherNode(currentNode); if (!otherNode.visited) { TryQueueNewTile(otherNode, l, nodesToVisit, goalNode); } } if (nodesToVisit.Count == 0) { pathResult = PathStatus.DESTINATION_UNREACHABLE; } else { currentNode = nodesToVisit.Pop(); testCount++; #if LOG D.Log("testing new node: " + currentNode); #endif currentNode.visited = true; if (currentNode == goalNode) { pathResult = PathStatus.FOUND_GOAL; } } } // Path finished, collect float tLength = 0; if (pathResult == PathStatus.FOUND_GOAL) { tLength = currentNode.pathCostHere; while (currentNode != pStart) { resultNodeList.Add((PointTileNode)currentNode); currentNode = currentNode.linkLeadingHere.GetOtherNode(currentNode); } resultNodeList.Add((PointTileNode)currentNode); resultNodeList.Reverse(); } return new Path(resultNodeList.ToArray(), tLength, pathResult, testCount); }
World CreateWorldWithSomeRooms() { InitialSaveFileCreator isc = new InitialSaveFileCreator(); World world = new World(isc.CreateEmptyRelay()); SimpleRoomBuilder srb = new SimpleRoomBuilder(world.roomRunner); srb.CreateRoomWithSize("Eden", 10, 10); var middleRoom = srb.CreateRoomWithSize("MiddleRoom", 10, 10); var wrongRoom = srb.CreateRoomWithSize("WrongRoom", 10, 10); var distantRoom = srb.CreateRoomWithSize("DistantRoom", 10, 10); middleRoom.worldPosition = new IntPoint(10, 0); wrongRoom.worldPosition = new IntPoint(30, 0); distantRoom.worldPosition = new IntPoint(50, 0); // Add doors var edenDoor = world.tingRunner.CreateTing<Door>("edenDoor", new WorldCoordinate("Eden", new IntPoint(4, 4))); var middleRoomDoor1 = world.tingRunner.CreateTing<Door>("middleRoomDoor1", new WorldCoordinate("MiddleRoom", new IntPoint(2, 4))); var middleRoomDoor2 = world.tingRunner.CreateTing<Door>("middleRoomDoor2", new WorldCoordinate("MiddleRoom", new IntPoint(7, 4))); var middleRoomDoor3 = world.tingRunner.CreateTing<Door>("middleRoomDoor3", new WorldCoordinate("MiddleRoom", new IntPoint(4, 4))); var wrongRoomDoor = world.tingRunner.CreateTing<Door>("wrongRoomDoor", new WorldCoordinate("WrongRoom", new IntPoint(4, 4))); var distantRoomDoor = world.tingRunner.CreateTing<Door>("distantRoomDoor", new WorldCoordinate("DistantRoom", new IntPoint(2, 4))); edenDoor.targetDoorName = "middleRoomDoor1"; middleRoomDoor1.targetDoorName = "edenDoor"; middleRoomDoor2.targetDoorName = "distantRoomDoor"; middleRoomDoor3.targetDoorName = "wrongRoomDoor"; wrongRoomDoor.targetDoorName = "middleRoomDoor3"; distantRoomDoor.targetDoorName = "middleRoomDoor2"; var distantTile = new PointTileNode(new IntPoint(200, 200), wrongRoom); distantTile.group = 1; wrongRoom.AddTile(distantTile); var wrongRoomUnattachedDoor = world.tingRunner.CreateTing<Door>("wrongRoomUnattachedDoor", new WorldCoordinate("WrongRoom", new IntPoint(200, 200))); wrongRoomUnattachedDoor.targetDoorName = "edenDoor"; world.sourceCodeDispenser.CreateSourceCodeFromString ("OnDoorUsed", ""); if(!world.isReadyToPlay) { foreach (string s in world.Preload()) {} } return world; }
private void Move(float dt) { #if LOG && DEEP s_logger.Log("# Move"); #endif if (_tilePath.status == PathStatus.DESTINATION_UNREACHABLE) { #if LOG s_logger.Log("DESTINATION_UNREACHABLE, returning"); #endif return; } _character.walkTimer += _character.calculateFinalWalkSpeed() * dt; if (_character.walkTimer >= 1f) { _character.walkTimer = 0f; _character.walkIterator++; if (_tilePath.nodes == null) { #if LOG s_logger.Log("_tilePath.nodes == null"); #endif _character.CancelWalking(); return; } if (_character.walkIterator > _tilePath.nodes.Length - 1) { #if LOG s_logger.Log("Walk iterator > _path.nodes.Length"); #endif _character.CancelWalking(); return; } PointTileNode newNode = _tilePath.nodes[_character.walkIterator]; #if LOG if (newNode.HasOccupantsButIgnoreSomeTypes(notTrueObstacles)) { _character.logger.Log(_character.name + " is trying to move to a occupied tile (" + newNode.GetOccupantsAsString() + ") at " + newNode.position + ""); } #endif // Look ahead to final position when getting close to final position // TODO: THIS CODE IS PROBLEMATIC if (_character.walkIterator > _tilePath.nodes.Length - 7) { var lastNode = _tilePath.nodes[_tilePath.nodes.Length - 1]; var lastTile = _character.room.GetTile(lastNode.position.localPosition); if (lastTile.HasOccupants <Character>(_character)) { //D.Log("The object(s) " + lastTile.GetOccupantsAsString() + " is/are at the position where " + _character + " wanted to end up!"); _character.CancelWalking(); _character.timetableTimer = 1.0f; return; } } /* * int lookAheadIndex = Math.Min(_character.walkIterator + 4, _tilePath.nodes.Length - 1); * var lookAheadNode = _tilePath.nodes[lookAheadIndex]; * var lookAheadTile = _character.room.GetTile(lookAheadNode.position.localPosition); * if(lookAheadTile.HasOccupants<Character>(_character)) { * D.Log("Some character is at the position where " + _character + " wants to end up!"); * _character.CancelWalking(); * return; * } */ _character.direction = (newNode.localPoint - _character.localPoint).ToDirection(); _character.position = newNode.position; #if LOG && DEEP s_logger.Log("Reached new position: " + _character.position); #endif AnalyzeNewTile(); } }
public void Push(PointTileNode pNode) { _nodes[pNode.GetUniqueID()] = pNode; }
// Returns true on success private static bool GetClosestInteractionPoint(RoomRunner pRoomRunner, Room pRoom, PointTileNode pStartTile, IntPoint[] pPossiblePoints, out IntPoint closestPoint, Character pCharacter, bool pIgnoreCharacters) { D.isNull(pRoom, "pRoom is null"); D.isNull(pPossiblePoints, "possiblePoints is null"); if (pRoom != pCharacter.room) { throw new Exception("Error for " + pCharacter.name + "! Can only pathfind to closest interaction point in the same room: " + pCharacter.room.name + ", tried to do it in: " + pRoom.name); } closestPoint = IntPoint.Zero; float shortestDistance = float.MaxValue; bool foundSomething = false; #if LOG s_logger.Log("Trying to find closest interaction point for " + pCharacter + ", nr of possible points: " + pPossiblePoints.Length); #endif foreach(IntPoint p in pPossiblePoints) { PointTileNode tileNode = pRoom.GetTile(p); if(tileNode == null) { #if LOG s_logger.Log("Node at " + p + " was null, ignoring it"); #endif continue; } var ignoreList = notTrueObstacles; if (pIgnoreCharacters) { ignoreList = notTrueObstaclesIncludingCharacters; } if(tileNode.HasOccupantsButIgnoreSomeTypes(ignoreList)) { #if LOG s_logger.Log("Will ignore node at " + p + " since it has occupants: " + tileNode.GetOccupantsAsString()); #endif continue; } #if LOG s_logger.Log("Checking tile node " + tileNode); #endif pRoom.Reset(); var path = _tilePathSolver.FindPath(pStartTile, tileNode, pRoomRunner, false); #if LOG s_logger.Log("RESULT Path from " + pStartTile + " to " + tileNode + ": " + path.status); #endif //D.Log("RESULT Path from " + pStartTile + " to " + tileNode + ": " + path.status); D.isNull(path, "path is null"); if((path.status == PathStatus.FOUND_GOAL || path.status == PathStatus.ALREADY_THERE) && path.pathLength < shortestDistance) { closestPoint = p; shortestDistance = path.pathLength; foundSomething = true; } #if LOG s_logger.Log("path.status = " + path.status); #endif } if(!foundSomething) { #if LOG s_logger.Log(pCharacter + " at position " + pCharacter.position + " can't find an interaction point for final target " + pCharacter.finalTargetTing); #endif return false; } return true; }
void TryToFindAlternativeStartingTile() { _character.logger.Log(_character.name + " is not on a tile, will look for an alternative starting tile..."); // TODO Need a better method for finding a good point that is both close to the current position and in the general direction of the goal tile (which is not set yet) PointTileNode node = _character.room.FindClosestTile(_character.localPoint); //PointTileNode node = Randomizer.RandNth (_character.room.tiles); // ALTERNATIVE METHOD, NOT VERY GOOD if(node != null) { #if LOG _character.logger.Log("Found an alternative starting tile at " + node.worldPoint); #endif _startTileNode = node; } else { #if LOG _character.logger.Log("Found no alternative starting tile, it will be null (and no path will be found)"); #endif } }
public void BasicUsage() { { RelayTwo relay = new RelayTwo(); relay.CreateTable(Room.TABLE_NAME); RoomRunner roomRunner = new RoomRunner(relay); foreach (string s in roomRunner.Preload()) { ; } Room r1 = roomRunner.CreateRoom <Room>("r1"); Room r2 = roomRunner.CreateRoom <Room>("r2"); PointTileNode door1 = null; PointTileNode door2 = null; for (int i = 0; i < 100; i++) { int x = i % 10; int y = i / 10; if (x == 9 && y == 9) { door1 = new PointTileNode(new IntPoint(9, 9), r1); r1.AddTile(door1); } else { r1.AddTile(new PointTileNode(new IntPoint(x, y), r1)); } } for (int i = 0; i < 100; i++) { int x = i % 10; int y = i / 10; if (x == 0 && y == 0) { door2 = new PointTileNode(new IntPoint(0, 0), r2); r2.AddTile(door2); } else { r2.AddTile(new PointTileNode(new IntPoint(x, y), r2)); } } r1.worldPosition = new IntPoint(50, 0); door1.teleportTarget = door2; door2.teleportTarget = door1; relay.SaveAll("room_test.json"); } { RelayTwo relay = new RelayTwo("room_test.json"); RoomRunner roomRunner = new RoomRunner(relay); foreach (string s in roomRunner.Preload()) { ; } Room r1 = roomRunner.GetRoom("r1"); Room r2 = roomRunner.GetRoom("r2"); r1.GetTile(9, 9).teleportTarget = r2.GetTile(0, 0); r2.worldPosition = new IntPoint(0, 0); PointTileNode start = r1.GetTile(new IntPoint(0, 5)); PointTileNode goal = r2.GetTile(new IntPoint(9, 5)); D.isNull(start); D.isNull(goal); PathSolver <PointTileNode> pathSolver = new PathSolver <PointTileNode>(); Path <PointTileNode> path = pathSolver.FindPath(start, goal, roomRunner); Assert.AreEqual(PathStatus.FOUND_GOAL, path.status); Console.WriteLine("path resolved using " + path.pathSearchTestCount + " node tests"); Console.WriteLine("path tile count " + path.nodes.Length); } }
private void TryQueueNewTile(PointTileNode pNewNode, PathLink pLink, AStarStack pNodesToVisit, PointTileNode pGoal) { PointTileNode previousNode = pLink.GetOtherNode(pNewNode); float linkDistance = pLink.distance; float newPathCost = previousNode.pathCostHere + pNewNode.baseCost + linkDistance; if (pNewNode.linkLeadingHere == null || (pNewNode.pathCostHere > newPathCost)) { pNewNode.distanceToGoal = pNewNode.DistanceTo(pGoal) * 2f; pNewNode.pathCostHere = newPathCost; pNewNode.linkLeadingHere = pLink; pNodesToVisit.Push(pNewNode); } }
// Returns true on success private static bool GetClosestInteractionPoint(RoomRunner pRoomRunner, Room pRoom, PointTileNode pStartTile, IntPoint[] pPossiblePoints, out IntPoint closestPoint, Character pCharacter, bool pIgnoreCharacters) { D.isNull(pRoom, "pRoom is null"); D.isNull(pPossiblePoints, "possiblePoints is null"); if (pRoom != pCharacter.room) { throw new Exception("Error for " + pCharacter.name + "! Can only pathfind to closest interaction point in the same room: " + pCharacter.room.name + ", tried to do it in: " + pRoom.name); } closestPoint = IntPoint.Zero; float shortestDistance = float.MaxValue; bool foundSomething = false; #if LOG s_logger.Log("Trying to find closest interaction point for " + pCharacter + ", nr of possible points: " + pPossiblePoints.Length); #endif foreach (IntPoint p in pPossiblePoints) { PointTileNode tileNode = pRoom.GetTile(p); if (tileNode == null) { #if LOG s_logger.Log("Node at " + p + " was null, ignoring it"); #endif continue; } var ignoreList = notTrueObstacles; if (pIgnoreCharacters) { ignoreList = notTrueObstaclesIncludingCharacters; } if (tileNode.HasOccupantsButIgnoreSomeTypes(ignoreList)) { #if LOG s_logger.Log("Will ignore node at " + p + " since it has occupants: " + tileNode.GetOccupantsAsString()); #endif continue; } #if LOG s_logger.Log("Checking tile node " + tileNode); #endif pRoom.Reset(); var path = _tilePathSolver.FindPath(pStartTile, tileNode, pRoomRunner, false); #if LOG s_logger.Log("RESULT Path from " + pStartTile + " to " + tileNode + ": " + path.status); #endif //D.Log("RESULT Path from " + pStartTile + " to " + tileNode + ": " + path.status); D.isNull(path, "path is null"); if ((path.status == PathStatus.FOUND_GOAL || path.status == PathStatus.ALREADY_THERE) && path.pathLength < shortestDistance) { closestPoint = p; shortestDistance = path.pathLength; foundSomething = true; } #if LOG s_logger.Log("path.status = " + path.status); #endif } if (!foundSomething) { #if LOG s_logger.Log(pCharacter + " at position " + pCharacter.position + " can't find an interaction point for final target " + pCharacter.finalTargetTing); #endif return(false); } return(true); }
// Returns true if the character should start walking again private bool TilePathfindToTargetPositionInRoom() { #if PROFILE Stopwatch sw = new Stopwatch(); sw.Start(); #endif _tilePath = Path.EMPTY; _startTileNode = _character.tile; if (_startTileNode == null) { TryToFindAlternativeStartingTile(); if (_startTileNode != null) { //D.Log (_character + " has no start tile, will set his pos to alternative start tile " + _startTileNode); _character.StartAction("", null, 0f, 0f); _character.position = _startTileNode.position; } else { //D.Log (_character + " has no start tile but didn't find alternative start tile"); } } Room finalRoom = _roomRunner.GetRoom(_character.finalTargetPosition.roomName); if (_character.room == finalRoom) { if (_character.finalTargetTing != null) { // Try to go to the closest interaction point instead of straight to the actual ting position // (which will lead to an error) #if LOG s_logger.Log(_character + " with timetable " + _character.timetable + " will tilepathfind to closest interaction point of " + _character.finalTargetTing + " at position " + _character.finalTargetTing.position); #endif bool ignoreCharacters = (_character.finalTargetTing is Door || _character.finalTargetTing is Portal); IntPoint closestInteractionPoint; if (_character.finalTargetTing.interactionPointsTryTheseFirst != null && GetClosestInteractionPoint(_roomRunner, finalRoom, _character.tile, _character.finalTargetTing.interactionPointsTryTheseFirst, out closestInteractionPoint, _character, ignoreCharacters)) { _character.finalTargetPosition = new WorldCoordinate(_character.finalTargetPosition.roomName, closestInteractionPoint); #if LOG s_logger.Log("Found a closest target position for " + _character.name + ": " + _character.finalTargetPosition); #endif } else if (GetClosestInteractionPoint(_roomRunner, finalRoom, _character.tile, _character.finalTargetTing.interactionPoints, out closestInteractionPoint, _character, ignoreCharacters)) { _character.finalTargetPosition = new WorldCoordinate(_character.finalTargetPosition.roomName, closestInteractionPoint); #if LOG s_logger.Log("Found a closest target position B for " + _character.name + ": " + _character.finalTargetPosition); #endif } else { //Console.WriteLine(_character.name + " can't find closest target position for ting " + _character.finalTargetTing + " at pos " + _character.finalTargetTing.position); _character.CancelWalking(); _character.timetableTimer = Randomizer.GetValue(5.0f, 10.0f); // how long to wait? (used to be 0) return(false); } } // The target in the room should be the same as the final target position _character.targetPositionInRoom = _character.finalTargetPosition; } else { // In this case the target position in the room should be already set by MimanPathfinding } _goalTileNode = _character.room.GetTile(_character.targetPositionInRoom.localPosition); if (_goalTileNode == null) { TryToFindAlternativeGoalTile(); } if (_goalTileNode == null) { #if LOG s_logger.Log("Tilepathfinding for " + _character.name + " failed, can't find a goal tile node"); #endif return(false); } if (_startTileNode.group > -1 && _goalTileNode.group > -1 && _startTileNode.group != _goalTileNode.group) { _character.CancelWalking(); _character.timetableTimer = Randomizer.GetValue(5.0f, 10.0f); // how long to wait? (used to be 0) #if LOG s_logger.Log("Tilepathfinding for " + _character.name + " failed, startTileNode at " + _startTileNode.position + " has group " + _startTileNode.group + " while _goalTileNode at " + _goalTileNode.position + " has group " + _goalTileNode.group); #endif return(false); } /* * if(_character.HasRecentlyMadeAFailedPathFindingSearch(_startTileNode, _goalTileNode)) { * _character.logger.Log(_character.name + " will not pathfind; has recently made a failed path finding search between " + _character.tile + " and " + _goalTileNode); * _character.CancelWalking(); * return false; * } */ #if LOG s_logger.Log(_character.name + " will pathfind from " + _character.tile + " to " + _goalTileNode); #endif _character.room.Reset(); _tilePath = _tilePathSolver.FindPath(_startTileNode, _goalTileNode, _roomRunner, false); foreach (var tilePathNode in _tilePath.nodes) { Fence fence = tilePathNode.GetOccupantOfType <Fence>(); if (fence != null) { //s_logger.Log("There is a Fence on the path of " + _character + ", will interact with that instead"); _character.CancelWalking(); _character.WalkToTingAndInteract(fence); return(false); } } #if LOG s_logger.Log("Tile path solve from " + _startTileNode + " to " + _goalTileNode + ": " + _tilePath.status); // + ", PATH NODES " + _tilePath); #endif #if PROFILE sw.Stop(); if (sw.Elapsed.TotalSeconds > 0.001f) { D.Log("TilePathFinding for " + _character + " from " + _startTileNode + " to " + _goalTileNode + " took " + sw.Elapsed.TotalSeconds + " s."); } #endif if (_tilePath.status == PathStatus.DESTINATION_UNREACHABLE) { #if LOG s_logger.Log("The destination was unreachable so we'll register it and cancel walking"); #endif //_character.RegisterFailedPathFindingSearch(_startTileNode, _goalTileNode); #if LOG s_logger.Log(_character.name + ": The destination " + _goalTileNode.position + " was unreachable from " + _startTileNode.position); #endif //_character.CancelWalking(); return(false); } else if (_tilePath.status == PathStatus.ALREADY_THERE) { #if LOG s_logger.Log("Already there, analyze tile"); #endif AnalyzeNewTile(); return(false); } else if (_tilePath.status == PathStatus.FOUND_GOAL) { #if LOG s_logger.Log("Found goal at " + _goalTileNode); s_logger.Log("Path for " + _character + ": " + string.Join(", ", _tilePath.nodes.Select(t => t.ToString()).ToArray())); #endif return(true); } else { #if LOG s_logger.Log("This case should really not happen"); #endif } return(false); }
// Returns true if the character should start walking again private bool TilePathfindToTargetPositionInRoom() { #if PROFILE Stopwatch sw = new Stopwatch(); sw.Start(); #endif _tilePath = Path.EMPTY; _startTileNode = _character.tile; if(_startTileNode == null) { TryToFindAlternativeStartingTile(); if (_startTileNode != null) { //D.Log (_character + " has no start tile, will set his pos to alternative start tile " + _startTileNode); _character.StartAction ("", null, 0f, 0f); _character.position = _startTileNode.position; } else { //D.Log (_character + " has no start tile but didn't find alternative start tile"); } } Room finalRoom = _roomRunner.GetRoom(_character.finalTargetPosition.roomName); if (_character.room == finalRoom) { if (_character.finalTargetTing != null) { // Try to go to the closest interaction point instead of straight to the actual ting position // (which will lead to an error) #if LOG s_logger.Log(_character + " with timetable " + _character.timetable + " will tilepathfind to closest interaction point of " + _character.finalTargetTing + " at position " + _character.finalTargetTing.position); #endif bool ignoreCharacters = (_character.finalTargetTing is Door || _character.finalTargetTing is Portal); IntPoint closestInteractionPoint; if (_character.finalTargetTing.interactionPointsTryTheseFirst != null && GetClosestInteractionPoint(_roomRunner, finalRoom, _character.tile, _character.finalTargetTing.interactionPointsTryTheseFirst, out closestInteractionPoint, _character, ignoreCharacters)) { _character.finalTargetPosition = new WorldCoordinate(_character.finalTargetPosition.roomName, closestInteractionPoint); #if LOG s_logger.Log("Found a closest target position for " + _character.name + ": " + _character.finalTargetPosition); #endif } else if (GetClosestInteractionPoint(_roomRunner, finalRoom, _character.tile, _character.finalTargetTing.interactionPoints, out closestInteractionPoint, _character, ignoreCharacters)) { _character.finalTargetPosition = new WorldCoordinate(_character.finalTargetPosition.roomName, closestInteractionPoint); #if LOG s_logger.Log("Found a closest target position B for " + _character.name + ": " + _character.finalTargetPosition); #endif } else { //Console.WriteLine(_character.name + " can't find closest target position for ting " + _character.finalTargetTing + " at pos " + _character.finalTargetTing.position); _character.CancelWalking (); _character.timetableTimer = Randomizer.GetValue(5.0f, 10.0f); // how long to wait? (used to be 0) return false; } } // The target in the room should be the same as the final target position _character.targetPositionInRoom = _character.finalTargetPosition; } else { // In this case the target position in the room should be already set by MimanPathfinding } _goalTileNode = _character.room.GetTile(_character.targetPositionInRoom.localPosition); if(_goalTileNode == null) { TryToFindAlternativeGoalTile(); } if (_goalTileNode == null) { #if LOG s_logger.Log ("Tilepathfinding for " + _character.name + " failed, can't find a goal tile node"); #endif return false; } if(_startTileNode.group > -1 && _goalTileNode.group > -1 && _startTileNode.group != _goalTileNode.group) { _character.CancelWalking (); _character.timetableTimer = Randomizer.GetValue(5.0f, 10.0f); // how long to wait? (used to be 0) #if LOG s_logger.Log("Tilepathfinding for " + _character.name + " failed, startTileNode at " + _startTileNode.position + " has group " + _startTileNode.group + " while _goalTileNode at " + _goalTileNode.position + " has group " + _goalTileNode.group); #endif return false; } /* if(_character.HasRecentlyMadeAFailedPathFindingSearch(_startTileNode, _goalTileNode)) { _character.logger.Log(_character.name + " will not pathfind; has recently made a failed path finding search between " + _character.tile + " and " + _goalTileNode); _character.CancelWalking(); return false; } */ #if LOG s_logger.Log(_character.name + " will pathfind from " + _character.tile + " to " + _goalTileNode); #endif _character.room.Reset(); _tilePath = _tilePathSolver.FindPath(_startTileNode, _goalTileNode, _roomRunner, false); foreach(var tilePathNode in _tilePath.nodes) { Fence fence = tilePathNode.GetOccupantOfType<Fence>(); if(fence != null) { //s_logger.Log("There is a Fence on the path of " + _character + ", will interact with that instead"); _character.CancelWalking (); _character.WalkToTingAndInteract(fence); return false; } } #if LOG s_logger.Log("Tile path solve from " + _startTileNode + " to " + _goalTileNode + ": " + _tilePath.status); // + ", PATH NODES " + _tilePath); #endif #if PROFILE sw.Stop(); if(sw.Elapsed.TotalSeconds > 0.001f) { D.Log("TilePathFinding for " + _character + " from " + _startTileNode + " to " + _goalTileNode + " took " + sw.Elapsed.TotalSeconds + " s."); } #endif if(_tilePath.status == PathStatus.DESTINATION_UNREACHABLE) { #if LOG s_logger.Log("The destination was unreachable so we'll register it and cancel walking"); #endif //_character.RegisterFailedPathFindingSearch(_startTileNode, _goalTileNode); #if LOG s_logger.Log(_character.name + ": The destination " + _goalTileNode.position + " was unreachable from " + _startTileNode.position); #endif //_character.CancelWalking(); return false; } else if(_tilePath.status == PathStatus.ALREADY_THERE) { #if LOG s_logger.Log("Already there, analyze tile"); #endif AnalyzeNewTile(); return false; } else if(_tilePath.status == PathStatus.FOUND_GOAL) { #if LOG s_logger.Log("Found goal at " + _goalTileNode); s_logger.Log("Path for " + _character + ": " + string.Join(", ", _tilePath.nodes.Select(t => t.ToString()).ToArray())); #endif return true; } else { #if LOG s_logger.Log("This case should really not happen"); #endif } return false; }