Ejemplo n.º 1
0
        public override bool Build()
        {
            InterruptCondition = delegate
            {
                return(npcOwner.IsDead);
            };
            #region Start Group

            Node start = NodeBuilder.Start(this);
            AddNode(start, null, "Start");

            #endregion

            #region Nodes Initialize

            Node shoot          = null;
            Node idle           = null;
            Node searchForActor = null;

            //TODO: Rewrite nodes code using NodeContainers (in order to get rid of strings)
            NodeContainer shootContainer          = new NodeContainer(shoot);
            NodeContainer idleContainer           = new NodeContainer(idle);
            NodeContainer searchForActorContainer = new NodeContainer(searchForActor);

            #endregion

            #region Idle state

            //TODO: Remove this unneccesary condition
            Func <bool> seesActorCondition = delegate
            {
                return(npcOwner.focusedTarget != null &&
                       npcOwner.CanSeeActor(npcOwner.focusedTarget));
            };
            Func <bool> seesEnemyCondition = delegate
            {
                return(npcOwner.focusedTarget != null &&
                       npcOwner.focusedTarget.ActorFraction != npcOwner.ActorFraction &&
                       !npcOwner.focusedTarget.IsDead);
            };

            StateData idleStateData = new StateData
                                      (
                null,
                null,
                delegate { npcOwner.Animator.SetTrigger("Idle" + npcOwner.EquipedWeapon.Settings.HoldingType.ToString()); },
                (seesActorCondition, 0)
                                      );
            idle = new Node(idleStateData);
            idleContainer.AttachedNode = idle;
            Node idleSeesActorSwitch = NodeBuilder.Switch("Idle State", ("Shoot State", seesEnemyCondition));
            AddNode(idle, start, "Idle State");
            AddNode(idleSeesActorSwitch, idle, "Idle State: Sees actor switch");

            #endregion

            #region Shoot State

            Func <bool> enemyIsDead = delegate
            {
                return(npcOwner.focusedTarget != null && npcOwner.focusedTarget.IsDead);
            };

            Action shootingAction = delegate
            {
                npcOwner.ShootInActor(npcOwner.focusedTarget);
            };

            StateData shootStateData = new StateData
                                       (
                null,
                null,
                delegate { Debug.Log("Shoot on sate"); shootingAction.Invoke(); }, //On update
                (enemyIsDead, 0),
                (() => { return(true); }, 1)
                                       );
            shoot = new Node(shootStateData);
            shootContainer.AttachedNode = shoot;
            AddNode(shoot, idleSeesActorSwitch, "Shoot State");
            // Idle is now child of shooting state with localId = 0
            ConnectNodes("Shoot State", "Idle State");

            Action searchForActorContext = delegate
            {
                // Interruption
                if (seesActorCondition() && seesEnemyCondition())
                {
                    searchForActor.Exit();
                }
            };

            Func <bool> noSearchResultCondition = delegate
            {
                return(npcOwner.Agent.InDestination());
            };

            StateData searchForActorData = new StateData
                                           (
                () => { npcOwner.Agent.SetDestination(npcOwner.TargetLastSeenPosition); },
                null,
                searchForActorContext,
                (noSearchResultCondition, 1)
                                           );

            searchForActor = new Node(searchForActorData);
            searchForActorContainer.AttachedNode = searchForActor;

            // Shooting choice-node with localId = 1
            Node shootingChoiceNode = NodeBuilder.Choice
                                      (
                "Shoot State",
                "Shoot State: Search State",
                () => { return(npcOwner.focusedTarget != null && !npcOwner.focusedTarget.IsDead && npcOwner.CanSeeActor(npcOwner.focusedTarget)); }
                                      );
            AddNode(shootingChoiceNode, shoot, "Shoot State: Choice");
            AddNode(searchForActor, shoot, "Shoot State: Search State");
            // shoot is now child of searchForActor with localId = 0
            ConnectNodes("Shoot State: Search State", "Shoot State");
            // idle is now child of searchForActor with localId = 1
            ConnectNodes("Shoot State: Search State", "Idle State");

            #endregion

            return(true);
        }