TheYellowRaptor
Usuario de oro
Buenas! Comencé a trabajar en un proyectito personal de decomp en pokeemerald y tratando de crear un nuevo ataque me salta el error del título y no sé que significa ni cómo resolverlo. Esto va a ser un poco largo, así que me disculpo por anticipado.
No soy programador ni tengo mucha experiencia en ello, pero algo logro entender empleando lo que ya existe. Me puse en campaña para crear un nuevo ataque (al que llamé "Hold Position") que maximice el stat DEF pero minice el stat ATK y, debido al enorme parecido que tiene con Tambor, decidí usarlo como base. Así que recreé todo exactamente igual que ese ataque: Definí el nuevo ataque en "moves.h" (ampliando la cantidad de "MOVES_COUNT"), añadí el ataque al archivo "battle_moves.h", le agregué una descripción en "move_descriptions.h" y un nombre en "move_names.h". Luego de eso creé un nuevo efecto (llamado como el movimiento: "EFFECT_HOLD_POSITION") e hice lo mismo: lo definí en "battle_moves_effects.h" y se lo asigné al movimiento.
Ahora empieza lo mas grueso del proceso: en el archivo en "battle_script_1.s" vi cómo funcionaba el ataque tambor, y vi que tenía la función (o comando, no estoy seguro de cómo llamarlo) "maxattackhalvehp". Fui al archivo "battle_script_commands.c" para ver cómo funcionaba y me encontré con lo siguiente:
No termino de entender qué hace el "T1_READ_PTR(gBattlescriptCurrInstr+1)", pero como sólo sucede si no se cumple el segundo "if", decidí dejarlo tal como está. El resto del código es bastante sencillo de interpretar, así que lo copié debajo, le quité todo lo referente a reducir los HP y lo modifiqué lo suficiente como para que cumpla la función que deseo, dejándolo así:
Tranquilos, definí el "Cmd_maxdefenseminattack(void)" al inicio del archivo (en la parte del "static void") y como constante en "gBattleScriptingCommandsTable[]" (el valor que, creo yo, tiene asignado es el 0xFA, que es el siguiente después del útlimo).
Nuevamente fui a "battle_script_1.s" y agregué el efecto de la siguiente manera:
Lo último que hice fue agregar en "battle_script.inc" el .macro "maxdefenseminattack" (tal como el de belly drum), dejándolo tal que así:
La cosa es que al compilar la ROM, me salta el error que ya les mencioné, de la siguiente manera (sin las comillas):
"data/battle_scripts_1.o: in function `BattleScript_EffectHoldPosition':
(script_data+0x155b): relocation truncated to fit: R_ARM_ABS8 against symbol `BattleScript_ButItFailed' defined in script_data section in data/battle_scripts_1.o"
Supongo que debe ser algo con a función "param0", que no tengo ni idea de qué es ni de para qué sirve; o puede que haya cometido un error en algún paso anterior. También se me ocurre que puede deberse a que el macro no se halla en 0xFA, sino que en otra parte.
Así que eso, cualquier ayuda que puedan brindarme será bien recibida. ¡Gracias!
No soy programador ni tengo mucha experiencia en ello, pero algo logro entender empleando lo que ya existe. Me puse en campaña para crear un nuevo ataque (al que llamé "Hold Position") que maximice el stat DEF pero minice el stat ATK y, debido al enorme parecido que tiene con Tambor, decidí usarlo como base. Así que recreé todo exactamente igual que ese ataque: Definí el nuevo ataque en "moves.h" (ampliando la cantidad de "MOVES_COUNT"), añadí el ataque al archivo "battle_moves.h", le agregué una descripción en "move_descriptions.h" y un nombre en "move_names.h". Luego de eso creé un nuevo efecto (llamado como el movimiento: "EFFECT_HOLD_POSITION") e hice lo mismo: lo definí en "battle_moves_effects.h" y se lo asigné al movimiento.
Ahora empieza lo mas grueso del proceso: en el archivo en "battle_script_1.s" vi cómo funcionaba el ataque tambor, y vi que tenía la función (o comando, no estoy seguro de cómo llamarlo) "maxattackhalvehp". Fui al archivo "battle_script_commands.c" para ver cómo funcionaba y me encontré con lo siguiente:
Código:
static void Cmd_maxattackhalvehp(void) // belly drum
{
u32 halfHp = gBattleMons[gBattlerAttacker].maxHP / 2;
if (!(gBattleMons[gBattlerAttacker].maxHP / 2))
halfHp = 1;
if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] < MAX_STAT_STAGE
&& gBattleMons[gBattlerAttacker].hp > halfHp)
{
gBattleMons[gBattlerAttacker].statStages[STAT_ATK] = MAX_STAT_STAGE;
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 2;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattlescriptCurrInstr += 5;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
Código:
static void Cmd_maxdefenseminattack(void) // Hold position
{
if (gBattleMons[gBattlerAttacker].statStages[STAT_DEF] < MAX_STAT_STAGE)
{
gBattleMons[gBattlerAttacker].statStages[STAT_DEF] = MAX_STAT_STAGE;
gBattleMons[gBattlerAttacker].statStages[STAT_ATK] = MIN_STAT_STAGE;
gBattlescriptCurrInstr += 5;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
Nuevamente fui a "battle_script_1.s" y agregué el efecto de la siguiente manera:
Código:
BattleScript_EffectHoldPosition::
attackcanceler
attackstring
ppreduce
maxdefenseminattack BattleScript_ButItFailed
attackanimation
waitanimation
printstring STRINGID_HOLDPOSITION
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
Código:
.macro maxdefenseminattack param0:req
.byte 0xfa
.byte \param0
.endm
"data/battle_scripts_1.o: in function `BattleScript_EffectHoldPosition':
(script_data+0x155b): relocation truncated to fit: R_ARM_ABS8 against symbol `BattleScript_ButItFailed' defined in script_data section in data/battle_scripts_1.o"
Supongo que debe ser algo con a función "param0", que no tengo ni idea de qué es ni de para qué sirve; o puede que haya cometido un error en algún paso anterior. También se me ocurre que puede deberse a que el macro no se halla en 0xFA, sino que en otra parte.
Así que eso, cualquier ayuda que puedan brindarme será bien recibida. ¡Gracias!