(pokeruby) Implementando habilidades nuevas

Avisos


Like Tree14Gracias
  • 5 Post By Lumbreon
  • 2 Post By Lunos
  • 1 Post By Lumbreon
  • 1 Post By InmortalKaktus
  • 2 Post By Lumbreon
  • 1 Post By Lunos
  • 1 Post By Lumbreon
  • 1 Post By Lunos
Respuesta
 
Herramientas Desplegado
  #1  
Hace 3 Semanas
Predeterminado (pokeruby) Implementando habilidades nuevas
¡NUEVAS HABILIDADES PARA POKERUBY!


He estado toqueteando un poco por aquí y por allá los archivos referentes al
combate y logre implementar algunas habilidades, así que me pareció buena
idea compartirlas aquí.

También me gustaría que en este mismo tema compartieran métodos para implementar nuevas habilidades de 4ta generación en adelante.

Aquí la lista de los que llevo hasta ahora

Spoiler

Adaptable
Manto Níveo
Afortunado
Audaz - Copy paste de un archivo de Lunos
Experto - Copy paste de un archivo de Lunos
Filtro - Copy paste de un archivo de Lunos
Ignífugo
Encadenado - Copy paste de un archivo de Lunos
Antídoto
Colector
Cromolente - Copy paste de un archivo de Lunos
Defensa Hoja
Electromotor
Gula


Asi que vamos por partes...

Primero hay que hacer que el juego reconozca las habilidades que vayamos a agregar

Paso 1

Vamos al archivo "pokeruby\include\constants\abilities.h" y definimos la nueva habilidad de la misma forma en la que se definen las anteriores, si quisiésemos agregar la habilidad adaptable, quedaría de la siguiente forma despues de "air lock".
"#define ABILITY_ADAPTABILITY 79".


Paso 2

Ahora en el archivo "pokeruby\data\text\ability_names.inc" Añadimos el nombre de la habilidad como se mostrará en el juego, claro esto después de "air lock"...
cabe destacar que el nombre no puede tener mas de 12 caracteres.
Luego hacemos lo propio en el archivo de descripciones dentro de la misma carpeta, aquí recomiendo que busquen "AirLock" y copien la linea entera luego remplacen con la información de la habilidad nueva. Esto lo tienen que hacer dos veces, porque primero se define la descripción y al final del archivo se define el puntero.


Paso 3

Ya solo resta ponerle la habilidad a un pokémon a para comprobar y listo, solo faltaría darle su función a esa habilidad.


Ahora algunas habilidades

Audaz,Encadenado,Experto,Adaptable

vamos al archivo "battle_4.h" en la carpeta "pokeruby\src\battle" y buscamos "check stab"ahi veremos la función que checkea si el tipo del ataque coincide con el tipo del pokémon.
Bien... Solo hay que reemplazar esa funcion por estas 2
Código:
		if (gBattleMons[gBankAttacker].ability == ABILITY_SKILL_LINK || gBattleMons[gBankAttacker].ability == ABILITY_RECKLESS || gBattleMons[gBankAttacker].ability == ABILITY_TECHNICIAN)
         {   if ((gBattleMoves[gCurrentMove].effect == EFFECT_DOUBLE_EDGE || gBattleMoves[gCurrentMove].effect == EFFECT_RECOIL_IF_MISS || gBattleMoves[gCurrentMove].effect == EFFECT_RECOIL) && gBattleMons[gBankAttacker].ability == ABILITY_RECKLESS)
                gBattleMoveDamage = gBattleMoveDamage * 15; // Reckless
            if ((gBattleMoves[gCurrentMove].effect == EFFECT_MULTI_HIT || gBattleMoves[gCurrentMove].effect == EFFECT_DOUBLE_HIT || gBattleMoves[gCurrentMove].effect == EFFECT_TWINEEDLE) && gBattleMons[gBankAttacker].ability == ABILITY_SKILL_LINK)
                gBattleMoveDamage = gBattleMoveDamage * 15; // Skill Link			
            if (gBattleMoves[gCurrentMove].power <= 60 && gBattleMons[gBankAttacker].ability == ABILITY_TECHNICIAN)
                gBattleMoveDamage = gBattleMoveDamage * 50; // Technician
			
				gBattleMoveDamage = gBattleMoveDamage / 10;
		}	
        //check stab
        if ((gBattleMons[gBankAttacker].type1 == move_type || gBattleMons[gBankAttacker].type2 == move_type) && gBattleMons[gBankAttacker].ability != ABILITY_ADAPTABILITY)
        {
            gBattleMoveDamage = gBattleMoveDamage * 15;
            gBattleMoveDamage = gBattleMoveDamage / 10;
        }
		if ((gBattleMons[gBankAttacker].type1 == move_type || gBattleMons[gBankAttacker].type2 == move_type) && gBattleMons[gBankAttacker].ability == ABILITY_ADAPTABILITY)
        {
            gBattleMoveDamage = gBattleMoveDamage * 20;
            gBattleMoveDamage = gBattleMoveDamage / 10;
        }


Y listo...


Bueno, casi... Para que esto funcione, deben definir las habilidades tal cual como yo lo hice en el archivo "abilities.h". De esta forma
Código:
#define ABILITY_ADAPTABILITY 78
#define ABILITY_RECKLESS 79
#define ABILITY_TECHNICIAN 80
#define ABILITY_SKILL_LINK 81
Y ya está, estaré actualizando con las demás habilidades que dejé en la lista de arriba, también me gustaría que colaborasen añadiendo más habilidades en este tema para colaborar entre nosotros y añadir muchas más.
  #2  
Hace 3 Semanas
Predeterminado Re: (pokeruby) Implementando habilidades nuevas
Pues el tutorial es sencillo de comprender, eso si, hay que dejar en claro que aquí solo se está explicando lo que viene siendo la base para añadir nuevas habilidades, y que añadir su función o sus funciones es una tarea distinta, y dependiendo del caso, mucho mas complicada.

también me gustaría que colaborasen añadiendo más habilidades en este tema para colaborar entre nosotros y añadir muchas más
Pues noté que en el post principal mencionas algunas implementaciones de habilidades hechas por mi, pero no has enlazado nada al post principal. Debido a eso, decidí dejar por aquí un poco de mi trabajo, directo desde mi repositorio (Pokeruby493).

Dejando Adaptability, Reckless y Technician de lado, pues este post ya las cubre, yo tengo:
-Aftermath/Resquicio
-Anger Point/Irascible (aunque de hecho la implementación fue hecha por DoesntKnowHowToPlay, asi que creditos a él.)
-Bad Dreams/Mal Sueño (Nota: Por algun motivo que no comprendo, no funciona contra un Seedot.)
-Filter/Filtro (Ctrl+F "ABILITY_FILTER")
-Heatproof/Ignífugo
-Iron Fist/Puño Férreo
-No Guard/Indefenso, aunque está un poco a medias. No pude hacer que funcione con los movimientos OHKO.
-Poison Heal/Antidoto (implementado por un conocido mio llamado ItsJustChris, el credito es suyo)

Tambien están Snow Warning/Nevada, Snow Cloak/Manto Niveo y Ice Body/Gélido, implementados por Fontbane y añadidos al proyecto mediante Pull Request.
https://github.com/LOuroboros/pokeruby493/pull/1

Si alguien encuentra algun error en alguna de estas implementaciones, haganmelo saber.
Naturalmente, los creditos donde corresponden.

Espero que mas gente se cope y podamos tener una buena cantidad de contenido para usar en nuestros respectivos proyectos.

Última edición por Lunos; Hace 1 hora a las 00:12 Razón: Correcciones, aclaraciones y eliminada la implementación de Unburden pues está mal hecha, o más bien a mitad de camino.
  #3  
Hace 3 Semanas
Predeterminado Respuesta: (pokeruby) Implementando habilidades nuevas
Bueno, siguiendo el tema como va, que lo veo muy bien.
aquí otras habilidades

Storm Drain/Colector Motor Drive/Electromotor

Primero las añadimos al los archivos "abilities.h" "ability_names.inc" y "ability_description.inc" como en el post principal.
Ahora los pasos a seguir

Paso 1

En el archivo "pokeruby\src\battle\battle_util.h" y buscamos esto "ABILITY_WATER_ABSORB" Veremos este código
Código:
                case ABILITY_WATER_ABSORB:
                    if (moveType == TYPE_WATER && gBattleMoves[move].power != 0)
                    {
                        if (gProtectStructs[gBankAttacker].notFirstStrike)
                            gBattlescriptCurrInstr = BattleScript_MoveHPDrain;
                        else
                            gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss;
                        effect = 1;
                    }
                    break;
despues del "break;" en una nueva linea pegamos el siguiente codigo
Código:
                case ABILITY_STORM_DRAIN:
                    if (moveType == TYPE_WATER && gBattleMoves[move].power != 0)
                    {
						if (gBattleMons[bank].statStages[STAT_STAGE_SPATK] < 0xC)
							gBattleMons[bank].statStages[STAT_STAGE_SPATK]++;
						gBattleStruct->animArg1 = 0xF;
                        gBattleStruct->animArg2 = 0;
                        gBattlescriptCurrInstr = BattleScript_MoveSpAtkDrain;
						effect++;
						if (gBattleMons[bank].statStages[STAT_STAGE_SPATK] >= 0xC)
						gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP;
						effect = 2;
                    }
                    break;
                case ABILITY_MOTOR_DRIVE:
                    if (moveType == TYPE_ELECTRIC && gBattleMoves[move].power != 0)
                    {
						if (gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC)
							gBattleMons[bank].statStages[STAT_STAGE_SPEED]++;
						gBattleStruct->animArg1 = 0x11;
                        gBattleStruct->animArg2 = 0;
                        gBattlescriptCurrInstr = BattleScript_MoveSpeedDrain;
						effect++;
						if (gBattleMons[bank].statStages[STAT_STAGE_SPEED] >= 0xC)
						gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP;
						effect = 2;
                    }
                    break;
Luego buscamos "extern u8 BattleScript_MoveHPDrain[];" y seguido de eso pegamos esto.
Código:
extern u8 BattleScript_MoveSpeedDrain[];
extern u8 BattleScript_MoveSpAtkDrain[];
para que quede tal que así
Código:
extern u8 BattleScript_MoveHPDrain[];
extern u8 BattleScript_MoveSpeedDrain[];
extern u8 BattleScript_MoveSpAtkDrain[];
extern u8 BattleScript_MoveHPDrain_PPLoss[];
(esta entre dos lineas del archivo original para dar contexto)

Paso 2

Ahora en el archivo "pokeruby\data\battle_scripts_1.h" y al final del todo pegamos esto.
Código:
BattleScript_MoveSpAtkDrain:: @ 81D9866
	attackstring
	pause 32
	printstring BATTLE_TEXT_MadeUseless
	waitmessage 64
	orbyte gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
	playanimation TARGET, B_ANIM_STATS_CHANGE, sANIM_ARG1
	printstring BATTLE_TEXT_SpAtkRisen
	waitmessage 64	
	goto BattleScript_MoveEnd
	
BattleScript_MoveSpeedDrain:: @ 81D9866
	attackstring
	pause 32
	printstring BATTLE_TEXT_MadeUseless
	waitmessage 64
	orbyte gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
	playanimation TARGET, B_ANIM_STATS_CHANGE, sANIM_ARG1	
	printstring BATTLE_TEXT_SpeedRisen
	waitmessage 64	
	goto BattleScript_MoveEnd

Paso 3

Ahora para terminar lo que creo que iba primer xd.
Agregar el texto que va a salir al activarse las habilidades (solo la de Storm Drain, porque para Motor Drive solo usaremos la string de Speed Boost).
Vamos al archivo"pokeruby\constants\battle_text.inc" en el cual solo agregaremos esto.
Código:
	enum BATTLE_TEXT_SpAtkRisen
Al final del archivo.
Luego en "pokeruby\src\data\battle_strings_en.h" buscamos " BATTLE_TEXT_NoEffectOn," y seguidamente en una linea nueva antes del "}," pegamos esto
Código:
BATTLE_TEXT_SpAtkRisen,
luego buscamos "const u8 BattleText_Dark[] = _" y en la siguiente linea pegamos esto
Código:
const u8 BattleText_SpAtkRisen[] = _("¡{STRING 22} de {DEFENDING_MON}\nsubió su At. Especial!");
Ya por ultimo buscamos esto "BattleText_NoEffectOn," y en una linea nueva y antes del "}," pegamos lo siguiente
Código:
BattleText_SpAtkRisen,
Y si no me salté nada, ya deberia estar funcionando tanto Storm Drain como Motor Drive
Gracias: Lunos

Última edición por Lumbreon; Hace 1 semana a las 19:50 Razón: Pequeño error :v
  #4  
Hace 3 Semanas
Predeterminado Respuesta: (pokeruby) Implementando habilidades nuevas
¡Wow!

Me gusta que poco a poco os vayáis animando con decompilación y además hagáis tutoriales. Sin duda, saber donde encontrar lo que necesitamos cambiar concretamente sin tener que investigarlo, gracias a tener esa información recogida en un post, es un puntazo.

Eso sí, te recomendaría que incluyeras código a modo de ejemplo para que los usuarios sin mucha experiencia sepan a qué te refieres, o incluso para los que ya llevamos un tiempo, que nunca vienen mal a modo de referencia.

Si la idea es aportar la mayor cantidad de habilidades posibles, o recopilarlas, te recomendaría que crearas un fork de pokeruby o pokeemerald (el segundo mejor :3) y que todos pudieran contribuir allí, a la par que seguir dejando por aquí los respectivos códigos para aquellos que lo necesiten para algo puntual.

¡Sigue con esa buena iniciativa, buen tuto y un saludo!
Gracias: Lumbreon

  #5  
Hace 2 Semanas
Predeterminado Respuesta: (pokeruby) Implementando habilidades nuevas
Dicho por FatKip Ver mensaje
¡Wow!

Me gusta que poco a poco os vayáis animando con decompilación y además hagáis tutoriales. Sin duda, saber donde encontrar lo que necesitamos cambiar concretamente sin tener que investigarlo, gracias a tener esa información recogida en un post, es un puntazo.

Eso sí, te recomendaría que incluyeras código a modo de ejemplo para que los usuarios sin mucha experiencia sepan a qué te refieres, o incluso para los que ya llevamos un tiempo, que nunca vienen mal a modo de referencia.

Si la idea es aportar la mayor cantidad de habilidades posibles, o recopilarlas, te recomendaría que crearas un fork de pokeruby o pokeemerald (el segundo mejor :3) y que todos pudieran contribuir allí, a la par que seguir dejando por aquí los respectivos códigos para aquellos que lo necesiten para algo puntual.

¡Sigue con esa buena iniciativa, buen tuto y un saludo!
Gracias por el apoyo y las recomendaciones las tendré muy en cuenta.

Normalidad/Normalize

Esta habilidad lo que hace es convertir todos los ataque al tipo normal. Para añadirla hay que ir a pokeruby\src\battle\battle_4.c y buscamos esto"static void atk06_typecalc(void)" y veremos esto:
Código:
static void atk06_typecalc(void)
{
    int i = 0;
    u8 move_type;
    if (gCurrentMove != MOVE_STRUGGLE)
    {
        if (gBattleStruct->dynamicMoveType)
            move_type = gBattleStruct->dynamicMoveType & 0x3F;
        else
            move_type = gBattleMoves[gCurrentMove].type;
Con mas cosas dentro de la misma función pero esto es suficiente para dar contexto.
Bueno, debajo de eso pegamos el siguiente código en una linea nueva.
Código:
if (gBattleMons[gBankAttacker].ability == ABILITY_NORMALIZE && gBattleMoves[gCurrentMove].type != TYPE_NORMAL)
		{
			gBattleStruct->dynamicMoveType = TYPE_NORMAL;
			move_type = TYPE_NORMAL;
		}
Y si hicimos los cambios correspondiente a la habilidad que expliqué en el post principal, ya debería estar funcionando.

Actualización de Sturdy/Robustez

Esta habilidad hasta la 4ta generación funcionaba solo bloqueando los ataques "One Hit KO" pero desde la 5ta generación a parte de eso, también impide que el pokémon caiga debilitado de un golpe si sus Ps. Estaban al máximo.

Para hacer que tenga sus dos efectos hay que ir al archivo "pokeruby\src\battle\battle_4.c" y buscar esto "(hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality)" y en una linea nueva justo arriba pegamos este código:
Código:
if (gBattleMons[gBankTarget].ability == ABILITY_STURDY && gBattleMons[gBankTarget].maxHP == gBattleMons[gBankTarget].hp && gBattleMons[gBankAttacker].ability != ABILITY_MOLD_BREAKER)
    {
        gProtectStructs[gBankTarget].endured = 1;
    }
Para que quede tal que así junto con lo que buscamos previamente.
Código:
if (gBattleMons[gBankTarget].ability == ABILITY_STURDY && gBattleMons[gBankTarget].maxHP == gBattleMons[gBankTarget].hp && gBattleMons[gBankAttacker].ability != ABILITY_MOLD_BREAKER)
    {
        gProtectStructs[gBankTarget].endured = 1;
    }
    if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality)
Ya con esto el pokémon se quedará a un Ps. Y ejecutará el mismo script de "Endure" o "Aguante".
  #6  
Hace 1 semana
Corazón Re: Respuesta: (pokeruby) Implementando habilidades nuevas
Dicho por Lumbreon Ver mensaje

"Aftermath"

En "battle.util.c"
Original
Código:
            case ABILITY_AFTERMATH:
                if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
                 && gBattleMons[gBankTarget].hp == 0
                 && (gBattleMoves[move].flags & F_MAKES_CONTACT))
                {
                    gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4;
                    if (gBattleMoveDamage == 0)
                        gBattleMoveDamage = 1;
                    BattleScriptPushCursor();
                    gBattlescriptCurrInstr = BattleScript_AftermathDmg;
                    effect++;
                }
                break;
Con Fix
Código:
            case ABILITY_AFTERMATH:
                if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
                 && gBattleMons[gBankTarget].hp == 0)
                {
                    gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4;
                    if (gBattleMoveDamage == 0)
                        gBattleMoveDamage = 1;
                    BattleScriptPushCursor();
                    gBattlescriptCurrInstr = BattleScript_AftermathDmg;
                    effect++;
                }
                break;
Según yo es un arreglo, quité el comprobante de sí el ataque hace contacto o no, porque si no mal recuerdo, el único requisito para que esta habilidad se active es que el pokémon sea debilitado.

Y en "battle_scripts_1.s" queda agregar un "hitanimation USER" en la primera linea del script que ejecuta esta función (BattleScript_AftermathDmg) si se quiere que haga la animación de ser golpeado.
Tu corrección a Aftermath está mal, y lo de añadir una animación es enteramente opcional. Recien ahora le estoy echando un vistazo apropiadamente, al reimplementar la habilidad en un nuevo repositorio.

Aftermath unicamente se activa si el pokémon que la posee es debilitado por un ataque fisico, y como tal, no produce ninguna animación en los juegos de la 4ta Generación y posteriores.
Lo ultimo no es que esté incorrecto ni nada, pero si es algo opcional. Mi implementación no posee una, porque mi objetivo era replicar de la manera mas fiel posible la habilidad como GF la desarrolló.

EDITO:
Dicho por Lumbreon Ver mensaje

"Anger Point"

En "battle_util.c"
Original
Código:
            case ABILITY_ANGER_POINT:
                if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gCritMultiplier > 1 && !gProtectStructs[gBankAttacker].confusionSelfDmg && gBattleMons[gBankTarget].hp != 0 && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))
                {
                    gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] = 12;
                    BattleScriptPushCursor();
                    gBattlescriptCurrInstr = BattleScript_AngerPointBoost;
                    effect++;
                }
                break;
Con Fix
Código:
				case ABILITY_ANGER_POINT:
                if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gCritMultiplier > 1 && !gProtectStructs[gBankAttacker].confusionSelfDmg && gBattleMons[gBankTarget].hp != 0 && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))
                {
                    gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] = 12;
					gBattleStruct->animArg1 = 0xF;
                    gBattleStruct->animArg2 = 0;					
                    BattleScriptPushCursor();
                    gBattlescriptCurrInstr = BattleScript_AngerPointBoost;
                    effect++;
                }
                break;
Aquí el cambio es meramente estético, pero me parece necesario.
Ya que con las lineas que agregué se prepara el terreno para que en el script de combate se haga la animación de aumento de estadísticas, la cual no se hace con el método original posteado por Doesnt.

En "battle_scripts_1.s"
Original
Código:
BattleScript_AngerPointBoost::
	printstring BATTLE_TEXT_AngerPointBoost
	waitmessage 64
	return
Con fix
Código:
BattleScript_AngerPointBoost::
	playanimation TARGET, B_ANIM_STATS_CHANGE, sANIM_ARG1
	printstring BATTLE_TEXT_AngerPointBoost
	waitmessage 64
	return
Nada mas que agregar, solo hacemos que ejecute la animación que declaramos anteriormente.
Lo mismo pasa aquí, Anger Point no activa ninguna animación de subida de estadisticas. Quizá sea por eso que la implementación de Doesnt no tiene una, porque entonces no seria fiel a como funciona la habilidad en los juegos oficiales.
Gracias: Lumbreon

Última edición por Lunos; Hace 1 semana a las 18:35
  #7  
Hace 1 semana
Predeterminado Respuesta: (pokeruby) Implementando habilidades nuevas
Lo siento Lunos por ese pequeño desliz debí informarme correctamente antes de corregir un trabajo ajeno, la verdad fue muy tonto, así que ahora traigo una corrección correcta y acorde al funcionamiento de la habilidad en los juegos originales.
(Lo de las animaciónes debí dejarlo, al menos para mi gusto quedaba muy bien, pero me precipité al borrarlo :v)
se trata de "Skill link" o "Encadenado", ya que la manera en que presenté esta habilidad en el post principal(que francamente no sé de donde la saqué :v), lo que hace es amplificar el daño de los movimientos "Multi hit".
Cuando originalmente lo que hace es que éstos siempre impacten 5 veces, para conseguir esto ultimo hay que hacer lo siguiente.

Encadenado

Hay que ir al archivo "pokeruby/src/battle/battle_4.c" y vamos a buscar esto "atk8D_setmultihitcounter" donde encontraremos la siguiente función:
Código:
static void atk8D_setmultihitcounter(void)
{
    if (T2_READ_8(gBattlescriptCurrInstr + 1))
        gMultiHitCounter = T2_READ_8(gBattlescriptCurrInstr + 1);
    else
    {
        gMultiHitCounter = Random() & 3;
        if (gMultiHitCounter > 1)
            gMultiHitCounter = (Random() & 3) + 2;
        else
            gMultiHitCounter += 2;

    }
    gBattlescriptCurrInstr += 2;
}
La cual vamos a remplazar por esta:
Código:
static void atk8D_setmultihitcounter(void)
{
    if (T2_READ_8(gBattlescriptCurrInstr + 1))
        gMultiHitCounter = T2_READ_8(gBattlescriptCurrInstr + 1);
    else
    {
        gMultiHitCounter = Random() & 3;
        if (gMultiHitCounter > 1)
            gMultiHitCounter = (Random() & 3) + 2;
        else
            gMultiHitCounter += 2;
		
		if (gBattleMons[gBankAttacker].ability == ABILITY_SKILL_LINK)
            gMultiHitCounter = 5;
    }
    gBattlescriptCurrInstr += 2;
}
Y listo ya estaría, cabe destacar que esto lo saque del battle engine de dizzyegg, el cual usaría pero por alguna razón no me compila cuando lo copio a mi carpeta de pokeemerald.


Scrappy o Intrepido

Esta habilidad hace el pokémon que la posea pueda atacar a pokémon de tipo fantasma con ataques de tipo normal y lucha.
En el mismo archivo (battle_4.c) buscamos lo siguiente:
Código:
{
            while (gTypeEffectiveness[i]!= TYPE_ENDTABLE)
            {
                if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
                {
                    if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) <------ esto lo modificamos
                        break;
                    i += 3;
                    continue;
                }
Donde señalé colocaremos esto:
Código:
while (gTypeEffectiveness[i]!= TYPE_ENDTABLE)
            {
                if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
                {
                    if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT || gBattleMons[gBankAttacker].ability == ABILITY_SCRAPPY) <----- colocamos el comprobante de la habilidad
                        break;
                    i += 3;
                    continue;
                }
Gracias: Tyren Sealess
  #8  
Hace 4 días
Predeterminado Re: (pokeruby) Implementando habilidades nuevas
Oye @Lumbreon, elimina mi implementación de la habilidad Filtro de tu hack/repositorio, porque está mal hecha.
Aquí puedes encontrarla bien hecha, Ctrl+F "ABILITY_FILTER".
https://pastebin.com/HRESyn3A
La pongo en un Pastebin porque la tengo puesta en un repositorio aun sin subir.

En fin, a lo que venia.
Mi implementación de "Bad Dreams" (la habilidad de Darkrai) tiene un pequeño problema, y es rarisimo.
Primero que nada y antes que todo describirla, Bad Dreams es una habilidad que le quita 1/8 de HP al oponente al final de cada turno, siempre y cuando esté dormido.

En si, la habilidad está funcionando correctamente contra un Wurmple, contra un Zigzagoon o contra un Poochyena, pero al probarla contra un Seedot, no funciona.

Lo que estoy haciendo para testear la habilidad basicamente es:
1) Darsela a Torchic.
2) Darle el movimiento Spore, para que pueda dormir enemigos sin error.
3) Entro en batalla, tiro Spore y luego puro Focus Energy para que pasen los turnos y yo pueda compruebar el efecto de Bad Dreams.

El resultado es que al final del turno, estando Wurmple/Poochyena/Zigzagoon dormidos, ellos pierden HP y la linea de texto que le asigné a Bad Dreams se muestra en pantalla.
La habilidad basicamente funciona correctamente.

Pero con Seedot, la habilidad no se activa en lo absoluto. Él se queda dormido, y el turno pasa normalmente.

Si tú (Lumineon) o alguien más tiene alguna idea sobre que puede estar pasando aquí, no dude en contactarme sea por aquí o por Discord (Lunos#4026).
El codigo es exactamente el mismo que enlacé ahi arriba. Mismas modificaciones tambien, excepto por lo que sea que hice en include\constants\egg_hatch.h. No tengo idea de que sea esa modificación, pero no está relacionada a la habilidad en lo absoluto y por eso no lo repliqué.

Agradezco de antemano por leer.

EDITO: Por cierto, tu implementación de Skill Link es completamente incorrecta.
El efecto de esa habilidad es hacer que los movimientos que golpean multiples veces, como por ejemplo Bullet Seed, Comet Punch y tal, siempre den 5 golpes en lugar de un numero aleatorio entre 2 y 5. No aumenta su poder de ninguna forma, como estás mostrando tú en el post principal.

EDITO2: Y bueno, poner Technician y Reckless dentro de una función que comprueba el daño por tipos no es exactamente correcto, aunque si las habilidades en si funcionan, pues que mas dá supongo.

EDITO3: Tras notar lo de Skill Link, decidí intentar hacer la habilidad yo mismo, a ver si podia.
.... Y pude.

Tras insertar el nombre, la descripción y definir la habilidad en include\constants\abilities.h, hay que modificar la función "atk8D_setmultihitcounter" del archivo src\battle\battle_4.c de la siguiente forma:
Código:
static void atk8D_setmultihitcounter(void)
{
    if (T2_READ_8(gBattlescriptCurrInstr + 1))
        gMultiHitCounter = T2_READ_8(gBattlescriptCurrInstr + 1);
    if (gBattleMons[gBankAttacker].ability == ABILITY_SKILL_LINK)
        gMultiHitCounter = 5;
    else
    {
        gMultiHitCounter = Random() & 3;
        if (gMultiHitCounter > 1)
            gMultiHitCounter = (Random() & 3) + 2;
        else
            gMultiHitCounter += 2;
    }
    gBattlescriptCurrInstr += 2;
}
Guardar, darsela a un pokémon para probar y compilar.

EDITO4: Tu implementación de Motor Drive funciona, pero faltó pulirla. Tiene un montón de codigo inutil.
Aquí dejo la habilidad tras retocarla un poco. Si ves algo mal o incorrecto, tú avisame.

BattleScript
Código:
BattleScript_MoveSpeedDrain::
	attackstring
	pause 32
	playanimation TARGET, B_ANIM_STATS_CHANGE, sANIM_ARG1	
	printstring BATTLE_TEXT_SpeedRisen
	waitmessage 64	
	goto BattleScript_MoveEnd
Efecto de la habilidad (src\battle\battle_util.c)
Código:
case ABILITY_MOTOR_DRIVE:
	if (moveType == TYPE_ELECTRIC && gBattleMoves[move].power != 0)
	{
		if (gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC)
			gBattleMons[bank].statStages[STAT_STAGE_SPEED]++;
		gBattleStruct->animArg1 = 0x11;
		gBattleStruct->animArg2 = 0;
		gBattlescriptCurrInstr = BattleScript_MoveSpeedDrain;
		effect = 2;
	}
	break;
Ya el formato, los espacios y tal lo arregla cada uno a la hora de insertar el codigo.
Gracias: Lumbreon

Última edición por Lunos; Hace 4 horas a las 21:50
Respuesta

Herramientas
Desplegado

Permisos para publicar mensajes
No puedes crear nuevos temas
No puedes responder mensajes
No puedes subir archivos adjuntos
No puedes editar tus mensajes

Los BB code están Activado
Los Emoticones están Activado
El código [IMG] está Activado
El Código HTML está Desactivado
Trackbacks are Activado
Pingbacks are Activado
Refbacks are Desactivado



Extra
Estilo clásico
La franja horaria es GMT +1. Ahora son las 02:07.