Same as Shadow Rush, add the new constant in constants\include\battle_move_effects.h and add the effect to the move in in src\battle_moves.h
Now, the effect of Shadow Half seems simple. It's a status move that deals damage by half the current HP of each Pokémon in battle, preventing fainting, and the next turns needs to recharge. Like a fusion of Hyper Beam, Super Fang and False Swipe. Normally a status move never does damage. That's where my first problem came. Those kind of moves that affect all Pokémon, like Sandstorm or Haze, actually target the User. I tried targeting both foes and ally and then apply the effects to the user, but that only caused problems on the number of times the User took damage and so. I finally managed for the move to target the User and the effect to target everyone, with the help of the Perish Song script.
In data\battle_scripts_1.s, add the .4byte part like with Shadow Rush. Then, the script for the move is the following:
Code:
BattleScript_EffectShadowHalf:
setmoveeffect MOVE_EFFECT_RECHARGE | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
attackanimation
waitanimation
seteffectwithchance
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
setbyte sBATTLER, 0x0
BattleScript_ShadowHalfLoop::
healthbarupdate BS_SCRIPTING
datahpupdate BS_SCRIPTING
BattleScript_ShadowHalfLoopIncrement::
addbyte sBATTLER, 0x1
jumpifbytenotequal sBATTLER, gBattlersCount, BattleScript_ShadowHalfLoop
printstring STRINGID_SHADOWHALFDAMAGE
waitmessage 0x40
goto BattleScript_MoveEnd
Everything before the setbyte command should be clear, a lot of moves have those commands in common. I add the Recharge effect to the new effect and set it with seteffectwithchance. Now, what I did after, is a loop to check the damage on each Pokémon (depends if it's a Single Battle or Double Battle) and update their respective HPBar. The setbyte sBATTLER 0x0 make the game first battler in gBattlersCount the active battler, and I add a byte for every battler after that (the BS_SCRIPTING actually checks the current sBATTLER, so it comes in handy). That way it checks the HP of each Pokémon and lowers it correctly. When the loop finishes (that's after the jumpifbytenotequal), I print a new made string, wait for the message, and redirect to the script that finishes the move.
But now, something's missing. Where do I tell to halve the HP of each mon? I had problem creating a new case in SetMoveEffect in src\battle_script_commands.c, so I had to modify a little the function healthbarupdate. The function is called Cmd_healthbarupdate and you can find it in the same file. I added the following code after the gActiveBattler is given a value.
Code:
if (gBattleMoves[gCurrentMove].effect == EFFECT_SHADOW_HALF)
{
if (!(IsBattlerAlive(gActiveBattler)))
{
gBattlescriptCurrInstr = BattleScript_ShadowHalfLoopIncrement;
return;
}
if (gBattleMons[gActiveBattler].hp > 1)
gBattleMoveDamage = gBattleMons[gActiveBattler].hp / 2;
else if (gBattleMons[gActiveBattler].hp == 1)
gBattleMoveDamage = gBattleMons[gActiveBattler].hp - 1;
}
That's simply it. Obviously explaining it is easier now XD, but is has been difficult to get with a solution. The last thing we have to do is add the BattleScript_ShadowHalfLoopIncrement as a constant in include\battle_scripts.h like so:
Code:
extern const u8 BattleScript_PerishBodyActivates[];
extern const u8 BattleScript_ShadowHalfLoopIncrement[];
And also, I added a new string, so we have to add it as well. The constant goes in include\constants\battle_string_ids.h
Code:
#define STRINGID_AURAFLAREDTOLIFE 562
#define STRINGID_SHADOWHALFDAMAGE 563
#define BATTLESTRINGS_COUNT 564
And the string itself goes in src\battle_mesagge.c, first the static const, and then in the gBattleStringsTable
Code:
static const u8 sText_ShadowHalfDamage[] = _("{B_ATK_NAME_WITH_PREFIX}'s darkness damaged\nall Pokémon!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
...
[STRINGID_SCREENCLEANERENTERS - 12] = sText_ScreenCleanerActivates,
[STRINGID_SHADOWHALFDAMAGE - 12] = sText_ShadowHalfDamage,