public AtaqueCombate Atacar(AtaqueID ataqueID)
    {
        AtaqueCombate proximoAtaque = new AtaqueCombate();

        proximoAtaque.haFallado  = ComprobarSiElAtaqueFalla(ataqueID);
        proximoAtaque.tipoAtaque = Pokemon.Ataque(ataqueID).DatosFijos.tipoDeAtaque;

        if (!proximoAtaque.haFallado)
        {
            proximoAtaque.id    = ataqueID;
            proximoAtaque.danio = CalcularDanio(ataqueID);
            proximoAtaque.estadoAlteradoProvocado = CalcularEstadoAlterado(ataqueID);
            if (ComprobarSiSeAutoCura(ataqueID))
            {
                proximoAtaque.pokemonOriginalSeCura             = true;
                proximoAtaque.porcentajeCuracionPokemonOriginal = Pokemon.Ataque(ataqueID).DatosFijos.porcentajeDeCuracion;
            }
            if (ComprobarSiSeAutoInflingeDanio(ataqueID))
            {
                proximoAtaque.pokemonOriginalSeHaceDanio     = true;
                proximoAtaque.porcentajeDanioPokemonOriginal = Pokemon.Ataque(ataqueID).DatosFijos.porcentajeDeDanioAutoInflingido;
            }
        }
        Debug.Log(string.Concat("Pokemon ", Pokemon.ID.ToString(), " va a atacar: ", ataqueID.ToString(), " ", proximoAtaque.ToString()));
        return(proximoAtaque);
    }
 public void RecibirAtaque(AtaqueCombate ataque)
 {
     Pokemon.ReducirSalud(ataque.danio);
     if (ataque.estadoAlteradoProvocado != EstadoAlterado.NINGUNO && Pokemon.EstaVivo())
     {
         Pokemon.EstadoAlterado = ataque.estadoAlteradoProvocado;
     }
 }
 private IEnumerator TurnoOponenteCorrutina()
 {
     //Si el pokemon enemigo está vivo, lanza un ataque...
     if (DatosCombate.CombateActivo && DatosCombate.PokemonEnemigoActivo().Pokemon.EstaVivo())
     {
         //Pokémon del enemigo realiza un ataque aleatorio
         //TODO: comprobar PP del ataque antes de realizarlo
         AtaqueCombate Ataque = DatosCombate.PokemonEnemigoActivo().PokemonEnemigoAtaqueAleatorio();
         yield return(StartCoroutine(Atacar(DatosCombate.PokemonEnemigoActivo(), DatosCombate.PokemonJugadorActivo(), Ataque, barraSaludPokemonEnemigo, barraSaludPokemonJugador, textoSaludPokemonEnemigo, textoSaludPokemonJugador, false)));
     }
 }
    private IEnumerator TurnoJugadorCorrutina()
    {
        if (DatosCombate.CombateActivo && DatosCombate.PokemonJugadorActivo().Pokemon.EstaVivo())
        {
            switch (proximaAccion.TipoAccion)
            {
            case TipoAccion.Atacar:
                //Pokémon del jugador genera ataque (La comprobación de PP para ver si puede atacar se realizará en la interfaz)
                //Si se queda sin PP en todos los ataques al seleccionar Atacar en la interfaz realizará un ataque básico
                AtaqueCombate ataque = DatosCombate.PokemonJugadorActivo().Atacar(proximaAccion.Ataque);
                yield return(StartCoroutine(Atacar(DatosCombate.PokemonJugadorActivo(), DatosCombate.PokemonEnemigoActivo(), ataque, barraSaludPokemonJugador, barraSaludPokemonEnemigo, textoSaludPokemonJugador, textoSaludPokemonEnemigo, true)));

                break;

            case TipoAccion.UsarItem:
                switch (proximaAccion.Item.tipoDeItem)
                {
                case TipoDeItem.Curacion:
                    //No hacer nada, la curación se hará desde la interfaz
                    //Actualizamos la barra de salud
                    barraSaludPokemonJugador.fillAmount = DatosCombate.PokemonJugadorActivo().Pokemon.SaludEnEscalaDe1();
                    textoSaludPokemonJugador.text       = string.Concat((DatosCombate.PokemonJugadorActivo().Pokemon.EstadisticaSaludMaxima() * barraSaludPokemonJugador.fillAmount).ToString("0"), "/", DatosCombate.PokemonJugadorActivo().Pokemon.EstadisticaSaludMaxima());
                    break;

                case TipoDeItem.Pokeball:
                    yield return(StartCoroutine(LanzarPokeball(proximaAccion.Item)));

                    break;
                }
                break;

            case TipoAccion.Escapar:
                if (UnityEngine.Random.Range(0f, 1f) > 0.5f)
                {
                    DatosCombate.CombateActivo = false;
                    DatosCombate.CombateGanado = true;
                    //... Imprime texto indicando que ha podido escapar
                    yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(
                                                    Ajustes.Instancia.textoConsigueEscaparPokemonSalvaje, true, false, Ajustes.Instancia.tiempoDeEsperaUltimaVentanaDialogoEnCombateSiNoSeLeeElTeclado)));
                }
                else
                {
                    //... Imprime texto indicando que no ha podido escapar
                    yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(
                                                    Ajustes.Instancia.textoNoConsigueEscaparPokemonSalvaje, true, false, Ajustes.Instancia.tiempoDeEsperaUltimaVentanaDialogoEnCombateSiNoSeLeeElTeclado)));
                }
                break;

            case TipoAccion.CambiarPokemon:

                //... Oculta la barra de salud
                panelBarraSaludPokemonJugador.SetActive(false);

                //... Imprime texto indicando el cambio de pokémon
                string texto = Ajustes.Instancia.textoRetirarPokemonJugador
                               .Replace(Ajustes.Instancia.palabraParaReemplazarEnLosTexto1, DatosCombate.PokemonJugadorActivo().Pokemon.DatosFijos.nombre);
                yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(texto, true, false, Ajustes.Instancia.tiempoDeEsperaUltimaVentanaDialogoEnCombateSiNoSeLeeElTeclado)));

                //... Cambia el pokémon activo por el nuevo pokémon seleccionado
                DatosCombate.CambiarPokemonActivoDelJugador(proximaAccion.ProximoPokemon);

                //... Muestra la animación
                while (spritesCombate.MostrarAnimacionCombate(AnimacionCombate.JugadorRetirarPokemon))
                {
                    yield return(null);
                }

                //... Asigna los valores del nuevo pokémon a la interfaz y activa el panel de vida
                RellenarInterfazConDatosDelPokemonActivo(DatosCombate.PokemonJugadorActivo(), barraSaludPokemonJugador, nombreYNivelPokemonJugador, textoSaludPokemonJugador);

                //... Imprime mensaje de enviar nuevo pokémon
                string texto2 = Ajustes.Instancia.textoJugadorEnviaPokemon.Replace(Ajustes.Instancia.palabraParaReemplazarEnLosTexto1, DatosCombate.PokemonJugadorActivo().Pokemon.DatosFijos.nombre);
                yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(texto2, true, false, Ajustes.Instancia.tiempoDeEsperaUltimaVentanaDialogoEnCombateSiNoSeLeeElTeclado)));

                //... Muestra la animación de enviar nuevo pokémon
                while (spritesCombate.MostrarAnimacionCombate(AnimacionCombate.JugadorEnviaPokemon))
                {
                    yield return(null);
                }

                //... Activa la barra de salud
                panelBarraSaludPokemonJugador.SetActive(true);

                break;
            }
        }
    }
    private IEnumerator Atacar(PokemonLuchador pokemonAtacante, PokemonLuchador pokemonDefensor, AtaqueCombate ataque, Image barraSaludAtacante, Image barraSaludDefensor, Text textoSaludPokemonAtacante, Text textoSaludPokemonDefensor, bool atacaElJugador)
    {
        //Si no ha fallado el ataque...
        if (!ataque.haFallado)
        {
            //... Imprime texto indicando el pokémon y ataque
            string texto = Ajustes.Instancia.textoPokemonAtaca
                           .Replace(Ajustes.Instancia.palabraParaReemplazarEnLosTexto1, pokemonAtacante.Pokemon.DatosFijos.nombre)
                           .Replace(Ajustes.Instancia.palabraParaReemplazarEnLosTexto2, pokemonAtacante.Pokemon.Ataque(ataque.id).DatosFijos.nombre);
            yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(texto, false, false, Ajustes.Instancia.tiempoDeEsperaUltimaVentanaDialogoEnCombateSiNoSeLeeElTeclado)));

            if (atacaElJugador)
            {
                if (ataque.tipoAtaque == TipoDeAtaque.Fisico)
                {
                    while (spritesCombate.MostrarAnimacionCombate(AnimacionCombate.PokemonJugadorRealizaAtaqueFisico))
                    {
                        yield return(null);
                    }
                }

                while (spritesCombate.MostrarAnimacionAtaque(ataque.id, Atacante.Jugador))
                {
                    yield return(null);
                }
            }
            else
            {
                if (ataque.tipoAtaque == TipoDeAtaque.Fisico)
                {
                    while (spritesCombate.MostrarAnimacionCombate(AnimacionCombate.PokemonEnemigoRealizaAtaqueFisico))
                    {
                        yield return(null);
                    }
                }

                while (spritesCombate.MostrarAnimacionAtaque(ataque.id, Atacante.Enemigo))
                {
                    yield return(null);
                }
            }

            //... Comprobamos el incremento del daño del ataque según el tipo de elemento del pokémon enemigo
            float multiplicadorDanioPorElementos = tablaTipos.MultiplicadorElemento(ataque.elemento, pokemonDefensor.Pokemon.DatosFijos.tipoElemento1, pokemonDefensor.Pokemon.DatosFijos.tipoElemento2);
            //... Si ha devuelto 0 significa que es inmune y no se le hace daño...
            if (multiplicadorDanioPorElementos <= 0)
            {
                //... Por lo que imprime el texto en pantalla indicando que es inmune
                yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(Ajustes.Instancia.textoPokemonInmuneAlAtaque, false, false)));
            }
            //... Si no es inmune comprobamos el daño final...
            else
            {
                //... Comprueba si el ataque ha sido crítico
                float multiplicadorCritico = 1;
                if (ataque.esCritico)
                {
                    multiplicadorCritico = Ajustes.Instancia.danioCriticos;
                }

                //... Calcula el daño final del ataque teniendo en cuenta los tipos de elementos y si ha sido crítico
                ataque.danio = (int)(ataque.danio * multiplicadorDanioPorElementos * multiplicadorCritico);

                //... El pokémon enemigo recibe el ataque
                pokemonDefensor.RecibirAtaque(ataque);

                //... Si el multiplicador no es cercano a 1 (1 sería un ataque normal que no es muy efectivo ni poco efectivo) imprimimos por pantalla un texto informando de la efectividad del ataque
                if (multiplicadorDanioPorElementos <= 0.9f || multiplicadorDanioPorElementos > 1.1f)
                {
                    if (multiplicadorDanioPorElementos < 0.3f)
                    {
                        texto = Ajustes.Instancia.textoPokemonAtaque25PorcientoDanio;
                    }
                    else if (multiplicadorDanioPorElementos < 0.7f)
                    {
                        texto = Ajustes.Instancia.textoPokemonAtaque50PorcientoDanio;
                    }
                    else if (multiplicadorDanioPorElementos > 1.9f)
                    {
                        texto = Ajustes.Instancia.textoPokemonAtaque200PorcientoDanio;
                    }
                    else
                    {
                        texto = Ajustes.Instancia.textoPokemonAtaque150PorcientoDanio;
                    }

                    yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(texto, false, false, Ajustes.Instancia.tiempoDeEsperaUltimaVentanaDialogoEnCombateSiNoSeLeeElTeclado)));
                }

                if (atacaElJugador)
                {
                    while (spritesCombate.MostrarAnimacionCombate(AnimacionCombate.PokemonEnemigoRecibeAtaque))
                    {
                        yield return(null);
                    }
                }
                else
                {
                    while (spritesCombate.MostrarAnimacionCombate(AnimacionCombate.PokemonJugadorRecibeAtaque))
                    {
                        yield return(null);
                    }
                }

                //... Cambia el valor de la barra de salud con una animación
                float porcentajeDeSalud = pokemonDefensor.Pokemon.SaludEnEscalaDe1();
                yield return(StartCoroutine(CorrutinasComunes.MoverBarraDeslizadora(barraSaludDefensor, porcentajeDeSalud, pokemonDefensor.Pokemon.EstadisticaSaludMaxima(), textoSaludPokemonDefensor, null)));
            }

            //... Comprueba si el pokémon original se autoinflinge daño
            if (ataque.pokemonOriginalSeHaceDanio)
            {
                pokemonAtacante.RecibirAutoAtaque(ataque);
                //TODO: reproducir animacion recibir daño
                //... Cambia el valor de la barra de salud con una animación
                float porcentajeDeSalud = pokemonAtacante.Pokemon.SaludEnEscalaDe1();
                while (barraSaludAtacante.fillAmount != porcentajeDeSalud)
                {
                    barraSaludAtacante.fillAmount = Mathf.Lerp(barraSaludAtacante.fillAmount, porcentajeDeSalud, Ajustes.Instancia.velocidadDeMovimientoDeBarrasDeSaludEnCombate);
                    yield return(null);
                }
            }
            //... Comprueba si el pokémon original se autocura
            if (ataque.pokemonOriginalSeCura)
            {
                pokemonAtacante.RecibirAutoSanacion(ataque);
                //TODO: reproducir animacion curar
                //... Cambia el valor de la barra de salud con una animación
                float porcentajeDeSalud = pokemonAtacante.Pokemon.SaludEnEscalaDe1();
                while (barraSaludAtacante.fillAmount != porcentajeDeSalud)
                {
                    barraSaludAtacante.fillAmount = Mathf.Lerp(barraSaludAtacante.fillAmount, porcentajeDeSalud, Ajustes.Instancia.velocidadDeMovimientoDeBarrasDeSaludEnCombate);
                    yield return(null);
                }
            }

            //... Resta PP al ataque usado
            pokemonAtacante.RestarPP(ataque.id);
        }
        else
        {
            yield return(StartCoroutine(UIControlador.Instancia.Dialogo.componentePrincipal.MostrarTextoCorrutina(Ajustes.Instancia.textoPokemonFallaAtaque, false, false, Ajustes.Instancia.tiempoDeEsperaUltimaVentanaDialogoEnCombateSiNoSeLeeElTeclado)));
        }
    }
    public void RecibirAutoSanacion(AtaqueCombate autoSanacion)
    {
        int cantidadRestaurada = (int)(autoSanacion.danio * autoSanacion.porcentajeCuracionPokemonOriginal);

        Pokemon.RestaurarSalud(cantidadRestaurada);
    }
    public void RecibirAutoAtaque(AtaqueCombate autoAtaque)
    {
        int cantidadDanio = (int)(autoAtaque.danio * autoAtaque.porcentajeDanioPokemonOriginal);

        Pokemon.ReducirSalud(cantidadDanio);
    }