//foreach possible decision pair it with target given by context //this is bad solution, because to create new qualifier we need to upgrade this method public void MakeDecisionsList(ContextBase context) { if (PossibleDecisions == null) { PossibleDecisions = new List <Decision>(); } PossibleDecisions.Clear(); for (int i = 0; i < Qualifiers.Count; ++i) { if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.MeleeAttack) { for (int j = 0; j < context.AvailableMeleeTargets.Count; ++j) { Character target = GameController.Instance.FindCharacter(context.AvailableMeleeTargets[j]); //we need define from that side character can attack his target List <Vector3Int> possibleTilesToAttack = GridSystem.Instance.GetNearMovemapTilesList(target.Coords); if (GameController.Instance.IsCharactersStayNear(context.Provider.GetControlledCharacter(), target)) { possibleTilesToAttack.Add(context.Provider.GetControlledCharacter().Coords); } foreach (var coords in possibleTilesToAttack) { Decision decision = new Decision(); decision.Context = context.Copy(); decision.Context.Target = target; decision.Context.Data.Add("AttackTile", coords); decision.QualifierRef = Qualifiers[i]; PossibleDecisions.Add(decision); } } } else if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.Move) { Character currentCharacter = context.Provider.GetControlledCharacter(); Movemap movemap = GridSystem.Instance.GetCurrentMovemap(); for (int j = 0; j < movemap.MoveCoords.Count; ++j) { if (movemap.MoveCoords[j] == currentCharacter.Coords) { continue; } Decision decision = new Decision(); decision.Context = context.Copy(); decision.Context.Target = movemap.MoveCoords[j]; decision.QualifierRef = Qualifiers[i]; PossibleDecisions.Add(decision); } } else if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.RangedAttack) { for (int j = 0; j < context.AvailableRangedTargets.Count; ++j) { Character target = GameController.Instance.FindCharacter(context.AvailableRangedTargets[j]); Decision decision = new Decision(); decision.Context = context.Copy(); decision.Context.Target = target; decision.QualifierRef = Qualifiers[i]; PossibleDecisions.Add(decision); } } else if (Qualifiers[i].Type == UtilityAISystem.Qualifiers.Skill) { Character user = context.Provider.GetControlledCharacter(); Skill skill = user.Skills[Qualifiers[i].SkillNo]; if (skill.CurrentCooldown > 0 || skill.CurrentCount == 0) { continue; } if (skill.TypeTarget == Skill.TargetType.Self) { Decision decision = new Decision(); decision.Context = context.Copy(); decision.Context.Target = user; decision.Context.Data.Add("SkillNo", Qualifiers[i].SkillNo); decision.QualifierRef = Qualifiers[i]; PossibleDecisions.Add(decision); } else if (skill.TypeUse == Skill.UseType.Melee) { //define list of target fractions List <string> fractionList = new List <string>(); if (skill.FractionTarget == Skill.TargetFraction.Enemy) { fractionList.Add(user.GetOppositeFraction()); } else if (skill.FractionTarget == Skill.TargetFraction.Ally) { fractionList.Add(user.tag); } else { fractionList.Add(user.GetOppositeFraction()); fractionList.Add(user.tag); } //define all data Movemap skillMovemap = new Movemap(); skillMovemap.MoveCoords.AddRange(GridSystem.Instance.GetCurrentMovemap().MoveCoords); //define all target that character can reach GridSystem.Instance.DefineAvailableMeleeTargets(skillMovemap, user, GameController.Instance.CharacterList, GridSystem.ConvertFractionsFromStringToNode(fractionList), skill.Distance); //define all positions to attack for all targets List <List <Vector3Int> > possiblePositions = new List <List <Vector3Int> >(); for (int j = 0; j < skillMovemap.MeleeCoords.Count; ++j) { Character targetCharacter = GridSystem.Instance.GetCharacterFromCoords(skillMovemap.MeleeCoords[j]); //get possible positions to attack possiblePositions.Add(GridSystem.Instance.DefinePositionsToAttackTarget(skillMovemap, targetCharacter, skill.Distance)); //additional special checks skill.AdditionalChecks(targetCharacter, possiblePositions[j]); //if there no possible positions to attack than delete this target from list if (possiblePositions[j].Count == 0) { skillMovemap.MeleeCoords.RemoveAt(j); possiblePositions.RemoveAt(j); --j; } } //create decision to all pairs target-possible position for (int j = 0; j < skillMovemap.MeleeCoords.Count; ++j) { foreach (var coords in possiblePositions[j]) { Decision decision = new Decision(); decision.Context = context.Copy(); decision.Context.Target = GridSystem.Instance.GetCharacterFromCoords(skillMovemap.MeleeCoords[j]); decision.Context.Data.Add("AttackTile", coords); decision.Context.Data.Add("SkillNo", Qualifiers[i].SkillNo); decision.QualifierRef = Qualifiers[i]; PossibleDecisions.Add(decision); } } } else if (skill.TypeUse == Skill.UseType.Randged) { //define list of target fractions List <string> fractionList = new List <string>(); if (skill.FractionTarget == Skill.TargetFraction.Enemy) { fractionList.Add(user.GetOppositeFraction()); } else if (skill.FractionTarget == Skill.TargetFraction.Ally) { fractionList.Add(user.tag); } else { fractionList.Add(user.GetOppositeFraction()); fractionList.Add(user.tag); } Movemap skillMovemap = new Movemap(); bool isThereEnemyNearby = GameController.Instance.IsThereEnemyNearby(user); if ((isThereEnemyNearby && skill.UseNearEnemy) || (!isThereEnemyNearby && user.Properties.Class != CharacterClass.Archer)) { foreach (var fraction in fractionList) { skillMovemap.RangeCoords.AddRange(GameController.Instance.DefineAvailableRangedTargets(user, fraction)); } } else if (!isThereEnemyNearby && user.Properties.Class == CharacterClass.Archer) //this can reduce amount of raycasts { skillMovemap.RangeCoords.AddRange(GridSystem.Instance.GetCurrentMovemap().RangeCoords); if (fractionList.Contains(user.tag)) { skillMovemap.RangeCoords.AddRange(GameController.Instance.DefineAvailableRangedTargets(user, user.tag)); } } foreach (var targetCoords in skillMovemap.RangeCoords) { Decision decision = new Decision(); decision.Context = context.Copy(); decision.Context.Target = GridSystem.Instance.GetCharacterFromCoords(targetCoords); decision.Context.Data.Add("SkillNo", Qualifiers[i].SkillNo); decision.QualifierRef = Qualifiers[i]; PossibleDecisions.Add(decision); } } } } }