IEnumerator OnLeftCursorDown(int pointer = -1) { yield return(null); if (UI.IsCursorOnUI(pointer)) { yield break; } Tile tile = GridManager.GetHoveredTile(); if (tile != null) { if (GameControl.GetGamePhase() == _GamePhase.UnitDeployment) { GridManager.OnCursorDown(); yield break; } if (AbilityManager.InTargetMode()) { GridManager.OnCursorDown(); yield break; } heldTile = tile; holdStartedTime = Time.time; if (touchMode && GridManager.CanAttackTile(GridManager.GetHoveredTile())) { NewClickTile(tile); } else if (touchMode && GridManager.CanMoveToTile(GridManager.GetHoveredTile())) { NewClickTile(tile); } else { if (!GridManager.CanPerformAction(tile)) { //ClearLastClickTile(); dont call last click tile, we dont want to hide unit info if there's any lastClickTile = null; UIInputOverlay.SetNewHoveredTile(null); } else { GridManager.OnCursorDown(); //ClearLastClickTile() will be called as soon as unit move or attack or cast ability } } } else { ClearLastClickTile(); } //~ if(tile!=null){ //~ if(tile.unit!=null){ //~ if(!GameControl.CanSelectUnit(tile.unit)) UIUnitInfo.Show(tile); //~ else{ //~ GridManager.OnCursorDown(); //~ UIUnitInfo.Hide(); //~ return; //~ } //~ } //~ else UIUnitInfo.Hide(); //~ if(touchMode && GridManager.CanAttackTile(GridManager.GetHoveredTile())){ //~ NewClickTile(tile); //~ } //~ else if(touchMode && GridManager.CanMoveToTile(GridManager.GetHoveredTile())){ //~ NewClickTile(tile); //~ } //~ else{ //~ if(!GridManager.CanPerFormAction(tile)){ //~ //ClearLastClickTile(); dont call last click tile, we dont want to hide unit info if there's any //~ lastClickTile=null; //~ UIInputOverlay.SetNewHoveredTile(null); //~ } //~ else GridManager.OnCursorDown(); //ClearLastClickTile() will be called as soon as unit move or attack or cast ability //~ } //~ } //~ else ClearLastClickTile(); }
//called by GameControl to initiate the factions, //load from data when needed, spawn the startingUnit, initiate the unit (abillities), check if unit deployment is required.... public void Init(){ if(instance==null) instance=this; if(generateUnitOnStart) GenerateUnit(); //setup all the unit in the game for(int i=0; i<factionList.Count; i++){ for(int n=0; n<factionList[i].allUnitList.Count; n++){ if(factionList[i].allUnitList[n]==null){ factionList[i].allUnitList.RemoveAt(n); n--; continue; } factionList[i].allUnitList[n].InitUnitAbility(); factionList[i].allUnitList[n].isAIUnit=!factionList[i].isPlayerFaction; } } Vector3 pos=new Vector3(0, 99999, 0); Quaternion rot=Quaternion.identity; for(int i=0; i<factionList.Count; i++){ Faction fac=factionList[i]; //if load from data, then load the list from data and then put it to startingUnitList /* if(fac.loadFromData){ fac.dataList=TBData.GetStartData(fac.dataID); if(fac.dataList!=null && fac.dataList.Count>0){ fac.startingUnitList=new List<Unit>(); for(int n=0; n<fac.dataList.Count; n++) fac.startingUnitList.Add(fac.dataList[n].unit); //put the data list back into the end data first, to save the current starting lineup for next menu loading //in case the player didnt finish the level and GameOver is not called TBData.SetEndData(fac.dataID, fac.dataList); } else fac.loadFromData=false; } if(!fac.loadFromData){ //if using default startingUnitList, make sure none of the element in startingUnitList is empty for(int n=0; n<fac.startingUnitList.Count; n++){ if(fac.startingUnitList[n]==null){ fac.startingUnitList.RemoveAt(n); n-=1; } } } */ if(fac.loadFromData){ fac.startingUnitList=new List<Unit>(); fac.dataList=TBData.GetStartData(fac.dataID); if(fac.dataList==null){ Debug.LogWarning("TBTK faction's data not setup properly", this); continue; } Debug.Log("unit from data: "+fac.dataList.Count); for(int n=0; n<fac.dataList.Count; n++) fac.startingUnitList.Add(fac.dataList[n].unit); //put the data list back into the end data first, to save the current starting lineup for next menu loading //in case the player didnt finish the level and GameOver is not called TBData.SetEndData(fac.dataID, fac.dataList); } else{ //if using default startingUnitList, make sure none of the element in startingUnitList is empty for(int n=0; n<fac.startingUnitList.Count; n++){ if(fac.startingUnitList[n]==null){ fac.startingUnitList.RemoveAt(n); n-=1; } } } for(int n=0; n<fac.startingUnitList.Count; n++){ GameObject unitObj=(GameObject)Instantiate(fac.startingUnitList[n].gameObject, pos, rot); fac.startingUnitList[n]=unitObj.GetComponent<Unit>(); fac.startingUnitList[n].InitUnitAbility(); fac.startingUnitList[n].isAIUnit=!fac.isPlayerFaction; unitObj.transform.parent=transform; unitObj.SetActive(false); if(fac.loadFromData) //fac.startingUnitList[n].ModifyStatsToData(fac.dataList[n], n); fac.dataList[n].CopyStatsToUnit(fac.startingUnitList[n], n); } if(fac.isPlayerFaction && fac.startingUnitList.Count>0 && !requireDeployment){ if(deployingFactionID==-1) deployingFactionID=i; requireDeployment=true; } } if(!GameControl.EnableManualUnitDeployment()){ for(int i=0; i<factionList.Count; i++){ if(factionList[i].startingUnitList.Count<=0) continue; AutoDeployFaction(i); for(int n=0; n<deployedUnitList.Count; n++){ deployedUnitList[n].factionID=factionList[i].ID; factionList[i].allUnitList.Add(deployedUnitList[n]); } deployedUnitList=new List<Unit>(); } } }
bool UpdateDisplay() { if (GridManager.CanMoveToTile(lastHoveredTile)) { indicator.position = lastHoveredTile.GetPos() + new Vector3(0, 0.05f, 0); indicator.gameObject.SetActive(true); } else { indicator.gameObject.SetActive(false); } if (GridManager.CanMoveToTile(lastHoveredTile) && GameControl.UseAPForMove()) { verticalOffset = -65; tooltipPanelBodyObj.SetActive(false); UpdateTooltipPos(); lbAction.text = "Move"; lbAPCost.text = GameControl.GetSelectedUnit().GetMoveAPCostToTile(lastHoveredTile) + "AP"; return(true); } if (GridManager.CanAttackTile(lastHoveredTile)) { verticalOffset = 0; tooltipPanelBodyObj.SetActive(true); UpdateTooltipPos(); Unit selectedUnit = GameControl.GetSelectedUnit(); lbAction.text = "Attack"; if (GameControl.UseAPForAttack()) { lbAPCost.text = ""; } else { lbAPCost.text = selectedUnit.GetAttackAPCost().ToString("f0") + "AP"; } AttackInstance attInstance = selectedUnit.GetAttackInfo(lastHoveredTile.unit); if (!attInstance.isMelee) { lbDamage.text = selectedUnit.GetDamageMin() + "-" + selectedUnit.GetDamageMax(); } else { lbDamage.text = selectedUnit.GetDamageMinMelee() + "-" + selectedUnit.GetDamageMaxMelee(); } lbChance.text = (attInstance.hitChance * 100).ToString("f0") + "%\n"; lbChance.text += (attInstance.critChance * 100).ToString("f0") + "%\n"; return(true); } return(false); }
//analyse the grid to know where the unit should move to private Tile Analyse(Unit unit, _AIMode activeMode) { //get all wakable tiles in range first List <Tile> walkableTilesInRange = GridManager.GetTilesWithinDistance(unit.tile, unit.GetEffectiveMoveRange(), true); walkableTilesInRange.Add(unit.tile); //get all visible hostile List <Unit> allHostileInSight = FactionManager.GetAllHostileUnit(unit.factionID); if (GameControl.EnableFogOfWar()) { for (int i = 0; i < allHostileInSight.Count; i++) { if (!FogOfWar.IsTileVisibleToFaction(allHostileInSight[i].tile, unit.factionID)) { allHostileInSight.RemoveAt(i); i -= 1; } } } //if cover system is in used if (GameControl.EnableCover()) { Tile tile = AnalyseCoverSystem(unit, walkableTilesInRange, allHostileInSight); if (tile != null) { return(tile); } } //if there are hostile if (allHostileInSight.Count > 0) { //fill up the walkableTilesInRange hostile list //then filter thru walkableTilesInRange, those that have a hostile in range will be add to a tilesWithHostileInRange List <Tile> tilesWithHostileInRange = new List <Tile>(); GridManager.SetupHostileInRangeforTile(unit, walkableTilesInRange); for (int i = 0; i < walkableTilesInRange.Count; i++) { if (walkableTilesInRange[i].GetHostileInRange().Count > 0) { tilesWithHostileInRange.Add(walkableTilesInRange[i]); } } //if the tilesWithHostileInRange is not empty after the process, means there's tiles which the unit can move into and attack //return one of those in the tilesWithHostileInRange so the unit can attack if (tilesWithHostileInRange.Count > 0) { //if the unit current tile is one of those tiles with hostile, just stay put and attack if (tilesWithHostileInRange.Contains(unit.tile)) { //randomize it a bit so the unit do move around but not stay in place all the time if (Random.Range(0f, 1f) > 0.25f) { return(unit.tile); } } return(tilesWithHostileInRange[Random.Range(0, tilesWithHostileInRange.Count)]); } } //if there's not potential target at all, check if the unit has any previous attacker //if there are, go after the last attacker if (unit.lastAttacker != null) { return(unit.lastAttacker.tile); } //for aggresive mode with FogOfWar disabled, try move towards the nearest unit if (activeMode == _AIMode.Aggressive && Random.Range(0f, 1f) > 0.25f) { List <Unit> allHostile = FactionManager.GetAllHostileUnit(unit.factionID); float nearest = Mathf.Infinity; int nearestIndex = 0; for (int i = 0; i < allHostile.Count; i++) { float dist = GridManager.GetDistance(allHostile[i].tile, unit.tile); if (dist < nearest) { nearest = dist; nearestIndex = i; } } return(allHostile[nearestIndex].tile); } //if there's really no hostile to go after, then just move randomly in one of the walkable int rand = Random.Range(0, walkableTilesInRange.Count); //clear in hostileInRange list for all moveable tile so, just in case the list is not empty (hostileInRange dont clear after each move) //so the unit dont try to attack anything when it moves into the targetTile walkableTilesInRange[rand].SetHostileInRange(new List <Tile>()); return(walkableTilesInRange[rand]); }
private bool requireDeployment=false; //set to true when user need to manually deploy the starting units public static bool RequireManualUnitDeployment(){ return GameControl.EnableManualUnitDeployment() & instance.requireDeployment; }
public void OnRestartButton() { GameControl.RestartScene(); }
public void OnMenuButton() { GameControl.LoadMainMenu(); }
public static bool InLOS(Tile tile1, Tile tile2, float peekFactor, bool debugging = false) { Vector3 pos1 = tile1.GetPos(); Vector3 pos2 = tile2.GetPos(); if (peekFactor < 0) { peekFactor = GameControl.GetPeekFactor(); } float dist = Vector3.Distance(pos2, pos1); Vector3 dir = (pos2 - pos1).normalized; Vector3 dirO = new Vector3(-dir.z, 0, dir.x).normalized; float posOffset = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio() * peekFactor; LayerMask mask = 1 << TBTK.GetLayerObstacleFullCover(); // | 1<<LayerManager.GetLayerObstacleHalfCover(); bool flag = false; if (!LOSRaycast(pos1, dir, dist, mask, debugging)) { if (debugging) { flag = true; } else { return(true); } } if (posOffset == 0) { return(flag); } if (!LOSRaycast(pos1 + dirO * posOffset, dir, dist, mask, debugging)) { if (debugging) { flag = true; } else { return(true); } } if (!LOSRaycast(pos1 - dirO * posOffset, dir, dist, mask, debugging)) { if (debugging) { flag = true; } else { return(true); } } return(flag); }
public void Init() { if (init) { return; } init = true; thisT = transform; Transform deploymentIndicator = null; Transform moveableIndicator = null; Transform hostileIndicator = null; Transform abRangeIndicator = null; Transform abTargetIndicator = null; if (GridManager.GetTileType() == _TileType.Hex) { deploymentIndicator = hexDeployment; moveableIndicator = hexMoveable; hostileIndicator = hexHostile; abRangeIndicator = hexAbRange; abTargetIndicator = hexAbTarget; cursorIndicatorF = (Transform)Instantiate(hexCursorF); cursorIndicatorH = (Transform)Instantiate(hexCursorH); selectIndicator = (Transform)Instantiate(hexSelected); } else if (GridManager.GetTileType() == _TileType.Square) { deploymentIndicator = sqDeployment; moveableIndicator = sqMoveable; hostileIndicator = sqHostile; abRangeIndicator = sqAbRange; abTargetIndicator = sqAbTarget; cursorIndicatorF = (Transform)Instantiate(sqCursorF); cursorIndicatorH = (Transform)Instantiate(sqCursorH); selectIndicator = (Transform)Instantiate(sqSelected); } cursorIndicatorF.parent = thisT; cursorIndicatorH.parent = thisT; selectIndicator.parent = thisT; for (int i = 0; i < 20; i++) { deploymentIndicatorList.Add((Transform)Instantiate(deploymentIndicator)); deploymentIndicatorList[i].gameObject.SetActive(false); deploymentIndicatorList[i].parent = thisT; } for (int i = 0; i < 20; i++) { moveableIndicatorList.Add((Transform)Instantiate(moveableIndicator)); moveableIndicatorList[i].gameObject.SetActive(false); moveableIndicatorList[i].parent = thisT; } for (int i = 0; i < 10; i++) { hostileIndicatorList.Add((Transform)Instantiate(hostileIndicator)); hostileIndicatorList[i].gameObject.SetActive(false); hostileIndicatorList[i].parent = thisT; } for (int i = 0; i < 20; i++) { abRangeIndicatorList.Add((Transform)Instantiate(abRangeIndicator)); abRangeIndicatorList[i].gameObject.SetActive(false); abRangeIndicatorList[i].parent = thisT; } for (int i = 0; i < 20; i++) { abTargetIndicatorList.Add((Transform)Instantiate(abTargetIndicator)); abTargetIndicatorList[i].gameObject.SetActive(false); abTargetIndicatorList[i].parent = thisT; } if (TurnControl.GetTurnMode() == _TurnMode.FactionPerTurn) { //create the moved indicator for (int i = 0; i < 10; i++) { movedIndicatorList.Add((Transform)Instantiate(movedIndicator)); movedIndicatorList[i].gameObject.SetActive(false); movedIndicatorList[i].parent = thisT; } } if (GameControl.EnableFogOfWar()) { Transform fogObj = null; if (GridManager.GetTileType() == _TileType.Hex) { fogObj = hexFogObj; } else if (GridManager.GetTileType() == _TileType.Square) { fogObj = sqFogObj; } List <Tile> tileList = GridManager.GetTileList(); for (int i = 0; i < tileList.Count; i++) { //if(!tileList[i].walkable) continue; tileList[i].SetFogOfWarObj((Transform)Instantiate(fogObj)); } } if (GameControl.EnableCover()) { float scaleOffset = GridManager.GetTileType() == _TileType.Hex ? 0.5f : 0.8f; float tileSize = GridManager.GetTileSize(); for (int i = 0; i < 5; i++) { coverOverlayHList.Add((Transform)Instantiate(coverOverlayH)); coverOverlayFList.Add((Transform)Instantiate(coverOverlayF)); coverOverlayHList[i].localScale *= tileSize * scaleOffset; coverOverlayHList[i].parent = thisT; coverOverlayHList[i].gameObject.SetActive(false); coverOverlayFList[i].localScale *= tileSize * scaleOffset; coverOverlayFList[i].parent = thisT; coverOverlayFList[i].gameObject.SetActive(false); } } }
public void OnContinueButton() { GameControl.LoadNextScene(); }
public void Init() { for (int i = 0; i < tileList.Count; i++) { tileList[i].Init(); } GridManager gridManager = GridManager.GetInstance(); //setup the neighbour of each tile if (gridManager.tileType == _TileType.Square) { float distTH = gridManager.tileSize * gridManager.gridToTileRatio * 1.1f; for (int i = 0; i < tileList.Count; i++) { Tile tile = tileList[i]; tile.aStar = new TileAStar(tile); List <Tile> neighbourList = new List <Tile>(); int nID = i + 1; if (nID < tileList.Count && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i + gridManager.length; if (nID < tileList.Count && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i - 1; if (nID >= 0 && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i - gridManager.length; if (nID >= 0 && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } //tile.aStar.straightNeighbourCount=neighbourList.Count; //diagonal neighbour, not in used if (GridManager.EnableDiagonalNeighbour()) { nID = (i + 1) + gridManager.length; if (nID < tileList.Count && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH * 1.5f) { neighbourList.Add(tileList[nID]); } nID = (i + 1) - gridManager.length; if (nID >= 0 && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH * 1.5f) { neighbourList.Add(tileList[nID]); } nID = (i - 1) + gridManager.length; if (nID < tileList.Count && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH * 1.5f) { neighbourList.Add(tileList[nID]); } nID = (i - 1) - gridManager.length; if (nID >= 0 && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH * 1.5f) { neighbourList.Add(tileList[nID]); } } tile.aStar.SetNeighbourList(neighbourList); } } else if (gridManager.tileType == _TileType.Hex) { float distTH = GridGenerator.spaceZHex * gridManager.tileSize * gridManager.gridToTileRatio * 1.1f; for (int i = 0; i < tileList.Count; i++) { Tile tile = tileList[i]; tile.aStar = new TileAStar(tile); List <Tile> neighbourList = new List <Tile>(); int nID = i + 1; if (nID < tileList.Count && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i + gridManager.length; if (nID < tileList.Count && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i + gridManager.length - 1; if (nID < tileList.Count && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i - 1; if (nID >= 0 && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i - gridManager.length; if (nID >= 0 && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } nID = i - gridManager.length + 1; if (nID >= 0 && Vector3.Distance(tile.GetPosG(), tileList[nID].GetPosG()) <= distTH) { neighbourList.Add(tileList[nID]); } tile.aStar.SetNeighbourList(neighbourList); //tile.aStar.straightNeighbourCount=neighbourList.Count; } } //setup the wall for (int i = 0; i < tileList.Count; i++) { tileList[i].InitWall(); } if (GridManager.EnableDiagonalNeighbour()) { for (int i = 0; i < tileList.Count; i++) { tileList[i].CheckDiagonal(); } } //setup the cover if (GameControl.EnableCover()) { for (int i = 0; i < tileList.Count; i++) { CoverSystem.InitCoverForTile(tileList[i]); } } }
void Awake() { instance = this; TBData.ClearEndData(); SettingDB settingDB = InitSetting(); if (enableCover) { CoverSystem.SetFullCoverDodgeBonus(fullCoverBonus); CoverSystem.SetHalfCoverDodgeBonus(halfCoverBonus); CoverSystem.SetExposedCritChanceBonus(exposedCritBonus); } //get the instance of each component and initiate them, the order in which these component matters PerkManager perkManager = (PerkManager)FindObjectOfType(typeof(PerkManager)); if (perkManager != null) { perkManager.Init(); } AbilityManagerUnit abManagerUnit = (AbilityManagerUnit)FindObjectOfType(typeof(AbilityManagerUnit)); if (abManagerUnit != null) { abManagerUnit.Init(); } AbilityManagerFaction abManagerFac = (AbilityManagerFaction)FindObjectOfType(typeof(AbilityManagerFaction)); if (abManagerFac != null) { abManagerFac.Init(); } TurnControl turnControl = (TurnControl)FindObjectOfType(typeof(TurnControl)); turnControl.Init(); if (settingDB != null) { turnControl.turnMode = settingDB.turnMode; turnControl.moveOrder = settingDB.moveOrder; } GridManager gridManager = (GridManager)FindObjectOfType(typeof(GridManager)); if (settingDB != null) { gridManager.generateGridOnStart = settingDB.generateGridOnStart; } gridManager.Init(); FactionManager factionManager = (FactionManager)FindObjectOfType(typeof(FactionManager)); if (settingDB != null) { factionManager.generateUnitOnStart = settingDB.generateUnitOnStart; } factionManager.Init(); CollectibleManager collectibleManager = (CollectibleManager)FindObjectOfType(typeof(CollectibleManager)); if (settingDB != null) { collectibleManager.generateCollectibleOnStart = settingDB.generateCollectibleOnStart; } collectibleManager.Init(); GridManager.SetupGridForFogOfWar(); OverlayManager overlayManager = (OverlayManager)FindObjectOfType(typeof(OverlayManager)); overlayManager.Init(); defaultShootObject = Resources.Load("ScenePrefab/DefaultShootObject", typeof(GameObject)) as GameObject; gamePhase = _GamePhase.Initialization; }
private void CalculateChance() { if (calculated) { return; } calculated = true; float coverDodgeBonus = 0; float exposedCritBonus = 0; //if cover system is enabled, get the dodge and crit bonus if (GameControl.EnableCover()) { coverType = CoverSystem.GetCoverType(srcUnit.tile, tgtUnit.tile); if (coverType == CoverSystem._CoverType.Half) { coverDodgeBonus = CoverSystem.GetHalfCoverDodgeBonus(); } else if (coverType == CoverSystem._CoverType.Full) { coverDodgeBonus = CoverSystem.GetFullCoverDodgeBonus(); } else { exposedCritBonus = CoverSystem.GetExposedCritChanceBonus(); } } //calculate the hit chance float hit = !isMelee?srcUnit.GetHitChance() : srcUnit.GetHitChanceMelee(); float dodge = tgtUnit.GetDodgeChance() + coverDodgeBonus; hitChance = Mathf.Clamp(hit - dodge, 0f, 1f); //calculate the critical chance float critHit = (!isMelee ? srcUnit.GetCritChance() : srcUnit.GetCritChanceMelee()) + exposedCritBonus; float critAvoid = tgtUnit.GetCritAvoidance(); critChance = Mathf.Clamp(critHit - critAvoid, 0f, 1f); //calculate stun chance float stunHit = srcUnit.GetStunChance(); float stunAvoid = tgtUnit.GetStunAvoidance(); stunChance = Mathf.Clamp(stunHit - stunAvoid, 0f, 1f); //calculate silent chance float silentHit = srcUnit.GetSilentChance(); float silentAvoid = tgtUnit.GetSilentAvoidance(); silentChance = Mathf.Clamp(silentHit - silentAvoid, 0f, 1f); if (isOverwatch) { hitChance -= GameControl.GetOverwatchHitPenalty(); critHit -= GameControl.GetOverwatchCritPenalty(); } //check if flanking is enabled an applicable in this instance if (GameControl.EnableFlanking()) { //Vector2 dir=new Vector2(srcUnit.tile.pos.x-tgtUnit.tile.pos.x, srcUnit.tile.pos.z-tgtUnit.tile.pos.z); float angleTH = 180 - Mathf.Min(180, GameControl.GetFlankingAngle()); Quaternion attackRotation = Quaternion.LookRotation(tgtUnit.tile.GetPos() - srcUnit.tile.GetPos()); //Debug.Log(Quaternion.Angle(attackRotation, tgtUnit.thisT.rotation)+" "+angleTH); if (Quaternion.Angle(attackRotation, tgtUnit.thisT.rotation) < angleTH) { flanked = true; } } }
//do the stats processing public void Process() { if (processed) { return; } if (isAbility) //if this instance is for ability, then there's no need to calculate the rest of the stats { if (Random.Range(0f, 1f) > hitChance) { missed = true; return; } } processed = true; //first determine all the chances and condition CalculateChance(); //if the attack missed, skip the rest of the calculation if (Random.Range(0f, 1f) > hitChance) { missed = true; return; } //get the base damage if (!isMelee) { damage = Random.Range(srcUnit.GetDamageMin(), srcUnit.GetDamageMax()); } else { damage = Random.Range(srcUnit.GetDamageMinMelee(), srcUnit.GetDamageMaxMelee()); } //modify the damage with damage to armor modifier int armorType = tgtUnit.armorType; int damageType = srcUnit.damageType; damageTableModifier = DamageTable.GetModifier(armorType, damageType); damage *= damageTableModifier; //if this is a counter attack, modify the damage with counter modifier if (isCounter) { damage *= GameControl.GetCounterDamageMultiplier(); } //this the target is flanked, apply the flanking bonus if (!isCounter && flanked) { flankingBonus = 1 + GameControl.GetFlankingBonus() + srcUnit.GetFlankingBonus() - tgtUnit.GetFlankedModifier(); damage *= flankingBonus; } //if the attack crits, add the critical multiplier if (Random.Range(0f, 1f) < critChance) { critical = true; damage *= srcUnit.GetCritMultiplier(); //damage*=!isMelee ? srcUnit.GetCritMultiplier() : srcUnit.GetCritMultiplierMelee(); } //if the attack stuns the target, get the stun duration if (Random.Range(0f, 1f) < stunChance) { stunned = true; stun = srcUnit.GetStunDuration(); } //if the attack stuns the target, get the stun duration if (Random.Range(0f, 1f) < silentChance) { silenced = true; silent = srcUnit.GetSilentDuration(); } //check if the unit is destroyed in this instance and make the destroyed flag according if (damage > tgtUnit.HP) { destroyed = true; } //Debug.Log("Damage: "+damage); //new TextOverlay(tgtUnit.GetTargetT().position, damage.ToString("f0"), Color.white); }
//~ public void ActivateTargetModeUnit(Tile tile, int range, int AOE, bool normalAttack, bool requireDirectLOS, _TargetType type, TargetModeCallBack sCallBack, TargetModeCallBack eCallBack){ public void ActivateTargetModeUnit(Tile tile, UnitAbility ability, int abIndex, TargetModeCallBack sCallBack, ExitTargetModeCallBack eCallBack) { TBTK.OnUnitABTargetMode(abIndex); _ActivateTargetMode(abIndex, ability.GetAOERange(), ability.targetType, sCallBack, eCallBack); if (!ability.AttackInLine()) { if (!ability.normalAttack) { if (targetModeType == _TargetType.EmptyTile) { targetModeTileList = GridManager.GetTilesWithinDistance(tile, ability.GetRange(), true); } else { targetModeTileList = GridManager.GetTilesWithinDistance(tile, ability.GetRange()); } } else { targetModeTileList = new List <Tile>(); List <Tile> tilesInRangeList = GridManager.GetTilesWithinDistance(tile, ability.GetRange()); int sight = tile.unit.GetSight(); List <Unit> allFriendlyUnitList = FactionManager.GetAllUnitsOfFaction(tile.unit.factionID); for (int i = 0; i < tilesInRangeList.Count; i++) { Tile targetTile = tilesInRangeList[i]; if (!GameControl.EnableFogOfWar() && !GameControl.AttackThroughObstacle()) { if (!FogOfWar.InLOS(tile, targetTile, 0)) { continue; } } bool inSight = GameControl.EnableFogOfWar() ? false : true; if (GameControl.EnableFogOfWar()) { if (FogOfWar.InLOS(tile, targetTile) && GridManager.GetDistance(tile, targetTile) <= sight) { inSight = true; } else if (!ability.requireDirectLOS) { for (int n = 0; n < allFriendlyUnitList.Count; n++) { if (allFriendlyUnitList[n] == tile.unit) { continue; } if (GridManager.GetDistance(allFriendlyUnitList[n].tile, targetTile) > allFriendlyUnitList[n].GetSight()) { continue; } if (FogOfWar.InLOS(allFriendlyUnitList[n].tile, targetTile)) { inSight = true; break; } } } } if (inSight) { targetModeTileList.Add(targetTile); } } } } else { /* * List<Tile> neighbourList=tile.GetNeighbourList(); * for(int i=0; i<neighbourList.Count; i++){ * bool walkableOnly=(ability.type==UnitAbility._AbilityType.ChargeAttack); * List<Tile> tileList=GridManager.GetTilesInALine(tile, neighbourList[i], ability.GetRange(), walkableOnly); * * if(tileList.Count>0){ * if(targetModeType!=_TargetType.EmptyTile) targetModeTileList.Add(tileList[tileList.Count-1]); * else if (tileList[tileList.Count-1].unit==null) targetModeTileList.Add(tileList[tileList.Count-1]); * } * } */ } //for(int i=0; i<targetModeTileList.Count; i++) targetModeTileList[i].SetState(_TileState.Range); OverlayManager.ShowAbilityRangeIndicator(targetModeTileList); }
IEnumerator _ApplyAbilityEffect(Tile targetTile, Ability ability, int type, Unit srcUnit = null, float critMult = 1.0f) { if (targetTile != null && ability.effectObject != null) { if (!ability.autoDestroyEffect) { ObjectPoolManager.Spawn(ability.effectObject, targetTile.GetPos(), Quaternion.identity); } else { ObjectPoolManager.Spawn(ability.effectObject, targetTile.GetPos(), Quaternion.identity, ability.effectObjectDuration); } } if (!ability.useDefaultEffect) { yield break; } if (ability.effectDelayDuration > 0) { yield return(new WaitForSeconds(ability.effectDelayDuration)); } if (type == 1) //_AbilityType.Generic { List <Tile> tileList = new List <Tile>(); if (targetTile != null) { if (ability.aoeRange > 0) { tileList = GridManager.GetTilesWithinDistance(targetTile, ability.aoeRange); } tileList.Add(targetTile); } else { if (ability.effTargetType == _EffectTargetType.Tile) { tileList = GridManager.GetTileList(); } else { List <Unit> unitList = FactionManager.GetAllUnit(); for (int i = 0; i < unitList.Count; i++) { tileList.Add(unitList[i].tile); } } } if (ability.effTargetType == _EffectTargetType.AllUnit) { for (int i = 0; i < tileList.Count; i++) { if (tileList[i].unit == null) { continue; } tileList[i].unit.ApplyEffect(ability.CloneEffect(critMult), srcUnit); SpawnEffectObjTarget(ability, tileList[i]); } } else if (ability.effTargetType == _EffectTargetType.HostileUnit) { for (int i = 0; i < tileList.Count; i++) { if (tileList[i].unit == null) { continue; } if (tileList[i].unit.factionID == ability.factionID) { continue; } tileList[i].unit.ApplyEffect(ability.CloneEffect(critMult), srcUnit); SpawnEffectObjTarget(ability, tileList[i]); } } else if (ability.effTargetType == _EffectTargetType.FriendlyUnit) { for (int i = 0; i < tileList.Count; i++) { if (tileList[i].unit == null) { continue; } if (tileList[i].unit.factionID != ability.factionID) { continue; } tileList[i].unit.ApplyEffect(ability.CloneEffect(critMult), srcUnit); SpawnEffectObjTarget(ability, tileList[i]); } } else if (ability.effTargetType == _EffectTargetType.Tile) { for (int i = 0; i < tileList.Count; i++) { tileList[i].ApplyEffect(ability.CloneEffect(critMult)); SpawnEffectObjTarget(ability, tileList[i]); } } } else if (type == 2) //_AbilityType.SpawnNew { Quaternion rot = srcUnit != null ? srcUnit.thisT.rotation : Quaternion.identity; GameObject unitObj = (GameObject)Instantiate(ability.spawnUnit.gameObject, targetTile.GetPos(), rot); Unit unit = unitObj.GetComponent <Unit>(); unitObj.transform.position = targetTile.GetPos(); if (srcUnit != null) { unitObj.transform.rotation = srcUnit.thisT.rotation; } else { Faction faction = FactionManager.GetFaction(ability.factionID); if (faction != null) { unitObj.transform.rotation = Quaternion.Euler(0, faction.spawnDirection, 0); } } FactionManager.InsertUnit(unit, ability.factionID); unit.SetNewTile(targetTile); //if(GridManager.GetDistance(targetTile, srcUnit.tile)<=srcUnit.GetMoveRange()) GameControl.SelectUnit(srcUnit); } else if (type == 3) //_AbilityType.ScanFogOfWar) { List <Tile> targetTileList = GridManager.GetTilesWithinDistance(targetTile, ability.GetAOERange()); targetTileList.Add(targetTile); for (int i = 0; i < targetTileList.Count; i++) { targetTileList[i].ForceVisible(ability.effect.duration); } } else if (type == 4) //_AbilityType.Overwatch { targetTile.unit.Overwatch(ability.CloneEffect(critMult)); } else if (type == 5) //_AbilityType.Teleport { Quaternion wantedRot = Quaternion.LookRotation(targetTile.GetPos() - ability.unit.tile.GetPos()); ability.unit.thisT.rotation = wantedRot; GameControl.ClearSelectedUnit(); ability.unit.SetNewTile(targetTile); GameControl.SelectUnit(srcUnit); } else if (type == 6) //charge attack { List <Tile> tileList = GridManager.GetTilesInALine(srcUnit.tile, targetTile, ability.GetRange()); for (int i = 0; i < tileList.Count; i++) { while (true) { float dist = Vector3.Distance(srcUnit.thisT.position, tileList[i].GetPos()); if (dist < 0.05f) { if (tileList[i].unit != null) { tileList[i].unit.ApplyEffect(ability.CloneEffect(critMult)); SpawnEffectObjTarget(ability, tileList[i]); } break; } Quaternion wantedRot = Quaternion.LookRotation(tileList[i].GetPos() - srcUnit.thisT.position); srcUnit.thisT.rotation = Quaternion.Slerp(srcUnit.thisT.rotation, wantedRot, Time.deltaTime * srcUnit.moveSpeed * 6); Vector3 dir = (tileList[i].GetPos() - srcUnit.thisT.position).normalized; srcUnit.thisT.Translate(dir * Mathf.Min(srcUnit.moveSpeed * 2 * Time.deltaTime, dist), Space.World); yield return(null); } } srcUnit.tile.unit = null; srcUnit.tile = tileList[tileList.Count - 1]; tileList[tileList.Count - 1].unit = srcUnit; GameControl.ReselectUnit(); } else if (type == 7) //attack all unit in a straight line { List <Tile> tileList = GridManager.GetTilesInALine(srcUnit.tile, targetTile, ability.GetRange()); for (int i = 0; i < tileList.Count; i++) { if (tileList[i].unit == null) { continue; } tileList[i].unit.ApplyEffect(ability.CloneEffect(critMult)); SpawnEffectObjTarget(ability, tileList[i]); } } else { Debug.LogWarning("Error, unknown ability type (" + type + ")"); } yield return(null); }