void _NewHoveredTile(Tile tile){ hoveredTile=tile; if(AbilityManager.InTargetMode()){ SetTargetModeHoveredTile(tile); return; } bool isWalkable=walkableTileList.Contains(tile); bool isSelectedUnitTile=GameControl.GetSelectedUnit()==null ? false : true; if(isSelectedUnitTile) isSelectedUnitTile=GameControl.GetSelectedUnit().tile!=tile ? false : true ; //show cover overlay if cover-system is enabled if(GameControl.EnableCover() && (isWalkable || isSelectedUnitTile)){ OverlayManager.ShowCoverOverlay(tile); } //highlight potential target for the unit to be moved into this tile if(isWalkable && GameControl.GetSelectedUnit().CanAttack()){ SetWalkableHostileList(tile); } TBTK.OnHoverTile(tile); }
public void _SelectUnit(){ if(!GameControl.EnableCover()) return; for(int n=0; n<factionList.Count; n++){ for(int i=0; i<factionList[n].allUnitList.Count; i++){ factionList[n].allUnitList[i].UpdateCoverStatus(); } } }
public void EnableWall(Transform wallObjT) { for (int i = 0; i < wallList.Count; i++) { if (wallList[i].wallObjT == wallObjT) { Tile neighbour = wallList[i].neighbour; aStar.DisconnectNeighbour(neighbour); for (int n = 0; n < neighbour.wallList.Count; n++) { if (neighbour.wallList[n].wallObjT == wallObjT) { aStar.DisconnectNeighbour(neighbour.wallList[n].neighbour); if (GameControl.EnableCover()) { for (int j = 0; j < neighbour.coverList.Count; j++) { if (Mathf.Abs(coverList[j].angle - neighbour.wallList[n].angle) < 1) { coverList[j].enabled = true; } } } break; } } if (GameControl.EnableCover()) { for (int m = 0; m < coverList.Count; m++) { if (Mathf.Abs(coverList[m].angle - wallList[i].angle) < 1) { coverList[m].enabled = true; } } } break; } } }
//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]); }
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 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]); } } }
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; } } }