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
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
 public Path(PointTileNode[] pNodes, float pPathLength, PathStatus pStatus, int pPathSearchTestCount)
 {
     nodes = pNodes;
     pathLength = pPathLength;
     status = pStatus;
     pathSearchTestCount = pPathSearchTestCount;
 }
Beispiel #4
0
        public void GetCurrentTile()
        {
            Ting          t = _tingRunner.GetTing("Ting0");
            PointTileNode n = t.tile;

            Assert.NotNull(n);
            Assert.AreEqual(t.localPoint, n.localPoint);
        }
Beispiel #5
0
        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>());
        }
Beispiel #6
0
        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();
        }
Beispiel #7
0
		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);
			}
		}
Beispiel #8
0
        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]);
        }
Beispiel #9
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);
        }
Beispiel #10
0
        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
            }
        }
Beispiel #12
0
 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");
     }
 }
Beispiel #13
0
        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!", "");
            }
        }
Beispiel #14
0
        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);
            }
        }
Beispiel #15
0
		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! 
				}
			}
		}
Beispiel #16
0
        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);
        }
Beispiel #17
0
 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);
     }
 }
Beispiel #18
0
        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);
            }
        }
Beispiel #19
0
 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();
 }
Beispiel #20
0
 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
            }
        }
Beispiel #22
0
        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();
            }
        }
Beispiel #25
0
 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
            }
        }
Beispiel #28
0
        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);
            }
        }
Beispiel #29
0
        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;
        }