Beispiel #1
0
        public void CreateRoomsWithDuplicateNames()
        {
            RelayTwo relay = new RelayTwo();

            relay.CreateTable(Room.TABLE_NAME);
            RoomRunner roomRunner = new RoomRunner(relay);

            roomRunner.CreateRoom <Room>("Hallway");
            Assert.Throws <TingTingException>(() => {
                roomRunner.CreateRoom <Room>("Hallway");
            });
        }
Beispiel #2
0
        TingRunner CreateTingRunnerWithSomeRoom()
        {
            relay = new RelayTwo();
            relay.CreateTable(Ting.TABLE_NAME);
            relay.CreateTable(Room.TABLE_NAME);
            RoomRunner rr = new RoomRunner(relay);

            rr.CreateRoom <Room>("SomeRoom");
            TingRunner tingRunner = new TingRunner(relay, rr);

            return(tingRunner);
        }
Beispiel #3
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 #4
0
        public void Setup()
        {
            _relay = new RelayTwo();
            _table = _relay.CreateTable(Ting.TABLE_NAME);
            _relay.CreateTable(Room.TABLE_NAME);
            _roomRunner = new RoomRunner(_relay);
            Room room = _roomRunner.CreateRoom<Room>(ROOM_NAME);

            for (int i = 0; i < 100; i++)
            {
                room.AddTile(new PointTileNode(new IntPoint(i % 10, i / 10), room));
            }

            _tingRunner = new TingRunner(_relay, _roomRunner);
            _tingRunner.CreateTing<MyTing>("Ting0", new WorldCoordinate(ROOM_NAME, new IntPoint(0, 0)));
            _tingRunner.CreateTing<MyTing>("Ting1", new WorldCoordinate(ROOM_NAME, new IntPoint(1, 0)));
        }
Beispiel #5
0
 private void Init(RelayTwo pRelay)
 {
     paused              = false;
     isReadyToPlay       = false;
     relay               = pRelay;
     dialogueRunner      = new DialogueRunner(relay, Language.DEFAULT);
     roomRunner          = new RoomRunner(relay);
     programRunner       = new ProgramRunner(relay);
     sourceCodeDispenser = new SourceCodeDispenser(relay);
     timetableRunner     = new TimetableRunner(relay);
     settings            = new WorldSettings(relay);
     tingRunner          = new MimanTingRunner(relay, dialogueRunner, programRunner, sourceCodeDispenser, roomRunner, timetableRunner, settings);
     grimmApiDefinitions = new MimanGrimmApiDefinitions(this);
     grimmApiDefinitions.RegisterFunctions();
     grimmApiDefinitions.RegisterExpressions();
     translator = new Translator(Translator.Language.SWEDISH);
 }
Beispiel #6
0
        public void Setup()
        {
            _relay = new RelayTwo();
            _table = _relay.CreateTable(Ting.TABLE_NAME);
            _relay.CreateTable(Room.TABLE_NAME);
            _roomRunner = new RoomRunner(_relay);
            Room room = _roomRunner.CreateRoom <Room>(ROOM_NAME);

            for (int i = 0; i < 100; i++)
            {
                room.AddTile(new PointTileNode(new IntPoint(i % 10, i / 10), room));
            }

            _tingRunner = new TingRunner(_relay, _roomRunner);
            _tingRunner.CreateTing <MyTing>("Ting0", new WorldCoordinate(ROOM_NAME, new IntPoint(0, 0)));
            _tingRunner.CreateTing <MyTing>("Ting1", new WorldCoordinate(ROOM_NAME, new IntPoint(1, 0)));
        }
Beispiel #7
0
		private void Init(RelayTwo pRelay)
        {
			paused = false;
			isReadyToPlay = false;
			relay = pRelay;
			dialogueRunner = new DialogueRunner(relay, Language.DEFAULT);
			roomRunner = new RoomRunner(relay);
			programRunner = new ProgramRunner(relay);
			sourceCodeDispenser = new SourceCodeDispenser(relay);
			timetableRunner = new TimetableRunner(relay);
			settings = new WorldSettings(relay);
            tingRunner = new MimanTingRunner(relay, dialogueRunner, programRunner, sourceCodeDispenser, roomRunner, timetableRunner, settings);
			grimmApiDefinitions = new MimanGrimmApiDefinitions(this);
			grimmApiDefinitions.RegisterFunctions();
			grimmApiDefinitions.RegisterExpressions();
			translator = new Translator (Translator.Language.SWEDISH);
		}
Beispiel #8
0
		public void CreatingEmptyRoom()
		{
			string saveName = "MyEmptyRoomSave.json";
			{
				RelayTwo relay = new RelayTwo();
				relay.CreateTable(Room.TABLE_NAME);
				RoomRunner roomRunner = new RoomRunner(relay);
				roomRunner.CreateRoom<Room>("MyRoom");
				relay.SaveAll(saveName);
			}
			{
				RelayTwo relay = new RelayTwo(saveName);
				RoomRunner roomRunner = new RoomRunner(relay);
				Room room = roomRunner.GetRoom("MyRoom");
				Assert.IsNotNull(room);
				Assert.AreEqual("MyRoom", room.name);
				Assert.AreEqual(new PointTileNode[] {}, room.tiles);
			}
		}
Beispiel #9
0
        public MimanTingRunner(
            RelayTwo pRelay,
            DialogueRunner pDialogueRunner,
            ProgramRunner pProgramRunner,
            SourceCodeDispenser pSourceCodeDispenser,
            RoomRunner pRoomRunner,
            TimetableRunner pTimetableRunner,
            WorldSettings pWorldSettings
            )
            : base(pRelay, pRoomRunner)
        {
            _dialogueRunner = pDialogueRunner;
            _dialogueRunner.AddOnSomeoneSaidSomethingListener(this.OnSomeoneSaidSomething);
            _programRunner       = pProgramRunner;
            _sourceCodeDispenser = pSourceCodeDispenser;
            _timetableRunner     = pTimetableRunner;
            _worldSettings       = pWorldSettings;

            foreach (Ting ting in _tings.Values)
            {
                if (ting is MimanTing)
                {
                    (ting as MimanTing).SetMimanRunners(_programRunner, _sourceCodeDispenser, _dialogueRunner, _worldSettings);
                }
                if (ting is Character)
                {
                    (ting as Character).SetTimetableRunner(_timetableRunner);
                }
            }

            foreach (Ting ting in _tings.Values)
            {
                if (ting is MimanTing)
                {
                    var mimanTing = ting as MimanTing;
                    mimanTing.Init();
                    if (mimanTing.autoUnregisterFromUpdate && mimanTing.dialogueLine != "")
                    {
                        Unregister(mimanTing);
                    }
                }
            }
        }
Beispiel #10
0
 public void CreatingEmptyRoom()
 {
     string saveName = "MyEmptyRoomSave.json";
     {
         RelayTwo relay = new RelayTwo();
         relay.CreateTable(Room.TABLE_NAME);
         RoomRunner roomRunner = new RoomRunner(relay);
         roomRunner.CreateRoom <Room>("MyRoom");
         relay.SaveAll(saveName);
     }
     {
         RelayTwo   relay      = new RelayTwo(saveName);
         RoomRunner roomRunner = new RoomRunner(relay);
         Room       room       = roomRunner.GetRoom("MyRoom");
         Assert.IsNotNull(room);
         Assert.AreEqual("MyRoom", room.name);
         Assert.AreEqual(0, room.tilePoints.Length);
     }
 }
Beispiel #11
0
        public void CreatingRoomConveniently()
        {
            RelayTwo relay = new RelayTwo();

            relay.CreateTable(Room.TABLE_NAME);
            RoomRunner roomRunner = new RoomRunner(relay);

            SimpleRoomBuilder srb = new SimpleRoomBuilder(roomRunner);
            Room closet           = srb.CreateRoomWithSize("Closet", 4, 3);

            Assert.AreEqual(12, closet.tilePoints.Length);

            for (int x = 0; x < 4; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    Assert.IsNotNull(closet.GetTile(new IntPoint(x, y)));
                }
            }
        }
Beispiel #12
0
        public void DeleteRoomAndCreateNewOneAfterThat()
        {
            RelayTwo relay = new RelayTwo();

            relay.CreateTable(Room.TABLE_NAME);
            RoomRunner roomRunner = new RoomRunner(relay);

            {
                Room bathroom = roomRunner.CreateRoom <Room>("Bathroom");
                bathroom.AddTile(new PointTileNode(new IntPoint(7, 9), bathroom));
                bathroom.AddTile(new PointTileNode(new IntPoint(8, 9), bathroom));
                Assert.AreEqual(2, bathroom.tilePoints.Length);
                Assert.AreEqual(new IntPoint(7, 9), bathroom.tilePoints[0]);
            }

            {
                roomRunner.DestroyRoom("Bathroom");
                Room bathroomAgain = roomRunner.CreateRoom <Room>("Bathroom");
                Assert.AreEqual(0, bathroomAgain.tilePoints.Length);
                bathroomAgain.AddTile(new PointTileNode(new IntPoint(7, 9), bathroomAgain));                // should be able to add node
                Assert.AreEqual(1, bathroomAgain.tilePoints.Length);
            }
        }
        public SmartWalkBehaviour(Character pCharacter, RoomRunner pRoomRunner, TingRunner pTingRunner, WorldSettings pWorldSettings)
        {
            #if LOG && DEEP
            s_logger.Log("Created SmartWalkBehaviour for character " + pCharacter.name);
            #endif

            _character = pCharacter;
            _roomRunner = pRoomRunner;
            _tingRunner = pTingRunner;
            _worldSettings = pWorldSettings;

            _mimanPathFinder = new MimanPathfinder2(_tingRunner, _roomRunner);
            //_mimanPathFinder = new MimanPathfinder_DEPRECATED(_tingRunner);

            CalculateFinalTargetPosition();
            bool startWalkingAgain = RefreshPaths();
            if(startWalkingAgain) {
                _character.StartAction("Walking", null, Character.LONG_TIME, Character.LONG_TIME);
            }
            else {

            }
        }
        public SmartWalkBehaviour(Character pCharacter, RoomRunner pRoomRunner, TingRunner pTingRunner, WorldSettings pWorldSettings)
        {
#if LOG && DEEP
            s_logger.Log("Created SmartWalkBehaviour for character " + pCharacter.name);
#endif

            _character     = pCharacter;
            _roomRunner    = pRoomRunner;
            _tingRunner    = pTingRunner;
            _worldSettings = pWorldSettings;

            _mimanPathFinder = new MimanPathfinder2(_tingRunner, _roomRunner);
            //_mimanPathFinder = new MimanPathfinder_DEPRECATED(_tingRunner);

            CalculateFinalTargetPosition();
            bool startWalkingAgain = RefreshPaths();
            if (startWalkingAgain)
            {
                _character.StartAction("Walking", null, Character.LONG_TIME, Character.LONG_TIME);
            }
            else
            {
            }
        }
Beispiel #15
0
 public MimanPathfinder2(TingRunner pTingRunner, RoomRunner pRoomRunner)
 {
     _tingRunner = pTingRunner;
     _roomRunner = pRoomRunner;
 }
Beispiel #16
0
 TingRunner CreateTingRunnerWithSomeRoom()
 {
     relay = new RelayTwo();
     relay.CreateTable(Ting.TABLE_NAME);
     relay.CreateTable(Room.TABLE_NAME);
     RoomRunner rr = new RoomRunner(relay);
     rr.CreateRoom<Room>("SomeRoom");
     TingRunner tingRunner = new TingRunner(relay, rr);
     return tingRunner;
 }
Beispiel #17
0
        public void Update(float dt, GameTime pCurrentTime, Character pCharacter, MimanTingRunner pTingRunner, RoomRunner pRoomRunner, DialogueRunner pDialogueRunner, WorldSettings pWorldSettings)
        {
            TimetableSpan currentSpan = GetCurrentSpan(pCurrentTime);

            if (currentSpan != TimetableSpan.NULL)
            {
                if (pCharacter.isAvatar)
                {
                    return;
                }

                if (pCharacter.lastTimetableSpan != currentSpan)
                {
                    if (pCharacter.lastTimetableSpan != TimetableSpan.NULL)
                    {
                        pCharacter.logger.Log(pCharacter.name + " ended span " + pCharacter.lastTimetableSpan.name);
                        pCharacter.lastTimetableSpan.behaviour.OnFinish(pCharacter, pTingRunner, pRoomRunner, pDialogueRunner);
                    }
                    else
                    {
                        pCharacter.logger.Log(pCharacter.name + " ended span NULL");
                    }
                }
                pCharacter.lastTimetableSpan = currentSpan;

                //pCharacter.logger.Log("Current timetable span to update: " + currentSpan.ToString());
                if (pCharacter.timetableTimer <= 0f)
                {
                    pCharacter.timetableTimer = currentSpan.behaviour.Execute(pCharacter, pTingRunner, pRoomRunner, pDialogueRunner, pWorldSettings);
                    //pCharacter.logger.Log(pCharacter.name + " executed " + currentSpan.behaviour + " and set timetableTimer to " + pCharacter.timetableTimer);
                }
                else
                {
                    pCharacter.timetableTimer -= dt;
                    //pCharacter.logger.Log(pCharacter.name + " timetableTimer = " + pCharacter.timetableTimer);
                }
            }
            else
            {
                D.Log("Found no matching time span in Timetable for character " + pCharacter.name + " at time " + pCurrentTime);
            }
        }
Beispiel #18
0
 public TingrunnerAPI(Computer pComputer, TingRunner pTingRunner, RoomRunner pRoomRunner)
 {
     _computer = pComputer;
     _tingRunner = pTingRunner;
     _roomRunner = pRoomRunner;
 }
Beispiel #19
0
 public SimpleRoomBuilder(RoomRunner pRoomRunner)
 {
     _roomRunner = pRoomRunner;
 }
Beispiel #20
0
        public void Update(float dt, GameTime pCurrentTime, Character pCharacter, MimanTingRunner pTingRunner, RoomRunner pRoomRunner, DialogueRunner pDialogueRunner, WorldSettings pWorldSettings)
        {
            TimetableSpan currentSpan = GetCurrentSpan(pCurrentTime);

            if(currentSpan != TimetableSpan.NULL) {

                if (pCharacter.isAvatar) {
                    return;
                }

                if(pCharacter.lastTimetableSpan != currentSpan) {
                    if(pCharacter.lastTimetableSpan != TimetableSpan.NULL) {
                        pCharacter.logger.Log(pCharacter.name + " ended span " + pCharacter.lastTimetableSpan.name);
                        pCharacter.lastTimetableSpan.behaviour.OnFinish(pCharacter, pTingRunner, pRoomRunner, pDialogueRunner);
                    } else {
                        pCharacter.logger.Log(pCharacter.name + " ended span NULL");
                    }
                }
                pCharacter.lastTimetableSpan = currentSpan;

                //pCharacter.logger.Log("Current timetable span to update: " + currentSpan.ToString());
                if(pCharacter.timetableTimer <= 0f) {
                    pCharacter.timetableTimer = currentSpan.behaviour.Execute(pCharacter, pTingRunner, pRoomRunner, pDialogueRunner, pWorldSettings);
                    //pCharacter.logger.Log(pCharacter.name + " executed " + currentSpan.behaviour + " and set timetableTimer to " + pCharacter.timetableTimer);
                } else {
                    pCharacter.timetableTimer -= dt;
                    //pCharacter.logger.Log(pCharacter.name + " timetableTimer = " + pCharacter.timetableTimer);
                }
            }
            else {
                D.Log("Found no matching time span in Timetable for character " + pCharacter.name + " at time " + pCurrentTime);
            }
        }
Beispiel #21
0
		public void CreatingRoomConveniently()
		{
			RelayTwo relay = new RelayTwo();
			relay.CreateTable(Room.TABLE_NAME);
			RoomRunner roomRunner = new RoomRunner(relay);
			
			SimpleRoomBuilder srb = new SimpleRoomBuilder(roomRunner);
			Room closet = srb.CreateRoomWithSize("Closet", 4, 3);
			Assert.AreEqual(12, closet.tiles.Length);
			
			for(int x = 0; x < 4; x++)
			{
				for(int y = 0; y < 3; y++)
				{
					Assert.IsNotNull(closet.GetTile(new IntPoint(x, y)));
				}
			}
		}
Beispiel #22
0
		public void DeleteRoomAndCreateNewOneAfterThat()
		{
			RelayTwo relay = new RelayTwo();
			relay.CreateTable(Room.TABLE_NAME);
			RoomRunner roomRunner = new RoomRunner(relay);
			
			{
				Room bathroom = roomRunner.CreateRoom<Room>("Bathroom");
				bathroom.AddTile(new PointTileNode(new IntPoint(7, 9), bathroom));
                bathroom.AddTile(new PointTileNode( new IntPoint(8, 9), bathroom));
				Assert.AreEqual(2, bathroom.tiles.Length);
				Assert.AreEqual(new PointTileNode(new IntPoint(7, 9), bathroom), bathroom.tiles[0]);
			}
			
			{
				roomRunner.DestroyRoom("Bathroom");
				Room bathroomAgain = roomRunner.CreateRoom<Room>("Bathroom");
				Assert.AreEqual(0, bathroomAgain.tiles.Length);
				bathroomAgain.AddTile(new PointTileNode(new IntPoint(7, 9),bathroomAgain)); // should be able to add node
				Assert.AreEqual(1, bathroomAgain.tiles.Length);
			}
		}
Beispiel #23
0
		public void CreateRoomsWithDuplicateNames()
		{
			RelayTwo relay = new RelayTwo();
			relay.CreateTable(Room.TABLE_NAME);
			RoomRunner roomRunner = new RoomRunner(relay);
			roomRunner.CreateRoom<Room>("Hallway");
			Assert.Throws<TingTingException>(() => {
				roomRunner.CreateRoom<Room>("Hallway");
			});
		}
Beispiel #24
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 #25
0
 internal void SetupBaseRunners(TingRunner pTingRunner, RoomRunner pRoomRunner)
 {
     _roomRunner = pRoomRunner;
     _tingRunner = pTingRunner;
 }
        // 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);
        }
Beispiel #27
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);
        }
        // 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;
        }