コード例 #1
0
 public AttackState()
 {
     actions                   = new Action[1];
     actions[0]                = new AttackEnemyAction();
     transitions               = new Transition[1];
     transitions[0].decision   = new WeakerThanEnemyDecision();
     transitions[0].trueState  = new RunAwayState();
     transitions[0].falseState = this;
 }
コード例 #2
0
    public override IEnumerator CalculateActions(List <AIAction> validActions, BoardManager gm, Actor ai)
    {
        if (ai.CanAttack())
        {
            List <TileNode> movementNodes = GetTileNodeMovementRange(gm, ai);

            /// Store the actual position of the ai so that we can restore it later
            int originalX = ai.GetPosX();
            int originalY = ai.GetPosY();


            //Just going to get skills for now, expand to equipment and inventory
            //
            List <Skill> avaliableSkills = ai.actorData.JobDataState.GetAllSkillsOffCoolDown(ai);



            //stress test more skills
            // 7 * 3 = 21 skills to consider
            // a little inaccurate since coping this many skills would take more time than just processing them but ya know
            //
            Debug.Log("Skill count: " + avaliableSkills.Count);

            // So we're going to cycle through the possible movement options
            // use that as the source to find the range for each target type
            // use each node in that range for the target of each type

            //foreach tilenode                                   /pretend we moved there
            //foreach skill                                      /pretend we used that skill from there to find a rance
            //foreach tilenode in range                         /pretend we used the skill
            //record the combat data for that skill used

            int n = 0;

            //cycle through every place we can move
            foreach (TileNode movementOption in movementNodes)
            {
                // Basically we need to actually change the positional data of the ai to
                // accurately predict the best ability to use

                //We should also be checking if the unit is calculating from the area tha tit's starting from
                if (movementOption.data.posX == originalX && movementOption.data.posY == originalY)
                {
                    Debug.Log("Calculating from starting position");
                }


                ai.actorData.gridPosX = movementOption.data.posX;
                ai.actorData.gridPosY = movementOption.data.posY;

                //this might serve some purpose that i don't understand
                // yield return null;


                //cycle through every skill that can be used
                foreach (Skill skillOption in avaliableSkills)
                {
                    //find the range of the skill
                    // Get a list of tiles associated with that skill's range
                    //
                    List <TileNode> nodesInRange = gm.pathfinding.GetNodes(
                        gm.pathfinding.ValidBFS(skillOption, movementOption, ai
                                                ));

                    //gm.tileSelection.PopulateAttackRange(nodesInRange);

                    foreach (TileNode nodeInSkillrange in nodesInRange) //should be valid targets for the skill based on when it's being used from
                    {
                        /// So now we are cycling through a list of valid targets,
                        /// so we'll use the skill on this target and calculate the score
                        ///

                        //yield return null;
                        Combat testCombat = new Combat(ai);


                        AnimationData animationData = AnimationData.NewAntionData(skillOption, gm.pathfinding.GetTileNode(ai), nodeInSkillrange);
                        testCombat.animationDatas.Add(animationData);
                        testCombat.PoopulateCombat(animationData);

                        // So now we have a combat damage map we can use to determine the score and create an action



                        //check to make sure there is an actor here and that the actor is player controlled
                        // so we dont just randomaly blow up our own ppl
                        // further work: give negative score if allied units would be damaged?

                        AttackEnemyAction action = new AttackEnemyAction(nodeInSkillrange, movementOption, ai, skillOption);


                        CalculateDamageScore(testCombat, action);

                        CalcuateTileCost(movementOption, ai, action);
                        CalculateBuffScore(testCombat, action);
                        CacluateSummonScore(testCombat, action);

                        validActions.Add(action); //make this is like a heap or something later

                        /*
                         * if (score != 0)
                         * {
                         *  Debug.Log("Target Node: " + nodeInSkillrange.data.posX + ", " + nodeInSkillrange.data.posY +
                         *  ".  Skilled Used: " + skillOption.GetKey() +
                         *  ". Move Target: " + movementOption.data.posX + ", " + movementOption.data.posY +
                         *  "Score: " + action.GetScore());
                         * }*/
                    }
                }
            }

            //Debug.Log("Time compexity kinda: " + n);

            //POTENTIAL OPTIMIZATION: we theoretically know the ranges of skills and the aoe of there target
            //types so maybe we can just do math to cut out tiles where we know there wont be anything

            //Set the position back to where the actor ACTUALLY is
            ai.actorData.gridPosX = originalX;
            ai.actorData.gridPosY = originalY;

            //yield return null;
        }

        yield return(null);
    }