public string _SelectAbility(int ID) { Ability ab = abilityList[ID]; Debug.Log(ab.name); string exception = ab.IsAvailable(); if (exception != "") { return(exception); } if (!ab.requireTargetSelection) { ActivateAbility(ab); //no target selection required, fire it away } else { if (onTargetSelectModeE != null) { onTargetSelectModeE(true); //enter target selection phase } inTargetSelectMode = true; validTarget = false; selectedAbilityID = ID; if (ab.indicator != null) { currentIndicator = ab.indicator; } else { currentIndicator = defaultIndicator; if (ab.autoScaleIndicator) { if (ab.singleUnitTargeting) { float gridSize = BuildManager.GetGridSize(); currentIndicator.localScale = new Vector3(gridSize, 1, gridSize); } else { currentIndicator.localScale = new Vector3(ab.GetAOERadius() * 2, 1, ab.GetAOERadius() * 2); } } } currentIndicator.gameObject.SetActive(true); } return(""); }
//apply the ability effect, damage, stun, buff and so on IEnumerator ApplyAbilityEffect(Ability ab, Vector3 pos, Unit tgtUnit = null) { yield return(new WaitForSeconds(ab.effectDelay)); LayerMask mask1 = 1 << LayerManager.LayerTower(); LayerMask mask2 = 1 << LayerManager.LayerCreep(); LayerMask mask3 = 1 << LayerManager.LayerCreepF(); LayerMask mask = mask1 | mask2 | mask3; List <Unit> creepList = new List <Unit>(); List <Unit> towerList = new List <Unit>(); if (tgtUnit == null) { float radius = ab.requireTargetSelection ? ab.GetAOERadius() : Mathf.Infinity; Collider[] cols = Physics.OverlapSphere(pos, radius, mask); if (cols.Length > 0) { for (int i = 0; i < cols.Length; i++) { Unit unit = cols[i].gameObject.GetComponent <Unit>(); if (unit.unitC != null) { creepList.Add(unit.unitC); } if (unit.unitT != null) { towerList.Add(unit.unitT); } } } } else { creepList.Add(tgtUnit); towerList.Add(tgtUnit); } AbilityEffect eff = ab.GetActiveEffect(); for (int n = 0; n < creepList.Count; n++) { if (eff.damageMax > 0) { creepList[n].ApplyDamage(Random.Range(eff.damageMin, eff.damageMax)); } else if (eff.stunChance > 0 && eff.duration > 0) { if (Random.Range(0f, 1f) < eff.stunChance) { creepList[n].ApplyStun(eff.duration); } } else if (eff.slow.IsValid()) { creepList[n].ApplySlow(eff.slow); } else if (eff.dot.GetTotalDamage() > 0) { creepList[n].ApplyDot(eff.dot); } } for (int n = 0; n < towerList.Count; n++) { if (eff.duration > 0) { if (eff.damageBuff > 0) { towerList[n].ABBuffDamage(eff.damageBuff, eff.duration); } else if (eff.rangeBuff > 0) { towerList[n].ABBuffRange(eff.rangeBuff, eff.duration); } else if (eff.cooldownBuff > 0) { towerList[n].ABBuffCooldown(eff.cooldownBuff, eff.duration); } } else if (eff.HPGainMax > 0) { towerList[n].RestoreHP(Random.Range(eff.HPGainMin, eff.HPGainMax)); } } }
//apply the ability effect, damage, stun, buff and so on IEnumerator ApplyAbilityEffect(Ability ab, Vector3 pos, Unit tgtUnit=null){ yield return new WaitForSeconds(ab.effectDelay); LayerMask mask1=1<<LayerManager.LayerTower(); LayerMask mask2=1<<LayerManager.LayerCreep(); LayerMask mask3=1<<LayerManager.LayerCreepF(); LayerMask mask=mask1 | mask2 | mask3; List<Unit> creepList=new List<Unit>(); List<Unit> towerList=new List<Unit>(); if(tgtUnit==null){ float radius=ab.requireTargetSelection ? ab.GetAOERadius() : Mathf.Infinity; Collider[] cols=Physics.OverlapSphere(pos, radius, mask); if(cols.Length>0){ for(int i=0; i<cols.Length; i++){ Unit unit=cols[i].gameObject.GetComponent<Unit>(); if(unit.unitC!=null) creepList.Add(unit.unitC); if(unit.unitT!=null) towerList.Add(unit.unitT); } } } else{ creepList.Add(tgtUnit); towerList.Add(tgtUnit); } AbilityEffect eff=ab.GetActiveEffect(); for(int n=0; n<creepList.Count; n++){ if(eff.damageMax>0){ creepList[n].ApplyDamage(Random.Range(eff.damageMin, eff.damageMax)); } else if(eff.stunChance>0 && eff.duration>0){ if(Random.Range(0f, 1f)<eff.stunChance) creepList[n].ApplyStun(eff.duration); } else if(eff.slow.IsValid()){ creepList[n].ApplySlow(eff.slow); } else if(eff.dot.GetTotalDamage()>0){ creepList[n].ApplyDot(eff.dot); } } for(int n=0; n<towerList.Count; n++){ if(eff.duration>0){ if(eff.damageBuff>0){ towerList[n].ABBuffDamage(eff.damageBuff, eff.duration); } else if(eff.rangeBuff>0){ towerList[n].ABBuffRange(eff.rangeBuff, eff.duration); } else if(eff.cooldownBuff>0){ towerList[n].ABBuffCooldown(eff.cooldownBuff, eff.duration); } } else if(eff.HPGainMax>0){ towerList[n].RestoreHP(Random.Range(eff.HPGainMin, eff.HPGainMax)); } } }
IEnumerator SelectAbilityTargetRoutine(Ability ability, int pointerID = -1) { yield return(null); Vector3 cursorPos = Vector3.zero; Unit targetUnit = null; LayerMask mask = maskAOE; if (ability.singleUnitTargeting) { if (ability.targetType == Ability._TargetType.Hybrid) { mask |= 1 << TDTK.GetLayerTower() | 1 << TDTK.GetLayerCreep(); } else if (ability.targetType == Ability._TargetType.Friendly) { mask |= 1 << TDTK.GetLayerTower(); } else if (ability.targetType == Ability._TargetType.Hostile) { mask |= 1 << TDTK.GetLayerCreep(); } } Transform indicator = ability.indicator; if (indicator == null) { indicator = defaultIndicator; float scale = ability.singleUnitTargeting ? BuildManager.GetGridSize() : ability.GetAOERadius() * 2; indicator.localScale = new Vector3(scale, scale, scale); } //TDTK.OnGameMessage("SelectAbilityTargetRoutine "+pointerID); isSelectingTarget = true; TDTK.OnAbilityTargetSelectModeE(true); if (pointerID >= 0) { while (true) { if (TDTK.IsTouchStarting(pointerID)) { break; } yield return(null); } } bool cursorOnUI = true; while (isSelectingTarget) { if (Input.GetKeyDown(KeyCode.Escape)) { break; } bool invalidCursor = false; bool invalidTarget = false; if (pointerID < 0) { cursorPos = Input.mousePosition; } else { cursorPos = TDTK.GetTouchPosition(pointerID); } if (cursorPos.magnitude < 0) { invalidCursor = true; } if (!invalidCursor && !cursorOnUI) { Ray ray = Camera.main.ScreenPointToRay(cursorPos); RaycastHit hit; if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask)) { indicator.position = hit.point; targetUnit = null; if (ability.singleUnitTargeting) { targetUnit = hit.transform.GetComponent <Unit>(); if (targetUnit != null) { indicator.position = targetUnit.thisT.position; } else { invalidTarget = true; } } } } indicator.gameObject.SetActive(!invalidCursor); if (pointerID == -1) { if (Input.GetMouseButtonDown(0)) { if (cursorOnUI) { break; } if (!invalidTarget) { ActivateAbility(ability, indicator.position, targetUnit); } else { TDTK.OnGameMessage("Invalid target for ability"); } break; } if (Input.GetMouseButtonDown(1)) { break; } } else { if (TDTK.IsTouchEnding(pointerID)) { //TDTK.OnGameMessage("SelectAbilityTargetRoutine "+pointerID+" "+UI.IsCursorOnUI(pointerID)); if (cursorOnUI) { break; } if (!invalidTarget) { ActivateAbility(ability, indicator.position, targetUnit); } else { TDTK.OnGameMessage("Invalid target for ability"); } break; } } //check in previous frame cause IsCursorOnUI wont return true if the touch is ending cursorOnUI = UI.IsCursorOnUI(pointerID); yield return(null); } yield return(null); indicator.gameObject.SetActive(false); isSelectingTarget = false; TDTK.OnAbilityTargetSelectModeE(false); }