Registrarse

[pokeruby] Implementando habilidades nuevas

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Flower Gift (Gen. 4)
Tras definir la habilidad y opcionalmente darle un nombre y una descripción, añadimos el siguiente check a la lista ordenada de distintos calculos en la función CalculateBaseDamage del archivo src\battle\calculate_base_damage.c
Código:
if (defender->ability == ABILITY_FLOWER_GIFT && (gBattleWeather & WEATHER_SUN_ANY))
        spDefense = (150 * spDefense) / 100;
    if (attacker->ability == ABILITY_FLOWER_GIFT && (gBattleWeather & WEATHER_SUN_ANY))
        attack = (150 * attack) / 100;
Basicamente, debe quedar algo tal que asi.

Es muy sencilo de leer.
Si el pokémon que se está defendiendo tiene Flower Gift como habilidad y el clima es soleado, aumenta su Defensa Especial x1.5
Si el pokémon que está atacando tiene Flower Gift como habilidad y el clima es soleado, aumenta su Ataque x1.5

https://streamable.com/vjvjo
Nota: Las ridiculas cantidades de daño mostradas en este video son efecto de testear la habilidad con distintos valores.

EDITO:
¡Buenas!

Viendo que os estaba costando tanto el tema de Bad Dreams me he puesto un ratito a hacerlo todo desde cero y he conseguido que funcione tanto en individuales como en dobles, aquí dos GIF's que lo demuestran (en los siguientes turnos funciona también correctamente)


Bien, una vez demostrado que funciona, paso a dejar el BattleScript (que es muy importante) y la función.

En "data/battle_scripts_1.s" añadiremos

Código:
BattleScript_BadDreamsActivates:: @ 81D8C43
	healthbarupdate USER
	datahpupdate USER
	printstring BATTLE_TEXT_HurtOther
	waitmessage 64
	end3
Y en "src/battle/battle_util.c" añadiremos al principio del archivo

Código:
extern u8 BattleScript_BadDreamsActivates[];
Entre los demás de su tipo


Y luego, muy importante donde colocamos esto, si no, no funcionará.

Debe estar dentro del "case ABILITYEFFECT_ENDTURN:", esta función

Código:
case ABILITY_BAD_DREAMS:
    if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) && gBattleMons[gBankAttacker].hp != 0)
    {
        gLastUsedAbility = ABILITY_BAD_DREAMS;
        BattleScriptPushCursorAndCallback(BattleScript_BadDreamsActivates);
        gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 8;
        if (gBattleMoveDamage == 0)
            gBattleMoveDamage = 1;
        effect++;
    }
    break;

Sabéis que antes de todo esto hay que definir la habilidad



Definir su nombre in-game



Y su descripción



¡Espero que os sirva para futuras habilidades! ;)
Puees.. no está yendo muy bien que digamos. Probé la habilidad en una rama totalmente limpia, al dia con el repositorio de Pokeruby de Pret, y parece estar actuando pese a que ninguno de los pokémon en batalla tenga Bad Dreams.
En mi caso, yo dormí a Seedot usando Spore con mi Torchic que tiene Blaze como habilidad, y al final del turno Seedot perdió vida supuestamente debido a causa de la habilidad Blaze, cosa que no deberia pasar.
https://streamable.com/mvwq7

Yo seguí tus imagenes al pie de la letra, si de algo sirve.
https://imgur.com/a/YJRc7ZE

Basicamente, Bad Dreams está actuando pese a que ningun pokémon tiene la habilidad en batalla.
 
Última edición:

Kaktus

Miembro insignia
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Puees.. no está yendo muy bien que digamos. Probé la habilidad en una rama totalmente limpia, al dia con el repositorio de Pokeruby de Pret, y parece estar actuando pese a que ninguno de los pokémon en batalla tenga Bad Dreams.
En mi caso, yo dormí a Seedot usando Spore con mi Torchic que tiene Blaze como habilidad, y al final del turno Seedot perdió vida supuestamente debido a causa de la habilidad Blaze, cosa que no deberia pasar.
https://streamable.com/mvwq7

Yo seguí tus imagenes al pie de la letra, si de algo sirve.
https://imgur.com/a/YJRc7ZE

Basicamente, Bad Dreams está actuando pese a que ningun pokémon tiene la habilidad en batalla.
Como ya te comenté por Discord, lo único que hay que hacer es meterlo dentro de EndTurn, que al parecer, se me pasó y lo puse fuera. Habrá que hacer más cambios a la función de todas formas, pero yo ahora mismo no dispongo de más tiempo para ello.

Aún así, lo digo por si alguien se propone solucionarlo, tenerlo al menos un poco más fácil.
 

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

Listo, solucionado lo de bad dreams.
ahí las modificaciones necesarias.
Lo que ocurría con mi implementación anterior es que solo verificaba el estado alterado de 1 enemigo(el de la derecha), por lo que no hacia daño al enemigo de la izquierda si era el único dormido, mas si le hacía daño si ambos estaban dormidos, algo lioso... Pero ya funciona bien, que es lo importante.
 
Última edición:

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Listo, solucionado lo de bad dreams.
ahí las modificaciones necesarias.
Lo que ocurría con mi implementación anterior es que solo verificaba el estado alterado de 1 enemigo(el de la derecha), por lo que no hacia daño al enemigo de la izquierda si era el único dormido, mas si le hacía daño si ambos estaban dormidos, algo lioso... Pero ya funciona bien, que es lo importante.
Punto importante a mencionar para quien lea este tema:
La función IsBattlerAlive hay que moverla de lugar. Si se pone debajo de la función atkF8_trygetbaddreamstarget tal y como se muestra en la comparación por GitHub, Pokeruby no compilará.

En mi caso, yo la puse abajo de los bonos de captura de las poké balls y arriba de la función atk00_attackcanceler, y ahi Pokeruby compila correctamente.
https://i.imgur.com/fdTypOH.png

Videito de muestra.


EDITO: Ah, hace unos dias implementé Dry Skin en Pokeruby y se me habia olvidado postearlo.

Antes de hacer eso pero, por separado, queria hacer un repaso rapido de como añadir nuevas lineas de texto para movimientos o habilidades en batalla.

1) En constants\battle_text.inc seguiremos el patrón marcado por el archivo y añadiremos una nueva linea de texto para usar en batallas como lo querramos.
Por defecto, la ultima linea es enum BATTLE_TEXT_NoEffectOn.

2) En src\battle\battle_message.c sumamos 1 al numero de lineas de texto para batallas, que tiene un atajo conveniente cerca del inicio del archivo, marcado por #define BATTLESTRINGS_NO.

3) En src\data\battle_strings_en.h definiremos nuestra linea de texto de 2 formas diferentes y luego escribiremos el texto en si.
La linea de texto hay que definirla una vez despues de "BATTLE_TEXT_NoEffectOn," y otra vez despues de "BattleText_NoEffectOn,".
Lo que es la linea de texto en si, la escribiremos despues de "const u8 BattleText_Dark[] = _("a DARK move");", en una linea nueva y como siempre, siguiendo como ejemplo las lineas de texto anteriores.
Si necesitan muestras, de nuevo, pueden revisar la comparación en GitHub que Lumbreon ya posteó ahi arriba.

Ahora si.

Dry Skin (Gen. 4)

Empezamos por lo basico. Definir la habilidad, su nombre, descripción y luego definimos una linea de texto para el efecto de la habilidad en batalla. En mi caso yo la llamé "DrySkinDmg".
Dicho eso:

Código:
const u8 BattleText_DrySkinDmg[] = _("{DEFENDING_MON}'s {STRING 22}\ncaused damage!");

Código:
if (defender->ability == ABILITY_DRY_SKIN && (gBattleMoves[gCurrentMove].type == TYPE_FIRE))
        gBattleMovePower = (125 * gBattleMovePower) / 100;

Código:
case ABILITY_DRY_SKIN:
                    if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY)
                     && gBattleMons[bank].maxHP > gBattleMons[bank].hp)
                    {
                        gLastUsedAbility = ABILITY_DRY_SKIN; // why
                        BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates);
                        gBattleMoveDamage = gBattleMons[bank].maxHP / 8;
                        if (gBattleMoveDamage == 0)
                            gBattleMoveDamage = 1;
                        gBattleMoveDamage *= -1;
                        effect++;
                    }
                    if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_SUN_ANY)
                     && gBattleMons[bank].maxHP > gBattleMons[bank].hp)
                    {
                        gLastUsedAbility = ABILITY_DRY_SKIN; // why
                        BattleScriptPushCursorAndCallback(BattleScript_DrySkinDmg);
                        gBattleMoveDamage = gBattleMons[bank].maxHP / 8;
                        if (gBattleMoveDamage == 0)
                            gBattleMoveDamage = 1;
                        effect++;
                    }
                    break;

Y a probar.

Como recordatorio, los efectos de Dry Skin son:
1) El pokémon recupera 1/8 de vida al final de cada turno si está lloviendo.
2) El pokémon pierde 1/8 de vida al final de cada turno si está soleado.
3) Si un pokémon usa un ataque de Tipo Fuego y la victima tiene Dry Skin, el poder de ese movimiento aumenta un 25%.

Como siempre, si alguien ve algo incorrecto, hagamelo saber.
 
Última edición:

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

Código:
case ABILITY_DRY_SKIN:
                    if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY)
                     && gBattleMons[bank].maxHP > gBattleMons[bank].hp)
                    {
                        gLastUsedAbility = ABILITY_DRY_SKIN; // why
                        BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates);
                        gBattleMoveDamage = gBattleMons[bank].maxHP / 8;
                        if (gBattleMoveDamage == 0)
                            gBattleMoveDamage = 1;
                        gBattleMoveDamage *= -1;
                        effect++;
                    }
                    if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_SUN_ANY)
                     && gBattleMons[bank].maxHP > gBattleMons[bank].hp)
                    {
                        gLastUsedAbility = ABILITY_DRY_SKIN; // why
                        BattleScriptPushCursorAndCallback(BattleScript_DrySkinDmg);
                        gBattleMoveDamage = gBattleMons[bank].maxHP / 8;
                        if (gBattleMoveDamage == 0)
                            gBattleMoveDamage = 1;
                        effect++;
                    }
                    break;

Y a probar.

Como recordatorio, los efectos de Dry Skin son:
1) El pokémon recupera 1/8 de vida al final de cada turno si está lloviendo.
2) El pokémon pierde 1/8 de vida al final de cada turno si está soleado.
3) Si un pokémon usa un ataque de Tipo Fuego y la victima tiene Dry Skin, el poder de ese movimiento aumenta un 25%.

Como siempre, si alguien ve algo incorrecto, hagamelo saber.
¡Muy bien, ya se esta moviendo un poco este post!

Solo que te faltó un efecto de esta habilidad, el cual inmuniza al pokémon que la posea ante ataques del tipo agua a la vez que restaura 25% de su salud para lo que bastaría solo colocar en el archivo battle_util.c un "case ABILITY_DRY_SKIN:" arriba de "case ABILITY_WATER_ABSORB:" ya que el efecto es el mismo.
debe quedar así.
Código:
case ABILITY_DRY_SKIN:
                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;
 

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

Aquí las habilidades Storm Drain, Motor Drive, Sap Sipper y la actualización de Lightning Rod Con algunas correcciones de bad dreams porque soy medio tonto xd
Los efectos de las habilidades son los siguientes:

Storm Drain: Hace al pokémon inmune a movimientos de tipo agua y sube su ataque especial al recibir un ataque de dicho tipo.
También en combates dobles causa que cualquier ataque de tipo agua sea dirigido hacia el pokémon que posea la habilidad.



Lightning Rod: Exactamente lo mismo que Storm Drain pero con el tipo eléctrico.



Motor Drive: Sube Velocidad al recibir movimientos tipo eléctrico.



Sap Sipper: Sube ataque al recibir movimientos tipo planta.

 
Última edición:

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

Habilidad Simple:
Hace que los cambios de estadísticas se dupliques, ergo, que si por ejemplo un pokémon con esta habilidad usa "DANZA ESPADA" su ataque subirá 4 niveles y usan "GRUÑIDO" su ataque bajará en 2 niveles.




 

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

Flower Gift (Gen. 4)
Tras definir la habilidad y opcionalmente darle un nombre y una descripción, añadimos el siguiente check a la lista ordenada de distintos calculos en la función CalculateBaseDamage del archivo src\battle\calculate_base_damage.c
Código:
if (defender->ability == ABILITY_FLOWER_GIFT && (gBattleWeather & WEATHER_SUN_ANY))
        spDefense = (150 * spDefense) / 100;
    if (attacker->ability == ABILITY_FLOWER_GIFT && (gBattleWeather & WEATHER_SUN_ANY))
        attack = (150 * attack) / 100;
Basicamente, debe quedar algo tal que asi.

Es muy sencilo de leer.
Si el pokémon que se está defendiendo tiene Flower Gift como habilidad y el clima es soleado, aumenta su Defensa Especial x1.5
Si el pokémon que está atacando tiene Flower Gift como habilidad y el clima es soleado, aumenta su Ataque x1.5
Acabando de leer la habilidad en la wikidex noté que te faltó una parte del efecto y es que esta habilidad tambien potencia a los compañeros en batallas dobles, para lo que bastaría con estas lineas:
Código:
if ((gBattleWeather & WEATHER_SUN_ANY) && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_FLOWER_GIFT, 0, 0))
        spDefense = (150 * spDefense) / 100;
    if ((gBattleWeather & WEATHER_SUN_ANY) && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_FLOWER_GIFT, 0, 0))
        attack = (150 * attack) / 100;
claro, bajo las que ya añadiste tu.

También en la implementación de Filter pues... No funciona xd
no se si esta es la "corregida" pero es la única que conseguí en el post así que aquí tengo una implementación funcional junto con la habilidad "Tinte Lens" (Aquí).
Aprovecho para decir que actualicé el post principal con las habilidades que van de momento.
 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

También en la implementación de Filter pues... No funciona xd
Si que funciona, si. La tienes que poner en 2 partes distintas del archivo, quizá no notaste eso, pero la implementación funciona perfectamente.

EDITO: Ah, y bueno, como es evidente, tienes que definir la habilidad Filter y la habilidad Solid Rock, que tiene exactamente el mismo efecto y por eso las implementé a las dos del tirón.

EDITO2:
Motor Drive: Sube Velocidad al recibir movimientos tipo eléctrico.
Ciertamente, por lo que la descripción que tú le diste está mal xD
Código:
gAbilityDescription_MotorDrive: @ 81FA0F6
	.string "Turns electricity to SP.ATK.$"
 
Última edición:

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

¡4TA GEN LISTA!
Aquí todas las habilidades hasta la cuarta generación en mi repositorio en GitHub.
Están todas definidas con nombre y descripción en español y con todos(o casi, no lo se :v) diálogos de combate también traducidos.

Sap Sipper:



Slow Start:



Storm Drain:


Download:



Motor Drive:


Mold Breaker:
 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Habilidad Simple:
Hace que los cambios de estadísticas se dupliques, ergo, que si por ejemplo un pokémon con esta habilidad usa "DANZA ESPADA" su ataque subirá 4 niveles y usan "GRUÑIDO" su ataque bajará en 2 niveles.




Compruebalo tú mismo por las dudas, pero creo que los cambios de esta commit arruinan algunas lineas de texto en batalla.
Lo ultimo que hice en mi repositorio fue añadir tu implementación de la habilidad "Simple", y mientras trabajaba en mi implementación de la habilidad "Gluttony", noté que el mensaje al comer una baya salia de manera incorrecta.


Revertí los cambios hechos en esa commit en la cual inserté Simple, y ahora el mensaje aparece correctamente.

Pruebalo dandote una Starf Berry/Baya Arabol, equipala a tu pokémon y haz que la coma en batalla.
 
Última edición:

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

Compruebalo tú mismo por las dudas, pero creo que los cambios de esta commit arruinan algunas lineas de texto en batalla.
Lo ultimo que hice en mi repositorio fue añadir tu implementación de la habilidad "Simple", y mientras trabajaba en mi implementación de la habilidad "Gluttony", noté que el mensaje al comer una baya salia de manera incorrecta.


Revertí los cambios hechos en esa commit en la cual inserté Simple, y ahora el mensaje aparece correctamente.

Pruebalo dandote una Starf Berry/Baya Arabol, equipala a tu pokémon y haz que la coma en batalla.
Lo que pasa(y me faltó decirlo) es que está pensado para usar strings en español, por ende cambié los buffer de lugar para que diga "sube mucho" y no "mucho sube" pero en ingles ya no se ve bien porque ocurre lo que demuestras en tu captura, por eso con la commit está el archivo "battle_strings.h" casi totalmente en español.
 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Gluttony/Gula (Gen. 4)
Esto es extremadamente sencillo.

Iremos a src\battle_util.c y nos enfocaremos en los siguientes efectos de objeto:
-HOLD_EFFECT_ATTACK_UP (Liechi Berry)
-HOLD_EFFECT_DEFENSE_UP (Ganlon Berry)
-HOLD_EFFECT_SPEED_UP (Salac Berry)
-HOLD_EFFECT_SP_ATTACK_UP (Petaya Berry)
-HOLD_EFFECT_SP_DEFENSE_UP (Apicot Berry)
-HOLD_EFFECT_CRITICAL_UP (Lansat Berry)
-HOLD_EFFECT_RANDOM_STAT_UP (Starf Berry)

Un Ctrl+F buscando el HOLD_EFFECT en cuestión bastará.

El proceso es practicamente igual para los 7 efectos, asi que solo lo demostraré con uno a modo de ejemplo.
Nos vamos a case HOLD_EFFECT_ATTACK_UP y veremos lo siguiente:
Código:
case HOLD_EFFECT_ATTACK_UP:
                if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_ATK] < 0xC)
                {
                    gBattleTextBuff1[0] = 0xFD;
                    gBattleTextBuff1[1] = 5;
                    gBattleTextBuff1[2] = STAT_STAGE_ATK;
                    gBattleTextBuff1[3] = EOS;

                    gBattleTextBuff2[0] = 0xFD;
                    gBattleTextBuff2[1] = 0;
                    gBattleTextBuff2[2] = 0xD2;
                    gBattleTextBuff2[3] = 0xD2 >> 8;
                    gBattleTextBuff2[4] = EOS;

                    gEffectBank = bank;
                    gBattleStruct->statChanger = 0x10 + STAT_STAGE_ATK;
                    gBattleStruct->animArg1 = 0xE + STAT_STAGE_ATK;
                    gBattleStruct->animArg2 = 0;
                    BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
                    effect = ITEM_STATS_CHANGE;
                }
break;
La unica modificación que haremos, es decirle a este bonito codigo que si el pokémon tiene la habilidad Gluttony/Gula, le dé el valor "2" a bankQuality, que claramente es la variable que controla el punto minimo en el que el pokémon tiene permitido comer la baya que está sujetando.

Hecho y dicho eso, el resultado es el siguiente:
Código:
case HOLD_EFFECT_ATTACK_UP:
				if (gBattleMons[bank].ability == ABILITY_GLUTTONY)
					bankQuality /= 2;
                if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_ATK] < 0xC)
                {
                    gBattleTextBuff1[0] = 0xFD;
                    gBattleTextBuff1[1] = 5;
                    gBattleTextBuff1[2] = STAT_STAGE_ATK;
                    gBattleTextBuff1[3] = EOS;

                    gBattleTextBuff2[0] = 0xFD;
                    gBattleTextBuff2[1] = 0;
                    gBattleTextBuff2[2] = 0xD2;
                    gBattleTextBuff2[3] = 0xD2 >> 8;
                    gBattleTextBuff2[4] = EOS;

                    gEffectBank = bank;
                    gBattleStruct->statChanger = 0x10 + STAT_STAGE_ATK;
                    gBattleStruct->animArg1 = 0xE + STAT_STAGE_ATK;
                    gBattleStruct->animArg2 = 0;
                    BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
                    effect = ITEM_STATS_CHANGE;
                }
                break;
Y basicamente la misma tonteria hay que aplicarla a los otros 6 efectos.

Si todo salió bien, el pokémon deberia comerse una de las bayas previamente mencionadas en el momento en que alcance el 50% de su vida, o menos.
Normalmente, el pokémon comeria la baya tras alcanzar el 25% o menos, como referencia.

Resultado:


Y eso es todo.

Creditos a Blurose, porque pese a que la forma en la que yo originalmente implementé la habilidad funcionaba, la suya funciona y es muchisimo mas agradable a la vista.
 
Última edición:

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Hydration
Esta habilidad cura cualquier problema de estado siempre y cuando esté lloviendo en el campo de batalla.

Tan facilito como el anterior. Es una copia modificada de Shed Skin.
Abran src\battle\battle_util.c, y ponganla debajo de case ABILITY_SHED_SKIN.
Código:
case ABILITY_HYDRATION:
					if ((gBattleMons[bank].status1 & STATUS_ANY) && (gBattleWeather & WEATHER_RAIN_ANY))
                    {
                        if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON))
                            StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
                        if (gBattleMons[bank].status1 & STATUS_SLEEP)
                            StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
                        if (gBattleMons[bank].status1 & STATUS_PARALYSIS)
                            StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
                        if (gBattleMons[bank].status1 & STATUS_BURN)
                            StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
                        if (gBattleMons[bank].status1 & STATUS_FREEZE)
                            StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
                        gBattleMons[bank].status1 = 0;
						gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
                        gBattleStruct->scriptingActive = gActiveBattler = bank;
                        BattleScriptPushCursorAndCallback(BattleScript_ShedSkinActivates);
                        EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1);
                        MarkBufferBankForExecution(gActiveBattler);
                        effect++;
                    }
					break;
Guardar, compilar y testear.

Aquí un video rapido:
https://streamable.com/uturw

Si ven algun problema, avisenme.

Vaya, por fin lo pude postear. Me cago en el filtro boludo de los doble posts.
 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Recien noté que podia implementar Tinted Lens/Cromolente de forma facil y sencilla, de manera similar a Adaptabilidad, Filtro o Roca Sólida, asi que lo hice y lo dejo por aquí.

Es cuestión de añadir lo siguiente en las funciones atk06_typecalc y TypeCalc del archivo src\battle\battle_4.c
Código:
if ((gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE) && gBattleMons[gBankAttacker].ability == ABILITY_TINTED_LENS)
        gBattleMoveDamage = gBattleMoveDamage *= 2;
Basicamente, algo tal que asi.

Resultado:

Nota: El daño exagerado es producto de usar un valor mayor que 2 para mejor testeo.

Si ven algun problema, avisenme.

Y eso es todo.
 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Quick Feet
Cuando un pokémon con esta habilidad sufre un estado alterado, recibe un aumento de velocidad del 50%.

La forma de implementar la habilidad es sencillisima. Nos iremos a src\battle\battle_2.c y una vez allí, haremos Ctrl+F "MACHO_BRACE".
Como pudieron suponer, aquí es donde se aplica la reducción de velocidad al pokémon si lleva el Macho Brace equipado.

Muy bien, ahora mismo estamos dentro de la función GetWhoStrikesFirst.
Lo que haremos será añadir 2 chequeos, 1 para el pokémon del Jugador, y otro para el del Oponente.

Si leemos el archivo, veremos comentarios escritos por los miembros de Pret.
Quiero que enfoquen su atención en 2 comentarios en particular:
-Calculate adjusted speed for first mon
-Calculate adjusted speed for second mon

Bajo estos comentarios es que se encuentran los calculos de distintas cosas que afectan la velocidad de un pokémon o el otro bajo determinadas situaciones, como lo mencioné con el Macho Brace.

Pues en cada una de esas secciones, añadiremos los 2 chequeos.

1) Chequeo para el pokémon del Jugador:
Código:
// Quick Feet
    if (gBattleMons[bank1].ability == ABILITY_QUICK_FEET && (gBattleMons[bank1].status1 & STATUS_ANY))
        bank1AdjustedSpeed = (bank1AdjustedSpeed * 150) / 100;
2) Chequeo para el pokémon del Oponente:
Código:
// Quick Feet
    if (gBattleMons[bank2].ability == ABILITY_QUICK_FEET && (gBattleMons[bank2].status1 & STATUS_ANY))
        bank2AdjustedSpeed = (bank2AdjustedSpeed * 150) / 100;
Y listo, asi de simple.
Si lo hicieron bien, deberia lucir mas o menos asi.

Resultado:
https://streamable.com/tzizh

Nota: No se crean ni por un instante que un Torchic de Nivel 7 podria superar en velocidad a un puto Deoxys con mas nivel gracias a esta habilidad. Como siempre, yo utilizo valores exageradamente grandes para testear mas comodamente.

Y eso fue todo.
 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Rivalry

-Si el pokémon oponente es del mismo genero que el tuyo, aumenta tu ataque en un 25%
-Si es del genero opuesto, baja tu ataque en un 25%
-Si tiene un genero especifico, no hace nada.

Nos vamos a src\battle\calculate_base_damage.c y añadimos lo siguiente, debajo del resto de calculaciones de movimientos, habilidades, objetos y tal.

Código:
// Rivalry
	if (GetGenderFromSpeciesAndPersonality(attacker->species, attacker->personality) != MON_GENDERLESS
		&& GetGenderFromSpeciesAndPersonality(defender->species, defender->personality) != MON_GENDERLESS)
	{
		if (GetGenderFromSpeciesAndPersonality(attacker->species, attacker->personality)
		== GetGenderFromSpeciesAndPersonality(defender->species, defender->personality))
			gBattleMovePower = (125 * gBattleMovePower) / 100;
		else
			gBattleMovePower = (150 * gBattleMovePower) / 200;
	}
En mi archivo, luce asi.

Resultado:
https://streamable.com/esrmq
Nota: Lo usual. El daño exagerado es para poder testear mas comodamente.

Creditos a DizzyEgg, pues esto es mas o menos un port de su implementación para el batle engine v2.
 

Lumbreon

Soy nuevo XD :3
Respuesta: (pokeruby) Implementando habilidades nuevas

Rivalry

-Si el pokémon oponente es del mismo genero que el tuyo, aumenta tu ataque en un 25%
-Si es del genero opuesto, baja tu ataque en un 25%
-Si tiene un genero especifico, no hace nada.

Nos vamos a src\battle\calculate_base_damage.c y añadimos lo siguiente, debajo del resto de calculaciones de movimientos, habilidades, objetos y tal.

Código:
// Rivalry
	if (GetGenderFromSpeciesAndPersonality(attacker->species, attacker->personality) != MON_GENDERLESS
		&& GetGenderFromSpeciesAndPersonality(defender->species, defender->personality) != MON_GENDERLESS)
	{
		if (GetGenderFromSpeciesAndPersonality(attacker->species, attacker->personality)
		== GetGenderFromSpeciesAndPersonality(defender->species, defender->personality))
			gBattleMovePower = (125 * gBattleMovePower) / 100;
		else
			gBattleMovePower = (150 * gBattleMovePower) / 200;
	}
En mi archivo, luce asi.

Resultado:
https://streamable.com/esrmq
Nota: Lo usual. El daño exagerado es para poder testear mas comodamente.

Creditos a DizzyEgg, pues esto es mas o menos un port de su implementación para el batle engine v2.
Jejeje, yo tardé mucho intentando hacer esta habilidad.
Pero en tu implementación noto que no tienes el comprobante de la habilidad (attacker->ability == ABILITY_RIVALRY) y si no está por ahí significa que se harán la bonificación o la reducción a cualquier pokémon aún sin la habilidad.
 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Jejeje, yo tardé mucho intentando hacer esta habilidad.
Pero en tu implementación noto que no tienes el comprobante de la habilidad (attacker->ability == ABILITY_RIVALRY) y si no está por ahí significa que se harán la bonificación o la reducción a cualquier pokémon aún sin la habilidad.
Fallo tonto de mi parte.
Basta con añadir:
Código:
&& attacker->ability == ABILITY_RIVALRY
Y listo.

 

Lunos

Enfrentando a La Organización
Miembro insignia
Respuesta: (pokeruby) Implementando habilidades nuevas

Scrappy

Hace que los movimientos de Tipo Normal y Lucha puedan afectar a pokémon de Tipo Fantasma.

No tengo mucho que decir, la verdad. Abrí un nuevo repositorio para mi proyecto y archivé el viejo.
En el nuevo es en donde estaré subiendo cada habilidad que haga de aquí en más, asi que no tengo que explicar mucha cosa.

Las modificaciones para Scrappy se encuentran aquí, enfoquense en src\battle\battle_4.c:
https://github.com/LOuroboros/pokeruby493/commit/6b7e4a2f34443e19f3d4412d4f985e9ce82573ae

Resultado:


Y eso fue todo.
 
Arriba