public CharacterTurn(BaseCharacter bs, MapZone zone, List <BasicTile> bt, TurnSet parent) { characterAP = bs.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.AP]; parentTS = parent; character = bs; turns.Clear(); characterArea.Clear(); int temp = bs.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.AP]; int maxMoves = bs.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.MOB]; for (int i = 1; i < temp + 1; i++) { turns.Add(new TurnInfo(maxMoves)); // characterArea.Add(MapListUtility.returnMapRadius((i - 1) * maxMoves, i * maxMoves, bt, bs)); if (i > 1) { for (int j = 1; j < 2; j++) { List <BasicTile> list = MapListUtility.returnValidMapRadius((i - 1) * maxMoves + maxMoves, bt, bs.position).Except(characterArea[i - 1 - j]).ToList(); characterArea.Add(list); } } else { characterArea.Add(MapListUtility.returnValidMapRadius((i - 1) * maxMoves + maxMoves, bt, bs.position)); } } }
private void RegenerateRadius() { int radius = selectedCharTurn.character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.MOB] * selectedCharTurn.character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.AP] - (EncounterInfo.currentTurn().selectedCharTurn.stepsSet - 2); switch (selectedCharTurn.character.rotationIndex) { case (int)BaseCharacter.Rotation.Up: CombatProcessor.radiusTiles = MapListUtility.returnValidMapRadius(radius, EncounterInfo.currentTurn().selectedCharTurn.returnCompleteArea(), selectedCharTurn.character.position - new Vector2(0, 64)); CombatProcessor.radiusTiles.RemoveAll(t => t.distanceCoordsFrom(selectedCharTurn.character.position) > radius - 2); break; case (int)BaseCharacter.Rotation.Down: CombatProcessor.radiusTiles = MapListUtility.returnValidMapRadius(radius, EncounterInfo.currentTurn().selectedCharTurn.returnCompleteArea(), selectedCharTurn.character.position + new Vector2(0, 64)); CombatProcessor.radiusTiles.RemoveAll(t => t.distanceCoordsFrom(selectedCharTurn.character.position + new Vector2(0, 64)) > radius - 2); break; case (int)BaseCharacter.Rotation.Right: CombatProcessor.radiusTiles = MapListUtility.returnValidMapRadius(radius, EncounterInfo.currentTurn().selectedCharTurn.returnCompleteArea(), selectedCharTurn.character.position + new Vector2(64, 0)); CombatProcessor.radiusTiles.RemoveAll(t => t.distanceCoordsFrom(selectedCharTurn.character.position + new Vector2(64, 0)) > radius - 2); break; case (int)BaseCharacter.Rotation.Left: CombatProcessor.radiusTiles = MapListUtility.returnValidMapRadius(radius, EncounterInfo.currentTurn().selectedCharTurn.returnCompleteArea(), selectedCharTurn.character.position - new Vector2(64, 0)); CombatProcessor.radiusTiles.RemoveAll(t => t.distanceCoordsFrom(selectedCharTurn.character.position) > radius - 2); break; } //CombatProcessor.radiusTiles.RemoveAll(t => t.distanceCoordsFrom(selectedCharTurn.character.position) > radius - 1); bRegenerateRadius = false; }
/// <summary> /// Can, well should, only be used for player selected turns /// </summary> public List <List <BasicTile> > SoftGenerateTurn(List <BasicTile> bt, Vector2 charPos) { List <List <BasicTile> > temp = new List <List <BasicTile> >(); int AP = character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.AP]; int maxMoves = character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.MOB]; int currentMoved = turns[0].movesTaken; temp.Add(MapListUtility.returnMapRadius(maxMoves - currentMoved, maxMoves, bt, charPos)); for (int i = 2; i < AP; i++) { temp.Add(MapListUtility.returnMapRadius((i - 1) * maxMoves, i * maxMoves, bt, charPos)); } return(temp); }
public void GenerateTurn(BaseCharacter bs, MapZone zone, List <BasicTile> bt) { bAttackedThisCT = false; abiUsedInfo = null; character = bs; turns.Clear(); characterArea.Clear(); int temp = bs.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.AP]; int maxMoves = bs.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.MOB]; for (int i = 1; i < temp; i++) { turns.Add(new TurnInfo(maxMoves)); characterArea.Add(MapListUtility.returnMapRadius((i - 1) * maxMoves, i * maxMoves, bt, bs)); } }
/// <summary> /// For enemy radius preview /// </summary> /// <param name="bt"></param> public void ReGenerateTurn2(List <BasicTile> bt) { bAttackedThisCT = false; abiUsedInfo = null; turns.Clear(); characterArea.Clear(); int temp = character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.AP]; int maxMoves = character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.MOB]; for (int i = 1; i < temp + 1; i++) { turns.Add(new TurnInfo(maxMoves)); if (i > 1) { for (int j = 1; j < 2; j++) { List <BasicTile> list = MapListUtility.returnValidMapRadius2((i - 1) * maxMoves + maxMoves, bt, character.position).Except(characterArea[i - 1 - j]).ToList(); characterArea.Add(list); } } else { characterArea.Add(MapListUtility.returnValidMapRadius2((i - 1) * maxMoves + maxMoves, bt, character.position)); } } try { var tempT = bt.Find(t => t.positionGrid.ToPoint() == (character.position / 64).ToPoint()); if (tempT != null && !characterArea[0].Contains(tempT)) { characterArea[0].Add(tempT); } if (characterArea[0].Count == 0) { characterArea[0].Add(bt.Find(t => t.mapPosition.Location.ToVector2() == character.position)); } } catch { } }
public bool bCanHitTarget(BaseCharacter caster, BaseCharacter target, List <BasicTile> bt) { if (bCanNotTargetSelf && caster == target) { return(false); } if (IsAbilityAvailable(caster.trueSTATChart())) { if (MapListUtility.returnValidMapRadius(abilityMinRange, abilityMaxRange, bt, target.position).Find(t => t.mapPosition.Location == caster.position.ToPoint()) != null) { return(true); } else { return(false); } } else { return(false); } }
public static void AIPreCalculate(List <BasicTile> moveRadius, CharacterTurn ct) { BaseCharacter caster = ct.character; List <List <BasicTile> > abilityRangesAttack = new List <List <BasicTile> >(); List <List <BasicTile> > abilityRangesSupport = new List <List <BasicTile> >(); List <BaseCharacter> possibleTargetCharsAttack = new List <BaseCharacter>(); List <BaseCharacter> possibleTargetCharsSupport = new List <BaseCharacter>(); List <BaseCharacter> possibleAITargetsAttack = new List <BaseCharacter>(); List <BaseCharacter> possibleAITargetsSupport = new List <BaseCharacter>(); possibleAITargets.Clear(); List <BasicAbility> attackAbilities = caster.AbilityList().FindAll(abi => abi.abilityType == (int)BasicAbility.ABILITY_TYPE.ATTACK); List <BasicAbility> supportAbilities = caster.AbilityList().FindAll(abi => abi.abilityType == (int)BasicAbility.ABILITY_TYPE.SUPPORT); bool bCharHasSupportAbis = supportAbilities.Count > 0; #region supportCheck if (bCharHasSupportAbis) { var listOfCharactersTemp = ct.parentTS.charactersInGroup; foreach (var character in listOfCharactersTemp) { if (character.bIsAlive) { possibleTargetCharsSupport.Add(character); } } foreach (var ability in supportAbilities) { foreach (var character in possibleTargetCharsSupport) { if (character.NeedsHealing(3)) { abilityRangesSupport.Add(MapListUtility.returnValidMapRadius(ability.abilityMinRange, ability.abilityMaxRange, CombatProcessor.zoneTiles, (character.position / 64).ToPoint().ToVector2() * 64)); Vector2 positionGridCaster = new Vector2((int)(caster.position.X / 64), (int)(caster.position.Y / 64)); var test = abilityRangesSupport[abilityRangesSupport.Count - 1].Find(t => moveRadius.Contains(t) || (t.positionGrid.X == positionGridCaster.X && t.positionGrid.Y == positionGridCaster.Y)); if (test != null) { if (!possibleAITargetsSupport.Contains(character)) { possibleAITargetsSupport.Add(character); } } } } } } #endregion var listOfCharacters = ct.parentTS.targetGroups[GamePlayUtility.Randomize(0, ct.parentTS.targetGroups.Count - 1)].charactersInGroup; if (attackAbilities.Count != 0) { foreach (var character in listOfCharacters) { if (character.bIsAlive) { possibleTargetCharsAttack.Add(character); } } } if (possibleAITargetsSupport.Count == 0 && attackAbilities.Count != 0) { bCharHasSupportAbis = false; //If nothing is in need of healing, try prioiritize attacking instead. } foreach (var ability in attackAbilities) { if (ability.IsAbilityAvailable(caster.trueSTATChart())) { if (ability.abilityFightStyle == (int)BasicAbility.ABILITY_CAST_TYPE.MELEE) { foreach (var character in possibleTargetCharsAttack) { abilityRangesAttack.Add(MapListUtility.returnValidMapRadius(ability.abilityMinRange, ability.abilityMaxRange, CombatProcessor.zoneTiles, (character.position / 64).ToPoint().ToVector2() * 64)); Vector2 positionGridCaster = new Vector2((int)(caster.position.X / 64), (int)(caster.position.Y / 64)); var test = abilityRangesAttack[abilityRangesAttack.Count - 1].Find(t => moveRadius.Contains(t) || (t.positionGrid.X == positionGridCaster.X && t.positionGrid.Y == positionGridCaster.Y)); if (test != null) { if (!possibleAITargetsAttack.Contains(character)) { possibleAITargetsAttack.Add(character); } } } } else if (ability.abilityFightStyle == (int)BasicAbility.ABILITY_CAST_TYPE.RANGED || ability.abilityFightStyle == (int)BasicAbility.ABILITY_CAST_TYPE.MAGIC) { abilityRangesAttack.Add(MapListUtility.returnValidMapRadius(ability.abilityMinRange, ability.abilityMaxRange, CombatProcessor.zoneTiles, (caster.position / 64).ToPoint().ToVector2() * 64)); foreach (var item in possibleTargetCharsAttack) { if (ability.abilityCanHitTargetInRange(caster, item)) { if (!possibleAITargetsAttack.Contains(item)) { possibleAITargetsAttack.Add(item); } } } } //else if (ability.abilityFightStyle == (int)BasicAbility.ABILITY_CAST_TYPE.RANGED) //{ // abilityRanges.Add(MapListUtility.returnValidMapRadius(ability.abilityMinRange, ability.abilityMaxRange, CombatProcessor.zoneTiles, (caster.position / 64).ToPoint().ToVector2() * 64)); // foreach (var item in heroCharactersStillAlive) // { // if (ability.abilityCanHitTargetInRange(caster, item)) // { // if (!possibleAITargets.Contains(item)) // { // possibleAITargets.Add(item); // } // } // } //} } } if (!bCharHasSupportAbis) { possibleAITargets = new List <BaseCharacter>(possibleAITargetsAttack); } else { bool bShouldSupport = false; float percentageSupportAbis = (float)((float)supportAbilities.Count / (float)caster.AbilityList().Count); float percentageAttackAbis = 1 - percentageSupportAbis; percentageSupportAbis *= 100f; percentageAttackAbis *= 100f; int amountOfEnemies = possibleAITargetsAttack.Count(); int amountOfAlliesInNeed = possibleAITargetsSupport.Count(); if (amountOfAlliesInNeed > amountOfEnemies) { int percent = GamePlayUtility.Randomize(30, (int)(percentageSupportAbis + 20)); if (percent > GamePlayUtility.Randomize(40, 70)) { bShouldSupport = true; } } if (bShouldSupport) { possibleAITargets = new List <BaseCharacter>(possibleAITargetsSupport); bDoSupport = true; } else if (possibleTargetCharsAttack.Count != 0) { possibleAITargets = new List <BaseCharacter>(possibleAITargetsAttack); bDoSupport = false; } } }
public static KeyValuePair <List <List <BasicTile> >, List <BasicAbility> > returnTilesToAttackFrom(List <BasicTile> moveRadius, List <BasicTile> allTiles, BaseCharacter caster, BaseCharacter target) { List <BasicAbility> tempAbilityList = new List <BasicAbility>(); List <List <BasicTile> > abilityRanges = new List <List <BasicTile> >(); // Console.WriteLine("---------------Report Begin----------"); // Console.WriteLine("Checking if enemy has an ability to attack the selected partymember with: " + caster.CharacterName + caster.position); List <BasicAbility> abilityCheckList = new List <BasicAbility>(); if (bDoSupport) { abilityCheckList.AddRange(caster.AbilityList().FindAll(abi => abi.abilityType == (int)BasicAbility.ABILITY_TYPE.SUPPORT)); } else { abilityCheckList.AddRange(caster.AbilityList().FindAll(abi => abi.abilityType == (int)BasicAbility.ABILITY_TYPE.ATTACK)); } foreach (var ability in abilityCheckList) { if (ability.IsAbilityAvailable(caster.trueSTATChart())) { if (ability.abilityType == (int)BasicAbility.ABILITY_TYPE.ATTACK && ability.abilityFightStyle == (int)BasicAbility.ABILITY_CAST_TYPE.MELEE && (ability.targetableTypes.Contains(target.CCC.equippedClass.classType) || ability.targetableTypes.Count == 0)) { abilityRanges.Add(MapListUtility.returnValidMapRadius(ability.abilityMinRange, ability.abilityMaxRange, allTiles, (target.position / 64).ToPoint().ToVector2() * 64)); var test = abilityRanges[abilityRanges.Count - 1].Find(t => moveRadius.Contains(t)); if (test != null) { tempAbilityList.Add(ability); Console.WriteLine(ability.ToString() + " is in range!"); } else { abilityRanges.RemoveAt(abilityRanges.Count - 1); } } else if (ability.abilityType == (int)BasicAbility.ABILITY_TYPE.ATTACK && (ability.abilityFightStyle == (int)BasicAbility.ABILITY_CAST_TYPE.RANGED || ability.abilityFightStyle == (int)BasicAbility.ABILITY_CAST_TYPE.MAGIC) && (ability.targetableTypes.Contains(target.CCC.equippedClass.classType) || ability.targetableTypes.Count == 0)) { if (ability.abilityCanHitTargetInRange(caster, target)) { abilityRanges.Add(MapListUtility.returnValidMapRadius(ability.abilityMinRange, ability.abilityMaxRange, allTiles, (target.position / 64).ToPoint().ToVector2() * 64)); tempAbilityList.Add(ability); Console.WriteLine(ability.ToString() + " is in range!"); } else { // abilityRanges.RemoveAt(abilityRanges.Count - 1); } } else if (ability.abilityType == (int)BasicAbility.ABILITY_TYPE.SUPPORT && (ability.targetableTypes.Contains(target.CCC.equippedClass.classType) || ability.targetableTypes.Count == 0)) { abilityRanges.Add(MapListUtility.returnValidMapRadius(ability.abilityMinRange, ability.abilityMaxRange, allTiles, (target.position / 64).ToPoint().ToVector2() * 64)); var test = abilityRanges[abilityRanges.Count - 1].Find(t => moveRadius.Contains(t)); if (test != null) { tempAbilityList.Add(ability); Console.WriteLine(ability.ToString() + " is in range!"); } else { // abilityRanges.RemoveAt(abilityRanges.Count - 1); } } } } List <BasicTile> temp = new List <BasicTile>(); foreach (var range in abilityRanges) { temp.AddRange(range.Except(temp)); } temp.RemoveAll(t => !moveRadius.Contains(t)); if (abilityRanges.Count == 0 && tempAbilityList.Count != 0) { abilityRanges.Add(new List <BasicTile>()); } // Console.WriteLine("---------------Report End----------"); return(new KeyValuePair <List <List <BasicTile> >, List <BasicAbility> >(abilityRanges, tempAbilityList)); }
internal void UpdateEnemyLogic(CharacterTurn gts) { if (!PathMoveHandler.bIsBusy) { PathMoveHandler.SkipPathMovement(); } if (gts != null && !LUA.LuaExecutionList.DemandOverride() && !PathMoveHandler.bIsBusy && !bTest && BattleGUI.TurnEffectsList.Find(te => te.bMustShow) == null) { if (bPlayerTurnEnemyOverriden) { gts = currentEnemy; } if (GameProcessor.cameraFollowTarget != gts.character) { GameProcessor.cameraFollowTarget = gts.character; } bTest = true; //randomEnemy = GamePlayUtility.Randomize(0, CombatProcessor.heroCharacters.Count - 1); selectedCharTurn = null; currentEnemy = gts; AIUtility.AIPreCalculate(gts.returnCompleteArea(), gts); //AIUtility.Report(AIBehaviour.ProcessBehaviour(currentEnemy.character,AIUtility.possibleAITargets)); BaseCharacter target = null; var temp = AIBehaviour.ProcessBehaviour(currentEnemy.character, AIUtility.possibleAITargets); if (temp.Count != 0) { target = AIUtility.SelectTargetBasedOnBehaviour(temp); } var playableMap = GameProcessor.loadedMap.possibleTilesGameZoneForEnemy(CombatProcessor.zoneTiles, currentEnemy.character); var beep = new KeyValuePair <List <List <BasicTile> >, List <BasicAbility> >(); if (target != null) { // var beep = AIUtility.returnTilesToAttackFrom(CombatProcessor.zoneTiles,gts.character,target); beep = AIUtility.returnTilesToAttackFrom(gts.returnCompleteArea(), playableMap, gts.character, target); while (beep.Key.Count == 0 && beep.Value.Count == 0 && AIUtility.possibleAITargets.Count - 1 > 0) { AIUtility.possibleAITargets.Remove(target); target = AIUtility.SelectTargetBasedOnBehaviour(AIBehaviour.ProcessBehaviour(currentEnemy.character, AIUtility.possibleAITargets)); beep = AIUtility.returnTilesToAttackFrom(playableMap, playableMap, gts.character, target); } } if (target != null && beep.Key.Count == 0 && beep.Value.Count == 0) { target = null; } gts.ReGenerateTurn(playableMap); List <Node> allPossibleNodes; if (target != null) { //allPossibleNodes = PathFinder.NewPathSearch(gts.character.position, target.position + new Vector2(64, 0), playableMap); var enemyFavor = AIUtility.returnFavoredAttackAndPosition(beep, gts.character, target); if (enemyFavor.Key != null) { allPossibleNodes = PathFinder.NewPathSearch(gts.character.position, enemyFavor.Key.mapPosition.Location.ToVector2(), playableMap); } else { allPossibleNodes = null; } AITarget = target; AIbtba = enemyFavor; } else { List <int> amountOfCharsForEachGroup = new List <int>(); List <float> percentagesForEachGroup = new List <float>(); int totalChars = 0; foreach (var item in gts.parentTS.targetGroups) { int tempCount = item.charactersInGroup.FindAll(c => c.IsAlive()).Count; totalChars += tempCount; amountOfCharsForEachGroup.Add(tempCount); } foreach (var item in amountOfCharsForEachGroup) { percentagesForEachGroup.Add(((float)item / (float)totalChars) * 100); } TurnSet targetGroup = null; int tempIndex = 0; while (targetGroup == null) { int randomNumber = GamePlayUtility.Randomize(0, 100); if (percentagesForEachGroup[tempIndex] >= randomNumber) { targetGroup = targetGroups[tempIndex]; } tempIndex++; if (tempIndex > percentagesForEachGroup.Count) { targetGroup = targetGroups[0]; } } BaseCharacter randomCharacter = targetGroup.charactersInGroup.FindAll(c => c.IsAlive())[GamePlayUtility.Randomize(0, targetGroup.charactersInGroup.FindAll(c => c.IsAlive()).Count)]; allPossibleNodes = PathFinder.NewPathSearch(gts.character.position, randomCharacter.position + new Vector2(64, 0), playableMap); } if (allPossibleNodes != null) { CombatProcessor.what = new List <Node>(allPossibleNodes); var NodesWithinRange = MapListUtility.findEqualNodesToTileList(allPossibleNodes, gts.returnCompleteArea()); PathMoveHandler.Start(gts.character, NodesWithinRange); } //FinalizeEnemyRound(); } if (gts != null && !PathMoveHandler.bIsBusy && bTest && !GameProcessor.bStartCombatZoom) { //THIS IS THE VERY LAST LINE BEFORE AN ENEMY HAS IT'S TURN COMPLETED if (!AIbtba.Equals(default(KeyValuePair <BasicTile, BasicAbility>))) { if ((AIbtba.Key == null || AIbtba.Key.mapPosition.Location.ToVector2() == gts.character.position) && AIbtba.Value.abilityCanHitTargetInRange(gts.character, AITarget) && AIbtba.Value.IsAbilityAvailable(gts.character.trueSTATChart())) { FaceCharacterInCorrectDirection(gts.character, AITarget); GameProcessor.StartBattleSoon(gts.character, AITarget, gts.character.AbilityList().IndexOf(AIbtba.Value)); //GameProcessor.StartBattleSoon(gts.character, AITarget, gts.character.AbilityList().IndexOf(gts.character.AbilityList().Find(ba => ba.abilityName.Equals(AIbtba.Value.abilityName)))); } else { if (!currentEnemy.character.attackedAsAI) { LastDitchEffortAttack(); } else { FinalizeEnemyRound(); } } } else { if (!currentEnemy.character.attackedAsAI) { LastDitchEffortAttack(); } else { FinalizeEnemyRound(); } } // } else if (gts == null) { if (bPlayerTurnEnemyOverriden) { bPlayerTurnEnemyOverriden = false; } } }
public void ReGenerateTurn(List <BasicTile> bt) { bAttackedThisCT = false; abiUsedInfo = null; turns.Clear(); characterArea.Clear(); int temp = character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.AP]; int maxMoves = character.trueSTATChart().currentPassiveStats[(int)STATChart.PASSIVESTATS.MOB]; for (int i = 1; i < temp + 1; i++) { turns.Add(new TurnInfo(maxMoves)); if (i > 1) { for (int j = 1; j < 2; j++) { List <BasicTile> list = MapListUtility.returnValidMapRadius((i - 1) * maxMoves + maxMoves, bt, character.position).Except(characterArea[i - 1 - j]).ToList(); characterArea.Add(list); } } else { characterArea.Add(MapListUtility.returnValidMapRadius((i - 1) * maxMoves + maxMoves, bt, character.position)); } } try { var tempT = bt.Find(t => t.positionGrid.ToPoint() == (character.position / 64).ToPoint()); if (tempT != null && !characterArea[0].Contains(tempT)) { characterArea[0].Add(tempT); } if (characterArea[0].Count == 0) { characterArea[0].Add(bt.Find(t => t.mapPosition.Location.ToVector2() == character.position)); } } catch { } bool bStuffToAdjust = false; List <KeyValuePair <BasicTile, int> > allUniqueTiles = new List <KeyValuePair <BasicTile, int> >(); List <KeyValuePair <BasicTile, int> > duplicates = new List <KeyValuePair <BasicTile, int> >(); for (int i = 0; i < characterArea.Count; i++) { for (int j = 0; j < characterArea[i].Count; j++) { if (allUniqueTiles.Find(t => t.Key == characterArea[i][j]).Equals(default(KeyValuePair <BasicTile, int>))) { allUniqueTiles.Add(new KeyValuePair <BasicTile, int>(characterArea[i][j], i)); } else { bStuffToAdjust = true; duplicates.Add(new KeyValuePair <BasicTile, int>(characterArea[i][j], i)); } } } if (bStuffToAdjust) { for (int i = 0; i < duplicates.Count; i++) { characterArea[duplicates[i].Value].Remove(duplicates[i].Key); } } }