public void ModoDeMovimento() { UnidadeNoTabuleiro atual = BatalhaController.instancia.unidadesNoTabuleiro[BatalhaController.instancia.unidadeAtualIndex]; if (!atual.gridDeMovimento) { BatalhaController.instancia.removerTileHighlights(); atual.gridDeMovimento = true; atual.gridDeAtaque = false; //Se a unidade atual tem combustivel if (atual.unidadeAssociada.status[13] > 0) { BatalhaController.instancia.highlightTilesAt(atual.gridPosition, BatalhaController.instancia.TileGridMovimento, atual.unidadeAssociada.status[3]); } else { BatalhaController.instancia.highlightTilesAt(atual.gridPosition, BatalhaController.instancia.TileGridMovimento, 1); } } else { atual.gridDeMovimento = false; atual.gridDeAtaque = false; BatalhaController.instancia.removerTileHighlights(); } if (botoesDeAcao.activeSelf) { botoesDeAcao.SetActive(false); } }
private void tooglarBotoesDeAcoes() { UnidadeNoTabuleiro atual = BatalhaController.instancia.unidadesNoTabuleiro[BatalhaController.instancia.unidadeAtualIndex]; if (!botoesDeAcao.activeSelf) { botoesDeAcao.SetActive(true); if (atual.artilharia) { posicionar.gameObject.SetActive(true); if (atual.preparada) { atacar.interactable = true; posicionar.interactable = false; } else { atacar.interactable = false; posicionar.interactable = true; } } else { posicionar.gameObject.SetActive(false); } } else { botoesDeAcao.SetActive(false); } }
public UnidadeNoTabuleiro ProcurarMaisProximoInimigo() { List <UnidadeNoTabuleiro> inimigosNoTabuleiro = BatalhaController.instancia.aliadosEmCampo; float menorDistancia = inimigosNoTabuleiro.Min(uni => Vector2.Distance(gridPosition, uni.gridPosition)); UnidadeNoTabuleiro alvo = inimigosNoTabuleiro.First(uni => Vector2.Distance(gridPosition, uni.gridPosition) == menorDistancia); return(alvo); }
public static UnidadeXml CreateUnidadeXml(UnidadeNoTabuleiro unidade) { return(new UnidadeXml() { id = (int)unidade.unidadeAssociada.idNoBancoDeDados, locX = (int)unidade.gridPosition.x, locY = (int)unidade.gridPosition.y }); }
public void setarUnidadeNoSlot(Tile tile) { unidadeSendoSetada.gridPosition = tile.posicaoNoTabuleiro; unidadesNoTabuleiro.Add(unidadeSendoSetada); colocandoUnidade = false; tile.ocupado = true; unidadeSendoSetada = null; //instanciarUnidade(unidadeSendoSetada.unidadeAssociada.id); }
void Update() { if (Input.GetMouseButtonDown(1) && colocandoUnidade) { colocandoUnidade = false; Destroy(unidadeSendoSetada.gameObject); unidadeSendoSetada = null; } }
public void reposicionarUnidade(Tile tile) { tile.ocupado = false; if (unidadeSendoSetada != null) { unidadeSendoSetada = null; } unidadeSendoSetada = unidadesNoTabuleiro.First(uni => uni.gridPosition == tile.posicaoNoTabuleiro); unidadesNoTabuleiro.Remove(unidadeSendoSetada); }
public void terminouVez() { if (botoesDeAcao.activeSelf) { botoesDeAcao.SetActive(false); } UnidadeNoTabuleiro atual = BatalhaController.instancia.unidadesNoTabuleiro[BatalhaController.instancia.unidadeAtualIndex]; tooglarAcoesDoPlayer(!atual.inimigo); mostrarHoras(); atualizarCountdown(); }
void OnMouseDown() { if (Input.GetMouseButtonDown(0)) { if (!noConstrutor) { if (BatalhaController.instancia.preBattle && !ocupado && sobreHighlight) { BatalhaController.instancia.setarUnidadeNoSlot(this); } else if (BatalhaController.instancia.preBattle && ocupado) { BatalhaController.instancia.reposicionarUnidadeNoTabuleiro(this); } else { UnidadeNoTabuleiro atual = BatalhaController.instancia.unidadesNoTabuleiro[BatalhaController.instancia.unidadeAtualIndex]; if (atual.gridDeMovimento) { BatalhaController.instancia.verificarTentativaDeMovimento(this); } else if (atual.gridDeAtaque) { BatalhaController.instancia.atacarComPlayerAtual(this); } else if (!atual.gridDeAtaque && !atual.gridDeMovimento && ocupado) { BatalhaController.instancia.mostrarInformacoesDaUnidadeClicada(this); } } } else { if (MapCreatorManager.instance.mudandoTipo) { setarTipoeVisual(MapCreatorManager.instance.palletSelection); } else if (MapCreatorManager.instance.mudandoMecanica) { setarMecanicaeVisual(MapCreatorManager.instance.mechanicPallet); } else if (MapCreatorManager.instance.colocandoUnidade && !ocupado) { MapCreatorManager.instance.setarUnidadeNoSlot(this); } else if (!MapCreatorManager.instance.colocandoUnidade && ocupado) { MapCreatorManager.instance.colocandoUnidade = true; MapCreatorManager.instance.reposicionarUnidade(this); } } } }
public void instanciarUnidade(int id) { if (unidadeSendoSetada != null) { unidadeSendoSetada = null; } UnidadeNoTabuleiro unidadeNova = ((GameObject)Instantiate(unidadePrefab)).GetComponent <UnidadeNoTabuleiro>(); unidadeSendoSetada = unidadeNova; unidadeSendoSetada.unidadeAssociada = banco.retornarUnidade(id); unidadeSendoSetada.gameObject.GetComponent <Animator>().runtimeAnimatorController = controladoresInimigos[(int)unidadeNova.unidadeAssociada.classe]; }
//Aqui que vamos calcular o caminho caminho mais curto até o destino a partir da origem public static List <Tile> FindPathTilesReturn(Tile origem, Tile destino) { List <Tile> closed = new List <Tile>(); List <TilePath> open = new List <TilePath>(); UnidadeNoTabuleiro unidadeAtual = BatalhaController.instancia.unidadesNoTabuleiro[BatalhaController.instancia.unidadeAtualIndex]; TilePath originPath = new TilePath(); originPath.addTile(origem); open.Add(originPath); while (open.Count > 0) { open = open.OrderBy(x => x.custoDoCaminho).ToList(); TilePath current = open[0]; open.Remove(open[0]); if (closed.Contains(current.ultimoTile)) { continue; } if (current.ultimoTile == destino) { current.listaDeTiles.Remove(origem); return(current.listaDeTiles); } closed.Add(current.ultimoTile); foreach (Tile t in current.ultimoTile.vizinhos) { if (t.instransponivel) { continue; } if (unidadeAtual.gridDeMovimento && t.ocupado) { continue; } if (unidadeAtual.gridDeMovimento && t.classesRestritas.Contains(unidadeAtual.unidadeAssociada.classe)) { continue; } TilePath newTilePath = new TilePath(current); newTilePath.addTile(t); open.Add(newTilePath); } } return(null); }
public void mostrarAcoes() { UnidadeNoTabuleiro atual = BatalhaController.instancia.unidadesNoTabuleiro[BatalhaController.instancia.unidadeAtualIndex]; if (atual.inimigo) { desativarAcoesDoPlayer(); } else { ativarAcoesDoPlayer(); } atual.gridDeMovimento = false; atual.gridDeAtaque = false; BatalhaController.instancia.removerTileHighlights(); tooglarBotoesDeAcoes(); }
//Diferente das unidades de mais de 1 tiles de Range, close combat units não devem ir atrás de um inimigo que ja está cercado public UnidadeNoTabuleiro ProcurarMaisProximoInimigoDeCloseCombat() { List <UnidadeNoTabuleiro> inimigosNoTabuleiro = BatalhaController.instancia.aliadosEmCampo; while (true) { float menorDistancia = inimigosNoTabuleiro.Min(uni => Vector2.Distance(gridPosition, uni.gridPosition)); UnidadeNoTabuleiro alvo = inimigosNoTabuleiro.First(uni => Vector2.Distance(gridPosition, uni.gridPosition) == menorDistancia); Tile tileDoAlvo = BatalhaController.instancia.tabuleiro[(int)alvo.gridPosition.x][(int)alvo.gridPosition.y]; foreach (Tile t in tileDoAlvo.vizinhos) { if (!t.ocupado) { return(alvo); } } inimigosNoTabuleiro.Remove(alvo); } }
//A Partir daqui os codigos da IA public void AITurno() { if (!viva) { Debug.Log("Algo estranho, unidade morta teve turno chamado"); return; }//Seja lá o que aconteceu, uma unidade morta não faz ação //Caso sofra do efeito blitzkrieg, a unidade inimiga perderá a vez if (pontosDeAcao == 0 && !AIfazAcaoEspecial) { BatalhaController.instancia.AdministrarFimDeAcao(); } //Novo turno = novo alvo, e portanto, o caminho pode ser que seja nescessario backtrackar if (pontosDeAcao == 2) { alvoDeAtaque = null; } DecidirAcao(); }
public void loadMapFromXml(string nome) { MapXmlContainer container = MapSaveLoad.MapBuildLoad(nome + ".xml"); colunas = container.coluns; linhas = container.lines; destruirTabuleiroAtual(); for (int i = 0; i < colunas; i++) { List <Tile> row = new List <Tile>(); for (int j = 0; j < linhas; j++) { Tile tile = ((GameObject)Instantiate(tilePrefab, new Vector3(i - Mathf.Floor(linhas / 2), 0, -j + Mathf.Floor(colunas / 2)), Quaternion.Euler(new Vector3()))).GetComponent <Tile>(); tile.transform.parent = mapHolder.transform; tile.noConstrutor = true; tile.posicaoNoTabuleiro = new Vector2(i, j); tile.setarTipoeVisual((TileType)container.tiles.Where(x => x.locX == i && x.locY == j).First().id); tile.setarMecanicaeVisual((TileMechanic)container.tiles.Where(x => x.locX == i && x.locY == j).First().mechanic); row.Add(tile); } tabuleiro.Add(row); } foreach (UnidadeXml uXML in container.unidadesNoTabuleiro) { UnidadeNoTabuleiro unidadeNova = ((GameObject)Instantiate(unidadePrefab, tabuleiro[uXML.locX][uXML.locY].transform.position + 1 * Vector3.up, Quaternion.Euler(new Vector3(90, 0, 0)))).GetComponent <UnidadeNoTabuleiro>(); unidadeNova.gridPosition = new Vector2(uXML.locX, uXML.locY); unidadeNova.unidadeAssociada = BancoDeDados.instancia.retornarUnidade(uXML.id); unidadeNova.gameObject.GetComponent <Animator>().runtimeAnimatorController = controladoresInimigos[(int)unidadeNova.unidadeAssociada.classe]; //Aqui so entrarão unidades que vão estar contra você no jogo, então sempre serão inimigos unidadeNova.inimigo = true; tabuleiro[uXML.locX][uXML.locY].ocupado = true; unidadesNoTabuleiro.Add(unidadeNova); } configurarCameraParaNovoTabuleiro(tabuleiro); }
public void artilleryMove(UnidadeNoTabuleiro target, Tile tileDeOrigem) { Tile tileDoTarget = BatalhaController.instancia.tabuleiro[(int)target.gridPosition.x][(int)target.gridPosition.y]; //Primeiro Caso, Alvo em Range e não precisa se mover a ele, portanto double attack gridDeAtaque = true; gridDeMovimento = false; if (TileHighlight.FindHighlight(tileDeOrigem, unidadeAssociada.status[4]).Contains(tileDoTarget)) { if (preparada) { BatalhaController.instancia.highlightTilesAt(tileDeOrigem.posicaoNoTabuleiro, BatalhaController.instancia.TileGridAtaque, unidadeAssociada.status[4]); BatalhaController.instancia.atacarComPlayerAtual(tileDoTarget); } else { BatalhaController.instancia.unidadeDeArtilhariaSePreparou(); } } else { gridDeAtaque = false; gridDeMovimento = true; Classe classeDaUnidade = unidadeAssociada.classe; if (!preparada) { BatalhaController.instancia.unidadeDeArtilhariaSePreparou(); } else { BatalhaController.instancia.AdministrarFimDeAcao(); } gridDeMovimento = false; } }
public void TrackDownEnemies(UnidadeNoTabuleiro target, Tile tileDeOrigem) { Tile tileDoTarget = BatalhaController.instancia.tabuleiro[(int)target.gridPosition.x][(int)target.gridPosition.y]; //Primeiro Caso, Alvo em Range e não precisa se mover a ele, portanto double attack gridDeAtaque = true; gridDeMovimento = false; if (TileHighlight.FindHighlight(tileDeOrigem, unidadeAssociada.status[4]).Contains(tileDoTarget)) { BatalhaController.instancia.highlightTilesAt(tileDeOrigem.posicaoNoTabuleiro, BatalhaController.instancia.TileGridAtaque, unidadeAssociada.status[4]); BatalhaController.instancia.atacarComPlayerAtual(tileDoTarget); } //Segundo caso, Alvo não está em range, mas pode ser alcançado com um movimento else { gridDeAtaque = false; gridDeMovimento = true; BatalhaController.instancia.highlightTilesAt(tileDeOrigem.posicaoNoTabuleiro, BatalhaController.instancia.TileGridMovimento, unidadeAssociada.status[3]); //Pegar todos os tiles de movimento possivel List <Tile> movementTiles = TileHighlight.FindHighlight(tileDeOrigem, unidadeAssociada.status[3]); //Verificar se algums dos tiles está a uma distancia que a unidade pode atacar após mover if (movementTiles.Any(tile => Vector2.Distance(tile.posicaoNoTabuleiro, tileDoTarget.posicaoNoTabuleiro) == unidadeAssociada.status[4])) { //Pegar qualquer tile cuja distancia para o alvo seja igual ao range maximo do seu ataque //List<Tile> possiveisParaMovimento = movementTiles.Where(tile => Vector2.Distance(tile.posicaoNoTabuleiro, tileDoTarget.posicaoNoTabuleiro) == unidadeAssociada.status[4]).ToList(); //float maiorDistancia = movementTiles.Max(tile => Vector2.Distance(tileDoTarget.posicaoNoTabuleiro, tile.posicaoNoTabuleiro)); Tile tileParaMoverMaisProximo = movementTiles.First(tile => Vector2.Distance(tile.posicaoNoTabuleiro, tileDoTarget.posicaoNoTabuleiro) == unidadeAssociada.status[4]); BatalhaController.instancia.verificarTentativaDeMovimento(tileParaMoverMaisProximo); alvoDeAtaque = target; } //Terceiro caso, Muito longe para atacar o inimigo depois do movimento, porntanto so se importar com chegar o mais proximo possivel else { List <Tile> CaminhoMaisCurtoParaOAlvo = null; foreach (Tile tile in tileDoTarget.vizinhos) { if (!tile.ocupado) { CaminhoMaisCurtoParaOAlvo = TilePathFinder.FindPathTilesReturn(tileDeOrigem, tile); break; } } if (CaminhoMaisCurtoParaOAlvo == null) { BatalhaController.instancia.proximaVez(); return; } for (int i = CaminhoMaisCurtoParaOAlvo.Count - 1; i >= 0; i--) { if (movementTiles.Contains(CaminhoMaisCurtoParaOAlvo[i])) { BatalhaController.instancia.verificarTentativaDeMovimento(CaminhoMaisCurtoParaOAlvo[i]); break; } } //movementTiles.Any(tile => CaminhoMaisCurtoParaOAlvo.Contains(tile)); } gridDeMovimento = false; } }
//Esse highlight vai "atirar" pra todo lado, sem um destino especifico, apenas indo até os pontosDeMovimento deixarem public static List <Tile> FindHighlight(Tile tileDeOrigem, int pontosDeMovimento) { List <Tile> closed = new List <Tile>(); //aqui são aqueles Tiles que ja foram "computados" e que vão voltar pro BatalhaController List <TilePath> open = new List <TilePath>(); //Tiles que ainda não foram processados UnidadeNoTabuleiro unidadeAtual = BatalhaController.instancia.unidadesNoTabuleiro[BatalhaController.instancia.unidadeAtualIndex]; TilePath caminhoDeOrigem = new TilePath(); //Começando um um novo caminho caminhoDeOrigem.addTile(tileDeOrigem); //Esse caminho parte da origem open.Add(caminhoDeOrigem); //Guardando esse caminho nas tiles opens, porque se tu der closed na origem so vai da pra fazer o primeiro caminho while (open.Count > 0) //Enquanto houver tiles ainda não processados.... { TilePath atual = open[0]; open.Remove(open[0]); if (closed.Contains(atual.ultimoTile)) { continue; //Se esse tile ja foi fechado, não há porque computar } if (atual.custoDoCaminho > pontosDeMovimento + 1) { continue; //Se acabou os pontos de movimento } closed.Add(atual.ultimoTile); foreach (Tile t in atual.ultimoTile.vizinhos) { if (t.instransponivel) { continue; } if ((t.ocupado && !unidadeAtual.gridDeAtaque)) { continue; } if (unidadeAtual.gridDeMovimento && t.classesRestritas.Contains(unidadeAtual.unidadeAssociada.classe)) { continue; } TilePath newTilePath = new TilePath(atual); newTilePath.addTile(t); open.Add(newTilePath); } } //Salvador, aqui vai verificar se caso os pontos de movimento forem muito poucos, adicionar todos os vizinhos //da origem pra evitar atolamento, isso não ignora tiles instraponiveis ou ocupados, apenas o custo da caminho if (unidadeAtual.gridDeMovimento) { //Checar se tem algo na lista de tiles além dos vizinhos do tile de origem //Caso tenha e porque ele pode ser mover em alguma direção além dessa sem estar atolado if (closed.Count == 0 || closed.Any(x => tileDeOrigem.vizinhos.Any(y => x != y))) { foreach (Tile vizinho in tileDeOrigem.vizinhos) { if (vizinho.instransponivel || vizinho.ocupado || vizinho.classesRestritas.Contains(unidadeAtual.unidadeAssociada.classe)) { continue; } closed.Add(vizinho); } } } closed.Remove(tileDeOrigem); return(closed); }
public void focarNoPlayer(UnidadeNoTabuleiro playerAFocar) { transform.position = playerAFocar.transform.position + Vector3.up * 5; //this.GetComponent<Camera>().orthographicSize = 2; }
//Essa unidade está procurando alguém para entrar em confronto public void DecidirAcao() { //List<UnidadeNoTabuleiro> unidadesNoCampo = BatalhaController.instancia.unidadesNoTabuleiro; //List<UnidadeNoTabuleiro> alvosPrioritarios = BatalhaController.instancia.alvosPrioritarios; List <List <Tile> > tabuleiro = BatalhaController.instancia.tabuleiro; Tile tileAtual = tabuleiro[(int)gridPosition.x][(int)gridPosition.y]; //Unidade está com problemas, retirar da batalha pra evitar mais casualidades if (unidadeAssociada.status[13] <= 10 || unidadeAssociada.status[15] <= 10 || unidadeAssociada.status[1] <= (unidadeAssociada.status[0] * 25) / 100) { Tile tileARetirar = retiradaDaBatalhaDaAI(tileAtual); AIfazAcaoEspecial = true; if (tileARetirar != tileAtual) { BatalhaController.instancia.verificarTentativaDeMovimento(tileARetirar); } else { StartCoroutine(BatalhaController.instancia.RetiradaDaBatalha(this)); } return; } AIfazAcaoEspecial = false; if (alvoDeAtaque == null || !alvoDeAtaque.viva) { if (unidadeAssociada.status[4] > 1) { alvoDeAtaque = ProcurarMaisProximoInimigo(); } else { alvoDeAtaque = ProcurarMaisProximoInimigoDeCloseCombat(); } } if (artilharia) { artilleryMove(alvoDeAtaque, tileAtual); } else { TrackDownEnemies(alvoDeAtaque, tileAtual); } //A IA vai sempre atrás de alvos prioritarios, mesmo se eles estiverem longe da linha de defesa /*if(alvosPrioritarios.Count != 0 && unidadesNoLimite.Intersect(alvosPrioritarios).Any()){ * List<UnidadeNoTabuleiro> alvosPrioritariosEmRange = unidadesNoLimite.Intersect(alvosPrioritarios).ToList(); * TrackDownEnemies(alvosPrioritarios.First(uni => uni.gridPosition.x == alvosPrioritarios.Max(coluna => coluna.gridPosition.x)),tileAtual); * } * //Sem nenhum alvo prioritario a AI vai verificar se está muito longe da linha defensiva * else if (gridPosition.x > colunaDeDefesa+5 || gridPosition.x < colunaDeDefesa-5){ * Debug.Log("Estamos fora da linha defensiva!"); * ReestruturarLinhaDefensiva(colunaDeDefesa,tileAtual); * } * //Estando na linha defensiva e sem nennhum alvo prioritario, ela vai atrás de atacar alguém * else{ * //Pegar o alvo com a menor distancia para com essa unidade de IA, o foco e atacar 2 vezes sempre que possivel * UnidadeNoTabuleiro alvoMaisProximo = unidadesNoLimite.FirstOrDefault(uni => Vector2.Distance(tileAtual.posicaoNoTabuleiro, new Vector2(uni.gridPosition.x, uni.gridPosition.y)) == unidadesNoLimite.Min(min => Vector2.Distance(tileAtual.posicaoNoTabuleiro, new Vector2(min.gridPosition.x, min.gridPosition.y)))); * //Se tiver um alvo qualquer em Range * if (alvoMaisProximo!=null) { TrackDownEnemies(alvoMaisProximo,tileAtual); } * //Nenehum inimigo na area de influencia, ja está na linha de defesa, pular turno * else { * Debug.Log("Nada pra AI fazer, proximo"); * BatalhaController.instancia.proximaVez(); * } * } */ }