public DungeonEngine(WowInterface wowInterface)
        {
            WowInterface = wowInterface;

            CurrentNodes     = new Queue <DungeonNode>();
            ExitDungeonEvent = new TimegatedEvent(TimeSpan.FromMilliseconds(1000));

            RootSelector = new Selector <DungeonBlackboard>
                           (
                "HasFinishedDungeon",
                (b) => Progress == 100.0,
                new Leaf <DungeonBlackboard>("LeaveDungeon", (b) => ExitDungeon()),
                new Selector <DungeonBlackboard>
                (
                    "IDied",
                    (b) => IDied,
                    new Sequence <DungeonBlackboard>
                    (
                        new Leaf <DungeonBlackboard>("RecoverDeathPosition", (b) => MoveToPosition(DeathPosition)),
                        new Leaf <DungeonBlackboard>("SetIDiedToFalse", (b) =>
            {
                IDied = false;
                return(BehaviorTreeStatus.Success);
            })
                    ),
                    new Selector <DungeonBlackboard>
                    (
                        "AmITheLeader",
                        (b) => WowInterface.ObjectManager.PartyleaderGuid == WowInterface.ObjectManager.PlayerGuid || !WowInterface.ObjectManager.PartymemberGuids.Any(),
                        new Selector <DungeonBlackboard>
                        (
                            "AreAllPlayersPresent",
                            (b) => AreAllPlayersPresent(48.0),
                            new Leaf <DungeonBlackboard>("FollowNodePath", (b) => FollowNodePath()),
                            new Leaf <DungeonBlackboard>("WaitForPlayersToArrive", (b) => { return(BehaviorTreeStatus.Success); })
                        ),
                        new Selector <DungeonBlackboard>
                        (
                            "IsDungeonLeaderInRange",
                            (b) => WowInterface.ObjectManager.Partyleader != null,
                            new Leaf <DungeonBlackboard>("FollowLeader", (b) => MoveToPosition(WowInterface.ObjectManager.Partyleader.Position, 0f, MovementAction.Following)),
                            new Leaf <DungeonBlackboard>("WaitForLeaderToArrive", (b) => { return(BehaviorTreeStatus.Success); })
                        )
                    )
                )
                           );

            BehaviorTree = new AmeisenBotBehaviorTree <DungeonBlackboard>
                           (
                "DungeonBehaviorTree",
                RootSelector,
                DungeonBlackboard
                           );
        }
        public void SimpleTreeTest()
        {
            int treeResult0 = 0;
            int treeResult1 = 0;

            TestBlackboard testBlackboard = new TestBlackboard()
            {
                FirstNode = true
            };

            AmeisenBotBehaviorTree <TestBlackboard> tree = new AmeisenBotBehaviorTree <TestBlackboard>
                                                           (
                new Selector <TestBlackboard>
                (
                    (blackboard) => blackboard.FirstNode,
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult0;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult1;
                return(BehaviorTreeStatus.Success);
            }
                    )
                ),
                testBlackboard
                                                           );

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(0, treeResult1);

            testBlackboard.FirstNode = false;

            tree.Tick();
            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(2, treeResult1);
        }
        public void InverterTreeTest()
        {
            int treeResult0 = 0;
            int treeResult1 = 0;

            TestBlackboard testBlackboard = new TestBlackboard()
            {
                FirstNode = true
            };

            AmeisenBotBehaviorTree <TestBlackboard> tree = new AmeisenBotBehaviorTree <TestBlackboard>
                                                           (
                new Sequence <TestBlackboard>
                (
                    new Inverter <TestBlackboard>
                    (
                        new Leaf <TestBlackboard>
                        (
                            (blackboard) =>
            {
                ++treeResult0;
                return(BehaviorTreeStatus.Success);
            }
                        )
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult1;
                return(BehaviorTreeStatus.Success);
            }
                    )
                ),
                testBlackboard
                                                           );

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(0, treeResult1);

            tree.Tick();
            tree.Tick();

            Assert.AreEqual(3, treeResult0);
            Assert.AreEqual(0, treeResult1);
        }
        public StateGhost(AmeisenBotStateMachine stateMachine, AmeisenBotConfig config, WowInterface wowInterface) : base(stateMachine, config, wowInterface)
        {
            Blackboard = new GhostBlackboard(wowInterface);

            DungeonSelector = new Selector <GhostBlackboard>
                              (
                (b) => Config.DungeonUsePartyMode,
                new Selector <GhostBlackboard>
                (
                    (b) => WowInterface.DungeonEngine.TryGetProfileByMapId(StateMachine.LastDiedMap) != null,
                    new Leaf <GhostBlackboard>(RunToDungeonProfileEntry),
                    new Selector <GhostBlackboard>
                    (
                        (b) => IsUnitToFollowNear(out b.playerToFollowGuid),
                        new Leaf <GhostBlackboard>(FollowNearestUnit),
                        new Leaf <GhostBlackboard>(RunToCorpsePositionAndSearchForPortals)
                    )
                ),
                new Selector <GhostBlackboard>
                (
                    (b) => WowInterface.DungeonEngine.DeathEntrancePosition != default,
                    new Leaf <GhostBlackboard>(RunToDungeonEntry),
                    new Leaf <GhostBlackboard>(RunToCorpsePositionAndSearchForPortals)
                )
                              );

            BehaviorTree = new AmeisenBotBehaviorTree <GhostBlackboard>
                           (
                new Selector <GhostBlackboard>
                (
                    (b) => WowInterface.ObjectManager.MapId.IsBattlegroundMap(),
                    new Leaf <GhostBlackboard>((b) =>
            {
                WowInterface.MovementEngine.StopMovement();
                return(BehaviorTreeStatus.Ongoing);
            }),
                    new Selector <GhostBlackboard>
                    (
                        (b) => StateMachine.LastDiedMap.IsDungeonMap(),
                        DungeonSelector,
                        new Leaf <GhostBlackboard>(RunToCorpseAndRetrieveIt)
                    )
                ),
                Blackboard,
                TimeSpan.FromSeconds(1)
                           );
        }
        public WarsongGulchProfile(WowInterface wowInterface)
        {
            WowInterface = wowInterface;

            ActionEvent   = new TimegatedEvent(TimeSpan.FromMilliseconds(500));
            LosCheckEvent = new TimegatedEvent(TimeSpan.FromMilliseconds(1000));

            JBgBlackboard = new CtfBlackboard(UpdateBattlegroundInfo);

            KillEnemyFlagCarrierSelector = new Selector <CtfBlackboard>
                                           (
                "EnemyTeamFlagCarrierInRange",
                (b) => b.EnemyTeamFlagCarrier != null,
                new Selector <CtfBlackboard>
                (
                    "HasFlag",
                    (b) => b.MyTeamHasFlag ||
                    b.EnemyTeamFlagCarrier.Position.GetDistance(WsgDataset.EnemyBasePosition)
                    < WowInterface.ObjectManager.Player.Position.GetDistance(WsgDataset.EnemyBasePosition),
                    new Leaf <CtfBlackboard>("KillEnemyFlagCarrier", KillEnemyFlagCarrier),
                    new Leaf <CtfBlackboard>("MoveToEnemyBaseAndGetFlag", MoveToEnemyBaseAndGetFlag)
                ),
                new Selector <CtfBlackboard>
                (
                    "IsFlagNearOwnOrEnemyBase",
                    (b) => b.EnemyTeamFlagPos.GetDistance2D(WsgDataset.EnemyBasePositionMapCoords)
                    < b.EnemyTeamFlagPos.GetDistance2D(WsgDataset.OwnBasePositionMapCoords),
                    new Leaf <CtfBlackboard>("MoveToEnemyBase", (b) => MoveToPosition(WsgDataset.EnemyBasePosition)),
                    new Leaf <CtfBlackboard>("MoveToOwnBase", (b) => MoveToPosition(WsgDataset.OwnBasePosition))
                )
                                           );

            FlagSelector = new DualSelector <CtfBlackboard>
                           (
                "WhoHasTheFlag",
                (b) => b.MyTeamHasFlag,
                (b) => b.EnemyTeamHasFlag,

                // no team has the flag
                new Leaf <CtfBlackboard>("MoveToEnemyBaseAndGetFlag", MoveToEnemyBaseAndGetFlag),

                // only my team has the flag
                new Selector <CtfBlackboard>
                (
                    "AmITheFlagCarrier",
                    (b) => b.MyTeamFlagCarrier != null && b.MyTeamFlagCarrier.Guid == WowInterface.ObjectManager.PlayerGuid,
                    new Leaf <CtfBlackboard>("MoveToOwnBase", (b) => MoveToPosition(WsgDataset.OwnBasePosition)),
                    new Selector <CtfBlackboard>
                    (
                        "IsTheFlagCarrierInRange",
                        (b) => b.MyTeamFlagCarrier != null,
                        new Leaf <CtfBlackboard>("MoveToOwnFlagCarrier", (b) => MoveToPosition(b.MyTeamFlagCarrier.Position)),
                        new Leaf <CtfBlackboard>("DefendOwnBase", DefendOwnBase)
                    )
                ),

                // only enemy team has the flag
                KillEnemyFlagCarrierSelector,

                // both teams have the flag
                new Selector <CtfBlackboard>
                (
                    "AmITheFlagCarrier",
                    (b) => b.MyTeamFlagCarrier != null && b.MyTeamFlagCarrier.Guid == WowInterface.ObjectManager.PlayerGuid,
                    new Selector <CtfBlackboard>
                    (
                        "AmINearOwnBase",
                        (b) => WowInterface.ObjectManager.Player.Position.GetDistance(WsgDataset.OwnBasePosition) < 128.0,
                        new Leaf <CtfBlackboard>("MoveToHidingSpot", (b) => MoveToPosition(WsgDataset.FlagHidingSpot)),
                        new Leaf <CtfBlackboard>("MoveToOwnBase", (b) => MoveToPosition(WsgDataset.OwnBasePosition))
                    ),
                    KillEnemyFlagCarrierSelector
                )
                           );

            MainSelector = new Selector <CtfBlackboard>
                           (
                "IsGateOpen",
                (b) => IsGateOpen(),
                new Selector <CtfBlackboard>
                (
                    "IsFlagNear",
                    (b) => IsFlagNear(),
                    new Leaf <CtfBlackboard>("UseNearestFlag", UseNearestFlag),
                    new Selector <CtfBlackboard>
                    (
                        "IsAnyBuffNearMe",
                        (b) => IsAnyBuffNearMe(16.0),
                        new Leaf <CtfBlackboard>("MoveToNearestBuff", MoveToNearestBuff),
                        new Selector <CtfBlackboard>
                        (
                            "DoWeOutnumberOurEnemies",
                            (b) => DoWeOutnumberOurEnemies(b),
                            new Leaf <CtfBlackboard>("AttackNearWeakestEnemy", AttackNearWeakestEnemy),
                            FlagSelector
                        )
                    )
                ),
                new Leaf <CtfBlackboard>("MoveToGatePosition", (b) => MoveToPosition(WsgDataset.GatePosition))
                           );

            BehaviorTree = new AmeisenBotBehaviorTree <CtfBlackboard>
                           (
                "JBgWarsongGulchBehaviorTree",
                MainSelector,
                JBgBlackboard,
                TimeSpan.FromSeconds(1)
                           );
        }
        public void SequenceTreeTest()
        {
            int treeResult0 = 0;
            int treeResult1 = 0;
            int treeResult2 = 0;

            TestBlackboard testBlackboard = new TestBlackboard();

            AmeisenBotBehaviorTree <TestBlackboard> tree = new AmeisenBotBehaviorTree <TestBlackboard>
                                                           (
                new Sequence <TestBlackboard>
                (
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult1;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult0;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult2;
                return(BehaviorTreeStatus.Failed);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult0;
                return(BehaviorTreeStatus.Success);
            }
                    )
                ),
                testBlackboard
                                                           );

            tree.Tick();

            Assert.AreEqual(0, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(0, treeResult2);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(0, treeResult2);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(1, treeResult2);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(2, treeResult1);
            Assert.AreEqual(1, treeResult2);
        }
        public void OngoingTreeTestResume()
        {
            int treeResult0 = 0;
            int treeResult1 = 0;
            int treeResult2 = 0;

            TestBlackboard testBlackboard = new TestBlackboard();

            AmeisenBotBehaviorTree <TestBlackboard> tree = new AmeisenBotBehaviorTree <TestBlackboard>
                                                           (
                new Sequence <TestBlackboard>
                (
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult1;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult0;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult2;
                return(treeResult2 < 5 ? BehaviorTreeStatus.Ongoing : BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult0;
                return(BehaviorTreeStatus.Success);
            }
                    )
                ),
                testBlackboard,
                true
                                                           );

            Assert.AreEqual(true, tree.ResumeOngoingNodes);
            Assert.AreEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(0, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(0, treeResult2);

            Assert.AreNotEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(0, treeResult2);

            Assert.AreNotEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(1, treeResult2);

            Assert.AreNotEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(2, treeResult2);

            Assert.AreNotEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(3, treeResult2);

            Assert.AreNotEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(4, treeResult2);

            Assert.AreNotEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(1, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(5, treeResult2);

            Assert.AreNotEqual(null, tree.OngoingNode);

            tree.Tick();

            Assert.AreEqual(2, treeResult0);
            Assert.AreEqual(1, treeResult1);
            Assert.AreEqual(5, treeResult2);

            Assert.AreEqual(null, tree.OngoingNode);
        }
        public void DualSelectorTreeTest()
        {
            int treeResult00 = 0;
            int treeResult10 = 0;
            int treeResult01 = 0;
            int treeResult11 = 0;

            TestBlackboard testBlackboard = new TestBlackboard();

            AmeisenBotBehaviorTree <TestBlackboard> tree = new AmeisenBotBehaviorTree <TestBlackboard>
                                                           (
                new DualSelector <TestBlackboard>
                (
                    (blackboard) => blackboard.FirstNode,
                    (blackboard) => blackboard.SecondFirstNode,
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult00;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult10;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult01;
                return(BehaviorTreeStatus.Success);
            }
                    ),
                    new Leaf <TestBlackboard>
                    (
                        (blackboard) =>
            {
                ++treeResult11;
                return(BehaviorTreeStatus.Success);
            }
                    )
                ),
                testBlackboard
                                                           );

            testBlackboard.FirstNode       = false;
            testBlackboard.SecondFirstNode = false;

            tree.Tick();

            Assert.AreEqual(1, treeResult00);
            Assert.AreEqual(0, treeResult10);
            Assert.AreEqual(0, treeResult01);
            Assert.AreEqual(0, treeResult11);

            testBlackboard.FirstNode = true;

            tree.Tick();

            Assert.AreEqual(1, treeResult00);
            Assert.AreEqual(1, treeResult10);
            Assert.AreEqual(0, treeResult01);
            Assert.AreEqual(0, treeResult11);

            testBlackboard.FirstNode       = false;
            testBlackboard.SecondFirstNode = true;

            tree.Tick();

            Assert.AreEqual(1, treeResult00);
            Assert.AreEqual(1, treeResult10);
            Assert.AreEqual(1, treeResult01);
            Assert.AreEqual(0, treeResult11);

            testBlackboard.FirstNode       = true;
            testBlackboard.SecondFirstNode = true;

            tree.Tick();

            Assert.AreEqual(1, treeResult00);
            Assert.AreEqual(1, treeResult10);
            Assert.AreEqual(1, treeResult01);
            Assert.AreEqual(1, treeResult11);
        }