Registrarse

[Pokeruby/Pokeemerald/Pokefirered] Repartidor de Experiencia Estilo Gen. 6 (aka Exp. All)

Lunos

Enfrentando a La Organización
EDITO: He porteado esta mecanica que Blurose escribió a Pokeemerald y Pokefirered.
Pueden ver los cambios necesarios a continuación.

Pokeemerald:
https://github.com/LOuroboros/pokeemerald/commit/6c4af6c13ae8fafc60f1753c9cc5a6a7b327a04b
https://github.com/LOuroboros/pokeemerald/commit/ec778a6aeac8edc5409e39ab0a91583a9886c7ff

Pokefirered:
https://github.com/LOuroboros/pokefirered/commit/fb68fb9d133dc8a350a847c7c322415cd681fb06

Post Original:
Holi. Siguiendo con estos no tutoriales, vengo a dejar por aquí las modificaciones para hacer que nuestro Exp. Share pase a funcionar como el de la Sexta Generación de juegos pokémon.
Antes de comenzar, hay que destacar que esto lo hizo @BluRose y lo escribió justo aqui, asi que todos los creditos van para él.
Sin mas que decir, empecemos.

Requisitos:
-Leer mi tema de introducción a Pokeruby.
-Editor de texto (yo usaré Notepad++)

Instrucciones:
1) Abrimos pokeruby\include\global.h con nuestro editor de texto.
Acto seguido buscamos "struct SaveBlock2 /* 0x02024EA4 */" mediante Ctrl+F, y veremos esto:
struct SaveBlock2 /* 0x02024EA4 */
{
/*0x00*/ u8 playerName[8];
/*0x08*/ u8 playerGender; // MALE, FEMALE
/*0x09*/ u8 specialSaveWarp;
/*0x0A*/ u8 playerTrainerId[4];
/*0x0E*/ u16 playTimeHours;
/*0x10*/ u8 playTimeMinutes;
/*0x11*/ u8 playTimeSeconds;
/*0x12*/ u8 playTimeVBlanks;
/*0x13*/ u8 optionsButtonMode; // OPTIONS_BUTTON_MODE_[NORMAL/LR/L_EQUALS_A]
/*0x14*/ u16 optionsTextSpeed:3; // OPTIONS_TEXT_SPEED_[SLOW/MID/FAST]
u16 optionsWindowFrameType:5; // Specifies one of the 20 decorative borders for text boxes
u16 optionsSound:1; // OPTIONS_SOUND_[MONO/STEREO]
u16 optionsBattleStyle:1; // OPTIONS_BATTLE_STYLE_[SHIFT/SET]
u16 optionsBattleSceneOff:1; // whether battle animations are disabled
u16 regionMapZoom:1; // whether the map is zoomed in
/*0x18*/ struct Pokedex pokedex;
/*0x90*/ u8 filler_90[0x8];
/*0x98*/ struct Time localTimeOffset;
/*0xA0*/ struct Time lastBerryTreeUpdate;
/*0xA8*/ struct BattleTowerData battleTower;
};​
Debajo de "u16 regionMapZoom:1" añadiremos "u16 expShare:1;".
Sugiero respetar el patrón de espacios, para que todo luzca lindo y prolijo.

2) Abrimos pokeruby\src\strings.c con nuestro editor de texto.
Acto seguido añadiremos estas 2 lineas en donde nos plazca.
Yo las añadí en las Lineas #151 y #152, porque si.
const u8 gOtherText_ExpShareOn[] = _("Turned on the Exp. Share.\pParty will now gain a portion\nof the Experience Points.{PAUSE_UNTIL_PRESS}");
const u8 gOtherText_ExpShareOff[] = _("Turned off the Exp. Share.\pParty will no longer gain a portion\nof any Experience Points.{PAUSE_UNTIL_PRESS}");​
3) Abrimos pokeruby\include\strings.h con nuestro editor de texto.
Acto seguido añadiremos estas 2 lineas en donde nos plazca.
Yo las añadí en las Lineas #141 y #142, porque si.
extern const u8 gOtherText_ExpShareOn[];
extern const u8 gOtherText_ExpShareOff[];​
3.1) Opcionalmente:
Nos vamos a pokeruby\src\data y abrimos el archivo item_descriptions_en.h con nuestro editor de texto.
Ctrl+F "gItemDescription_ExpShare" y reemplazaremos la descripción del Exp. Share que es esta:
static const u8 gItemDescription_ExpShare[] = _(
"A hold item that\n"
"gets EXP. points\n"
"from battles.");​
Por esta:
static const u8 gItemDescription_ExpShare[] = _(
"A special device\n"
"that spreads Exp.\n"
"pts. from battles.");​
^ O si prefieren, traduzcanla.

4) Abrimos pokeruby\src\item_use.c con nuestro editor de texto.
Añadiremos la siguiente función en donde queramos.
Yo la puse luego de "void ItemUseOutOfBattle_Mail(u8 taskId)" porque me salió de las pelotas.
void ItemUseOutOfBattle_ExpShare(u8 taskId)
{
if (!gSaveBlock2.expShare)
{
PlaySE(SE_EXPMAX);
if (!gTasks[taskId].data[2]) // to account for pressing select in the overworld
{
Menu_EraseWindowRect(0, 13, 13, 20);
DisplayItemMessageOnField(taskId, gOtherText_ExpShareOn, CleanUpItemMenuMessage, 1);
}
else
{
DisplayItemMessageOnField(taskId, gOtherText_ExpShareOn, CleanUpOverworldMessage, 0);
}
}
else
{
PlaySE(SE_PC_OFF);
if (!gTasks[taskId].data[2]) // to account for pressing select in the overworld
{
Menu_EraseWindowRect(0, 13, 13, 20);
DisplayItemMessageOnField(taskId, gOtherText_ExpShareOff, CleanUpItemMenuMessage, 1);
}
else
{
DisplayItemMessageOnField(taskId, gOtherText_ExpShareOff, CleanUpOverworldMessage, 0);
}
}
gSaveBlock2.expShare = !gSaveBlock2.expShare;
}​
5) Abrimos pokeruby\include\item_use.h con nuestro editor de texto.
Añadiremos esta linea en donde queramos.
Yo la puse debajo de "void ItemUseOutOfBattle_Mail(u8);" porque me salia de las pelotas.
void ItemUseOutOfBattle_ExpShare(u8);​
6) Abrimos pokeruby\src\battle\battle_4.c
Aquí la bestia aumenta un poco de tamaño ( ͡° ͜ʖ ͡°) ....

No, en serio, vamos a la función "static void atk23_getexp(void)" en la Linea #5367, y veremos este pedazo de cacho de trozo de función que ni en broma pienso pegar aquí

Pues lo que modificaremos serán los Casos 1 y 2.
Basicamente reemplazaremos el contenido de la Linea #5397 a la #5531 por esta función que tambien es medio larga y no pondré aquí directamente porque luce para el ojete.

7) Abrimos pokeruby\src\data\items_en.h con nuestro editor de texto.
Ctrl+F "share" y veremos lo siguiente:
{
.name = _("EXP. SHARE"),
.itemId = ITEM_EXP_SHARE,
.price = 0,
.holdEffect = HOLD_EFFECT_NONE,
.holdEffectParam = 0,
.description = gItemDescription_ExpShare,
.importance = 1,
.exitsBagOnUse = 0,
.pocket = POCKET_KEY_ITEMS,
.type = 2,
.fieldUseFunc = ItemUseOutOfBattle_ExpShare,
.battleUsage = 0,
.battleUseFunc = NULL,
.secondaryId = 0,
},​
Lo modificaremos tal que asi:
{
.name = _("EXP. SHARE"),
.itemId = ITEM_EXP_SHARE,
.price = 0,
.holdEffect = HOLD_EFFECT_NONE,
.holdEffectParam = 0,
.description = gItemDescription_ExpShare,
.importance = 1,
.exitsBagOnUse = 0,
.pocket = POCKET_KEY_ITEMS,
.type = 2,
.fieldUseFunc = ItemUseOutOfBattle_ExpShare,
.battleUsage = 0,
.battleUseFunc = NULL,
.secondaryId = 0,
},​
Si no me salté nada, este deberia ser su resultado:


Por ahi la sintaxis luce para el reverendo culo en este foro. En ese caso, agarren las piezas de codigo nuevas desde el post enlazado al inicio de este y ya. Muy sencillo todo.

Y ya está.​
 
Última edición:

BluRose

chiste, chiste
Respuesta: Repartidor de Experiencia Estilo Gen. 6 (aka Exp. All)

gracas por traerlo aquí ajaja

una cosa que necesito mencionar:
el juego imprime los nombres de todos los pokemon que tienes; no dice "y el resto del equipo gana experiencia" o lo que sea, no sé
me gustaría añadir eso eventualmente, pero ahora no
lo siento por todos que asumían que fuera así ;-;
 

Lunos

Enfrentando a La Organización
Respuesta: Repartidor de Experiencia Estilo Gen. 6 (aka Exp. All)

He porteado esta versión de la mecanica escrita por Blurose a Pokeemerald.
Los cambios relevantes los pueden ver en esta commit.
Meses despues, recien me doy cuenta de que los Huevos Pokémon tambien pueden recibir experiencia.

Para corregirlo, pueden hacer este pequeñisimo cambio para prohibir que eso ocurra:
https://github.com/LOuroboros/pokeemerald/commit/ec778a6aeac8edc5409e39ab0a91583a9886c7ff
 

BluRose

chiste, chiste
Respuesta: Repartidor de Experiencia Estilo Gen. 6 (aka Exp. All)

me parece que esto sea algo que siempre nunca tengo en cuenta: los huevos

tambien podrias hacer algo asi:
Código:
!GetMonData(gBattleStruct->expGetterMonId, MON_DATA_IS_EGG)
en lugar de
Código:
(GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPECIES2) != SPECIES_EGG)
 

Lunos

Enfrentando a La Organización
Respuesta: Repartidor de Experiencia Estilo Gen. 6 (aka Exp. All)

me parece que esto sea algo que siempre nunca tengo en cuenta: los huevos

tambien podrias hacer algo asi:
Código:
!GetMonData(gBattleStruct->expGetterMonId, MON_DATA_IS_EGG)
en lugar de
Código:
(GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPECIES2) != SPECIES_EGG)
Lo he intentado asi como tú sugieres, pero no parecia ir muy bien, la verdad.
https://streamable.com/d6z4g

 

Samu

Usuario de Oro
Re: Respuesta: Repartidor de Experiencia Estilo Gen. 6 (aka Exp. All)

Que raro, en principio debería ser equivalente. No obstante, tampoco es una mejora significativa del código, si no funciona déjalo así, pero no tiene mucho sentido.

Edit*

Espeeera, se ha debido confundir al ponerte el código, prueba con esto
Código:
!GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId],  MON_DATA_IS_EGG);
Con lo que te había dejado BluRose estabas pasando el slot del Pokémon a GetMonData, en vez del puntero al struct del Pokémon :p
 
Arriba