private List <Cell> GetTargetCells(EnemyAttack attack, EnemyTarget enemy) { switch (attack.targettingClass) { case TargettingClass.relative: return(RelativeTargetting(attack, enemy)); case TargettingClass.global: return(GlobalTargetting(attack, enemy)); default: Debug.LogError("targetting class not assigned properly"); return(null); } }
private List <Cell> RelativeTargetting(EnemyAttack attack, EnemyTarget enemy) { List <Cell> convertedCells = new List <Cell>(); for (var i = 0; i < attack.relativeTargetCells.Length; i++) { var convertedVector = RelativeCoordinateConversion(enemy.wing, enemy.GetComponent <Mover>().GetGridPos(), attack.relativeTargetCells[i]); if (combatController.ListOfcells.ContainsKey(convertedVector)) { convertedCells.Add(combatController.ListOfcells[convertedVector]); } } return(convertedCells); }
private List <Cell> GlobalTargetting(EnemyAttack attack, EnemyTarget enemy) { List <Cell> convertedCells = new List <Cell>(); for (var i = 0; i < attack.globalTargetCells.Length; i++) { var currentVector = attack.globalTargetCells[i]; if (combatController.ListOfcells.ContainsKey(currentVector)) { convertedCells.Add(combatController.ListOfcells[currentVector]); } } return(convertedCells); }
public void DeathAttack(EnemyAttack ability) { selectedAbility = ability; //apply madness if necessary here selectedTargets = GetTargets(selectedAbility, enemyTarget); float channelTime = selectedAbility.attackChannelTime; //fix to setTargettedCells //attackIndicator.HighlightTargettedCells(selectedAbility, enemyTarget); attackExecutor.PerformAttack(selectedAbility, selectedTargets, enemyTarget, false); channel.StartChannel(selectedAbility.attackChannelTime); selectedTargets.Clear(); GetComponent <PlayerStats>().isDead = true; }
private void Awake() { mover = GetComponent <Mover>(); coolDown = GetComponent <CoolDown>(); channel = GetComponent <Channel>(); combatController = FindObjectOfType <CombatController>(); deathHandler = GetComponent <DeathHandler>(); zodiac = enemy.zodiac; UpdateWingPosition(); speed = enemy.speed; strength = enemy.strength; evasion = enemy.evasion; armor = enemy.armor; health = enemy.health; maxHealth = enemy.health; counterAttack = enemy.counterAttack; }
public void ExecutePushGlobal(Pushable pushable, EnemyAttack ability) { Vector2Int[] targetCellCoords = new Vector2Int[ability.pushForce]; Cell[] targetCells = new Cell[ability.pushForce]; int pushMaximum = 0; if (ability.push == Push.west) { for (var i = ability.pushForce - 1; i > 0; i--) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x + i, pushable.GetGridPos().y); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].isOccupied || targetCells[i].isEnemyCell || targetCells[i] == null) { continue; } pushMaximum = i; break; } for (var i = 0; i < ability.pushForce; i++) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x + i, pushable.GetGridPos().y); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].hasObstacle == true) { if (combatController.ListOfPlayerCells[new Vector2Int(pushable.GetGridPos().x + 1, pushable.GetGridPos().y)].isOccupied) { pushMaximum = 0; break; } if (pushMaximum > i - 1) { pushMaximum = i - 1; } } } } else if (ability.push == Push.east) { for (var i = ability.pushForce - 1; i > 0; i--) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x - i, pushable.GetGridPos().y); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].isOccupied || targetCells[i].isEnemyCell || targetCells[i] == null) { continue; } pushMaximum = i; break; } for (var i = 0; i < ability.pushForce; i++) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x - i, pushable.GetGridPos().y); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].hasObstacle == true) { if (combatController.ListOfPlayerCells[new Vector2Int(pushable.GetGridPos().x - 1, pushable.GetGridPos().y)].isOccupied) { pushMaximum = 0; break; } if (pushMaximum > i - 1) { pushMaximum = i - 1; } } } } else if (ability.push == Push.north) { for (var i = ability.pushForce - 1; i > 0; i--) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y + i); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].isOccupied || targetCells[i].isEnemyCell || targetCells[i] == null) { continue; } pushMaximum = i; break; } for (var i = 0; i < ability.pushForce; i++) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y + i); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].hasObstacle == true) { if (combatController.ListOfPlayerCells[new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y + 1)].isOccupied) { pushMaximum = 0; break; } if (pushMaximum > i - 1) { pushMaximum = i - 1; } } } } else { for (var i = ability.pushForce - 1; i > 0; i--) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y - i); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].isOccupied || targetCells[i].isEnemyCell || targetCells[i] == null) { continue; } pushMaximum = i; break; } for (var i = 0; i < ability.pushForce; i++) { targetCellCoords[i] = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y - i); if (!combatController.ListOfPlayerCells.ContainsKey(targetCellCoords[i])) { continue; } targetCells[i] = combatController.ListOfPlayerCells[targetCellCoords[i]]; if (targetCells[i].hasObstacle == true) { if (combatController.ListOfPlayerCells[new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y - 1)].isOccupied) { pushMaximum = 0; break; } if (pushMaximum > i - 1) { pushMaximum = i - 1; } } } } if (pushMaximum > 0) { pushable.GetComponent <Mover>().Pathfind(targetCells[pushMaximum]); pushable.GetComponent <Mover>().isBeingPushed = true; targetCells[pushMaximum].isOccupied = true; } }
public List <Pushable> MakeListOfPushablesRelative(EnemyAttack ability, EnemyTarget enemyTarget) { Pushable[] pushableArray = FindObjectsOfType <Pushable>(); List <Pushable> listOfPushables = new List <Pushable>(pushableArray); List <Pushable> deleteMeList = new List <Pushable>(); Mover mover = enemyTarget.GetComponent <Mover>(); if (enemyTarget.wing == Wing.port || enemyTarget.wing == Wing.starboard) { listOfPushables.Sort(SortByX); } else { listOfPushables.Sort(SortByY); listOfPushables.Reverse(); } if (enemyTarget.wing == Wing.starboard) { listOfPushables.Reverse(); } bool deleteRest = false; Vector2Int interferenceCheck; foreach (Pushable pushable in listOfPushables) { if (enemyTarget.wing == Wing.port) { if (ability.push == Push.north) { interferenceCheck = new Vector2Int(pushable.GetGridPos().x + 1, pushable.GetGridPos().y); } else { interferenceCheck = new Vector2Int(pushable.GetGridPos().x - 1, pushable.GetGridPos().y); } } else if (enemyTarget.wing == Wing.starboard) { if (ability.push == Push.north) { interferenceCheck = new Vector2Int(pushable.GetGridPos().x - 1, pushable.GetGridPos().y); } else { interferenceCheck = new Vector2Int(pushable.GetGridPos().x + 1, pushable.GetGridPos().y); } } else { if (ability.push == Push.north) { interferenceCheck = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y - 1); } else { interferenceCheck = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y + 1); } } if ((enemyTarget.wing == Wing.starboard) || (enemyTarget.wing == Wing.port)) { if (pushable.GetGridPos().y != mover.GetGridPos().y) { deleteMeList.Add(pushable); continue; } } else { if (pushable.GetGridPos().x != mover.GetGridPos().x) { deleteMeList.Add(pushable); continue; } } if (pushable.GetComponent <Obstacle>() != null) { deleteMeList.Add(pushable); deleteRest = true; } if (combatController.ListOfcells.ContainsKey(interferenceCheck)) { if (combatController.ListOfcells[interferenceCheck].isOccupied) { Obstacle[] obstacles = FindObjectsOfType <Obstacle>(); foreach (Obstacle obstacle in obstacles) { if (obstacle.GetComponent <Pushable>().GetGridPos() == interferenceCheck) { deleteMeList.Add(pushable); break; } } } if (combatController.ListOfcells[interferenceCheck].isEnemyCell) { deleteMeList.Add(pushable); } if (combatController.ListOfcells[interferenceCheck] == null) { deleteMeList.Add(pushable); } } if (deleteRest == true) { deleteMeList.Add(pushable); } } foreach (Pushable pushable in deleteMeList) { listOfPushables.Remove(pushable); } if (ability.push == Push.north) { listOfPushables.Reverse(); } return(listOfPushables); }
public List <Pushable> MakeListOfPushablesGlobal(EnemyAttack ability) { Pushable[] pushableArray = FindObjectsOfType <Pushable>(); List <Pushable> listOfPushables = new List <Pushable>(pushableArray); List <Pushable> deleteMeList = new List <Pushable>(); if (ability.push == Push.north) { listOfPushables.Sort(SortByY); listOfPushables.Reverse(); } else if (ability.push == Push.west) { listOfPushables.Sort(SortByX); listOfPushables.Reverse(); } else if (ability.push == Push.east) { listOfPushables.Sort(SortByX); } else if (ability.push == Push.south) { listOfPushables.Sort(SortByY); } bool deleteRest = false; Vector2Int interferenceCheck; foreach (Pushable pushable in listOfPushables) { if (ability.push == Push.west) { interferenceCheck = new Vector2Int(pushable.GetGridPos().x + 1, pushable.GetGridPos().y); } else if (ability.push == Push.east) { interferenceCheck = new Vector2Int(pushable.GetGridPos().x - 1, pushable.GetGridPos().y); } else if (ability.push == Push.north) { interferenceCheck = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y + 1); } else { interferenceCheck = new Vector2Int(pushable.GetGridPos().x, pushable.GetGridPos().y - 1); } if (pushable.GetComponent <Obstacle>() != null) { deleteMeList.Add(pushable); } if (combatController.ListOfcells.ContainsKey(interferenceCheck)) { if (combatController.ListOfcells[interferenceCheck].isOccupied) { Obstacle[] obstacles = FindObjectsOfType <Obstacle>(); foreach (Obstacle obstacle in obstacles) { if (obstacle.GetComponent <Pushable>().GetGridPos() == interferenceCheck) { deleteMeList.Add(pushable); break; } } } if (combatController.ListOfcells[interferenceCheck].isEnemyCell) { deleteMeList.Add(pushable); } if (combatController.ListOfcells[interferenceCheck] == null) { deleteMeList.Add(pushable); } } if (deleteRest == true) { deleteMeList.Add(pushable); } } foreach (Pushable pushable in deleteMeList) { listOfPushables.Remove(pushable); } return(listOfPushables); }
public void SetNewCounter(EnemyAttack counter) { GetComponent <SpellsEquipped>().counterAttack = counter; }
//switch (stateMachine.state) //{ // //PlayerState // case State.channeling: // channel.CheckChannel(); // Targetting(selectedAbility); // if (!channel.isChanneling) // { // state = State.animating; // } // break; // //PlayerState // case State.animating: // print(attackInProgress); // if (!attackInProgress) // { // AIController[] enemies = FindObjectsOfType<AIController>(); // foreach(AIController enemy in enemies) // { // if (enemy.attackInProgress == true && enemy.gameObject!= this.gameObject) // { // return; // } // } // attackInProgress = true; // PerformAttack(selectedAbility); // } //foreach (Cell cell in attackIndicator.convertedCells) //{ // cell.enemyHighlight = false; // attackIndicator.areCellsColored = false; // cell.DoDefaultColor(); // enemyTarget.SaveMaterial(); // enemyTarget.DoDefaultMaterial(); //} // break; // } //} /* GOALS WITHIN THIS CODE * 1. Segment out a combat controller utilized public method pool. This pool will handle calculations that are universal such as zodiac and magic interactions * 2. AIController should handle the decisions of the AI. Namely, seeing which abilities are available to it. Checking to see which ones are best. and picking between them. * 3. An Attack Executor (should be shared with FIGHTER class) Class should handle distributing damage and effects. It will use the singleton, Combat Controller, to access universal algorithms in calculating damage. * 4. Animation needs to be accounted for with a separate timer. The timer will tick normally when not moving or pushing else it will wait for moving or pushing to complete then issue the same "END OF ANIMATION" method. * 5. AIController should resemble a player brain. Any limitations of the enemy class not related to decision making should be relegated to another class. * 6. NEW CLASSES: CC.AttackAlgorithms, AnimationTimer, AttackExecutor, AttackReceiver, PlayerState */ //Pre targeting for relative global and support targeting //dont think this needed. private List <AttackReceiver> GetTargets(EnemyAttack ability, EnemyTarget enemy) { allPushables = FindObjectsOfType <Pushable>(); List <AttackReceiver> newTargets = new List <AttackReceiver>(); List <Pushable> translatedTargetList = new List <Pushable>(); switch (ability.targettingClass) { case TargettingClass.global: foreach (Pushable pushable in allPushables) { foreach (Vector2Int position in ability.globalTargetCells) { if (pushable.GetComponent <Mover>().GetGridPos() == position) { translatedTargetList.Add(pushable); } } } //remove targets based on beeline targeting if (ability.attackTarget == AttackTarget.beeline) { switch (enemyTarget.wing) { case Wing.bow: translatedTargetList.Sort(SortByY); translatedTargetList.Reverse(); break; case Wing.port: translatedTargetList.Sort(SortByX); break; case Wing.starboard: translatedTargetList.Sort(SortByX); translatedTargetList.Reverse(); break; default: print("NO WING DEFINED"); break; } } //final list foreach (Pushable pushable in translatedTargetList) { if (pushable.GetComponent <AttackReceiver>() != null) { newTargets.Add(pushable.GetComponent <AttackReceiver>()); } if (ability.attackTarget == AttackTarget.beeline) { break; } } break; case TargettingClass.relative: Vector2Int[] translatedTargetCells = TranslateRelativeTargetCells(ability.relativeTargetCells, enemy); //print("allPushables count: " + allPushables.Length); foreach (Pushable pushable in allPushables) { foreach (Vector2Int position in translatedTargetCells) { if (pushable.GetComponent <Mover>().GetGridPos() == position) { translatedTargetList.Add(pushable); //print("adding pushable"); } } } //print("translatedTargetCells: " + translatedTargetList.Count); //remove targets based on beeline targeting if (ability.attackTarget == AttackTarget.beeline) { switch (enemyTarget.wing) { case Wing.bow: translatedTargetList.Sort(SortByY); translatedTargetList.Reverse(); break; case Wing.port: translatedTargetList.Sort(SortByX); break; case Wing.starboard: translatedTargetList.Sort(SortByX); translatedTargetList.Reverse(); break; default: print("NO WING DEFINED"); break; } } //final list foreach (Pushable pushable in translatedTargetList) { if (pushable.GetComponent <AttackReceiver>() != null) { newTargets.Add(pushable.GetComponent <AttackReceiver>()); } if (pushable.GetComponent <Destroyable>() != null) { pushable.GetComponent <Destroyable>().DestroySelf(); } if (ability.attackTarget == AttackTarget.beeline) { break; } } break; case TargettingClass.support: EnemyTarget randomEnemy = SelectRandomSupportTarget(); newTargets.Add(randomEnemy.GetComponent <AttackReceiver>()); break; case TargettingClass.self: newTargets.Add(attackReceiver); break; //this case inherits "melee Target" from the TestAbility method. This is to reduce redundancy in finding available targets. case TargettingClass.melee: if (meleeTarget == null) { print("no melee targets, ATTACK FILTERING ERROR"); } newTargets.Add(meleeTarget.GetComponent <AttackReceiver>()); break; case TargettingClass.homing: Fighter randomActor = SelectRandomHomingTarget(); if (randomActor != null) { newTargets.Add(randomActor.GetComponent <AttackReceiver>()); } break; case TargettingClass.allAllies: foreach (Fighter fighter in allActors) { if (!fighter.isDead) { if (!fighter.isIntangible) { newTargets.Add(fighter.GetComponent <AttackReceiver>()); } } } break; case TargettingClass.allFoes: foreach (EnemyTarget target in allEnemies) { newTargets.Add(target.GetComponent <AttackReceiver>()); } break; default: print("no valid targeting class error."); break; } return(newTargets); }
//tests to see if ability can be used in given context private bool TestAbility(EnemyAttack selectedAbility) { if (selectedAbility.targettingClass == TargettingClass.melee) { Vector2Int[] directions = { Vector2Int.up, Vector2Int.down, Vector2Int.right, Vector2Int.left }; foreach (Fighter fighter in allActors) { foreach (Vector2Int direction in directions) { if (fighter.GetComponent <Mover>().GetGridPos() + direction == mover.GetGridPos()) { if (!fighter.isDead && !fighter.isIntangible) { meleeTarget = fighter; return(true); } } } } return(false); } if (selectedAbility.targettingClass == TargettingClass.support) { if (allEnemies.Length <= 1) { return(false); } } if (selectedAbility.usesRails) { if (selectedAbility.targettingClass == TargettingClass.global) { if (combatController.ListOfcells[selectedAbility.LandingCell].isOccupied) { return(false); } } if (selectedAbility.targettingClass == TargettingClass.relative) { Vector2Int[] targetCells = { selectedAbility.LandingCell }; if (combatController.ListOfcells[TranslateRelativeTargetCells(targetCells, enemyTarget)[0]].isOccupied) { return(false); } } } if (selectedAbility.RequiredCells.Length > 0) { bool matchFound = false; foreach (Vector2Int coord in selectedAbility.RequiredCells) { if (mover.GetGridPos() == coord) { matchFound = true; } } if (!matchFound) { return(false); } } if (selectedAbility.RequiredWing != Wing.none) { if (enemyTarget.wing != selectedAbility.RequiredWing) { return(false); } } return(true); }